├── jpg
├── hjbl.png
├── laku.png
├── tz.png
├── 未标题-1.png
├── IMG_1344.JPG
├── Screenshot_2022_0730_200049.jpg
├── A97F963D4799767B81EDDD73A763BF19.jpg
├── C1F26C7C1B84EA696F2F50C5B3AE58FC.jpg
└── C1F26C7C1B84EA696F2F50C5B3AE58FC.png
├── 对接傻妞
├── README.md
├── 教程.txt
└── 我在校园.js
├── README.md
├── wzxy_bbfx.js
├── sendNotify.js
├── wzxy_check.js
├── wzxy_qd.js
└── wzxy_rjrb.js
/jpg/hjbl.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhacha222/wozaixiaoyuan/HEAD/jpg/hjbl.png
--------------------------------------------------------------------------------
/jpg/laku.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhacha222/wozaixiaoyuan/HEAD/jpg/laku.png
--------------------------------------------------------------------------------
/jpg/tz.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhacha222/wozaixiaoyuan/HEAD/jpg/tz.png
--------------------------------------------------------------------------------
/jpg/未标题-1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhacha222/wozaixiaoyuan/HEAD/jpg/未标题-1.png
--------------------------------------------------------------------------------
/jpg/IMG_1344.JPG:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhacha222/wozaixiaoyuan/HEAD/jpg/IMG_1344.JPG
--------------------------------------------------------------------------------
/jpg/Screenshot_2022_0730_200049.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhacha222/wozaixiaoyuan/HEAD/jpg/Screenshot_2022_0730_200049.jpg
--------------------------------------------------------------------------------
/jpg/A97F963D4799767B81EDDD73A763BF19.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhacha222/wozaixiaoyuan/HEAD/jpg/A97F963D4799767B81EDDD73A763BF19.jpg
--------------------------------------------------------------------------------
/jpg/C1F26C7C1B84EA696F2F50C5B3AE58FC.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhacha222/wozaixiaoyuan/HEAD/jpg/C1F26C7C1B84EA696F2F50C5B3AE58FC.jpg
--------------------------------------------------------------------------------
/jpg/C1F26C7C1B84EA696F2F50C5B3AE58FC.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/zhacha222/wozaixiaoyuan/HEAD/jpg/C1F26C7C1B84EA696F2F50C5B3AE58FC.png
--------------------------------------------------------------------------------
/对接傻妞/README.md:
--------------------------------------------------------------------------------
1 | #由于傻妞在2022年9月份插件规则更新,因此本插件仅适用于在2022年9月份以前的老傻妞,最新版傻妞不能使用!
2 |
3 | ## 对接傻妞
4 | 目前基本框架已经写完,可能会存在一些小bug(不影响使用)。
5 | ### 已完成功能:
6 |
7 | 1 . 修改密码 ✅
8 |
9 | 2 . 添加账号 ✅
10 |
11 | 3 . 删除账号 ✅
12 |
13 | 4 . 账号统计✅
14 |
15 | 5 . 教程✅
16 |
17 |
18 |
19 | ### 计划功能:
20 |
21 | 1 . 执行签到任务 **(摆烂中,不写了... )**
22 |
23 |
--------------------------------------------------------------------------------
/对接傻妞/教程.txt:
--------------------------------------------------------------------------------
1 | 关于变量值中各参数的说明:
2 |
3 | username —— “我在校园”的账号,一般是你的手机号码
4 |
5 | password —— “我在校园”的密码,忘记了打开小程序重新设置就行(建议四个英文+四个数字 类似“wzxy1234” 复杂了简单了可能都不行,改完密码运行脚本前不要再登录小程序)
6 |
7 | qd_location —— 签到位置的经纬度(wzxy_qd.js)
8 |
9 | rjrb_answers —— 日检日报的 填空参数(wzxy_rjrb.js) 看下面一些踩坑以及经验的第5条
10 |
11 | rjrb_location —— 日检日报位置的经纬度(wzxy_rjrb.js)
12 |
13 | jkdk_answers —— 健康打卡的 填空参数(wzxy_jkdk.js)
14 |
15 | jkdk_location —— 健康打卡位置的经纬度(wzxy_jkdk.js) 参考下面一些踩坑以及经验的第5条
16 |
17 | mark —— 用户昵称(不一定要真名,随便填都行,便于自己区分打卡用户)
18 |
19 | 一些踩坑以及经验:
20 |
21 | 1.我在校园密码不能太复杂,也不能太简单,推荐使用四个英文+四个数字,例如我用是wzxy1234
22 |
23 | 2.如果第一次使用,即使密码没问题,但是运行脚本时提示密码错误,请去小程序修改密码后重新运行脚本(我在校园本身的bug)
24 |
25 | 3.经纬度获取可以去这个网站获取,一般精确到小数点后六位就差不多了 https://jingweidu.bmcx.com/
26 |
27 | 4.脚本运行时间采用正则表达式,对此不太熟练的可以去这个在线网站一键生成 http://cron.ciding.cc/
28 |
29 | 5.这里对这个填空参数说明一下,如果是填空,那么参数就是填空内容;如果是选择题,选项一 参数是0,选项二 参数是1,以此类推····
30 |
31 | 每一项的参数填入""内,用,隔开,最终的参数再用[]括起来
32 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 我在校园 青龙面板
2 |
3 | > **开源项目,不接受任何打赏,谢谢!**
4 |
5 | ## 🐧企鹅群
6 | > **不懂的可以加交流群问,发现bug也加群说,看到了就会回,群号:[744087145](https://jq.qq.com/?_wv=1027&k=1deSaQ3X)**
7 |
8 |
9 |
10 |
11 | ## 📌须知:
12 |
13 | * 1.只支持青龙面板(推荐使用青龙版本2.10.13),部署教程 ==> [点击查看](https://github.com/whyour/qinglong#%E9%83%A8%E7%BD%B2)
14 |
15 | * 2.本库脚本通用 `wzxy`这一个变量
16 |
17 | * 3.脚本变量只推荐在青龙的【环境变量】页添加,有强迫症在【配置文件】`config.sh`中添加的如果出现问题自己解决
18 |
19 | * 4.支持多用户,每一用户在【环境变量】单独新建变量`wzxy`,切勿一个变量内填写多个用户的参数
20 |
21 | * 5.脚本通知方式采用`青龙面板默认通知`,请在【配置文件】`config.sh`里配置
22 |
23 | * 6.关于各脚本的具体使用方法,请仔细阅读各脚本内的注释!
24 |
25 |
26 |
27 |
28 | ## 📍拉库:
29 |
30 | - 2.12.1之前版本青龙拉库:
31 |
32 | ```
33 | 定时任务——新建任务
34 | 名称:我在校园拉库
35 | 命令:ql repo https://ghproxy.com/https://github.com/zhacha222/wozaixiaoyuan.git "wzxy_|sendNotify" "" "sendNotify"
36 | 定时:0 0 * * *
37 | ```
38 |
39 | - 2.12.1之后版本青龙拉库:
40 |
41 | ```
42 | 订阅管理——新建订阅
43 | 名称:我在校园拉库
44 | 类型:公开仓库
45 | 链接:https://ghproxy.com/https://github.com/zhacha222/wozaixiaoyuan.git
46 | 白名单:wzxy_|sendNotify
47 | 定时类型:crontab
48 | 定时:0 0 * * *
49 | 其他不填
50 | ```
51 |
52 |
53 |
54 |
55 |
56 | ## 🔎环境变量:
57 |
58 | **变量名称:**
59 | ```
60 | wzxy
61 | ```
62 | **变量值:**
63 | ```
64 | {
65 | "username": "手机号",
66 | "password": "密码",
67 | "qd_location": "133.333333,33.333333",
68 | "rjrb_answers": ["0","0"],
69 | "rjrb_location": "133.333333,33.333333",
70 | "jkdk_answers": ["0","无","1","0","36.2","没有","1","1","2"],
71 | "jkdk_location": "133.333333,33.333333",
72 | "mark": "用户昵称"
73 | }
74 | ```
75 |
76 |
77 |
78 |
79 |
80 |
81 | **关于变量值中各参数的说明:**
82 |
83 | * `username` —— “我在校园”的账号,一般是你的手机号码
84 |
85 | * `password` —— “我在校园”的密码,忘记了打开小程序重新设置就行(推荐四个英文+四个数字,例如“wzxy1234”,改完密码后,在运行脚本前不要再登录小程序)
86 |
87 | * `qd_location` —— 签到位置的经纬度(wzxy_qd.js)
88 |
89 | * `rjrb_answers` —— 日检日报的 填空参数(wzxy_rjrb.js) 看下面`一些踩坑以及经验`的第6条
90 |
91 | * `rjrb_location` —— 日检日报位置的经纬度(wzxy_rjrb.js)
92 |
93 | * `jkdk_answers` —— 健康打卡的 填空参数(wzxy_jkdk.js)
94 |
95 | * `jkdk_location` —— 健康打卡位置的经纬度(wzxy_jkdk.js) 参考下面`一些踩坑以及经验`的第6条
96 |
97 | * `mark` —— 用户昵称(不一定要真名,随便填都行,便于自己区分打卡用户)
98 |
99 | ## 📝一些踩坑以及经验:
100 |
101 | * 1.我在校园密码不能太复杂,也不能太简单,推荐使用四个英文+四个数字,例如我用是`wzxy1234`
102 |
103 | * 2.如果第一次使用,即使密码没问题,但是运行脚本时提示密码错误,请去小程序修改密码后重新运行脚本(我在校园本身的bug)
104 |
105 | * 3.经纬度获取可以去这个网站获取,一般精确到小数点后六位就差不多了
106 | https://jingweidu.bmcx.com/
107 |
108 | * 4.脚本运行时间采用Cron表达式,对此不太熟练的可以去这个在线网站一键生成 http://cron.ciding.cc/
109 |
110 | * 5.可以去这个网站对你的变量值进行格式化检验 https://www.bejson.com/
111 |
112 | * 6.这里对这个填空参数说明一下:
113 |
114 | > 对于 **旧版日检日报和旧版健康打卡**,
115 | 如果是填空题,那么参数就是要填空的内容;
116 | 如果是选择题,选项一 参数是`0`,选项二 参数是`1`,以此类推····
117 |
118 | > 但是,对于**新版的健康打卡**,不管选择还是填空题,参数都是选项的 **文字内容**,具体看下面截图演示
119 |
120 | 每一题的参数都要填入`""`内,两两之间用`,`隔开,最终的参数再用`[]`括起来(另外,日检日报的体温体温已内置为36.0不用另填,但是健康打卡的体温需要自己填进填空参数里)
121 |
122 |
123 |
124 |
125 |
126 | ## 🔔通知方式:
127 |
128 | **在下面随便选一个自己喜欢的推送方式,在配置文件`config.sh`中的`通知环境变量(大概第41行到121行)`配置**
129 |
130 |
131 |
132 |
133 |
134 |
135 | **右图是本人在用的`企业微信应用`通知截图**
136 |
137 |
138 |
139 |
140 | |通知名称|通知渠道|推送方式|使用教程|
141 | |:---:|:---:|:---|:---|
142 | |[server酱](https://sct.ftqq.com)|微信(公众号)|一对一||
143 | |[BARK](https://github.com/Finb/Bark)|iOS(APP)|一对一||
144 | |[Telegram](https://core.telegram.org/bots/api)|TG(tg机器人)|一对一,一对多||
145 | |[dingtalk](https://developers.dingtalk.com/document/app/custom-robot-access)|钉钉(群聊机器人)|一对一,一对多||
146 | |[企业微信群机器人](https://work.weixin.qq.com/api/doc/90000/90136/91770)|企业微信(群聊机器人)|一对多||
147 | |[企业微信应用消息](http://note.youdao.com/s/HMiudGkb)|企业微信(类似公众号)|一对多|[查看](https://www.zc4g.cn/658.html)|
148 | |[iGot聚合](https://wahao.github.io/Bark-MP-helper)|Bark(ios),邮箱,微信|一对一,一对多||
149 | |[pushplus](http://www.pushplus.plus)|微信(公众号)|一对一||
150 | |[go-cqhttp](https://github.com/Mrs4s/go-cqhttp)|QQ(QQ机器人)|一对一,一对多||
151 | |[gotify](https://gotify.net/docs/)|自建消息推送服务(ws)|一对一,一对多||
152 |
153 |
154 |
155 |
156 |
157 |
158 | ## 🎉特别鸣谢:
159 |
160 | * [@bean661:wozaixiaoyuanjkdkql](https://github.com/bean661/wozaixiaoyuanjkdkql)
161 | * [@whyour:qinglong](https://github.com/whyour/qinglong)
162 |
163 |
164 |
165 |
166 |
--------------------------------------------------------------------------------
/对接傻妞/我在校园.js:
--------------------------------------------------------------------------------
1 | // [rule: 我在校园 ]
2 | // [disable: false] 是否禁用
3 | // [admin: false] 是否只允许管理员使用
4 |
5 |
6 | let su = []
7 | let str = ""
8 | let msg = ""
9 | let msg1 = ""
10 | let menutext = ""
11 | let j = ""
12 | let n = ""
13 | let h = ""
14 | let username=""
15 | let password=""
16 | let rjrb_answers=""
17 | let rjrb_location=""
18 | let jkdk_answers=""
19 | let jkdk_location=""
20 | let qd_location=""
21 | let mark=""
22 | let delstr = []
23 | let data = ""
24 | let getToken = ""
25 | let wzxy_disablenum = ""
26 | let wzxy_num=""
27 |
28 |
29 | var user = GetUserID()
30 | var isAdmin = isAdmin()
31 |
32 | try{
33 | var wzxy = bucketGet("wzxy", user)
34 | str=JSON.parse(wzxy)}catch(e){str=[]}
35 | try{var QL=JSON.parse(bucketGet("wzxy", `QL`))}catch(e){var QL=[]}
36 | try{var ql_host=QL[0].ql_host}catch(e){var ql_host = ``}
37 | try{var ql_client_id=QL[0].ql_client_id}catch(e){var ql_client_id=``}
38 | try{var ql_client_secret=QL[0].ql_client_secret}catch(e){var ql_client_secret=``}
39 | var ql_token=GetToken()
40 |
41 | function mian() {
42 |
43 | if (isAdmin) {
44 | sendText("请在10s内从中选择你要进行的操作:(输入“q”随时退出会话。)\n\n=======用户菜单=======\n\n1 . 账号管理\n2 . 修改密码\n3 . 教程\n\n======管理员菜单======\n\n4 . 青龙绑定"+getToken+"\n5 . 账号统计")
45 | }else{
46 | sendText("请在10s内从中选择你要进行的操作:(输入“q”随时退出会话。)\n\n=======用户菜单=======\n\n1 . 账号管理\n2 . 修改密码\n3 . 教程")
47 | }
48 |
49 |
50 | iii = input(10000)
51 | if (iii == 1) { //账号管理
52 | myaccount()
53 | return;
54 | }else if (iii == 2) { //修改密码
55 | changePassword()
56 | return;
57 | }else if (iii == 3) { //教程
58 | var jiaocheng = request({url: "https://ghproxy.com/https://github.com/zhacha222/wozaixiaoyuan/blob/main/%E5%AF%B9%E6%8E%A5%E5%82%BB%E5%A6%9E/%E6%95%99%E7%A8%8B.txt"})
59 | sendText(jiaocheng)
60 | return;
61 | }else if (iii == 4) { //青龙绑定
62 | if (isAdmin) {
63 | qinglong()
64 | return;
65 | }else {
66 | var iii = "qq"
67 | }
68 |
69 | }else if (iii == 5) { //账号统计
70 | if (isAdmin) {
71 | WZXY_NUM()
72 | return;
73 | }else {
74 | var iii = "qq"
75 | }
76 | }else {
77 | var iii = "q"
78 | }
79 |
80 | if (iii == "q" || iii == "Q" || iii == "" ) {
81 | sendText("已退出设置。")
82 | return;
83 | }else {
84 | sendText('指令错误,请重新输入:')
85 | sleep(300)
86 | return mian()
87 | }
88 | }
89 |
90 |
91 | //青龙绑定
92 | function qinglong() {
93 |
94 | WZXYQL ={"ql_host": ql_host,"ql_client_id": ql_client_id,"ql_client_secret": ql_client_secret}
95 |
96 | sendText("请选择要编辑的属性(q退出,wq保存):\n\n1 . 面板地址 -"+ql_host+`\n\n2 . ClientID -`+ql_client_id+ `\n\n3 . ClientSecret -`+ql_client_secret)
97 |
98 | msg=input()
99 | if(msg==1){
100 | sendText("请输入青龙面板地址:")
101 | ql_host = input()
102 | return qinglong()
103 | }else if(msg==2){
104 | sendText("请输入ClientID:")
105 | ql_client_id = input()
106 | return qinglong()
107 | }else if(msg==3){
108 | sendText("请输入ClientSecret:")
109 | ql_client_secret = input()
110 | return qinglong()
111 | }else if (msg == "q" || msg == "Q" || msg == "" ) {
112 | sendText("已退出设置。")
113 | return;
114 | }else if (msg == "wq" ) {
115 | QL.splice(0,1,WZXYQL)
116 | //QL.push(WZXYQL)
117 | bucketSet("wzxy", `QL`,JSON.stringify(QL))
118 | sendText("已保存")
119 | return;
120 | }else {
121 | sendText('指令错误,请重新输入:')
122 | sleep(300)
123 | menutext = ""
124 | return qinglong()
125 | }
126 |
127 | }
128 |
129 |
130 | //修改密码
131 | function changePassword() {
132 | sendText("请30秒内输入我在校园11位手机号:\n(输入“q”随时退出会话。)")
133 | var phone = input(30000)
134 |
135 | if(!phone || phone == "q" || phone == "Q"){
136 | sendText("已退出会话。")
137 | return;
138 | }
139 | var result = request({
140 | url: "https://gw.wozaixiaoyuan.com/basicinfo/mobile/login/getCode?phone=" + phone,
141 | "dataType": "json",
142 | "timeOut": 30000
143 | })
144 | if (result.code == 0) {
145 | sendText("验证码码获取成功")
146 | }
147 | else {
148 | sendText("验证码获取超时。")
149 | return;
150 | }
151 | sendText("请输入验证码:")
152 | var code = input(30000)
153 | if(!code || code == "q" || code == "Q"){
154 | sendText("已退出会话。")
155 | return;
156 | }
157 | sendText("请输入想要修改成的密码:")
158 | var newPassword = input(30000)
159 | if(!code || code == "q" || code == "Q"){
160 | sendText("已退出会话。")
161 | return;
162 | }
163 | var result1 = request({
164 | url: "https://gw.wozaixiaoyuan.com/basicinfo/mobile/login/changePassword?phone="+phone+"&code="+code+"&password="+newPassword,
165 | "dataType": "json",
166 | "timeOut": 30000
167 | })
168 |
169 | if (result1.code == 0) {
170 | sendText("密码修改成功")
171 | return;
172 | }
173 | else {
174 | sendText("密码修改失败!")
175 | return;
176 | }
177 |
178 | }
179 |
180 |
181 | //账号管理
182 | function myaccount() {
183 | //var n = str.length
184 | for (var i=0,j=1;imsg&&msg>-j){
206 |
207 | n = msg.split(`-`)[1] -1
208 | del()
209 | return myaccount()
210 |
211 | }else if (msg == "q" || msg == "Q" || msg == "" ) {
212 | sendText("已退出设置。")
213 | return;
214 | }else if (msg == "wq" ) {
215 | bucketSet("wzxy", user, JSON.stringify(str))
216 | sendText("已保存修改")
217 | post()
218 | return;
219 | }else {
220 | sendText('指令错误,请重新输入:')
221 | sleep(300)
222 | menutext = ""
223 | return myaccount()
224 | }
225 |
226 | }
227 |
228 |
229 | //添加账号
230 | function add() {
231 |
232 | data ={"username": username,"password": password,"qd_location": qd_location,"rjrb_answers":rjrb_answers,"rjrb_location": rjrb_location,"jkdk_answers": jkdk_answers,"jkdk_location": jkdk_location,"mark": mark}
233 |
234 | sendText(`请选择要编辑的属性(u返回,q退出,wq保存):` + `\n\n1. 姓名 --`+data.mark+`\n\n2. 手机号 --` +data.username+`\n\n3. 密码 --`+data.password+`\n\n4. 日检日报Answers \n-- `+data.rjrb_answers+`\n\n5. 日检日报Location \n-- `+data.rjrb_location+`\n\n6. 健康打卡Answers \n-- `+data.jkdk_answers+`\n\n7. 健康打卡Location \n-- `+data.jkdk_location+`\n\n8. 签到Location \n-- `+data.qd_location)
235 |
236 | msg1=input()
237 | if(msg1==1){
238 | sendText(`请输入姓名:`)
239 | mark=input()
240 | return add()
241 | }else if(msg1==2){
242 | sendText(`请输入手机号:`)
243 | username=input()
244 | return add()
245 | }else if(msg1==3){
246 | sendText(`请输入密码:`)
247 | password=input()
248 | return add()
249 | }else if(msg1==4){
250 | sendText(`请输入日检日报Answers:`)
251 | sendText(`正确格式示例:["0","0"]`)
252 | //bucketSet("wzxy", user, JSON.stringify(data))
253 | rjrb_answers=JSON.parse(input())
254 | return add()
255 | }else if(msg1==5){
256 | sendText(`请输入日检日报Location:`)
257 | sendText(`正确格式示例:133.333333,33.333333`)
258 | rjrb_location=input()
259 | return add()
260 | }else if(msg1==6){
261 | sendText(`请输入健康打卡Answers:`)
262 | sendText(`正确格式示例:["0","0"]`)
263 | jkdk_answers=JSON.parse(input())
264 | return add()
265 | }else if(msg1==7){
266 | sendText(`请输入健康打卡Location:`)
267 | sendText(`正确格式示例:133.333333,33.333333`)
268 | jkdk_location=input()
269 | return add()
270 | }else if(msg1==8){
271 | sendText(`请输入签到Location:`)
272 | sendText(`正确格式示例:133.333333,33.333333`)
273 | qd_location=input()
274 | return add()
275 | }else if (msg1 == "q" || msg1== "Q" || msg1 == "" ) {
276 | sendText("已退出设置。")
277 | return;
278 | }else if (msg1 == "wq" ) {
279 | str.push(data)
280 | bucketSet("wzxy", user, JSON.stringify(str))
281 | sendText("已保存修改")
282 | //sendText(JSON.stringify(bucketGet("wzxy", user)))
283 | post()
284 | return;
285 | }else if (msg1 == "u"||msg1 == "U") {
286 | str.push(data)
287 | menutext = ""
288 | username=""
289 | password=""
290 | rjrb_answers=""
291 | rjrb_location=""
292 | jkdk_answers=""
293 | jkdk_location=""
294 | qd_location=""
295 | mark=""
296 | return myaccount()
297 | }else {
298 | sendText('指令错误,请重新输入:')
299 | sleep(300)
300 | return add()
301 | }
302 |
303 |
304 | }
305 |
306 |
307 | //编辑账号
308 | function edit() {
309 |
310 | data ={"username": username,"password": password,"qd_location": qd_location,"rjrb_answers":rjrb_answers,"rjrb_location": rjrb_location,"jkdk_answers": jkdk_answers,"jkdk_location": jkdk_location,"mark": mark}
311 |
312 | sendText(`请选择要编辑的属性(u返回,q退出,wq保存):` + `\n\n1. 姓名 --`+data.mark+`\n\n2. 手机号 --` +data.username+`\n\n3. 密码 --`+data.password+`\n\n4. 日检日报Answers \n-- `+data.rjrb_answers+`\n\n5. 日检日报Location \n-- `+data.rjrb_location+`\n\n6. 健康打卡Answers \n-- `+data.jkdk_answers+`\n\n7. 健康打卡Location \n-- `+data.jkdk_location+`\n\n8. 签到Location \n-- `+data.qd_location)
313 |
314 | msg1=input()
315 | if(msg1==1){
316 | sendText(`请输入姓名:`)
317 | mark=input()
318 | return edit()
319 | }else if(msg1==2){
320 | sendText(`请输入手机号:`)
321 | username=input()
322 | return edit()
323 | }else if(msg1==3){
324 | sendText(`请输入密码:`)
325 | password=input()
326 | return edit()
327 | }else if(msg1==4){
328 | sendText(`请输入日检日报Answers:`)
329 | sendText(`正确格式示例:["0","0"]`)
330 | //bucketSet("wzxy", user, JSON.stringify(data))
331 | rjrb_answers=JSON.parse(input())
332 | return edit()
333 | }else if(msg1==5){
334 | sendText(`请输入日检日报Location:`)
335 | sendText(`正确格式示例:133.333333,33.333333`)
336 | rjrb_location=input()
337 | return edit()
338 | }else if(msg1==6){
339 | sendText(`请输入健康打卡Answers:`)
340 | sendText(`正确格式示例:["0","0"]`)
341 | jkdk_answers=JSON.parse(input())
342 | return edit()
343 | }else if(msg1==7){
344 | sendText(`请输入健康打卡Location:`)
345 | sendText(`正确格式示例:133.333333,33.333333`)
346 | jkdk_location=input()
347 | return edit()
348 | }else if(msg1==8){
349 | sendText(`请输入签到Location:`)
350 | sendText(`正确格式示例:133.333333,33.333333`)
351 | qd_location=input()
352 | return edit()
353 | }else if (msg1 == "q" || msg1== "Q" || msg1 == "" ) {
354 | sendText("已退出设置。")
355 | return;
356 | }else if (msg1 == "wq" ) {
357 | str.splice(h,1,data)
358 | bucketSet("wzxy", user, JSON.stringify(str))
359 | sendText("已保存修改")
360 | //sendText(JSON.stringify(bucketGet("wzxy", user)))
361 | post()
362 | return;
363 | }else if (msg1 == "u"||msg1 == "U") {
364 | str.splice(h,1,data)
365 | menutext = ""
366 | username=""
367 | password=""
368 | rjrb_answers=""
369 | rjrb_location=""
370 | jkdk_answers=""
371 | jkdk_location=""
372 | qd_location=""
373 | mark=""
374 | return myaccount()
375 | }else {
376 | sendText('指令错误,请重新输入:')
377 | sleep(300)
378 | return edit()
379 | }
380 |
381 |
382 | }
383 |
384 |
385 | //删除账号
386 | function del(){
387 |
388 | var del = str.splice(n,1)
389 | menutext = ""
390 | delstr.push(del[0])
391 | //sendText(delstr.length)
392 | }
393 |
394 |
395 | //上传ck
396 | function post() {
397 | try{
398 | var account= bucketGet("wzxy", user)
399 | var postdata = JSON.parse(account)
400 |
401 | //上传ck
402 | for(let k=0;k {
78 | if (typeof $request !== "undefined") {
79 | await GetRewrite();
80 | } else {
81 | if (!(await Envs()))
82 | return;
83 | else {
84 |
85 | log(`\n\n============================================= \n脚本执行 - 北京时间(UTC+8):${new Date(
86 | new Date().getTime() + new Date().getTimezoneOffset() * 60 * 1000 +
87 | 8 * 60 * 60 * 1000).toLocaleString()} \n=============================================\n`);
88 |
89 | await poem();
90 | await getVersion();
91 |
92 | log(`\n============ 当前版本:${scriptVersion} 最新版本:${scriptVersionLatest} ============`)
93 |
94 | if(scriptVersionLatest != scriptVersion){
95 | log(`\n发现新版本,请及时拉库更新!\n${update_data}`)
96 | }
97 |
98 | log(`\n=================== 共找到 ${wzxyArr.length} 个账号 ===================`)
99 |
100 |
101 | for (let index = 0; index < wzxyArr.length; index++) {
102 |
103 | let num = index + 1
104 | if (num >1 && wait == 0){
105 | log('**********休息10s,防止黑IP**********');
106 | await $.wait(10 * 1000);
107 | }
108 | log(`\n========= 开始【第 ${num} 个账号】=========\n`)
109 | data = wzxyArr[index];
110 | content = JSON.parse(data)
111 | username = content.username
112 | password = content.password
113 | mark = content.mark
114 | log(`返校用户:${mark}`)
115 | loginBack = 0;
116 |
117 | log('开始检查jwsession是否存在...');
118 | await checkJwsession()
119 | await $.wait(2 * 1000);
120 |
121 | if (loginBack > 0) {
122 | PunchInback = 0//重置上个账号的状态码
123 | log('开始获取报备列表...');
124 | await PunchIn()
125 | await $.wait(2 * 1000);
126 |
127 | if (PunchInback>0) {
128 | log('开始报备返校...');
129 | await doPunchIn()
130 | await $.wait(2 * 1000);
131 | }
132 | }
133 | var resultlog = getResult()
134 |
135 | if (OnlyfaxiaoNotify>0){
136 | if (status_code == 1 ){
137 | msg += `返校用户:${mark}\n返校情况:${resultlog}\n\n`
138 | }
139 | }else {
140 | msg += `返校用户:${mark}\n返校情况:${resultlog}\n\n`
141 | }
142 |
143 | }
144 |
145 | // log(msg);
146 | await SendMsg(msg);
147 | }
148 | }
149 |
150 | })()
151 | .catch((e) => log(e))
152 | .finally(() => $.done())
153 |
154 |
155 |
156 | /**
157 | * 判断jwsession是否存在
158 | */
159 | function checkJwsession() {
160 |
161 | fs.open('.cache/' + username + ".json", 'r+', function(err, fd) {
162 | if (err) {
163 | console.error("找不到cache文件,正在使用账号信息登录...")
164 | login()
165 | return
166 | }
167 | console.log("找到cache文件,正在使用jwsession返校...")
168 | var read = fs.readFileSync('.cache/' + username + ".json")
169 | jwsession = read.toString()
170 | loginBack = 1
171 |
172 | });
173 |
174 | }
175 |
176 |
177 | /**
178 | * 登录
179 | */
180 | function login(timeout = 3 * 1000) {
181 | return new Promise((resolve) => {
182 | let url = {
183 | url: `https://gw.wozaixiaoyuan.com/basicinfo/mobile/login/username?username=${username}&password=${password}`,
184 | headers: {
185 | "Accept-Encoding": "gzip, deflate, br",
186 | "Connection": "keep-alive",
187 | "User-Agent": "Mozilla/5.0 (iPad; CPU OS 15_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.23(0x1800172f) NetType/WIFI Language/zh_CN miniProgram/wxce6d08f781975d91",
188 | "content-type": "application/json;charset=UTF-8",
189 | "Content-Length": "2",
190 | "Host": "gw.wozaixiaoyuan.com",
191 | "Accept-Language": "en-us,en",
192 | "Accept": "application/json, text/plain, */*"
193 | },
194 | data: ``,
195 | }
196 |
197 |
198 | request.post(url, async (error, response, data) => {
199 | try {
200 | let result = data == "undefined" ? await login() : JSON.parse(data);
201 |
202 | //登录成功
203 | if (result.code == 0 ) {
204 |
205 | jwsession = response.headers['jwsession']
206 | //储存jwsession
207 | setJwsession(jwsession)
208 | loginBack = 1;
209 | log(`登录成功`)
210 |
211 | } else {
212 | log(`❌ 登录失败,${result.message}`)
213 | status_code = 5;
214 | loginBack = 0;
215 | }
216 |
217 | } catch (e) {
218 | log(e)
219 | } finally {
220 | resolve();
221 | }
222 | }, timeout)
223 | })
224 | }
225 |
226 |
227 | /**
228 | * 存储jwsession
229 | */
230 | function setJwsession(jwsession) {
231 |
232 | fs.mkdir('.cache',function(err){
233 | if (err) {
234 |
235 | console.log("找到cache文件");
236 | }
237 | else console.log("正在创建cache储存目录与文件...");
238 | });
239 |
240 | fs.writeFile('.cache/' + username + ".json", jwsession, function(err) {
241 | if (err) {
242 | return console.error(err);
243 | }
244 | console.log("更新jwsession成功");
245 | })
246 |
247 | }
248 |
249 |
250 | /**
251 | * 获取报备列表
252 | */
253 | function PunchIn(timeout = 3 * 1000) {
254 | return new Promise((resolve) => {
255 |
256 | let url = {
257 | url: "https://gw.wozaixiaoyuan.com/out/mobile/out/getOne",
258 | headers: {
259 | 'jwsession': jwsession,
260 | 'Content-Type': 'application/json'
261 | },
262 | body: ``
263 | }
264 |
265 | $.post(url, async (error, response, data) => {
266 | //log(data)
267 | try {
268 | let result = data == "undefined" ? await PunchIn() : JSON.parse(data);
269 | if (result.code == 103) {
270 | log('jwsession 无效,尝试账号密码登录...')
271 | status_code = 4;
272 | PunchInback = 0;
273 | loginBack = 0;
274 | await login()
275 | await $.wait(2 * 1000);
276 | if (loginBack > 0) {
277 | log('重新获取报备列表...');
278 | await PunchIn()
279 | await $.wait(2 * 1000)
280 | return
281 | }
282 | }
283 | if (result.code == 0) {
284 | id = result.data.id
285 | endDatetime =result.data.endDatetime
286 | state =result.data.state //state为2表示未返校,为5表示已返校,为4表示当前已超过返校时间
287 | //log(state)
288 | if (state==5){
289 | log('🈚️ 暂无返校任务,跳过返校...')
290 | wait = 1
291 | status_code = 2
292 | PunchInback = 0
293 | }else if(state==2){
294 | log("✅ 找到未返校任务,开始返校...")
295 | PunchInback = 1
296 | wait=0
297 | }else if(state==4){
298 | log("⚠️当前已超过返校时间,开始返校...")
299 | PunchInback = 1
300 | wait=0
301 | }
302 |
303 | }
304 | if (result.code != 0) {
305 | log(`获取失败,原因:${error}`)
306 | PunchInback = 0
307 | }
308 |
309 | } catch (e) {
310 | log(e)
311 | } finally {
312 | resolve();
313 | }
314 | }, timeout)
315 | })
316 | }
317 |
318 |
319 | /**
320 | * 开始返校
321 | */
322 | function doPunchIn(timeout = 3 * 1000) {
323 | return new Promise((resolve) => {
324 | let url = {
325 | url: `https://gw.wozaixiaoyuan.com/out/mobile/out/back?id=${id}`,
326 | headers: {
327 | 'jwsession': jwsession,
328 | 'Content-Type': 'application/json'
329 | },
330 | body: ``,
331 |
332 | }
333 |
334 | $.post(url, async (error, response, data) => {
335 |
336 | try {
337 | let result = data == "undefined" ? await doPunchIn() : JSON.parse(data);
338 |
339 | //返校情况
340 | if (result.code == 0){
341 | log("✅ 返校成功")
342 | status_code = 1
343 | } else{
344 | log("❌ 返校失败")
345 | status_code = 0
346 | }
347 |
348 | } catch (e) {
349 | log(e)
350 | } finally {
351 | resolve();
352 | }
353 | }, timeout)
354 | })
355 | }
356 |
357 |
358 | /**
359 | * 获取返校结果
360 | */
361 | function getResult(timeout = 3 * 1000) {
362 | res = status_code
363 | if (res == 1) return "✅ 返校成功"
364 | if (res == 2) return "🈚️ 当前无返校任务"
365 | if (res == 3) return "❌ 返校失败,当前不在返校时间段内"
366 | if (res == 4) return "❌ 返校失败,jwsession 无效"
367 | if (res == 5) return "❌ 返校失败,登录错误,请检查账号信息"
368 | else return "❌ 返校失败,发生未知错误"
369 | }
370 |
371 |
372 | // ============================================变量检查============================================ \\
373 | async function Envs() {
374 | if (wzxy) {
375 | if (wzxy.indexOf("@") != -1 || wzxy.indexOf("&") != -1) {
376 | wzxy.split("@"&&"&").forEach((item) => {
377 | wzxyArr.push(item);
378 | });
379 | }
380 | // else if (wzxy.indexOf("\n") != -1) {
381 | // wzxy.split("\n").forEach((item) => {
382 | // wzxyArr.push(item);
383 | // });
384 | // }
385 | else {
386 | wzxyArr.push(wzxy);
387 | }
388 | } else {
389 | log(`\n 未填写变量 wzxy`)
390 | return;
391 | }
392 |
393 | return true;
394 | }
395 | // ============================================发送消息============================================ \\
396 | async function SendMsg(msg) {
397 | if (!msg)
398 | return;
399 |
400 | if (Notify > 0) {
401 | if ($.isNode()) {
402 | var notify = require('./sendNotify');
403 | await notify.sendNotify($.name, msg+ `\n执行时间:${t()}\n`);
404 | } else {
405 | $.msg(msg);
406 | }
407 | } else {
408 | log(msg);
409 | }
410 | }
411 |
412 | /**
413 | * 随机数生成
414 | */
415 | function randomString(e) {
416 | e = e || 32;
417 | var t = "QWERTYUIOPASDFGHJKLZXCVBNM1234567890",
418 | a = t.length,
419 | n = "";
420 | for (i = 0; i < e; i++)
421 | n += t.charAt(Math.floor(Math.random() * a));
422 | return n
423 | }
424 |
425 | /**
426 | * 随机整数生成
427 | */
428 | function randomInt(min, max) {
429 | return Math.round(Math.random() * (max - min) + min)
430 | }
431 |
432 | /**
433 | * 获取毫秒时间戳
434 | */
435 | function timestampMs(){
436 | return new Date().getTime();
437 | }
438 |
439 | /**
440 | *
441 | * 获取秒时间戳
442 | */
443 | function timestampS(){
444 | return Date.parse(new Date())/1000;
445 | }
446 |
447 | /**
448 | * 获取随机诗词
449 | */
450 | function poem(timeout = 3 * 1000) {
451 | return new Promise((resolve) => {
452 | let url = {
453 | url: `https://v1.jinrishici.com/all.json`
454 | }
455 | $.get(url, async (err, resp, data) => {
456 | try {
457 | data = JSON.parse(data)
458 | log(`${data.content} \n————《${data.origin}》${data.author}`);
459 | } catch (e) {
460 | log(e, resp);
461 | } finally {
462 | resolve()
463 | }
464 | }, timeout)
465 | })
466 | }
467 |
468 | /**
469 | * 修改配置文件
470 | */
471 | function modify() {
472 |
473 | fs.readFile('/ql/data/config/config.sh','utf8',function(err,dataStr){
474 | if(err){
475 | return log('读取文件失败!'+err)
476 | }
477 | else {
478 | var result = dataStr.replace(/regular/g,string);
479 | fs.writeFile('/ql/data/config/config.sh', result, 'utf8', function (err) {
480 | if (err) {return log(err);}
481 | });
482 | }
483 | })
484 | }
485 |
486 | /**
487 | * 获取远程版本
488 | */
489 | function getVersion(timeout = 3 * 1000) {
490 | return new Promise((resolve) => {
491 | let url = {
492 | url: `https://ghproxy.com/https://raw.githubusercontent.com/zhacha222/wozaixiaoyuan/main/wzxy_bbfx.js`,
493 | }
494 | $.get(url, async (err, resp, data) => {
495 | try {
496 | scriptVersionLatest = data.match(/scriptVersion = "([\d\.]+)"/)[1]
497 | update_data = data.match(/update_data = "(.*?)"/)[1]
498 | } catch (e) {
499 | $.logErr(e, resp);
500 | } finally {
501 | resolve()
502 | }
503 | }, timeout)
504 | })
505 | }
506 |
507 | /**
508 | * time 输出格式:1970-01-01 00:00:00
509 | */
510 | function t() {
511 | var date = new Date();
512 | // 获取当前月份
513 | var nowMonth = date.getMonth() + 1;
514 | // 获取当前是几号
515 | var strDate = date.getDate();
516 | //获取当前小时(0-23)
517 | var nowhour = date.getHours()
518 | //获取当前分钟(0-59)
519 | var nowMinute = date.getMinutes()
520 | //获取当前秒数(0-59)
521 | var nowSecond = date.getSeconds();
522 | // 添加分隔符“-”
523 | var seperator = "-";
524 | // 添加分隔符“:”
525 | var seperator1 = ":";
526 |
527 | // 对月份进行处理,1-9月在前面添加一个“0”
528 | if (nowMonth >= 1 && nowMonth <= 9) {
529 | nowMonth = "0" + nowMonth;
530 | }
531 | // 对月份进行处理,1-9号在前面添加一个“0”
532 | if (strDate >= 0 && strDate <= 9) {
533 | strDate = "0" + strDate;
534 | }
535 | // 对小时进行处理,0-9号在前面添加一个“0”
536 | if (nowhour >= 0 && nowhour <= 9) {
537 | nowhour = "0" + nowhour;
538 | }
539 | // 对分钟进行处理,0-9号在前面添加一个“0”
540 | if (nowMinute >= 0 && nowMinute <= 9) {
541 | nowMinute = "0" + nowMinute;
542 | }
543 | // 对秒数进行处理,0-9号在前面添加一个“0”
544 | if (nowSecond >= 0 && nowSecond <= 9) {
545 | nowSecond = "0" + nowSecond;
546 | }
547 |
548 | // 最后拼接字符串,得到一个格式为(yyyy-MM-dd)的日期
549 | var nowDate = date.getFullYear() + seperator + nowMonth + seperator + strDate + ` ` + nowhour + seperator1 + nowMinute + seperator1 + nowSecond
550 | return nowDate
551 | }
552 |
553 | function Env(t, e) {
554 | "undefined" != typeof process && JSON.stringify(process.env).indexOf("GITHUB") > -1 && process.exit(0);
555 | class s {
556 | constructor(t) {
557 | this.env = t
558 | }
559 | send(t, e = "GET") {
560 | t = "string" == typeof t ? {
561 | url: t
562 | } : t;
563 | let s = this.get;
564 | return "POST" === e && (s = this.post), new Promise((e, i) => {
565 | s.call(this, t, (t, s, r) => {
566 | t ? i(t) : e(s)
567 | })
568 | })
569 | }
570 | get(t) {
571 | return this.send.call(this.env, t)
572 | }
573 | post(t) {
574 | return this.send.call(this.env, t, "POST")
575 | }
576 | }
577 | return new class {
578 | constructor(t, e) {
579 | this.name = t, this.http = new s(this), this.data = null, this.dataFile = "box.dat", this.logs = [], this.isMute = !1, this.isNeedRewrite = !1, this.logSeparator = "\n", this.startTime = (new Date).getTime(), Object.assign(this, e), this.log("", `🔔${this.name}, 开始!`)
580 | }
581 | isNode() {
582 | return "undefined" != typeof module && !!module.exports
583 | }
584 | isQuanX() {
585 | return "undefined" != typeof $task
586 | }
587 | isSurge() {
588 | return "undefined" != typeof $httpClient && "undefined" == typeof $loon
589 | }
590 | isLoon() {
591 | return "undefined" != typeof $loon
592 | }
593 | toObj(t, e = null) {
594 | try {
595 | return JSON.parse(t)
596 | } catch {
597 | return e
598 | }
599 | }
600 | toStr(t, e = null) {
601 | try {
602 | return JSON.stringify(t)
603 | } catch {
604 | return e
605 | }
606 | }
607 | getjson(t, e) {
608 | let s = e;
609 | const i = this.getdata(t);
610 | if (i) try {
611 | s = JSON.parse(this.getdata(t))
612 | } catch {}
613 | return s
614 | }
615 | setjson(t, e) {
616 | try {
617 | return this.setdata(JSON.stringify(t), e)
618 | } catch {
619 | return !1
620 | }
621 | }
622 | getScript(t) {
623 | return new Promise(e => {
624 | this.get({
625 | url: t
626 | }, (t, s, i) => e(i))
627 | })
628 | }
629 | runScript(t, e) {
630 | return new Promise(s => {
631 | let i = this.getdata("@chavy_boxjs_userCfgs.httpapi");
632 | i = i ? i.replace(/\n/g, "").trim() : i;
633 | let r = this.getdata("@chavy_boxjs_userCfgs.httpapi_timeout");
634 | r = r ? 1 * r : 20, r = e && e.timeout ? e.timeout : r;
635 | const [o, h] = i.split("@"), n = {
636 | url: `http://${h}/v1/scripting/evaluate`,
637 | body: {
638 | script_text: t,
639 | mock_type: "cron",
640 | timeout: r
641 | },
642 | headers: {
643 | "X-Key": o,
644 | Accept: "*/*"
645 | }
646 | };
647 | this.post(n, (t, e, i) => s(i))
648 | }).catch(t => this.logErr(t))
649 | }
650 | loaddata() {
651 | if (!this.isNode()) return {}; {
652 | this.fs = this.fs ? this.fs : require("fs"), this.path = this.path ? this.path : require("path");
653 | const t = this.path.resolve(this.dataFile),
654 | e = this.path.resolve(process.cwd(), this.dataFile),
655 | s = this.fs.existsSync(t),
656 | i = !s && this.fs.existsSync(e);
657 | if (!s && !i) return {}; {
658 | const i = s ? t : e;
659 | try {
660 | return JSON.parse(this.fs.readFileSync(i))
661 | } catch (t) {
662 | return {}
663 | }
664 | }
665 | }
666 | }
667 | writedata() {
668 | if (this.isNode()) {
669 | this.fs = this.fs ? this.fs : require("fs"), this.path = this.path ? this.path : require("path");
670 | const t = this.path.resolve(this.dataFile),
671 | e = this.path.resolve(process.cwd(), this.dataFile),
672 | s = this.fs.existsSync(t),
673 | i = !s && this.fs.existsSync(e),
674 | r = JSON.stringify(this.data);
675 | s ? this.fs.writeFileSync(t, r) : i ? this.fs.writeFileSync(e, r) : this.fs.writeFileSync(t, r)
676 | }
677 | }
678 | lodash_get(t, e, s) {
679 | const i = e.replace(/\[(\d+)\]/g, ".$1").split(".");
680 | let r = t;
681 | for (const t of i)
682 | if (r = Object(r)[t], void 0 === r) return s;
683 | return r
684 | }
685 | lodash_set(t, e, s) {
686 | return Object(t) !== t ? t : (Array.isArray(e) || (e = e.toString().match(/[^.[\]]+/g) || []), e.slice(0, -1).reduce((t, s, i) => Object(t[s]) === t[s] ? t[s] : t[s] = Math.abs(e[i + 1]) >> 0 == +e[i + 1] ? [] : {}, t)[e[e.length - 1]] = s, t)
687 | }
688 | getdata(t) {
689 | let e = this.getval(t);
690 | if (/^@/.test(t)) {
691 | const [, s, i] = /^@(.*?)\.(.*?)$/.exec(t), r = s ? this.getval(s) : "";
692 | if (r) try {
693 | const t = JSON.parse(r);
694 | e = t ? this.lodash_get(t, i, "") : e
695 | } catch (t) {
696 | e = ""
697 | }
698 | }
699 | return e
700 | }
701 | setdata(t, e) {
702 | let s = !1;
703 | if (/^@/.test(e)) {
704 | const [, i, r] = /^@(.*?)\.(.*?)$/.exec(e), o = this.getval(i), h = i ? "null" === o ? null : o || "{}" : "{}";
705 | try {
706 | const e = JSON.parse(h);
707 | this.lodash_set(e, r, t), s = this.setval(JSON.stringify(e), i)
708 | } catch (e) {
709 | const o = {};
710 | this.lodash_set(o, r, t), s = this.setval(JSON.stringify(o), i)
711 | }
712 | } else s = this.setval(t, e);
713 | return s
714 | }
715 | getval(t) {
716 | return this.isSurge() || this.isLoon() ? $persistentStore.read(t) : this.isQuanX() ? $prefs.valueForKey(t) : this.isNode() ? (this.data = this.loaddata(), this.data[t]) : this.data && this.data[t] || null
717 | }
718 | setval(t, e) {
719 | return this.isSurge() || this.isLoon() ? $persistentStore.write(t, e) : this.isQuanX() ? $prefs.setValueForKey(t, e) : this.isNode() ? (this.data = this.loaddata(), this.data[e] = t, this.writedata(), !0) : this.data && this.data[e] || null
720 | }
721 | initGotEnv(t) {
722 | this.got = this.got ? this.got : require("got"), this.cktough = this.cktough ? this.cktough : require("tough-cookie"), this.ckjar = this.ckjar ? this.ckjar : new this.cktough.CookieJar, t && (t.headers = t.headers ? t.headers : {}, void 0 === t.headers.Cookie && void 0 === t.cookieJar && (t.cookieJar = this.ckjar))
723 | }
724 | get(t, e = (() => {})) {
725 | t.headers && (delete t.headers["Content-Type"], delete t.headers["Content-Length"]), this.isSurge() || this.isLoon() ? (this.isSurge() && this.isNeedRewrite && (t.headers = t.headers || {}, Object.assign(t.headers, {
726 | "X-Surge-Skip-Scripting": !1
727 | })), $httpClient.get(t, (t, s, i) => {
728 | !t && s && (s.body = i, s.statusCode = s.status), e(t, s, i)
729 | })) : this.isQuanX() ? (this.isNeedRewrite && (t.opts = t.opts || {}, Object.assign(t.opts, {
730 | hints: !1
731 | })), $task.fetch(t).then(t => {
732 | const {
733 | statusCode: s,
734 | statusCode: i,
735 | headers: r,
736 | body: o
737 | } = t;
738 | e(null, {
739 | status: s,
740 | statusCode: i,
741 | headers: r,
742 | body: o
743 | }, o)
744 | }, t => e(t))) : this.isNode() && (this.initGotEnv(t), this.got(t).on("redirect", (t, e) => {
745 | try {
746 | if (t.headers["set-cookie"]) {
747 | const s = t.headers["set-cookie"].map(this.cktough.Cookie.parse).toString();
748 | s && this.ckjar.setCookieSync(s, null), e.cookieJar = this.ckjar
749 | }
750 | } catch (t) {
751 | this.logErr(t)
752 | }
753 | }).then(t => {
754 | const {
755 | statusCode: s,
756 | statusCode: i,
757 | headers: r,
758 | body: o
759 | } = t;
760 | e(null, {
761 | status: s,
762 | statusCode: i,
763 | headers: r,
764 | body: o
765 | }, o)
766 | }, t => {
767 | const {
768 | message: s,
769 | response: i
770 | } = t;
771 | e(s, i, i && i.body)
772 | }))
773 | }
774 | post(t, e = (() => {})) {
775 | if (t.body && t.headers && !t.headers["Content-Type"] && (t.headers["Content-Type"] = "application/x-www-form-urlencoded"), t.headers && delete t.headers["Content-Length"], this.isSurge() || this.isLoon()) this.isSurge() && this.isNeedRewrite && (t.headers = t.headers || {}, Object.assign(t.headers, {
776 | "X-Surge-Skip-Scripting": !1
777 | })), $httpClient.post(t, (t, s, i) => {
778 | !t && s && (s.body = i, s.statusCode = s.status), e(t, s, i)
779 | });
780 | else if (this.isQuanX()) t.method = "POST", this.isNeedRewrite && (t.opts = t.opts || {}, Object.assign(t.opts, {
781 | hints: !1
782 | })), $task.fetch(t).then(t => {
783 | const {
784 | statusCode: s,
785 | statusCode: i,
786 | headers: r,
787 | body: o
788 | } = t;
789 | e(null, {
790 | status: s,
791 | statusCode: i,
792 | headers: r,
793 | body: o
794 | }, o)
795 | }, t => e(t));
796 | else if (this.isNode()) {
797 | this.initGotEnv(t);
798 | const {
799 | url: s,
800 | ...i
801 | } = t;
802 | this.got.post(s, i).then(t => {
803 | const {
804 | statusCode: s,
805 | statusCode: i,
806 | headers: r,
807 | body: o
808 | } = t;
809 | e(null, {
810 | status: s,
811 | statusCode: i,
812 | headers: r,
813 | body: o
814 | }, o)
815 | }, t => {
816 | const {
817 | message: s,
818 | response: i
819 | } = t;
820 | e(s, i, i && i.body)
821 | })
822 | }
823 | }
824 | time(t, e = null) {
825 | const s = e ? new Date(e) : new Date;
826 | let i = {
827 | "M+": s.getMonth() + 1,
828 | "d+": s.getDate(),
829 | "H+": s.getHours(),
830 | "m+": s.getMinutes(),
831 | "s+": s.getSeconds(),
832 | "q+": Math.floor((s.getMonth() + 3) / 3),
833 | S: s.getMilliseconds()
834 | };
835 | /(y+)/.test(t) && (t = t.replace(RegExp.$1, (s.getFullYear() + "").substr(4 - RegExp.$1.length)));
836 | for (let e in i) new RegExp("(" + e + ")").test(t) && (t = t.replace(RegExp.$1, 1 == RegExp.$1.length ? i[e] : ("00" + i[e]).substr(("" + i[e]).length)));
837 | return t
838 | }
839 | msg(e = t, s = "", i = "", r) {
840 | const o = t => {
841 | if (!t) return t;
842 | if ("string" == typeof t) return this.isLoon() ? t : this.isQuanX() ? {
843 | "open-url": t
844 | } : this.isSurge() ? {
845 | url: t
846 | } : void 0;
847 | if ("object" == typeof t) {
848 | if (this.isLoon()) {
849 | let e = t.openUrl || t.url || t["open-url"],
850 | s = t.mediaUrl || t["media-url"];
851 | return {
852 | openUrl: e,
853 | mediaUrl: s
854 | }
855 | }
856 | if (this.isQuanX()) {
857 | let e = t["open-url"] || t.url || t.openUrl,
858 | s = t["media-url"] || t.mediaUrl;
859 | return {
860 | "open-url": e,
861 | "media-url": s
862 | }
863 | }
864 | if (this.isSurge()) {
865 | let e = t.url || t.openUrl || t["open-url"];
866 | return {
867 | url: e
868 | }
869 | }
870 | }
871 | };
872 | if (this.isMute || (this.isSurge() || this.isLoon() ? $notification.post(e, s, i, o(r)) : this.isQuanX() && $notify(e, s, i, o(r))), !this.isMuteLog) {
873 | let t = ["", "==============📣系统通知📣=============="];
874 | t.push(e), s && t.push(s), i && t.push(i), console.log(t.join("\n")), this.logs = this.logs.concat(t)
875 | }
876 | }
877 | log(...t) {
878 | t.length > 0 && (this.logs = [...this.logs, ...t]), console.log(t.join(this.logSeparator))
879 | }
880 | logErr(t, e) {
881 | const s = !this.isSurge() && !this.isQuanX() && !this.isLoon();
882 | s ? this.log("", `❗️${this.name}, 错误!`, t.stack) : this.log("", `❗️${this.name}, 错误!`, t)
883 | }
884 | wait(t) {
885 | return new Promise(e => setTimeout(e, t))
886 | }
887 | done(t = {}) {
888 | const e = (new Date).getTime(),
889 | s = (e - this.startTime) / 1e3;
890 | this.log("", `🔔${this.name}, 结束! 🕛 ${s} 秒`), this.log(), (this.isSurge() || this.isQuanX() || this.isLoon()) && $done(t)
891 | }
892 | }(t, e)
893 | }
894 |
--------------------------------------------------------------------------------
/sendNotify.js:
--------------------------------------------------------------------------------
1 | /*
2 | * @Author: lxk0301 https://gitee.com/lxk0301
3 | * @Date: 2020-08-19 16:12:40
4 | * @Last Modified by: whyour
5 | * @Last Modified time: 2021-5-1 15:00:54
6 | * sendNotify 推送通知功能
7 | * @param text 通知头
8 | * @param desp 通知体
9 | * @param params 某些推送通知方式点击弹窗可跳转, 例:{ url: 'https://abc.com' }
10 | * @param author 作者仓库等信息 例:`本通知 By:https://github.com/whyour/qinglong`
11 | */
12 |
13 | const querystring = require('querystring');
14 | const $ = new Env();
15 | const timeout = 15000; //超时时间(单位毫秒)
16 | // =======================================gotify通知设置区域==============================================
17 | //gotify_url 填写gotify地址,如https://push.example.de:8080
18 | //gotify_token 填写gotify的消息应用token
19 | //gotify_priority 填写推送消息优先级,默认为0
20 | let GOTIFY_URL = '';
21 | let GOTIFY_TOKEN = '';
22 | let GOTIFY_PRIORITY = 0;
23 | // =======================================go-cqhttp通知设置区域===========================================
24 | //gobot_url 填写请求地址http://127.0.0.1/send_private_msg
25 | //gobot_token 填写在go-cqhttp文件设置的访问密钥
26 | //gobot_qq 填写推送到个人QQ或者QQ群号
27 | //go-cqhttp相关API https://docs.go-cqhttp.org/api
28 | let GOBOT_URL = ''; // 推送到个人QQ: http://127.0.0.1/send_private_msg 群:http://127.0.0.1/send_group_msg
29 | let GOBOT_TOKEN = ''; //访问密钥
30 | let GOBOT_QQ = ''; // 如果GOBOT_URL设置 /send_private_msg 则需要填入 user_id=个人QQ 相反如果是 /send_group_msg 则需要填入 group_id=QQ群
31 |
32 | // =======================================微信server酱通知设置区域===========================================
33 | //此处填你申请的SCKEY.
34 | //(环境变量名 PUSH_KEY)
35 | let SCKEY = '';
36 |
37 | // =======================================Bark App通知设置区域===========================================
38 | //此处填你BarkAPP的信息(IP/设备码,例如:https://api.day.app/XXXXXXXX)
39 | let BARK_PUSH = '';
40 | //BARK app推送铃声,铃声列表去APP查看复制填写
41 | let BARK_SOUND = '';
42 | //BARK app推送消息的分组, 默认为"QingLong"
43 | let BARK_GROUP = 'QingLong';
44 |
45 | // =======================================telegram机器人通知设置区域===========================================
46 | //此处填你telegram bot 的Token,telegram机器人通知推送必填项.例如:1077xxx4424:AAFjv0FcqxxxxxxgEMGfi22B4yh15R5uw
47 | //(环境变量名 TG_BOT_TOKEN)
48 | let TG_BOT_TOKEN = '';
49 | //此处填你接收通知消息的telegram用户的id,telegram机器人通知推送必填项.例如:129xxx206
50 | //(环境变量名 TG_USER_ID)
51 | let TG_USER_ID = '';
52 | //tg推送HTTP代理设置(不懂可忽略,telegram机器人通知推送功能中非必填)
53 | let TG_PROXY_HOST = ''; //例如:127.0.0.1(环境变量名:TG_PROXY_HOST)
54 | let TG_PROXY_PORT = ''; //例如:1080(环境变量名:TG_PROXY_PORT)
55 | let TG_PROXY_AUTH = ''; //tg代理配置认证参数
56 | //Telegram api自建的反向代理地址(不懂可忽略,telegram机器人通知推送功能中非必填),默认tg官方api(环境变量名:TG_API_HOST)
57 | let TG_API_HOST = 'api.telegram.org';
58 | // =======================================钉钉机器人通知设置区域===========================================
59 | //此处填你钉钉 bot 的webhook,例如:5a544165465465645d0f31dca676e7bd07415asdasd
60 | //(环境变量名 DD_BOT_TOKEN)
61 | let DD_BOT_TOKEN = '';
62 | //密钥,机器人安全设置页面,加签一栏下面显示的SEC开头的字符串
63 | let DD_BOT_SECRET = '';
64 |
65 | // =======================================企业微信机器人通知设置区域===========================================
66 | //此处填你企业微信机器人的 webhook(详见文档 https://work.weixin.qq.com/api/doc/90000/90136/91770),例如:693a91f6-7xxx-4bc4-97a0-0ec2sifa5aaa
67 | //(环境变量名 QYWX_KEY)
68 | let QYWX_KEY = '';
69 |
70 | // =======================================企业微信应用消息通知设置区域===========================================
71 | /*
72 | 此处填你企业微信应用消息的值(详见文档 https://work.weixin.qq.com/api/doc/90000/90135/90236)
73 | 环境变量名 QYWX_AM依次填入 corpid,corpsecret,touser(注:多个成员ID使用|隔开),agentid,消息类型(选填,不填默认文本消息类型)
74 | 注意用,号隔开(英文输入法的逗号),例如:wwcff56746d9adwers,B-791548lnzXBE6_BWfxdf3kSTMJr9vFEPKAbh6WERQ,mingcheng,1000001,2COXgjH2UIfERF2zxrtUOKgQ9XklUqMdGSWLBoW_lSDAdafat
75 | 可选推送消息类型(推荐使用图文消息(mpnews)):
76 | - 文本卡片消息: 0 (数字零)
77 | - 文本消息: 1 (数字一)
78 | - 图文消息(mpnews): 素材库图片id, 可查看此教程(http://note.youdao.com/s/HMiudGkb)或者(https://note.youdao.com/ynoteshare1/index.html?id=1a0c8aff284ad28cbd011b29b3ad0191&type=note)
79 | */
80 | let QYWX_AM = '';
81 |
82 | // =======================================iGot聚合推送通知设置区域===========================================
83 | //此处填您iGot的信息(推送key,例如:https://push.hellyw.com/XXXXXXXX)
84 | let IGOT_PUSH_KEY = '';
85 |
86 | // =======================================push+设置区域=======================================
87 | //官方文档:http://www.pushplus.plus/
88 | //PUSH_PLUS_TOKEN:微信扫码登录后一对一推送或一对多推送下面的token(您的Token),不提供PUSH_PLUS_USER则默认为一对一推送
89 | //PUSH_PLUS_USER: 一对多推送的“群组编码”(一对多推送下面->您的群组(如无则新建)->群组编码,如果您是创建群组人。也需点击“查看二维码”扫描绑定,否则不能接受群组消息推送)
90 | let PUSH_PLUS_TOKEN = '';
91 | let PUSH_PLUS_USER = '';
92 |
93 | //==========================云端环境变量的判断与接收=========================
94 | if (process.env.GOTIFY_URL) {
95 | GOTIFY_URL = process.env.GOTIFY_URL;
96 | }
97 | if (process.env.GOTIFY_TOKEN) {
98 | GOTIFY_TOKEN = process.env.GOTIFY_TOKEN;
99 | }
100 | if (process.env.GOTIFY_PRIORITY) {
101 | GOTIFY_PRIORITY = process.env.GOTIFY_PRIORITY;
102 | }
103 |
104 | if (process.env.GOBOT_URL) {
105 | GOBOT_URL = process.env.GOBOT_URL;
106 | }
107 | if (process.env.GOBOT_TOKEN) {
108 | GOBOT_TOKEN = process.env.GOBOT_TOKEN;
109 | }
110 | if (process.env.GOBOT_QQ) {
111 | GOBOT_QQ = process.env.GOBOT_QQ;
112 | }
113 |
114 | if (process.env.PUSH_KEY) {
115 | SCKEY = process.env.PUSH_KEY;
116 | }
117 |
118 | if (process.env.QQ_SKEY) {
119 | QQ_SKEY = process.env.QQ_SKEY;
120 | }
121 |
122 | if (process.env.QQ_MODE) {
123 | QQ_MODE = process.env.QQ_MODE;
124 | }
125 |
126 | if (process.env.BARK_PUSH) {
127 | if (
128 | process.env.BARK_PUSH.indexOf('https') > -1 ||
129 | process.env.BARK_PUSH.indexOf('http') > -1
130 | ) {
131 | //兼容BARK自建用户
132 | BARK_PUSH = process.env.BARK_PUSH;
133 | } else {
134 | BARK_PUSH = `https://api.day.app/${process.env.BARK_PUSH}`;
135 | }
136 | if (process.env.BARK_SOUND) {
137 | BARK_SOUND = process.env.BARK_SOUND;
138 | }
139 | if (process.env.BARK_GROUP) {
140 | BARK_GROUP = process.env.BARK_GROUP;
141 | }
142 | } else {
143 | if (
144 | BARK_PUSH &&
145 | BARK_PUSH.indexOf('https') === -1 &&
146 | BARK_PUSH.indexOf('http') === -1
147 | ) {
148 | //兼容BARK本地用户只填写设备码的情况
149 | BARK_PUSH = `https://api.day.app/${BARK_PUSH}`;
150 | }
151 | }
152 | if (process.env.TG_BOT_TOKEN) {
153 | TG_BOT_TOKEN = process.env.TG_BOT_TOKEN;
154 | }
155 | if (process.env.TG_USER_ID) {
156 | TG_USER_ID = process.env.TG_USER_ID;
157 | }
158 | if (process.env.TG_PROXY_AUTH) TG_PROXY_AUTH = process.env.TG_PROXY_AUTH;
159 | if (process.env.TG_PROXY_HOST) TG_PROXY_HOST = process.env.TG_PROXY_HOST;
160 | if (process.env.TG_PROXY_PORT) TG_PROXY_PORT = process.env.TG_PROXY_PORT;
161 | if (process.env.TG_API_HOST) TG_API_HOST = process.env.TG_API_HOST;
162 |
163 | if (process.env.DD_BOT_TOKEN) {
164 | DD_BOT_TOKEN = process.env.DD_BOT_TOKEN;
165 | if (process.env.DD_BOT_SECRET) {
166 | DD_BOT_SECRET = process.env.DD_BOT_SECRET;
167 | }
168 | }
169 |
170 | if (process.env.QYWX_KEY) {
171 | QYWX_KEY = process.env.QYWX_KEY;
172 | }
173 |
174 | if (process.env.QYWX_AM) {
175 | QYWX_AM = process.env.QYWX_AM;
176 | }
177 |
178 | if (process.env.IGOT_PUSH_KEY) {
179 | IGOT_PUSH_KEY = process.env.IGOT_PUSH_KEY;
180 | }
181 |
182 | if (process.env.PUSH_PLUS_TOKEN) {
183 | PUSH_PLUS_TOKEN = process.env.PUSH_PLUS_TOKEN;
184 | }
185 | if (process.env.PUSH_PLUS_USER) {
186 | PUSH_PLUS_USER = process.env.PUSH_PLUS_USER;
187 | }
188 | //==========================云端环境变量的判断与接收=========================
189 |
190 | /**
191 | * sendNotify 推送通知功能
192 | * @param text 通知头
193 | * @param desp 通知体
194 | * @param params 某些推送通知方式点击弹窗可跳转, 例:{ url: 'https://abc.com' }
195 | * @param author 作者仓库等信息 例:`本通知 By:https://github.com/whyour/qinglong`
196 | * @returns {Promise}
197 | */
198 | async function sendNotify(
199 | text,
200 | desp,
201 | params = {},
202 | author = '\n\n本通知 By:https://github.com/zhacha222/wozaixiaoyuan',
203 | ) {
204 | //提供6种通知
205 | desp += author; //增加作者信息,防止被贩卖等
206 | await Promise.all([
207 | serverNotify(text, desp), //微信server酱
208 | pushPlusNotify(text, desp), //pushplus(推送加)
209 | ]);
210 | //由于上述两种微信通知需点击进去才能查看到详情,故text(标题内容)携带了账号序号以及昵称信息,方便不点击也可知道是哪个京东哪个活动
211 | text = text.match(/.*?(?=\s?-)/g) ? text.match(/.*?(?=\s?-)/g)[0] : text;
212 | await Promise.all([
213 | BarkNotify(text, desp, params), //iOS Bark APP
214 | tgBotNotify(text, desp), //telegram 机器人
215 | ddBotNotify(text, desp), //钉钉机器人
216 | qywxBotNotify(text, desp), //企业微信机器人
217 | qywxamNotify(text, desp), //企业微信应用消息推送
218 | iGotNotify(text, desp, params), //iGot
219 | gobotNotify(text, desp),//go-cqhttp
220 | gotifyNotify(text, desp),//gotify
221 | ]);
222 | }
223 |
224 | function gotifyNotify(text, desp) {
225 | return new Promise((resolve) => {
226 | if (GOTIFY_URL && GOTIFY_TOKEN) {
227 | const options = {
228 | url: `${GOTIFY_URL}/message?token=${GOTIFY_TOKEN}`,
229 | body: `title=${encodeURIComponent(text)}&message=${encodeURIComponent(desp)}&priority=${GOTIFY_PRIORITY}`,
230 | headers: {
231 | 'Content-Type': 'application/x-www-form-urlencoded',
232 | }
233 | };
234 | $.post(options, (err, resp, data) => {
235 | try {
236 | if (err) {
237 | console.log('gotify发送通知调用API失败!!\n');
238 | console.log(err);
239 | } else {
240 | data = JSON.parse(data);
241 | if (data.id) {
242 | console.log('gotify发送通知消息成功🎉\n');
243 | } else {
244 | console.log(`${data.message}\n`);
245 | }
246 | }
247 | } catch (e) {
248 | $.logErr(e, resp);
249 | } finally {
250 | resolve();
251 | }
252 | });
253 | } else {
254 | resolve();
255 | }
256 | });
257 | }
258 |
259 | function gobotNotify(text, desp, time = 2100) {
260 | return new Promise((resolve) => {
261 | if (GOBOT_URL) {
262 | const options = {
263 | url: `${GOBOT_URL}?access_token=${GOBOT_TOKEN}&${GOBOT_QQ}`,
264 | json: {message:`${text}\n${desp}`},
265 | headers: {
266 | 'Content-Type': 'application/json',
267 | },
268 | timeout,
269 | };
270 | setTimeout(() => {
271 | $.post(options, (err, resp, data) => {
272 | try {
273 | if (err) {
274 | console.log('发送go-cqhttp通知调用API失败!!\n');
275 | console.log(err);
276 | } else {
277 | data = JSON.parse(data);
278 | if (data.retcode === 0) {
279 | console.log('go-cqhttp发送通知消息成功🎉\n');
280 | } else if (data.retcode === 100) {
281 | console.log(`go-cqhttp发送通知消息异常: ${data.errmsg}\n`);
282 | } else {
283 | console.log(
284 | `go-cqhttp发送通知消息异常\n${JSON.stringify(data)}`,
285 | );
286 | }
287 | }
288 | } catch (e) {
289 | $.logErr(e, resp);
290 | } finally {
291 | resolve(data);
292 | }
293 | });
294 | }, time);
295 | } else {
296 | resolve();
297 | }
298 | });
299 | }
300 |
301 | function serverNotify(text, desp, time = 2100) {
302 | return new Promise((resolve) => {
303 | if (SCKEY) {
304 | //微信server酱推送通知一个\n不会换行,需要两个\n才能换行,故做此替换
305 | desp = desp.replace(/[\n\r]/g, '\n\n');
306 | const options = {
307 | url: SCKEY.includes('SCT')
308 | ? `https://sctapi.ftqq.com/${SCKEY}.send`
309 | : `https://sc.ftqq.com/${SCKEY}.send`,
310 | body: `text=${text}&desp=${desp}`,
311 | headers: {
312 | 'Content-Type': 'application/x-www-form-urlencoded',
313 | },
314 | timeout,
315 | };
316 | setTimeout(() => {
317 | $.post(options, (err, resp, data) => {
318 | try {
319 | if (err) {
320 | console.log('发送通知调用API失败!!\n');
321 | console.log(err);
322 | } else {
323 | data = JSON.parse(data);
324 | //server酱和Server酱·Turbo版的返回json格式不太一样
325 | if (data.errno === 0 || data.data.errno === 0) {
326 | console.log('server酱发送通知消息成功🎉\n');
327 | } else if (data.errno === 1024) {
328 | // 一分钟内发送相同的内容会触发
329 | console.log(`server酱发送通知消息异常: ${data.errmsg}\n`);
330 | } else {
331 | console.log(
332 | `server酱发送通知消息异常\n${JSON.stringify(data)}`,
333 | );
334 | }
335 | }
336 | } catch (e) {
337 | $.logErr(e, resp);
338 | } finally {
339 | resolve(data);
340 | }
341 | });
342 | }, time);
343 | } else {
344 | resolve();
345 | }
346 | });
347 | }
348 |
349 | function CoolPush(text, desp) {
350 | return new Promise((resolve) => {
351 | if (QQ_SKEY) {
352 | let options = {
353 | url: `https://push.xuthus.cc/${QQ_MODE}/${QQ_SKEY}`,
354 | headers: {
355 | 'Content-Type': 'application/json',
356 | },
357 | };
358 |
359 | // 已知敏感词
360 | text = text.replace(/京豆/g, '豆豆');
361 | desp = desp.replace(/京豆/g, '');
362 | desp = desp.replace(/🐶/g, '');
363 | desp = desp.replace(/红包/g, 'H包');
364 |
365 | switch (QQ_MODE) {
366 | case 'email':
367 | options.json = {
368 | t: text,
369 | c: desp,
370 | };
371 | break;
372 | default:
373 | options.body = `${text}\n\n${desp}`;
374 | }
375 |
376 | let pushMode = function (t) {
377 | switch (t) {
378 | case 'send':
379 | return '个人';
380 | case 'group':
381 | return 'QQ群';
382 | case 'wx':
383 | return '微信';
384 | case 'ww':
385 | return '企业微信';
386 | case 'email':
387 | return '邮件';
388 | default:
389 | return '未知方式';
390 | }
391 | };
392 |
393 | $.post(options, (err, resp, data) => {
394 | try {
395 | if (err) {
396 | console.log(`发送${pushMode(QQ_MODE)}通知调用API失败!!\n`);
397 | console.log(err);
398 | } else {
399 | data = JSON.parse(data);
400 | if (data.code === 200) {
401 | console.log(`酷推发送${pushMode(QQ_MODE)}通知消息成功🎉\n`);
402 | } else if (data.code === 400) {
403 | console.log(
404 | `QQ酷推(Cool Push)发送${pushMode(QQ_MODE)}推送失败:${
405 | data.msg
406 | }\n`,
407 | );
408 | } else if (data.code === 503) {
409 | console.log(`QQ酷推出错,${data.message}:${data.data}\n`);
410 | } else {
411 | console.log(`酷推推送异常: ${JSON.stringify(data)}`);
412 | }
413 | }
414 | } catch (e) {
415 | $.logErr(e, resp);
416 | } finally {
417 | resolve(data);
418 | }
419 | });
420 | } else {
421 | resolve();
422 | }
423 | });
424 | }
425 |
426 | function BarkNotify(text, desp, params = {}) {
427 | return new Promise((resolve) => {
428 | if (BARK_PUSH) {
429 | const options = {
430 | url: `${BARK_PUSH}/${encodeURIComponent(text)}/${encodeURIComponent(
431 | desp,
432 | )}?sound=${BARK_SOUND}&group=${BARK_GROUP}&${querystring.stringify(params)}`,
433 | headers: {
434 | 'Content-Type': 'application/x-www-form-urlencoded',
435 | },
436 | timeout,
437 | };
438 | $.get(options, (err, resp, data) => {
439 | try {
440 | if (err) {
441 | console.log('Bark APP发送通知调用API失败!!\n');
442 | console.log(err);
443 | } else {
444 | data = JSON.parse(data);
445 | if (data.code === 200) {
446 | console.log('Bark APP发送通知消息成功🎉\n');
447 | } else {
448 | console.log(`${data.message}\n`);
449 | }
450 | }
451 | } catch (e) {
452 | $.logErr(e, resp);
453 | } finally {
454 | resolve();
455 | }
456 | });
457 | } else {
458 | resolve();
459 | }
460 | });
461 | }
462 |
463 | function tgBotNotify(text, desp) {
464 | return new Promise((resolve) => {
465 | if (TG_BOT_TOKEN && TG_USER_ID) {
466 | const options = {
467 | url: `https://${TG_API_HOST}/bot${TG_BOT_TOKEN}/sendMessage`,
468 | body: `chat_id=${TG_USER_ID}&text=${text}\n\n${desp}&disable_web_page_preview=true`,
469 | headers: {
470 | 'Content-Type': 'application/x-www-form-urlencoded',
471 | },
472 | timeout,
473 | };
474 | if (TG_PROXY_HOST && TG_PROXY_PORT) {
475 | const tunnel = require('tunnel');
476 | const agent = {
477 | https: tunnel.httpsOverHttp({
478 | proxy: {
479 | host: TG_PROXY_HOST,
480 | port: TG_PROXY_PORT * 1,
481 | proxyAuth: TG_PROXY_AUTH,
482 | },
483 | }),
484 | };
485 | Object.assign(options, { agent });
486 | }
487 | $.post(options, (err, resp, data) => {
488 | try {
489 | if (err) {
490 | console.log('telegram发送通知消息失败!!\n');
491 | console.log(err);
492 | } else {
493 | data = JSON.parse(data);
494 | if (data.ok) {
495 | console.log('Telegram发送通知消息成功🎉。\n');
496 | } else if (data.error_code === 400) {
497 | console.log(
498 | '请主动给bot发送一条消息并检查接收用户ID是否正确。\n',
499 | );
500 | } else if (data.error_code === 401) {
501 | console.log('Telegram bot token 填写错误。\n');
502 | }
503 | }
504 | } catch (e) {
505 | $.logErr(e, resp);
506 | } finally {
507 | resolve(data);
508 | }
509 | });
510 | } else {
511 | resolve();
512 | }
513 | });
514 | }
515 | function ddBotNotify(text, desp) {
516 | return new Promise((resolve) => {
517 | const options = {
518 | url: `https://oapi.dingtalk.com/robot/send?access_token=${DD_BOT_TOKEN}`,
519 | json: {
520 | msgtype: 'text',
521 | text: {
522 | content: ` ${text}\n\n${desp}`,
523 | },
524 | },
525 | headers: {
526 | 'Content-Type': 'application/json',
527 | },
528 | timeout,
529 | };
530 | if (DD_BOT_TOKEN && DD_BOT_SECRET) {
531 | const crypto = require('crypto');
532 | const dateNow = Date.now();
533 | const hmac = crypto.createHmac('sha256', DD_BOT_SECRET);
534 | hmac.update(`${dateNow}\n${DD_BOT_SECRET}`);
535 | const result = encodeURIComponent(hmac.digest('base64'));
536 | options.url = `${options.url}×tamp=${dateNow}&sign=${result}`;
537 | $.post(options, (err, resp, data) => {
538 | try {
539 | if (err) {
540 | console.log('钉钉发送通知消息失败!!\n');
541 | console.log(err);
542 | } else {
543 | data = JSON.parse(data);
544 | if (data.errcode === 0) {
545 | console.log('钉钉发送通知消息成功🎉。\n');
546 | } else {
547 | console.log(`${data.errmsg}\n`);
548 | }
549 | }
550 | } catch (e) {
551 | $.logErr(e, resp);
552 | } finally {
553 | resolve(data);
554 | }
555 | });
556 | } else if (DD_BOT_TOKEN) {
557 | $.post(options, (err, resp, data) => {
558 | try {
559 | if (err) {
560 | console.log('钉钉发送通知消息失败!!\n');
561 | console.log(err);
562 | } else {
563 | data = JSON.parse(data);
564 | if (data.errcode === 0) {
565 | console.log('钉钉发送通知消息完成。\n');
566 | } else {
567 | console.log(`${data.errmsg}\n`);
568 | }
569 | }
570 | } catch (e) {
571 | $.logErr(e, resp);
572 | } finally {
573 | resolve(data);
574 | }
575 | });
576 | } else {
577 | resolve();
578 | }
579 | });
580 | }
581 |
582 | function qywxBotNotify(text, desp) {
583 | return new Promise((resolve) => {
584 | const options = {
585 | url: `https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=${QYWX_KEY}`,
586 | json: {
587 | msgtype: 'text',
588 | text: {
589 | content: ` ${text}\n\n${desp}`,
590 | },
591 | },
592 | headers: {
593 | 'Content-Type': 'application/json',
594 | },
595 | timeout,
596 | };
597 | if (QYWX_KEY) {
598 | $.post(options, (err, resp, data) => {
599 | try {
600 | if (err) {
601 | console.log('企业微信发送通知消息失败!!\n');
602 | console.log(err);
603 | } else {
604 | data = JSON.parse(data);
605 | if (data.errcode === 0) {
606 | console.log('企业微信发送通知消息成功🎉。\n');
607 | } else {
608 | console.log(`${data.errmsg}\n`);
609 | }
610 | }
611 | } catch (e) {
612 | $.logErr(e, resp);
613 | } finally {
614 | resolve(data);
615 | }
616 | });
617 | } else {
618 | resolve();
619 | }
620 | });
621 | }
622 |
623 | function ChangeUserId(desp) {
624 | const QYWX_AM_AY = QYWX_AM.split(',');
625 | if (QYWX_AM_AY[2]) {
626 | const userIdTmp = QYWX_AM_AY[2].split('|');
627 | let userId = '';
628 | for (let i = 0; i < userIdTmp.length; i++) {
629 | const count = '账号' + (i + 1);
630 | const count2 = '签到号 ' + (i + 1);
631 | if (desp.match(count2)) {
632 | userId = userIdTmp[i];
633 | }
634 | }
635 | if (!userId) userId = QYWX_AM_AY[2];
636 | return userId;
637 | } else {
638 | return '@all';
639 | }
640 | }
641 |
642 | function qywxamNotify(text, desp) {
643 | return new Promise((resolve) => {
644 | if (QYWX_AM) {
645 | const QYWX_AM_AY = QYWX_AM.split(',');
646 | const options_accesstoken = {
647 | url: `https://qyapi.weixin.qq.com/cgi-bin/gettoken`,
648 | json: {
649 | corpid: `${QYWX_AM_AY[0]}`,
650 | corpsecret: `${QYWX_AM_AY[1]}`,
651 | },
652 | headers: {
653 | 'Content-Type': 'application/json',
654 | },
655 | timeout,
656 | };
657 | $.post(options_accesstoken, (err, resp, data) => {
658 | html = desp.replace(/\n/g, '
');
659 | var json = JSON.parse(data);
660 | accesstoken = json.access_token;
661 | let options;
662 |
663 | switch (QYWX_AM_AY[4]) {
664 | case '0':
665 | options = {
666 | msgtype: 'textcard',
667 | textcard: {
668 | title: `${text}`,
669 | description: `${desp}`,
670 | url: 'https://github.com/whyour/qinglong',
671 | btntxt: '更多',
672 | },
673 | };
674 | break;
675 |
676 | case '1':
677 | options = {
678 | msgtype: 'text',
679 | text: {
680 | content: `${text}\n\n${desp}`,
681 | },
682 | };
683 | break;
684 |
685 | default:
686 | options = {
687 | msgtype: 'mpnews',
688 | mpnews: {
689 | articles: [
690 | {
691 | title: `${text}`,
692 | thumb_media_id: `${QYWX_AM_AY[4]}`,
693 | author: `智能助手`,
694 | content_source_url: ``,
695 | content: `${html}`,
696 | digest: `${desp}`,
697 | },
698 | ],
699 | },
700 | };
701 | }
702 | if (!QYWX_AM_AY[4]) {
703 | //如不提供第四个参数,则默认进行文本消息类型推送
704 | options = {
705 | msgtype: 'text',
706 | text: {
707 | content: `${text}\n\n${desp}`,
708 | },
709 | };
710 | }
711 | options = {
712 | url: `https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=${accesstoken}`,
713 | json: {
714 | touser: `${ChangeUserId(desp)}`,
715 | agentid: `${QYWX_AM_AY[3]}`,
716 | safe: '0',
717 | ...options,
718 | },
719 | headers: {
720 | 'Content-Type': 'application/json',
721 | },
722 | };
723 |
724 | $.post(options, (err, resp, data) => {
725 | try {
726 | if (err) {
727 | console.log(
728 | '成员ID:' +
729 | ChangeUserId(desp) +
730 | '企业微信应用消息发送通知消息失败!!\n',
731 | );
732 | console.log(err);
733 | } else {
734 | data = JSON.parse(data);
735 | if (data.errcode === 0) {
736 | console.log(
737 | '成员ID:' +
738 | ChangeUserId(desp) +
739 | '企业微信应用消息发送通知消息成功🎉。\n',
740 | );
741 | } else {
742 | console.log(`${data.errmsg}\n`);
743 | }
744 | }
745 | } catch (e) {
746 | $.logErr(e, resp);
747 | } finally {
748 | resolve(data);
749 | }
750 | });
751 | });
752 | } else {
753 | resolve();
754 | }
755 | });
756 | }
757 |
758 | function iGotNotify(text, desp, params = {}) {
759 | return new Promise((resolve) => {
760 | if (IGOT_PUSH_KEY) {
761 | // 校验传入的IGOT_PUSH_KEY是否有效
762 | const IGOT_PUSH_KEY_REGX = new RegExp('^[a-zA-Z0-9]{24}$');
763 | if (!IGOT_PUSH_KEY_REGX.test(IGOT_PUSH_KEY)) {
764 | console.log('您所提供的IGOT_PUSH_KEY无效\n');
765 | resolve();
766 | return;
767 | }
768 | const options = {
769 | url: `https://push.hellyw.com/${IGOT_PUSH_KEY.toLowerCase()}`,
770 | body: `title=${text}&content=${desp}&${querystring.stringify(params)}`,
771 | headers: {
772 | 'Content-Type': 'application/x-www-form-urlencoded',
773 | },
774 | timeout,
775 | };
776 | $.post(options, (err, resp, data) => {
777 | try {
778 | if (err) {
779 | console.log('发送通知调用API失败!!\n');
780 | console.log(err);
781 | } else {
782 | if (typeof data === 'string') data = JSON.parse(data);
783 | if (data.ret === 0) {
784 | console.log('iGot发送通知消息成功🎉\n');
785 | } else {
786 | console.log(`iGot发送通知消息失败:${data.errMsg}\n`);
787 | }
788 | }
789 | } catch (e) {
790 | $.logErr(e, resp);
791 | } finally {
792 | resolve(data);
793 | }
794 | });
795 | } else {
796 | resolve();
797 | }
798 | });
799 | }
800 |
801 | function pushPlusNotify(text, desp) {
802 | return new Promise((resolve) => {
803 | if (PUSH_PLUS_TOKEN) {
804 | desp = desp.replace(/[\n\r]/g, '
'); // 默认为html, 不支持plaintext
805 | const body = {
806 | token: `${PUSH_PLUS_TOKEN}`,
807 | title: `${text}`,
808 | content: `${desp}`,
809 | topic: `${PUSH_PLUS_USER}`,
810 | };
811 | const options = {
812 | url: `https://www.pushplus.plus/send`,
813 | body: JSON.stringify(body),
814 | headers: {
815 | 'Content-Type': ' application/json',
816 | },
817 | timeout,
818 | };
819 | $.post(options, (err, resp, data) => {
820 | try {
821 | if (err) {
822 | console.log(
823 | `push+发送${
824 | PUSH_PLUS_USER ? '一对多' : '一对一'
825 | }通知消息失败!!\n`,
826 | );
827 | console.log(err);
828 | } else {
829 | data = JSON.parse(data);
830 | if (data.code === 200) {
831 | console.log(
832 | `push+发送${
833 | PUSH_PLUS_USER ? '一对多' : '一对一'
834 | }通知消息完成。\n`,
835 | );
836 | } else {
837 | console.log(
838 | `push+发送${
839 | PUSH_PLUS_USER ? '一对多' : '一对一'
840 | }通知消息失败:${data.msg}\n`,
841 | );
842 | }
843 | }
844 | } catch (e) {
845 | $.logErr(e, resp);
846 | } finally {
847 | resolve(data);
848 | }
849 | });
850 | } else {
851 | resolve();
852 | }
853 | });
854 | }
855 |
856 | module.exports = {
857 | sendNotify,
858 | BARK_PUSH,
859 | };
860 |
861 | // prettier-ignore
862 | function Env(t,s){return new class{constructor(t,s){this.name=t,this.data=null,this.dataFile="box.dat",this.logs=[],this.logSeparator="\n",this.startTime=(new Date).getTime(),Object.assign(this,s),this.log("",`\ud83d\udd14${this.name}, \u5f00\u59cb!`)}isNode(){return"undefined"!=typeof module&&!!module.exports}isQuanX(){return"undefined"!=typeof $task}isSurge(){return"undefined"!=typeof $httpClient&&"undefined"==typeof $loon}isLoon(){return"undefined"!=typeof $loon}getScript(t){return new Promise(s=>{$.get({url:t},(t,e,i)=>s(i))})}runScript(t,s){return new Promise(e=>{let i=this.getdata("@chavy_boxjs_userCfgs.httpapi");i=i?i.replace(/\n/g,"").trim():i;let o=this.getdata("@chavy_boxjs_userCfgs.httpapi_timeout");o=o?1*o:20,o=s&&s.timeout?s.timeout:o;const[h,a]=i.split("@"),r={url:`http://${a}/v1/scripting/evaluate`,body:{script_text:t,mock_type:"cron",timeout:o},headers:{"X-Key":h,Accept:"*/*"}};$.post(r,(t,s,i)=>e(i))}).catch(t=>this.logErr(t))}loaddata(){if(!this.isNode())return{};{this.fs=this.fs?this.fs:require("fs"),this.path=this.path?this.path:require("path");const t=this.path.resolve(this.dataFile),s=this.path.resolve(process.cwd(),this.dataFile),e=this.fs.existsSync(t),i=!e&&this.fs.existsSync(s);if(!e&&!i)return{};{const i=e?t:s;try{return JSON.parse(this.fs.readFileSync(i))}catch(t){return{}}}}}writedata(){if(this.isNode()){this.fs=this.fs?this.fs:require("fs"),this.path=this.path?this.path:require("path");const t=this.path.resolve(this.dataFile),s=this.path.resolve(process.cwd(),this.dataFile),e=this.fs.existsSync(t),i=!e&&this.fs.existsSync(s),o=JSON.stringify(this.data);e?this.fs.writeFileSync(t,o):i?this.fs.writeFileSync(s,o):this.fs.writeFileSync(t,o)}}lodash_get(t,s,e){const i=s.replace(/\[(\d+)\]/g,".$1").split(".");let o=t;for(const t of i)if(o=Object(o)[t],void 0===o)return e;return o}lodash_set(t,s,e){return Object(t)!==t?t:(Array.isArray(s)||(s=s.toString().match(/[^.[\]]+/g)||[]),s.slice(0,-1).reduce((t,e,i)=>Object(t[e])===t[e]?t[e]:t[e]=Math.abs(s[i+1])>>0==+s[i+1]?[]:{},t)[s[s.length-1]]=e,t)}getdata(t){let s=this.getval(t);if(/^@/.test(t)){const[,e,i]=/^@(.*?)\.(.*?)$/.exec(t),o=e?this.getval(e):"";if(o)try{const t=JSON.parse(o);s=t?this.lodash_get(t,i,""):s}catch(t){s=""}}return s}setdata(t,s){let e=!1;if(/^@/.test(s)){const[,i,o]=/^@(.*?)\.(.*?)$/.exec(s),h=this.getval(i),a=i?"null"===h?null:h||"{}":"{}";try{const s=JSON.parse(a);this.lodash_set(s,o,t),e=this.setval(JSON.stringify(s),i)}catch(s){const h={};this.lodash_set(h,o,t),e=this.setval(JSON.stringify(h),i)}}else e=$.setval(t,s);return e}getval(t){return this.isSurge()||this.isLoon()?$persistentStore.read(t):this.isQuanX()?$prefs.valueForKey(t):this.isNode()?(this.data=this.loaddata(),this.data[t]):this.data&&this.data[t]||null}setval(t,s){return this.isSurge()||this.isLoon()?$persistentStore.write(t,s):this.isQuanX()?$prefs.setValueForKey(t,s):this.isNode()?(this.data=this.loaddata(),this.data[s]=t,this.writedata(),!0):this.data&&this.data[s]||null}initGotEnv(t){this.got=this.got?this.got:require("got"),this.cktough=this.cktough?this.cktough:require("tough-cookie"),this.ckjar=this.ckjar?this.ckjar:new this.cktough.CookieJar,t&&(t.headers=t.headers?t.headers:{},void 0===t.headers.Cookie&&void 0===t.cookieJar&&(t.cookieJar=this.ckjar))}get(t,s=(()=>{})){t.headers&&(delete t.headers["Content-Type"],delete t.headers["Content-Length"]),this.isSurge()||this.isLoon()?$httpClient.get(t,(t,e,i)=>{!t&&e&&(e.body=i,e.statusCode=e.status),s(t,e,i)}):this.isQuanX()?$task.fetch(t).then(t=>{const{statusCode:e,statusCode:i,headers:o,body:h}=t;s(null,{status:e,statusCode:i,headers:o,body:h},h)},t=>s(t)):this.isNode()&&(this.initGotEnv(t),this.got(t).on("redirect",(t,s)=>{try{const e=t.headers["set-cookie"].map(this.cktough.Cookie.parse).toString();this.ckjar.setCookieSync(e,null),s.cookieJar=this.ckjar}catch(t){this.logErr(t)}}).then(t=>{const{statusCode:e,statusCode:i,headers:o,body:h}=t;s(null,{status:e,statusCode:i,headers:o,body:h},h)},t=>s(t)))}post(t,s=(()=>{})){if(t.body&&t.headers&&!t.headers["Content-Type"]&&(t.headers["Content-Type"]="application/x-www-form-urlencoded"),delete t.headers["Content-Length"],this.isSurge()||this.isLoon())$httpClient.post(t,(t,e,i)=>{!t&&e&&(e.body=i,e.statusCode=e.status),s(t,e,i)});else if(this.isQuanX())t.method="POST",$task.fetch(t).then(t=>{const{statusCode:e,statusCode:i,headers:o,body:h}=t;s(null,{status:e,statusCode:i,headers:o,body:h},h)},t=>s(t));else if(this.isNode()){this.initGotEnv(t);const{url:e,...i}=t;this.got.post(e,i).then(t=>{const{statusCode:e,statusCode:i,headers:o,body:h}=t;s(null,{status:e,statusCode:i,headers:o,body:h},h)},t=>s(t))}}time(t){let s={"M+":(new Date).getMonth()+1,"d+":(new Date).getDate(),"H+":(new Date).getHours(),"m+":(new Date).getMinutes(),"s+":(new Date).getSeconds(),"q+":Math.floor(((new Date).getMonth()+3)/3),S:(new Date).getMilliseconds()};/(y+)/.test(t)&&(t=t.replace(RegExp.$1,((new Date).getFullYear()+"").substr(4-RegExp.$1.length)));for(let e in s)new RegExp("("+e+")").test(t)&&(t=t.replace(RegExp.$1,1==RegExp.$1.length?s[e]:("00"+s[e]).substr((""+s[e]).length)));return t}msg(s=t,e="",i="",o){const h=t=>!t||!this.isLoon()&&this.isSurge()?t:"string"==typeof t?this.isLoon()?t:this.isQuanX()?{"open-url":t}:void 0:"object"==typeof t&&(t["open-url"]||t["media-url"])?this.isLoon()?t["open-url"]:this.isQuanX()?t:void 0:void 0;$.isMute||(this.isSurge()||this.isLoon()?$notification.post(s,e,i,h(o)):this.isQuanX()&&$notify(s,e,i,h(o))),this.logs.push("","==============\ud83d\udce3\u7cfb\u7edf\u901a\u77e5\ud83d\udce3=============="),this.logs.push(s),e&&this.logs.push(e),i&&this.logs.push(i)}log(...t){t.length>0?this.logs=[...this.logs,...t]:console.log(this.logs.join(this.logSeparator))}logErr(t,s){const e=!this.isSurge()&&!this.isQuanX()&&!this.isLoon();e?$.log("",`\u2757\ufe0f${this.name}, \u9519\u8bef!`,t.stack):$.log("",`\u2757\ufe0f${this.name}, \u9519\u8bef!`,t)}wait(t){return new Promise(s=>setTimeout(s,t))}done(t={}){const s=(new Date).getTime(),e=(s-this.startTime)/1e3;this.log("",`\ud83d\udd14${this.name}, \u7ed3\u675f! \ud83d\udd5b ${e} \u79d2`),this.log(),(this.isSurge()||this.isQuanX()||this.isLoon())&&$done(t)}}(t,s)}
863 |
--------------------------------------------------------------------------------
/wzxy_check.js:
--------------------------------------------------------------------------------
1 | /**
2 | * 作者QQ: 1483081359 欢迎前来提交bug
3 | * github仓库:https://github.com/zhacha222/wozaixiaoyuan
4 | * 微信小程序:我在校园 账号检测
5 | * 脚本说明:此脚本用于延长【我在校园】账号的有效时长,防止账号过期(务必启用!务必启用!务必启用!)
6 | * 默认定时:默认每天运行两次,如果你每天都需要频繁登录手机端,也可以自己改定时每天多运行几次防止账号失效
7 | * cron: 15 11,23 * * *
8 | * 变量名称:wzxy
9 | * 变量值: {
10 | "username": "手机号",
11 | "password": "密码",
12 | "qd_location": "133.333333,33.333333",
13 | "rjrb_answers": ["0","0"],
14 | "rjrb_location": "133.333333,33.333333",
15 | "jkdk_answers": ["0","无","1","0","36.2","没有","1","1","2"],
16 | "jkdk_location": "133.333333,33.333333",
17 | "mark": "用户昵称"
18 | }
19 |
20 | ***一些前提说明:
21 | 1.只支持青龙面板(本人青龙版本2.10.13),搭建教程自行百度
22 | 2.本库脚本通用 wzxy这一个变量
23 | 3.脚本变量只推荐在青龙的【环境变量】页添加,有强迫症在【配置文件】config.sh中添加的如果出现问题自己解决
24 | 4.支持多用户,每一用户在【环境变量】单独新建变量wzxy,切勿一个变量内填写多个用户的参数
25 | 5.脚本通知方式采用青龙面板默认通知,请在【配置文件】config.sh里配置
26 | 6.关于各脚本的具体使用方法,请阅读脚本内的注释
27 |
28 | ***关于变量值中各参数的解释:
29 | username ———————— 手机号
30 | password —————————密码
31 | qd_location ————— 签到的`经纬度` (wzxy_qd.js)
32 | rjrb_answers —————日检日报的`填空参数`(wzxy_rjrb.js)
33 | rjrb_location ————日检日报的`经纬度` (wzxy_rjrb.js)
34 | jkdk_answers ———— 健康签到的`填空参数`(wzxy_jkdk.js)
35 | jkdk_location ————健康签到的`经纬度` (wzxy_jkdk.js)
36 | mark —————————————用户昵称(不一定要真名,随便填都行,便于自己区分打卡用户)
37 |
38 | ***更新日志:
39 | 1.0.0 完成账号检测的基本功能:检测,重置密码,更新jwsession
40 | 1.0.1 增加账号失效自动禁用 增加仅账号失效通知
41 | 1.0.2 增加等待15s,防止黑ip
42 | 1.0.5 适配青龙最新版
43 | 1.0.6 优化通知
44 | 1.0.7 log增加新版本内容
45 |
46 |
47 | */
48 |
49 | //cron: 15 11,23 * * *
50 | //===============通知设置=================//
51 | const Notify = 1; //0为关闭通知,1为打开通知,默认为1
52 | const errorNotify = 0; //0为关闭仅账号失效通知,1为打开仅账号失效通知,默认为0
53 | ////////////////////////////////////////////
54 | const $ = new Env('账号检测');
55 | const {log} = console;
56 | const notify = $.isNode() ? require('./sendNotify') : '';
57 | const request = require('request');
58 | const got = require('got');
59 | require('dotenv').config();
60 | const { readFile } = require('fs/promises');
61 | const path = require('path');
62 | const qlDir = '/ql';
63 | const fs = require('fs');
64 | let Fileexists = fs.existsSync('/ql/data/config/auth.json');
65 | let authFile="";
66 | if (Fileexists)
67 | authFile="/ql/data/config/auth.json"
68 | else
69 | authFile="/ql/config/auth.json"
70 | //const authFile = path.join(qlDir, 'config/auth.json');
71 |
72 | const api = got.extend({
73 | prefixUrl: 'http://127.0.0.1:5600',
74 | retry: { limit: 0 },
75 | });
76 | //我在校园账号数据
77 | let scriptVersion = "1.0.7";
78 | let scriptVersionLatest = '';
79 | let update_data = "1.0.7 log增加新版本内容"; //新版本更新内容
80 | let wzxyArr = [];
81 | let wait = 0;
82 | let checkBack = 0;
83 | let passwordchangeBack = 0;
84 | let msg = '';
85 | let jwsession = '';
86 | let status_code = 0;
87 | let status_code1 = 0;
88 | let eid = '';
89 |
90 |
91 | !(async () => {
92 | if (typeof $request !== "undefined") {
93 | await GetRewrite();
94 | } else {
95 | if (!(await getEnvs()))
96 | return;
97 | else {
98 |
99 | log(`\n\n============================================= \n脚本执行 - 北京时间(UTC+8):${new Date(
100 | new Date().getTime() + new Date().getTimezoneOffset() * 60 * 1000 +
101 | 8 * 60 * 60 * 1000).toLocaleString()} \n=============================================\n`);
102 |
103 | await poem();
104 | await getVersion();
105 |
106 | log(`\n============ 当前版本:${scriptVersion} 最新版本:${scriptVersionLatest} ============`)
107 |
108 | if(scriptVersionLatest != scriptVersion){
109 | log(`\n发现新版本,请及时拉库更新!\n${update_data}`)
110 | }
111 |
112 | log(`\n=================== 共找到 ${wzxyArr.length} 个账号 ===================`)
113 | //log(wzxyArr[0])
114 |
115 |
116 | for (let index = 0; index < wzxyArr.length; index++) {
117 |
118 |
119 | let num = index + 1
120 | if (num >1&& wait == 0){
121 | log('**********休息15s,防止黑IP**********');
122 | await $.wait(16 * 1000);
123 | }
124 | log(`\n========= 开始检测【第 ${num} 个账号】=========\n`)
125 | eid = wzxyArr[index]._id
126 | status = wzxyArr[index].status
127 | data = JSON.parse(wzxyArr[index].value)
128 | //log(data)
129 | username = data.username
130 | password = data.password
131 | mark = data.mark
132 |
133 | log(`检测用户: ${mark}`)
134 | if (status == 1) {
135 | log(`🚫 账号已禁用`)
136 | status_code = 3
137 | status_code1 = 3
138 | wait = 1
139 | }else{
140 | wait = 0
141 | checkBack = 0;//置0,防止上一个号影响下一个号
142 | await check()
143 | await $.wait(2 * 1000);
144 |
145 | if (checkBack > 0) {
146 | await passwordchange()
147 | await $.wait(2 * 1000);
148 |
149 | if (passwordchangeBack > 0) {
150 | log(`正在更新jwsession...`)
151 | await login()
152 | await $.wait(2 * 1000);
153 |
154 | }
155 |
156 | }
157 | }
158 | var resultlog = getResult()
159 | var updatelog = getupdateResult()
160 |
161 | if (errorNotify>0){
162 | if (status_code != 1 || status_code1 !=1){
163 | msg += `检测用户:${mark}\n${resultlog}\n${updatelog}\n\n`
164 | }
165 | }else {
166 | msg += `检测用户:${mark}\n${resultlog}\n${updatelog}\n\n`
167 | }
168 |
169 | }
170 | // log(msg);
171 | await SendMsg(msg);
172 | }
173 | }
174 |
175 | })()
176 | .catch((e) => log(e))
177 | .finally(() => $.done())
178 |
179 |
180 |
181 |
182 | /**
183 | * 检测账号是否失效
184 | */
185 | function check(timeout = 3 * 1000) {
186 | return new Promise((resolve) => {
187 | let url = {
188 | url: `https://gw.wozaixiaoyuan.com/basicinfo/mobile/login/username?username=${username}&password=${password}`,
189 | headers: {
190 | "Accept-Encoding": "gzip, deflate, br",
191 | "Connection": "keep-alive",
192 | "User-Agent": "Mozilla/5.0 (iPad; CPU OS 15_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.23(0x1800172f) NetType/WIFI Language/zh_CN miniProgram/wxce6d08f781975d91",
193 | "content-type": "application/json;charset=UTF-8",
194 | "Content-Length": "2",
195 | "Host": "gw.wozaixiaoyuan.com",
196 | "Accept-Language": "en-us,en",
197 | "Accept": "application/json, text/plain, */*"
198 | },
199 | data: ``,
200 | }
201 | request.post(url, async (error, response, data) => {
202 | try {
203 | let result = data == "undefined" ? await check() : JSON.parse(data);
204 |
205 | //登录成功
206 | if (result.code == 0 ) {
207 |
208 | jwsession = response.headers['jwsession']
209 | log(`账号未失效,开始重置密码...`)
210 | checkBack = 1;
211 | status_code = 1;
212 | }
213 | else {
214 | log(`❌ 账号已失效,尝试使用jwsession更新`)
215 | checkJwsession()
216 | status_code = 2;
217 | }
218 |
219 | } catch (e) {
220 | log(e)
221 | } finally {
222 | resolve();
223 | }
224 | }, timeout)
225 | })
226 | }
227 |
228 |
229 | /**
230 | * 判断jwsession是否存在
231 | */
232 | function checkJwsession() {
233 |
234 | fs.open('.cache/' + username + ".json", 'r+', function(err, fd) {
235 | if (err) {
236 | console.error("jwsession不存在,开始禁用账号...")
237 | DisableCk(eid)
238 | return
239 | }
240 | var read = fs.readFileSync('.cache/' + username + ".json")
241 | jwsession = read.toString()
242 | if (jwsession == ``){
243 | console.log("jwsession不存在,开始禁用账号..." +
244 | "")
245 | DisableCk(eid)
246 | return
247 | }else{
248 | log(`找到jwsession,正在重置密码...`)
249 | checkBack = 1
250 | }
251 | });
252 |
253 | }
254 |
255 |
256 | /**
257 | * 重置密码 以延长账号有效期
258 | */
259 | function passwordchange(timeout = 3 * 1000) {
260 | return new Promise((resolve) => {
261 | let url = {
262 | url: `https://gw.wozaixiaoyuan.com/basicinfo/mobile/my/changePassword?oldPassword=${password}&newPassword=${password}`,
263 | headers: {
264 | "Accept":"application/json, text/plain, */*",
265 | "Accept-Encoding":"gzip, deflate, br",
266 | "Cookie":"JWSESSION=1ed2d1bda1fe4975a4a128acd837b787",
267 | "Content-Type":"application/json;charset=UTF-8",
268 | "Referer":"https://gw.wozaixiaoyuan.com/h5/mobile/basicinfo/index/my/changePassword",
269 | "Host":"gw.wozaixiaoyuan.com",
270 | "User-Agent":"Mozilla/5.0 (iPad; CPU OS 15_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.23(0x1800172f) NetType/WIFI Language/zh_CN miniProgram/wxce6d08f781975d91",
271 | "Connection":"keep-alive",
272 | "Accept-Language":"zh-CN,zh-Hans;q=0.9",
273 | "JWSESSION":jwsession,
274 | },
275 | data: ``,
276 | }
277 |
278 | request.get(url, async (error, response, data) => {
279 | try {
280 | let result = data == "undefined" ? await passwordchange() : JSON.parse(data);
281 |
282 | if (result.code == 0 ) {
283 | log(`✅ 密码重置成功`)
284 | status_code1 = 1
285 | passwordchangeBack = 1
286 | }else{
287 | log(`❌ jwsession已失效,开始禁用账号...`)
288 | DisableCk(eid)
289 | status_code1 = 2
290 | passwordchangeBack = 0
291 |
292 | }
293 |
294 | } catch (e) {
295 | log(e)
296 | } finally {
297 | resolve();
298 | }
299 | }, timeout)
300 | })
301 | }
302 |
303 |
304 |
305 | /**
306 | * 登录
307 | */
308 | function login(timeout = 3 * 1000) {
309 | return new Promise((resolve) => {
310 | let url = {
311 | url: `https://gw.wozaixiaoyuan.com/basicinfo/mobile/login/username?username=${username}&password=${password}`,
312 | headers: {
313 | "Accept-Encoding": "gzip, deflate, br",
314 | "Connection": "keep-alive",
315 | "User-Agent": "Mozilla/5.0 (iPad; CPU OS 15_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.23(0x1800172f) NetType/WIFI Language/zh_CN miniProgram/wxce6d08f781975d91",
316 | "content-type": "application/json;charset=UTF-8",
317 | "Content-Length": "2",
318 | "Host": "gw.wozaixiaoyuan.com",
319 | "Accept-Language": "en-us,en",
320 | "Accept": "application/json, text/plain, */*"
321 | },
322 | data: ``,
323 | }
324 |
325 |
326 | request.post(url, async (error, response, data) => {
327 | try {
328 | let result = data == "undefined" ? await login() : JSON.parse(data);
329 |
330 | //登录成功
331 | if (result.code == 0 ) {
332 | jwsession = response.headers['jwsession']
333 | setJwsession(jwsession)
334 |
335 | } else {
336 | log(`❌ 更新失败,${result.message}`)
337 | }
338 |
339 | } catch (e) {
340 | log(e)
341 | } finally {
342 | resolve();
343 | }
344 | }, timeout)
345 | })
346 | }
347 |
348 |
349 | /**
350 | * 获取账号检测结果
351 | */
352 | function getResult(timeout = 3 * 1000) {
353 | res = status_code
354 | if (res == 1) return "✅ 账号未失效"
355 | if (res == 2) return "❌ 账号已失效"
356 | if (res == 3) return "🚫 账号已被禁用,请及时更新"
357 | else return "❌ 发生未知错误"
358 | }
359 |
360 |
361 | /**
362 | * 获取账号更新结果
363 | */
364 | function getupdateResult(timeout = 3 * 1000) {
365 | res1 = status_code1
366 | if (res1 == 1) return "✅ 账号更新成功"
367 | if (res1 == 2) return "❌ 账号更新失败,请手动更改密码后重新登录"
368 | if (res1 == 3) return ""
369 | if (res1 == 4) return "🚫 账号禁用成功"
370 | else return "❌ 发生未知错误"
371 | }
372 |
373 |
374 | /**
375 | * 存储jwsession
376 | */
377 | function setJwsession(jwsession) {
378 |
379 | fs.mkdir('.cache',function(err){
380 | if (err) {
381 |
382 | console.log("找到cache文件");
383 | }
384 | else console.log("正在创建cache储存目录与文件...");
385 | });
386 |
387 | fs.writeFile('.cache/' + username + ".json", jwsession, function(err) {
388 | if (err) {
389 | return console.error(err);
390 | }
391 | console.log("✅ jwsession成功更新");
392 |
393 | })
394 |
395 | }
396 |
397 | // ============================================变量检查============================================ \\
398 |
399 | async function getToken() {
400 | const authConfig = JSON.parse(await readFile(authFile));
401 | //console.log(authConfig)
402 | return authConfig.token;
403 | }
404 |
405 |
406 | async function getEnvs() {
407 | const token = await getToken();
408 | const body = await api({
409 | url: 'api/envs',
410 | searchParams: {
411 | searchValue: 'wzxy',
412 | t: Date.now(),
413 | },
414 | headers: {
415 | Accept: 'application/json',
416 | authorization: `Bearer ${token}`,
417 | },
418 | }).json();
419 | for(var i=0,j=0;i 0) {
456 | if ($.isNode()) {
457 | var notify = require('./sendNotify');
458 | await notify.sendNotify($.name, msg+ `\n检测时间:${t()}\n`);
459 | } else {
460 | $.msg(msg);
461 | }
462 | } else {
463 | //log(msg);
464 | }
465 | }
466 |
467 | /**
468 | * 随机数生成
469 | */
470 | function randomString(e) {
471 | e = e || 32;
472 | var t = "QWERTYUIOPASDFGHJKLZXCVBNM1234567890",
473 | a = t.length,
474 | n = "";
475 | for (i = 0; i < e; i++)
476 | n += t.charAt(Math.floor(Math.random() * a));
477 | return n
478 | }
479 |
480 | /**
481 | * 随机整数生成
482 | */
483 | function randomInt(min, max) {
484 | return Math.round(Math.random() * (max - min) + min)
485 | }
486 |
487 | /**
488 | * 获取毫秒时间戳
489 | */
490 | function timestampMs(){
491 | return new Date().getTime();
492 | }
493 |
494 | /**
495 | *
496 | * 获取秒时间戳
497 | */
498 | function timestampS(){
499 | return Date.parse(new Date())/1000;
500 | }
501 |
502 | /**
503 | * 获取随机诗词
504 | */
505 | function poem(timeout = 3 * 1000) {
506 | return new Promise((resolve) => {
507 | let url = {
508 | url: `https://v1.jinrishici.com/all.json`
509 | }
510 | $.get(url, async (err, resp, data) => {
511 | try {
512 | data = JSON.parse(data)
513 | log(`${data.content} \n————《${data.origin}》${data.author}`);
514 | } catch (e) {
515 | log(e, resp);
516 | } finally {
517 | resolve()
518 | }
519 | }, timeout)
520 | })
521 | }
522 |
523 | /**
524 | * 修改配置文件
525 | */
526 | function modify() {
527 |
528 | fs.readFile('/ql/data/config/config.sh','utf8',function(err,dataStr){
529 | if(err){
530 | return log('读取文件失败!'+err)
531 | }
532 | else {
533 | var result = dataStr.replace(/regular/g,string);
534 | fs.writeFile('/ql/data/config/config.sh', result, 'utf8', function (err) {
535 | if (err) {return log(err);}
536 | });
537 | }
538 | })
539 | }
540 |
541 | /**
542 | * 获取远程版本
543 | */
544 | function getVersion(timeout = 3 * 1000) {
545 | return new Promise((resolve) => {
546 | let url = {
547 | url: `https://ghproxy.com/https://raw.githubusercontent.com/zhacha222/wozaixiaoyuan/main/wzxy_check.js`,
548 | }
549 | $.get(url, async (err, resp, data) => {
550 | try {
551 | scriptVersionLatest = data.match(/scriptVersion = "([\d\.]+)"/)[1]
552 | update_data = data.match(/update_data = "(.*?)"/)[1]
553 | } catch (e) {
554 | $.logErr(e, resp);
555 | } finally {
556 | resolve()
557 | }
558 | }, timeout)
559 | })
560 | }
561 |
562 | /**
563 | * time 输出格式:1970-01-01 00:00:00
564 | */
565 | function t() {
566 | var date = new Date();
567 | // 获取当前月份
568 | var nowMonth = date.getMonth() + 1;
569 | // 获取当前是几号
570 | var strDate = date.getDate();
571 | //获取当前小时(0-23)
572 | var nowhour = date.getHours()
573 | //获取当前分钟(0-59)
574 | var nowMinute = date.getMinutes()
575 | //获取当前秒数(0-59)
576 | var nowSecond = date.getSeconds();
577 | // 添加分隔符“-”
578 | var seperator = "-";
579 | // 添加分隔符“:”
580 | var seperator1 = ":";
581 |
582 | // 对月份进行处理,1-9月在前面添加一个“0”
583 | if (nowMonth >= 1 && nowMonth <= 9) {
584 | nowMonth = "0" + nowMonth;
585 | }
586 | // 对月份进行处理,1-9号在前面添加一个“0”
587 | if (strDate >= 0 && strDate <= 9) {
588 | strDate = "0" + strDate;
589 | }
590 | // 对小时进行处理,0-9号在前面添加一个“0”
591 | if (nowhour >= 0 && nowhour <= 9) {
592 | nowhour = "0" + nowhour;
593 | }
594 | // 对分钟进行处理,0-9号在前面添加一个“0”
595 | if (nowMinute >= 0 && nowMinute <= 9) {
596 | nowMinute = "0" + nowMinute;
597 | }
598 | // 对秒数进行处理,0-9号在前面添加一个“0”
599 | if (nowSecond >= 0 && nowSecond <= 9) {
600 | nowSecond = "0" + nowSecond;
601 | }
602 |
603 | // 最后拼接字符串,得到一个格式为(yyyy-MM-dd)的日期
604 | var nowDate = date.getFullYear() + seperator + nowMonth + seperator + strDate + ` ` + nowhour + seperator1 + nowMinute + seperator1 + nowSecond
605 | return nowDate
606 | }
607 |
608 | function Env(t, e) {
609 | "undefined" != typeof process && JSON.stringify(process.env).indexOf("GITHUB") > -1 && process.exit(0);
610 | class s {
611 | constructor(t) {
612 | this.env = t
613 | }
614 | send(t, e = "GET") {
615 | t = "string" == typeof t ? {
616 | url: t
617 | } : t;
618 | let s = this.get;
619 | return "POST" === e && (s = this.post), new Promise((e, i) => {
620 | s.call(this, t, (t, s, r) => {
621 | t ? i(t) : e(s)
622 | })
623 | })
624 | }
625 | get(t) {
626 | return this.send.call(this.env, t)
627 | }
628 | post(t) {
629 | return this.send.call(this.env, t, "POST")
630 | }
631 | }
632 | return new class {
633 | constructor(t, e) {
634 | this.name = t, this.http = new s(this), this.data = null, this.dataFile = "box.dat", this.logs = [], this.isMute = !1, this.isNeedRewrite = !1, this.logSeparator = "\n", this.startTime = (new Date).getTime(), Object.assign(this, e), this.log("", `🔔${this.name}, 开始!`)
635 | }
636 | isNode() {
637 | return "undefined" != typeof module && !!module.exports
638 | }
639 | isQuanX() {
640 | return "undefined" != typeof $task
641 | }
642 | isSurge() {
643 | return "undefined" != typeof $httpClient && "undefined" == typeof $loon
644 | }
645 | isLoon() {
646 | return "undefined" != typeof $loon
647 | }
648 | toObj(t, e = null) {
649 | try {
650 | return JSON.parse(t)
651 | } catch {
652 | return e
653 | }
654 | }
655 | toStr(t, e = null) {
656 | try {
657 | return JSON.stringify(t)
658 | } catch {
659 | return e
660 | }
661 | }
662 | getjson(t, e) {
663 | let s = e;
664 | const i = this.getdata(t);
665 | if (i) try {
666 | s = JSON.parse(this.getdata(t))
667 | } catch {}
668 | return s
669 | }
670 | setjson(t, e) {
671 | try {
672 | return this.setdata(JSON.stringify(t), e)
673 | } catch {
674 | return !1
675 | }
676 | }
677 | getScript(t) {
678 | return new Promise(e => {
679 | this.get({
680 | url: t
681 | }, (t, s, i) => e(i))
682 | })
683 | }
684 | runScript(t, e) {
685 | return new Promise(s => {
686 | let i = this.getdata("@chavy_boxjs_userCfgs.httpapi");
687 | i = i ? i.replace(/\n/g, "").trim() : i;
688 | let r = this.getdata("@chavy_boxjs_userCfgs.httpapi_timeout");
689 | r = r ? 1 * r : 20, r = e && e.timeout ? e.timeout : r;
690 | const [o, h] = i.split("@"), n = {
691 | url: `http://${h}/v1/scripting/evaluate`,
692 | body: {
693 | script_text: t,
694 | mock_type: "cron",
695 | timeout: r
696 | },
697 | headers: {
698 | "X-Key": o,
699 | Accept: "*/*"
700 | }
701 | };
702 | this.post(n, (t, e, i) => s(i))
703 | }).catch(t => this.logErr(t))
704 | }
705 | loaddata() {
706 | if (!this.isNode()) return {}; {
707 | this.fs = this.fs ? this.fs : require("fs"), this.path = this.path ? this.path : require("path");
708 | const t = this.path.resolve(this.dataFile),
709 | e = this.path.resolve(process.cwd(), this.dataFile),
710 | s = this.fs.existsSync(t),
711 | i = !s && this.fs.existsSync(e);
712 | if (!s && !i) return {}; {
713 | const i = s ? t : e;
714 | try {
715 | return JSON.parse(this.fs.readFileSync(i))
716 | } catch (t) {
717 | return {}
718 | }
719 | }
720 | }
721 | }
722 | writedata() {
723 | if (this.isNode()) {
724 | this.fs = this.fs ? this.fs : require("fs"), this.path = this.path ? this.path : require("path");
725 | const t = this.path.resolve(this.dataFile),
726 | e = this.path.resolve(process.cwd(), this.dataFile),
727 | s = this.fs.existsSync(t),
728 | i = !s && this.fs.existsSync(e),
729 | r = JSON.stringify(this.data);
730 | s ? this.fs.writeFileSync(t, r) : i ? this.fs.writeFileSync(e, r) : this.fs.writeFileSync(t, r)
731 | }
732 | }
733 | lodash_get(t, e, s) {
734 | const i = e.replace(/\[(\d+)\]/g, ".$1").split(".");
735 | let r = t;
736 | for (const t of i)
737 | if (r = Object(r)[t], void 0 === r) return s;
738 | return r
739 | }
740 | lodash_set(t, e, s) {
741 | return Object(t) !== t ? t : (Array.isArray(e) || (e = e.toString().match(/[^.[\]]+/g) || []), e.slice(0, -1).reduce((t, s, i) => Object(t[s]) === t[s] ? t[s] : t[s] = Math.abs(e[i + 1]) >> 0 == +e[i + 1] ? [] : {}, t)[e[e.length - 1]] = s, t)
742 | }
743 | getdata(t) {
744 | let e = this.getval(t);
745 | if (/^@/.test(t)) {
746 | const [, s, i] = /^@(.*?)\.(.*?)$/.exec(t), r = s ? this.getval(s) : "";
747 | if (r) try {
748 | const t = JSON.parse(r);
749 | e = t ? this.lodash_get(t, i, "") : e
750 | } catch (t) {
751 | e = ""
752 | }
753 | }
754 | return e
755 | }
756 | setdata(t, e) {
757 | let s = !1;
758 | if (/^@/.test(e)) {
759 | const [, i, r] = /^@(.*?)\.(.*?)$/.exec(e), o = this.getval(i), h = i ? "null" === o ? null : o || "{}" : "{}";
760 | try {
761 | const e = JSON.parse(h);
762 | this.lodash_set(e, r, t), s = this.setval(JSON.stringify(e), i)
763 | } catch (e) {
764 | const o = {};
765 | this.lodash_set(o, r, t), s = this.setval(JSON.stringify(o), i)
766 | }
767 | } else s = this.setval(t, e);
768 | return s
769 | }
770 | getval(t) {
771 | return this.isSurge() || this.isLoon() ? $persistentStore.read(t) : this.isQuanX() ? $prefs.valueForKey(t) : this.isNode() ? (this.data = this.loaddata(), this.data[t]) : this.data && this.data[t] || null
772 | }
773 | setval(t, e) {
774 | return this.isSurge() || this.isLoon() ? $persistentStore.write(t, e) : this.isQuanX() ? $prefs.setValueForKey(t, e) : this.isNode() ? (this.data = this.loaddata(), this.data[e] = t, this.writedata(), !0) : this.data && this.data[e] || null
775 | }
776 | initGotEnv(t) {
777 | this.got = this.got ? this.got : require("got"), this.cktough = this.cktough ? this.cktough : require("tough-cookie"), this.ckjar = this.ckjar ? this.ckjar : new this.cktough.CookieJar, t && (t.headers = t.headers ? t.headers : {}, void 0 === t.headers.Cookie && void 0 === t.cookieJar && (t.cookieJar = this.ckjar))
778 | }
779 | get(t, e = (() => {})) {
780 | t.headers && (delete t.headers["Content-Type"], delete t.headers["Content-Length"]), this.isSurge() || this.isLoon() ? (this.isSurge() && this.isNeedRewrite && (t.headers = t.headers || {}, Object.assign(t.headers, {
781 | "X-Surge-Skip-Scripting": !1
782 | })), $httpClient.get(t, (t, s, i) => {
783 | !t && s && (s.body = i, s.statusCode = s.status), e(t, s, i)
784 | })) : this.isQuanX() ? (this.isNeedRewrite && (t.opts = t.opts || {}, Object.assign(t.opts, {
785 | hints: !1
786 | })), $task.fetch(t).then(t => {
787 | const {
788 | statusCode: s,
789 | statusCode: i,
790 | headers: r,
791 | body: o
792 | } = t;
793 | e(null, {
794 | status: s,
795 | statusCode: i,
796 | headers: r,
797 | body: o
798 | }, o)
799 | }, t => e(t))) : this.isNode() && (this.initGotEnv(t), this.got(t).on("redirect", (t, e) => {
800 | try {
801 | if (t.headers["set-cookie"]) {
802 | const s = t.headers["set-cookie"].map(this.cktough.Cookie.parse).toString();
803 | s && this.ckjar.setCookieSync(s, null), e.cookieJar = this.ckjar
804 | }
805 | } catch (t) {
806 | this.logErr(t)
807 | }
808 | }).then(t => {
809 | const {
810 | statusCode: s,
811 | statusCode: i,
812 | headers: r,
813 | body: o
814 | } = t;
815 | e(null, {
816 | status: s,
817 | statusCode: i,
818 | headers: r,
819 | body: o
820 | }, o)
821 | }, t => {
822 | const {
823 | message: s,
824 | response: i
825 | } = t;
826 | e(s, i, i && i.body)
827 | }))
828 | }
829 | post(t, e = (() => {})) {
830 | if (t.body && t.headers && !t.headers["Content-Type"] && (t.headers["Content-Type"] = "application/x-www-form-urlencoded"), t.headers && delete t.headers["Content-Length"], this.isSurge() || this.isLoon()) this.isSurge() && this.isNeedRewrite && (t.headers = t.headers || {}, Object.assign(t.headers, {
831 | "X-Surge-Skip-Scripting": !1
832 | })), $httpClient.post(t, (t, s, i) => {
833 | !t && s && (s.body = i, s.statusCode = s.status), e(t, s, i)
834 | });
835 | else if (this.isQuanX()) t.method = "POST", this.isNeedRewrite && (t.opts = t.opts || {}, Object.assign(t.opts, {
836 | hints: !1
837 | })), $task.fetch(t).then(t => {
838 | const {
839 | statusCode: s,
840 | statusCode: i,
841 | headers: r,
842 | body: o
843 | } = t;
844 | e(null, {
845 | status: s,
846 | statusCode: i,
847 | headers: r,
848 | body: o
849 | }, o)
850 | }, t => e(t));
851 | else if (this.isNode()) {
852 | this.initGotEnv(t);
853 | const {
854 | url: s,
855 | ...i
856 | } = t;
857 | this.got.post(s, i).then(t => {
858 | const {
859 | statusCode: s,
860 | statusCode: i,
861 | headers: r,
862 | body: o
863 | } = t;
864 | e(null, {
865 | status: s,
866 | statusCode: i,
867 | headers: r,
868 | body: o
869 | }, o)
870 | }, t => {
871 | const {
872 | message: s,
873 | response: i
874 | } = t;
875 | e(s, i, i && i.body)
876 | })
877 | }
878 | }
879 | time(t, e = null) {
880 | const s = e ? new Date(e) : new Date;
881 | let i = {
882 | "M+": s.getMonth() + 1,
883 | "d+": s.getDate(),
884 | "H+": s.getHours(),
885 | "m+": s.getMinutes(),
886 | "s+": s.getSeconds(),
887 | "q+": Math.floor((s.getMonth() + 3) / 3),
888 | S: s.getMilliseconds()
889 | };
890 | /(y+)/.test(t) && (t = t.replace(RegExp.$1, (s.getFullYear() + "").substr(4 - RegExp.$1.length)));
891 | for (let e in i) new RegExp("(" + e + ")").test(t) && (t = t.replace(RegExp.$1, 1 == RegExp.$1.length ? i[e] : ("00" + i[e]).substr(("" + i[e]).length)));
892 | return t
893 | }
894 | msg(e = t, s = "", i = "", r) {
895 | const o = t => {
896 | if (!t) return t;
897 | if ("string" == typeof t) return this.isLoon() ? t : this.isQuanX() ? {
898 | "open-url": t
899 | } : this.isSurge() ? {
900 | url: t
901 | } : void 0;
902 | if ("object" == typeof t) {
903 | if (this.isLoon()) {
904 | let e = t.openUrl || t.url || t["open-url"],
905 | s = t.mediaUrl || t["media-url"];
906 | return {
907 | openUrl: e,
908 | mediaUrl: s
909 | }
910 | }
911 | if (this.isQuanX()) {
912 | let e = t["open-url"] || t.url || t.openUrl,
913 | s = t["media-url"] || t.mediaUrl;
914 | return {
915 | "open-url": e,
916 | "media-url": s
917 | }
918 | }
919 | if (this.isSurge()) {
920 | let e = t.url || t.openUrl || t["open-url"];
921 | return {
922 | url: e
923 | }
924 | }
925 | }
926 | };
927 | if (this.isMute || (this.isSurge() || this.isLoon() ? $notification.post(e, s, i, o(r)) : this.isQuanX() && $notify(e, s, i, o(r))), !this.isMuteLog) {
928 | let t = ["", "==============📣系统通知📣=============="];
929 | t.push(e), s && t.push(s), i && t.push(i), console.log(t.join("\n")), this.logs = this.logs.concat(t)
930 | }
931 | }
932 | log(...t) {
933 | t.length > 0 && (this.logs = [...this.logs, ...t]), console.log(t.join(this.logSeparator))
934 | }
935 | logErr(t, e) {
936 | const s = !this.isSurge() && !this.isQuanX() && !this.isLoon();
937 | s ? this.log("", `❗️${this.name}, 错误!`, t.stack) : this.log("", `❗️${this.name}, 错误!`, t)
938 | }
939 | wait(t) {
940 | return new Promise(e => setTimeout(e, t))
941 | }
942 | done(t = {}) {
943 | const e = (new Date).getTime(),
944 | s = (e - this.startTime) / 1e3;
945 | this.log("", `🔔${this.name}, 结束! 🕛 ${s} 秒`), this.log(), (this.isSurge() || this.isQuanX() || this.isLoon()) && $done(t)
946 | }
947 | }(t, e)
948 | }
949 |
--------------------------------------------------------------------------------
/wzxy_qd.js:
--------------------------------------------------------------------------------
1 | /**
2 | * 作者QQ: 1483081359 欢迎前来提交bug
3 | * github仓库:https://github.com/zhacha222/wozaixiaoyuan
4 | * 微信小程序:我在校园 签到
5 | * 脚本说明:适用于我在校园所有类型的签到,包括定位、蓝牙签到等···
6 | * 默认定时:默认不自动运行,在签到发布后,需要手动运行一次此脚本(当然,如果你有定时的签到,也可以自己去修改定时规则,在签到时间内定时运行该脚本即可)
7 | * cron: 0
8 | * 变量名称:wzxy
9 | * 变量值: {
10 | "username": "手机号",
11 | "password": "密码",
12 | "qd_location": "133.333333,33.333333",
13 | "rjrb_answers": ["0","0"],
14 | "rjrb_location": "133.333333,33.333333",
15 | "jkdk_answers": ["0","无","1","0","36.2","没有","1","1","2"],
16 | "jkdk_location": "133.333333,33.333333",
17 | "mark": "用户昵称"
18 | }
19 |
20 | ***一些前提说明:
21 | 1.只支持青龙面板(本人青龙版本2.10.13),搭建教程自行百度
22 | 2.本库脚本通用 wzxy这一个变量
23 | 3.脚本变量只推荐在青龙的【环境变量】页添加,有强迫症在【配置文件】config.sh中添加的如果出现问题自己解决
24 | 4.支持多用户,每一用户在【环境变量】单独新建变量wzxy,切勿一个变量内填写多个用户的参数
25 | 5.脚本通知方式采用青龙面板默认通知,请在【配置文件】config.sh里配置
26 | 6.关于各脚本的具体使用方法,请阅读脚本内的注释
27 |
28 | ***关于变量值中各参数的解释:
29 | username ———————— 手机号
30 | password —————————密码
31 | qd_location ————— 签到的`经纬度` (wzxy_qd.js)
32 | rjrb_answers —————日检日报的`填空参数`(wzxy_rjrb.js)
33 | rjrb_location ————日检日报的`经纬度` (wzxy_rjrb.js)
34 | jkdk_answers ———— 健康签到的`填空参数`(wzxy_jkdk.js)
35 | jkdk_location ————健康签到的`经纬度` (wzxy_jkdk.js)
36 | mark —————————————用户昵称(不一定要真名,随便填都行,便于自己区分打卡用户)
37 |
38 | 更新日志:
39 | 1.0.0 完成签到的基本功能
40 | 1.0.1 增加等待15s,防止黑ip
41 | 1.0.2 增加完整参数验证
42 | 1.0.5 修复地址信息请求失败的bug
43 | 1.0.6 优化通知
44 | 1.0.7 log增加新版本内容
45 | 1.0.8 增加`仅通知签到失败`模式,在脚本第52行修改开启
46 |
47 | */
48 | //cron: 0
49 |
50 | //===============通知设置=================//
51 | const Notify = 1; //0为关闭通知,1为打开通知,默认为1
52 | const OnlyErrorNotify = 0; //0为关闭`仅通知签到失败`模式,1为打开`仅通知签到失败`模式,默认为0
53 | ////////////////////////////////////////////
54 |
55 | const $ = new Env('我在校园签到');
56 | const notify = $.isNode() ? require('./sendNotify') : '';
57 | const fs = require("fs");
58 | const request = require('request');
59 | const {log} = console;
60 |
61 | //////////////////////
62 | let scriptVersion = "1.0.8";
63 | let scriptVersionLatest = '';
64 | let update_data = "1.0.8 增加`仅通知签到失败`模式,可在脚本第52行修改开启"; //新版本更新内容
65 | //我在校园账号数据
66 | let wzxy = ($.isNode() ? process.env.wzxy : $.getdata("wzxy")) || "";
67 | let wzxyArr = [];
68 | let wait = 0;
69 | let checkBack = 0;
70 | let loginBack = 0;
71 | let PunchInBack = 0;
72 | let requestAddressBack = 0;
73 | let msg = '';
74 | let jwsession = '';
75 | let location = '';
76 | let signId = '';
77 | let id = '';
78 | let sign_data = '';
79 | let status_code = 0;
80 | let locat = '';
81 | let fail = 0;
82 |
83 | !(async () => {
84 | if (typeof $request !== "undefined") {
85 | await GetRewrite();
86 | } else {
87 | if (!(await Envs()))
88 | return;
89 | else {
90 |
91 | log(`\n\n============================================= \n脚本执行 - 北京时间(UTC+8):${new Date(
92 | new Date().getTime() + new Date().getTimezoneOffset() * 60 * 1000 +
93 | 8 * 60 * 60 * 1000).toLocaleString()} \n=============================================\n`);
94 |
95 | await poem();
96 | await getVersion();
97 |
98 | log(`\n============ 当前版本:${scriptVersion} 最新版本:${scriptVersionLatest} ============`)
99 |
100 | if(scriptVersionLatest != scriptVersion){
101 | log(`\n发现新版本,请及时拉库更新!\n${update_data}`)
102 | }
103 |
104 | log(`\n=================== 共找到 ${wzxyArr.length} 个账号 ===================`)
105 |
106 |
107 | for (let index = 0; index < wzxyArr.length; index++) {
108 |
109 |
110 | let num = index + 1
111 | if (num >1 && wait == 0){
112 | log('**********休息15s,防止黑IP**********');
113 | await $.wait(16 * 1000);
114 | }
115 | log(`\n========= 开始【第 ${num} 个账号】=========\n`)
116 | data = wzxyArr[index];
117 | content = JSON.parse(data)
118 | username = content.username
119 | password = content.password
120 | location = content.qd_location
121 | mark = content.mark
122 |
123 | log(`签到用户:${mark}`)
124 | var checkBack = 0;
125 | loginBack = 0;
126 | locat = location.split(',')
127 | if (!locat[0] || !locat[1]){
128 | log('未填写qd_location,跳过打卡');
129 | var checkBack = 1
130 | status_code = 6
131 | wait = 1
132 | }
133 | if (checkBack == 0) {
134 | log('开始检查jwsession是否存在...');
135 | await checkJwsession()
136 | await $.wait(2 * 1000);
137 |
138 | if (loginBack) {
139 |
140 | log('开始获取签到列表...');
141 | await PunchIn()
142 | await $.wait(2 * 1000);
143 |
144 | if (PunchInBack > 0) {
145 | log('正在请求地址信息...');
146 | await requestAddress()
147 | await $.wait(2 * 1000);
148 |
149 | if (requestAddressBack) {
150 | log('开始签到...');
151 | await doPunchIn()
152 | await $.wait(2 * 1000);
153 |
154 | }
155 |
156 | }
157 |
158 | }
159 | }
160 | var resultlog = getResult()
161 |
162 | if (OnlyErrorNotify>0){
163 | if (status_code != 1 ){
164 | msg += `签到用户:${mark}\n签到情况:${resultlog}\n\n`
165 | fail=fail+1
166 | }
167 | }else {
168 | msg += `签到用户:${mark}\n签到情况:${resultlog}\n\n`
169 | }
170 |
171 | }
172 | if (OnlyErrorNotify>0){
173 |
174 | if(fail==0){
175 | msg=`共${wzxyArr.length}个用户,全部签到成功 ✅ `
176 | }else{
177 | msg=`共${wzxyArr.length}个用户,❌ 失败${fail}个\n\n===========失败详情=============\n\n`+msg
178 | }
179 | }
180 |
181 | // log(msg);
182 | await SendMsg(msg);
183 | }
184 | }
185 |
186 | })()
187 | .catch((e) => log(e))
188 | .finally(() => $.done())
189 |
190 | /**
191 | * 判断jwsession是否存在
192 | */
193 | function checkJwsession() {
194 |
195 | fs.open('.cache/' + username + ".json", 'r+', function(err, fd) {
196 | if (err) {
197 | console.error("找不到cache文件,正在使用账号信息登录...")
198 | login()
199 | return
200 | }
201 | console.log("找到cache文件,正在使用jwsession签到...")
202 | var read = fs.readFileSync('.cache/' + username + ".json")
203 | jwsession = read.toString()
204 | loginBack = 1
205 |
206 | });
207 |
208 | }
209 |
210 |
211 | /**
212 | * 登录
213 | */
214 | function login(timeout = 3 * 1000) {
215 | return new Promise((resolve) => {
216 | let url = {
217 | url: `https://gw.wozaixiaoyuan.com/basicinfo/mobile/login/username?username=${username}&password=${password}`,
218 | headers: {
219 | "Accept-Encoding": "gzip, deflate, br",
220 | "Connection": "keep-alive",
221 | "User-Agent": "Mozilla/5.0 (iPad; CPU OS 15_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.23(0x1800172f) NetType/WIFI Language/zh_CN miniProgram/wxce6d08f781975d91",
222 | "content-type": "application/json;charset=UTF-8",
223 | "Content-Length": "2",
224 | "Host": "gw.wozaixiaoyuan.com",
225 | "Accept-Language": "en-us,en",
226 | "Accept": "application/json, text/plain, */*"
227 | },
228 | data: ``,
229 | }
230 | request.post(url, async (error, response, data) => {
231 | try {
232 | let result = data == "undefined" ? await login() : JSON.parse(data);
233 | //登录成功
234 | if (result.code == 0 ) {
235 | jwsession = response.headers['jwsession']
236 | //储存jwsession
237 | setJwsession(jwsession)
238 | loginBack = 1;
239 | log(`登录成功`)
240 |
241 | } else {
242 | log(`❌ 登录失败,${result.message}`)
243 | status_code = 5;
244 | loginBack = 0;
245 | }
246 |
247 | } catch (e) {
248 | log(e)
249 | } finally {
250 | resolve();
251 | }
252 | }, timeout)
253 | })
254 | }
255 |
256 |
257 | /**
258 | * 存储jwsession
259 | */
260 | function setJwsession(jwsession) {
261 |
262 | fs.mkdir('.cache',function(err){
263 | if (err) {
264 |
265 | console.log("找到cache文件");
266 | }
267 | else console.log("正在创建cache储存目录与文件...");
268 | });
269 |
270 | fs.writeFile('.cache/' + username + ".json", jwsession, function(err) {
271 | if (err) {
272 | return console.error(err);
273 | }
274 | console.log("更新jwsession成功");
275 | })
276 |
277 | }
278 |
279 |
280 | /**
281 | * 获取签到列表,符合条件则自动进行签到
282 | */
283 | function PunchIn(timeout = 3 * 1000) {
284 | return new Promise((resolve) => {
285 |
286 | let url = {
287 | url: "https://student.wozaixiaoyuan.com/sign/getSignMessage.json",
288 | headers: {
289 | 'jwsession': jwsession,
290 | },
291 | body: 'page=1&size=5'
292 | }
293 |
294 | $.post(url, async (error, response, data) => {
295 |
296 | try {
297 | let result = data == "undefined" ? await PunchIn() : JSON.parse(data);
298 |
299 | if (result.code == -10) {
300 | log('jwsession 无效,尝试账号密码签到')
301 | status_code = 4;
302 | PunchInBack = 0;
303 | loginBack = 0;
304 | await login()
305 | await $.wait(2 * 1000);
306 | if (loginBack > 0) {
307 | log('重新获取签到列表...');
308 | await PunchIn()
309 | await $.wait(2 * 1000)
310 | return
311 | }
312 | }
313 | if (result.code == 0) {
314 | sign_message = result.data[0]
315 | id= sign_message.logId
316 | signId= sign_message.id
317 | log("获取成功,开始签到")
318 | PunchInBack = 1
319 | }
320 |
321 | } catch (e) {
322 | log(e)
323 | } finally {
324 | resolve();
325 | }
326 | }, timeout)
327 | })
328 | }
329 |
330 |
331 | /**
332 | * 请求地址信息
333 | */
334 | function requestAddress(timeout = 3 * 1000) {
335 | return new Promise((resolve) => {
336 | location = location.split(',')
337 | let url = {
338 | url: `https://apis.map.qq.com/ws/geocoder/v1/?key=A3YBZ-NC5RU-MFYVV-BOHND-RO3OT-ABFCR&location=${location[1]},${location[0]}`,
339 | }
340 | $.get(url, async (error, response, data) => {
341 | try {
342 | let result = data == "undefined" ? await requestAddress() : JSON.parse(data);
343 | if (result.status == 0) {
344 | log(`地址信息获取成功`);
345 | try {town=result.result.address_reference.town.title}catch (e) {town=``}
346 | try {street=result.result.address_reference.street.title}catch (e) {street=``}
347 | data = {
348 | "latitude": location[1],
349 | "longitude": location[0],
350 | "country": encodeURI('中国'),
351 | "district": encodeURI(result.result.address_component.district),
352 | "province": encodeURI(result.result.address_component.province),
353 | "township": encodeURI(town),
354 | "towncode": "0",
355 | "citycode": "0",
356 | "street": encodeURI(street),
357 | "id": id,
358 | "signId": signId,
359 | }
360 | sign_data = JSON.stringify(data)
361 | requestAddressBack = 1
362 | } else {
363 | log(`❌ 地址信息获取失败`)
364 | requestAddressBack = 0
365 | }
366 |
367 | } catch (e) {
368 | log(e)
369 | } finally {
370 | resolve();
371 | }
372 | }, timeout)
373 | })
374 | }
375 |
376 |
377 | /**
378 | * 开始签到
379 | */
380 | function doPunchIn(timeout = 3 * 1000) {
381 | return new Promise((resolve) => {
382 | let url = {
383 | url: "https://student.wozaixiaoyuan.com/sign/doSign.json",
384 | headers: {
385 | 'jwsession': jwsession,
386 | 'Content-Type': 'application/json'
387 | },
388 | body: sign_data,
389 | }
390 |
391 | $.post(url, async (error, response, data) => {
392 | try {
393 | let result = data == "undefined" ? await doPunchIn() : JSON.parse(data);
394 | if (result.code == 0){
395 | log("✅ 签到成功")
396 | status_code = 1
397 | }
398 | else {
399 | log("❌ 签到失败,原因:"+data)
400 | }
401 |
402 | } catch (e) {
403 | log(e)
404 | } finally {
405 | resolve();
406 | }
407 | }, timeout)
408 | })
409 | }
410 |
411 |
412 | /**
413 | * 获取签到结果
414 | */
415 | function getResult(timeout = 3 * 1000) {
416 | res = status_code
417 | if (res == 1) return "✅ 签到成功"
418 | if (res == 2) return "✅ 你已经签过到了,无需重复签到"
419 | if (res == 3) return "❌ 签到失败,当前不在签到时间段内"
420 | if (res == 4) return "❌ 签到失败,jwsession 无效"
421 | if (res == 5) return "❌ 签到失败,登录错误,请检查账号信息"
422 | if (res == 6) return "❌ 跳过打卡,变量参数不完整"
423 | else return "❌ 签到失败,发生未知错误"
424 | }
425 |
426 |
427 | // ============================================变量检查============================================ \\
428 | async function Envs() {
429 | if (wzxy) {
430 | if (wzxy.indexOf("@") != -1 || wzxy.indexOf("&") != -1) {
431 | wzxy.split("@"&&"&").forEach((item) => {
432 | wzxyArr.push(item);
433 | });
434 | }
435 | // else if (wzxy.indexOf("\n") != -1) {
436 | // wzxy.split("\n").forEach((item) => {
437 | // wzxyArr.push(item);
438 | // });
439 | // }
440 | else {
441 | wzxyArr.push(wzxy);
442 | }
443 | } else {
444 | log(`\n 未填写变量 wzxy`)
445 | return;
446 | }
447 |
448 | return true;
449 | }
450 | // ============================================发送消息============================================ \\
451 | async function SendMsg(msg) {
452 | if (!msg)
453 | return;
454 |
455 | if (Notify > 0) {
456 | if ($.isNode()) {
457 | var notify = require('./sendNotify');
458 | await notify.sendNotify($.name, msg+ `\n签到时间:${t()}\n`);
459 | } else {
460 | $.msg(msg);
461 | }
462 | } else {
463 | //log(msg);
464 | }
465 | }
466 |
467 |
468 |
469 | /**
470 | * 获取当前小时数
471 | */
472 | function local_hours() {
473 | let myDate = new Date();
474 | let h = myDate.getHours();
475 | return h;
476 | }
477 |
478 | /**
479 | * 获取当前分钟数
480 | */
481 | function local_minutes() {
482 | let myDate = new Date();
483 | let m = myDate.getMinutes();
484 | return m;
485 | }
486 |
487 | /**
488 | * 随机数生成
489 | */
490 | function randomString(e) {
491 | e = e || 32;
492 | var t = "QWERTYUIOPASDFGHJKLZXCVBNM1234567890",
493 | a = t.length,
494 | n = "";
495 | for (i = 0; i < e; i++)
496 | n += t.charAt(Math.floor(Math.random() * a));
497 | return n
498 | }
499 |
500 | /**
501 | * 随机整数生成
502 | */
503 | function randomInt(min, max) {
504 | return Math.round(Math.random() * (max - min) + min)
505 | }
506 |
507 | /**
508 | * 获取毫秒时间戳
509 | */
510 | function timestampMs(){
511 | return new Date().getTime();
512 | }
513 |
514 | /**
515 | *
516 | * 获取秒时间戳
517 | */
518 | function timestampS(){
519 | return Date.parse(new Date())/1000;
520 | }
521 |
522 | /**
523 | * 获取随机诗词
524 | */
525 | function poem(timeout = 3 * 1000) {
526 | return new Promise((resolve) => {
527 | let url = {
528 | url: `https://v1.jinrishici.com/all.json`
529 | }
530 | $.get(url, async (err, resp, data) => {
531 | try {
532 | data = JSON.parse(data)
533 | log(`${data.content} \n————《${data.origin}》${data.author}`);
534 | } catch (e) {
535 | log(e, resp);
536 | } finally {
537 | resolve()
538 | }
539 | }, timeout)
540 | })
541 | }
542 |
543 | /**
544 | * 修改配置文件
545 | */
546 | function modify() {
547 |
548 | fs.readFile('/ql/data/config/config.sh','utf8',function(err,dataStr){
549 | if(err){
550 | return log('读取文件失败!'+err)
551 | }
552 | else {
553 | var result = dataStr.replace(/regular/g,string);
554 | fs.writeFile('/ql/data/config/config.sh', result, 'utf8', function (err) {
555 | if (err) {return log(err);}
556 | });
557 | }
558 | })
559 | }
560 |
561 | /**
562 | * 获取远程版本
563 | */
564 | function getVersion(timeout = 3 * 1000) {
565 | return new Promise((resolve) => {
566 | let url = {
567 | url: `https://ghproxy.com/https://raw.githubusercontent.com/zhacha222/wozaixiaoyuan/main/wzxy_qd.js`,
568 | }
569 | $.get(url, async (err, resp, data) => {
570 | try {
571 | scriptVersionLatest = data.match(/scriptVersion = "([\d\.]+)"/)[1]
572 | update_data = data.match(/update_data = "(.*?)"/)[1]
573 | } catch (e) {
574 | $.logErr(e, resp);
575 | } finally {
576 | resolve()
577 | }
578 | }, timeout)
579 | })
580 | }
581 |
582 | /**
583 | * time 输出格式:1970-01-01 00:00:00
584 | */
585 | function t() {
586 | var date = new Date();
587 | // 获取当前月份
588 | var nowMonth = date.getMonth() + 1;
589 | // 获取当前是几号
590 | var strDate = date.getDate();
591 | //获取当前小时(0-23)
592 | var nowhour = date.getHours()
593 | //获取当前分钟(0-59)
594 | var nowMinute = date.getMinutes()
595 | //获取当前秒数(0-59)
596 | var nowSecond = date.getSeconds();
597 | // 添加分隔符“-”
598 | var seperator = "-";
599 | // 添加分隔符“:”
600 | var seperator1 = ":";
601 |
602 | // 对月份进行处理,1-9月在前面添加一个“0”
603 | if (nowMonth >= 1 && nowMonth <= 9) {
604 | nowMonth = "0" + nowMonth;
605 | }
606 | // 对月份进行处理,1-9号在前面添加一个“0”
607 | if (strDate >= 0 && strDate <= 9) {
608 | strDate = "0" + strDate;
609 | }
610 | // 对小时进行处理,0-9号在前面添加一个“0”
611 | if (nowhour >= 0 && nowhour <= 9) {
612 | nowhour = "0" + nowhour;
613 | }
614 | // 对分钟进行处理,0-9号在前面添加一个“0”
615 | if (nowMinute >= 0 && nowMinute <= 9) {
616 | nowMinute = "0" + nowMinute;
617 | }
618 | // 对秒数进行处理,0-9号在前面添加一个“0”
619 | if (nowSecond >= 0 && nowSecond <= 9) {
620 | nowSecond = "0" + nowSecond;
621 | }
622 |
623 | // 最后拼接字符串,得到一个格式为(yyyy-MM-dd)的日期
624 | var nowDate = date.getFullYear() + seperator + nowMonth + seperator + strDate + ` ` + nowhour + seperator1 + nowMinute + seperator1 + nowSecond
625 | return nowDate
626 | }
627 |
628 | function Env(t, e) {
629 | "undefined" != typeof process && JSON.stringify(process.env).indexOf("GITHUB") > -1 && process.exit(0);
630 | class s {
631 | constructor(t) {
632 | this.env = t
633 | }
634 | send(t, e = "GET") {
635 | t = "string" == typeof t ? {
636 | url: t
637 | } : t;
638 | let s = this.get;
639 | return "POST" === e && (s = this.post), new Promise((e, i) => {
640 | s.call(this, t, (t, s, r) => {
641 | t ? i(t) : e(s)
642 | })
643 | })
644 | }
645 | get(t) {
646 | return this.send.call(this.env, t)
647 | }
648 | post(t) {
649 | return this.send.call(this.env, t, "POST")
650 | }
651 | }
652 | return new class {
653 | constructor(t, e) {
654 | this.name = t, this.http = new s(this), this.data = null, this.dataFile = "box.dat", this.logs = [], this.isMute = !1, this.isNeedRewrite = !1, this.logSeparator = "\n", this.startTime = (new Date).getTime(), Object.assign(this, e), this.log("", `🔔${this.name}, 开始!`)
655 | }
656 | isNode() {
657 | return "undefined" != typeof module && !!module.exports
658 | }
659 | isQuanX() {
660 | return "undefined" != typeof $task
661 | }
662 | isSurge() {
663 | return "undefined" != typeof $httpClient && "undefined" == typeof $loon
664 | }
665 | isLoon() {
666 | return "undefined" != typeof $loon
667 | }
668 | toObj(t, e = null) {
669 | try {
670 | return JSON.parse(t)
671 | } catch {
672 | return e
673 | }
674 | }
675 | toStr(t, e = null) {
676 | try {
677 | return JSON.stringify(t)
678 | } catch {
679 | return e
680 | }
681 | }
682 | getjson(t, e) {
683 | let s = e;
684 | const i = this.getdata(t);
685 | if (i) try {
686 | s = JSON.parse(this.getdata(t))
687 | } catch {}
688 | return s
689 | }
690 | setjson(t, e) {
691 | try {
692 | return this.setdata(JSON.stringify(t), e)
693 | } catch {
694 | return !1
695 | }
696 | }
697 | getScript(t) {
698 | return new Promise(e => {
699 | this.get({
700 | url: t
701 | }, (t, s, i) => e(i))
702 | })
703 | }
704 | runScript(t, e) {
705 | return new Promise(s => {
706 | let i = this.getdata("@chavy_boxjs_userCfgs.httpapi");
707 | i = i ? i.replace(/\n/g, "").trim() : i;
708 | let r = this.getdata("@chavy_boxjs_userCfgs.httpapi_timeout");
709 | r = r ? 1 * r : 20, r = e && e.timeout ? e.timeout : r;
710 | const [o, h] = i.split("@"), n = {
711 | url: `http://${h}/v1/scripting/evaluate`,
712 | body: {
713 | script_text: t,
714 | mock_type: "cron",
715 | timeout: r
716 | },
717 | headers: {
718 | "X-Key": o,
719 | Accept: "*/*"
720 | }
721 | };
722 | this.post(n, (t, e, i) => s(i))
723 | }).catch(t => this.logErr(t))
724 | }
725 | loaddata() {
726 | if (!this.isNode()) return {}; {
727 | this.fs = this.fs ? this.fs : require("fs"), this.path = this.path ? this.path : require("path");
728 | const t = this.path.resolve(this.dataFile),
729 | e = this.path.resolve(process.cwd(), this.dataFile),
730 | s = this.fs.existsSync(t),
731 | i = !s && this.fs.existsSync(e);
732 | if (!s && !i) return {}; {
733 | const i = s ? t : e;
734 | try {
735 | return JSON.parse(this.fs.readFileSync(i))
736 | } catch (t) {
737 | return {}
738 | }
739 | }
740 | }
741 | }
742 | writedata() {
743 | if (this.isNode()) {
744 | this.fs = this.fs ? this.fs : require("fs"), this.path = this.path ? this.path : require("path");
745 | const t = this.path.resolve(this.dataFile),
746 | e = this.path.resolve(process.cwd(), this.dataFile),
747 | s = this.fs.existsSync(t),
748 | i = !s && this.fs.existsSync(e),
749 | r = JSON.stringify(this.data);
750 | s ? this.fs.writeFileSync(t, r) : i ? this.fs.writeFileSync(e, r) : this.fs.writeFileSync(t, r)
751 | }
752 | }
753 | lodash_get(t, e, s) {
754 | const i = e.replace(/\[(\d+)\]/g, ".$1").split(".");
755 | let r = t;
756 | for (const t of i)
757 | if (r = Object(r)[t], void 0 === r) return s;
758 | return r
759 | }
760 | lodash_set(t, e, s) {
761 | return Object(t) !== t ? t : (Array.isArray(e) || (e = e.toString().match(/[^.[\]]+/g) || []), e.slice(0, -1).reduce((t, s, i) => Object(t[s]) === t[s] ? t[s] : t[s] = Math.abs(e[i + 1]) >> 0 == +e[i + 1] ? [] : {}, t)[e[e.length - 1]] = s, t)
762 | }
763 | getdata(t) {
764 | let e = this.getval(t);
765 | if (/^@/.test(t)) {
766 | const [, s, i] = /^@(.*?)\.(.*?)$/.exec(t), r = s ? this.getval(s) : "";
767 | if (r) try {
768 | const t = JSON.parse(r);
769 | e = t ? this.lodash_get(t, i, "") : e
770 | } catch (t) {
771 | e = ""
772 | }
773 | }
774 | return e
775 | }
776 | setdata(t, e) {
777 | let s = !1;
778 | if (/^@/.test(e)) {
779 | const [, i, r] = /^@(.*?)\.(.*?)$/.exec(e), o = this.getval(i), h = i ? "null" === o ? null : o || "{}" : "{}";
780 | try {
781 | const e = JSON.parse(h);
782 | this.lodash_set(e, r, t), s = this.setval(JSON.stringify(e), i)
783 | } catch (e) {
784 | const o = {};
785 | this.lodash_set(o, r, t), s = this.setval(JSON.stringify(o), i)
786 | }
787 | } else s = this.setval(t, e);
788 | return s
789 | }
790 | getval(t) {
791 | return this.isSurge() || this.isLoon() ? $persistentStore.read(t) : this.isQuanX() ? $prefs.valueForKey(t) : this.isNode() ? (this.data = this.loaddata(), this.data[t]) : this.data && this.data[t] || null
792 | }
793 | setval(t, e) {
794 | return this.isSurge() || this.isLoon() ? $persistentStore.write(t, e) : this.isQuanX() ? $prefs.setValueForKey(t, e) : this.isNode() ? (this.data = this.loaddata(), this.data[e] = t, this.writedata(), !0) : this.data && this.data[e] || null
795 | }
796 | initGotEnv(t) {
797 | this.got = this.got ? this.got : require("got"), this.cktough = this.cktough ? this.cktough : require("tough-cookie"), this.ckjar = this.ckjar ? this.ckjar : new this.cktough.CookieJar, t && (t.headers = t.headers ? t.headers : {}, void 0 === t.headers.Cookie && void 0 === t.cookieJar && (t.cookieJar = this.ckjar))
798 | }
799 | get(t, e = (() => {})) {
800 | t.headers && (delete t.headers["Content-Type"], delete t.headers["Content-Length"]), this.isSurge() || this.isLoon() ? (this.isSurge() && this.isNeedRewrite && (t.headers = t.headers || {}, Object.assign(t.headers, {
801 | "X-Surge-Skip-Scripting": !1
802 | })), $httpClient.get(t, (t, s, i) => {
803 | !t && s && (s.body = i, s.statusCode = s.status), e(t, s, i)
804 | })) : this.isQuanX() ? (this.isNeedRewrite && (t.opts = t.opts || {}, Object.assign(t.opts, {
805 | hints: !1
806 | })), $task.fetch(t).then(t => {
807 | const {
808 | statusCode: s,
809 | statusCode: i,
810 | headers: r,
811 | body: o
812 | } = t;
813 | e(null, {
814 | status: s,
815 | statusCode: i,
816 | headers: r,
817 | body: o
818 | }, o)
819 | }, t => e(t))) : this.isNode() && (this.initGotEnv(t), this.got(t).on("redirect", (t, e) => {
820 | try {
821 | if (t.headers["set-cookie"]) {
822 | const s = t.headers["set-cookie"].map(this.cktough.Cookie.parse).toString();
823 | s && this.ckjar.setCookieSync(s, null), e.cookieJar = this.ckjar
824 | }
825 | } catch (t) {
826 | this.logErr(t)
827 | }
828 | }).then(t => {
829 | const {
830 | statusCode: s,
831 | statusCode: i,
832 | headers: r,
833 | body: o
834 | } = t;
835 | e(null, {
836 | status: s,
837 | statusCode: i,
838 | headers: r,
839 | body: o
840 | }, o)
841 | }, t => {
842 | const {
843 | message: s,
844 | response: i
845 | } = t;
846 | e(s, i, i && i.body)
847 | }))
848 | }
849 | post(t, e = (() => {})) {
850 | if (t.body && t.headers && !t.headers["Content-Type"] && (t.headers["Content-Type"] = "application/x-www-form-urlencoded"), t.headers && delete t.headers["Content-Length"], this.isSurge() || this.isLoon()) this.isSurge() && this.isNeedRewrite && (t.headers = t.headers || {}, Object.assign(t.headers, {
851 | "X-Surge-Skip-Scripting": !1
852 | })), $httpClient.post(t, (t, s, i) => {
853 | !t && s && (s.body = i, s.statusCode = s.status), e(t, s, i)
854 | });
855 | else if (this.isQuanX()) t.method = "POST", this.isNeedRewrite && (t.opts = t.opts || {}, Object.assign(t.opts, {
856 | hints: !1
857 | })), $task.fetch(t).then(t => {
858 | const {
859 | statusCode: s,
860 | statusCode: i,
861 | headers: r,
862 | body: o
863 | } = t;
864 | e(null, {
865 | status: s,
866 | statusCode: i,
867 | headers: r,
868 | body: o
869 | }, o)
870 | }, t => e(t));
871 | else if (this.isNode()) {
872 | this.initGotEnv(t);
873 | const {
874 | url: s,
875 | ...i
876 | } = t;
877 | this.got.post(s, i).then(t => {
878 | const {
879 | statusCode: s,
880 | statusCode: i,
881 | headers: r,
882 | body: o
883 | } = t;
884 | e(null, {
885 | status: s,
886 | statusCode: i,
887 | headers: r,
888 | body: o
889 | }, o)
890 | }, t => {
891 | const {
892 | message: s,
893 | response: i
894 | } = t;
895 | e(s, i, i && i.body)
896 | })
897 | }
898 | }
899 | time(t, e = null) {
900 | const s = e ? new Date(e) : new Date;
901 | let i = {
902 | "M+": s.getMonth() + 1,
903 | "d+": s.getDate(),
904 | "H+": s.getHours(),
905 | "m+": s.getMinutes(),
906 | "s+": s.getSeconds(),
907 | "q+": Math.floor((s.getMonth() + 3) / 3),
908 | S: s.getMilliseconds()
909 | };
910 | /(y+)/.test(t) && (t = t.replace(RegExp.$1, (s.getFullYear() + "").substr(4 - RegExp.$1.length)));
911 | for (let e in i) new RegExp("(" + e + ")").test(t) && (t = t.replace(RegExp.$1, 1 == RegExp.$1.length ? i[e] : ("00" + i[e]).substr(("" + i[e]).length)));
912 | return t
913 | }
914 | msg(e = t, s = "", i = "", r) {
915 | const o = t => {
916 | if (!t) return t;
917 | if ("string" == typeof t) return this.isLoon() ? t : this.isQuanX() ? {
918 | "open-url": t
919 | } : this.isSurge() ? {
920 | url: t
921 | } : void 0;
922 | if ("object" == typeof t) {
923 | if (this.isLoon()) {
924 | let e = t.openUrl || t.url || t["open-url"],
925 | s = t.mediaUrl || t["media-url"];
926 | return {
927 | openUrl: e,
928 | mediaUrl: s
929 | }
930 | }
931 | if (this.isQuanX()) {
932 | let e = t["open-url"] || t.url || t.openUrl,
933 | s = t["media-url"] || t.mediaUrl;
934 | return {
935 | "open-url": e,
936 | "media-url": s
937 | }
938 | }
939 | if (this.isSurge()) {
940 | let e = t.url || t.openUrl || t["open-url"];
941 | return {
942 | url: e
943 | }
944 | }
945 | }
946 | };
947 | if (this.isMute || (this.isSurge() || this.isLoon() ? $notification.post(e, s, i, o(r)) : this.isQuanX() && $notify(e, s, i, o(r))), !this.isMuteLog) {
948 | let t = ["", "==============📣系统通知📣=============="];
949 | t.push(e), s && t.push(s), i && t.push(i), console.log(t.join("\n")), this.logs = this.logs.concat(t)
950 | }
951 | }
952 | log(...t) {
953 | t.length > 0 && (this.logs = [...this.logs, ...t]), console.log(t.join(this.logSeparator))
954 | }
955 | logErr(t, e) {
956 | const s = !this.isSurge() && !this.isQuanX() && !this.isLoon();
957 | s ? this.log("", `❗️${this.name}, 错误!`, t.stack) : this.log("", `❗️${this.name}, 错误!`, t)
958 | }
959 | wait(t) {
960 | return new Promise(e => setTimeout(e, t))
961 | }
962 | done(t = {}) {
963 | const e = (new Date).getTime(),
964 | s = (e - this.startTime) / 1e3;
965 | this.log("", `🔔${this.name}, 结束! 🕛 ${s} 秒`), this.log(), (this.isSurge() || this.isQuanX() || this.isLoon()) && $done(t)
966 | }
967 | }(t, e)
968 | }
969 |
--------------------------------------------------------------------------------
/wzxy_rjrb.js:
--------------------------------------------------------------------------------
1 | /**
2 | * 作者QQ: 1483081359 欢迎前来提交bug
3 | * github仓库:https://github.com/zhacha222/wozaixiaoyuan
4 | * 微信小程序:我在校园 日检日报
5 | * 脚本说明:如果打卡不止两次,自己去修改改定时,在打卡时间段内运行该脚本即可
6 | * 默认定时:默认每天 8点5分 和 16点5分 运行两次。
7 | * cron: 5 8,16 * * *
8 | * 变量名称:wzxy
9 | * 变量值: {
10 | "username": "手机号",
11 | "password": "密码",
12 | "qd_location": "133.333333,33.333333",
13 | "rjrb_answers": ["0","0"],
14 | "rjrb_location": "133.333333,33.333333",
15 | "jkdk_answers": ["0","无","1","0","36.2","没有","1","1","2"],
16 | "jkdk_location": "133.333333,33.333333",
17 | "mark": "用户昵称"
18 | }
19 |
20 | ***一些前提说明:
21 | 1.只支持青龙面板(本人青龙版本2.10.13),搭建教程自行百度
22 | 2.本库脚本通用 wzxy这一个变量
23 | 3.脚本变量只推荐在青龙的【环境变量】页添加,有强迫症在【配置文件】config.sh中添加的如果出现问题自己解决
24 | 4.支持多用户,每一用户在【环境变量】单独新建变量wzxy,切勿一个变量内填写多个用户的参数
25 | 5.脚本通知方式采用青龙面板默认通知,请在【配置文件】config.sh里配置
26 | 6.关于各脚本的具体使用方法,请阅读脚本内的注释
27 |
28 | ***关于变量值中各参数的解释:
29 | username ———————— 手机号
30 | password —————————密码
31 | qd_location ————— 签到的`经纬度` (wzxy_qd.js)
32 | rjrb_answers —————日检日报的`填空参数`(wzxy_rjrb.js)
33 | rjrb_location ————日检日报的`经纬度` (wzxy_rjrb.js)
34 | jkdk_answers ———— 健康签到的`填空参数`(wzxy_jkdk.js)
35 | jkdk_location ————健康签到的`经纬度` (wzxy_jkdk.js)
36 | mark —————————————用户昵称(不一定要真名,随便填都行,便于自己区分打卡用户)
37 |
38 |
39 | ***更新日志:
40 |
41 | 1.0.0 完成日检日报的基本功能
42 | 1.0.1 修复seq识别出错的bug
43 | 1.0.2 增加等待15s,防止黑ip
44 | 1.0.3 修复打卡通知成功但 实际上没打上卡的bug
45 | 1.0.4 增加完整参数验证
46 | 1.0.6 修复当前时间格式
47 | 1.0.7 增加打卡Content-Type
48 | 1.0.8 修复地址信息请求失败的bug
49 | 1.0.9 优化通知
50 | 1.1.0 log增加新版本内容
51 | 1.1.1 增加`仅通知打卡失败`模式,在脚本第58行修改开启
52 |
53 | */
54 | //cron: 5 8,16 * * *
55 |
56 | //===============通知设置=================//
57 | const Notify = 1; //0为关闭通知,1为打开通知,默认为1
58 | const OnlyErrorNotify = 0; //0为关闭`仅通知打卡失败`模式,1为打开`仅通知打卡失败`模式,默认为0
59 | ////////////////////////////////////////////
60 |
61 | const $ = new Env('日检日报');
62 | const notify = $.isNode() ? require('./sendNotify') : '';
63 | const fs = require("fs");
64 | const request = require('request');
65 | const {log} = console;
66 | //////////////////////
67 | let scriptVersion = "1.1.1";
68 | let scriptVersionLatest = '';
69 | let update_data = "1.1.1 增加`仅通知打卡失败`模式,可在脚本第58行修改开启"; //新版本更新内容
70 | //我在校园账号数据
71 | let wzxy = ($.isNode() ? process.env.wzxy : $.getdata("wzxy")) || "";
72 | let wzxyArr = [];
73 | let wait = 0;
74 | let checkBack = 0;
75 | let loginBack = 0;
76 | let PunchInBack = 0;
77 | let requestAddressBack = 0;
78 | let msg = '';
79 | let jwsession = '';
80 | let location = '';
81 | let sign_data = '';
82 | let answers = '';
83 | let status_code = 0;
84 | let startTime = '';
85 | let endTime = '';
86 | let seq = '';
87 | let locat = '';
88 | let fail = 0;
89 |
90 | !(async () => {
91 | if (typeof $request !== "undefined") {
92 | await GetRewrite();
93 | } else {
94 | if (!(await Envs()))
95 | return;
96 | else {
97 |
98 | log(`\n\n============================================= \n脚本执行 - 北京时间(UTC+8):${new Date(
99 | new Date().getTime() + new Date().getTimezoneOffset() * 60 * 1000 +
100 | 8 * 60 * 60 * 1000).toLocaleString()} \n=============================================\n`);
101 |
102 | await poem();
103 | await getVersion();
104 |
105 | log(`\n============ 当前版本:${scriptVersion} 最新版本:${scriptVersionLatest} ============`)
106 |
107 | if(scriptVersionLatest != scriptVersion){
108 | log(`\n发现新版本,请及时拉库更新!\n${update_data}`)
109 | }
110 |
111 | log(`\n=================== 共找到 ${wzxyArr.length} 个账号 ===================`)
112 |
113 |
114 | for (let index = 0; index < wzxyArr.length; index++) {
115 |
116 |
117 | let num = index + 1
118 | if (num >1 && wait == 0){
119 | log('**********休息15s,防止黑IP**********');
120 | await $.wait(16 * 1000);
121 | }
122 | log(`\n========= 开始【第 ${num} 个账号】=========\n`)
123 | data = wzxyArr[index];
124 | content = JSON.parse(data)
125 | username = content.username
126 | password = content.password
127 | location = content.rjrb_location
128 | answers = JSON.stringify(content.rjrb_answers)
129 | mark = content.mark
130 | log(`打卡用户:${mark}`)
131 | var checkBack = 0;
132 | loginBack = 0;//置0,防止上一个号影响下一个号
133 | locat = location.split(',')
134 | if (!locat[0] || !locat[1]){
135 | log('未填写rjrb_location,跳过打卡');
136 | var checkBack = 1
137 | status_code = 6
138 | wait = 1
139 | }
140 | if (checkBack == 0) {
141 | log('开始检查jwsession是否存在...');
142 | await checkJwsession()
143 | await $.wait(2 * 1000);
144 |
145 | if (loginBack) {
146 |
147 | log('开始获取打卡列表...');
148 | await PunchIn()
149 | await $.wait(2 * 1000);
150 |
151 | if (PunchInBack > 0) {
152 | log('正在请求地址信息...');
153 | await requestAddress()
154 | await $.wait(2 * 1000);
155 |
156 | if (requestAddressBack) {
157 | log('开始日检日报打卡...');
158 | await doPunchIn()
159 | await $.wait(2 * 1000);
160 |
161 | }
162 |
163 | }
164 |
165 | }
166 | }
167 | var resultlog = getResult()
168 |
169 |
170 | if (OnlyErrorNotify>0){
171 | if (status_code != 1 ){
172 | msg += `打卡用户:${mark}\n打卡情况:${resultlog}\n\n`
173 | fail=fail+1
174 | }
175 | }else {
176 | msg += `打卡用户:${mark}\n打卡情况:${resultlog}\n\n`
177 | }
178 |
179 | }
180 | if (OnlyErrorNotify>0){
181 |
182 | if(fail==0){
183 | msg=`共${wzxyArr.length}个用户,全部打卡成功 ✅ `
184 | }else{
185 | msg=`共${wzxyArr.length}个用户,❌ 失败${fail}个\n\n===========失败详情=============\n\n`+msg
186 | }
187 | }
188 | // log(msg);
189 | await SendMsg(msg);
190 | }
191 | }
192 |
193 | })()
194 | .catch((e) => log(e))
195 | .finally(() => $.done())
196 |
197 |
198 |
199 | /**
200 | * 判断jwsession是否存在
201 | */
202 | function checkJwsession() {
203 |
204 | fs.open('.cache/' + username + ".json", 'r+', function(err, fd) {
205 | if (err) {
206 | console.error("找不到cache文件,正在使用账号信息登录...")
207 | login()
208 | return
209 | }
210 | console.log("找到cache文件,正在使用jwsession打卡...")
211 | var read = fs.readFileSync('.cache/' + username + ".json")
212 | jwsession = read.toString()
213 | loginBack = 1
214 |
215 | });
216 |
217 | }
218 |
219 |
220 | /**
221 | * 登录
222 | */
223 | function login(timeout = 3 * 1000) {
224 | return new Promise((resolve) => {
225 | let url = {
226 | url: `https://gw.wozaixiaoyuan.com/basicinfo/mobile/login/username?username=${username}&password=${password}`,
227 | headers: {
228 | "Accept-Encoding": "gzip, deflate, br",
229 | "Connection": "keep-alive",
230 | "User-Agent": "Mozilla/5.0 (iPad; CPU OS 15_5 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.23(0x1800172f) NetType/WIFI Language/zh_CN miniProgram/wxce6d08f781975d91",
231 | "content-type": "application/json;charset=UTF-8",
232 | "Content-Length": "2",
233 | "Host": "gw.wozaixiaoyuan.com",
234 | "Accept-Language": "en-us,en",
235 | "Accept": "application/json, text/plain, */*"
236 | },
237 | data: ``,
238 | }
239 |
240 |
241 | request.post(url, async (error, response, data) => {
242 | try {
243 | let result = data == "undefined" ? await login() : JSON.parse(data);
244 |
245 | //登录成功
246 | if (result.code == 0 ) {
247 |
248 | jwsession = response.headers['jwsession']
249 | //储存jwsession
250 | setJwsession(jwsession)
251 | loginBack = 1;
252 | log(`登录成功`)
253 |
254 | } else {
255 | log(`❌ 登录失败,${result.message}`)
256 | status_code = 5;
257 | loginBack = 0;
258 | }
259 |
260 | } catch (e) {
261 | log(e)
262 | } finally {
263 | resolve();
264 | }
265 | }, timeout)
266 | })
267 | }
268 |
269 |
270 | /**
271 | * 存储jwsession
272 | */
273 | function setJwsession(jwsession) {
274 |
275 | fs.mkdir('.cache',function(err){
276 | if (err) {
277 |
278 | console.log("找到cache文件");
279 | }
280 | else console.log("正在创建cache储存目录与文件...");
281 | });
282 |
283 | fs.writeFile('.cache/' + username + ".json", jwsession, function(err) {
284 | if (err) {
285 | return console.error(err);
286 | }
287 | console.log("更新jwsession成功");
288 | })
289 |
290 | }
291 |
292 |
293 | /**
294 | * 获取打卡列表,判断当前打卡时间段与打卡情况,符合条件则自动进行打卡
295 | */
296 | function PunchIn(timeout = 3 * 1000) {
297 | return new Promise((resolve) => {
298 |
299 | let url = {
300 | url: "https://student.wozaixiaoyuan.com/heat/getTodayHeatList.json",
301 | headers: {
302 | 'jwsession': jwsession,
303 | },
304 | body: ''
305 | }
306 |
307 | $.post(url, async (error, response, data) => {
308 | try {
309 | let result = data == "undefined" ? await PunchIn() : JSON.parse(data);
310 |
311 | if (result.code == -10) {
312 | log('jwsession 无效,尝试账号密码登录...')
313 | status_code = 4;
314 | PunchInBack = 0;
315 | loginBack = 0;
316 | await login()
317 | await $.wait(2 * 1000);
318 | if (loginBack > 0) {
319 | log('重新获取打卡列表...');
320 | await PunchIn()
321 | await $.wait(2 * 1000)
322 | return
323 | }
324 | }
325 | if (result.code == 0) {
326 |
327 | //晨午检判断
328 | for (let i = 0; i < result['data'].length; i++) {
329 |
330 | var d = new Date()
331 | var hour = d.getHours()
332 | hour = hour > 9 ? hour : '0' + hour.toString()
333 | var minute = d.getMinutes()
334 | minute = minute > 9 ? minute : '0' + minute.toString()
335 | now = hour + `:`+minute
336 |
337 | startTime = result['data'][i]['startTime']
338 | endTime = result['data'][i]['endTime']
339 |
340 | if(startTime < now && now < endTime){
341 |
342 | seq = i + 1
343 | // var seq = result['data'][i]['seq']
344 | // if(!seq) {
345 | // seq = result['data'][i].seq
346 | // }
347 | }
348 | }
349 | if (!seq){
350 | log("❌ 打卡失败,当前不在打卡时间段内")
351 | PunchInBack = 0;
352 | status_code = 3;
353 | return
354 | }
355 | if (seq > 0){
356 | log("获取成功,开始打卡")
357 | PunchInBack = 1
358 | }
359 |
360 | }
361 | if (result.code != 0 && result.code != -10) {
362 | log(`❌ 获取失败,原因:${error}`)
363 | PunchInBack = 0
364 | }
365 |
366 | } catch (e) {
367 | log(e)
368 | } finally {
369 | resolve();
370 | }
371 | }, timeout)
372 | })
373 | }
374 |
375 |
376 | /**
377 | * 请求地址信息
378 | */
379 | function requestAddress(timeout = 3 * 1000) {
380 | return new Promise((resolve) => {
381 | location = location.split(',')
382 | let url = {
383 | url: `https://apis.map.qq.com/ws/geocoder/v1/?key=A3YBZ-NC5RU-MFYVV-BOHND-RO3OT-ABFCR&location=${location[1]},${location[0]}`,
384 | }
385 |
386 | $.get(url, async (error, response, data) => {
387 | try {
388 | let result = data == "undefined" ? await requestAddress() : JSON.parse(data);
389 |
390 | if (result.status == 0) {
391 | log(`地址信息获取成功`);
392 | timestampMs()
393 | try {town=result.result.address_reference.town.title}catch (e) {town=``}
394 | try {street=result.result.address_reference.street.title}catch (e) {street=``}
395 | _data =`answers=${answers}&seq=${seq}&temperature=36.0&latitude=${location[1]}&longitude=${location[0]}&country=中国&city=${result.result.address_component.city}&district=${result.result.address_component.district}&province=${result.result.address_component.province}&township=${town}&street=${street}&areacode=${result.result.ad_info.adcode}&towncode=0&citycode=0×tampHeader=${new Date().getTime()}`
396 | sign_data = encodeURI(_data)
397 | requestAddressBack = 1
398 |
399 | } else {
400 | log(`❌ 地址信息获取失败`)
401 | requestAddressBack = 0
402 | }
403 |
404 | } catch (e) {
405 | log(e)
406 | } finally {
407 | resolve();
408 | }
409 | }, timeout)
410 | })
411 | }
412 |
413 |
414 |
415 | /**
416 | * 开始打卡
417 | */
418 | function doPunchIn(timeout = 3 * 1000) {
419 | return new Promise((resolve) => {
420 | let url = {
421 | url: "https://student.wozaixiaoyuan.com/heat/save.json",
422 | headers: {
423 | "Content-Type": "application/x-www-form-urlencoded",
424 | "jwsession": jwsession,
425 | },
426 | body: sign_data,
427 |
428 | }
429 |
430 | $.post(url, async (error, response, data) => {
431 | try {
432 | let result = data == "undefined" ? await doPunchIn() : JSON.parse(data);
433 |
434 | //打卡情况
435 | if (result.code == 0){
436 | log("✅ 打卡成功")
437 | status_code = 1
438 | }
439 | if (result.code != 0) {
440 | log("❌ 打卡失败,原因:"+data)
441 | }
442 |
443 | } catch (e) {
444 | log(e)
445 | } finally {
446 | resolve();
447 | }
448 | }, timeout)
449 | })
450 | }
451 |
452 |
453 | /**
454 | * 获取打卡结果
455 | */
456 | function getResult(timeout = 3 * 1000) {
457 | res = status_code
458 | if (res == 1) return "✅ 打卡成功"
459 | if (res == 2) return "✅ 你已经打过卡了,无需重复打卡"
460 | if (res == 3) return "❌ 打卡失败,当前不在打卡时间段内"
461 | if (res == 4) return "❌ 打卡失败,jwsession 无效"
462 | if (res == 5) return "❌ 打卡失败,登录错误,请检查账号信息"
463 | if (res == 6) return "❌ 跳过打卡,变量参数不完整"
464 | else return "❌ 打卡失败,发生未知错误"
465 | }
466 |
467 |
468 | // ============================================变量检查============================================ \\
469 | async function Envs() {
470 | if (wzxy) {
471 | if (wzxy.indexOf("@") != -1 || wzxy.indexOf("&") != -1) {
472 | wzxy.split("@"&&"&").forEach((item) => {
473 | wzxyArr.push(item);
474 | });
475 | }
476 | // else if (wzxy.indexOf("\n") != -1) {
477 | // wzxy.split("\n").forEach((item) => {
478 | // wzxyArr.push(item);
479 | // });
480 | // }
481 | else {
482 | wzxyArr.push(wzxy);
483 | }
484 | } else {
485 | log(`\n 未填写变量 wzxy`)
486 | return;
487 | }
488 |
489 | return true;
490 | }
491 | // ============================================发送消息============================================ \\
492 | async function SendMsg(msg) {
493 | if (!msg)
494 | return;
495 |
496 | if (Notify > 0) {
497 | if ($.isNode()) {
498 | var notify = require('./sendNotify');
499 | await notify.sendNotify($.name, msg+ `\n打卡时间:${t()}\n`);
500 | } else {
501 | $.msg(msg);
502 | }
503 | } else {
504 | //log(msg);
505 | }
506 | }
507 |
508 |
509 |
510 | /**
511 | * 获取当前小时数
512 | */
513 | function local_hours() {
514 | let myDate = new Date();
515 | let h = myDate.getHours();
516 | return h;
517 | }
518 |
519 | /**
520 | * 获取当前分钟数
521 | */
522 | function local_minutes() {
523 | let myDate = new Date();
524 | let m = myDate.getMinutes();
525 | return m;
526 | }
527 |
528 | /**
529 | * 随机数生成
530 | */
531 | function randomString(e) {
532 | e = e || 32;
533 | var t = "QWERTYUIOPASDFGHJKLZXCVBNM1234567890",
534 | a = t.length,
535 | n = "";
536 | for (i = 0; i < e; i++)
537 | n += t.charAt(Math.floor(Math.random() * a));
538 | return n
539 | }
540 |
541 | /**
542 | * 随机整数生成
543 | */
544 | function randomInt(min, max) {
545 | return Math.round(Math.random() * (max - min) + min)
546 | }
547 |
548 | /**
549 | * 获取毫秒时间戳
550 | */
551 | function timestampMs(){
552 | return new Date().getTime();
553 | }
554 |
555 | /**
556 | *
557 | * 获取秒时间戳
558 | */
559 | function timestampS(){
560 | return Date.parse(new Date())/1000;
561 | }
562 |
563 | /**
564 | * 获取随机诗词
565 | */
566 | function poem(timeout = 3 * 1000) {
567 | return new Promise((resolve) => {
568 | let url = {
569 | url: `https://v1.jinrishici.com/all.json`
570 | }
571 | $.get(url, async (err, resp, data) => {
572 | try {
573 | data = JSON.parse(data)
574 | log(`${data.content} \n————《${data.origin}》${data.author}`);
575 | } catch (e) {
576 | log(e, resp);
577 | } finally {
578 | resolve()
579 | }
580 | }, timeout)
581 | })
582 | }
583 |
584 | /**
585 | * 修改配置文件
586 | */
587 | function modify() {
588 |
589 | fs.readFile('/ql/data/config/config.sh','utf8',function(err,dataStr){
590 | if(err){
591 | return log('读取文件失败!'+err)
592 | }
593 | else {
594 | var result = dataStr.replace(/regular/g,string);
595 | fs.writeFile('/ql/data/config/config.sh', result, 'utf8', function (err) {
596 | if (err) {return log(err);}
597 | });
598 | }
599 | })
600 | }
601 |
602 | /**
603 | * 获取远程版本
604 | */
605 | function getVersion(timeout = 3 * 1000) {
606 | return new Promise((resolve) => {
607 | let url = {
608 | url: `https://ghproxy.com/https://raw.githubusercontent.com/zhacha222/wozaixiaoyuan/main/wzxy_rjrb.js`,
609 | }
610 | $.get(url, async (err, resp, data) => {
611 | try {
612 | scriptVersionLatest = data.match(/scriptVersion = "([\d\.]+)"/)[1]
613 | update_data = data.match(/update_data = "(.*?)"/)[1]
614 | } catch (e) {
615 | $.logErr(e, resp);
616 | } finally {
617 | resolve()
618 | }
619 | }, timeout)
620 | })
621 | }
622 |
623 | /**
624 | * time 输出格式:1970-01-01 00:00:00
625 | */
626 | function t() {
627 | var date = new Date();
628 | // 获取当前月份
629 | var nowMonth = date.getMonth() + 1;
630 | // 获取当前是几号
631 | var strDate = date.getDate();
632 | //获取当前小时(0-23)
633 | var nowhour = date.getHours()
634 | //获取当前分钟(0-59)
635 | var nowMinute = date.getMinutes()
636 | //获取当前秒数(0-59)
637 | var nowSecond = date.getSeconds();
638 | // 添加分隔符“-”
639 | var seperator = "-";
640 | // 添加分隔符“:”
641 | var seperator1 = ":";
642 |
643 | // 对月份进行处理,1-9月在前面添加一个“0”
644 | if (nowMonth >= 1 && nowMonth <= 9) {
645 | nowMonth = "0" + nowMonth;
646 | }
647 | // 对月份进行处理,1-9号在前面添加一个“0”
648 | if (strDate >= 0 && strDate <= 9) {
649 | strDate = "0" + strDate;
650 | }
651 | // 对小时进行处理,0-9号在前面添加一个“0”
652 | if (nowhour >= 0 && nowhour <= 9) {
653 | nowhour = "0" + nowhour;
654 | }
655 | // 对分钟进行处理,0-9号在前面添加一个“0”
656 | if (nowMinute >= 0 && nowMinute <= 9) {
657 | nowMinute = "0" + nowMinute;
658 | }
659 | // 对秒数进行处理,0-9号在前面添加一个“0”
660 | if (nowSecond >= 0 && nowSecond <= 9) {
661 | nowSecond = "0" + nowSecond;
662 | }
663 |
664 | // 最后拼接字符串,得到一个格式为(yyyy-MM-dd)的日期
665 | var nowDate = date.getFullYear() + seperator + nowMonth + seperator + strDate + ` ` + nowhour + seperator1 + nowMinute + seperator1 + nowSecond
666 | return nowDate
667 | }
668 |
669 | function Env(t, e) {
670 | "undefined" != typeof process && JSON.stringify(process.env).indexOf("GITHUB") > -1 && process.exit(0);
671 | class s {
672 | constructor(t) {
673 | this.env = t
674 | }
675 | send(t, e = "GET") {
676 | t = "string" == typeof t ? {
677 | url: t
678 | } : t;
679 | let s = this.get;
680 | return "POST" === e && (s = this.post), new Promise((e, i) => {
681 | s.call(this, t, (t, s, r) => {
682 | t ? i(t) : e(s)
683 | })
684 | })
685 | }
686 | get(t) {
687 | return this.send.call(this.env, t)
688 | }
689 | post(t) {
690 | return this.send.call(this.env, t, "POST")
691 | }
692 | }
693 | return new class {
694 | constructor(t, e) {
695 | this.name = t, this.http = new s(this), this.data = null, this.dataFile = "box.dat", this.logs = [], this.isMute = !1, this.isNeedRewrite = !1, this.logSeparator = "\n", this.startTime = (new Date).getTime(), Object.assign(this, e), this.log("", `🔔${this.name}, 开始!`)
696 | }
697 | isNode() {
698 | return "undefined" != typeof module && !!module.exports
699 | }
700 | isQuanX() {
701 | return "undefined" != typeof $task
702 | }
703 | isSurge() {
704 | return "undefined" != typeof $httpClient && "undefined" == typeof $loon
705 | }
706 | isLoon() {
707 | return "undefined" != typeof $loon
708 | }
709 | toObj(t, e = null) {
710 | try {
711 | return JSON.parse(t)
712 | } catch {
713 | return e
714 | }
715 | }
716 | toStr(t, e = null) {
717 | try {
718 | return JSON.stringify(t)
719 | } catch {
720 | return e
721 | }
722 | }
723 | getjson(t, e) {
724 | let s = e;
725 | const i = this.getdata(t);
726 | if (i) try {
727 | s = JSON.parse(this.getdata(t))
728 | } catch {}
729 | return s
730 | }
731 | setjson(t, e) {
732 | try {
733 | return this.setdata(JSON.stringify(t), e)
734 | } catch {
735 | return !1
736 | }
737 | }
738 | getScript(t) {
739 | return new Promise(e => {
740 | this.get({
741 | url: t
742 | }, (t, s, i) => e(i))
743 | })
744 | }
745 | runScript(t, e) {
746 | return new Promise(s => {
747 | let i = this.getdata("@chavy_boxjs_userCfgs.httpapi");
748 | i = i ? i.replace(/\n/g, "").trim() : i;
749 | let r = this.getdata("@chavy_boxjs_userCfgs.httpapi_timeout");
750 | r = r ? 1 * r : 20, r = e && e.timeout ? e.timeout : r;
751 | const [o, h] = i.split("@"), n = {
752 | url: `http://${h}/v1/scripting/evaluate`,
753 | body: {
754 | script_text: t,
755 | mock_type: "cron",
756 | timeout: r
757 | },
758 | headers: {
759 | "X-Key": o,
760 | Accept: "*/*"
761 | }
762 | };
763 | this.post(n, (t, e, i) => s(i))
764 | }).catch(t => this.logErr(t))
765 | }
766 | loaddata() {
767 | if (!this.isNode()) return {}; {
768 | this.fs = this.fs ? this.fs : require("fs"), this.path = this.path ? this.path : require("path");
769 | const t = this.path.resolve(this.dataFile),
770 | e = this.path.resolve(process.cwd(), this.dataFile),
771 | s = this.fs.existsSync(t),
772 | i = !s && this.fs.existsSync(e);
773 | if (!s && !i) return {}; {
774 | const i = s ? t : e;
775 | try {
776 | return JSON.parse(this.fs.readFileSync(i))
777 | } catch (t) {
778 | return {}
779 | }
780 | }
781 | }
782 | }
783 | writedata() {
784 | if (this.isNode()) {
785 | this.fs = this.fs ? this.fs : require("fs"), this.path = this.path ? this.path : require("path");
786 | const t = this.path.resolve(this.dataFile),
787 | e = this.path.resolve(process.cwd(), this.dataFile),
788 | s = this.fs.existsSync(t),
789 | i = !s && this.fs.existsSync(e),
790 | r = JSON.stringify(this.data);
791 | s ? this.fs.writeFileSync(t, r) : i ? this.fs.writeFileSync(e, r) : this.fs.writeFileSync(t, r)
792 | }
793 | }
794 | lodash_get(t, e, s) {
795 | const i = e.replace(/\[(\d+)\]/g, ".$1").split(".");
796 | let r = t;
797 | for (const t of i)
798 | if (r = Object(r)[t], void 0 === r) return s;
799 | return r
800 | }
801 | lodash_set(t, e, s) {
802 | return Object(t) !== t ? t : (Array.isArray(e) || (e = e.toString().match(/[^.[\]]+/g) || []), e.slice(0, -1).reduce((t, s, i) => Object(t[s]) === t[s] ? t[s] : t[s] = Math.abs(e[i + 1]) >> 0 == +e[i + 1] ? [] : {}, t)[e[e.length - 1]] = s, t)
803 | }
804 | getdata(t) {
805 | let e = this.getval(t);
806 | if (/^@/.test(t)) {
807 | const [, s, i] = /^@(.*?)\.(.*?)$/.exec(t), r = s ? this.getval(s) : "";
808 | if (r) try {
809 | const t = JSON.parse(r);
810 | e = t ? this.lodash_get(t, i, "") : e
811 | } catch (t) {
812 | e = ""
813 | }
814 | }
815 | return e
816 | }
817 | setdata(t, e) {
818 | let s = !1;
819 | if (/^@/.test(e)) {
820 | const [, i, r] = /^@(.*?)\.(.*?)$/.exec(e), o = this.getval(i), h = i ? "null" === o ? null : o || "{}" : "{}";
821 | try {
822 | const e = JSON.parse(h);
823 | this.lodash_set(e, r, t), s = this.setval(JSON.stringify(e), i)
824 | } catch (e) {
825 | const o = {};
826 | this.lodash_set(o, r, t), s = this.setval(JSON.stringify(o), i)
827 | }
828 | } else s = this.setval(t, e);
829 | return s
830 | }
831 | getval(t) {
832 | return this.isSurge() || this.isLoon() ? $persistentStore.read(t) : this.isQuanX() ? $prefs.valueForKey(t) : this.isNode() ? (this.data = this.loaddata(), this.data[t]) : this.data && this.data[t] || null
833 | }
834 | setval(t, e) {
835 | return this.isSurge() || this.isLoon() ? $persistentStore.write(t, e) : this.isQuanX() ? $prefs.setValueForKey(t, e) : this.isNode() ? (this.data = this.loaddata(), this.data[e] = t, this.writedata(), !0) : this.data && this.data[e] || null
836 | }
837 | initGotEnv(t) {
838 | this.got = this.got ? this.got : require("got"), this.cktough = this.cktough ? this.cktough : require("tough-cookie"), this.ckjar = this.ckjar ? this.ckjar : new this.cktough.CookieJar, t && (t.headers = t.headers ? t.headers : {}, void 0 === t.headers.Cookie && void 0 === t.cookieJar && (t.cookieJar = this.ckjar))
839 | }
840 | get(t, e = (() => {})) {
841 | t.headers && (delete t.headers["Content-Type"], delete t.headers["Content-Length"]), this.isSurge() || this.isLoon() ? (this.isSurge() && this.isNeedRewrite && (t.headers = t.headers || {}, Object.assign(t.headers, {
842 | "X-Surge-Skip-Scripting": !1
843 | })), $httpClient.get(t, (t, s, i) => {
844 | !t && s && (s.body = i, s.statusCode = s.status), e(t, s, i)
845 | })) : this.isQuanX() ? (this.isNeedRewrite && (t.opts = t.opts || {}, Object.assign(t.opts, {
846 | hints: !1
847 | })), $task.fetch(t).then(t => {
848 | const {
849 | statusCode: s,
850 | statusCode: i,
851 | headers: r,
852 | body: o
853 | } = t;
854 | e(null, {
855 | status: s,
856 | statusCode: i,
857 | headers: r,
858 | body: o
859 | }, o)
860 | }, t => e(t))) : this.isNode() && (this.initGotEnv(t), this.got(t).on("redirect", (t, e) => {
861 | try {
862 | if (t.headers["set-cookie"]) {
863 | const s = t.headers["set-cookie"].map(this.cktough.Cookie.parse).toString();
864 | s && this.ckjar.setCookieSync(s, null), e.cookieJar = this.ckjar
865 | }
866 | } catch (t) {
867 | this.logErr(t)
868 | }
869 | }).then(t => {
870 | const {
871 | statusCode: s,
872 | statusCode: i,
873 | headers: r,
874 | body: o
875 | } = t;
876 | e(null, {
877 | status: s,
878 | statusCode: i,
879 | headers: r,
880 | body: o
881 | }, o)
882 | }, t => {
883 | const {
884 | message: s,
885 | response: i
886 | } = t;
887 | e(s, i, i && i.body)
888 | }))
889 | }
890 | post(t, e = (() => {})) {
891 | if (t.body && t.headers && !t.headers["Content-Type"] && (t.headers["Content-Type"] = "application/x-www-form-urlencoded"), t.headers && delete t.headers["Content-Length"], this.isSurge() || this.isLoon()) this.isSurge() && this.isNeedRewrite && (t.headers = t.headers || {}, Object.assign(t.headers, {
892 | "X-Surge-Skip-Scripting": !1
893 | })), $httpClient.post(t, (t, s, i) => {
894 | !t && s && (s.body = i, s.statusCode = s.status), e(t, s, i)
895 | });
896 | else if (this.isQuanX()) t.method = "POST", this.isNeedRewrite && (t.opts = t.opts || {}, Object.assign(t.opts, {
897 | hints: !1
898 | })), $task.fetch(t).then(t => {
899 | const {
900 | statusCode: s,
901 | statusCode: i,
902 | headers: r,
903 | body: o
904 | } = t;
905 | e(null, {
906 | status: s,
907 | statusCode: i,
908 | headers: r,
909 | body: o
910 | }, o)
911 | }, t => e(t));
912 | else if (this.isNode()) {
913 | this.initGotEnv(t);
914 | const {
915 | url: s,
916 | ...i
917 | } = t;
918 | this.got.post(s, i).then(t => {
919 | const {
920 | statusCode: s,
921 | statusCode: i,
922 | headers: r,
923 | body: o
924 | } = t;
925 | e(null, {
926 | status: s,
927 | statusCode: i,
928 | headers: r,
929 | body: o
930 | }, o)
931 | }, t => {
932 | const {
933 | message: s,
934 | response: i
935 | } = t;
936 | e(s, i, i && i.body)
937 | })
938 | }
939 | }
940 | time(t, e = null) {
941 | const s = e ? new Date(e) : new Date;
942 | let i = {
943 | "M+": s.getMonth() + 1,
944 | "d+": s.getDate(),
945 | "H+": s.getHours(),
946 | "m+": s.getMinutes(),
947 | "s+": s.getSeconds(),
948 | "q+": Math.floor((s.getMonth() + 3) / 3),
949 | S: s.getMilliseconds()
950 | };
951 | /(y+)/.test(t) && (t = t.replace(RegExp.$1, (s.getFullYear() + "").substr(4 - RegExp.$1.length)));
952 | for (let e in i) new RegExp("(" + e + ")").test(t) && (t = t.replace(RegExp.$1, 1 == RegExp.$1.length ? i[e] : ("00" + i[e]).substr(("" + i[e]).length)));
953 | return t
954 | }
955 | msg(e = t, s = "", i = "", r) {
956 | const o = t => {
957 | if (!t) return t;
958 | if ("string" == typeof t) return this.isLoon() ? t : this.isQuanX() ? {
959 | "open-url": t
960 | } : this.isSurge() ? {
961 | url: t
962 | } : void 0;
963 | if ("object" == typeof t) {
964 | if (this.isLoon()) {
965 | let e = t.openUrl || t.url || t["open-url"],
966 | s = t.mediaUrl || t["media-url"];
967 | return {
968 | openUrl: e,
969 | mediaUrl: s
970 | }
971 | }
972 | if (this.isQuanX()) {
973 | let e = t["open-url"] || t.url || t.openUrl,
974 | s = t["media-url"] || t.mediaUrl;
975 | return {
976 | "open-url": e,
977 | "media-url": s
978 | }
979 | }
980 | if (this.isSurge()) {
981 | let e = t.url || t.openUrl || t["open-url"];
982 | return {
983 | url: e
984 | }
985 | }
986 | }
987 | };
988 | if (this.isMute || (this.isSurge() || this.isLoon() ? $notification.post(e, s, i, o(r)) : this.isQuanX() && $notify(e, s, i, o(r))), !this.isMuteLog) {
989 | let t = ["", "==============📣系统通知📣=============="];
990 | t.push(e), s && t.push(s), i && t.push(i), console.log(t.join("\n")), this.logs = this.logs.concat(t)
991 | }
992 | }
993 | log(...t) {
994 | t.length > 0 && (this.logs = [...this.logs, ...t]), console.log(t.join(this.logSeparator))
995 | }
996 | logErr(t, e) {
997 | const s = !this.isSurge() && !this.isQuanX() && !this.isLoon();
998 | s ? this.log("", `❗️${this.name}, 错误!`, t.stack) : this.log("", `❗️${this.name}, 错误!`, t)
999 | }
1000 | wait(t) {
1001 | return new Promise(e => setTimeout(e, t))
1002 | }
1003 | done(t = {}) {
1004 | const e = (new Date).getTime(),
1005 | s = (e - this.startTime) / 1e3;
1006 | this.log("", `🔔${this.name}, 结束! 🕛 ${s} 秒`), this.log(), (this.isSurge() || this.isQuanX() || this.isLoon()) && $done(t)
1007 | }
1008 | }(t, e)
1009 | }
1010 |
--------------------------------------------------------------------------------