diff --git a/Points_Based/wps_pro_3.0.2.py b/Points_Based/WPSpro_Loader_3.0.2.py similarity index 97% rename from Points_Based/wps_pro_3.0.2.py rename to Points_Based/WPSpro_Loader_3.0.2.py index 09c3fb6..f02486a 100644 --- a/Points_Based/wps_pro_3.0.2.py +++ b/Points_Based/WPSpro_Loader_3.0.2.py @@ -1,1441 +1,1441 @@ -# cron: 12 8 * * * -# new Env("WPS签到") -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -""" -@File : wps签到任务 -@CreateTime : 2026/01/17 -@UpdateTime : 2026/04/12 -@Author : Rex -@Version : 3.0.2 -@Contact : 2375560790@qq.com -@QQ群 : 621124138 备注妖火 -@License : MIT -@UpdateContent : - 1.适配 任务中心新任务。 - 2.修复 办公助手任务。 - 3.新增 WPS挑战计划。 - 4. 增强错误处理。 -@Desc : - 活动地址: - https://personal-act.wps.cn/rubik2/portal/HD2025031821201822/YM2025040908558269?cs_from=web_vipcenter_banner_inpublic&mk_key=4b9deqIfqNO3KCZrgH17WPH1kdzMoKUEvya&position=pc_aty_ban3_kaixue_test_b - 核心功能: - 1. WPS任务中心:每日签到、自动完成所有任务、自动抽奖 - 2. 办公助手(办公助手 2026.03.16结束):每日签到、自动完成所有任务、自动抽奖 - 3. 天天领福利:每日签到、自动完成所有任务、自动抽奖 - 4. WPS超级会员小程序:签到 - 5. WPS挑战计划:自动完成所有任务、自动抽奖 - 使用: - 1. cookie 抓取这个接口的请求头cookie字段 https://personal-act.wps.cn/activity-rubik/activity/component_action - 2. 青龙配置环境变量 WPS_TASK_CK,格式:备注#cookie,支持多账号,多账号回车换行 - 2. 青龙面板推荐 cron 0 0 7 * * * - 遗留问题: - 1.WPS挑战计划:'PDF转换', 'PDF合并', '语音速记', '关注' 后续开发 - 2.小程序只有签到抽奖等妖友待测 - 3.WPS任务中心 疑似存在新旧任务列表,任务可以多做,暂时未适配 -""" -import os -import sys -import random -import time -from typing import Optional, Dict, Any, Union, Tuple, List -import requests -import urllib3 -from loguru import logger -from requests import Response - -# ------------------------ 模块加载区 -------------------------- -# 1. 获取当前脚本的绝对路径 -current_script = os.path.abspath(__file__) -# 2. 定位根目录(根据实际结构调整层级) -# 假设脚本在根目录的子目录(如 src/)中,根目录是当前脚本目录的上层目录 -root_dir = os.path.dirname(os.path.dirname(current_script)) -# 3. 将根目录添加到模块搜索路径(确保只添加一次) -if root_dir not in sys.path: - sys.path.insert(0, root_dir) # 插入到最前面,优先搜索根目录 -try: - from RnlProxy import RnlProxy -except: - RnlProxy = None - logger.error('未检测到 RnlProxy.py 模块,使用默认ip') -try: - from rnl_push import rnl_push -except: - try: - import notify - if hasattr(notify, 'send'): - notify.sendNotify = notify.send - rnl_push = notify - except: - rnl_push = None - logger.error('未检测到 rnl_push.py、notify.py 模块,不进行消息推送') -# ------------------------ 模块加载区 -------------------------- - -class Utils: - @staticmethod - def r_sleep(s=1.0, e=None): - """随机休眠函数(外部传秒,内部精确到毫秒)""" - try: - s = float(s) - e = float(e) if e is not None else None - except (ValueError, TypeError): - raise ValueError("参数 s/e 必须是可转换为浮点数的数字(秒)") - if e is None: - e = s + 1.0 - if s > e: - s, e = e, s - s = max(s, 0.0) - e = max(e, 0.0) - s_ms = int(round(s * 1000)) - e_ms = int(round(e * 1000)) - sleep_ms = random.randint(s_ms, e_ms) - sleep_sec = sleep_ms / 1000 - time.sleep(sleep_sec) - return round(sleep_sec, 3) - - @staticmethod - def dict_cookie_to_string(cookie_dict): - cookie_list = [] - for key, value in cookie_dict.items(): - cookie_list.append(f"{key}={value}") - return "; ".join(cookie_list) - - @staticmethod - def string_cookie_to_dict(cookie_str): - cookie_dict = {} - if not cookie_str: - return cookie_dict - cookie_pairs = [pair.strip() for pair in cookie_str.split(';') if pair.strip()] - for pair in cookie_pairs: - key_value = pair.split('=', 1) - if len(key_value) == 2: - key, value = key_value - cookie_dict[key.strip()] = value.strip() - else: - cookie_dict[key_value[0].strip()] = "" - return cookie_dict - - -class RnlRequest: - def __init__(self, proxies=None, cookies=None, headers=None): - urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) - self.session = requests.Session() - self.session.trust_env = False - self.session.verify = False - self.last_response: Optional[Response] = None - if proxies: - self.session.proxies.update(proxies) - self._base_headers = headers or { - 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36', - } - self.update_cookies(cookies) - - @property - def status_code(self) -> Optional[int]: - return self.last_response.status_code if self.last_response else None - - @property - def ok(self) -> bool: - return 200 <= self.status_code < 300 if self.status_code else False - - @property - def json(self) -> Any: - if not self.last_response: - return None - try: - return self.last_response.json() - except (ValueError, TypeError): - return None - - @property - def text(self) -> Optional[str]: - return self.last_response.text if self.last_response else None - - @property - def content(self) -> Optional[bytes]: - return self.last_response.content if self.last_response else None - - @property - def headers(self) -> Optional[Dict[str, str]]: - return dict(self.last_response.headers) if self.last_response else None - - def update_cookies(self, cookies: Union[str, dict, None]) -> None: - if not cookies: - return - if isinstance(cookies, str): - cookies = dict( - item.strip().split('=', 1) - for item in cookies.split(';') - if '=' in item.strip() - ) - elif not isinstance(cookies, dict): - return - self.session.cookies.update(cookies) - - def get_cookies(self) -> Dict[str, str]: - return self.session.cookies.get_dict() - - def update_headers(self, headers: Dict[str, str]) -> None: - self._base_headers.update(headers) - - def raise_for_status(self) -> None: - if self.last_response: - self.last_response.raise_for_status() - - def request(self, method, url, params=None, data=None, json=None, headers=None, - cookies=None, files=None, auth=None, timeout=None, allow_redirects=True, - proxies=None, hooks=None, stream=None, verify=None, cert=None, **kwargs) -> Optional[Response]: - self.last_response = None - request_headers = {**self._base_headers, **(headers or {})} - try: - resp = self.session.request( - method=method.upper(), - url=url, - params=params, - data=data, - json=json, - headers=request_headers, - cookies=cookies, - files=files, - auth=auth, - timeout=timeout, - allow_redirects=allow_redirects, - proxies=proxies, - hooks=hooks, - stream=stream, - verify=verify if verify is not None else self.session.verify, - cert=cert, - **kwargs - ) - self.last_response = resp - return resp - except requests.RequestException as e: - if hasattr(e, 'response') and e.response: - self.last_response = e.response - return e.response - return None - - def get(self, url, **kwargs): - return self.request(method='GET', url=url, **kwargs) - - def post(self, url, **kwargs): - return self.request(method='POST', url=url, **kwargs) - - def __enter__(self): - return self - - def __exit__(self, exc_type, exc_val, exc_tb): - self.session.close() - - -import json -import hashlib -import hmac -from datetime import datetime, timezone - - -def generate_sign(t: dict, i: str, r: str) -> str: - sorted_keys = sorted(t.keys()) - n = {key: t[key] for key in sorted_keys} - p = json.dumps(n, ensure_ascii=False, separators=(',', ':')) - md5_p = hashlib.md5(p.encode('utf-8')).hexdigest() - utc_time = datetime.now(timezone.utc).strftime('%a, %d %b %Y %H:%M:%S GMT') - f = i + md5_p + utc_time - hmac_obj = hmac.new(r.encode('utf-8'), f.encode('utf-8'), hashlib.sha256) - u = hmac_obj.hexdigest() - return u - - -class RNL: - def __init__(self, c, proxies=None): - if isinstance(c, str): - new_c = Utils.string_cookie_to_dict(c) - else: - new_c = c - self.act_csrf_token = new_c.get('act_csrf_token') - self.user_id = new_c.get('uid') - if not self.act_csrf_token or not self.user_id: - logger.error(f'[用户{self.user_id or "未知"}] cookie参数不全(缺少act_csrf_token或uid)') - exit(1) - self.user_id = int(new_c.get('uid')) - self.userAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36 Edg/134.0.0.0' - self.rr = RnlRequest(proxies=proxies, cookies=new_c, headers={'User-Agent': self.userAgent}) - self.de = { - 'PROMOTIONAL_MATERIAL': "task_center.promotional_material", - 'START_TASK': "task_center.start", - 'FINISH': "task_center.finish", - 'TOKEN_FINISH': "task_center.token_finish", - 'REWARD': "task_center.reward" - } - self.operation_logs = [] - self.global_config = { - 'task_center': True, # WPS任务中心 - 'fragment_collect': False, # 办公助手 2026.03.16结束 - 'lottery3': True, # 天天领福利 - 'svip_applet': True, # 超级会员applet - 'challenge': True, # WPS挑战计划 - } - - # WPS任务中心-获取签到key - def get_public_key(self): - headers = { - 'accept': 'application/json, text/plain, */*', - 'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6', - 'origin': 'https://personal-act.wps.cn', - 'priority': 'u=1, i', - 'referer': 'https://personal-act.wps.cn/', - 'sec-ch-ua': '"Chromium";v="134", "Not:A-Brand";v="24", "Microsoft Edge";v="134"', - 'sec-ch-ua-mobile': '?0', - 'sec-ch-ua-platform': '"Windows"', - 'sec-fetch-dest': 'empty', - 'sec-fetch-mode': 'cors', - 'sec-fetch-site': 'same-site', - } - response = self.rr.get('https://personal-bus.wps.cn/sign_in/v1/encrypt/key', headers=headers) - json_data = response.json() - if json_data['code'] == 1000000: - logger.success(f'[用户{self.user_id}] 获取加密密钥成功') - return json_data['data'] - logger.error(f'[用户{self.user_id}] 获取加密密钥失败:{json_data["msg"]}') - return None - - # WPS任务中心-签到 - def sign_in(self, encryptData): - data = { - 'encryptData': encryptData, - 'userId': self.user_id, - } - resp = self.rr.post('https://py.leishennb.icu/v1/rnl-2-gather/get-wps-publickey', json=data).json() - params_obj = resp['data'] - headers = { - 'accept': 'application/json, text/plain, */*', - 'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6', - 'content-type': 'application/json', - 'origin': 'https://personal-act.wps.cn', - 'priority': 'u=1, i', - 'referer': 'https://personal-act.wps.cn/', - 'sec-ch-ua': '"Chromium";v="134", "Not:A-Brand";v="24", "Microsoft Edge";v="134"', - 'sec-ch-ua-mobile': '?0', - 'sec-ch-ua-platform': '"Windows"', - 'sec-fetch-dest': 'empty', - 'sec-fetch-mode': 'cors', - 'sec-fetch-site': 'same-site', - 'token': params_obj['token'], - } - json_data = params_obj['data'] - response = self.rr.post('https://personal-bus.wps.cn/sign_in/v1/sign_in', headers=headers, - json=json_data) - json_data = response.json() - if json_data.get('code') == 1000000: - rewards = json_data['data']['rewards'][0] - sign_msg = f"任务中心签到成功:{rewards['reward_name']}" - logger.success(f'[用户{self.user_id}] {sign_msg}') - self.operation_logs.append(sign_msg) - return True - if 'has sign' in json_data.get('msg'): - sign_msg = '今天已签到' - logger.info(f'[用户{self.user_id}] {sign_msg}') - self.operation_logs.append(sign_msg) - return True - sign_msg = f'任务中心签到失败:{json_data.get("msg", "未知错误")}' - logger.error(f'[用户{self.user_id}] {sign_msg}') - self.operation_logs.append(sign_msg) - return None - - # WPS任务中心-通用完成任务 - def common_component_action(self, task_id, title, component_action=None): - headers = { - 'accept': 'application/json, text/plain, */*', - 'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6', - 'content-type': 'application/json', - 'origin': 'https://personal-act.wps.cn', - 'priority': 'u=1, i', - 'referer': 'https://personal-act.wps.cn/rubik2/portal/HD2025031821201822/YM2025040908558269?cs_from=web_vipcenter_banner_inpublic&mk_key=4b9deqIfqNO3KCZrgH17WPH1kdzMoKUEvya&position=pc_aty_ban3_kaixue_test_b', - 'sec-ch-ua': '"Chromium";v="134", "Not:A-Brand";v="24", "Microsoft Edge";v="134"', - 'sec-ch-ua-mobile': '?0', - 'sec-ch-ua-platform': '"Windows"', - 'sec-fetch-dest': 'empty', - 'sec-fetch-mode': 'cors', - 'sec-fetch-site': 'same-origin', - 'user-agent': self.userAgent, - 'x-act-csrf-token': self.act_csrf_token, - } - json_data = { - 'component_uniq_number': { - 'activity_number': 'HD2025031821201822', - 'page_number': 'YM2025040908558269', - 'component_number': 'ZJ2025040709458367', - 'component_node_id': 'FN1744160180RthG', - 'filter_params': { - 'cs_from': 'web_vipcenter_banner_inpublic', - 'mk_key': '4b9deqIfqNO3KCZrgH17WPH1kdzMoKUEvya', - 'position': 'pc_aty_ban3_kaixue_test_b', - }, - }, - 'component_type': 35, - 'component_action': component_action or self.de['FINISH'], - 'task_center': { - 'task_id': task_id, - }, - } - try: - response = self.rr.post( - 'https://personal-act.wps.cn/activity-rubik/activity/component_action', - headers=headers, - json=json_data, - ).json() - if response['result'] == 'ok': - task_center = response['data']['task_center'] - if task_center['success']: - task_msg = f'完成任务 [{title}] 成功' - logger.success(f'[用户{self.user_id}] {task_msg}') - # self.operation_logs.append(task_msg) - return task_center.get('token') or True - task_msg = f'完成任务 [{title}] 失败:{task_center["reason"]}' - logger.error(f'[用户{self.user_id}] {task_msg}') - self.operation_logs.append(task_msg) - return False - task_msg = f'完成任务 [{title}] 失败:{response}' - logger.error(f'[用户{self.user_id}] {task_msg}') - self.operation_logs.append(task_msg) - return False - except Exception as e: - task_msg = f'完成任务 [{title}] 异常:{str(e)}' - logger.error(f'[用户{self.user_id}] {task_msg}') - self.operation_logs.append(task_msg) - return False - - # WPS任务中心-通用领取奖励 - def common_reward_component_action(self, task_id, title): - headers = { - 'accept': 'application/json, text/plain, */*', - 'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6', - 'content-type': 'application/json', - 'origin': 'https://personal-act.wps.cn', - 'priority': 'u=1, i', - 'referer': 'https://personal-act.wps.cn/rubik2/portal/HD2025031821201822/YM2025040908558269?cs_from=web_vipcenter_banner_inpublic&mk_key=4b9deqIfqNO3KCZrgH17WPH1kdzMoKUEvya&position=pc_aty_ban3_kaixue_test_b', - 'sec-ch-ua': '"Chromium";v="134", "Not:A-Brand";v="24", "Microsoft Edge";v="134"', - 'sec-ch-ua-mobile': '?0', - 'sec-ch-ua-platform': '"Windows"', - 'sec-fetch-dest': 'empty', - 'sec-fetch-mode': 'cors', - 'sec-fetch-site': 'same-origin', - 'x-act-csrf-token': self.act_csrf_token, - } - json_data = { - 'component_uniq_number': { - 'activity_number': 'HD2025031821201822', - 'page_number': 'YM2025040908558269', - 'component_number': 'ZJ2025040709458367', - 'component_node_id': 'FN1744160180RthG', - 'filter_params': { - 'cs_from': 'web_vipcenter_banner_inpublic', - 'mk_key': '4b9deqIfqNO3KCZrgH17WPH1kdzMoKUEvya', - 'position': 'pc_aty_ban3_kaixue_test_b', - }, - }, - 'component_type': 35, - 'component_action': self.de['REWARD'], - 'task_center': { - 'task_id': task_id, - }, - } - try: - response = self.rr.post( - 'https://personal-act.wps.cn/activity-rubik/activity/component_action', - headers=headers, - json=json_data, - ).json() - if response['result'] == 'ok': - task_center = response['data']['task_center'] - if task_center['success']: - reward_msg = f'领取 [{title}] 奖励成功' - logger.success(f'[用户{self.user_id}] {reward_msg}') - self.operation_logs.append(reward_msg) - return True - reward_msg = f'领取 [{title}] 奖励失败:{task_center["reason"]}' - logger.error(f'[用户{self.user_id}] {reward_msg}') - self.operation_logs.append(reward_msg) - return False - reward_msg = f'领取 [{title}] 奖励失败:{response}' - logger.error(f'[用户{self.user_id}] {reward_msg}') - self.operation_logs.append(reward_msg) - return False - except Exception as e: - reward_msg = f'领取 [{title}] 奖励异常:{str(e)}' - logger.error(f'[用户{self.user_id}] {reward_msg}') - self.operation_logs.append(reward_msg) - return False - - # WPS任务中心-任务详情 - def task_info(self, token): - headers = { - 'accept': 'application/json, text/plain, */*', - 'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6', - 'priority': 'u=1, i', - 'referer': 'https://personal-act.wps.cn/rubik2/portal/HD2025091109421588/YM2025091121369865?cs_from=android_ucsty_rwzx&positon=ad_rwzx_task', - 'sec-ch-ua': '"Chromium";v="134", "Not:A-Brand";v="24", "Microsoft Edge";v="134"', - 'sec-ch-ua-mobile': '?0', - 'sec-ch-ua-platform': '"Windows"', - 'sec-fetch-dest': 'empty', - 'sec-fetch-mode': 'cors', - 'sec-fetch-site': 'same-origin', - 'user-agent': self.userAgent, - } - start_time = int(time.time()*1000) - params = { - 'batch_tag': start_time, - 'token': token, - } - try: - response = self.rr.get( - 'https://personal-act.wps.cn/activity-rubik/user/task_center/task_info', - params=params, - headers=headers, - ).json() - if response.get('result') == 'ok': - return start_time + response['data']['start_at'] - logger.error(response) - return None - except Exception as e: - logger.error(str(e)) - return None - - # WPS任务中心-抽奖handle - def lottery_process(self, task_list): - if not task_list: - return - for task in task_list: - task_id = task['task_id'] - title = task['title'] - task_status = task['task_status'] - if task_status == 2: - logger.info(f'[用户{self.user_id}] 任务 [{title}] 已完成') - continue - if '浏览' in title: - token = self.common_component_action(task_id=task_id, title=title, - component_action=self.de['START_TASK']) - if token: - batch_tag = self.task_info(token=token) - if not batch_tag: - logger.error('获取浏览任务信息失败,跳过') - continue - Utils.r_sleep(10, 11) - is_done1 = self.task_finish(token=token, title=title, batch_tag=batch_tag) - if is_done1: - Utils.r_sleep(1) - self.common_reward_component_action(task_id=task_id, title=title) - Utils.r_sleep(1) - continue - skip_keywords = ['认证', '上喜马拉雅', '消费', '邀请', '微博', '苏宁易购', '开通会员'] - if any(keyword in title for keyword in skip_keywords): - logger.info(f'[用户{self.user_id}] 跳过任务 [{title}]') - continue - is_done = self.common_component_action(task_id=task_id, title=title) - if is_done: - Utils.r_sleep(1) - self.common_reward_component_action(task_id=task_id, title=title) - Utils.r_sleep(1) - - # 天天领福利-任务完成 浏览任务 - def task_finish(self, token, title, batch_tag): - headers = { - 'User-Agent': self.userAgent, - 'Accept': 'application/json, text/plain, */*', - # 'Accept-Encoding': 'gzip, deflate, br, zstd', - 'Content-Type': 'application/json', - 'sec-ch-ua-platform': '"Windows"', - 'sec-ch-ua': '"Google Chrome";v="129", "Not=A?Brand";v="8", "Chromium";v="129"', - 'sec-ch-ua-mobile': '?0', - 'origin': 'https://personal-act.wps.cn', - 'sec-fetch-site': 'same-origin', - 'sec-fetch-mode': 'cors', - 'sec-fetch-dest': 'empty', - 'referer': 'https://personal-act.wps.cn/rubik2/portal/HD2025031721339450/YM2025031721331326?cs_from=ad_ucsty_rwzx&position=ad_ucsty_rwzx', - 'accept-language': 'zh-CN,zh;q=0.9', - 'priority': 'u=1, i', - } - json_data = { - 'batch_tag': batch_tag, - 'token': token, - } - try: - response = self.rr.post( - 'https://personal-act.wps.cn/activity-rubik/user/task_center/task_finish', - headers=headers, - json=json_data, - ).json() - if response.get('result') == 'ok': - reward_msg = f'完成任务 [{title}] 成功' - logger.success(f'[用户{self.user_id}] {reward_msg}') - self.operation_logs.append(reward_msg) - return True - reward_msg = f'任务 {title} 完成失败:{response}' - logger.error(f'[用户{self.user_id}] {reward_msg}') - self.operation_logs.append(reward_msg) - return False - except Exception as e: - reward_msg = f'任务 {title} 完成失败:{str(e)}' - logger.error(f'[用户{self.user_id}] {reward_msg}') - self.operation_logs.append(reward_msg) - return False - - # 天天领福利-签到 - def fragment_collect_sign_in(self): - headers = { - 'accept': 'application/json, text/plain, */*', - 'accept-language': 'zh-CN,zh;q=0.9', - 'cache-control': 'no-cache', - 'content-type': 'application/json', - 'origin': 'https://personal-act.wps.cn', - 'pragma': 'no-cache', - 'priority': 'u=1, i', - 'referer': 'https://personal-act.wps.cn/rubik2/portal/HD2025031721339450/YM2025031721331326?cs_from=ad_ucsty_rwzx&position=ad_ucsty_rwzx', - 'sec-ch-ua': '"Google Chrome";v="129", "Not=A?Brand";v="8", "Chromium";v="129"', - 'sec-ch-ua-mobile': '?0', - 'sec-ch-ua-platform': '"Windows"', - 'sec-fetch-dest': 'empty', - 'sec-fetch-mode': 'cors', - 'sec-fetch-site': 'same-origin', - 'x-act-csrf-token': self.act_csrf_token, - } - sign_date = datetime.now().strftime("%Y-%m-%d") - json_data = { - 'component_uniq_number': { - 'activity_number': 'HD2025031721339450', - 'page_number': 'YM2025031721331326', - 'component_number': 'ZJ2025061815363325', - 'component_node_id': 'FN1750234948dBVL', - 'filter_params': { - 'cs_from': 'ad_ucsty_rwzx', - 'position': 'ad_ucsty_rwzx', - }, - }, - 'component_type': 42, - 'component_action': 'fragment_collect.sign_in', - 'fragment_collect': { - 'sign_date': sign_date, - 'series_id': '', - 'is_new_sign_series': True, - }, - } - try: - response = self.rr.post( - 'https://personal-act.wps.cn/activity-rubik/activity/component_action', - headers=headers, - json=json_data, - ) - json_data = response.json() - if json_data.get('result') == 'ok': - success = json_data['data']['fragment_collect']['success'] - rewards = json_data['data']['fragment_collect']['reason'] - if success: - sign_msg = f"天天领福利签到成功:{rewards}" - logger.success(f'[用户{self.user_id}] {sign_msg}') - self.operation_logs.append(sign_msg) - return True - sign_msg = f"天天领福利签到失败:{rewards}" - logger.error(f'[用户{self.user_id}] {sign_msg}') - self.operation_logs.append(sign_msg) - return False - _msg = json_data.get('msg') - if 'Duplicate entry' in _msg: - sign_msg = f"天天领福利-今日已签到" - else: - sign_msg = f"天天领福利签到失败:{_msg}" - logger.error(f'[用户{self.user_id}] {sign_msg}') - self.operation_logs.append(sign_msg) - return False - except Exception as e: - logger.error(str(e)) - sign_msg = f"天天领福利签到失败:{str(e)}" - self.operation_logs.append(sign_msg) - return False - - # 天天领福利-抽奖 - def lottery_v22(self): - headers = { - 'accept': 'application/json, text/plain, */*', - 'accept-language': 'zh-CN,zh;q=0.9', - 'cache-control': 'no-cache', - 'content-type': 'application/json', - 'origin': 'https://personal-act.wps.cn', - 'pragma': 'no-cache', - 'priority': 'u=1, i', - 'referer': 'https://personal-act.wps.cn/rubik2/portal/HD2025031721339450/YM2025031721331326?cs_from=ad_ucsty_rwzx&position=ad_ucsty_rwzx', - 'sec-ch-ua': '"Google Chrome";v="129", "Not=A?Brand";v="8", "Chromium";v="129"', - 'sec-ch-ua-mobile': '?0', - 'sec-ch-ua-platform': '"Windows"', - 'sec-fetch-dest': 'empty', - 'sec-fetch-mode': 'cors', - 'sec-fetch-site': 'same-origin', - 'x-act-csrf-token': self.act_csrf_token, - } - json_data = { - 'component_uniq_number': { - 'activity_number': 'HD2025031721339450', - 'page_number': 'YM2025031721331326', - 'component_number': 'ZJ2025092916515917', - 'component_node_id': 'FN1761875116m2x8', - 'filter_params': { - 'cs_from': 'ad_ucsty_rwzx', - 'position': 'ad_ucsty_rwzx', - }, - }, - 'component_type': 45, - 'component_action': 'lottery_v2.exec', - 'lottery_v2': { - 'session_id': 3001, - }, - } - try: - response = self.rr.post( - 'https://personal-act.wps.cn/activity-rubik/activity/component_action', - headers=headers, - json=json_data, - ) - json_data = response.json() - if json_data['result'] == 'ok': - reward_name = json_data['data']['lottery_v2']['reward_name'] - lottery_msg = f"天天领福利抽奖成功:{reward_name}" - logger.success(f'[用户{self.user_id}] {lottery_msg}') - self.operation_logs.append(lottery_msg) - return True - lottery_msg = f'天天领福利抽奖失败:{json_data.get("msg", "未知错误")}' - logger.error(f'[用户{self.user_id}] {lottery_msg}') - self.operation_logs.append(lottery_msg) - return None - except Exception as e: - lottery_msg = f'天天领福利抽奖异常:{str(e)}' - logger.error(f'[用户{self.user_id}] {lottery_msg}') - self.operation_logs.append(lottery_msg) - return False - - # WPS任务中心-抽奖 - def lottery_v2(self): - headers = { - 'sec-ch-ua-platform': '"Windows"', - 'Referer': 'https://personal-act.wps.cn/rubik2/portal/HD2025031821201822/YM2025040908558269?cs_from=web_vipcenter_banner_inpublic&mk_key=4b9deqIfqNO3KCZrgH17WPH1kdzMoKUEvya&position=pc_aty_ban3_kaixue_test_b', - 'sec-ch-ua': '"Chromium";v="134", "Not:A-Brand";v="24", "Microsoft Edge";v="134"', - 'sec-ch-ua-mobile': '?0', - 'User-Agent': self.userAgent, - 'Accept': 'application/json, text/plain, */*', - 'Content-Type': 'application/json', - 'X-Act-Csrf-Token': self.act_csrf_token, - } - json_data = { - 'component_uniq_number': { - 'activity_number': 'HD2025031821201822', - 'page_number': 'YM2025040908558269', - 'component_number': 'ZJ2025092916516585', - 'component_node_id': 'FN1762345949vdR1', - 'filter_params': { - 'cs_from': 'web_vipcenter_banner_inpublic', - 'mk_key': '4b9deqIfqNO3KCZrgH17WPH1kdzMoKUEvya', - 'position': 'pc_aty_ban3_kaixue_test_b', - }, - }, - 'component_type': 45, - 'component_action': 'lottery_v2.exec', - 'lottery_v2': { - 'session_id': 2, - }, - } - try: - response = self.rr.post('https://personal-act.wps.cn/activity-rubik/activity/component_action', - headers=headers, json=json_data) - json_data = response.json() - if json_data['result'] == 'ok': - reward_name = json_data['data']['lottery_v2']['reward_name'] - lottery_msg = f"抽奖成功:{reward_name}" - logger.success(f'[用户{self.user_id}] {lottery_msg}') - self.operation_logs.append(lottery_msg) - return True - lottery_msg = f'抽奖失败:{json_data.get("msg", "未知错误")}' - logger.error(f'[用户{self.user_id}] {lottery_msg}') - self.operation_logs.append(lottery_msg) - return None - except Exception as e: - lottery_msg = f'抽奖异常:{str(e)}' - logger.error(f'[用户{self.user_id}] {lottery_msg}') - self.operation_logs.append(lottery_msg) - return False - - # WPS任务中心-活动信息 - # https://personal-act.wps.cn/rubik2/portal/HD2025031821201822/YM2025040908558269?cs_from=web_vipcenter_banner_inpublic&mk_key=4b9deqIfqNO3KCZrgH17WPH1kdzMoKUEvya&position=pc_aty_ban3_kaixue_test_b - def page_info(self): - headers = { - 'accept': 'application/json, text/plain, */*', - 'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6', - 'priority': 'u=1, i', - 'referer': 'https://personal-act.wps.cn/rubik2/portal/HD2025031821201822/YM2025040908558269?cs_from=web_vipcenter_banner_inpublic&mk_key=4b9deqIfqNO3KCZrgH17WPH1kdzMoKUEvya&position=pc_aty_ban3_kaixue_test_b', - 'sec-ch-ua': '"Chromium";v="134", "Not:A-Brand";v="24", "Microsoft Edge";v="134"', - 'sec-ch-ua-mobile': '?0', - 'sec-ch-ua-platform': '"Windows"', - 'sec-fetch-dest': 'empty', - 'sec-fetch-mode': 'cors', - 'sec-fetch-site': 'same-origin', - 'user-agent': self.userAgent, - } - try: - # page_number=YM2025031821202008 - response = self.rr.get( - 'https://personal-act.wps.cn/activity-rubik/activity/page_info?activity_number=HD2025031821201822&page_number=YM2025040908558269&filter_params=%7B%22cs_from%22:%22web_vipcenter_banner_inpublic%22,%22mk_key%22:%224b9deqIfqNO3KCZrgH17WPH1kdzMoKUEvya%22,%22position%22:%22pc_aty_ban3_kaixue_test_b%22%7D', - headers=headers, - ).json() - if response['result'] == 'ok': - lottery_times = None - user_integral = None - task_list = None - - for item in response["data"]: - if lottery_times is None: - if item.get("type") == 45 and item.get("lottery_v2"): - for session in item["lottery_v2"].get("lottery_list", []): - if session.get("session_id") == 2: - lottery_times = session.get("times") - continue - if user_integral is None: - if item.get("task_center_user_info"): - user_integral = item["task_center_user_info"].get("integral") - elif item.get("integral_waterfall"): - user_integral = item["integral_waterfall"].get("user_integral") - if task_list is None: - if item.get("task_center"): - task_list = item["task_center"].get("task_list") - if lottery_times and user_integral and task_list: - break - logger.info(f'[用户{self.user_id}] 积分:{user_integral},抽奖次数:{lottery_times}') - return { - "lottery_times": lottery_times, - "user_integral": user_integral, - "task_list": task_list - } - except Exception as e: - logger.error(f'[用户{self.user_id}] 获取用户信息异常:{str(e)}') - return None - - # 办公助手-活动信息 - # https://personal-act.wps.cn/rubik2/portal/HD2025031010408781/YM2025061216463517?cs_from=xinchao_activity_lottery&position=xinchao_bgzs_autoreply_2148_cj - def page_info2(self): - headers = { - 'accept': 'application/json, text/plain, */*', - 'accept-language': 'zh-CN,zh;q=0.9', - 'cache-control': 'no-cache', - 'pragma': 'no-cache', - 'priority': 'u=1, i', - 'referer': 'https://personal-act.wps.cn/rubik2/portal/HD2025031010408781/YM2025061216463517?cs_from=xinchao_activity_lottery&position=xinchao_bgzs_autoreply_2148_cj', - 'sec-ch-ua': '"Google Chrome";v="129", "Not=A?Brand";v="8", "Chromium";v="129"', - 'sec-ch-ua-mobile': '?0', - 'sec-ch-ua-platform': '"Windows"', - 'sec-fetch-dest': 'empty', - 'sec-fetch-mode': 'cors', - 'sec-fetch-site': 'same-origin', - } - try: - response = self.rr.get( - 'https://personal-act.wps.cn/activity-rubik/activity/page_info?activity_number=HD2025031010408781&page_number=YM2025061216463517&filter_params=%7B%22cs_from%22:%22xinchao_activity_lottery%22,%22position%22:%22xinchao_bgzs_autoreply_2148_cj%22%7D', - headers=headers, - ).json() - task_list = None - lottery_times = None - # 遍历data数组,定位包含task_center的元素 - for item in response["data"]: - if "task_center" in item and "task_list" in item["task_center"]: - task_list = item["task_center"]["task_list"] - if "lottery" in item and item["lottery"]: - lottery = item["lottery"] - if "rewards" in lottery and isinstance(lottery["rewards"], list) and len(lottery["rewards"]) > 0: - first_reward = lottery["rewards"][0] - if "times" in first_reward: - lottery_times = first_reward["times"] - if lottery_times != None and task_list != None: - break - return { - 'task_list': task_list, - 'lottery_times': lottery_times - } - except Exception as e: - logger.error(str(e)) - return None - - # 福利中心-活动信息 - def page_info3(self): - headers = { - 'accept': 'application/json, text/plain, */*', - 'accept-language': 'zh-CN,zh;q=0.9', - 'cache-control': 'no-cache', - 'pragma': 'no-cache', - 'priority': 'u=1, i', - 'referer': 'https://personal-act.wps.cn/rubik2/portal/HD2025031721339450/YM2025031721331326?cs_from=ad_ucsty_rwzx&position=ad_ucsty_rwzx', - 'sec-ch-ua': '"Google Chrome";v="129", "Not=A?Brand";v="8", "Chromium";v="129"', - 'sec-ch-ua-mobile': '?0', - 'sec-ch-ua-platform': '"Windows"', - 'sec-fetch-dest': 'empty', - 'sec-fetch-mode': 'cors', - 'sec-fetch-site': 'same-origin', - } - try: - response = self.rr.get( - 'https://personal-act.wps.cn/activity-rubik/activity/page_info?activity_number=HD2025031721339450&page_number=YM2025031721331326&filter_params=%7B%22cs_from%22:%22ad_ucsty_rwzx%22,%22position%22:%22ad_ucsty_rwzx%22%7D', - headers=headers, - ).json() - if response['result'] == 'ok': - lottery_times = None - for item in response["data"]: - if item.get("lottery_v2"): - for session in item["lottery_v2"].get("lottery_list", []): - if session.get("times"): - lottery_times = session.get("times") - break - return { - "lottery_times": lottery_times, - } - except Exception as e: - logger.error(f'[用户{self.user_id}] 获取用户信息异常:{str(e)}') - return None - - # 办公助手-领取 - def components_action2(self, task_id, title): - headers = { - 'accept': 'application/json, text/plain, */*', - 'accept-language': 'zh-CN,zh;q=0.9', - 'cache-control': 'no-cache', - 'content-type': 'application/json', - 'origin': 'https://personal-act.wps.cn', - 'pragma': 'no-cache', - 'priority': 'u=1, i', - 'referer': 'https://personal-act.wps.cn/rubik2/portal/HD2025031010408781/YM2025061216463517?cs_from=xinchao_activity_lottery&position=xinchao_bgzs_autoreply_2148_cj', - 'sec-ch-ua': '"Google Chrome";v="129", "Not=A?Brand";v="8", "Chromium";v="129"', - 'sec-ch-ua-mobile': '?0', - 'sec-ch-ua-platform': '"Windows"', - 'sec-fetch-dest': 'empty', - 'sec-fetch-mode': 'cors', - 'sec-fetch-site': 'same-origin', - } - json_data = { - 'component_uniq_number': { - 'activity_number': 'HD2025031010408781', - 'page_number': 'YM2025061216463517', - 'component_number': 'ZJ2024083022083755', - 'component_node_id': 'FN1740387182DaYX', - }, - 'component_type': 14, - 'component_action': self.de['REWARD'], - 'task_center': { - 'task_id': task_id, - }, - } - try: - response = self.rr.post( - 'https://personal-act.wps.cn/activity-rubik/activity/component_action', - headers=headers, - json=json_data, - ).json() - if response['result'] == 'ok': - task_center = response['data']['task_center'] - if task_center['success']: - reward_msg = f'领取 [{title}] 奖励成功' - logger.success(f'[用户{self.user_id}] {reward_msg}') - self.operation_logs.append(reward_msg) - return True - reward_msg = f'领取 [{title}] 奖励失败:{task_center["reason"]}' - logger.error(f'[用户{self.user_id}] {reward_msg}') - self.operation_logs.append(reward_msg) - return False - reward_msg = f'领取 [{title}] 奖励失败:{response}' - logger.error(f'[用户{self.user_id}] {reward_msg}') - self.operation_logs.append(reward_msg) - return False - except Exception as e: - reward_msg = f'领取 [{title}] 奖励异常:{str(e)}' - logger.error(f'[用户{self.user_id}] {reward_msg}') - self.operation_logs.append(reward_msg) - return False - - # 办公助手-抽奖 - def lottery_exec(self): - headers = { - 'accept': 'application/json, text/plain, */*', - 'accept-language': 'zh-CN,zh;q=0.9', - 'cache-control': 'no-cache', - 'content-type': 'application/json', - 'origin': 'https://personal-act.wps.cn', - 'pragma': 'no-cache', - 'priority': 'u=1, i', - 'referer': 'https://personal-act.wps.cn/rubik2/portal/HD2025031010408781/YM2025061216463517?cs_from=xinchao_activity_lottery&position=xinchao_bgzs_autoreply_2148_cj', - 'sec-ch-ua': '"Google Chrome";v="129", "Not=A?Brand";v="8", "Chromium";v="129"', - 'sec-ch-ua-mobile': '?0', - 'sec-ch-ua-platform': '"Windows"', - 'sec-fetch-dest': 'empty', - 'sec-fetch-mode': 'cors', - 'sec-fetch-site': 'same-origin', - } - json_data = { - 'component_uniq_number': { - 'activity_number': 'HD2025031010408781', - 'page_number': 'YM2025061216463517', - 'component_number': 'ZJ2024083022081230', - 'component_node_id': 'FN1741940010rC4c', - }, - 'component_type': 2, - 'component_action': 'lottery.exec', - 'lottery': { - 'pay_source': '', - 'integral_source': '', - 'position': 'bgzs_tasks_cj', - 'source': '', - 'ids': '1115,1119,1116,1117,1120,1121,1122,1118', - 'sign': '', - }, - } - try: - response = self.rr.post( - 'https://personal-act.wps.cn/activity-rubik/activity/component_action', - headers=headers, - json=json_data, - ) - json_data = response.json() - if json_data['result'] == 'ok': - reward_name = json_data['data']['lottery']['name'] - lottery_msg = f"抽奖成功:{reward_name}" - logger.success(f'[用户{self.user_id}] {lottery_msg}') - self.operation_logs.append(lottery_msg) - return True - lottery_msg = f'抽奖失败:{json_data.get("msg", "未知错误")}' - logger.error(f'[用户{self.user_id}] {lottery_msg}') - self.operation_logs.append(lottery_msg) - return None - except Exception as e: - lottery_msg = f'抽奖异常:{str(e)}' - logger.error(f'[用户{self.user_id}] {lottery_msg}') - self.operation_logs.append(lottery_msg) - return False - - # 办公助手-执行 - def done_task2_handler(self, task_list2, first_task=False): - for t2 in task_list2: - task_id = t2["task_id"] - title = t2["title"] - task_status = t2['task_status'] - if task_status == 1: - logger.info(f'[用户{self.user_id}] 任务 [{title}] 已完成') - continue - if first_task: - if '每日访问当前活动' in title: - self.components_action2(task_id=task_id, title=title) - Utils.r_sleep(2) - return - else: - if '每日访问当前活动' in title: - continue - self.components_action2(task_id=task_id, title=title) - Utils.r_sleep(2) - - # applet-wps超级会员签到 - def applet_sign(self): - s_key = '06196ab4da15c09a3aaee610162ca56f' - try: - clock_info = self.rr.get('https://personal-bus.wps.cn/activity/clock_in/v1/info').json() - s_key = clock_info.get('data',{}).get('s_key') - except Exception as e: - logger.error(str(e)) - ss = '7908b285f33c837d' - json_data = { - 'client_type': 1, - } - # 别动,签名算法不能用,固定即可 - signature = generate_sign(json_data, s_key, ss) - headers = { - 'Host': 'personal-bus.wps.cn', - 'Connection': 'keep-alive', - # 'Content-Length': '17', - 'date': 'Tue, 20 Jan 2026 14:42:58 GMT', - 'charset': 'utf-8', - 'signature': '0d8ff00f5c74de36d0b2e677c82b22a1dd5ab196b0d227cc875fb051eec50156', - 'x-csrftoken': '1234567890', - 'User-Agent': 'Mozilla/5.0 (Linux; Android 14; 23117RK66C Build/UKQ1.230804.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/142.0.7444.173 Mobile Safari/537.36 XWEB/1420153 MMWEBSDK/20240404 MMWEBID/3531 MicroMessenger/8.0.49.2600(0x2800313D) WeChat/arm64 Weixin Android Tablet NetType/WIFI Language/zh_CN ABI/arm64 MiniProgramEnv/android', - 'content-type': 'application/json', - # 'Accept-Encoding': 'gzip,compress,br,deflate', - 'Referer': 'https://servicewechat.com/wx2f333d84a103825d/240/page-frame.html', - } - try: - response = self.rr.post( - 'https://personal-bus.wps.cn/activity/clock_in/v1/clock_in', - headers=headers, - json=json_data, - ).json() - if response['result'] == 'ok': - lottery_msg = f"小程序签到成功" - logger.success(f'[用户{self.user_id}] {lottery_msg}') - self.operation_logs.append(lottery_msg) - return True - if 'already clocked in today' in response.get("msg", "未知错误"): - lottery_msg = f'小程序签到失败:今日已签到' - else: - lottery_msg = f'小程序签到失败:{response.get("msg", "未知错误")}' - logger.error(f'[用户{self.user_id}] {lottery_msg}') - self.operation_logs.append(lottery_msg) - return None - except Exception as e: - lottery_msg = f'小程序签到异常:{str(e)}' - logger.error(f'[用户{self.user_id}] {lottery_msg}') - self.operation_logs.append(lottery_msg) - return False - - # WPS挑战计划-任务完成or领取 - def challenge_component_action(self, title, task_id, component_action=None, action_name=None): - component_action = component_action or self.de['FINISH'] - if not action_name: - if self.de['FINISH'] == component_action: - action_name = '完成' - elif self.de['REWARD'] == component_action: - action_name = '领取' - headers = { - 'accept': 'application/json, text/plain, */*', - 'accept-language': 'zh-CN,zh;q=0.9', - 'content-type': 'application/json', - 'origin': 'https://personal-act.wps.cn', - 'priority': 'u=1, i', - 'referer': 'https://personal-act.wps.cn/rubik2/portal/HD2025121517384715/YM2025121517381164?cs_from=pc_ucsty_rwzx_task&position=pc_rwzx_task', - 'sec-ch-ua': '"Google Chrome";v="129", "Not=A?Brand";v="8", "Chromium";v="129"', - 'sec-ch-ua-mobile': '?0', - 'sec-ch-ua-platform': '"Windows"', - 'sec-fetch-dest': 'empty', - 'sec-fetch-mode': 'cors', - 'sec-fetch-site': 'same-origin', - 'user-agent': self.userAgent, - 'x-act-csrf-token': self.act_csrf_token, - } - json_data = { - 'component_uniq_number': { - 'activity_number': 'HD2025121517384715', - 'page_number': 'YM2025121517381164', - 'component_number': 'ZJ2025031817022062', - 'component_node_id': 'FN17642133971jKe', - 'filter_params': { - 'cs_from': 'pc_ucsty_rwzx_task', - 'position': 'pc_rwzx_task', - }, - }, - 'component_type': 35, - 'component_action': component_action, - 'task_center': { - 'task_id': task_id, - }, - } - try: - response = self.rr.post( - 'https://personal-act.wps.cn/activity-rubik/activity/component_action', - headers=headers, - json=json_data, - ).json() - if response['result'] == 'ok': - task_center = response['data']['task_center'] - if task_center['success']: - task_msg = f'{action_name}任务 [{title}] 成功' - logger.success(f'[用户{self.user_id}] {task_msg}') - if action_name == '领取': - self.operation_logs.append(task_msg) - return task_center.get('token') or True - task_msg = f'{action_name}任务 [{title}] 失败:{task_center["reason"]}' - logger.error(f'[用户{self.user_id}] {task_msg}') - self.operation_logs.append(task_msg) - return False - task_msg = f'{action_name}任务 [{title}] 失败:{response}' - logger.error(f'[用户{self.user_id}] {task_msg}') - self.operation_logs.append(task_msg) - return False - except Exception as e: - task_msg = f'{action_name}任务 [{title}] 异常:{str(e)}' - logger.error(f'[用户{self.user_id}] {task_msg}') - self.operation_logs.append(task_msg) - return False - - # WPS挑战计划-任务信息 - def challenge_page_info(self): - headers = { - 'accept': 'application/json, text/plain, */*', - 'accept-language': 'zh-CN,zh;q=0.9', - 'priority': 'u=1, i', - 'referer': 'https://personal-act.wps.cn/rubik2/portal/HD2025121517384715/YM2025121517381164?cs_from=pc_ucsty_rwzx_task&position=pc_rwzx_task', - 'sec-ch-ua': '"Google Chrome";v="129", "Not=A?Brand";v="8", "Chromium";v="129"', - 'sec-ch-ua-mobile': '?0', - 'sec-ch-ua-platform': '"Windows"', - 'sec-fetch-dest': 'empty', - 'sec-fetch-mode': 'cors', - 'sec-fetch-site': 'same-origin', - 'user-agent': self.userAgent, - } - try: - response = self.rr.get( - 'https://personal-act.wps.cn/activity-rubik/activity/page_info?activity_number=HD2025121517384715&page_number=YM2025121517381164&filter_params=%7B%22cs_from%22:%22pc_ucsty_rwzx_task%22,%22position%22:%22pc_rwzx_task%22%7D', - headers=headers, - ).json() - if response['result'] == 'ok': - lottery_times = None - task_list = None - for item in response["data"]: - if item.get("task_center"): - _task_list = item["task_center"].get("task_list", []) - if _task_list: - task_list = _task_list - if task_list and lottery_times: - break - return { - "task_list": task_list, - "lottery_times": lottery_times, - } - except Exception as e: - logger.error(f'[用户{self.user_id}] 获取WPS挑战计划任务列表异常:{str(e)}') - return None - - # WPS挑战计划-任务执行 - def challenge_exec(self, task_list): - if not task_list: - return - for task in task_list: - task_id = task['task_id'] - title = task['title'] - task_status = task['task_status'] - if task_status == 2: - logger.info(f'[用户{self.user_id}] 任务 [{title}] 已完成') - continue - skip_keywords = ['邀请', 'PDF转换', 'PDF合并', '语音速记', '关注', '认证', '消费', '开通会员'] - if any(keyword in title for keyword in skip_keywords): - logger.info(f'[用户{self.user_id}] 跳过任务 [{title}]') - continue - is_done = self.challenge_component_action(task_id=task_id, title=title, component_action=self.de['FINISH']) - if is_done: - Utils.r_sleep(1) - self.challenge_component_action(task_id=task_id, title=title, component_action=self.de['REWARD']) - Utils.r_sleep(1) - - def main(self): - self.operation_logs = [] - user_id = self.user_id - - # ================ WPS任务中心 ================= - if self.global_config.get('task_center'): - tip = '# 开始执行 WPS任务中心 任务' - self.operation_logs.append(tip) - logger.info(tip) - page_data = self.page_info() - if not page_data: - error_msg = f'[用户{user_id}] 获取用户信息失败:活动结束或cookie过期' - logger.error(error_msg) - self.operation_logs.append(error_msg) - # 返回None和消息 - return None, f'用户ID:{user_id}\n' + '\n'.join(self.operation_logs) - task_list = page_data.get("task_list") or [] - Utils.r_sleep(1) - # 签到 - public_data = self.get_public_key() - if public_data: - self.sign_in(public_data) - else: - self.operation_logs.append(f'[用户{user_id}] 获取签到密钥失败,终止任务') - return None, f'用户ID:{user_id}\n' + '\n'.join(self.operation_logs) - Utils.r_sleep(1) - # 完成领取任务 - self.lottery_process(task_list=task_list) - Utils.r_sleep(1.5) - # 重试 - page_data = self.page_info() - if page_data: - self.lottery_process(task_list=page_data.get("task_list") or []) - Utils.r_sleep(1.5) - page_data = self.page_info() - lottery_times = page_data.get("lottery_times") if page_data else 0 - # 抽奖 - if lottery_times and lottery_times > 0: - logger.info(f'[用户{user_id}] 开始执行抽奖(剩余次数:{lottery_times})') - for i in range(lottery_times): - lottery_result = self.lottery_v2() - if not lottery_result: - logger.info(f'[用户{user_id}] 抽奖第{i+1}次失败,终止抽奖') - break - Utils.r_sleep(1) - logger.info('# 执行完成 WPS任务中心 任务') - - # ============== 天天领福利 ============= - if self.global_config.get('lottery3'): - tip = '# 开始执行 天天领福利 任务' - self.operation_logs.append(tip) - logger.info(tip) - Utils.r_sleep(1) - self.fragment_collect_sign_in() - Utils.r_sleep(1) - page_info3 = self.page_info3() - if page_info3: - lottery_times3 = page_info3.get('lottery_times') or 0 - if lottery_times3 > 0: - for i3 in range(lottery_times3): - lottery_result3 = self.lottery_v22() - if not lottery_result3: - logger.info(f'[用户{user_id}] 抽奖第{i3+1}次失败,终止抽奖') - break - Utils.r_sleep(1) - logger.info('# 执行完成 天天领福利 任务') - - # ============== WPS办公助手(默认关闭) ============= - if self.global_config.get('fragment_collect'): - tip = '# 开始执行 WPS办公助手 任务' - self.operation_logs.append(tip) - logger.info(tip) - page_result = self.page_info2() - if page_result: - task_list2 = page_result.get("task_list") or [] - self.done_task2_handler(task_list2, first_task=True) - self.done_task2_handler(task_list2) - page_result = self.page_info2() - lottery_times = page_result.get("lottery_times") or 0 - Utils.r_sleep(1) - if lottery_times > 0: - for i2 in range(lottery_times): - lottery_result2 = self.lottery_exec() - if not lottery_result2: - logger.info(f'[用户{user_id}] 抽奖第{i2+1}次失败,终止抽奖') - break - Utils.r_sleep(1) - logger.info('# 执行完成 WPS办公助手 任务') - else: - logger.error("WPS办公助手数据异常,跳过") - - # ============== WPS挑战计划 ============= - if self.global_config.get('challenge'): - tip = '# 开始执行 WPS挑战计划 任务' - self.operation_logs.append(tip) - logger.info(tip) - challenge_data = self.challenge_page_info() - if challenge_data: - self.challenge_exec(challenge_data.get('task_list') or []) - - # ============== wps超级会员小程序 ============= - if self.global_config.get('svip_applet'): - tip = '# 开始执行 wps超级会员小程序 任务' - self.operation_logs.append(tip) - logger.info(tip) - self.applet_sign() - logger.info('# 执行完成 wps超级会员小程序 任务') - - # ---------- 构建统计信息 ---------- - stats = { - 'user_id': user_id, - 'task_center_checkin': any('任务中心签到成功' in log or '今天已签到' in log for log in self.operation_logs), - 'fragment_sign': any('天天领福利签到成功' in log for log in self.operation_logs), - 'applet_sign': any('小程序签到成功' in log for log in self.operation_logs), - 'completed_tasks': sum(1 for log in self.operation_logs if '完成任务' in log and '成功' in log), - 'lottery_results': [log for log in self.operation_logs if '抽奖成功' in log], - } - - final_msg = f'用户ID:{user_id}\n' + '\n'.join(self.operation_logs) - return stats, final_msg - - -def print_wps_table(stats_list): - """打印 WPS 单账户明细表格""" - if not stats_list: - return - print("\n" + "=" * 80) - print("📊 单账户明细:") - header = "┌──────┬──────────────┬──────────────┬──────────────┬──────────────┬──────────────┐" - title = "│ 序号 │ 用户ID │ 任务中心签到 │ 天天领福利 │ 小程序签到 │ 完成任务数 │" - split_line = "├──────┼──────────────┼──────────────┼──────────────┼──────────────┼──────────────┤" - footer = "└──────┴──────────────┴──────────────┴──────────────┴──────────────┴──────────────┘" - print(header) - print(title) - print(split_line) - for idx, s in enumerate(stats_list, 1): - uid = str(s.get('user_id', '?'))[:12] - checkin = '✅' if s.get('task_center_checkin') else '❌' - frag = '✅' if s.get('fragment_sign') else '❌' - applet = '✅' if s.get('applet_sign') else '❌' - tasks = s.get('completed_tasks', 0) - line = f"│ {idx:^4} │ {uid:^12} │ {checkin:^12} │ {frag:^12} │ {applet:^12} │ {tasks:^12} │" - print(line) - print(footer) - - # 汇总统计 - total = len(stats_list) - success_count = sum(1 for s in stats_list if s.get('task_center_checkin') or s.get('fragment_sign') or s.get('applet_sign')) - print("\n📊 账号汇总:") - print(f" 总账号: {total}") - print(f" 成功: {success_count} 失败: {total - success_count}") - print("=" * 80) - - -def read_users_from_env(): - users_env = os.getenv('WPS_TASK_CK', '') - users = [] - for line in users_env.strip().split('\n'): - if line.strip(): - parts = line.split('#') - if len(parts) >= 2: - user_info = { - 'username': parts[0].strip(), - 'cookie': parts[1].strip(), - } - users.append(user_info) - return users - - -if __name__ == "__main__": - users = read_users_from_env() - if not users: - print("未配置用户信息,请设置 WPS_TASK_CK 环境变量,格式:备注#cookie") - exit(1) - - print(f"共读取到 {len(users)} 个用户") - logger.info('随机等待30-600s') - Utils.r_sleep(30, 600) - - rnlProxy = None - if RnlProxy: - rnlProxy = RnlProxy() - - all_stats = [] - all_push_msgs = [] - - for i, user in enumerate(users, 1): - proxies = None - if rnlProxy: - proxies = rnlProxy.get_valid_proxy() - print(f'使用代理:{proxies}') - username = user['username'] - cookies = user['cookie'] - print(f"\n===== 正在处理第 {i} 个用户:{username} =====") - - try: - stats, msg = RNL(cookies, proxies=proxies).main() - if stats: - all_stats.append(stats) - all_push_msgs.append(f"【{username}】\n{msg}") - except Exception as e: - error_msg = f"【{username}】处理异常:{str(e)}" - logger.error(error_msg) - all_push_msgs.append(error_msg) - all_stats.append({ - 'user_id': 'error', - 'task_center_checkin': False, - 'fragment_sign': False, - 'applet_sign': False, - 'completed_tasks': 0 - }) - - # 输出表格与汇总 - print_wps_table(all_stats) - - # 推送(捕获异常避免中断) - if rnl_push and all_push_msgs: - try: - push_title = "WPS任务执行结果" - push_content = '\n\n'.join(all_push_msgs) - rnl_push.sendNotify(push_title, push_content) - print(f"\n推送消息已发送:\n{push_content}") - except Exception as e: - logger.error(f"推送消息失败: {e}") - elif not rnl_push: - print("\n推送功能未启用,跳过消息推送") - else: +# cron: 12 8 * * * +# new Env("WPS签到") +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +@File : wps签到任务 +@CreateTime : 2026/01/17 +@UpdateTime : 2026/04/12 +@Author : Rex +@Version : 3.0.2 +@Contact : 2375560790@qq.com +@QQ群 : 621124138 备注妖火 +@License : MIT +@UpdateContent : + 1.适配 任务中心新任务。 + 2.修复 办公助手任务。 + 3.新增 WPS挑战计划。 + 4. 增强错误处理。 +@Desc : + 活动地址: + https://personal-act.wps.cn/rubik2/portal/HD2025031821201822/YM2025040908558269?cs_from=web_vipcenter_banner_inpublic&mk_key=4b9deqIfqNO3KCZrgH17WPH1kdzMoKUEvya&position=pc_aty_ban3_kaixue_test_b + 核心功能: + 1. WPS任务中心:每日签到、自动完成所有任务、自动抽奖 + 2. 办公助手(办公助手 2026.03.16结束):每日签到、自动完成所有任务、自动抽奖 + 3. 天天领福利:每日签到、自动完成所有任务、自动抽奖 + 4. WPS超级会员小程序:签到 + 5. WPS挑战计划:自动完成所有任务、自动抽奖 + 使用: + 1. cookie 抓取这个接口的请求头cookie字段 https://personal-act.wps.cn/activity-rubik/activity/component_action + 2. 青龙配置环境变量 WPS_TASK_CK,格式:备注#cookie,支持多账号,多账号回车换行 + 2. 青龙面板推荐 cron 0 0 7 * * * + 遗留问题: + 1.WPS挑战计划:'PDF转换', 'PDF合并', '语音速记', '关注' 后续开发 + 2.小程序只有签到抽奖等妖友待测 + 3.WPS任务中心 疑似存在新旧任务列表,任务可以多做,暂时未适配 +""" +import os +import sys +import random +import time +from typing import Optional, Dict, Any, Union, Tuple, List +import requests +import urllib3 +from loguru import logger +from requests import Response + +# ------------------------ 模块加载区 -------------------------- +# 1. 获取当前脚本的绝对路径 +current_script = os.path.abspath(__file__) +# 2. 定位根目录(根据实际结构调整层级) +# 假设脚本在根目录的子目录(如 src/)中,根目录是当前脚本目录的上层目录 +root_dir = os.path.dirname(os.path.dirname(current_script)) +# 3. 将根目录添加到模块搜索路径(确保只添加一次) +if root_dir not in sys.path: + sys.path.insert(0, root_dir) # 插入到最前面,优先搜索根目录 +try: + from RnlProxy import RnlProxy +except: + RnlProxy = None + logger.error('未检测到 RnlProxy.py 模块,使用默认ip') +try: + from rnl_push import rnl_push +except: + try: + import notify + if hasattr(notify, 'send'): + notify.sendNotify = notify.send + rnl_push = notify + except: + rnl_push = None + logger.error('未检测到 rnl_push.py、notify.py 模块,不进行消息推送') +# ------------------------ 模块加载区 -------------------------- + +class Utils: + @staticmethod + def r_sleep(s=1.0, e=None): + """随机休眠函数(外部传秒,内部精确到毫秒)""" + try: + s = float(s) + e = float(e) if e is not None else None + except (ValueError, TypeError): + raise ValueError("参数 s/e 必须是可转换为浮点数的数字(秒)") + if e is None: + e = s + 1.0 + if s > e: + s, e = e, s + s = max(s, 0.0) + e = max(e, 0.0) + s_ms = int(round(s * 1000)) + e_ms = int(round(e * 1000)) + sleep_ms = random.randint(s_ms, e_ms) + sleep_sec = sleep_ms / 1000 + time.sleep(sleep_sec) + return round(sleep_sec, 3) + + @staticmethod + def dict_cookie_to_string(cookie_dict): + cookie_list = [] + for key, value in cookie_dict.items(): + cookie_list.append(f"{key}={value}") + return "; ".join(cookie_list) + + @staticmethod + def string_cookie_to_dict(cookie_str): + cookie_dict = {} + if not cookie_str: + return cookie_dict + cookie_pairs = [pair.strip() for pair in cookie_str.split(';') if pair.strip()] + for pair in cookie_pairs: + key_value = pair.split('=', 1) + if len(key_value) == 2: + key, value = key_value + cookie_dict[key.strip()] = value.strip() + else: + cookie_dict[key_value[0].strip()] = "" + return cookie_dict + + +class RnlRequest: + def __init__(self, proxies=None, cookies=None, headers=None): + urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning) + self.session = requests.Session() + self.session.trust_env = False + self.session.verify = False + self.last_response: Optional[Response] = None + if proxies: + self.session.proxies.update(proxies) + self._base_headers = headers or { + 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36', + } + self.update_cookies(cookies) + + @property + def status_code(self) -> Optional[int]: + return self.last_response.status_code if self.last_response else None + + @property + def ok(self) -> bool: + return 200 <= self.status_code < 300 if self.status_code else False + + @property + def json(self) -> Any: + if not self.last_response: + return None + try: + return self.last_response.json() + except (ValueError, TypeError): + return None + + @property + def text(self) -> Optional[str]: + return self.last_response.text if self.last_response else None + + @property + def content(self) -> Optional[bytes]: + return self.last_response.content if self.last_response else None + + @property + def headers(self) -> Optional[Dict[str, str]]: + return dict(self.last_response.headers) if self.last_response else None + + def update_cookies(self, cookies: Union[str, dict, None]) -> None: + if not cookies: + return + if isinstance(cookies, str): + cookies = dict( + item.strip().split('=', 1) + for item in cookies.split(';') + if '=' in item.strip() + ) + elif not isinstance(cookies, dict): + return + self.session.cookies.update(cookies) + + def get_cookies(self) -> Dict[str, str]: + return self.session.cookies.get_dict() + + def update_headers(self, headers: Dict[str, str]) -> None: + self._base_headers.update(headers) + + def raise_for_status(self) -> None: + if self.last_response: + self.last_response.raise_for_status() + + def request(self, method, url, params=None, data=None, json=None, headers=None, + cookies=None, files=None, auth=None, timeout=None, allow_redirects=True, + proxies=None, hooks=None, stream=None, verify=None, cert=None, **kwargs) -> Optional[Response]: + self.last_response = None + request_headers = {**self._base_headers, **(headers or {})} + try: + resp = self.session.request( + method=method.upper(), + url=url, + params=params, + data=data, + json=json, + headers=request_headers, + cookies=cookies, + files=files, + auth=auth, + timeout=timeout, + allow_redirects=allow_redirects, + proxies=proxies, + hooks=hooks, + stream=stream, + verify=verify if verify is not None else self.session.verify, + cert=cert, + **kwargs + ) + self.last_response = resp + return resp + except requests.RequestException as e: + if hasattr(e, 'response') and e.response: + self.last_response = e.response + return e.response + return None + + def get(self, url, **kwargs): + return self.request(method='GET', url=url, **kwargs) + + def post(self, url, **kwargs): + return self.request(method='POST', url=url, **kwargs) + + def __enter__(self): + return self + + def __exit__(self, exc_type, exc_val, exc_tb): + self.session.close() + + +import json +import hashlib +import hmac +from datetime import datetime, timezone + + +def generate_sign(t: dict, i: str, r: str) -> str: + sorted_keys = sorted(t.keys()) + n = {key: t[key] for key in sorted_keys} + p = json.dumps(n, ensure_ascii=False, separators=(',', ':')) + md5_p = hashlib.md5(p.encode('utf-8')).hexdigest() + utc_time = datetime.now(timezone.utc).strftime('%a, %d %b %Y %H:%M:%S GMT') + f = i + md5_p + utc_time + hmac_obj = hmac.new(r.encode('utf-8'), f.encode('utf-8'), hashlib.sha256) + u = hmac_obj.hexdigest() + return u + + +class RNL: + def __init__(self, c, proxies=None): + if isinstance(c, str): + new_c = Utils.string_cookie_to_dict(c) + else: + new_c = c + self.act_csrf_token = new_c.get('act_csrf_token') + self.user_id = new_c.get('uid') + if not self.act_csrf_token or not self.user_id: + logger.error(f'[用户{self.user_id or "未知"}] cookie参数不全(缺少act_csrf_token或uid)') + exit(1) + self.user_id = int(new_c.get('uid')) + self.userAgent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36 Edg/134.0.0.0' + self.rr = RnlRequest(proxies=proxies, cookies=new_c, headers={'User-Agent': self.userAgent}) + self.de = { + 'PROMOTIONAL_MATERIAL': "task_center.promotional_material", + 'START_TASK': "task_center.start", + 'FINISH': "task_center.finish", + 'TOKEN_FINISH': "task_center.token_finish", + 'REWARD': "task_center.reward" + } + self.operation_logs = [] + self.global_config = { + 'task_center': True, # WPS任务中心 + 'fragment_collect': False, # 办公助手 2026.03.16结束 + 'lottery3': True, # 天天领福利 + 'svip_applet': True, # 超级会员applet + 'challenge': True, # WPS挑战计划 + } + + # WPS任务中心-获取签到key + def get_public_key(self): + headers = { + 'accept': 'application/json, text/plain, */*', + 'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6', + 'origin': 'https://personal-act.wps.cn', + 'priority': 'u=1, i', + 'referer': 'https://personal-act.wps.cn/', + 'sec-ch-ua': '"Chromium";v="134", "Not:A-Brand";v="24", "Microsoft Edge";v="134"', + 'sec-ch-ua-mobile': '?0', + 'sec-ch-ua-platform': '"Windows"', + 'sec-fetch-dest': 'empty', + 'sec-fetch-mode': 'cors', + 'sec-fetch-site': 'same-site', + } + response = self.rr.get('https://personal-bus.wps.cn/sign_in/v1/encrypt/key', headers=headers) + json_data = response.json() + if json_data['code'] == 1000000: + logger.success(f'[用户{self.user_id}] 获取加密密钥成功') + return json_data['data'] + logger.error(f'[用户{self.user_id}] 获取加密密钥失败:{json_data["msg"]}') + return None + + # WPS任务中心-签到 + def sign_in(self, encryptData): + data = { + 'encryptData': encryptData, + 'userId': self.user_id, + } + resp = self.rr.post('https://py.leishennb.icu/v1/rnl-2-gather/get-wps-publickey', json=data).json() + params_obj = resp['data'] + headers = { + 'accept': 'application/json, text/plain, */*', + 'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6', + 'content-type': 'application/json', + 'origin': 'https://personal-act.wps.cn', + 'priority': 'u=1, i', + 'referer': 'https://personal-act.wps.cn/', + 'sec-ch-ua': '"Chromium";v="134", "Not:A-Brand";v="24", "Microsoft Edge";v="134"', + 'sec-ch-ua-mobile': '?0', + 'sec-ch-ua-platform': '"Windows"', + 'sec-fetch-dest': 'empty', + 'sec-fetch-mode': 'cors', + 'sec-fetch-site': 'same-site', + 'token': params_obj['token'], + } + json_data = params_obj['data'] + response = self.rr.post('https://personal-bus.wps.cn/sign_in/v1/sign_in', headers=headers, + json=json_data) + json_data = response.json() + if json_data.get('code') == 1000000: + rewards = json_data['data']['rewards'][0] + sign_msg = f"任务中心签到成功:{rewards['reward_name']}" + logger.success(f'[用户{self.user_id}] {sign_msg}') + self.operation_logs.append(sign_msg) + return True + if 'has sign' in json_data.get('msg'): + sign_msg = '今天已签到' + logger.info(f'[用户{self.user_id}] {sign_msg}') + self.operation_logs.append(sign_msg) + return True + sign_msg = f'任务中心签到失败:{json_data.get("msg", "未知错误")}' + logger.error(f'[用户{self.user_id}] {sign_msg}') + self.operation_logs.append(sign_msg) + return None + + # WPS任务中心-通用完成任务 + def common_component_action(self, task_id, title, component_action=None): + headers = { + 'accept': 'application/json, text/plain, */*', + 'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6', + 'content-type': 'application/json', + 'origin': 'https://personal-act.wps.cn', + 'priority': 'u=1, i', + 'referer': 'https://personal-act.wps.cn/rubik2/portal/HD2025031821201822/YM2025040908558269?cs_from=web_vipcenter_banner_inpublic&mk_key=4b9deqIfqNO3KCZrgH17WPH1kdzMoKUEvya&position=pc_aty_ban3_kaixue_test_b', + 'sec-ch-ua': '"Chromium";v="134", "Not:A-Brand";v="24", "Microsoft Edge";v="134"', + 'sec-ch-ua-mobile': '?0', + 'sec-ch-ua-platform': '"Windows"', + 'sec-fetch-dest': 'empty', + 'sec-fetch-mode': 'cors', + 'sec-fetch-site': 'same-origin', + 'user-agent': self.userAgent, + 'x-act-csrf-token': self.act_csrf_token, + } + json_data = { + 'component_uniq_number': { + 'activity_number': 'HD2025031821201822', + 'page_number': 'YM2025040908558269', + 'component_number': 'ZJ2025040709458367', + 'component_node_id': 'FN1744160180RthG', + 'filter_params': { + 'cs_from': 'web_vipcenter_banner_inpublic', + 'mk_key': '4b9deqIfqNO3KCZrgH17WPH1kdzMoKUEvya', + 'position': 'pc_aty_ban3_kaixue_test_b', + }, + }, + 'component_type': 35, + 'component_action': component_action or self.de['FINISH'], + 'task_center': { + 'task_id': task_id, + }, + } + try: + response = self.rr.post( + 'https://personal-act.wps.cn/activity-rubik/activity/component_action', + headers=headers, + json=json_data, + ).json() + if response['result'] == 'ok': + task_center = response['data']['task_center'] + if task_center['success']: + task_msg = f'完成任务 [{title}] 成功' + logger.success(f'[用户{self.user_id}] {task_msg}') + # self.operation_logs.append(task_msg) + return task_center.get('token') or True + task_msg = f'完成任务 [{title}] 失败:{task_center["reason"]}' + logger.error(f'[用户{self.user_id}] {task_msg}') + self.operation_logs.append(task_msg) + return False + task_msg = f'完成任务 [{title}] 失败:{response}' + logger.error(f'[用户{self.user_id}] {task_msg}') + self.operation_logs.append(task_msg) + return False + except Exception as e: + task_msg = f'完成任务 [{title}] 异常:{str(e)}' + logger.error(f'[用户{self.user_id}] {task_msg}') + self.operation_logs.append(task_msg) + return False + + # WPS任务中心-通用领取奖励 + def common_reward_component_action(self, task_id, title): + headers = { + 'accept': 'application/json, text/plain, */*', + 'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6', + 'content-type': 'application/json', + 'origin': 'https://personal-act.wps.cn', + 'priority': 'u=1, i', + 'referer': 'https://personal-act.wps.cn/rubik2/portal/HD2025031821201822/YM2025040908558269?cs_from=web_vipcenter_banner_inpublic&mk_key=4b9deqIfqNO3KCZrgH17WPH1kdzMoKUEvya&position=pc_aty_ban3_kaixue_test_b', + 'sec-ch-ua': '"Chromium";v="134", "Not:A-Brand";v="24", "Microsoft Edge";v="134"', + 'sec-ch-ua-mobile': '?0', + 'sec-ch-ua-platform': '"Windows"', + 'sec-fetch-dest': 'empty', + 'sec-fetch-mode': 'cors', + 'sec-fetch-site': 'same-origin', + 'x-act-csrf-token': self.act_csrf_token, + } + json_data = { + 'component_uniq_number': { + 'activity_number': 'HD2025031821201822', + 'page_number': 'YM2025040908558269', + 'component_number': 'ZJ2025040709458367', + 'component_node_id': 'FN1744160180RthG', + 'filter_params': { + 'cs_from': 'web_vipcenter_banner_inpublic', + 'mk_key': '4b9deqIfqNO3KCZrgH17WPH1kdzMoKUEvya', + 'position': 'pc_aty_ban3_kaixue_test_b', + }, + }, + 'component_type': 35, + 'component_action': self.de['REWARD'], + 'task_center': { + 'task_id': task_id, + }, + } + try: + response = self.rr.post( + 'https://personal-act.wps.cn/activity-rubik/activity/component_action', + headers=headers, + json=json_data, + ).json() + if response['result'] == 'ok': + task_center = response['data']['task_center'] + if task_center['success']: + reward_msg = f'领取 [{title}] 奖励成功' + logger.success(f'[用户{self.user_id}] {reward_msg}') + self.operation_logs.append(reward_msg) + return True + reward_msg = f'领取 [{title}] 奖励失败:{task_center["reason"]}' + logger.error(f'[用户{self.user_id}] {reward_msg}') + self.operation_logs.append(reward_msg) + return False + reward_msg = f'领取 [{title}] 奖励失败:{response}' + logger.error(f'[用户{self.user_id}] {reward_msg}') + self.operation_logs.append(reward_msg) + return False + except Exception as e: + reward_msg = f'领取 [{title}] 奖励异常:{str(e)}' + logger.error(f'[用户{self.user_id}] {reward_msg}') + self.operation_logs.append(reward_msg) + return False + + # WPS任务中心-任务详情 + def task_info(self, token): + headers = { + 'accept': 'application/json, text/plain, */*', + 'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6', + 'priority': 'u=1, i', + 'referer': 'https://personal-act.wps.cn/rubik2/portal/HD2025091109421588/YM2025091121369865?cs_from=android_ucsty_rwzx&positon=ad_rwzx_task', + 'sec-ch-ua': '"Chromium";v="134", "Not:A-Brand";v="24", "Microsoft Edge";v="134"', + 'sec-ch-ua-mobile': '?0', + 'sec-ch-ua-platform': '"Windows"', + 'sec-fetch-dest': 'empty', + 'sec-fetch-mode': 'cors', + 'sec-fetch-site': 'same-origin', + 'user-agent': self.userAgent, + } + start_time = int(time.time()*1000) + params = { + 'batch_tag': start_time, + 'token': token, + } + try: + response = self.rr.get( + 'https://personal-act.wps.cn/activity-rubik/user/task_center/task_info', + params=params, + headers=headers, + ).json() + if response.get('result') == 'ok': + return start_time + response['data']['start_at'] + logger.error(response) + return None + except Exception as e: + logger.error(str(e)) + return None + + # WPS任务中心-抽奖handle + def lottery_process(self, task_list): + if not task_list: + return + for task in task_list: + task_id = task['task_id'] + title = task['title'] + task_status = task['task_status'] + if task_status == 2: + logger.info(f'[用户{self.user_id}] 任务 [{title}] 已完成') + continue + if '浏览' in title: + token = self.common_component_action(task_id=task_id, title=title, + component_action=self.de['START_TASK']) + if token: + batch_tag = self.task_info(token=token) + if not batch_tag: + logger.error('获取浏览任务信息失败,跳过') + continue + Utils.r_sleep(10, 11) + is_done1 = self.task_finish(token=token, title=title, batch_tag=batch_tag) + if is_done1: + Utils.r_sleep(1) + self.common_reward_component_action(task_id=task_id, title=title) + Utils.r_sleep(1) + continue + skip_keywords = ['认证', '上喜马拉雅', '消费', '邀请', '微博', '苏宁易购', '开通会员'] + if any(keyword in title for keyword in skip_keywords): + logger.info(f'[用户{self.user_id}] 跳过任务 [{title}]') + continue + is_done = self.common_component_action(task_id=task_id, title=title) + if is_done: + Utils.r_sleep(1) + self.common_reward_component_action(task_id=task_id, title=title) + Utils.r_sleep(1) + + # 天天领福利-任务完成 浏览任务 + def task_finish(self, token, title, batch_tag): + headers = { + 'User-Agent': self.userAgent, + 'Accept': 'application/json, text/plain, */*', + # 'Accept-Encoding': 'gzip, deflate, br, zstd', + 'Content-Type': 'application/json', + 'sec-ch-ua-platform': '"Windows"', + 'sec-ch-ua': '"Google Chrome";v="129", "Not=A?Brand";v="8", "Chromium";v="129"', + 'sec-ch-ua-mobile': '?0', + 'origin': 'https://personal-act.wps.cn', + 'sec-fetch-site': 'same-origin', + 'sec-fetch-mode': 'cors', + 'sec-fetch-dest': 'empty', + 'referer': 'https://personal-act.wps.cn/rubik2/portal/HD2025031721339450/YM2025031721331326?cs_from=ad_ucsty_rwzx&position=ad_ucsty_rwzx', + 'accept-language': 'zh-CN,zh;q=0.9', + 'priority': 'u=1, i', + } + json_data = { + 'batch_tag': batch_tag, + 'token': token, + } + try: + response = self.rr.post( + 'https://personal-act.wps.cn/activity-rubik/user/task_center/task_finish', + headers=headers, + json=json_data, + ).json() + if response.get('result') == 'ok': + reward_msg = f'完成任务 [{title}] 成功' + logger.success(f'[用户{self.user_id}] {reward_msg}') + self.operation_logs.append(reward_msg) + return True + reward_msg = f'任务 {title} 完成失败:{response}' + logger.error(f'[用户{self.user_id}] {reward_msg}') + self.operation_logs.append(reward_msg) + return False + except Exception as e: + reward_msg = f'任务 {title} 完成失败:{str(e)}' + logger.error(f'[用户{self.user_id}] {reward_msg}') + self.operation_logs.append(reward_msg) + return False + + # 天天领福利-签到 + def fragment_collect_sign_in(self): + headers = { + 'accept': 'application/json, text/plain, */*', + 'accept-language': 'zh-CN,zh;q=0.9', + 'cache-control': 'no-cache', + 'content-type': 'application/json', + 'origin': 'https://personal-act.wps.cn', + 'pragma': 'no-cache', + 'priority': 'u=1, i', + 'referer': 'https://personal-act.wps.cn/rubik2/portal/HD2025031721339450/YM2025031721331326?cs_from=ad_ucsty_rwzx&position=ad_ucsty_rwzx', + 'sec-ch-ua': '"Google Chrome";v="129", "Not=A?Brand";v="8", "Chromium";v="129"', + 'sec-ch-ua-mobile': '?0', + 'sec-ch-ua-platform': '"Windows"', + 'sec-fetch-dest': 'empty', + 'sec-fetch-mode': 'cors', + 'sec-fetch-site': 'same-origin', + 'x-act-csrf-token': self.act_csrf_token, + } + sign_date = datetime.now().strftime("%Y-%m-%d") + json_data = { + 'component_uniq_number': { + 'activity_number': 'HD2025031721339450', + 'page_number': 'YM2025031721331326', + 'component_number': 'ZJ2025061815363325', + 'component_node_id': 'FN1750234948dBVL', + 'filter_params': { + 'cs_from': 'ad_ucsty_rwzx', + 'position': 'ad_ucsty_rwzx', + }, + }, + 'component_type': 42, + 'component_action': 'fragment_collect.sign_in', + 'fragment_collect': { + 'sign_date': sign_date, + 'series_id': '', + 'is_new_sign_series': True, + }, + } + try: + response = self.rr.post( + 'https://personal-act.wps.cn/activity-rubik/activity/component_action', + headers=headers, + json=json_data, + ) + json_data = response.json() + if json_data.get('result') == 'ok': + success = json_data['data']['fragment_collect']['success'] + rewards = json_data['data']['fragment_collect']['reason'] + if success: + sign_msg = f"天天领福利签到成功:{rewards}" + logger.success(f'[用户{self.user_id}] {sign_msg}') + self.operation_logs.append(sign_msg) + return True + sign_msg = f"天天领福利签到失败:{rewards}" + logger.error(f'[用户{self.user_id}] {sign_msg}') + self.operation_logs.append(sign_msg) + return False + _msg = json_data.get('msg') + if 'Duplicate entry' in _msg: + sign_msg = f"天天领福利-今日已签到" + else: + sign_msg = f"天天领福利签到失败:{_msg}" + logger.error(f'[用户{self.user_id}] {sign_msg}') + self.operation_logs.append(sign_msg) + return False + except Exception as e: + logger.error(str(e)) + sign_msg = f"天天领福利签到失败:{str(e)}" + self.operation_logs.append(sign_msg) + return False + + # 天天领福利-抽奖 + def lottery_v22(self): + headers = { + 'accept': 'application/json, text/plain, */*', + 'accept-language': 'zh-CN,zh;q=0.9', + 'cache-control': 'no-cache', + 'content-type': 'application/json', + 'origin': 'https://personal-act.wps.cn', + 'pragma': 'no-cache', + 'priority': 'u=1, i', + 'referer': 'https://personal-act.wps.cn/rubik2/portal/HD2025031721339450/YM2025031721331326?cs_from=ad_ucsty_rwzx&position=ad_ucsty_rwzx', + 'sec-ch-ua': '"Google Chrome";v="129", "Not=A?Brand";v="8", "Chromium";v="129"', + 'sec-ch-ua-mobile': '?0', + 'sec-ch-ua-platform': '"Windows"', + 'sec-fetch-dest': 'empty', + 'sec-fetch-mode': 'cors', + 'sec-fetch-site': 'same-origin', + 'x-act-csrf-token': self.act_csrf_token, + } + json_data = { + 'component_uniq_number': { + 'activity_number': 'HD2025031721339450', + 'page_number': 'YM2025031721331326', + 'component_number': 'ZJ2025092916515917', + 'component_node_id': 'FN1761875116m2x8', + 'filter_params': { + 'cs_from': 'ad_ucsty_rwzx', + 'position': 'ad_ucsty_rwzx', + }, + }, + 'component_type': 45, + 'component_action': 'lottery_v2.exec', + 'lottery_v2': { + 'session_id': 3001, + }, + } + try: + response = self.rr.post( + 'https://personal-act.wps.cn/activity-rubik/activity/component_action', + headers=headers, + json=json_data, + ) + json_data = response.json() + if json_data['result'] == 'ok': + reward_name = json_data['data']['lottery_v2']['reward_name'] + lottery_msg = f"天天领福利抽奖成功:{reward_name}" + logger.success(f'[用户{self.user_id}] {lottery_msg}') + self.operation_logs.append(lottery_msg) + return True + lottery_msg = f'天天领福利抽奖失败:{json_data.get("msg", "未知错误")}' + logger.error(f'[用户{self.user_id}] {lottery_msg}') + self.operation_logs.append(lottery_msg) + return None + except Exception as e: + lottery_msg = f'天天领福利抽奖异常:{str(e)}' + logger.error(f'[用户{self.user_id}] {lottery_msg}') + self.operation_logs.append(lottery_msg) + return False + + # WPS任务中心-抽奖 + def lottery_v2(self): + headers = { + 'sec-ch-ua-platform': '"Windows"', + 'Referer': 'https://personal-act.wps.cn/rubik2/portal/HD2025031821201822/YM2025040908558269?cs_from=web_vipcenter_banner_inpublic&mk_key=4b9deqIfqNO3KCZrgH17WPH1kdzMoKUEvya&position=pc_aty_ban3_kaixue_test_b', + 'sec-ch-ua': '"Chromium";v="134", "Not:A-Brand";v="24", "Microsoft Edge";v="134"', + 'sec-ch-ua-mobile': '?0', + 'User-Agent': self.userAgent, + 'Accept': 'application/json, text/plain, */*', + 'Content-Type': 'application/json', + 'X-Act-Csrf-Token': self.act_csrf_token, + } + json_data = { + 'component_uniq_number': { + 'activity_number': 'HD2025031821201822', + 'page_number': 'YM2025040908558269', + 'component_number': 'ZJ2025092916516585', + 'component_node_id': 'FN1762345949vdR1', + 'filter_params': { + 'cs_from': 'web_vipcenter_banner_inpublic', + 'mk_key': '4b9deqIfqNO3KCZrgH17WPH1kdzMoKUEvya', + 'position': 'pc_aty_ban3_kaixue_test_b', + }, + }, + 'component_type': 45, + 'component_action': 'lottery_v2.exec', + 'lottery_v2': { + 'session_id': 2, + }, + } + try: + response = self.rr.post('https://personal-act.wps.cn/activity-rubik/activity/component_action', + headers=headers, json=json_data) + json_data = response.json() + if json_data['result'] == 'ok': + reward_name = json_data['data']['lottery_v2']['reward_name'] + lottery_msg = f"抽奖成功:{reward_name}" + logger.success(f'[用户{self.user_id}] {lottery_msg}') + self.operation_logs.append(lottery_msg) + return True + lottery_msg = f'抽奖失败:{json_data.get("msg", "未知错误")}' + logger.error(f'[用户{self.user_id}] {lottery_msg}') + self.operation_logs.append(lottery_msg) + return None + except Exception as e: + lottery_msg = f'抽奖异常:{str(e)}' + logger.error(f'[用户{self.user_id}] {lottery_msg}') + self.operation_logs.append(lottery_msg) + return False + + # WPS任务中心-活动信息 + # https://personal-act.wps.cn/rubik2/portal/HD2025031821201822/YM2025040908558269?cs_from=web_vipcenter_banner_inpublic&mk_key=4b9deqIfqNO3KCZrgH17WPH1kdzMoKUEvya&position=pc_aty_ban3_kaixue_test_b + def page_info(self): + headers = { + 'accept': 'application/json, text/plain, */*', + 'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6', + 'priority': 'u=1, i', + 'referer': 'https://personal-act.wps.cn/rubik2/portal/HD2025031821201822/YM2025040908558269?cs_from=web_vipcenter_banner_inpublic&mk_key=4b9deqIfqNO3KCZrgH17WPH1kdzMoKUEvya&position=pc_aty_ban3_kaixue_test_b', + 'sec-ch-ua': '"Chromium";v="134", "Not:A-Brand";v="24", "Microsoft Edge";v="134"', + 'sec-ch-ua-mobile': '?0', + 'sec-ch-ua-platform': '"Windows"', + 'sec-fetch-dest': 'empty', + 'sec-fetch-mode': 'cors', + 'sec-fetch-site': 'same-origin', + 'user-agent': self.userAgent, + } + try: + # page_number=YM2025031821202008 + response = self.rr.get( + 'https://personal-act.wps.cn/activity-rubik/activity/page_info?activity_number=HD2025031821201822&page_number=YM2025040908558269&filter_params=%7B%22cs_from%22:%22web_vipcenter_banner_inpublic%22,%22mk_key%22:%224b9deqIfqNO3KCZrgH17WPH1kdzMoKUEvya%22,%22position%22:%22pc_aty_ban3_kaixue_test_b%22%7D', + headers=headers, + ).json() + if response['result'] == 'ok': + lottery_times = None + user_integral = None + task_list = None + + for item in response["data"]: + if lottery_times is None: + if item.get("type") == 45 and item.get("lottery_v2"): + for session in item["lottery_v2"].get("lottery_list", []): + if session.get("session_id") == 2: + lottery_times = session.get("times") + continue + if user_integral is None: + if item.get("task_center_user_info"): + user_integral = item["task_center_user_info"].get("integral") + elif item.get("integral_waterfall"): + user_integral = item["integral_waterfall"].get("user_integral") + if task_list is None: + if item.get("task_center"): + task_list = item["task_center"].get("task_list") + if lottery_times and user_integral and task_list: + break + logger.info(f'[用户{self.user_id}] 积分:{user_integral},抽奖次数:{lottery_times}') + return { + "lottery_times": lottery_times, + "user_integral": user_integral, + "task_list": task_list + } + except Exception as e: + logger.error(f'[用户{self.user_id}] 获取用户信息异常:{str(e)}') + return None + + # 办公助手-活动信息 + # https://personal-act.wps.cn/rubik2/portal/HD2025031010408781/YM2025061216463517?cs_from=xinchao_activity_lottery&position=xinchao_bgzs_autoreply_2148_cj + def page_info2(self): + headers = { + 'accept': 'application/json, text/plain, */*', + 'accept-language': 'zh-CN,zh;q=0.9', + 'cache-control': 'no-cache', + 'pragma': 'no-cache', + 'priority': 'u=1, i', + 'referer': 'https://personal-act.wps.cn/rubik2/portal/HD2025031010408781/YM2025061216463517?cs_from=xinchao_activity_lottery&position=xinchao_bgzs_autoreply_2148_cj', + 'sec-ch-ua': '"Google Chrome";v="129", "Not=A?Brand";v="8", "Chromium";v="129"', + 'sec-ch-ua-mobile': '?0', + 'sec-ch-ua-platform': '"Windows"', + 'sec-fetch-dest': 'empty', + 'sec-fetch-mode': 'cors', + 'sec-fetch-site': 'same-origin', + } + try: + response = self.rr.get( + 'https://personal-act.wps.cn/activity-rubik/activity/page_info?activity_number=HD2025031010408781&page_number=YM2025061216463517&filter_params=%7B%22cs_from%22:%22xinchao_activity_lottery%22,%22position%22:%22xinchao_bgzs_autoreply_2148_cj%22%7D', + headers=headers, + ).json() + task_list = None + lottery_times = None + # 遍历data数组,定位包含task_center的元素 + for item in response["data"]: + if "task_center" in item and "task_list" in item["task_center"]: + task_list = item["task_center"]["task_list"] + if "lottery" in item and item["lottery"]: + lottery = item["lottery"] + if "rewards" in lottery and isinstance(lottery["rewards"], list) and len(lottery["rewards"]) > 0: + first_reward = lottery["rewards"][0] + if "times" in first_reward: + lottery_times = first_reward["times"] + if lottery_times != None and task_list != None: + break + return { + 'task_list': task_list, + 'lottery_times': lottery_times + } + except Exception as e: + logger.error(str(e)) + return None + + # 福利中心-活动信息 + def page_info3(self): + headers = { + 'accept': 'application/json, text/plain, */*', + 'accept-language': 'zh-CN,zh;q=0.9', + 'cache-control': 'no-cache', + 'pragma': 'no-cache', + 'priority': 'u=1, i', + 'referer': 'https://personal-act.wps.cn/rubik2/portal/HD2025031721339450/YM2025031721331326?cs_from=ad_ucsty_rwzx&position=ad_ucsty_rwzx', + 'sec-ch-ua': '"Google Chrome";v="129", "Not=A?Brand";v="8", "Chromium";v="129"', + 'sec-ch-ua-mobile': '?0', + 'sec-ch-ua-platform': '"Windows"', + 'sec-fetch-dest': 'empty', + 'sec-fetch-mode': 'cors', + 'sec-fetch-site': 'same-origin', + } + try: + response = self.rr.get( + 'https://personal-act.wps.cn/activity-rubik/activity/page_info?activity_number=HD2025031721339450&page_number=YM2025031721331326&filter_params=%7B%22cs_from%22:%22ad_ucsty_rwzx%22,%22position%22:%22ad_ucsty_rwzx%22%7D', + headers=headers, + ).json() + if response['result'] == 'ok': + lottery_times = None + for item in response["data"]: + if item.get("lottery_v2"): + for session in item["lottery_v2"].get("lottery_list", []): + if session.get("times"): + lottery_times = session.get("times") + break + return { + "lottery_times": lottery_times, + } + except Exception as e: + logger.error(f'[用户{self.user_id}] 获取用户信息异常:{str(e)}') + return None + + # 办公助手-领取 + def components_action2(self, task_id, title): + headers = { + 'accept': 'application/json, text/plain, */*', + 'accept-language': 'zh-CN,zh;q=0.9', + 'cache-control': 'no-cache', + 'content-type': 'application/json', + 'origin': 'https://personal-act.wps.cn', + 'pragma': 'no-cache', + 'priority': 'u=1, i', + 'referer': 'https://personal-act.wps.cn/rubik2/portal/HD2025031010408781/YM2025061216463517?cs_from=xinchao_activity_lottery&position=xinchao_bgzs_autoreply_2148_cj', + 'sec-ch-ua': '"Google Chrome";v="129", "Not=A?Brand";v="8", "Chromium";v="129"', + 'sec-ch-ua-mobile': '?0', + 'sec-ch-ua-platform': '"Windows"', + 'sec-fetch-dest': 'empty', + 'sec-fetch-mode': 'cors', + 'sec-fetch-site': 'same-origin', + } + json_data = { + 'component_uniq_number': { + 'activity_number': 'HD2025031010408781', + 'page_number': 'YM2025061216463517', + 'component_number': 'ZJ2024083022083755', + 'component_node_id': 'FN1740387182DaYX', + }, + 'component_type': 14, + 'component_action': self.de['REWARD'], + 'task_center': { + 'task_id': task_id, + }, + } + try: + response = self.rr.post( + 'https://personal-act.wps.cn/activity-rubik/activity/component_action', + headers=headers, + json=json_data, + ).json() + if response['result'] == 'ok': + task_center = response['data']['task_center'] + if task_center['success']: + reward_msg = f'领取 [{title}] 奖励成功' + logger.success(f'[用户{self.user_id}] {reward_msg}') + self.operation_logs.append(reward_msg) + return True + reward_msg = f'领取 [{title}] 奖励失败:{task_center["reason"]}' + logger.error(f'[用户{self.user_id}] {reward_msg}') + self.operation_logs.append(reward_msg) + return False + reward_msg = f'领取 [{title}] 奖励失败:{response}' + logger.error(f'[用户{self.user_id}] {reward_msg}') + self.operation_logs.append(reward_msg) + return False + except Exception as e: + reward_msg = f'领取 [{title}] 奖励异常:{str(e)}' + logger.error(f'[用户{self.user_id}] {reward_msg}') + self.operation_logs.append(reward_msg) + return False + + # 办公助手-抽奖 + def lottery_exec(self): + headers = { + 'accept': 'application/json, text/plain, */*', + 'accept-language': 'zh-CN,zh;q=0.9', + 'cache-control': 'no-cache', + 'content-type': 'application/json', + 'origin': 'https://personal-act.wps.cn', + 'pragma': 'no-cache', + 'priority': 'u=1, i', + 'referer': 'https://personal-act.wps.cn/rubik2/portal/HD2025031010408781/YM2025061216463517?cs_from=xinchao_activity_lottery&position=xinchao_bgzs_autoreply_2148_cj', + 'sec-ch-ua': '"Google Chrome";v="129", "Not=A?Brand";v="8", "Chromium";v="129"', + 'sec-ch-ua-mobile': '?0', + 'sec-ch-ua-platform': '"Windows"', + 'sec-fetch-dest': 'empty', + 'sec-fetch-mode': 'cors', + 'sec-fetch-site': 'same-origin', + } + json_data = { + 'component_uniq_number': { + 'activity_number': 'HD2025031010408781', + 'page_number': 'YM2025061216463517', + 'component_number': 'ZJ2024083022081230', + 'component_node_id': 'FN1741940010rC4c', + }, + 'component_type': 2, + 'component_action': 'lottery.exec', + 'lottery': { + 'pay_source': '', + 'integral_source': '', + 'position': 'bgzs_tasks_cj', + 'source': '', + 'ids': '1115,1119,1116,1117,1120,1121,1122,1118', + 'sign': '', + }, + } + try: + response = self.rr.post( + 'https://personal-act.wps.cn/activity-rubik/activity/component_action', + headers=headers, + json=json_data, + ) + json_data = response.json() + if json_data['result'] == 'ok': + reward_name = json_data['data']['lottery']['name'] + lottery_msg = f"抽奖成功:{reward_name}" + logger.success(f'[用户{self.user_id}] {lottery_msg}') + self.operation_logs.append(lottery_msg) + return True + lottery_msg = f'抽奖失败:{json_data.get("msg", "未知错误")}' + logger.error(f'[用户{self.user_id}] {lottery_msg}') + self.operation_logs.append(lottery_msg) + return None + except Exception as e: + lottery_msg = f'抽奖异常:{str(e)}' + logger.error(f'[用户{self.user_id}] {lottery_msg}') + self.operation_logs.append(lottery_msg) + return False + + # 办公助手-执行 + def done_task2_handler(self, task_list2, first_task=False): + for t2 in task_list2: + task_id = t2["task_id"] + title = t2["title"] + task_status = t2['task_status'] + if task_status == 1: + logger.info(f'[用户{self.user_id}] 任务 [{title}] 已完成') + continue + if first_task: + if '每日访问当前活动' in title: + self.components_action2(task_id=task_id, title=title) + Utils.r_sleep(2) + return + else: + if '每日访问当前活动' in title: + continue + self.components_action2(task_id=task_id, title=title) + Utils.r_sleep(2) + + # applet-wps超级会员签到 + def applet_sign(self): + s_key = '06196ab4da15c09a3aaee610162ca56f' + try: + clock_info = self.rr.get('https://personal-bus.wps.cn/activity/clock_in/v1/info').json() + s_key = clock_info.get('data',{}).get('s_key') + except Exception as e: + logger.error(str(e)) + ss = '7908b285f33c837d' + json_data = { + 'client_type': 1, + } + # 别动,签名算法不能用,固定即可 + signature = generate_sign(json_data, s_key, ss) + headers = { + 'Host': 'personal-bus.wps.cn', + 'Connection': 'keep-alive', + # 'Content-Length': '17', + 'date': 'Tue, 20 Jan 2026 14:42:58 GMT', + 'charset': 'utf-8', + 'signature': '0d8ff00f5c74de36d0b2e677c82b22a1dd5ab196b0d227cc875fb051eec50156', + 'x-csrftoken': '1234567890', + 'User-Agent': 'Mozilla/5.0 (Linux; Android 14; 23117RK66C Build/UKQ1.230804.001; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/142.0.7444.173 Mobile Safari/537.36 XWEB/1420153 MMWEBSDK/20240404 MMWEBID/3531 MicroMessenger/8.0.49.2600(0x2800313D) WeChat/arm64 Weixin Android Tablet NetType/WIFI Language/zh_CN ABI/arm64 MiniProgramEnv/android', + 'content-type': 'application/json', + # 'Accept-Encoding': 'gzip,compress,br,deflate', + 'Referer': 'https://servicewechat.com/wx2f333d84a103825d/240/page-frame.html', + } + try: + response = self.rr.post( + 'https://personal-bus.wps.cn/activity/clock_in/v1/clock_in', + headers=headers, + json=json_data, + ).json() + if response['result'] == 'ok': + lottery_msg = f"小程序签到成功" + logger.success(f'[用户{self.user_id}] {lottery_msg}') + self.operation_logs.append(lottery_msg) + return True + if 'already clocked in today' in response.get("msg", "未知错误"): + lottery_msg = f'小程序签到失败:今日已签到' + else: + lottery_msg = f'小程序签到失败:{response.get("msg", "未知错误")}' + logger.error(f'[用户{self.user_id}] {lottery_msg}') + self.operation_logs.append(lottery_msg) + return None + except Exception as e: + lottery_msg = f'小程序签到异常:{str(e)}' + logger.error(f'[用户{self.user_id}] {lottery_msg}') + self.operation_logs.append(lottery_msg) + return False + + # WPS挑战计划-任务完成or领取 + def challenge_component_action(self, title, task_id, component_action=None, action_name=None): + component_action = component_action or self.de['FINISH'] + if not action_name: + if self.de['FINISH'] == component_action: + action_name = '完成' + elif self.de['REWARD'] == component_action: + action_name = '领取' + headers = { + 'accept': 'application/json, text/plain, */*', + 'accept-language': 'zh-CN,zh;q=0.9', + 'content-type': 'application/json', + 'origin': 'https://personal-act.wps.cn', + 'priority': 'u=1, i', + 'referer': 'https://personal-act.wps.cn/rubik2/portal/HD2025121517384715/YM2025121517381164?cs_from=pc_ucsty_rwzx_task&position=pc_rwzx_task', + 'sec-ch-ua': '"Google Chrome";v="129", "Not=A?Brand";v="8", "Chromium";v="129"', + 'sec-ch-ua-mobile': '?0', + 'sec-ch-ua-platform': '"Windows"', + 'sec-fetch-dest': 'empty', + 'sec-fetch-mode': 'cors', + 'sec-fetch-site': 'same-origin', + 'user-agent': self.userAgent, + 'x-act-csrf-token': self.act_csrf_token, + } + json_data = { + 'component_uniq_number': { + 'activity_number': 'HD2025121517384715', + 'page_number': 'YM2025121517381164', + 'component_number': 'ZJ2025031817022062', + 'component_node_id': 'FN17642133971jKe', + 'filter_params': { + 'cs_from': 'pc_ucsty_rwzx_task', + 'position': 'pc_rwzx_task', + }, + }, + 'component_type': 35, + 'component_action': component_action, + 'task_center': { + 'task_id': task_id, + }, + } + try: + response = self.rr.post( + 'https://personal-act.wps.cn/activity-rubik/activity/component_action', + headers=headers, + json=json_data, + ).json() + if response['result'] == 'ok': + task_center = response['data']['task_center'] + if task_center['success']: + task_msg = f'{action_name}任务 [{title}] 成功' + logger.success(f'[用户{self.user_id}] {task_msg}') + if action_name == '领取': + self.operation_logs.append(task_msg) + return task_center.get('token') or True + task_msg = f'{action_name}任务 [{title}] 失败:{task_center["reason"]}' + logger.error(f'[用户{self.user_id}] {task_msg}') + self.operation_logs.append(task_msg) + return False + task_msg = f'{action_name}任务 [{title}] 失败:{response}' + logger.error(f'[用户{self.user_id}] {task_msg}') + self.operation_logs.append(task_msg) + return False + except Exception as e: + task_msg = f'{action_name}任务 [{title}] 异常:{str(e)}' + logger.error(f'[用户{self.user_id}] {task_msg}') + self.operation_logs.append(task_msg) + return False + + # WPS挑战计划-任务信息 + def challenge_page_info(self): + headers = { + 'accept': 'application/json, text/plain, */*', + 'accept-language': 'zh-CN,zh;q=0.9', + 'priority': 'u=1, i', + 'referer': 'https://personal-act.wps.cn/rubik2/portal/HD2025121517384715/YM2025121517381164?cs_from=pc_ucsty_rwzx_task&position=pc_rwzx_task', + 'sec-ch-ua': '"Google Chrome";v="129", "Not=A?Brand";v="8", "Chromium";v="129"', + 'sec-ch-ua-mobile': '?0', + 'sec-ch-ua-platform': '"Windows"', + 'sec-fetch-dest': 'empty', + 'sec-fetch-mode': 'cors', + 'sec-fetch-site': 'same-origin', + 'user-agent': self.userAgent, + } + try: + response = self.rr.get( + 'https://personal-act.wps.cn/activity-rubik/activity/page_info?activity_number=HD2025121517384715&page_number=YM2025121517381164&filter_params=%7B%22cs_from%22:%22pc_ucsty_rwzx_task%22,%22position%22:%22pc_rwzx_task%22%7D', + headers=headers, + ).json() + if response['result'] == 'ok': + lottery_times = None + task_list = None + for item in response["data"]: + if item.get("task_center"): + _task_list = item["task_center"].get("task_list", []) + if _task_list: + task_list = _task_list + if task_list and lottery_times: + break + return { + "task_list": task_list, + "lottery_times": lottery_times, + } + except Exception as e: + logger.error(f'[用户{self.user_id}] 获取WPS挑战计划任务列表异常:{str(e)}') + return None + + # WPS挑战计划-任务执行 + def challenge_exec(self, task_list): + if not task_list: + return + for task in task_list: + task_id = task['task_id'] + title = task['title'] + task_status = task['task_status'] + if task_status == 2: + logger.info(f'[用户{self.user_id}] 任务 [{title}] 已完成') + continue + skip_keywords = ['邀请', 'PDF转换', 'PDF合并', '语音速记', '关注', '认证', '消费', '开通会员'] + if any(keyword in title for keyword in skip_keywords): + logger.info(f'[用户{self.user_id}] 跳过任务 [{title}]') + continue + is_done = self.challenge_component_action(task_id=task_id, title=title, component_action=self.de['FINISH']) + if is_done: + Utils.r_sleep(1) + self.challenge_component_action(task_id=task_id, title=title, component_action=self.de['REWARD']) + Utils.r_sleep(1) + + def main(self): + self.operation_logs = [] + user_id = self.user_id + + # ================ WPS任务中心 ================= + if self.global_config.get('task_center'): + tip = '# 开始执行 WPS任务中心 任务' + self.operation_logs.append(tip) + logger.info(tip) + page_data = self.page_info() + if not page_data: + error_msg = f'[用户{user_id}] 获取用户信息失败:活动结束或cookie过期' + logger.error(error_msg) + self.operation_logs.append(error_msg) + # 返回None和消息 + return None, f'用户ID:{user_id}\n' + '\n'.join(self.operation_logs) + task_list = page_data.get("task_list") or [] + Utils.r_sleep(1) + # 签到 + public_data = self.get_public_key() + if public_data: + self.sign_in(public_data) + else: + self.operation_logs.append(f'[用户{user_id}] 获取签到密钥失败,终止任务') + return None, f'用户ID:{user_id}\n' + '\n'.join(self.operation_logs) + Utils.r_sleep(1) + # 完成领取任务 + self.lottery_process(task_list=task_list) + Utils.r_sleep(1.5) + # 重试 + page_data = self.page_info() + if page_data: + self.lottery_process(task_list=page_data.get("task_list") or []) + Utils.r_sleep(1.5) + page_data = self.page_info() + lottery_times = page_data.get("lottery_times") if page_data else 0 + # 抽奖 + if lottery_times and lottery_times > 0: + logger.info(f'[用户{user_id}] 开始执行抽奖(剩余次数:{lottery_times})') + for i in range(lottery_times): + lottery_result = self.lottery_v2() + if not lottery_result: + logger.info(f'[用户{user_id}] 抽奖第{i+1}次失败,终止抽奖') + break + Utils.r_sleep(1) + logger.info('# 执行完成 WPS任务中心 任务') + + # ============== 天天领福利 ============= + if self.global_config.get('lottery3'): + tip = '# 开始执行 天天领福利 任务' + self.operation_logs.append(tip) + logger.info(tip) + Utils.r_sleep(1) + self.fragment_collect_sign_in() + Utils.r_sleep(1) + page_info3 = self.page_info3() + if page_info3: + lottery_times3 = page_info3.get('lottery_times') or 0 + if lottery_times3 > 0: + for i3 in range(lottery_times3): + lottery_result3 = self.lottery_v22() + if not lottery_result3: + logger.info(f'[用户{user_id}] 抽奖第{i3+1}次失败,终止抽奖') + break + Utils.r_sleep(1) + logger.info('# 执行完成 天天领福利 任务') + + # ============== WPS办公助手(默认关闭) ============= + if self.global_config.get('fragment_collect'): + tip = '# 开始执行 WPS办公助手 任务' + self.operation_logs.append(tip) + logger.info(tip) + page_result = self.page_info2() + if page_result: + task_list2 = page_result.get("task_list") or [] + self.done_task2_handler(task_list2, first_task=True) + self.done_task2_handler(task_list2) + page_result = self.page_info2() + lottery_times = page_result.get("lottery_times") or 0 + Utils.r_sleep(1) + if lottery_times > 0: + for i2 in range(lottery_times): + lottery_result2 = self.lottery_exec() + if not lottery_result2: + logger.info(f'[用户{user_id}] 抽奖第{i2+1}次失败,终止抽奖') + break + Utils.r_sleep(1) + logger.info('# 执行完成 WPS办公助手 任务') + else: + logger.error("WPS办公助手数据异常,跳过") + + # ============== WPS挑战计划 ============= + if self.global_config.get('challenge'): + tip = '# 开始执行 WPS挑战计划 任务' + self.operation_logs.append(tip) + logger.info(tip) + challenge_data = self.challenge_page_info() + if challenge_data: + self.challenge_exec(challenge_data.get('task_list') or []) + + # ============== wps超级会员小程序 ============= + if self.global_config.get('svip_applet'): + tip = '# 开始执行 wps超级会员小程序 任务' + self.operation_logs.append(tip) + logger.info(tip) + self.applet_sign() + logger.info('# 执行完成 wps超级会员小程序 任务') + + # ---------- 构建统计信息 ---------- + stats = { + 'user_id': user_id, + 'task_center_checkin': any('任务中心签到成功' in log or '今天已签到' in log for log in self.operation_logs), + 'fragment_sign': any('天天领福利签到成功' in log for log in self.operation_logs), + 'applet_sign': any('小程序签到成功' in log for log in self.operation_logs), + 'completed_tasks': sum(1 for log in self.operation_logs if '完成任务' in log and '成功' in log), + 'lottery_results': [log for log in self.operation_logs if '抽奖成功' in log], + } + + final_msg = f'用户ID:{user_id}\n' + '\n'.join(self.operation_logs) + return stats, final_msg + + +def print_wps_table(stats_list): + """打印 WPS 单账户明细表格""" + if not stats_list: + return + print("\n" + "=" * 80) + print("📊 单账户明细:") + header = "┌──────┬──────────────┬──────────────┬──────────────┬──────────────┬──────────────┐" + title = "│ 序号 │ 用户ID │ 任务中心签到 │ 天天领福利 │ 小程序签到 │ 完成任务数 │" + split_line = "├──────┼──────────────┼──────────────┼──────────────┼──────────────┼──────────────┤" + footer = "└──────┴──────────────┴──────────────┴──────────────┴──────────────┴──────────────┘" + print(header) + print(title) + print(split_line) + for idx, s in enumerate(stats_list, 1): + uid = str(s.get('user_id', '?'))[:12] + checkin = '✅' if s.get('task_center_checkin') else '❌' + frag = '✅' if s.get('fragment_sign') else '❌' + applet = '✅' if s.get('applet_sign') else '❌' + tasks = s.get('completed_tasks', 0) + line = f"│ {idx:^4} │ {uid:^12} │ {checkin:^12} │ {frag:^12} │ {applet:^12} │ {tasks:^12} │" + print(line) + print(footer) + + # 汇总统计 + total = len(stats_list) + success_count = sum(1 for s in stats_list if s.get('task_center_checkin') or s.get('fragment_sign') or s.get('applet_sign')) + print("\n📊 账号汇总:") + print(f" 总账号: {total}") + print(f" 成功: {success_count} 失败: {total - success_count}") + print("=" * 80) + + +def read_users_from_env(): + users_env = os.getenv('WPS_TASK_CK', '') + users = [] + for line in users_env.strip().split('\n'): + if line.strip(): + parts = line.split('#') + if len(parts) >= 2: + user_info = { + 'username': parts[0].strip(), + 'cookie': parts[1].strip(), + } + users.append(user_info) + return users + + +if __name__ == "__main__": + users = read_users_from_env() + if not users: + print("未配置用户信息,请设置 WPS_TASK_CK 环境变量,格式:备注#cookie") + exit(1) + + print(f"共读取到 {len(users)} 个用户") + logger.info('随机等待30-600s') + Utils.r_sleep(30, 600) + + rnlProxy = None + if RnlProxy: + rnlProxy = RnlProxy() + + all_stats = [] + all_push_msgs = [] + + for i, user in enumerate(users, 1): + proxies = None + if rnlProxy: + proxies = rnlProxy.get_valid_proxy() + print(f'使用代理:{proxies}') + username = user['username'] + cookies = user['cookie'] + print(f"\n===== 正在处理第 {i} 个用户:{username} =====") + + try: + stats, msg = RNL(cookies, proxies=proxies).main() + if stats: + all_stats.append(stats) + all_push_msgs.append(f"【{username}】\n{msg}") + except Exception as e: + error_msg = f"【{username}】处理异常:{str(e)}" + logger.error(error_msg) + all_push_msgs.append(error_msg) + all_stats.append({ + 'user_id': 'error', + 'task_center_checkin': False, + 'fragment_sign': False, + 'applet_sign': False, + 'completed_tasks': 0 + }) + + # 输出表格与汇总 + print_wps_table(all_stats) + + # 推送(捕获异常避免中断) + if rnl_push and all_push_msgs: + try: + push_title = "WPS任务执行结果" + push_content = '\n\n'.join(all_push_msgs) + rnl_push.sendNotify(push_title, push_content) + print(f"\n推送消息已发送:\n{push_content}") + except Exception as e: + logger.error(f"推送消息失败: {e}") + elif not rnl_push: + print("\n推送功能未启用,跳过消息推送") + else: print("\n无推送消息可发送") \ No newline at end of file