├── Backup ├── BattleForHeyTap.py ├── ChockInEarly.py ├── CollectionCard.py ├── Community.py └── Double11.py ├── BattleForRealMe.py ├── DailyCash.py ├── Doc ├── 0.png ├── 1.png ├── 10.png ├── 11.png ├── 2.png ├── 3.png ├── 4.png ├── 5.png ├── 6.png ├── 7.png ├── 8.png ├── 9.png └── README.md ├── HT_account.py ├── HT_config.py ├── LICENSE ├── OnePlusJYStation.py ├── README.md ├── TaskCenter.py ├── TimingCash.py ├── index.py └── sendNotify.py /Backup/BattleForHeyTap.py: -------------------------------------------------------------------------------- 1 | # !/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # @Time : 2021/9/26 4 | # @Author : MashiroF 5 | # @File : BattleForHeyTap.py 6 | # @Software: PyCharm 7 | 8 | ''' 9 | cron: 45 5,12 * * * BattleForHeyTap.py 10 | new Env('欢太积分大乱斗'); 11 | ''' 12 | 13 | import os 14 | import re 15 | import sys 16 | import time 17 | import random 18 | import requests 19 | 20 | # 配置文件 21 | try: 22 | from HT_config import downFlag,notifyBlackList,logger 23 | except Exception as error: 24 | logger.info(f'失败原因:{error}') 25 | sys.exit(0) 26 | 27 | # 判断是否发生下载行为 28 | if downFlag == True: 29 | logger.info('发生下载行为,应退出程序,编辑配置文件') 30 | sys.exit(0) 31 | 32 | # 配信文件 33 | try: 34 | from sendNotify import send 35 | except Exception as error: 36 | logger.info('推送文件有误') 37 | logger.info(f'失败原因:{error}') 38 | sys.exit(0) 39 | 40 | # 导入账户 41 | try: 42 | from HT_account import accounts 43 | lists = accounts 44 | except Exception as error: 45 | logger.info(f'失败原因:{error}') 46 | lists = [] 47 | 48 | # 配信内容格式 49 | allMess = '' 50 | def notify(content=None): 51 | global allMess 52 | allMess = allMess + content + '\n' 53 | logger.info(content) 54 | 55 | # 日志录入时间 56 | notify(f"任务:欢太积分大乱斗\n时间:{time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())}") 57 | 58 | class BattleForHeyTap: 59 | def __init__(self,dic): 60 | self.dic = dic 61 | self.sess = requests.session() 62 | 63 | # 登录验证 64 | def login(self): 65 | url = 'https://store.oppo.com/cn/oapi/users/web/member/check' 66 | headers = { 67 | 'Host': 'store.oppo.com', 68 | 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 69 | 'Content-Type': 'application/x-www-form-urlencoded', 70 | 'Connection': 'keep-alive', 71 | 'Accept-Language': 'zh-cn', 72 | 'Accept-Encoding': 'gzip, deflate, br', 73 | } 74 | response = self.sess.get(url=url,headers=headers).json() 75 | if response['code'] == 200: 76 | notify(f"{self.dic['user']}\t登录成功") 77 | return True 78 | else: 79 | notify(f"{self.dic['user']}\t登录失败") 80 | return False 81 | 82 | def receiveAward(self,dic): 83 | aid = 1598 84 | url = 'https://hd.oppo.com/task/award' 85 | headers = { 86 | 'Host': 'hd.oppo.com', 87 | 'Connection': 'keep-alive', 88 | 'Accept': '*/*', 89 | 'Origin': 'https://hd.oppo.com', 90 | 'X-Requested-With': 'XMLHttpRequest', 91 | 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', 92 | 'Referer': 'https://hd.oppo.com/act/m/2021/jifenzhuanpan/index.html?us=gerenzhongxin&um=hudongleyuan&uc=yingjifen', 93 | 'Accept-Encoding': 'gzip, deflate', 94 | 'Accept-Language': 'zh-CN,en-US;q=0.9' 95 | } 96 | data = { 97 | 'aid': aid, 98 | 't_index': dic['t_index'] 99 | } 100 | response = self.sess.post(url=url,headers=headers,data=data).json() 101 | if response['no'] == '200': 102 | notify(f"[{dic['title']}]\t{response['msg']}") 103 | else: 104 | notify(f"[{dic['title']}]\t{response['msg']}") 105 | time.sleep(random.randint(3,5)) 106 | 107 | def shareGoods(self,count=2,flag=None,dic=None): 108 | url = 'https://msec.opposhop.cn/users/vi/creditsTask/pushTask' 109 | headers = { 110 | 'clientPackage': 'com.oppo.store', 111 | 'Host': 'msec.opposhop.cn', 112 | 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 113 | 'Content-Type': 'application/x-www-form-urlencoded', 114 | 'Connection': 'keep-alive', 115 | 'User-Agent': 'okhttp/3.12.12.200sp1', 116 | 'Accept-Encoding': 'gzip', 117 | } 118 | params = { 119 | 'marking': 'daily_sharegoods' 120 | } 121 | for i in range(count + random.randint(1,3)): 122 | self.sess.get(url=url,headers=headers,params=params) 123 | notify(f"正在执行第{i+1}次微信分享...") 124 | time.sleep(random.randint(7,10)) 125 | if flag == 1: #来源积分大乱斗 126 | self.receiveAward(dic=dic) 127 | 128 | # 直播,宠粉,浏览商品 129 | def runViewTask(self,dic=None): 130 | aid = 1598 131 | url = 'https://hd.oppo.com/task/finish' 132 | headers = { 133 | 'Host': 'hd.oppo.com', 134 | 'Connection': 'keep-alive', 135 | 'Accept': '*/*', 136 | 'Origin': 'https://hd.oppo.com', 137 | 'X-Requested-With': 'XMLHttpRequest', 138 | 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', 139 | 'Referer': 'https://hd.oppo.com/act/m/2021/2021/realmejifendalu/index.html', 140 | 'Accept-Encoding': 'gzip, deflate', 141 | 'Accept-Language': 'zh-CN,en-US;q=0.9' 142 | } 143 | data = { 144 | 'aid': aid, 145 | 't_index': dic['t_index'] 146 | } 147 | response = self.sess.post(url=url,headers=headers,data=data).json() 148 | if response['no'] == '200': 149 | notify(f"[{dic['title']}]\t{response['msg']}") 150 | self.receiveAward(dic) 151 | else: 152 | notify(f"[{dic['title']}]\t{response['msg']}") 153 | time.sleep(random.randint(3,5)) 154 | 155 | def getBattleList(self): 156 | aid = 1598 # 抓包结果为固定值:1598 157 | url = 'https://hd.oppo.com/task/list' 158 | headers = { 159 | 'Host':'hd.oppo.com', 160 | 'Connection': 'keep-alive', 161 | 'Referer':'https://hd.oppo.com/act/m/2021/2021/realmejifendalu/index.html', 162 | 'Accept-Encoding': 'gzip, deflate', 163 | 'Accept-Language': 'zh-CN,en-US;q=0.9', 164 | } 165 | params = { 166 | 'aid':aid 167 | } 168 | response = self.sess.get(url=url,headers=headers,params=params).json() 169 | if response['no'] == '200': 170 | self.taskData = response['data'] 171 | return True 172 | else: 173 | notify(f"{response['msg']}") 174 | return False 175 | time.sleep(random.randint(1,3)) 176 | 177 | def runBattleTask(self): 178 | for each in self.taskData: 179 | if each['title'] == '浏览realme会场': 180 | if each['t_status'] == 0: 181 | self.runViewTask(dic=each) 182 | elif each['t_status'] == 1: 183 | self.receiveAward(each) 184 | elif each['t_status'] == 2: 185 | notify(f"[{each['title']}]\任务完成") 186 | elif each['title'] == '浏览一加会场': 187 | if each['t_status'] == 0: 188 | self.runViewTask(dic=each) 189 | elif each['t_status'] == 1: 190 | self.receiveAward(each) 191 | elif each['t_status'] == 2: 192 | notify(f"[{each['title']}]\t任务完成") 193 | elif each['title'] == '浏览潮流好物会场': 194 | if each['t_status'] == 0: 195 | self.runViewTask(dic=each) 196 | elif each['t_status'] == 1: 197 | self.receiveAward(each) 198 | elif each['t_status'] == 2: 199 | notify(f"[{each['title']}]\t任务完成") 200 | elif each['title'] == '观看realme直播': 201 | if each['t_status'] == 0: 202 | self.runViewTask(dic=each) 203 | elif each['t_status'] == 1: 204 | self.receiveAward(each) 205 | elif each['t_status'] == 2: 206 | notify(f"[{each['title']}]\t任务完成") 207 | elif each['title'] == '观看一加直播': 208 | if each['t_status'] == 0: 209 | self.runViewTask(dic=each) 210 | elif each['t_status'] == 1: 211 | self.receiveAward(each) 212 | elif each['t_status'] == 2: 213 | notify(f"[{each['title']}]\t任务完成") 214 | 215 | # 获取积分数量(只找到这个,找不到昨天积分数据) 216 | def getIntegral(self): 217 | url = 'https://store.oppo.com/cn/oapi/credits/web/credits/show' 218 | headers = { 219 | 'Host': 'store.oppo.com', 220 | 'Connection': 'keep-alive', 221 | 'source_type': '501', 222 | 'clientPackage': 'com.oppo.store', 223 | 'Accept': 'application/json, text/plain, */*', 224 | 'Accept-Encoding': 'gzip, deflate', 225 | 'Accept-Language': 'zh-CN,en-US;q=0.9', 226 | 'X-Requested-With': 'com.oppo.store', 227 | 'Referer': 'https://store.oppo.com/cn/app/taskCenter/index?us=gerenzhongxin&um=hudongleyuan&uc=renwuzhongxin' 228 | } 229 | response = self.sess.get(url=url,headers=headers).json() 230 | if response['code'] == 200: 231 | return f"{self.dic['user']}\t总积分:{response['data']['userCredits']}" 232 | else: 233 | return f"{self.dic['user']}\t错误原因:{response}" 234 | 235 | # 执行欢太商城实例对象 236 | def start(self): 237 | self.sess.headers.update({ 238 | "User-Agent":self.dic['UA'] 239 | }) 240 | self.sess.cookies.update({ 241 | "Cookie": self.dic['CK'] 242 | }) 243 | if self.login() == True: 244 | if self.getBattleList() == True: # 获取任务中心数据,判断CK是否正确(登录可能成功,但无法跑任务) 245 | self.runBattleTask() # 运行任务中心 246 | notify(self.getIntegral()) 247 | 248 | # 检测CK是否存在必备参数 249 | def checkHT(dic): 250 | CK = dic['CK'] 251 | if len(re.findall(r'source_type=.*?;',CK)) == 0: 252 | notify(f"{dic['user']}\tCK格式有误:可能缺少`source_type`字段") 253 | return False 254 | if len(re.findall(r'TOKENSID=.*?;',CK)) == 0: 255 | notify(f"{dic['user']}\tCK格式有误:可能缺少`TOKENSID`字段") 256 | return False 257 | if len(re.findall(r'app_param=.*?[;]?',CK)) == 0: 258 | notify(f"{dic['user']}\tCK格式有误:可能缺少`app_param`字段") 259 | return False 260 | return True 261 | 262 | # 兼容云函数 263 | def main_handler(event, context): 264 | global lists 265 | for each in lists: 266 | if each['CK']!='' and each['UA'] != '': 267 | if checkHT(each): 268 | battleForHeyTap = BattleForHeyTap(each) 269 | for count in range(3): 270 | try: 271 | time.sleep(random.randint(2,5)) # 随机延时 272 | battleForHeyTap.start() 273 | break 274 | except requests.exceptions.ConnectionError: 275 | notify(f"{battleForHeyTap.dic['user']}\t请求失败,随机延迟后再次访问") 276 | time.sleep(random.randint(2,5)) 277 | continue 278 | else: 279 | notify(f"账号: {battleForHeyTap.dic['user']}\n状态: 取消登录\n原因: 多次登录失败") 280 | break 281 | elif not all(each.values()): 282 | notify("账号:空账户\t状态:跳过") 283 | else: 284 | notify(f"账号: {each['user']}\n状态: 取消登录\n原因: json数据不齐全") 285 | notify('*' * 40 + '\n') 286 | if not os.path.basename(__file__).split('_')[-1][:-3] in notifyBlackList: 287 | send('欢太积分大乱斗',allMess) 288 | 289 | if __name__ == '__main__': 290 | main_handler(None,None) 291 | -------------------------------------------------------------------------------- /Backup/ChockInEarly.py: -------------------------------------------------------------------------------- 1 | # !/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # @Time : 2021/9/12 4 | # @Author : MashiroF 5 | # @File : ChockInEarly.py 6 | # @Software: PyCharm 7 | 8 | ''' 9 | cron: 35 0,19 * * * ChockInEarly.py 10 | new Env('欢太早睡打卡'); 11 | ''' 12 | 13 | import os 14 | import re 15 | import sys 16 | import time 17 | import random 18 | 19 | # 配置文件 20 | try: 21 | from HT_config import downFlag,notifyBlackList,logger 22 | import requests 23 | except Exception as error: 24 | logger.info(f'失败原因:{error}') 25 | sys.exit(0) 26 | 27 | # 判断是否发生下载行为 28 | if downFlag == True: 29 | logger.info('发生下载行为,应退出程序,编辑配置文件') 30 | sys.exit(0) 31 | 32 | # 配信文件 33 | try: 34 | from sendNotify import send 35 | except Exception as error: 36 | logger.info('推送文件有误') 37 | logger.info(f'失败原因:{error}') 38 | sys.exit(0) 39 | 40 | # 导入账户 41 | try: 42 | from HT_account import accounts 43 | lists = accounts 44 | except Exception as error: 45 | logger.info(f'失败原因:{error}') 46 | lists = [] 47 | 48 | # 配信内容格式 49 | allMess = '' 50 | def notify(content=None): 51 | global allMess 52 | allMess = allMess + content + '\n' 53 | logger.info(content) 54 | 55 | # 日志录入时间 56 | notify(f"任务:欢太早睡打卡\n时间:{time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())}") 57 | 58 | class CheckInEarly: 59 | def __init__(self,dic): 60 | self.dic = dic 61 | self.sess = requests.session() 62 | 63 | # 登录验证 64 | def login(self): 65 | url = 'https://store.oppo.com/cn/oapi/users/web/member/check' 66 | headers = { 67 | 'Host': 'store.oppo.com', 68 | 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 69 | 'Content-Type': 'application/x-www-form-urlencoded', 70 | 'Connection': 'keep-alive', 71 | 'Accept-Language': 'zh-cn', 72 | 'Accept-Encoding': 'gzip, deflate, br', 73 | } 74 | response = self.sess.get(url=url,headers=headers).json() 75 | if response['code'] == 200: 76 | notify(f"{self.dic['user']}\t登录成功") 77 | return True 78 | else: 79 | notify(f"{self.dic['user']}\t登录失败") 80 | return False 81 | 82 | # 报名或打卡 83 | # 报名或打卡是同一个链接,配合Linux定时系统 84 | def early(self): 85 | url = 'https://store.oppo.com/cn/oapi/credits/web/clockin/applyOrClockIn' 86 | headers = {'Host': 'store.oppo.com', 87 | 'Connection': 'keep-alive', 88 | 'source_type': '501', 89 | 'clientPackage': 'com.oppo.store', 90 | 'Accept': 'application/json, text/plain, */*', 91 | 'Referer': 'https://store.oppo.com/cn/app/cardingActivities?us=gerenzhongxin&um=hudongleyuan&uc=zaoshuidaka', 92 | 'Accept-Encoding': 'gzip, deflate', 93 | 'Accept-Language': 'zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7' 94 | } 95 | response = self.sess.get(url=url,headers=headers).json() 96 | if response['code'] == 200: 97 | if response['data']['clockInStatus'] == 0: 98 | if response['data']['applyStatus'] == 0: 99 | notify(f"{self.dic['user']}\t积分过少,取消报名!") 100 | elif response['data']['applyStatus'] == 1: 101 | notify(f"{self.dic['user']}\t报名成功!") 102 | elif response['data']['applyStatus'] == 2: 103 | notify(f"{self.dic['user']}\t已报名!") 104 | elif response['data']['clockInStatus'] == 1: 105 | notify(f"{self.dic['user']}\t早睡瓜分积分,打卡成功!") 106 | elif response['data']['clockInStatus'] == 2: 107 | notify(f"{self.dic['user']}\t早睡瓜分积分,已成功打卡!") 108 | elif response['code'] == 1000005: 109 | notify(f"{self.dic['user']}\t{response['errorMessage']}") 110 | 111 | # 获取积分数量(只找到这个,找不到昨天积分数据) 112 | def getIntegral(self): 113 | url = 'https://store.oppo.com/cn/oapi/credits/web/credits/show' 114 | headers = { 115 | 'Host': 'store.oppo.com', 116 | 'Connection': 'keep-alive', 117 | 'source_type': '501', 118 | 'clientPackage': 'com.oppo.store', 119 | 'Accept': 'application/json, text/plain, */*', 120 | 'Accept-Encoding': 'gzip, deflate', 121 | 'Accept-Language': 'zh-CN,en-US;q=0.9', 122 | 'X-Requested-With': 'com.oppo.store', 123 | 'Referer': 'https://store.oppo.com/cn/app/taskCenter/index?us=gerenzhongxin&um=hudongleyuan&uc=renwuzhongxin' 124 | } 125 | response = self.sess.get(url=url,headers=headers).json() 126 | if response['code'] == 200: 127 | return f"{self.dic['user']}\t总积分:{response['data']['userCredits']}" 128 | else: 129 | return f"{self.dic['user']}\t错误原因:{response}" 130 | 131 | # 执行欢太商城实例对象 132 | def start(self): 133 | self.sess.headers.update({ 134 | "User-Agent":self.dic['UA'] 135 | }) 136 | self.sess.cookies.update({ 137 | "Cookie":self.dic['CK'] 138 | }) 139 | if self.login() == True: 140 | self.early() 141 | notify(self.getIntegral()) 142 | 143 | # 检测CK是否存在必备参数 144 | def checkHT(dic): 145 | CK = dic['CK'] 146 | if len(re.findall(r'source_type=.*?;',CK)) == 0: 147 | notify(f"{dic['user']}\tCK格式有误:可能缺少`source_type`字段") 148 | return False 149 | if len(re.findall(r'TOKENSID=.*?;',CK)) == 0: 150 | notify(f"{dic['user']}\tCK格式有误:可能缺少`TOKENSID`字段") 151 | return False 152 | if len(re.findall(r'app_param=.*?[;]?',CK)) == 0: 153 | notify(f"{dic['user']}\tCK格式有误:可能缺少`app_param`字段") 154 | return False 155 | return True 156 | 157 | # 兼容云函数 158 | def main_handler(event, context): 159 | global lists 160 | for each in lists: 161 | if each['CK']!='' and each['UA'] != '': 162 | if checkHT(each): 163 | checkInEarly = CheckInEarly(each) 164 | for count in range(3): 165 | try: 166 | time.sleep(random.randint(2,5)) # 随机延时 167 | checkInEarly.start() 168 | break 169 | except requests.exceptions.ConnectionError: 170 | notify(f"{checkInEarly.dic['user']}\t请求失败,随机延迟后再次访问") 171 | time.sleep(random.randint(2,5)) 172 | continue 173 | else: 174 | notify(f"账号: {checkInEarly.dic['user']}\n状态: 取消登录\n原因: 多次登录失败") 175 | break 176 | elif not all(each.values()): 177 | notify("账号:空账户\t状态:跳过") 178 | else: 179 | notify(f"账号: {each['user']}\n状态: 取消登录\n原因: json数据不齐全") 180 | notify('*' * 40 + '\n') 181 | if not os.path.basename(__file__).split('_')[-1][:-3] in notifyBlackList: 182 | send('欢太早睡打卡',allMess) 183 | 184 | if __name__ == '__main__': 185 | main_handler(None,None) 186 | -------------------------------------------------------------------------------- /Backup/CollectionCard.py: -------------------------------------------------------------------------------- 1 | # !/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # @Time : 2021/9/26 4 | # @Author : MashiroF 5 | # @File : CollectionCard.py 6 | # @Software: PyCharm 7 | 8 | ''' 9 | cron: 46 5,12 * * * CollectionCard.py 10 | new Env('集卡赢套票'); 11 | ''' 12 | 13 | import os 14 | import re 15 | import sys 16 | import time 17 | import random 18 | import requests 19 | 20 | # 配置文件 21 | try: 22 | from HT_config import downFlag,notifyBlackList,logger 23 | except Exception as error: 24 | logger.info(f'失败原因:{error}') 25 | sys.exit(0) 26 | 27 | # 判断是否发生下载行为 28 | if downFlag == True: 29 | logger.info('发生下载行为,应退出程序,编辑配置文件') 30 | sys.exit(0) 31 | 32 | # 配信文件 33 | try: 34 | from sendNotify import send 35 | except Exception as error: 36 | logger.info('推送文件有误') 37 | logger.info(f'失败原因:{error}') 38 | sys.exit(0) 39 | 40 | # 导入账户 41 | try: 42 | from HT_account import accounts 43 | lists = accounts 44 | except Exception as error: 45 | logger.info(f'失败原因:{error}') 46 | lists = [] 47 | 48 | # 配信内容格式 49 | allMess = '' 50 | def notify(content=None): 51 | global allMess 52 | allMess = allMess + content + '\n' 53 | logger.info(content) 54 | 55 | # 日志录入时间 56 | notify(f"任务:集卡赢套票\n时间:{time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())}") 57 | 58 | class CollectionCard: 59 | def __init__(self,dic): 60 | self.dic = dic 61 | self.sess = requests.session() 62 | 63 | # 登录验证 64 | def login(self): 65 | url = 'https://store.oppo.com/cn/oapi/users/web/member/check' 66 | headers = { 67 | 'Host': 'store.oppo.com', 68 | 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 69 | 'Content-Type': 'application/x-www-form-urlencoded', 70 | 'Connection': 'keep-alive', 71 | 'Accept-Language': 'zh-cn', 72 | 'Accept-Encoding': 'gzip, deflate, br', 73 | } 74 | response = self.sess.get(url=url,headers=headers).json() 75 | if response['code'] == 200: 76 | notify(f"{self.dic['user']}\t登录成功") 77 | return True 78 | else: 79 | notify(f"{self.dic['user']}\t登录失败") 80 | return False 81 | 82 | def drawCard(self): 83 | url = 'https://store.oppo.com/cn/oapi/credits/web/ccv2/collect' 84 | headers = { 85 | "Host": "store.oppo.com", 86 | "Connection": "keep-alive", 87 | "s_channel": "oppo_appstore", 88 | "utm_term": "direct", 89 | "source_type": "501", 90 | "utm_campaign": "direct", 91 | "utm_source": "jika", 92 | "ut": "direct", 93 | "uc": "direct", 94 | "clientPackage": "com.oppo.store", 95 | "Cache-Control": "no-cache", 96 | "um": "youshangjiao", 97 | "ouid": "", 98 | "Content-Type": "application/x-www-form-urlencoded", 99 | "Accept": "application/json, text/plain, */*", 100 | "guid": "", 101 | "utm_medium": "xidi", 102 | "appId": "", 103 | "s_version": "201201", 104 | "us": "shouye", 105 | "appKey": "", 106 | "Origin": "https://store.oppo.com", 107 | "X-Requested-With": "com.oppo.store", 108 | "Referer": "https://store.oppo.com/cn/app/collectCard/index?activityId=RWTNLNQ8&us=shouye&um=youshangjiao", 109 | "Accept-Encoding": "gzip, deflate", 110 | "Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7" 111 | } 112 | data = { 113 | 'activityId':'RWTNLNQ8' 114 | } 115 | while True: 116 | response = self.sess.post(url=url,headers=headers,data=data).json() 117 | if response['code'] == 200: 118 | notify(f"[集卡活动]\t结果:{response['data']['collectCard']['cardName']}") 119 | else: 120 | notify(f"[集卡活动]\t{response['errorMessage']}") 121 | break 122 | time.sleep(random.randint(3,5)) 123 | 124 | 125 | def getTaskList(self): 126 | url = 'https://store.oppo.com/cn/oapi/credits/web/ccv2/showTaskList?activityId=RWTNLNQ8' 127 | headers = { 128 | "Host": "store.oppo.com", 129 | "Connection": "keep-alive", 130 | "s_channel": "oppo_appstore", 131 | "utm_term": "direct", 132 | "source_type": "501", 133 | "utm_campaign": "direct", 134 | "appKey": "", 135 | "ut": "direct", 136 | "uc": "direct", 137 | "clientPackage": "com.oppo.store", 138 | "Cache-Control": "no-cache", 139 | "um": "youshangjiao", 140 | "ouid": "", 141 | "Accept": "application/json, text/plain, */*", 142 | "guid": "", 143 | "appId": "", 144 | "s_version": "201201", 145 | "us": "shouye", 146 | "utm_source": "jika", 147 | "X-Requested-With": "com.oppo.store", 148 | "Referer": "https://store.oppo.com/cn/app/collectCard/index?activityId=RWTNLNQ8&us=shouye&um=youshangjiao", 149 | "Accept-Encoding": "gzip, deflate", 150 | "Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7" 151 | } 152 | response = self.sess.get(url=url,headers=headers).json() 153 | 154 | if response['code'] == 200: 155 | self.taskData = response['data'] 156 | return True 157 | else: 158 | notify(f"{response}") 159 | return False 160 | time.sleep(random.randint(1,3)) 161 | 162 | def runTask(self,dic): 163 | url = 'https://store.oppo.com/cn/oapi/credits/web/ccv2/ReportedTask' 164 | params = { 165 | 'activityId':'RWTNLNQ8', 166 | 'taskType':dic['taskId'] 167 | } 168 | headers = { 169 | "Host": "store.oppo.com", 170 | "Connection": "keep-alive", 171 | "s_channel": "oppo_appstore", 172 | "utm_term": "direct", 173 | "source_type": "501", 174 | "utm_campaign": "direct", 175 | "appKey": "", 176 | "ut": "direct", 177 | "uc": "direct", 178 | "clientPackage": "com.oppo.store", 179 | "Cache-Control": "no-cache", 180 | "um": "youshangjiao", 181 | "ouid": "", 182 | "Accept": "application/json, text/plain, */*", 183 | "guid": "", 184 | "utm_medium": "xidi", 185 | "appId": "", 186 | "s_version": "201201", 187 | "us": "shouye", 188 | "utm_source": "jika", 189 | "X-Requested-With": "com.oppo.store", 190 | "Referer": "https://store.oppo.com/cn/app/collectCard/index?activityId=RWTNLNQ8&us=shouye&um=youshangjiao", 191 | "Accept-Encoding": "gzip, deflate", 192 | "Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7" 193 | } 194 | response = self.sess.get(url=url,params=params,headers=headers).json() 195 | if response['code'] == 200: 196 | notify(f"[{dic['name']}]\t任务完成") 197 | else: 198 | notify(f"[{dic['name']}]\tcode:{response['code']}") 199 | time.sleep(random.randint(3,5)) 200 | 201 | def runTaskList(self): 202 | for each in self.taskData: 203 | if each['name'] == '每日打卡': 204 | if each['status'] == 0: 205 | self.runTask(dic=each) 206 | elif each['status'] == 2: 207 | notify(f"[{each['name']}]\t已打卡") 208 | elif each['name'] == '浏览会员日主会场': 209 | if each['status'] == 0: 210 | self.runTask(dic=each) 211 | elif each['status'] == 2: 212 | notify(f"[{each['name']}]\t已浏览") 213 | elif each['name'] == '分享活动': 214 | if each['status'] == 0: 215 | self.runTask(dic=each) 216 | elif each['status'] == 2: 217 | notify(f"[{each['name']}]\t已浏览") 218 | elif each['name'] == '浏览会员中心': 219 | if each['status'] == 0: 220 | self.runTask(dic=each) 221 | elif each['status'] == 2: 222 | notify(f"[{each['name']}]\t已浏览") 223 | elif each['name'] == '浏览秒杀频道': 224 | if each['status'] == 0: 225 | self.runTask(dic=each) 226 | elif each['status'] == 2: 227 | notify(f"[{each['name']}]\t已浏览") 228 | elif each['name'] == '浏览领券中心': 229 | if each['status'] == 0: 230 | self.runTask(dic=each) 231 | elif each['status'] == 2: 232 | notify(f"[{each['name']}]\t已浏览") 233 | 234 | # 执行欢太商城实例对象 235 | def start(self): 236 | self.sess.headers.update({ 237 | "User-Agent":self.dic['UA'] 238 | }) 239 | self.sess.cookies.update({ 240 | "Cookie": self.dic['CK'] 241 | }) 242 | if self.login() == True: 243 | if self.getTaskList() == True: # 获取任务中心数据,判断CK是否正确(登录可能成功,但无法跑任务) 244 | self.runTaskList() # 运行任务中心 245 | self.drawCard() 246 | notify('*' * 40 + '\n') 247 | 248 | # 检测CK是否存在必备参数 249 | def checkHT(dic): 250 | CK = dic['CK'] 251 | if len(re.findall(r'source_type=.*?;',CK)) == 0: 252 | notify(f"{dic['user']}\tCK格式有误:可能缺少`source_type`字段") 253 | return False 254 | if len(re.findall(r'TOKENSID=.*?;',CK)) == 0: 255 | notify(f"{dic['user']}\tCK格式有误:可能缺少`TOKENSID`字段") 256 | return False 257 | if len(re.findall(r'app_param=.*?[;]?',CK)) == 0: 258 | notify(f"{dic['user']}\tCK格式有误:可能缺少`app_param`字段") 259 | return False 260 | return True 261 | 262 | # 兼容云函数 263 | def main_handler(event, context): 264 | global lists 265 | for each in lists: 266 | if all(each.values()): 267 | if checkHT(each): 268 | collectionCard = CollectionCard(each) 269 | for count in range(3): 270 | try: 271 | time.sleep(random.randint(2,5)) # 随机延时 272 | collectionCard.start() 273 | break 274 | except requests.exceptions.ConnectionError: 275 | notify(f"{collectionCard.dic['user']}\t请求失败,随机延迟后再次访问") 276 | time.sleep(random.randint(2,5)) 277 | continue 278 | else: 279 | notify(f"账号: {collectionCard.dic['user']}\n状态: 取消登录\n原因: 多次登录失败") 280 | break 281 | elif not all(each.values()): 282 | notify("账号:空账户\t状态:跳过") 283 | else: 284 | notify(f"账号: {each['user']}\n状态: 取消登录\n原因: json数据不齐全") 285 | if not os.path.basename(__file__).split('_')[-1][:-3] in notifyBlackList: 286 | send('集卡赢套票',allMess) 287 | 288 | if __name__ == '__main__': 289 | main_handler(None,None) 290 | -------------------------------------------------------------------------------- /Backup/Community.py: -------------------------------------------------------------------------------- 1 | # !/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | # @Time : 2021/11/14 4 | # @Author : MashiroF 5 | # @File : Community.py 6 | # @Software: PyCharm 7 | 8 | ''' 9 | cron: 30 6,12 * * * Community.py 10 | new Env('OPPO社区签到、早起打卡'); 11 | ''' 12 | 13 | import os 14 | import re 15 | import sys 16 | import time 17 | import random 18 | import requests 19 | 20 | # 配置文件 21 | try: 22 | from HT_config import downFlag,notifyBlackList,logger 23 | except Exception as error: 24 | logger.info(f'失败原因:{error}') 25 | sys.exit(0) 26 | 27 | # 判断是否发生下载行为 28 | if downFlag == True: 29 | logger.info('发生下载行为,应退出程序,编辑配置文件') 30 | sys.exit(0) 31 | 32 | # 配信文件 33 | try: 34 | from sendNotify import send 35 | except Exception as error: 36 | logger.info('推送文件有误') 37 | logger.info(f'失败原因:{error}') 38 | sys.exit(0) 39 | 40 | # 导入账户 41 | try: 42 | from HT_account import accounts 43 | lists = accounts 44 | except Exception as error: 45 | logger.info(f'失败原因:{error}') 46 | lists = [] 47 | 48 | # 配信内容格式 49 | allMess = '' 50 | def notify(content=None): 51 | global allMess 52 | allMess = allMess + content + '\n' 53 | logger.info(content) 54 | 55 | # 日志录入时间 56 | notify(f"任务:OPPO社区签到、早起打卡\n时间:{time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())}") 57 | 58 | class Community: 59 | def __init__(self,dic): 60 | self.sess = requests.session() 61 | self.dic = dic 62 | self.ID = 453509395675611143 63 | 64 | def login(self): 65 | url = 'https://i-user.oppo.cn/member/v3/index/get.pb' 66 | headers = { 67 | "Accept-Encoding": "gzip", 68 | "Connection": "Keep-Alive", 69 | "Host": "i-user.oppo.cn", 70 | "TAP-GSLB": "0,0", 71 | "User-Agent": "okhttp/3.12.12.217", 72 | 'Accept': 'application/json, text/plain, */*' 73 | } 74 | response = self.sess.get(url=url,headers=headers).json() 75 | if response['message']['code'] == 200: 76 | self.loginMess = response 77 | notify(f"{self.dic['user']}\t登录成功") 78 | return True 79 | else: 80 | notify(f"{self.dic['user']}\t登录失败") 81 | return False 82 | 83 | # def computerValue(self,c,d): 84 | # r = int(d + (random.random() % 10) * 16) % 16 | 0 85 | # d = math.floor(d / 16) 86 | # return d,hex(r if c == 'x' else (r & 0x3 | 0x8))[-1] 87 | # 88 | # def generateUUID(self): 89 | # d = round(time.time() * 1000) 90 | # oldStr = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx' 91 | # newStr = '' 92 | # for i in oldStr: 93 | # if i == 'x' or i == 'y': 94 | # d,v = self.computerValue(i,d) 95 | # newStr += v 96 | # else: 97 | # newStr += i 98 | # return newStr 99 | 100 | def ClockIn(self): 101 | url = 'https://i-api.oppo.cn/sign/v1/index/create.pb' 102 | headers = { 103 | "Accept-Encoding": "gzip", 104 | "Connection": "Keep-Alive", 105 | "Host": "i-api.oppo.cn", 106 | "TAP-GSLB": "0,0", 107 | "User-Agent": "okhttp/3.12.12.217", 108 | 'Accept': 'application/json, text/plain, */*' 109 | } 110 | response = self.sess.get(url=url,headers=headers).json() 111 | if response['message']['code'] == 200 and response['message']['msg'] == '操作成功': 112 | notify(f"[每日签到]\t签到成功") 113 | elif response['message']['code'] == 200 and response['message']['msg'] == 'SUCCESS': 114 | notify(f"[每日签到]\t已签到") 115 | else: 116 | notify(f"[每日签到]\t签到失败\t失败原因:{response}") 117 | 118 | def SignUp(self): 119 | url = 'https://hdapi.oppo.cn/user/attendance/signUp' 120 | headers = { 121 | "Accept": "*/*", 122 | "Accept-Encoding": "gzip, deflate", 123 | "Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7", 124 | "Cache-Control": "no-cache", 125 | "Connection": "keep-alive", 126 | "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8", 127 | "Host": "hdapi.oppo.cn", 128 | "Origin": "https://hdpage.oppo.cn", 129 | "Pragma": "no-cache", 130 | "Referer": f"https://hdpage.oppo.cn/rglpdu/index.html?id={self.ID}", 131 | "X-Requested-With": "XMLHttpRequest" 132 | } 133 | data = { 134 | 'attendanceId':self.ID, 135 | 'nickName':self.loginMess['nickname'] 136 | } 137 | response = self.sess.post(url=url,headers=headers,data=data).json() 138 | if response['code'] == 200: 139 | notify(f"[早起打卡]\t报名成功") 140 | else: 141 | notify(f"[早起打卡]\t{response['msg']}") 142 | 143 | 144 | def SignIn(self): 145 | url = 'https://hdapi.oppo.cn/user/attendance/signIn' 146 | headers = { 147 | "Accept": "*/*", 148 | "Accept-Encoding": "gzip, deflate", 149 | "Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7", 150 | "Cache-Control": "no-cache", 151 | "Connection": "keep-alive", 152 | "Content-Type": "application/x-www-form-urlencoded;charset=UTF-8", 153 | "Host": "hdapi.oppo.cn", 154 | "Origin": "https://hdpage.oppo.cn", 155 | "Pragma": "no-cache", 156 | "Referer": f"https://hdpage.oppo.cn/rglpdu/index.html?id={self.ID}", 157 | "X-Requested-With": "XMLHttpRequest" 158 | } 159 | data = { 160 | 'attendanceId':self.ID 161 | } 162 | response = self.sess.post(url=url,headers=headers,data=data).json() 163 | if response['code'] == 200: 164 | notify(f"[早起打卡]\t打卡成功") 165 | else: 166 | notify(f"[早起打卡]\t{response['msg']}") 167 | 168 | def getTime(self): 169 | now = time.time() 170 | TZ = time.strftime("%Z", time.localtime(now)) 171 | if TZ == 'UTC' or TZ == '协调世界时': 172 | return time.strftime('%H:%M:%S',time.localtime(now+ 8*3600)) 173 | elif TZ == 'CST' or TZ == '中国标准时间': 174 | return time.strftime('%H:%M:%S',time.localtime(now)) 175 | else: 176 | notify(f"时区设置错误,当前时区:{TZ}\t预期时区:CST") 177 | return False 178 | 179 | def earlyBed(self): 180 | now = self.getTime() 181 | if now != False: 182 | if now > '09:30:00' and now < '23:59:00': 183 | self.SignUp() 184 | elif now > '05:30:00' and now < '09:00:00': 185 | self.SignIn() 186 | else: 187 | notify(f"[早起打卡]\t打卡报名时间段外,取消后续操作") 188 | 189 | 190 | def start(self): 191 | token = re.findall(r'TOKENSID=(TOKEN.*?;)',self.dic['CK'],re.S) 192 | if token !=[]: 193 | self.sess.headers.update({ 194 | "User-Agent":self.dic['UA'] 195 | }) 196 | self.sess.cookies.update({ 197 | "Cookie": ';token=' + token[0] 198 | }) 199 | if self.login() == True: 200 | self.ClockIn() 201 | self.earlyBed () 202 | 203 | def checkHT(dic): 204 | if len(re.findall(r'TOKENSID=.*?;',dic['CK'])) == 0: 205 | notify(f"{dic['user']}\tCK格式有误:可能缺少`TOKENSID`字段") 206 | return False 207 | return True 208 | 209 | # 兼容云函数 210 | def main_handler(event, context): 211 | global lists 212 | for each in lists: 213 | if each['CK']!='' and each['UA'] != '': 214 | if checkHT(each): 215 | community = Community(each) 216 | for count in range(3): 217 | try: 218 | time.sleep(random.randint(2,5)) # 随机延时 219 | community.start() 220 | break 221 | except requests.exceptions.ConnectionError: 222 | notify(f"{community.dic['user']}\t请求失败,随机延迟后再次访问") 223 | time.sleep(random.randint(2,5)) 224 | continue 225 | else: 226 | notify(f"账号: {community.dic['user']}\n状态: 取消登录\n原因: 多次登录失败") 227 | elif not all(each.values()): 228 | notify("账号:空账户\t状态:跳过") 229 | else: 230 | notify(f"账号: {each['user']}\n状态: 取消登录\n原因: json数据不齐全") 231 | notify('*' * 40 + '\n') 232 | if not os.path.basename(__file__).split('_')[-1][:-3] in notifyBlackList: 233 | send('OPPO社区签到、早起打卡',allMess) 234 | 235 | if __name__ == '__main__': 236 | main_handler(None,None) 237 | -------------------------------------------------------------------------------- /Backup/Double11.py: -------------------------------------------------------------------------------- 1 | # !/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # @Time : 2021/10/20 4 | # @Author : MashiroF 5 | # @File : Double11.py 6 | # @Software: PyCharm 7 | 8 | ''' 9 | cron: 44 7,11 * * * Double11.py 10 | new Env('全名抽免单'); 11 | ''' 12 | 13 | import os 14 | import re 15 | import sys 16 | import time 17 | import random 18 | import requests 19 | 20 | # 配置文件 21 | try: 22 | from HT_config import downFlag,notifyBlackList,logger 23 | except Exception as error: 24 | logger.info(f'失败原因:{error}') 25 | sys.exit(0) 26 | 27 | # 判断是否发生下载行为 28 | if downFlag == True: 29 | logger.info('发生下载行为,应退出程序,编辑配置文件') 30 | sys.exit(0) 31 | 32 | # 配信文件 33 | try: 34 | from sendNotify import send 35 | except Exception as error: 36 | logger.info('推送文件有误') 37 | logger.info(f'失败原因:{error}') 38 | sys.exit(0) 39 | 40 | # 导入账户 41 | try: 42 | from HT_account import accounts 43 | lists = accounts 44 | except Exception as error: 45 | logger.info(f'失败原因:{error}') 46 | lists = [] 47 | 48 | # 配信内容格式 49 | allMess = '' 50 | def notify(content=None): 51 | global allMess 52 | allMess = allMess + content + '\n' 53 | logger.info(content) 54 | 55 | # 日志录入时间 56 | notify(f"任务:全名抽免单\n时间:{time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())}") 57 | 58 | class Double11: 59 | def __init__(self,dic): 60 | self.dic = dic 61 | self.sess = requests.session() 62 | 63 | # 登录验证 64 | def login(self): 65 | url = 'https://store.oppo.com/cn/oapi/users/web/member/check' 66 | headers = { 67 | 'Host': 'store.oppo.com', 68 | 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 69 | 'Content-Type': 'application/x-www-form-urlencoded', 70 | 'Connection': 'keep-alive', 71 | 'Accept-Language': 'zh-cn', 72 | 'Accept-Encoding': 'gzip, deflate, br', 73 | } 74 | response = self.sess.get(url=url,headers=headers).json() 75 | if response['code'] == 200: 76 | notify(f"{self.dic['user']}\t登录成功") 77 | return True 78 | else: 79 | notify(f"{self.dic['user']}\t登录失败") 80 | return False 81 | 82 | # 秒杀详情页获取商品数据 83 | def getGoodMess(self,count=10): 84 | taskUrl = f'https://msec.opposhop.cn/goods/v1/SeckillRound/goods/{random.randint(100,250)}' # 随机商品 85 | headers = { 86 | 'clientPackage': 'com.oppo.store', 87 | 'Host': 'msec.opposhop.cn', 88 | 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 89 | 'Content-Type': 'application/x-www-form-urlencoded', 90 | 'Connection': 'keep-alive', 91 | 'User-Agent': 'okhttp/3.12.12.200sp1', 92 | 'Accept-Encoding': 'gzip', 93 | } 94 | params = { 95 | 'pageSize':count + random.randint(1,3) 96 | } 97 | response = self.sess.get(url=taskUrl,headers=headers,params=params).json() 98 | if response['meta']['code'] == 200: 99 | return response 100 | 101 | def viewGoods(self, count,dic=None): 102 | headers = { 103 | 'clientPackage': 'com.oppo.store', 104 | 'Host': 'msec.opposhop.cn', 105 | 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 106 | 'Content-Type': 'application/x-www-form-urlencoded', 107 | 'Connection': 'keep-alive', 108 | 'User-Agent': 'okhttp/3.12.12.200sp1', 109 | 'Accept-Encoding': 'gzip' 110 | } 111 | result = self.getGoodMess(count=count) # 秒杀列表存在商品url 112 | if result['meta']['code'] == 200: 113 | for each in result['detail']: 114 | url = f"https://msec.opposhop.cn/goods/v1/info/sku?skuId={each['skuid']}" 115 | self.sess.get(url=url,headers=headers) 116 | notify(f"正在浏览商品id:{each['skuid']}...") 117 | time.sleep(random.randint(7,10)) 118 | if dic: 119 | self.receiveAward(dic) 120 | 121 | def receiveAward(self,dic): 122 | aid = 1768 123 | url = 'https://hd.oppo.com/task/award' 124 | headers = { 125 | 'Host': 'hd.oppo.com', 126 | 'Connection': 'keep-alive', 127 | 'Accept': '*/*', 128 | 'Origin': 'https://hd.oppo.com', 129 | 'X-Requested-With': 'XMLHttpRequest', 130 | 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', 131 | 'Referer': 'https://hd.oppo.com/act/m/2021/jifenzhuanpan/index.html?us=gerenzhongxin&um=hudongleyuan&uc=yingjifen', 132 | 'Accept-Encoding': 'gzip, deflate', 133 | 'Accept-Language': 'zh-CN,en-US;q=0.9' 134 | } 135 | data = { 136 | 'aid': aid, 137 | 't_index': dic['t_index'] 138 | } 139 | response = self.sess.post(url=url,headers=headers,data=data).json() 140 | if response['no'] == '200': 141 | notify(f"[{dic['title']}]\t{response['msg']}") 142 | else: 143 | notify(f"[{dic['title']}]\t{response['msg']}") 144 | time.sleep(random.randint(1,3)) 145 | 146 | # def shareGoods(self,count=2,flag=None,dic=None): 147 | # url = 'https://msec.opposhop.cn/users/vi/creditsTask/pushTask' 148 | # headers = { 149 | # 'clientPackage': 'com.oppo.store', 150 | # 'Host': 'msec.opposhop.cn', 151 | # 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 152 | # 'Content-Type': 'application/x-www-form-urlencoded', 153 | # 'Connection': 'keep-alive', 154 | # 'User-Agent': 'okhttp/3.12.12.200sp1', 155 | # 'Accept-Encoding': 'gzip', 156 | # } 157 | # params = { 158 | # 'marking': 'daily_sharegoods' 159 | # } 160 | # for i in range(count + random.randint(1,3)): 161 | # self.sess.get(url=url,headers=headers,params=params) 162 | # notify(f"正在执行第{i+1}次微信分享...") 163 | # time.sleep(random.randint(7,10)) 164 | # if flag == 1: 165 | # self.receiveAward(dic=dic) 166 | 167 | def runViewTask(self,dic=None): 168 | aid = 1768 169 | url = 'https://hd.oppo.com/task/finish' 170 | headers = { 171 | 'Host': 'hd.oppo.com', 172 | 'Connection': 'keep-alive', 173 | 'Accept': '*/*', 174 | 'Origin': 'https://hd.oppo.com', 175 | 'X-Requested-With': 'XMLHttpRequest', 176 | 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', 177 | 'Referer': 'https://hd.oppo.com/act/m/2021/2021/realmejifendalu/index.html', 178 | 'Accept-Encoding': 'gzip, deflate', 179 | 'Accept-Language': 'zh-CN,en-US;q=0.9' 180 | } 181 | data = { 182 | 'aid': aid, 183 | 't_index': dic['t_index'] 184 | } 185 | response = self.sess.post(url=url,headers=headers,data=data).json() 186 | if response['no'] == '200': 187 | notify(f"[{dic['title']}]\t{response['msg']}") 188 | self.receiveAward(dic) 189 | else: 190 | notify(f"[{dic['title']}]\t{response['msg']}") 191 | time.sleep(random.randint(3,5)) 192 | 193 | def getBattleList(self): 194 | aid = 1768 # 抓包结果为固定值:1582 195 | url = 'https://hd.oppo.com/task/list' 196 | headers = { 197 | 'Host':'hd.oppo.com', 198 | 'Connection': 'keep-alive', 199 | 'Referer':'https://hd.oppo.com/act/m/2021/2021/realmejifendalu/index.html', 200 | 'Accept-Encoding': 'gzip, deflate', 201 | 'Accept-Language': 'zh-CN,en-US;q=0.9', 202 | } 203 | params = { 204 | 'aid':aid 205 | } 206 | response = self.sess.get(url=url,headers=headers,params=params).json() 207 | time.sleep(random.randint(3,5)) 208 | if response['no'] == '200': 209 | self.taskData = response['data'] 210 | return True 211 | else: 212 | notify(f"{response['msg']}") 213 | return False 214 | 215 | def runBattleTask(self): 216 | for each in self.taskData: 217 | if each['title'] == '每日签到': 218 | if each['t_status'] == 0: 219 | self.runViewTask(dic=each) 220 | elif each['t_status'] == 1: 221 | self.receiveAward(each) 222 | elif each['t_status'] == 2: 223 | notify(f"[{each['title']}]\t领取成功") 224 | elif each['title'] == '浏览11.11主会场': 225 | if each['t_status'] == 0: 226 | self.runViewTask(dic=each) 227 | elif each['t_status'] == 1: 228 | self.receiveAward(each) 229 | elif each['t_status'] == 2: 230 | notify(f"[{each['title']}]\t任务完成") 231 | elif each['title'] == '浏览天天抢5折会场': 232 | if each['t_status'] == 0: 233 | self.runViewTask(dic=each) 234 | elif each['t_status'] == 1: 235 | self.receiveAward(each) 236 | elif each['t_status'] == 2: 237 | notify(f"[{each['title']}]\t任务完成") 238 | elif each['title'] == '浏览会员中心': 239 | if each['t_status'] == 0: 240 | self.runViewTask(dic=each) 241 | elif each['t_status'] == 1: 242 | self.receiveAward(each) 243 | elif each['t_status'] == 2: 244 | notify(f"[{each['title']}]\t任务完成") 245 | elif each['title'] == '浏览OPPO 11.11会场': 246 | if each['t_status'] == 0: 247 | self.runViewTask(dic=each) 248 | elif each['t_status'] == 1: 249 | self.receiveAward(each) 250 | elif each['t_status'] == 2: 251 | notify(f"[{each['title']}]\t任务完成") 252 | elif each['title'] == '浏览一加 11.11会场': 253 | if each['t_status'] == 0: 254 | self.runViewTask(dic=each) 255 | elif each['t_status'] == 1: 256 | self.receiveAward(each) 257 | elif each['t_status'] == 2: 258 | notify(f"[{each['title']}]\t任务完成") 259 | elif each['title'] == '浏览realme 11.11会场': 260 | if each['t_status'] == 0: 261 | self.runViewTask(dic=each) 262 | elif each['t_status'] == 1: 263 | self.receiveAward(each) 264 | elif each['t_status'] == 2: 265 | notify(f"[{each['title']}]\t任务完成") 266 | elif each['title'] == '浏览智能硬件 11.11会场': 267 | if each['t_status'] == 0: 268 | self.runViewTask(dic=each) 269 | elif each['t_status'] == 1: 270 | self.receiveAward(each) 271 | elif each['t_status'] == 2: 272 | notify(f"[{each['title']}]\t任务完成") 273 | elif each['title'] == '浏览潮流好物 11.11会场': 274 | if each['t_status'] == 0: 275 | self.runViewTask(dic=each) 276 | elif each['t_status'] == 1: 277 | self.receiveAward(each) 278 | elif each['t_status'] == 2: 279 | notify(f"[{each['title']}]\t任务完成") 280 | elif each['title'] == '浏览商品': 281 | if each['t_status'] == 0: 282 | self.viewGoods(count=2,dic=each) 283 | elif each['t_status'] == 1: 284 | self.receiveAward(each) 285 | elif each['t_status'] == 2: 286 | notify(f"[{each['title']}]\t任务完成") 287 | 288 | # 获取积分数量(只找到这个,找不到昨天积分数据) 289 | def getIntegral(self): 290 | url = 'https://store.oppo.com/cn/oapi/credits/web/credits/show' 291 | headers = { 292 | 'Host': 'store.oppo.com', 293 | 'Connection': 'keep-alive', 294 | 'source_type': '501', 295 | 'clientPackage': 'com.oppo.store', 296 | 'Accept': 'application/json, text/plain, */*', 297 | 'Accept-Encoding': 'gzip, deflate', 298 | 'Accept-Language': 'zh-CN,en-US;q=0.9', 299 | 'X-Requested-With': 'com.oppo.store', 300 | 'Referer': 'https://store.oppo.com/cn/app/taskCenter/index?us=gerenzhongxin&um=hudongleyuan&uc=renwuzhongxin' 301 | } 302 | response = self.sess.get(url=url,headers=headers).json() 303 | if response['code'] == 200: 304 | return f"{self.dic['user']}\t总积分:{response['data']['userCredits']}" 305 | else: 306 | return f"{self.dic['user']}\t错误原因:{response}" 307 | 308 | # 执行欢太商城实例对象 309 | def start(self): 310 | self.sess.headers.update({ 311 | "User-Agent":self.dic['UA'] 312 | }) 313 | self.sess.cookies.update({ 314 | "Cookie": self.dic['CK'] 315 | }) 316 | if self.login() == True: 317 | if self.getBattleList() == True: # 获取任务中心数据,判断CK是否正确(登录可能成功,但无法跑任务) 318 | self.runBattleTask() # 运行任务中心 319 | notify(self.getIntegral()) 320 | notify('*' * 40 + '\n') 321 | 322 | # 检测CK是否存在必备参数 323 | def checkHT(dic): 324 | CK = dic['CK'] 325 | if len(re.findall(r'source_type=.*?;',CK)) == 0: 326 | notify(f"{dic['user']}\tCK格式有误:可能缺少`source_type`字段") 327 | return False 328 | if len(re.findall(r'TOKENSID=.*?;',CK)) == 0: 329 | notify(f"{dic['user']}\tCK格式有误:可能缺少`TOKENSID`字段") 330 | return False 331 | if len(re.findall(r'app_param=.*?[;]?',CK)) == 0: 332 | notify(f"{dic['user']}\tCK格式有误:可能缺少`app_param`字段") 333 | return False 334 | return True 335 | 336 | # 兼容云函数 337 | def main_handler(event, context): 338 | global lists 339 | for each in lists: 340 | if all(each.values()): 341 | if checkHT(each): 342 | double11 = Double11(each) 343 | for count in range(3): 344 | try: 345 | time.sleep(random.randint(2,5)) # 随机延时 346 | double11.start() 347 | break 348 | except requests.exceptions.ConnectionError: 349 | notify(f"{double11.dic['user']}\t请求失败,随机延迟后再次访问") 350 | time.sleep(random.randint(2,5)) 351 | continue 352 | else: 353 | notify(f"账号: {double11.dic['user']}\n状态: 取消登录\n原因: 多次登录失败") 354 | break 355 | elif not all(each.values()): 356 | notify("账号:空账户\t状态:跳过") 357 | else: 358 | notify(f"账号: {each['user']}\n状态: 取消登录\n原因: json数据不齐全") 359 | if not os.path.basename(__file__).split('_')[-1][:-3] in notifyBlackList: 360 | send('全名抽免单',allMess) 361 | 362 | if __name__ == '__main__': 363 | main_handler(None,None) 364 | -------------------------------------------------------------------------------- /BattleForRealMe.py: -------------------------------------------------------------------------------- 1 | # !/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # @Time : 2021/9/16 4 | # @Author : MashiroF 5 | # @File : BattleForRealMe.py 6 | # @Software: PyCharm 7 | 8 | ''' 9 | cron: 40 5,12 * * * BattleForRealMe.py 10 | new Env('RealMe积分大乱斗'); 11 | ''' 12 | 13 | import os 14 | import re 15 | import sys 16 | import time 17 | import random 18 | import requests 19 | 20 | # 配置文件 21 | try: 22 | from HT_config import downFlag,notifyBlackList,logger 23 | except Exception as error: 24 | logger.info(f'失败原因:{error}') 25 | sys.exit(0) 26 | 27 | # 判断是否发生下载行为 28 | if downFlag == True: 29 | logger.info('发生下载行为,应退出程序,编辑配置文件') 30 | sys.exit(0) 31 | 32 | # 配信文件 33 | try: 34 | from sendNotify import send 35 | except Exception as error: 36 | logger.info('推送文件有误') 37 | logger.info(f'失败原因:{error}') 38 | sys.exit(0) 39 | 40 | # 导入账户 41 | try: 42 | from HT_account import accounts 43 | lists = accounts 44 | except Exception as error: 45 | logger.info(f'失败原因:{error}') 46 | lists = [] 47 | 48 | # 配信内容格式 49 | allMess = '' 50 | def notify(content=None): 51 | global allMess 52 | allMess = allMess + content + '\n' 53 | logger.info(content) 54 | 55 | # 日志录入时间 56 | notify(f"任务:RealMe积分大乱斗\n时间:{time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())}") 57 | 58 | class BattleForRealMe: 59 | def __init__(self,dic): 60 | self.dic = dic 61 | self.sess = requests.session() 62 | 63 | # 登录验证 64 | def login(self): 65 | url = 'https://store.oppo.com/cn/oapi/users/web/member/check' 66 | headers = { 67 | 'Host': 'store.oppo.com', 68 | 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 69 | 'Content-Type': 'application/x-www-form-urlencoded', 70 | 'Connection': 'keep-alive', 71 | 'Accept-Language': 'zh-cn', 72 | 'Accept-Encoding': 'gzip, deflate, br', 73 | } 74 | response = self.sess.get(url=url,headers=headers).json() 75 | if response['code'] == 200: 76 | notify(f"{self.dic['user']}\t登录成功") 77 | return True 78 | else: 79 | notify(f"{self.dic['user']}\t登录失败") 80 | return False 81 | 82 | def receiveAward(self,dic): 83 | aid = 1582 84 | url = 'https://hd.oppo.com/task/award' 85 | headers = { 86 | 'Host': 'hd.oppo.com', 87 | 'Connection': 'keep-alive', 88 | 'Accept': '*/*', 89 | 'Origin': 'https://hd.oppo.com', 90 | 'X-Requested-With': 'XMLHttpRequest', 91 | 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', 92 | 'Referer': 'https://hd.oppo.com/act/m/2021/jifenzhuanpan/index.html?us=gerenzhongxin&um=hudongleyuan&uc=yingjifen', 93 | 'Accept-Encoding': 'gzip, deflate', 94 | 'Accept-Language': 'zh-CN,en-US;q=0.9' 95 | } 96 | data = { 97 | 'aid': aid, 98 | 't_index': dic['t_index'] 99 | } 100 | response = self.sess.post(url=url,headers=headers,data=data).json() 101 | if response['no'] == '200': 102 | notify(f"[{dic['title']}]\t{response['msg']}") 103 | else: 104 | notify(f"[{dic['title']}]\t{response['msg']}") 105 | time.sleep(random.randint(1,3)) 106 | 107 | def shareGoods(self,count=2,flag=None,dic=None): 108 | url = 'https://msec.opposhop.cn/users/vi/creditsTask/pushTask' 109 | headers = { 110 | 'clientPackage': 'com.oppo.store', 111 | 'Host': 'msec.opposhop.cn', 112 | 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 113 | 'Content-Type': 'application/x-www-form-urlencoded', 114 | 'Connection': 'keep-alive', 115 | 'User-Agent': 'okhttp/3.12.12.200sp1', 116 | 'Accept-Encoding': 'gzip', 117 | } 118 | params = { 119 | 'marking': 'daily_sharegoods' 120 | } 121 | for i in range(count + random.randint(1,3)): 122 | self.sess.get(url=url,headers=headers,params=params) 123 | notify(f"正在执行第{i+1}次微信分享...") 124 | time.sleep(random.randint(7,10)) 125 | if flag == 1: #来源积分大乱斗 126 | self.receiveAward(dic=dic) 127 | 128 | # # 直播,宠粉,浏览商品 129 | def runViewTask(self,dic=None): 130 | aid = 1582 131 | url = 'https://hd.oppo.com/task/finish' 132 | headers = { 133 | 'Host': 'hd.oppo.com', 134 | 'Connection': 'keep-alive', 135 | 'Accept': '*/*', 136 | 'Origin': 'https://hd.oppo.com', 137 | 'X-Requested-With': 'XMLHttpRequest', 138 | 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', 139 | 'Referer': 'https://hd.oppo.com/act/m/2021/2021/realmejifendalu/index.html', 140 | 'Accept-Encoding': 'gzip, deflate', 141 | 'Accept-Language': 'zh-CN,en-US;q=0.9' 142 | } 143 | data = { 144 | 'aid': aid, 145 | 't_index': dic['t_index'] 146 | } 147 | response = self.sess.post(url=url,headers=headers,data=data).json() 148 | if response['no'] == '200': 149 | notify(f"[{dic['title']}]\t{response['msg']}") 150 | self.receiveAward(dic) 151 | else: 152 | notify(f"[{dic['title']}]\t{response['msg']}") 153 | time.sleep(random.randint(3,5)) 154 | 155 | def getBattleList(self): 156 | aid = 1582 # 抓包结果为固定值:1582 157 | url = 'https://hd.oppo.com/task/list' 158 | headers = { 159 | 'Host':'hd.oppo.com', 160 | 'Connection': 'keep-alive', 161 | 'Referer':'https://hd.oppo.com/act/m/2021/2021/realmejifendalu/index.html', 162 | 'Accept-Encoding': 'gzip, deflate', 163 | 'Accept-Language': 'zh-CN,en-US;q=0.9', 164 | } 165 | params = { 166 | 'aid':aid 167 | } 168 | response = self.sess.get(url=url,headers=headers,params=params).json() 169 | time.sleep(random.randint(3,5)) 170 | if response['no'] == '200': 171 | self.taskData = response['data'] 172 | return True 173 | else: 174 | notify(f"{response['msg']}") 175 | return False 176 | 177 | def runBattleTask(self): 178 | for each in self.taskData: 179 | if each['title'] == '分享商品': 180 | if each['t_status'] == 0: 181 | self.shareGoods(flag=1,count=2,dic=each) 182 | elif each['t_status'] == 1: 183 | self.receiveAward(each) 184 | elif each['t_status'] == 2: 185 | notify(f"[{each['title']}]\t领取成功") 186 | elif each['title'] == '参与欢太超级宠粉': 187 | if each['t_status'] == 0: 188 | self.runViewTask(dic=each) 189 | elif each['t_status'] == 1: 190 | self.receiveAward(each) 191 | elif each['t_status'] == 2: 192 | notify(f"[{each['title']}]\t任务完成") 193 | elif each['title'] == '观看直播': 194 | if each['t_status'] == 0: 195 | self.runViewTask(dic=each) 196 | elif each['t_status'] == 1: 197 | self.receiveAward(each) 198 | elif each['t_status'] == 2: 199 | notify(f"[{each['title']}]\t任务完成") 200 | elif each['title'] == '浏览真我Q3S' or each['title'] == '浏览真我Q3S': 201 | if each['t_status'] == 0: 202 | self.runViewTask(dic=each) 203 | elif each['t_status'] == 1: 204 | self.receiveAward(each) 205 | elif each['t_status'] == 2: 206 | notify(f"[{each['title']}]\t任务完成") 207 | elif each['title'] == '浏览真我GT Neo2T' or each['title'] == '预约真我GT Neo2T': 208 | if each['t_status'] == 0: 209 | self.runViewTask(dic=each) 210 | elif each['t_status'] == 1: 211 | self.receiveAward(each) 212 | elif each['t_status'] == 2: 213 | notify(f"[{each['title']}]\t任务完成") 214 | elif each['title'] == '浏览realme会场': 215 | if each['t_status'] == 0: 216 | self.runViewTask(dic=each) 217 | elif each['t_status'] == 1: 218 | self.receiveAward(each) 219 | elif each['t_status'] == 2: 220 | notify(f"[{each['title']}]\t任务完成") 221 | 222 | # 获取积分数量(只找到这个,找不到昨天积分数据) 223 | def getIntegral(self): 224 | url = 'https://store.oppo.com/cn/oapi/credits/web/credits/show' 225 | headers = { 226 | 'Host': 'store.oppo.com', 227 | 'Connection': 'keep-alive', 228 | 'source_type': '501', 229 | 'clientPackage': 'com.oppo.store', 230 | 'Accept': 'application/json, text/plain, */*', 231 | 'Accept-Encoding': 'gzip, deflate', 232 | 'Accept-Language': 'zh-CN,en-US;q=0.9', 233 | 'X-Requested-With': 'com.oppo.store', 234 | 'Referer': 'https://store.oppo.com/cn/app/taskCenter/index?us=gerenzhongxin&um=hudongleyuan&uc=renwuzhongxin' 235 | } 236 | response = self.sess.get(url=url,headers=headers).json() 237 | if response['code'] == 200: 238 | return f"{self.dic['user']}\t总积分:{response['data']['userCredits']}" 239 | else: 240 | return f"{self.dic['user']}\t错误原因:{response}" 241 | 242 | # 执行欢太商城实例对象 243 | def start(self): 244 | self.sess.headers.update({ 245 | "User-Agent":self.dic['UA'] 246 | }) 247 | self.sess.cookies.update({ 248 | "Cookie": self.dic['CK'] 249 | }) 250 | if self.login() == True: 251 | if self.getBattleList() == True: # 获取任务中心数据,判断CK是否正确(登录可能成功,但无法跑任务) 252 | self.runBattleTask() # 运行任务中心 253 | notify(self.getIntegral()) 254 | 255 | # 检测CK是否存在必备参数 256 | def checkHT(dic): 257 | CK = dic['CK'] 258 | if len(re.findall(r'source_type=.*?;',CK)) == 0: 259 | notify(f"{dic['user']}\tCK格式有误:可能缺少`source_type`字段") 260 | return False 261 | if len(re.findall(r'TOKENSID=.*?;',CK)) == 0: 262 | notify(f"{dic['user']}\tCK格式有误:可能缺少`TOKENSID`字段") 263 | return False 264 | if len(re.findall(r'app_param=.*?[;]?',CK)) == 0: 265 | notify(f"{dic['user']}\tCK格式有误:可能缺少`app_param`字段") 266 | return False 267 | return True 268 | 269 | # 兼容云函数 270 | def main_handler(event, context): 271 | global lists 272 | for each in lists: 273 | if each['CK']!='' and each['UA'] != '': 274 | if checkHT(each): 275 | battleForRealMe = BattleForRealMe(each) 276 | for count in range(3): 277 | try: 278 | time.sleep(random.randint(2,5)) # 随机延时 279 | battleForRealMe.start() 280 | break 281 | except requests.exceptions.ConnectionError: 282 | notify(f"{battleForRealMe.dic['user']}\t请求失败,随机延迟后再次访问") 283 | time.sleep(random.randint(2,5)) 284 | continue 285 | else: 286 | notify(f"账号: {battleForRealMe.dic['user']}\n状态: 取消登录\n原因: 多次登录失败") 287 | break 288 | elif not all(each.values()): 289 | notify("账号:空账户\t状态:跳过") 290 | else: 291 | notify(f"账号: {each['user']}\n状态: 取消登录\n原因: json数据不齐全") 292 | notify('*' * 40 + '\n') 293 | if not os.path.basename(__file__).split('_')[-1][:-3] in notifyBlackList: 294 | send('RealMe积分大乱斗',allMess) 295 | 296 | if __name__ == '__main__': 297 | main_handler(None,None) 298 | -------------------------------------------------------------------------------- /DailyCash.py: -------------------------------------------------------------------------------- 1 | # !/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # @Time : 2021/9/12 4 | # @Author : MashiroF 5 | # @File : DailyCash.py 6 | # @Software: PyCharm 7 | 8 | ''' 9 | cron: 30 5,12 * * * DailyCash.py 10 | new Env('欢太每日现金'); 11 | ''' 12 | 13 | import os 14 | import re 15 | import sys 16 | import time 17 | import random 18 | 19 | # 配置文件 20 | try: 21 | from HT_config import downFlag,notifyBlackList,logger 22 | import requests 23 | except Exception as error: 24 | logger.info(f'失败原因:{error}') 25 | sys.exit(0) 26 | 27 | # 判断是否发生下载行为 28 | if downFlag == True: 29 | logger.info('发生下载行为,应退出程序,编辑配置文件') 30 | sys.exit(0) 31 | 32 | # 配信文件 33 | try: 34 | from sendNotify import send 35 | except Exception as error: 36 | logger.info('推送文件有误') 37 | logger.info(f'失败原因:{error}') 38 | sys.exit(0) 39 | 40 | # 导入账户 41 | try: 42 | from HT_account import accounts 43 | lists = accounts 44 | except Exception as error: 45 | logger.info(f'失败原因:{error}') 46 | lists = [] 47 | 48 | # 配信内容格式 49 | allMess = '' 50 | def notify(content=None): 51 | global allMess 52 | allMess = allMess + content + '\n' 53 | logger.info(content) 54 | 55 | # 日志录入时间 56 | notify(f"任务:欢太每日现金\n时间:{time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())}") 57 | 58 | class DailyCash: 59 | def __init__(self,dic): 60 | self.dic = dic 61 | self.sess = requests.session() 62 | 63 | # 登录验证 64 | def login(self): 65 | url = 'https://store.oppo.com/cn/oapi/users/web/member/check' 66 | headers = { 67 | 'Host': 'store.oppo.com', 68 | 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 69 | 'Content-Type': 'application/x-www-form-urlencoded', 70 | 'Connection': 'keep-alive', 71 | 'Accept-Language': 'zh-cn', 72 | 'Accept-Encoding': 'gzip, deflate, br', 73 | } 74 | response = self.sess.get(url=url,headers=headers).json() 75 | if response['code'] == 200: 76 | notify(f"{self.dic['user']}\t登录成功") 77 | return True 78 | else: 79 | notify(f"{self.dic['user']}\t登录失败") 80 | return False 81 | 82 | # 浏览商品 83 | def viewGoods(self, count,flag,dic=None): 84 | headers = { 85 | 'clientPackage': 'com.oppo.store', 86 | 'Host': 'msec.opposhop.cn', 87 | 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 88 | 'Content-Type': 'application/x-www-form-urlencoded', 89 | 'Connection': 'keep-alive', 90 | 'User-Agent': 'okhttp/3.12.12.200sp1', 91 | 'Accept-Encoding': 'gzip' 92 | } 93 | result = self.getGoodMess(count=count) # 秒杀列表存在商品url 94 | if result['meta']['code'] == 200: 95 | for each in result['detail']: 96 | url = f"https://msec.opposhop.cn/goods/v1/info/sku?skuId={each['skuid']}" 97 | self.sess.get(url=url,headers=headers) 98 | notify(f"正在浏览商品id:{each['skuid']}...") 99 | time.sleep(random.randint(7,10)) 100 | if flag == 1: # 来源天天领现金 101 | self.getCash(dic=dic) 102 | 103 | # 分享商品 104 | def shareGoods(self, flag,count,dic=None): 105 | url = 'https://msec.opposhop.cn/users/vi/creditsTask/pushTask' 106 | headers = { 107 | 'clientPackage': 'com.oppo.store', 108 | 'Host': 'msec.opposhop.cn', 109 | 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 110 | 'Content-Type': 'application/x-www-form-urlencoded', 111 | 'Connection': 'keep-alive', 112 | 'User-Agent': 'okhttp/3.12.12.200sp1', 113 | 'Accept-Encoding': 'gzip', 114 | } 115 | params = { 116 | 'marking': 'daily_sharegoods' 117 | } 118 | for i in range(count + random.randint(1,3)): 119 | self.sess.get(url=url,headers=headers,params=params) 120 | notify(f"正在执行第{i+1}次微信分享...") 121 | time.sleep(random.randint(7,10)) 122 | if flag == 1: #来源天天赚钱 123 | self.getCash(dic=dic) 124 | 125 | # 秒杀详情页获取商品数据 126 | def getGoodMess(self,count=10): 127 | taskUrl = f'https://msec.opposhop.cn/goods/v1/SeckillRound/goods/{random.randint(100,250)}' # 随机商品 128 | headers = { 129 | 'clientPackage': 'com.oppo.store', 130 | 'Host': 'msec.opposhop.cn', 131 | 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 132 | 'Content-Type': 'application/x-www-form-urlencoded', 133 | 'Connection': 'keep-alive', 134 | 'User-Agent': 'okhttp/3.12.12.200sp1', 135 | 'Accept-Encoding': 'gzip', 136 | } 137 | params = { 138 | 'pageSize':count + random.randint(1,3) 139 | } 140 | response = self.sess.get(url=taskUrl,headers=headers,params=params).json() 141 | if response['meta']['code'] == 200: 142 | return response 143 | else: 144 | notify(response) 145 | 146 | def getCash(self,dic): 147 | url = 'https://store.oppo.com/cn/oapi/omp-web/web/dailyCash/drawReward' 148 | headers = { 149 | 'Host': 'store.oppo.com', 150 | 'Connection': 'keep-alive', 151 | 'Origin': 'https://store.oppo.com', 152 | 'source_type': '501', 153 | 'clientPackage': 'com.oppo.store', 154 | 'Content-Type': 'application/x-www-form-urlencoded', 155 | 'Accept': 'application/json, text/plain, */*', 156 | 'Referer': 'https://store.oppo.com/cn/app/cashRedEnvelope?activityId=1&us=shouye&um=xuanfu&uc=xianjinhongbao', 157 | 'Accept-Encoding': 'gzip, deflate', 158 | 'Accept-Language': 'zh-CN,en-US;q=0.9' 159 | } 160 | data = { 161 | 'activityId':1, 162 | 'channel':3, 163 | 'channelRewardId':dic['id'] 164 | } 165 | response = self.sess.post(url=url,headers=headers,data=data).json() 166 | if response['code'] == 200: 167 | notify(f"[{dic['taskName']}]\t{response['data']['amount']}") 168 | elif response['code'] == 1000001: 169 | notify(f"[{dic['taskName']}]\t{response['errorMessage']}") 170 | 171 | # 天天领取现金 172 | def getDailyCashTask(self): 173 | url = 'https://store.oppo.com/cn/oapi/omp-web/web/dailyCash/queryActivityReward' 174 | headers = { 175 | 'Host': 'store.oppo.com', 176 | 'Connection': 'keep-alive', 177 | 'source_type': '501', 178 | 'clientPackage': 'com.oppo.store', 179 | 'Accept': 'application/json, text/plain, */*', 180 | 'Referer': 'https://store.oppo.com/cn/app/cashRedEnvelope?activityId=1&us=shouye&um=xuanfu&uc=xianjinhongbao', 181 | 'Accept-Encoding': 'gzip, deflate', 182 | 'Accept-Language': 'zh-CN,en-US;q=0.9' 183 | } 184 | params = { 185 | 'activityId':1 186 | } 187 | response = self.sess.get(url=url,headers=headers,params=params).json() 188 | if response['code'] == 200: 189 | self.taskRewardList = response['data']['taskRewardList'] 190 | self.timingRewardList = response['data']['timingRewardList'] 191 | return True 192 | elif response['code'] == 1000001: 193 | notify(response['errorMessage']) 194 | return False 195 | 196 | # 天天领现金浏览模板 197 | def viewCashTask(self,dic): 198 | url = 'https://store.oppo.com/cn/oapi/credits/web/dailyCash/reportDailyTask' 199 | param = { 200 | 'taskType':dic['taskType'], 201 | 'taskId':f"dailyCash{dic['id']}" 202 | } 203 | headers = { 204 | 'Host': 'store.oppo.com', 205 | 'Connection': 'keep-alive', 206 | 'source_type': '501', 207 | 'clientPackage': 'com.oppo.store', 208 | 'Cache-Control': 'no-cache', 209 | 'Accept': 'application/json, text/plain, */*', 210 | 'Referer': 'https://store.oppo.com/cn/app/cashRedEnvelope?activityId=1&us=shouye&um=xuanfu&uc=xianjinhongbao', 211 | 'Accept-Encoding': 'gzip, deflate', 212 | 'Accept-Language': 'zh-CN,en-US;q=0.9' 213 | } 214 | response = self.sess.get(url=url,headers=headers,params=param).json() 215 | if response['code'] == 200: 216 | notify(f"正在执行{dic['taskName']}...") 217 | time.sleep(random.randint(5,7)) 218 | self.getCash(dic=dic) 219 | else: 220 | notify(f"{dic['taskName']}执行失败") 221 | 222 | 223 | def runTaskRewardList(self): 224 | for each in self.taskRewardList: 225 | if each['taskName'] == '浏览商品': 226 | if each['taskStatus'] == 0: 227 | self.viewGoods(count=6,flag=1,dic=each) 228 | elif each['taskStatus'] == 1: 229 | self.getCash(dic=each) 230 | elif each['taskStatus'] == 2: 231 | notify(f"{each['taskName']}\t已领取") 232 | elif each['taskName'] == '浏览秒杀专区': 233 | if each['taskStatus'] == 0: 234 | self.viewCashTask(each) 235 | elif each['taskStatus'] == 1: 236 | self.getCash(dic=each) 237 | elif each['taskStatus'] == 2: 238 | notify(f"{each['taskName']}\t已领取") 239 | elif each['taskName'] == '分享商品': 240 | if each['taskStatus'] == 0: 241 | self.shareGoods(count=2,flag=1,dic=each) 242 | elif each['taskStatus'] == 1: 243 | self.getCash(dic=each) 244 | elif each['taskStatus'] == 2: 245 | notify(f"{each['taskName']}\t已领取") 246 | elif each['taskName'] == '观看直播': 247 | if each['taskStatus'] == 0: 248 | self.viewCashTask(each) 249 | elif each['taskStatus'] == 1: 250 | self.getCash(dic=each) 251 | elif each['taskStatus'] == 2: 252 | notify(f"{each['taskName']}\t已领取") 253 | elif each['taskName'] == '浏览签到页': 254 | if each['taskStatus'] == 0: 255 | self.viewCashTask(each) 256 | elif each['taskStatus'] == 1: 257 | self.getCash(dic=each) 258 | elif each['taskStatus'] == 2: 259 | notify(f"{each['taskName']}\t已领取") 260 | if each['taskName'] == '浏览领券中心': 261 | if each['taskStatus'] == 0: 262 | self.viewCashTask(each) 263 | elif each['taskStatus'] == 1: 264 | self.getCash(dic=each) 265 | elif each['taskStatus'] == 2: 266 | notify(f"{each['taskName']}\t已领取") 267 | elif each['taskName'] == '浏览realme商品': 268 | if each['taskStatus'] == 0: 269 | self.viewCashTask(each) 270 | elif each['taskStatus'] == 1: 271 | self.getCash(dic=each) 272 | elif each['taskStatus'] == 2: 273 | notify(f"{each['taskName']}\t已领取") 274 | elif each['taskName'] == '浏览指定商品': 275 | if each['taskStatus'] == 0: 276 | self.viewCashTask(each) 277 | elif each['taskStatus'] == 1: 278 | self.getCash(dic=each) 279 | elif each['taskStatus'] == 2: 280 | notify(f"{each['taskName']}\t已领取") 281 | elif each['taskName'] == '浏览一加商品': 282 | if each['taskStatus'] == 0: 283 | self.viewCashTask(each) 284 | elif each['taskStatus'] == 1: 285 | self.getCash(dic=each) 286 | elif each['taskStatus'] == 2: 287 | notify(f"{each['taskName']}\t已领取") 288 | elif each['taskName'] == '浏览OPPO商品': 289 | if each['taskStatus'] == 0: 290 | self.viewCashTask(each) 291 | elif each['taskStatus'] == 1: 292 | self.getCash(dic=each) 293 | elif each['taskStatus'] == 2: 294 | notify(f"{each['taskName']}\t已领取") 295 | 296 | # 执行欢太商城实例对象 297 | def start(self): 298 | self.sess.headers.update({ 299 | "User-Agent":self.dic['UA'] 300 | }) 301 | self.sess.cookies.update({ 302 | "Cookie": self.dic['CK'] 303 | }) 304 | if self.login() == True: 305 | if self.getDailyCashTask() == True: # 获取天天领现金数据,判断CK是否正确(登录可能成功,但无法跑任务) 306 | self.runTaskRewardList() # 运行天天领现金 307 | 308 | # 检测CK是否存在必备参数 309 | def checkHT(dic): 310 | CK = dic['CK'] 311 | if len(re.findall(r'source_type=.*?;',CK)) == 0: 312 | notify(f"{dic['user']}\tCK格式有误:可能缺少`source_type`字段") 313 | return False 314 | if len(re.findall(r'TOKENSID=.*?;',CK)) == 0: 315 | notify(f"{dic['user']}\tCK格式有误:可能缺少`TOKENSID`字段") 316 | return False 317 | if len(re.findall(r'app_param=.*?[;]?',CK)) == 0: 318 | notify(f"{dic['user']}\tCK格式有误:可能缺少`app_param`字段") 319 | return False 320 | return True 321 | 322 | # 兼容云函数 323 | def main_handler(event, context): 324 | global lists 325 | for each in lists: 326 | if each['CK']!='' and each['UA'] != '': 327 | if checkHT(each): 328 | dailyCash = DailyCash(each) 329 | for count in range(3): 330 | try: 331 | time.sleep(random.randint(2,5)) # 随机延时 332 | dailyCash.start() 333 | break 334 | except requests.exceptions.ConnectionError: 335 | notify(f"{dailyCash.dic['user']}\t请求失败,随机延迟后再次访问") 336 | time.sleep(random.randint(2,5)) 337 | continue 338 | else: 339 | notify(f"账号: {dailyCash.dic['user']}\n状态: 取消登录\n原因: 多次登录失败") 340 | break 341 | elif not all(each.values()): 342 | notify("账号:空账户\t状态:跳过") 343 | else: 344 | notify(f"账号: {each['user']}\n状态: 取消登录\n原因: json数据不齐全") 345 | notify('*' * 40 + '\n') 346 | if not os.path.basename(__file__).split('_')[-1][:-3] in notifyBlackList: 347 | send('欢太每日现金',allMess) 348 | 349 | if __name__ == '__main__': 350 | main_handler(None,None) 351 | -------------------------------------------------------------------------------- /Doc/0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mashiro2000/HeyTapTask/a4a3989b18b3cc2c203ae207c5de90a7fe9741a7/Doc/0.png -------------------------------------------------------------------------------- /Doc/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mashiro2000/HeyTapTask/a4a3989b18b3cc2c203ae207c5de90a7fe9741a7/Doc/1.png -------------------------------------------------------------------------------- /Doc/10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mashiro2000/HeyTapTask/a4a3989b18b3cc2c203ae207c5de90a7fe9741a7/Doc/10.png -------------------------------------------------------------------------------- /Doc/11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mashiro2000/HeyTapTask/a4a3989b18b3cc2c203ae207c5de90a7fe9741a7/Doc/11.png -------------------------------------------------------------------------------- /Doc/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mashiro2000/HeyTapTask/a4a3989b18b3cc2c203ae207c5de90a7fe9741a7/Doc/2.png -------------------------------------------------------------------------------- /Doc/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mashiro2000/HeyTapTask/a4a3989b18b3cc2c203ae207c5de90a7fe9741a7/Doc/3.png -------------------------------------------------------------------------------- /Doc/4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mashiro2000/HeyTapTask/a4a3989b18b3cc2c203ae207c5de90a7fe9741a7/Doc/4.png -------------------------------------------------------------------------------- /Doc/5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mashiro2000/HeyTapTask/a4a3989b18b3cc2c203ae207c5de90a7fe9741a7/Doc/5.png -------------------------------------------------------------------------------- /Doc/6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mashiro2000/HeyTapTask/a4a3989b18b3cc2c203ae207c5de90a7fe9741a7/Doc/6.png -------------------------------------------------------------------------------- /Doc/7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mashiro2000/HeyTapTask/a4a3989b18b3cc2c203ae207c5de90a7fe9741a7/Doc/7.png -------------------------------------------------------------------------------- /Doc/8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mashiro2000/HeyTapTask/a4a3989b18b3cc2c203ae207c5de90a7fe9741a7/Doc/8.png -------------------------------------------------------------------------------- /Doc/9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Mashiro2000/HeyTapTask/a4a3989b18b3cc2c203ae207c5de90a7fe9741a7/Doc/9.png -------------------------------------------------------------------------------- /Doc/README.md: -------------------------------------------------------------------------------- 1 | ### 准备:访问腾讯云函数 2 | [云函数直达](https://console.cloud.tencent.com/scf/list) 3 | 4 | --- 5 | 6 | ### 第零步:下载压缩包 7 | ![](https://z3.ax1x.com/2021/10/28/5qwnfg.png) 8 | 9 | --- 10 | 11 | ### 第一步:创建云函数 12 | ![](https://z3.ax1x.com/2021/10/28/5qwAmt.png) 13 | 14 | --- 15 | 16 | ### 第二步:选择模板 17 | ![](https://z3.ax1x.com/2021/10/28/5qwVTf.png) 18 | 19 | --- 20 | 21 | ### 第三步:云函数配置 22 | ![](https://z3.ax1x.com/2021/10/28/5qwE0P.png) 23 | 24 | --- 25 | 26 | ### 第四步:上传代码包 27 | ![](https://z3.ax1x.com/2021/10/28/5qwFOI.png) 28 | 29 | --- 30 | 31 | ### 第五步:配置执行超时 32 | ![](https://z3.ax1x.com/2021/10/28/5qwek8.png) 33 | 34 | --- 35 | 36 | ### 第六步:创建触发器 37 | ![](https://z3.ax1x.com/2021/10/28/5qwmtS.png) 38 | 39 | --- 40 | 41 | ### 第七步:配置触发器 42 | ![](https://z3.ax1x.com/2021/10/28/5qwKpQ.png) 43 | --- 44 | 45 | ### 第八步:创建多个触发器 46 | ![](https://z3.ax1x.com/2021/10/28/5qwMlj.png) 47 | 48 | --- 49 | 50 | ### 第九步:配置账号文件 51 | ![](https://z3.ax1x.com/2021/10/28/5qwQ6s.png) 52 | 53 | --- 54 | 55 | ### 第十步:配置推送文件(可选) 56 | ![](https://z3.ax1x.com/2021/10/28/5qwlXn.png) 57 | 58 | --- 59 | 60 | ### 第十一步:部署云函数 61 | ![](https://z3.ax1x.com/2021/10/28/5qw3mq.png) 62 | 63 | --- 64 | 65 | ### 其它说明 66 | | 定时任务名称 | Cron表达式 | 67 | | ----------------- | --------------- | 68 | | `TaskCenter` | `25 5,12 * * *` | 69 | | `ChockInEarly` | `35 0,19 * * *` | 70 | | `Double11` | `44 7,11 * * *` | 71 | | `BattleForRealMe` | `40 5,12 * * *` | 72 | | `DailyCash` | `30 5,12 * * *` | 73 | | `TimingCash` | `*/30 * * * *` | 74 | 75 | --- 76 | -------------------------------------------------------------------------------- /HT_account.py: -------------------------------------------------------------------------------- 1 | # !/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # @Time : 2021/9/29 4 | # @Author : MashiroF 5 | # @File : HT_account.py 6 | # @Software: PyCharm 7 | 8 | ## 账号管理样本 9 | # { 10 | # 'user':'', # 备注,必要 11 | # 'CK':'', # Cookie,必要(建议全部粘贴) 12 | # 'UA':'' # User-Agent,必要 13 | # }, 14 | 15 | ## 账号管理 16 | accounts = [ 17 | { 18 | 'user':'', 19 | 'CK':'', 20 | 'UA':'' 21 | }, 22 | { 23 | 'user':'', 24 | 'CK':'', 25 | 'UA':'' 26 | }, 27 | ] -------------------------------------------------------------------------------- /HT_config.py: -------------------------------------------------------------------------------- 1 | # !/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # @Time : 2021/9/12 4 | # @Author : MashiroF 5 | # @File : HT_config.py 6 | # @Software: PyCharm 7 | 8 | #################################### 以下配置可更改 ######################################### 9 | ## 云函数/青龙面板 环境变量优先级 > 配置文件 `HT_config` 变量优先级 10 | # 通知黑名单 11 | # 环境变量名:notifyBlack,多个以`&`隔开 12 | notifyBlackList = ['TimingCash',''] 13 | 14 | ########################################################################################### 15 | 16 | 17 | 18 | 19 | ####################################### 以下配置不要动 ####################################### 20 | # 导入系统内置包 21 | import os 22 | import sys 23 | import logging 24 | 25 | # 全局变量 26 | downFlag = False # 下载标志 27 | notifyBlack = None 28 | 29 | # 读取通知黑名单以及转盘抽奖环境变量 30 | if "Lottery" in os.environ: 31 | Lottery = os.environ["Lottery"] 32 | if "notifyBlack" in os.environ: 33 | notifyBlack = os.environ["notifyBlack"] 34 | 35 | # 日志模块 36 | logger = logging.getLogger(__name__) 37 | logger.setLevel(logging.INFO) 38 | logFormat = logging.Formatter("%(message)s") 39 | 40 | # 日志输出流 41 | stream = logging.StreamHandler() 42 | stream.setFormatter(logFormat) 43 | logger.addHandler(stream) 44 | 45 | # 第三方库 46 | try: 47 | import requests 48 | except ModuleNotFoundError: 49 | logger.info("缺少requests依赖!程序将尝试安装依赖!") 50 | os.system("pip3 install requests -i https://pypi.tuna.tsinghua.edu.cn/simple") 51 | os.execl(sys.executable, 'python3', __file__, *sys.argv) 52 | 53 | # 检测配置文件并下载函数 54 | # Ps:云函数可能不适用,该函数语法不够优雅,希望大佬给个优雅方案 55 | def checkFile(urlList): 56 | for url in urlList: 57 | fileName = url.split('/')[-1] 58 | fileUrl = f'https://ghproxy.com/{url}' 59 | try: 60 | if not os.path.exists(fileName): 61 | global downFlag 62 | downFlag = True 63 | logger.info(f"`{fileName}`不存在,尝试进行下载...") 64 | content = requests.get(url=fileUrl).content.decode('utf-8') 65 | with open(file=fileName, mode='w', encoding='utf-8') as fc: 66 | fc.write(content) 67 | except: 68 | logger.info(f'请手动下载配置文件`{fileName[:-3]}`到 {os.path.dirname(os.path.abspath(__file__))}') 69 | logger.info(f'下载地址:{fileUrl}\n') 70 | 71 | # 检测必备文件 72 | fileUrlList = [ 73 | 'https://raw.githubusercontent.com/Mashiro2000/HeyTapTask/main/sendNotify.py', 74 | 'https://raw.githubusercontent.com/Mashiro2000/HeyTapTask/main/HT_account.py' 75 | ] 76 | checkFile(fileUrlList) 77 | 78 | ## 提示文本 79 | if os.path.exists('/ql/config/auth.json'): 80 | logger.info(""" 81 | 鉴于青龙面板会破坏欢太CK格式,尝试修复无效,故建议使用配置文件 82 | 该项目不再支持青龙面板`环境变量`添加账号,请将CK转移至配置文件 83 | 青龙面板 -> 脚本管理 -> 搜索`HT_account`关键字 -> 编辑 84 | CK最简格式:'source_type=xxx;TOKENSID=xxx;app_param=xxx;' 85 | """) 86 | 87 | ########################################################################################### 88 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 happy_and_healthy 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /OnePlusJYStation.py: -------------------------------------------------------------------------------- 1 | # !/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # @Time : 2021/9/26 4 | # @Author : MashiroF 5 | # @File : OnePlusJYStation.py 6 | # @Software: PyCharm 7 | 8 | ''' 9 | cron: 16 5,12 * * * OnePlusJYStation.py 10 | new Env('一加加油站'); 11 | ''' 12 | 13 | import os 14 | import re 15 | import sys 16 | import time 17 | import random 18 | import requests 19 | 20 | # 配置文件 21 | try: 22 | from HT_config import downFlag,notifyBlackList,logger 23 | except Exception as error: 24 | logger.info(f'失败原因:{error}') 25 | sys.exit(0) 26 | 27 | # 判断是否发生下载行为 28 | if downFlag == True: 29 | logger.info('发生下载行为,应退出程序,编辑配置文件') 30 | sys.exit(0) 31 | 32 | # 配信文件 33 | try: 34 | from sendNotify import send 35 | except Exception as error: 36 | logger.info('推送文件有误') 37 | logger.info(f'失败原因:{error}') 38 | sys.exit(0) 39 | 40 | # 导入账户 41 | try: 42 | from HT_account import accounts 43 | lists = accounts 44 | except: 45 | lists = [] 46 | 47 | # 配信内容格式 48 | allMess = '' 49 | def notify(content=None): 50 | global allMess 51 | allMess = allMess + content + '\n' 52 | logger.info(content) 53 | 54 | # 日志录入时间 55 | notify(f"任务:一加加油站\n时间:{time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())}") 56 | 57 | class OnePlusJYStation: 58 | def __init__(self,dic): 59 | self.dic = dic 60 | self.sess = requests.session() 61 | 62 | # 登录验证 63 | def login(self): 64 | url = 'https://store.oppo.com/cn/oapi/users/web/member/check' 65 | headers = { 66 | 'Host': 'store.oppo.com', 67 | 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 68 | 'Content-Type': 'application/x-www-form-urlencoded', 69 | 'Connection': 'keep-alive', 70 | 'Accept-Language': 'zh-cn', 71 | 'Accept-Encoding': 'gzip, deflate, br', 72 | } 73 | response = self.sess.get(url=url,headers=headers).json() 74 | if response['code'] == 200: 75 | notify(f"{self.dic['user']}\t登录成功") 76 | return True 77 | else: 78 | notify(f"{self.dic['user']}\t登录失败") 79 | return False 80 | 81 | def receiveAward(self,dic): 82 | aid = 1473 83 | url = 'https://hd.oppo.com/task/award' 84 | headers = { 85 | 'Host': 'hd.oppo.com', 86 | 'Connection': 'keep-alive', 87 | 'Accept': '*/*', 88 | 'Origin': 'https://hd.oppo.com', 89 | 'X-Requested-With': 'XMLHttpRequest', 90 | 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', 91 | 'Referer': 'https://hd.oppo.com/act/m/2021/jifenzhuanpan/index.html?us=gerenzhongxin&um=hudongleyuan&uc=yingjifen', 92 | 'Accept-Encoding': 'gzip, deflate', 93 | 'Accept-Language': 'zh-CN,en-US;q=0.9' 94 | } 95 | data = { 96 | 'aid': aid, 97 | 't_index': dic['t_index'] 98 | } 99 | response = self.sess.post(url=url,headers=headers,data=data).json() 100 | if response['no'] == '200': 101 | notify(f"[{dic['title']}]\t{response['msg']}") 102 | else: 103 | notify(f"[{dic['title']}]\t{response['msg']}") 104 | time.sleep(random.randint(3,5)) 105 | 106 | def shareGoods(self,count=2,flag=None,dic=None): 107 | url = 'https://msec.opposhop.cn/users/vi/creditsTask/pushTask' 108 | headers = { 109 | 'clientPackage': 'com.oppo.store', 110 | 'Host': 'msec.opposhop.cn', 111 | 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 112 | 'Content-Type': 'application/x-www-form-urlencoded', 113 | 'Connection': 'keep-alive', 114 | 'User-Agent': 'okhttp/3.12.12.200sp1', 115 | 'Accept-Encoding': 'gzip', 116 | } 117 | params = { 118 | 'marking': 'daily_sharegoods' 119 | } 120 | for i in range(count + random.randint(1,3)): 121 | self.sess.get(url=url,headers=headers,params=params) 122 | notify(f"正在执行第{i+1}次微信分享...") 123 | time.sleep(random.randint(7,10)) 124 | if flag == 1: #来源积分大乱斗 125 | self.receiveAward(dic=dic) 126 | # 秒杀详情页获取商品数据 127 | def getGoodMess(self,count=10): 128 | taskUrl = f'https://msec.opposhop.cn/goods/v1/SeckillRound/goods/{random.randint(100,250)}' # 随机商品 129 | headers = { 130 | 'clientPackage': 'com.oppo.store', 131 | 'Host': 'msec.opposhop.cn', 132 | 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 133 | 'Content-Type': 'application/x-www-form-urlencoded', 134 | 'Connection': 'keep-alive', 135 | 'User-Agent': 'okhttp/3.12.12.200sp1', 136 | 'Accept-Encoding': 'gzip', 137 | } 138 | params = { 139 | 'pageSize':count + random.randint(1,3) 140 | } 141 | response = self.sess.get(url=taskUrl,headers=headers,params=params).json() 142 | if response['meta']['code'] == 200: 143 | return response 144 | 145 | def viewGoods(self, count,dic=None): 146 | headers = { 147 | 'clientPackage': 'com.oppo.store', 148 | 'Host': 'msec.opposhop.cn', 149 | 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 150 | 'Content-Type': 'application/x-www-form-urlencoded', 151 | 'Connection': 'keep-alive', 152 | 'User-Agent': 'okhttp/3.12.12.200sp1', 153 | 'Accept-Encoding': 'gzip' 154 | } 155 | result = self.getGoodMess(count=count) # 秒杀列表存在商品url 156 | if result['meta']['code'] == 200: 157 | for each in result['detail']: 158 | url = f"https://msec.opposhop.cn/goods/v1/info/sku?skuId={each['skuid']}" 159 | self.sess.get(url=url,headers=headers) 160 | notify(f"正在浏览商品id:{each['skuid']}...") 161 | time.sleep(random.randint(7,10)) 162 | if dic: 163 | self.receiveAward(dic) 164 | 165 | # 直播,宠粉,浏览商品 166 | def runViewTask(self,dic=None): 167 | aid = 1473 168 | url = 'https://hd.oppo.com/task/finish' 169 | headers = { 170 | 'Host': 'hd.oppo.com', 171 | 'Connection': 'keep-alive', 172 | 'Accept': '*/*', 173 | 'Origin': 'https://hd.oppo.com', 174 | 'X-Requested-With': 'XMLHttpRequest', 175 | 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', 176 | 'Referer': 'https://hd.oppo.com/act/m/2021/2021/realmejifendalu/index.html', 177 | 'Accept-Encoding': 'gzip, deflate', 178 | 'Accept-Language': 'zh-CN,en-US;q=0.9' 179 | } 180 | data = { 181 | 'aid': aid, 182 | 't_index': dic['t_index'] 183 | } 184 | response = self.sess.post(url=url,headers=headers,data=data).json() 185 | if response['no'] == '200': 186 | notify(f"[{dic['title']}]\t{response['msg']}") 187 | self.receiveAward(dic) 188 | else: 189 | notify(f"[{dic['title']}]\t{response['msg']}") 190 | time.sleep(random.randint(3,5)) 191 | 192 | def getBattleList(self): 193 | aid = 1473 # 抓包结果为固定值:1473 194 | url = 'https://hd.oppo.com/task/list' 195 | headers = { 196 | 'Host':'hd.oppo.com', 197 | 'Connection': 'keep-alive', 198 | 'Referer':'https://hd.oppo.com/act/m/2021/2021/realmejifendalu/index.html', 199 | 'Accept-Encoding': 'gzip, deflate', 200 | 'Accept-Language': 'zh-CN,en-US;q=0.9', 201 | } 202 | params = { 203 | 'aid':aid 204 | } 205 | response = self.sess.get(url=url,headers=headers,params=params).json() 206 | if response['no'] == '200': 207 | self.taskData = response['data'] 208 | return True 209 | else: 210 | notify(f"{response['msg']}") 211 | return False 212 | time.sleep(random.randint(1,3)) 213 | 214 | def runBattleTask(self): 215 | for each in self.taskData: 216 | if each['title'] == '每日签到': 217 | if each['t_status'] == 0: 218 | self.runViewTask(dic=each) 219 | elif each['t_status'] == 1: 220 | self.receiveAward(each) 221 | elif each['t_status'] == 2: 222 | notify(f"[{each['title']}]\t领取成功") 223 | elif each['title'] == '浏览一加11.11会场': 224 | if each['t_status'] == 0: 225 | self.runViewTask(dic=each) 226 | elif each['t_status'] == 1: 227 | self.receiveAward(each) 228 | elif each['t_status'] == 2: 229 | notify(f"[{each['title']}]\t任务完成") 230 | elif each['title'] == '浏览一加商品': 231 | if each['t_status'] == 0: 232 | self.viewGoods(count=6,dic=each) 233 | elif each['t_status'] == 1: 234 | self.receiveAward(each) 235 | elif each['t_status'] == 2: 236 | notify(f"[{each['title']}]\t任务完成") 237 | 238 | # 获取积分数量(只找到这个,找不到昨天积分数据) 239 | def getIntegral(self): 240 | url = 'https://store.oppo.com/cn/oapi/credits/web/credits/show' 241 | headers = { 242 | 'Host': 'store.oppo.com', 243 | 'Connection': 'keep-alive', 244 | 'source_type': '501', 245 | 'clientPackage': 'com.oppo.store', 246 | 'Accept': 'application/json, text/plain, */*', 247 | 'Accept-Encoding': 'gzip, deflate', 248 | 'Accept-Language': 'zh-CN,en-US;q=0.9', 249 | 'X-Requested-With': 'com.oppo.store', 250 | 'Referer': 'https://store.oppo.com/cn/app/taskCenter/index?us=gerenzhongxin&um=hudongleyuan&uc=renwuzhongxin' 251 | } 252 | response = self.sess.get(url=url,headers=headers).json() 253 | if response['code'] == 200: 254 | return f"{self.dic['user']}\t总积分:{response['data']['userCredits']}" 255 | else: 256 | return f"{self.dic['user']}\t错误原因:{response}" 257 | 258 | # 执行欢太商城实例对象 259 | def start(self): 260 | self.sess.headers.update({ 261 | "User-Agent":self.dic['UA'] 262 | }) 263 | self.sess.cookies.update({ 264 | "Cookie": self.dic['CK'] 265 | }) 266 | if self.login() == True: 267 | if self.getBattleList() == True: # 获取任务中心数据,判断CK是否正确(登录可能成功,但无法跑任务) 268 | self.runBattleTask() # 运行任务中心 269 | notify(self.getIntegral()) 270 | 271 | # 检测CK是否存在必备参数 272 | def checkHT(dic): 273 | CK = dic['CK'] 274 | if len(re.findall(r'source_type=.*?;',CK)) == 0: 275 | notify(f"{dic['user']}\tCK格式有误:可能缺少`source_type`字段") 276 | return False 277 | if len(re.findall(r'TOKENSID=.*?;',CK)) == 0: 278 | notify(f"{dic['user']}\tCK格式有误:可能缺少`TOKENSID`字段") 279 | return False 280 | if len(re.findall(r'app_param=.*?[;]?',CK)) == 0: 281 | notify(f"{dic['user']}\tCK格式有误:可能缺少`app_param`字段") 282 | return False 283 | return True 284 | 285 | # 兼容云函数 286 | def main_handler(event, context): 287 | global lists 288 | for each in lists: 289 | if each['CK']!='' and each['UA'] != '': 290 | if checkHT(each): 291 | onePlusJYStation = OnePlusJYStation(each) 292 | for count in range(3): 293 | try: 294 | time.sleep(random.randint(2,5)) # 随机延时 295 | onePlusJYStation.start() 296 | break 297 | except requests.exceptions.ConnectionError: 298 | notify(f"{onePlusJYStation.dic['user']}\t请求失败,随机延迟后再次访问") 299 | time.sleep(random.randint(2,5)) 300 | continue 301 | else: 302 | notify(f"账号: {onePlusJYStation.dic['user']}\n状态: 取消登录\n原因: 多次登录失败") 303 | break 304 | elif not all(each.values()): 305 | notify("账号:空账户\t状态:跳过") 306 | else: 307 | notify(f"账号: {each['user']}\n状态: 取消登录\n原因: json数据不齐全") 308 | notify('*' * 40 + '\n') 309 | if not os.path.basename(__file__).split('_')[-1][:-3] in notifyBlackList: 310 | send('一加加油站',allMess) 311 | 312 | if __name__ == '__main__': 313 | main_handler(None,None) 314 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | #

HeyTapTask

2 |

早睡打卡,早起打卡需要验证,已下架脚本(欢太力度不大且验证码复杂,不再维护)

3 |

建议各位本地运行,由于本项目并不成熟,常变更拉库命令,请及时更新

4 |

喜欢这个项目?可以在右上角给颗⭐!你的支持是我最大的动力😎!

5 | 6 | ## 免责声明 7 | - 本仓库发布的HeyTapTask项目中涉及的任何脚本,仅用于测试和学习研究,禁止用于商业用途,不能保证其合法性,准确性,完整性和有效性,请根据情况自行判断. 8 | 9 | - 所有使用者在使用HeyTapTask项目的任何部分时,需先遵守法律法规。对于一切使用不当所造成的后果,需自行承担.对任何脚本问题概不负责,包括但不限于由任何脚本错误导致的任何损失或损害. 10 | 11 | - 如果任何单位或个人认为该项目可能涉嫌侵犯其权利,则应及时通知并提供身份证明,所有权证明,我们将在收到认证文件后删除相关文件. 12 | 13 | - 任何以任何方式查看此项目的人或直接或间接使用该HeyTapTask项目的任何脚本的使用者都应仔细阅读此声明。本人保留随时更改或补充此免责声明的权利。一旦使用并复制了任何相关脚本或HeyTapTask项目的规则,则视为您已接受此免责声明. 14 | 15 | 您必须在下载后的24小时内从计算机或手机中完全删除以上内容. 16 | 17 | > 您使用或者复制了本仓库且本人制作的任何脚本,则视为`已接受`此声明,请仔细阅读 18 | 19 | ## 环境 20 | 21 | [Python3](https://www.python.org/) >= 3.6 22 | 23 | ## 已实现功能 24 | * [x] 每日签到 25 | * [x] 每日浏览商品任务 26 | * [x] 每日分享商品任务 27 | * [x] ~~每日点推送任务~~(已下架) 28 | * [x] 赚积分活动 29 | * [x] ~~天天积分翻倍~~(暂时移除) 30 | * [x] 天天领现金任务列表 31 | * [x] 天天领现金定时红包 32 | * [x] 早睡打卡 33 | * [x] 集卡赢套票 34 | * [x] 积分大作战(realme) 35 | * [x] 积分大作战(HeyTap) 36 | * [x] 配信功能 由@Oreomeow开发 37 | * [x] OPPO社区早起打卡&OPPO社区签到(国内服务器) 38 | 39 | ## 文件说明 40 | ```text 41 | │ TaskCenter.py # 欢太商城任务中心 42 | │ TimingCash.py # 欢太定时红包 43 | │ DailyCash.py # 每日现金任务 44 | │ ChockInEarly.py # 欢太商城,早睡报名或打卡 45 | │ BattleForHeyTap.py # 积分大作战(欢太) 46 | │ BattleForRealMe.py # 积分大作战(真我) 47 | │ CollectionCard.py # 集卡赢套件(已下架) 48 | │ Community.py # OPPO社区(签到&早起打卡) 49 | │ HT_account.py # 欢太CK文件 50 | │ HT_config.py # 欢太配置文件 51 | │ sendNotify.py # 欢太配信文件(强制下载本项目配信文件,配信方式较全) 52 | │ README.md # 说明文档 53 | ``` 54 | 55 | #### 一、Linux部署 56 | ```bash 57 | yum install python3 -y 58 | 59 | yum install git -y 60 | 61 | git clone https://ghproxy.com/https://github.com/Mashiro2000/HeyTapTask.git # 国内git较慢,故添加代理前缀 62 | 63 | cd HeyTapTask 64 | 65 | vi HT_account.py 66 | ``` 67 | 68 | #### 二、青龙面板拉库指令 69 | ```text 70 | 第一次拉取 71 | ql repo https://github.com/Mashiro2000/HeyTapTask.git "" "Backup|index|HT.*|sendNotify" "HT.*|sendNotify" 72 | 73 | 拉取完成后,修改拉库指令,确保HT_account.py不被覆盖,更改拉库命令,命令如下 74 | ql repo https://github.com/Mashiro2000/HeyTapTask.git "" "Backup|index|HT.*|sendNotify" "HT_config|sendNotify" 75 | ``` 76 | 77 | #### 三、云函数 78 | > 云函数教程:[点击直达](https://github.com/Mashiro2000/HeyTapTask/blob/main/Doc/README.md) 79 | > > 特别感谢@FgywAwut、@11yiyang提供的方案 80 | 81 | ##### 变量值 82 | - 测试表明欢太所需CK为: `source_type`、`TOKENSID`、`app_param`,顺序不可乱 83 | - 不再支持青龙面板`环境变量`添加账号的方案,请尽快将CK转移至配置文件 84 | - 原因:欢太变量采用json字符串,但青龙会将`HUAWEI P50`解析为`HUAWEIP50` 85 | - CK和UA中的特定字符会被错误的解析,为了长远发展,请使用配置文件 86 | 87 | ##### 编辑配置文件(本地/青龙/云函数) 88 | ```text 89 | { 90 | 'user':'', # 自定义备注(为了区分账号,包括未登录状态下) 91 | 'CK':'source_type=xxx;TOKENSID=TOKEN_xxxx;app_param=xxxx', # 用户环境变量 Cookie,建议全部粘贴,且顺序不可乱 92 | 'UA':'UA' # 用户环境变量 User-Agent 93 | } 94 | ``` 95 | 96 | ##### 变量获取 97 | - CK和UA信息需自行抓包,欢太商城 -> 我的 -> 任务中心 -> 领券中心 98 | - 抓包地址:`https://store.oppo.com/cn/oapi/users/web/checkPeople/isNewPeople` 99 | 100 | - 集卡活动提示信息更改,缓存已刷新? 101 | - 欢太商城 -> 首页 -> 右上角集卡(访问进去) 102 | 103 | #### 其他帮助 104 | - Q:NameError: name '`xxxxxx`' is not defined 105 | - A:可能是因为CK的格式存在错误 106 | 107 | - Q:环境变量如何使用? 108 | - A:参考格式:`export notifyBlack="TimingCash&DailyCash"` 109 | 110 | 111 | #### 更新日志 112 |
113 | 114 | 115 | > 证明该项目仍然存活 116 | 117 | 2021-9-29 118 | 重构代码,确保后续更新不在涉及`HT_account.py`文件,新增环境变量`notifyBlack` 119 | 120 |
121 | -------------------------------------------------------------------------------- /TaskCenter.py: -------------------------------------------------------------------------------- 1 | # !/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # @Time : 2021/9/12 4 | # @Author : MashiroF 5 | # @File : TaskCenter.py 6 | # @Software: PyCharm 7 | 8 | ''' 9 | cron: 25 5,12 * * * TaskCenter.py 10 | new Env('欢太任务中心'); 11 | ''' 12 | 13 | import os 14 | import re 15 | import sys 16 | import time 17 | import random 18 | import requests 19 | 20 | # 配置文件 21 | try: 22 | from HT_config import downFlag,notifyBlackList,logger 23 | except Exception as error: 24 | logger.info(f'失败原因:{error}') 25 | sys.exit(0) 26 | 27 | # 判断是否发生下载行为 28 | if downFlag == True: 29 | logger.info('发生下载行为,应退出程序,编辑配置文件') 30 | sys.exit(0) 31 | 32 | # 配信文件 33 | try: 34 | from sendNotify import send 35 | except Exception as error: 36 | logger.info('推送文件有误') 37 | logger.info(f'失败原因:{error}') 38 | sys.exit(0) 39 | 40 | # 导入账户 41 | try: 42 | from HT_account import accounts 43 | lists = accounts 44 | except Exception as error: 45 | logger.info(f'失败原因:{error}') 46 | lists = [] 47 | 48 | # 配信内容格式 49 | allMess = '' 50 | def notify(content=None): 51 | global allMess 52 | allMess = allMess + content + '\n' 53 | logger.info(content) 54 | 55 | # 日志录入时间 56 | notify(f"任务:欢太任务中心\n时间:{time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())}") 57 | 58 | # 欢太任务中心类 59 | class TaskCenter: 60 | def __init__(self,dic): 61 | self.dic = dic 62 | self.sess = requests.session() 63 | 64 | # 登录验证 65 | def login(self): 66 | url = 'https://store.oppo.com/cn/oapi/users/web/member/check' 67 | headers = { 68 | 'Host': 'store.oppo.com', 69 | 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 70 | 'Content-Type': 'application/x-www-form-urlencoded', 71 | 'Connection': 'keep-alive', 72 | 'Accept-Language': 'zh-cn', 73 | 'Accept-Encoding': 'gzip, deflate, br', 74 | } 75 | response = self.sess.get(url=url,headers=headers).json() 76 | if response['code'] == 200: 77 | notify(f"{self.dic['user']}\t登录成功") 78 | return True 79 | else: 80 | notify(f"{self.dic['user']}\t登录失败") 81 | return False 82 | 83 | # 任务中心 84 | # 位置:我的 -> 任务中心 85 | # 函数作用:获取任务数据以及判断CK是否正确 86 | def getTaskList(self): 87 | url = 'https://store.oppo.com/cn/oapi/credits/web/credits/show' 88 | headers = { 89 | 'Host': 'store.oppo.com', 90 | 'Connection': 'keep-alive', 91 | 'source_type': '501', 92 | 'clientPackage': 'com.oppo.store', 93 | 'Accept': 'application/json, text/plain, */*', 94 | 'Accept-Encoding': 'gzip, deflate', 95 | 'Accept-Language': 'zh-CN,en-US;q=0.9', 96 | 'X-Requested-With': 'com.oppo.store', 97 | 'Referer': 'https://store.oppo.com/cn/app/taskCenter/index?us=gerenzhongxin&um=hudongleyuan&uc=renwuzhongxin' 98 | } 99 | response = self.sess.get(url=url,headers=headers).json() 100 | if response['code'] == 200: 101 | self.taskData = response['data'] 102 | return True 103 | else: 104 | notify(f"{self.dic['user']}\t失败原因:{response['errorMessage']}") 105 | return False 106 | 107 | # 每日签到 108 | # 位置: APP → 我的 → 签到 109 | def signIn(self): 110 | signInData = self.taskData['userReportInfoForm'] # 签到数据源 111 | if signInData['status'] == 0 : 112 | for each in signInData['gifts']: 113 | if each['today'] == True: 114 | url = 'https://store.oppo.com/cn/oapi/credits/web/report/immediately' 115 | headers = { 116 | 'Host': 'store.oppo.com', 117 | 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 118 | 'Content-Type': 'application/x-www-form-urlencoded', 119 | 'Connection': 'keep-alive', 120 | 'Accept-Language': 'zh-CN,en-US;q=0.9', 121 | 'Accept-Encoding': 'gzip, deflate, br', 122 | 'referer':'https://store.oppo.com/cn/app/taskCenter/index' 123 | } 124 | data = { 125 | 'amount': each['credits'] 126 | } 127 | while True: 128 | response = self.sess.post(url=url, headers=headers,data=data).json() 129 | if response['code'] == 200: 130 | notify(f"{self.dic['user']}\t签到结果:{response['data']['message']}") 131 | break 132 | elif response['code'] == 1000005: 133 | data = { 134 | 'amount': each['credits'], 135 | 'type': each['type'], 136 | 'gift': each['gift'] 137 | } 138 | else: 139 | notify(f"{self.dic['user']}\t签到结果:{response['errorMessage']}") 140 | break 141 | elif signInData['status'] == 1: 142 | notify(f"{self.dic['user']}\t今日已签到") 143 | else: 144 | notify(f"{self.dic['user']}\t未知错误") 145 | 146 | # 秒杀详情页获取商品数据 147 | def getGoodMess(self,count=10): 148 | taskUrl = f'https://msec.opposhop.cn/goods/v1/SeckillRound/goods/{random.randint(100,250)}' # 随机商品 149 | headers = { 150 | 'clientPackage': 'com.oppo.store', 151 | 'Host': 'msec.opposhop.cn', 152 | 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 153 | 'Content-Type': 'application/x-www-form-urlencoded', 154 | 'Connection': 'keep-alive', 155 | 'User-Agent': 'okhttp/3.12.12.200sp1', 156 | 'Accept-Encoding': 'gzip', 157 | } 158 | params = { 159 | 'pageSize':count + random.randint(1,3) 160 | } 161 | response = self.sess.get(url=taskUrl,headers=headers,params=params).json() 162 | if response['meta']['code'] == 200: 163 | return response 164 | 165 | # 整合每日浏览、分享、推送数据 166 | def dailyTask(self): 167 | if self.taskData['everydayList'] != None: 168 | for eachTask in self.taskData['everydayList']: # 每日任务数据源 169 | if eachTask['marking'] == 'daily_viewgoods': 170 | self.viewData = eachTask 171 | elif eachTask['marking'] == 'daily_sharegoods': 172 | self.shareData = eachTask 173 | # elif eachTask['marking'] == 'daily_viewpush': 174 | # self.pushData = eachTask 175 | return True 176 | else: 177 | notify(f"[每日任务]\t任务数据获取失败,跳过") 178 | return False 179 | 180 | # 浏览任务 181 | def runViewTask(self): 182 | if self.viewData['completeStatus'] == 0: 183 | self.viewGoods(count=self.viewData['times'] - self.viewData['readCount'], flag=1) 184 | elif self.viewData['completeStatus'] == 1: 185 | self.cashingCredits(self.viewData['name'],self.viewData['marking'], self.viewData['type'],self.viewData['credits']) 186 | elif self.viewData['completeStatus'] == 2: 187 | notify(f"[{self.viewData['name']}]\t已完成,奖励已领取") 188 | time.sleep(random.randint(3,5)) 189 | 190 | 191 | # 浏览商品 192 | def viewGoods(self, count,flag,dic=None): 193 | headers = { 194 | 'clientPackage': 'com.oppo.store', 195 | 'Host': 'msec.opposhop.cn', 196 | 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 197 | 'Content-Type': 'application/x-www-form-urlencoded', 198 | 'Connection': 'keep-alive', 199 | 'User-Agent': 'okhttp/3.12.12.200sp1', 200 | 'Accept-Encoding': 'gzip' 201 | } 202 | result = self.getGoodMess(count=count) # 秒杀列表存在商品url 203 | if result['meta']['code'] == 200: 204 | for each in result['detail']: 205 | url = f"https://msec.opposhop.cn/goods/v1/info/sku?skuId={each['skuid']}" 206 | self.sess.get(url=url,headers=headers) 207 | notify(f"正在浏览商品id:{each['skuid']}...") 208 | time.sleep(random.randint(7,10)) 209 | if flag == 1: # 来源任务中心的浏览任务 210 | self.cashingCredits(self.viewData['name'], self.viewData['marking'], self.viewData['type'],self.viewData['credits']) 211 | elif flag == 2: # 来源赚积分的浏览任务 212 | self.receiveAward(dic) 213 | 214 | # 分享任务 215 | def runShareTask(self): 216 | if self.shareData['completeStatus'] == 0: 217 | self.shareGoods(flag=1,count=self.shareData['times'] - self.shareData['readCount']) 218 | elif self.shareData['completeStatus'] == 1: 219 | self.cashingCredits(self.shareData['name'],self.shareData['marking'], self.shareData['type'],self.shareData['credits']) 220 | elif self.shareData['completeStatus'] == 2: 221 | notify(f"[{self.shareData['name']}]\t已完成,奖励已领取") 222 | time.sleep(random.randint(1,3)) 223 | 224 | # 分享商品 225 | def shareGoods(self, flag,count): 226 | url = 'https://msec.opposhop.cn/users/vi/creditsTask/pushTask' 227 | headers = { 228 | 'clientPackage': 'com.oppo.store', 229 | 'Host': 'msec.opposhop.cn', 230 | 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 231 | 'Content-Type': 'application/x-www-form-urlencoded', 232 | 'Connection': 'keep-alive', 233 | 'User-Agent': 'okhttp/3.12.12.200sp1', 234 | 'Accept-Encoding': 'gzip', 235 | } 236 | params = { 237 | 'marking': 'daily_sharegoods' 238 | } 239 | for i in range(count + random.randint(1,3)): 240 | self.sess.get(url=url,headers=headers,params=params) 241 | notify(f"正在执行第{i+1}次微信分享...") 242 | time.sleep(random.randint(7,10)) 243 | if flag == 1: # 来源任务中心 244 | self.cashingCredits(self.shareData['name'],self.shareData['marking'], self.shareData['type'],self.shareData['credits']) 245 | 246 | 247 | # # 浏览推送任务 248 | # def runViewPush(self): 249 | # if self.pushData['completeStatus'] == 0: 250 | # self.viewPush(self.pushData['times'] - self.pushData['readCount']) 251 | # elif self.pushData['completeStatus'] == 1: 252 | # self.cashingCredits(self.pushData['name'], self.pushData['marking'], self.pushData['type'],self.pushData['credits']) 253 | # elif self.pushData['completeStatus'] == 2: 254 | # notify(f"[{self.pushData['name']}]\t已完成,奖励已领取") 255 | # time.sleep(random.randint(1,3)) 256 | 257 | # # 点击推送 258 | # def viewPush(self,count): 259 | # url = 'https://msec.opposhop.cn/users/vi/creditsTask/pushTask' 260 | # headers = { 261 | # 'clientPackage': 'com.oppo.store', 262 | # 'Host': 'msec.opposhop.cn', 263 | # 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 264 | # 'Content-Type': 'application/x-www-form-urlencoded', 265 | # 'Connection': 'keep-alive', 266 | # 'User-Agent': 'okhttp/3.12.12.200sp1', 267 | # 'Accept-Encoding': 'gzip', 268 | # } 269 | # params = { 270 | # 'marking': 'daily_viewpush' 271 | # } 272 | # for i in range(count + random.randint(1,3)): 273 | # self.sess.get(url=url,headers=headers,params=params) 274 | # notify(f"正在点击第{i+1}次信息推送...") 275 | # time.sleep(random.randint(7,10)) 276 | # self.cashingCredits(self.pushData['name'], self.pushData['marking'], self.pushData['type'],self.pushData['credits']) 277 | 278 | # 领取奖励 279 | def cashingCredits(self,name,marking,type,amount): 280 | url = 'https://store.oppo.com/cn/oapi/credits/web/credits/cashingCredits' 281 | headers = { 282 | 'Host': 'store.oppo.com', 283 | 'Connection': 'keep-alive', 284 | 'Origin': 'https://store.oppo.com', 285 | 'clientPackage': 'com.oppo.store', 286 | 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 287 | 'Content-Type': 'application/x-www-form-urlencoded', 288 | 'Accept-Encoding': 'gzip, deflate', 289 | 'Accept-Language': 'zh-CN,en-US;q=0.9', 290 | 'Referer':'https://store.oppo.com/cn/app/taskCenter/index?us=gerenzhongxin&um=hudongleyuan&uc=renwuzhongxin' 291 | } 292 | data = { 293 | 'marking':marking, 294 | 'type':str(type), 295 | 'amount':str(amount) 296 | } 297 | response = self.sess.post(url=url,headers=headers,data=data).json() 298 | if response['code'] == 200: 299 | notify(f'{name}\t已领取奖励') 300 | else: 301 | notify(f'{name}\t领取失败') 302 | time.sleep(random.randint(3,5)) 303 | 304 | # 赚积分(抽奖)任务 305 | def runEarnPoint(self): 306 | aid = 1418 # 抓包结果为固定值:1418 307 | url = 'https://hd.oppo.com/task/list' 308 | headers = { 309 | 'Host':'hd.oppo.com', 310 | 'Connection': 'keep-alive', 311 | 'Referer':'https://hd.oppo.com/act/m/2021/jifenzhuanpan/index.html?us=gerenzhongxin&um=hudongleyuan&uc=yingjifen', 312 | 'Accept-Encoding': 'gzip, deflate', 313 | 'Accept-Language': 'zh-CN,en-US;q=0.9', 314 | } 315 | params = { 316 | 'aid':aid 317 | } 318 | response = self.sess.get(url=url,headers=headers,params=params).json() 319 | if response['no'] == '200': 320 | for each in response['data']: 321 | if each['title'] == '每日签到': 322 | if each['t_status'] == 0: 323 | self.clockIn(each) 324 | elif each['t_status'] == 1: 325 | self.receiveAward(each) 326 | elif each['t_status'] == 2: 327 | notify(f"[{each['title']}]\t任务完成") 328 | elif each['title'] == '浏览商详': 329 | if each['t_status'] == 0: 330 | self.viewGoods(count=6,flag=2,dic=each) 331 | elif each['t_status'] == 1: 332 | self.receiveAward(each) 333 | elif each['t_status'] == 2: 334 | notify(f"[{each['title']}]\t任务完成") 335 | time.sleep(random.randint(3,5)) 336 | 337 | # 赚积分 -> 每日打卡 338 | def clockIn(self,dic): 339 | aid = 1418 340 | url = 'https://hd.oppo.com/task/finish' 341 | headers = { 342 | 'Host': 'hd.oppo.com', 343 | 'Connection': 'keep-alive', 344 | 'Accept': '*/*', 345 | 'Origin': 'https://hd.oppo.com', 346 | 'X-Requested-With': 'XMLHttpRequest', 347 | 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', 348 | 'Referer': 'https://hd.oppo.com/act/m/2021/2021/realmejifendalu/index.html', 349 | 'Accept-Encoding': 'gzip, deflate', 350 | 'Accept-Language': 'zh-CN,en-US;q=0.9' 351 | } 352 | data = { 353 | 'aid': aid, 354 | 't_index': dic['t_index'] 355 | } 356 | response = self.sess.post(url=url,headers=headers,data=data).json() 357 | if response['no'] == '200': 358 | notify(f"[{dic['title']}]\t{response['msg']}") 359 | self.receiveAward(dic) 360 | else: 361 | notify(f"[{dic['title']}]\t{response['msg']}") 362 | time.sleep(random.randint(3,5)) 363 | 364 | # 领取奖励 365 | def receiveAward(self,dic): 366 | aid = 1418 367 | url = 'https://hd.oppo.com/task/award' 368 | headers = { 369 | 'Host': 'hd.oppo.com', 370 | 'Connection': 'keep-alive', 371 | 'Accept': '*/*', 372 | 'Origin': 'https://hd.oppo.com', 373 | 'X-Requested-With': 'XMLHttpRequest', 374 | 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', 375 | 'Referer': 'https://hd.oppo.com/act/m/2021/jifenzhuanpan/index.html?us=gerenzhongxin&um=hudongleyuan&uc=yingjifen', 376 | 'Accept-Encoding': 'gzip, deflate', 377 | 'Accept-Language': 'zh-CN,en-US;q=0.9' 378 | } 379 | data = { 380 | 'aid': aid, 381 | 't_index': dic['t_index'] 382 | } 383 | response = self.sess.post(url=url,headers=headers,data=data).json() 384 | if response['no'] == '200': 385 | notify(f"[{dic['title']}]\t{response['msg']}") 386 | else: 387 | notify(f"[{dic['title']}]\t{response['msg']}") 388 | time.sleep(random.randint(3,5)) 389 | 390 | # 跑任务中心 391 | # 位置:我的 -> 任务中心 392 | def runTaskCenter(self): 393 | self.signIn() # 签到打卡 394 | if self.dailyTask() == True: 395 | self.runViewTask() # 浏览任务 396 | self.runShareTask() # 分享任务 397 | self.runEarnPoint() # 赚积分 398 | # self.runViewPush() # 浏览推送任务(已下架) 399 | 400 | # 获取积分数量(只找到这个,找不到昨天积分数据) 401 | def getIntegral(self): 402 | url = 'https://store.oppo.com/cn/oapi/credits/web/credits/show' 403 | headers = { 404 | 'Host': 'store.oppo.com', 405 | 'Connection': 'keep-alive', 406 | 'source_type': '501', 407 | 'clientPackage': 'com.oppo.store', 408 | 'Accept': 'application/json, text/plain, */*', 409 | 'Accept-Encoding': 'gzip, deflate', 410 | 'Accept-Language': 'zh-CN,en-US;q=0.9', 411 | 'X-Requested-With': 'com.oppo.store', 412 | 'Referer': 'https://store.oppo.com/cn/app/taskCenter/index?us=gerenzhongxin&um=hudongleyuan&uc=renwuzhongxin' 413 | } 414 | response = self.sess.get(url=url,headers=headers).json() 415 | if response['code'] == 200: 416 | return f"{self.dic['user']}\t总积分:{response['data']['userCredits']}" 417 | else: 418 | return f"{self.dic['user']}\t错误原因:{response}" 419 | 420 | # 执行欢太商城实例对象 421 | def start(self): 422 | self.sess.headers.update({ 423 | "User-Agent":self.dic['UA'] 424 | }) 425 | self.sess.cookies.update({ 426 | "Cookie": self.dic['CK'] 427 | }) 428 | if self.login() == True: 429 | if self.getTaskList() == True: # 获取任务中心数据,判断CK是否正确(登录可能成功,但无法跑任务) 430 | self.runTaskCenter() # 运行任务中心 431 | notify(self.getIntegral()) 432 | 433 | # 检测CK是否存在必备参数 434 | def checkHT(dic): 435 | CK = dic['CK'] 436 | if len(re.findall(r'source_type=.*?;',CK)) == 0: 437 | notify(f"{dic['user']}\tCK格式有误:可能缺少`source_type`字段") 438 | return False 439 | if len(re.findall(r'TOKENSID=.*?;',CK)) == 0: 440 | notify(f"{dic['user']}\tCK格式有误:可能缺少`TOKENSID`字段") 441 | return False 442 | if len(re.findall(r'app_param=.*?[;]?',CK)) == 0: 443 | notify(f"{dic['user']}\tCK格式有误:可能缺少`app_param`字段") 444 | return False 445 | return True 446 | 447 | # 兼容云函数 448 | def main_handler(event, context): 449 | global lists 450 | for each in lists: 451 | if each['CK']!='' and each['UA'] != '': 452 | if checkHT(each): 453 | taskCenter = TaskCenter(each) 454 | for count in range(3): 455 | try: 456 | time.sleep(random.randint(2,5)) # 随机延时 457 | taskCenter.start() 458 | break 459 | except requests.exceptions.ConnectionError: 460 | notify(f"{taskCenter.dic['user']}\t请求失败,随机延迟后再次访问") 461 | time.sleep(random.randint(2,5)) 462 | continue 463 | else: 464 | notify(f"账号: {taskCenter.dic['user']}\n状态: 取消登录\n原因: 多次登录失败") 465 | break 466 | elif not all(each.values()): 467 | notify("账号:空账户\t状态:跳过") 468 | else: 469 | notify(f"账号: {each['user']}\n状态: 取消登录\n原因: json数据不齐全") 470 | notify('*' * 40 + '\n') 471 | if not os.path.basename(__file__).split('_')[-1][:-3] in notifyBlackList: 472 | send('欢太任务中心',allMess) 473 | 474 | if __name__ == '__main__': 475 | main_handler(None,None) 476 | -------------------------------------------------------------------------------- /TimingCash.py: -------------------------------------------------------------------------------- 1 | # !/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # @Time : 2021/9/17 4 | # @Author : MashiroF 5 | # @File : TimingCash.py 6 | # @Software: PyCharm 7 | 8 | ''' 9 | cron: */30 * * * * TimingCash.py 10 | new Env('欢太定时现金'); 11 | ''' 12 | 13 | import os 14 | import re 15 | import sys 16 | import time 17 | import random 18 | 19 | # 配置文件 20 | try: 21 | from HT_config import downFlag,notifyBlackList,logger 22 | import requests 23 | except Exception as error: 24 | logger.info(f'失败原因:{error}') 25 | sys.exit(0) 26 | 27 | # 判断是否发生下载行为 28 | if downFlag == True: 29 | logger.info('发生下载行为,应退出程序,编辑配置文件') 30 | sys.exit(0) 31 | 32 | # 配信文件 33 | try: 34 | from sendNotify import send 35 | except Exception as error: 36 | logger.info('推送文件有误') 37 | logger.info(f'失败原因:{error}') 38 | sys.exit(0) 39 | 40 | # 导入账户 41 | try: 42 | from HT_account import accounts 43 | lists = accounts 44 | except Exception as error: 45 | logger.info(f'失败原因:{error}') 46 | lists = [] 47 | 48 | # 配信内容格式 49 | allMess = '' 50 | def notify(content=None): 51 | global allMess 52 | allMess = allMess + content + '\n' 53 | logger.info(content) 54 | 55 | # 日志录入时间 56 | notify(f"任务:欢太定时现金\n时间:{time.strftime('%Y-%m-%d %H:%M:%S',time.localtime())}") 57 | 58 | class TimingCash: 59 | def __init__(self,dic): 60 | self.dic = dic 61 | self.sess = requests.session() 62 | 63 | # 登录验证 64 | def login(self): 65 | url = 'https://store.oppo.com/cn/oapi/users/web/member/check' 66 | headers = { 67 | 'Host': 'store.oppo.com', 68 | 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9', 69 | 'Content-Type': 'application/x-www-form-urlencoded', 70 | 'Connection': 'keep-alive', 71 | 'Accept-Language': 'zh-cn', 72 | 'Accept-Encoding': 'gzip, deflate, br', 73 | } 74 | response = self.sess.get(url=url,headers=headers).json() 75 | if response['code'] == 200: 76 | notify(f"{self.dic['user']}\t登录成功") 77 | return True 78 | else: 79 | notify(f"{self.dic['user']}\t登录失败") 80 | return False 81 | 82 | # 天天领取现金 83 | def getDailyCashTask(self): 84 | url = 'https://store.oppo.com/cn/oapi/omp-web/web/dailyCash/queryActivityReward' 85 | headers = { 86 | 'Host': 'store.oppo.com', 87 | 'Connection': 'keep-alive', 88 | 'source_type': '501', 89 | 'clientPackage': 'com.oppo.store', 90 | 'Accept': 'application/json, text/plain, */*', 91 | 'Referer': 'https://store.oppo.com/cn/app/cashRedEnvelope?activityId=1&us=shouye&um=xuanfu&uc=xianjinhongbao', 92 | 'Accept-Encoding': 'gzip, deflate', 93 | 'Accept-Language': 'zh-CN,en-US;q=0.9' 94 | } 95 | params = { 96 | 'activityId':1 97 | } 98 | response = self.sess.get(url=url,headers=headers,params=params).json() 99 | if response['code'] == 200: 100 | self.timingRewardList = response['data']['timingRewardList'] 101 | return True 102 | elif response['code'] == 1000001: 103 | notify(f"[定时红包]\t{response['errorMessage']}") 104 | return False 105 | 106 | def getCash(self,dic): 107 | url = 'https://store.oppo.com/cn/oapi/omp-web/web/dailyCash/drawReward' 108 | headers = { 109 | 'Host': 'store.oppo.com', 110 | 'Connection': 'keep-alive', 111 | 'Origin': 'https://store.oppo.com', 112 | 'source_type': '501', 113 | 'clientPackage': 'com.oppo.store', 114 | 'Content-Type': 'application/x-www-form-urlencoded', 115 | 'Accept': 'application/json, text/plain, */*', 116 | 'Referer': 'https://store.oppo.com/cn/app/cashRedEnvelope?activityId=1&us=shouye&um=xuanfu&uc=xianjinhongbao', 117 | 'Accept-Encoding': 'gzip, deflate', 118 | 'Accept-Language': 'zh-CN,en-US;q=0.9' 119 | } 120 | data = { 121 | 'activityId':1, 122 | 'channel':1, 123 | 'channelRewardId':dic['id'] 124 | } 125 | response = self.sess.post(url=url,headers=headers,data=data).json() 126 | if response['code'] == 200: 127 | notify(f"[定时红包]\t第{dic['id']}个红包:{response['data']['amount']}") 128 | elif response['code'] == 1000001: 129 | notify(f"[定时红包]\t第{dic['id']}个红包:{response['errorMessage']}") 130 | 131 | def runtimeReward(self): 132 | for each in self.timingRewardList: 133 | if each['hasDraw'] == False: 134 | self.getCash(dic=each) 135 | break 136 | 137 | # 执行欢太商城实例对象 138 | def start(self): 139 | self.sess.headers.update({ 140 | "User-Agent":self.dic['UA'] 141 | }) 142 | self.sess.cookies.update({ 143 | "Cookie": self.dic['CK'] 144 | }) 145 | if self.login() == True: 146 | if self.getDailyCashTask() == True: 147 | self.runtimeReward() 148 | 149 | # 检测CK是否存在必备参数 150 | def checkHT(dic): 151 | CK = dic['CK'] 152 | if len(re.findall(r'source_type=.*?;',CK)) == 0: 153 | notify(f"{dic['user']}\tCK格式有误:可能缺少`source_type`字段") 154 | return False 155 | if len(re.findall(r'TOKENSID=.*?;',CK)) == 0: 156 | notify(f"{dic['user']}\tCK格式有误:可能缺少`TOKENSID`字段") 157 | return False 158 | if len(re.findall(r'app_param=.*?[;]?',CK)) == 0: 159 | notify(f"{dic['user']}\tCK格式有误:可能缺少`app_param`字段") 160 | return False 161 | return True 162 | 163 | # 兼容云函数 164 | def main_handler(event, context): 165 | global lists 166 | for each in lists: 167 | if each['CK']!='' and each['UA'] != '': 168 | if checkHT(each): 169 | timingCash = TimingCash(each) 170 | for count in range(3): 171 | try: 172 | time.sleep(random.randint(2,5)) # 随机延时 173 | timingCash.start() 174 | break 175 | except requests.exceptions.ConnectionError: 176 | notify(f"{timingCash.dic['user']}\t请求失败,随机延迟后再次访问") 177 | time.sleep(random.randint(2,5)) 178 | continue 179 | else: 180 | notify(f"账号: {timingCash.dic['user']}\n状态: 取消登录\n原因: 多次登录失败") 181 | break 182 | elif not all(each.values()): 183 | notify("账号:空账户\t状态:跳过") 184 | else: 185 | notify(f"账号: {each['user']}\n状态: 取消登录\n原因: json数据不齐全") 186 | notify('*' * 40 + '\n') 187 | if not os.path.basename(__file__).split('_')[-1][:-3] in notifyBlackList: 188 | send('欢太定时现金',allMess) 189 | 190 | if __name__ == '__main__': 191 | main_handler(None,None) 192 | -------------------------------------------------------------------------------- /index.py: -------------------------------------------------------------------------------- 1 | # !/usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | # @Time : 2021/10/27 4 | # @Author : MashiroF 5 | # @File : index.py 6 | # @Software: PyCharm 7 | from importlib import import_module 8 | 9 | def main_handler(event, context): 10 | taskName = import_module(event['TriggerName']) 11 | taskName.main_handler(None, None) 12 | -------------------------------------------------------------------------------- /sendNotify.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | # _*_ coding:utf-8 _*_ 3 | import base64 4 | import hashlib 5 | import hmac 6 | import json 7 | import os 8 | import re 9 | import threading 10 | import time 11 | import traceback 12 | import urllib.parse 13 | 14 | import requests 15 | 16 | # 原先的 print 函数和主线程的锁 17 | _print = print 18 | mutex = threading.Lock() 19 | 20 | 21 | # 定义新的 print 函数 22 | def print(text, *args, **kw): 23 | """ 24 | 使输出有序进行,不出现多线程同一时间输出导致错乱的问题。 25 | """ 26 | with mutex: 27 | _print(text, *args, **kw) 28 | 29 | 30 | # 通知服务 31 | # fmt: off 32 | push_config = { 33 | 'HITOKOTO': False, # 启用一言(随机句子) 34 | 35 | 'BARK_PUSH': '', # bark IP 或设备码,例:https://api.day.app/DxHcxxxxxRxxxxxxcm 36 | 'BARK_ARCHIVE': '', # bark 推送是否存档 37 | 'BARK_GROUP': '', # bark 推送分组 38 | 'BARK_SOUND': '', # bark 推送声音 39 | 40 | 'CONSOLE': False, # 控制台输出 41 | 42 | 'DD_BOT_SECRET': '', # 钉钉机器人的 DD_BOT_SECRET 43 | 'DD_BOT_TOKEN': '', # 钉钉机器人的 DD_BOT_TOKEN 44 | 45 | 'FSKEY': '', # 飞书机器人的 FSKEY 46 | 47 | 'GOBOT_URL': '', # go-cqhttp 48 | # 推送到个人QQ:http://127.0.0.1/send_private_msg 49 | # 群:http://127.0.0.1/send_group_msg 50 | 'GOBOT_QQ': '', # go-cqhttp 的推送群或用户 51 | # GOBOT_URL 设置 /send_private_msg 时填入 user_id=个人QQ 52 | # /send_group_msg 时填入 group_id=QQ群 53 | 'GOBOT_TOKEN': '', # go-cqhttp 的 access_token 54 | 55 | 'IGOT_PUSH_KEY': '', # iGot 聚合推送的 IGOT_PUSH_KEY 56 | 57 | 'PUSH_KEY': '', # server 酱的 PUSH_KEY,兼容旧版与 Turbo 版 58 | 59 | 'PUSH_PLUS_TOKEN': '', # push+ 微信推送的用户令牌 60 | 'PUSH_PLUS_USER': '', # push+ 微信推送的群组编码 61 | 62 | 'QMSG_KEY': '', # qmsg 酱的 QMSG_KEY 63 | 'QMSG_TYPE': '', # qmsg 酱的 QMSG_TYPE 64 | 65 | 'QYWX_AM': '', # 企业微信应用 66 | 67 | 'QYWX_KEY': '', # 企业微信机器人 68 | 69 | 'TG_BOT_TOKEN': '', # tg 机器人的 TG_BOT_TOKEN,例:1407203283:AAG9rt-6RDaaX0HBLZQq0laNOh898iFYaRQ 70 | 'TG_USER_ID': '', # tg 机器人的 TG_USER_ID,例:1434078534 71 | 'TG_API_HOST': '', # tg 代理 api 72 | 'TG_PROXY_AUTH': '', # tg 代理认证参数 73 | 'TG_PROXY_HOST': '', # tg 机器人的 TG_PROXY_HOST 74 | 'TG_PROXY_PORT': '', # tg 机器人的 TG_PROXY_PORT 75 | } 76 | notify_function = [] 77 | # fmt: on 78 | 79 | # 首先读取 面板变量 或者 github action 运行变量 80 | for k in push_config: 81 | if os.getenv(k): 82 | v = os.getenv(k) 83 | push_config[k] = v 84 | 85 | 86 | def bark(title: str, content: str) -> None: 87 | """ 88 | 使用 bark 推送消息。 89 | """ 90 | if not push_config.get("BARK_PUSH"): 91 | print("bark 服务的 BARK_PUSH 未设置!!\n取消推送") 92 | return 93 | print("bark 服务启动") 94 | 95 | if push_config.get("BARK_PUSH").startswith("http"): 96 | url = f'{push_config.get("BARK_PUSH").rstrip("/")}/{urllib.parse.quote_plus(title)}/{urllib.parse.quote_plus(content)}' 97 | else: 98 | url = f'https://api.day.app/{push_config.get("BARK_PUSH")}/{urllib.parse.quote_plus(title)}/{urllib.parse.quote_plus(content)}' 99 | 100 | bark_params = { 101 | "BARK_ARCHIVE": "isArchive", 102 | "BARK_GROUP": "group", 103 | "BARK_SOUND": "sound", 104 | } 105 | params = "" 106 | for pair in filter( 107 | lambda pairs: pairs[0].startswith("BARK_") 108 | and pairs[0] != "BARK_PUSH" 109 | and pairs[1] 110 | and bark_params.get(pairs[0]), 111 | push_config.items(), 112 | ): 113 | params += f"{bark_params.get(pair[0])}={pair[1]}&" 114 | if params: 115 | url = url + "?" + params.rstrip("&") 116 | 117 | try: 118 | response = requests.get(url, timeout=15) 119 | try: 120 | datas = response.json() 121 | if datas.get("code") == 200: 122 | print("bark 推送成功!") 123 | elif datas.get("code") == 400: 124 | print("bark 推送失败!找不到 Key 对应的 DeviceToken。") 125 | else: 126 | print(f"bark 推送失败!响应数据:{datas}") 127 | except json.JSONDecodeError: 128 | print(f"推送返回值非 json 格式,请检查网址和账号是否填写正确。\n{response.text}") 129 | except requests.exceptions.RequestException: 130 | print(f"网络异常,请检查你的网络连接、推送服务器和代理配置。\n{traceback.format_exc()}") 131 | except Exception: 132 | print(f"其他错误信息:\n{traceback.format_exc()}") 133 | 134 | 135 | def console(title: str, content: str) -> None: 136 | """ 137 | 使用 控制台 推送消息。 138 | """ 139 | print(f"{title}\n\n{content}") 140 | 141 | 142 | def dingding_bot(title: str, content: str) -> None: 143 | """ 144 | 使用 钉钉机器人 推送消息。 145 | """ 146 | if not push_config.get("DD_BOT_SECRET") or not push_config.get("DD_BOT_TOKEN"): 147 | print("钉钉机器人 服务的 DD_BOT_SECRET 或者 DD_BOT_TOKEN 未设置!!\n取消推送") 148 | return 149 | print("钉钉机器人 服务启动") 150 | 151 | timestamp = str(round(time.time() * 1000)) 152 | secret_enc = push_config.get("DD_BOT_SECRET").encode("utf-8") 153 | string_to_sign = "{}\n{}".format(timestamp, push_config.get("DD_BOT_SECRET")) 154 | string_to_sign_enc = string_to_sign.encode("utf-8") 155 | hmac_code = hmac.new( 156 | secret_enc, string_to_sign_enc, digestmod=hashlib.sha256 157 | ).digest() 158 | sign = urllib.parse.quote_plus(base64.b64encode(hmac_code)) 159 | url = f'https://oapi.dingtalk.com/robot/send?access_token={push_config.get("DD_BOT_TOKEN")}×tamp={timestamp}&sign={sign}' 160 | headers = {"Content-Type": "application/json;charset=utf-8"} 161 | data = {"msgtype": "text", "text": {"content": f"{title}\n\n{content}"}} 162 | 163 | try: 164 | response = requests.post( 165 | url=url, data=json.dumps(data), headers=headers, timeout=15 166 | ) 167 | try: 168 | datas = response.json() 169 | if datas.get("errcode") == 0: 170 | print("钉钉机器人 推送成功!") 171 | else: 172 | print(f"钉钉机器人 推送失败!响应数据:{datas}") 173 | except json.JSONDecodeError: 174 | print(f"推送返回值非 json 格式,请检查网址和账号是否填写正确。\n{response.text}") 175 | except requests.exceptions.RequestException: 176 | print(f"网络异常,请检查你的网络连接、推送服务器和代理配置。\n{traceback.format_exc()}") 177 | except Exception: 178 | print(f"其他错误信息:\n{traceback.format_exc()}") 179 | 180 | 181 | def feishu_bot(title: str, content: str) -> None: 182 | """ 183 | 使用 飞书机器人 推送消息。 184 | """ 185 | if not push_config.get("FSKEY"): 186 | print("飞书 服务的 FSKEY 未设置!!\n取消推送") 187 | return 188 | print("飞书 服务启动") 189 | 190 | url = f'https://open.feishu.cn/open-apis/bot/v2/hook/{push_config.get("FSKEY")}' 191 | data = {"msg_type": "text", "content": {"text": f"{title}\n\n{content}"}} 192 | try: 193 | response = requests.post(url, data=json.dumps(data), timeout=15) 194 | try: 195 | datas = response.json() 196 | if datas.get("StatusCode") == 0: 197 | print("飞书 推送成功!") 198 | else: 199 | print(f"飞书 推送失败!响应数据:{datas}") 200 | except json.JSONDecodeError: 201 | print(f"推送返回值非 json 格式,请检查网址和账号是否填写正确。\n{response.text}") 202 | except requests.exceptions.RequestException: 203 | print(f"网络异常,请检查你的网络连接、推送服务器和代理配置。\n{traceback.format_exc()}") 204 | except Exception: 205 | print(f"其他错误信息:\n{traceback.format_exc()}") 206 | 207 | 208 | def go_cqhttp(title: str, content: str) -> None: 209 | """ 210 | 使用 go_cqhttp 推送消息。 211 | """ 212 | if not push_config.get("GOBOT_URL") or not push_config.get("GOBOT_QQ"): 213 | print("go-cqhttp 服务的 GOBOT_URL 或 GOBOT_QQ 未设置!!\n取消推送") 214 | return 215 | print("go-cqhttp 服务启动") 216 | 217 | url = f'{push_config.get("GOBOT_URL")}?access_token={push_config.get("GOBOT_TOKEN")}&{push_config.get("GOBOT_QQ")}&message=标题:{title}\n内容:{content}' 218 | 219 | try: 220 | response = requests.get(url, timeout=15) 221 | try: 222 | datas = response.json() 223 | if datas.get("status") == "ok": 224 | print("go-cqhttp 推送成功!") 225 | else: 226 | print(f"go-cqhttp 推送失败!响应数据:{datas}") 227 | except json.JSONDecodeError: 228 | print(f"推送返回值非 json 格式,请检查网址和账号是否填写正确。\n{response.text}") 229 | except requests.exceptions.RequestException: 230 | print(f"网络异常,请检查你的网络连接、推送服务器和代理配置。\n{traceback.format_exc()}") 231 | except Exception: 232 | print(f"其他错误信息:\n{traceback.format_exc()}") 233 | 234 | 235 | def iGot(title: str, content: str) -> None: 236 | """ 237 | 使用 iGot 推送消息。 238 | """ 239 | if not push_config.get("IGOT_PUSH_KEY"): 240 | print("iGot 服务的 IGOT_PUSH_KEY 未设置!!\n取消推送") 241 | return 242 | print("iGot 服务启动") 243 | 244 | url = f'https://push.hellyw.com/{push_config.get("IGOT_PUSH_KEY")}' 245 | data = {"title": title, "content": content} 246 | headers = {"Content-Type": "application/x-www-form-urlencoded"} 247 | 248 | try: 249 | response = requests.post(url, data=data, headers=headers, timeout=15) 250 | try: 251 | datas = response.json() 252 | if datas.get("ret") == 0: 253 | print("iGot 推送成功!") 254 | else: 255 | print(f'iGot 推送失败!错误信息:{datas.get("errMsg")}') 256 | except json.JSONDecodeError: 257 | print(f"推送返回值非 json 格式,请检查网址和账号是否填写正确。\n{response.text}") 258 | except requests.exceptions.RequestException: 259 | print(f"网络异常,请检查你的网络连接、推送服务器和代理配置。\n{traceback.format_exc()}") 260 | except Exception: 261 | print(f"其他错误信息:\n{traceback.format_exc()}") 262 | 263 | 264 | def serverJ(title: str, content: str) -> None: 265 | """ 266 | 通过 serverJ 推送消息。 267 | """ 268 | if not push_config.get("PUSH_KEY"): 269 | print("serverJ 服务的 PUSH_KEY 未设置!!\n取消推送") 270 | return 271 | print("serverJ 服务启动") 272 | 273 | data = {"text": title, "desp": content.replace("\n", "\n\n")} 274 | if push_config.get("PUSH_KEY").index("SCT") != -1: 275 | url = f'https://sctapi.ftqq.com/{push_config.get("PUSH_KEY")}.send' 276 | else: 277 | url = f'https://sc.ftqq.com/${push_config.get("PUSH_KEY")}.send' 278 | 279 | try: 280 | response = requests.post(url, data=data, timeout=15) 281 | try: 282 | datas = response.json() 283 | if datas.get("errno") == 0 or datas.get("code") == 0: 284 | print("serverJ 推送成功!") 285 | elif datas.get("code") == 40001: 286 | print("serverJ 推送失败!PUSH_KEY 错误。") 287 | else: 288 | print(f'serverJ 推送失败!错误码:{datas.get("message")}') 289 | except json.JSONDecodeError: 290 | print(f"推送返回值非 json 格式,请检查网址和账号是否填写正确。\n{response.text}") 291 | except requests.exceptions.RequestException: 292 | print(f"网络异常,请检查你的网络连接、推送服务器和代理配置。\n{traceback.format_exc()}") 293 | except Exception: 294 | print(f"其他错误信息:\n{traceback.format_exc()}") 295 | 296 | 297 | def pushplus_bot(title: str, content: str) -> None: 298 | """ 299 | 通过 push+ 推送消息。 300 | """ 301 | if not push_config.get("PUSH_PLUS_TOKEN"): 302 | print("PUSHPLUS 服务的 PUSH_PLUS_TOKEN 未设置!!\n取消推送") 303 | return 304 | print("PUSHPLUS 服务启动") 305 | 306 | url = "http://www.pushplus.plus/send" 307 | data = { 308 | "token": push_config.get("PUSH_PLUS_TOKEN"), 309 | "title": title, 310 | "content": content, 311 | "topic": push_config.get("PUSH_PLUS_USER"), 312 | } 313 | body = json.dumps(data).encode(encoding="utf-8") 314 | headers = {"Content-Type": "application/json"} 315 | 316 | try: 317 | response = requests.post(url=url, data=body, headers=headers, timeout=15) 318 | try: 319 | datas = response.json() 320 | if datas.get("code") == 200: 321 | print("PUSHPLUS 推送成功!") 322 | elif datas.get("code") == 600: 323 | url2 = "http://pushplus.hxtrip.com/send" 324 | response2 = requests.post( 325 | url=url2, data=body, headers=headers, timeout=15 326 | ) 327 | try: 328 | datas2 = response2.json() 329 | if datas2.get("code") == 200: 330 | print("PUSHPLUS(hxtrip) 推送成功!") 331 | elif datas2.get("code") == 600: 332 | print("PUSHPLUS 推送失败!PUSH_PLUS_TOKEN 错误。") 333 | else: 334 | print(f"PUSHPLUS(hxtrip) 推送失败!响应数据:{datas2}") 335 | except json.JSONDecodeError: 336 | print(f"推送返回值非 json 格式,请检查网址和账号是否填写正确。\n{response2.text}") 337 | else: 338 | print(f"PUSHPLUS 推送失败!响应数据:{datas}") 339 | except json.JSONDecodeError: 340 | print(f"推送返回值非 json 格式,请检查网址和账号是否填写正确。\n{response.text}") 341 | except requests.exceptions.RequestException: 342 | print(f"网络异常,请检查你的网络连接、推送服务器和代理配置。\n{traceback.format_exc()}") 343 | except Exception: 344 | print(f"其他错误信息:\n{traceback.format_exc()}") 345 | 346 | 347 | def qmsg_bot(title: str, content: str) -> None: 348 | """ 349 | 使用 qmsg 推送消息。 350 | """ 351 | if not push_config.get("QMSG_KEY") or not push_config.get("QMSG_TYPE"): 352 | print("qmsg 的 QMSG_KEY 或者 QMSG_TYPE 未设置!!\n取消推送") 353 | return 354 | print("qmsg 服务启动") 355 | 356 | url = f'https://qmsg.zendee.cn/{push_config.get("QMSG_TYPE")}/{push_config.get("QMSG_KEY")}' 357 | payload = {"msg": f'{title}\n\n{content.replace("----", "-")}'.encode("utf-8")} 358 | 359 | try: 360 | response = requests.post(url=url, params=payload, timeout=15) 361 | try: 362 | datas = response.json() 363 | if response.get("code") == 0: 364 | print("qmsg 推送成功!") 365 | else: 366 | print(f'qmsg 推送失败!错误信息:{datas.get("reason")}') 367 | except json.JSONDecodeError: 368 | print(f"推送返回值非 json 格式,请检查网址和账号是否填写正确。\n{response.text}") 369 | except requests.exceptions.RequestException: 370 | print(f"网络异常,请检查你的网络连接、推送服务器和代理配置。\n{traceback.format_exc()}") 371 | except Exception: 372 | print(f"其他错误信息:\n{traceback.format_exc()}") 373 | 374 | 375 | def wecom_app(title: str, content: str) -> None: 376 | """ 377 | 通过 企业微信 APP 推送消息。 378 | """ 379 | if not push_config.get("QYWX_AM"): 380 | print("QYWX_AM 未设置!!\n取消推送") 381 | return 382 | QYWX_AM_AY = re.split(",", push_config.get("QYWX_AM")) 383 | if 4 < len(QYWX_AM_AY) > 5: 384 | print("QYWX_AM 设置错误!!\n取消推送") 385 | return 386 | print("企业微信 APP 服务启动") 387 | 388 | corpid = QYWX_AM_AY[0] 389 | corpsecret = QYWX_AM_AY[1] 390 | touser = QYWX_AM_AY[2] 391 | agentid = QYWX_AM_AY[3] 392 | try: 393 | media_id = QYWX_AM_AY[4] 394 | except IndexError: 395 | media_id = "" 396 | wx = WeCom(corpid, corpsecret, agentid) 397 | # 如果没有配置 media_id 默认就以 text 方式发送 398 | try: 399 | if not media_id: 400 | message = title + "\n\n" + content 401 | datas = wx.send_text(message, touser) 402 | else: 403 | datas = wx.send_mpnews(title, content, media_id, touser) 404 | if datas == "ok": 405 | print("企业微信推送成功!") 406 | else: 407 | print(f"企业微信推送失败!错误信息:{datas}") 408 | except requests.exceptions.RequestException: 409 | print(f"网络异常,请检查你的网络连接、推送服务器和代理配置。\n{traceback.format_exc()}") 410 | except Exception: 411 | print(f"其他错误信息:\n{traceback.format_exc()}") 412 | 413 | 414 | class WeCom: 415 | def __init__(self, corpid, corpsecret, agentid): 416 | self.CORPID = corpid 417 | self.CORPSECRET = corpsecret 418 | self.AGENTID = agentid 419 | 420 | def get_access_token(self): 421 | url = "https://qyapi.weixin.qq.com/cgi-bin/gettoken" 422 | values = { 423 | "corpid": self.CORPID, 424 | "corpsecret": self.CORPSECRET, 425 | } 426 | req = requests.post(url, params=values, timeout=15) 427 | datas = json.loads(req.text) 428 | return datas.get("access_token") 429 | 430 | def send_text(self, message, touser="@all"): 431 | send_url = ( 432 | "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=" 433 | + self.get_access_token() 434 | ) 435 | send_values = { 436 | "touser": touser, 437 | "msgtype": "text", 438 | "agentid": self.AGENTID, 439 | "text": {"content": message}, 440 | "safe": "0", 441 | } 442 | send_msges = bytes(json.dumps(send_values), "utf-8") 443 | response = requests.post(send_url, send_msges, timeout=15) 444 | try: 445 | datas = response.json() 446 | return datas.get("errmsg") 447 | except json.JSONDecodeError: 448 | print(f"推送返回值非 json 格式,请检查网址和账号是否填写正确。\n{response.text}") 449 | return response.text 450 | 451 | def send_mpnews(self, title, message, media_id, touser="@all"): 452 | send_url = ( 453 | "https://qyapi.weixin.qq.com/cgi-bin/message/send?access_token=" 454 | + self.get_access_token() 455 | ) 456 | send_values = { 457 | "touser": touser, 458 | "msgtype": "mpnews", 459 | "agentid": self.AGENTID, 460 | "mpnews": { 461 | "articles": [ 462 | { 463 | "title": title, 464 | "thumb_media_id": media_id, 465 | "author": "Author", 466 | "content_source_url": "", 467 | "content": message.replace("\n", "
"), 468 | "digest": message, 469 | } 470 | ] 471 | }, 472 | } 473 | send_msges = bytes(json.dumps(send_values), "utf-8") 474 | response = requests.post(send_url, send_msges, timeout=15) 475 | try: 476 | datas = response.json() 477 | return datas.get("errmsg") 478 | except json.JSONDecodeError: 479 | print(f"推送返回值非 json 格式,请检查网址和账号是否填写正确。\n{response.text}") 480 | return response.text 481 | 482 | 483 | def wecom_bot(title: str, content: str) -> None: 484 | """ 485 | 通过 企业微信机器人 推送消息。 486 | """ 487 | if not push_config.get("QYWX_KEY"): 488 | print("企业微信机器人 服务的 QYWX_KEY 未设置!!\n取消推送") 489 | return 490 | print("企业微信机器人服务启动") 491 | 492 | url = f"https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key={push_config.get('QYWX_KEY')}" 493 | headers = {"Content-Type": "application/json;charset=utf-8"} 494 | data = {"msgtype": "text", "text": {"content": f"{title}\n\n{content}"}} 495 | 496 | try: 497 | response = requests.post( 498 | url=url, data=json.dumps(data), headers=headers, timeout=15 499 | ) 500 | try: 501 | datas = response.json() 502 | if datas.get("errcode") == 0: 503 | print("企业微信机器人 推送成功!") 504 | else: 505 | print(f"企业微信机器人 推送失败!响应数据:{datas}") 506 | except json.JSONDecodeError: 507 | print(f"推送返回值非 json 格式,请检查网址和账号是否填写正确。\n{response.text}") 508 | except requests.exceptions.RequestException: 509 | print(f"网络异常,请检查你的网络连接、推送服务器和代理配置。\n{traceback.format_exc()}") 510 | except Exception: 511 | print(f"其他错误信息:\n{traceback.format_exc()}") 512 | 513 | 514 | def telegram_bot(title: str, content: str) -> None: 515 | """ 516 | 使用 telegram 机器人 推送消息。 517 | """ 518 | if not push_config.get("TG_BOT_TOKEN") or not push_config.get("TG_USER_ID"): 519 | print("tg 服务的 bot_token 或者 user_id 未设置!!\n取消推送") 520 | return 521 | print("tg 服务启动") 522 | 523 | if push_config.get("TG_API_HOST"): 524 | url = f"https://{push_config.get('TG_API_HOST')}/bot{push_config.get('TG_BOT_TOKEN')}/sendMessage" 525 | else: 526 | url = ( 527 | f"https://api.telegram.org/bot{push_config.get('TG_BOT_TOKEN')}/sendMessage" 528 | ) 529 | headers = {"Content-Type": "application/x-www-form-urlencoded"} 530 | payload = { 531 | "chat_id": str(push_config.get("TG_USER_ID")), 532 | "text": f"{title}\n\n{content}", 533 | "disable_web_page_preview": "true", 534 | } 535 | proxies = None 536 | if push_config.get("TG_PROXY_HOST") and push_config.get("TG_PROXY_PORT"): 537 | if push_config.get("TG_PROXY_AUTH") is not None and "@" not in push_config.get( 538 | "TG_PROXY_HOST" 539 | ): 540 | push_config["TG_PROXY_HOST"] = ( 541 | push_config.get("TG_PROXY_AUTH") 542 | + "@" 543 | + push_config.get("TG_PROXY_HOST") 544 | ) 545 | proxyStr = "http://{}:{}".format( 546 | push_config.get("TG_PROXY_HOST"), push_config.get("TG_PROXY_PORT") 547 | ) 548 | proxies = {"http": proxyStr, "https": proxyStr} 549 | 550 | try: 551 | response = requests.post( 552 | url=url, headers=headers, params=payload, proxies=proxies, timeout=15 553 | ) 554 | try: 555 | datas = response.json() 556 | if datas.get("ok") == True: 557 | print("tg 推送成功!") 558 | elif datas.get("error_code") == 400: 559 | print("tg 推送失败!请主动给 bot 发送一条消息并检查接收用户 TG_USER_ID 是否正确。") 560 | elif datas.get("error_code") == 401: 561 | print("tg 推送失败!TG_BOT_TOKEN 填写错误。") 562 | else: 563 | print(f"tg 推送失败!响应数据:{datas}") 564 | except json.JSONDecodeError: 565 | print(f"推送返回值非 json 格式,请检查网址和账号是否填写正确。\n{response.text}") 566 | except requests.exceptions.RequestException: 567 | print(f"网络异常,请检查你的网络连接、推送服务器和代理配置。\n{traceback.format_exc()}") 568 | except Exception: 569 | print(f"其他错误信息:\n{traceback.format_exc()}") 570 | 571 | 572 | def one() -> str: 573 | """ 574 | 获取一条一言。 575 | :return: 576 | """ 577 | try: 578 | url = "https://v1.hitokoto.cn/" 579 | res = requests.get(url).json() 580 | return res["hitokoto"] + " ----" + res["from"] 581 | except requests.exceptions.ConnectionError: 582 | return "" 583 | 584 | 585 | if push_config.get("BARK_PUSH"): 586 | notify_function.append(bark) 587 | if push_config.get("CONSOLE"): 588 | notify_function.append(console) 589 | if push_config.get("DD_BOT_TOKEN") and push_config.get("DD_BOT_SECRET"): 590 | notify_function.append(dingding_bot) 591 | if push_config.get("FSKEY"): 592 | notify_function.append(feishu_bot) 593 | if push_config.get("GOBOT_URL") and push_config.get("GOBOT_QQ"): 594 | notify_function.append(go_cqhttp) 595 | if push_config.get("IGOT_PUSH_KEY"): 596 | notify_function.append(iGot) 597 | if push_config.get("PUSH_KEY"): 598 | notify_function.append(serverJ) 599 | if push_config.get("PUSH_PLUS_TOKEN"): 600 | notify_function.append(pushplus_bot) 601 | if push_config.get("QMSG_KEY") and push_config.get("QMSG_TYPE"): 602 | notify_function.append(qmsg_bot) 603 | if push_config.get("QYWX_AM"): 604 | notify_function.append(wecom_app) 605 | if push_config.get("QYWX_KEY"): 606 | notify_function.append(wecom_bot) 607 | if push_config.get("TG_BOT_TOKEN") and push_config.get("TG_USER_ID"): 608 | notify_function.append(telegram_bot) 609 | 610 | 611 | def send(title: str, content: str) -> None: 612 | if not content: 613 | print(f"{title} 推送内容为空!") 614 | return 615 | 616 | hitokoto = push_config.get("HITOKOTO") 617 | 618 | text = one() if hitokoto else "" 619 | content += "\n\n" + text 620 | 621 | ts = [ 622 | threading.Thread(target=mode, args=(title, content), name=mode.__name__) 623 | for mode in notify_function 624 | ] 625 | [t.start() for t in ts] 626 | [t.join() for t in ts] 627 | 628 | 629 | def main(): 630 | send("title", "content") 631 | 632 | 633 | if __name__ == "__main__": 634 | main() 635 | --------------------------------------------------------------------------------