1.购买服务器阿里云:服务器购买地址https://t.aliyun.com/U/W9mv4W若失效,可用地址
阿里云:
服务器购买地址
https://t.aliyun.com/U/W9mv4W
若失效,可用地址
https://www.aliyun.com/minisite/goods?source=5176.29345612&userCode=49hts92d
腾讯云:
https://curl.qcloud.com/wJpWmSfU
若失效,可用地址
https://cloud.tencent.com/act/cps/redirect?redirect=2446&cps_key=ad201ee2ef3b771157f72ee5464b1fea&from=console
华为云
https://activity.huaweicloud.com/cps.html?fromacct=64b5cf7cc11b4840bb4ed2ea0b2f4468&utm_source=V1g3MDY4NTY=&utm_medium=cps&utm_campaign=201905
2.部署教程
3.代码如下
"""
天翼云盘签到
cron: 50 1,18 * * *
const $ = new Env("天翼云盘签到");
"""
import requests
import time
import hmac
import hashlib
import base64
import os
from Crypto.PublicKey import RSA
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
from Crypto.Cipher import PKCS1_v1_5
import re
from urllib.parse import unquote
from datetime import datetime, timedelta
if 'cloud189_token' in os.environ:
cloud189_token = re.split("@|&",os.environ.get("cloud189_token"))
print(f'查找到{len(cloud189_token)}个账号')
else:
cloud189_token =['']
print('无cloud189_token变量')
aes_iv = "Zx8dG46ax3Qa8Mj2".encode() # 16 字节
aes_key = "bf8395f745R44f23".encode() # 16 字节
RSA_PUBLIC_KEY_PEM = """-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDC72L803mNmrQgyvaU
t115S5gSHuDcS+nGdqBakHYqFShEwrEaqKsr2Z/7DQt9AobB0ne2vIS
UW0tXjhgf5vfl00kT7K+J4j+t3WLkQ6Zwc9KtZHkSW6/fkFSC1EnShP
YLsG6rHYa5+wfefOY2P7yEFRsd5DGCqHNWkzOZclsXawIDAQAB
-----END PUBLIC KEY-----"""
# AES CBC 加密函数
def aes_cbc_encrypt(plaintext, key, iv):
cipher = AES.new(key, AES.MODE_CBC, iv)
padded_plaintext = pad(plaintext.encode('utf-8'), AES.block_size)
ciphertext = cipher.encrypt(padded_plaintext)
return base64.b64encode(ciphertext).decode('utf-8')
# AES CBC 解密函数
def aes_cbc_decrypt(ciphertext, key, iv):
ciphertext = base64.b64decode(ciphertext)
cipher = AES.new(key, AES.MODE_CBC, iv)
padded_plaintext = cipher.decrypt(ciphertext)
plaintext = unpad(padded_plaintext, AES.block_size)
return plaintext.decode('utf-8')
def encrypt_aes_key(key):
aes_session_key = key.encode('utf-8')
rsa_public_key = RSA.import_key(RSA_PUBLIC_KEY_PEM)
rsa_cipher = PKCS1_v1_5.new(rsa_public_key)
encrypted_aes_key = rsa_cipher.encrypt(aes_session_key)
return base64.b64encode(encrypted_aes_key).decode('utf-8')
def md5_encrypt(plaintext):
md5_hash = hashlib.md5()
md5_hash.update(plaintext.encode('utf-8'))
return md5_hash.hexdigest()
def hmac_sha1_hex(key, message):
key_bytes = key.encode('utf-8')
message_bytes = message.encode('utf-8')
hmac_hash = hmac.new(key_bytes, message_bytes, hashlib.sha1)
return hmac_hash.digest().hex()
def get_task_info(data):
task_info = []
for task in data["data"]:
if not task["status"]: # 只返回未完成的任务
task_info.append({
"taskId": task["taskId"],
"taskName": task["taskName"],
})
return task_info
send_msg = ''
one_msg = ''
def log(cont=''):
global send_msg, one_msg
if cont:
one_msg += f'{cont}\n'
send_msg += f'{cont}\n'
# 发送通知消息
def send_notification_message(title):
try:
from notify import send
print("加载通知服务成功!")
send(title, send_msg)
except Exception as e:
if e:
print('发送通知消息失败!')
def generateRsakey():
headers = {
'Host': 'api.cloud.189.cn',
'accept': 'application/json;charset=UTF-8',
'accept-language': 'zh-cn',
'x-request-id': '26E11B6CBEB94F77A2E5615C20C06175',
'date': 'Sun, 22 Jun 2025 14:33:08 GMT',
'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_8 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 Safari/604.1',
}
params = {
'clientType': 'TELEIPHONE',
'version': '10.3.3',
'model': 'iPhone',
'osFamily': 'iOS',
'osVersion': '15.8.3',
'clientSn': '02676BE3DD-8D86-4B4F-A666-852D1D5C9FF8',
'returnType': 'JSON',
}
response = requests.get('https://api.cloud.189.cn/security/generateRsaKey.action', params=params, headers=headers).json()
return response['pkId']
def get_AccessToken(sessionKey):
timestamp_1 = str(int(time.time()))
signature = md5_encrypt(f'AppKey=600100422&Timestamp={timestamp_1}&sessionKey={sessionKey}')
headers = {
'Host': 'api.cloud.189.cn',
'accept': 'application/json;charset=UTF-8',
'sign-type': '1',
'timestamp': timestamp_1,
'sec-fetch-site': 'same-site',
'accept-language': 'zh-CN,zh-Hans;q=0.9',
'signature': signature,
'sec-fetch-mode': 'cors',
'origin': 'https://m.cloud.189.cn',
'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 16_6_1 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 Ecloud/10.3.3 iOS/16.6.1 clientId/027A8AB808-F7A5-431E-8B37-6BD9559D22D7 clientModel/iPhone proVersion/1.0.5',
'appkey': '600155422',
'referer': 'https://m.cloud.189.cn/',
'sec-fetch-dest': 'empty',
}
params = {
'sessionKey': sessionKey,
}
response = requests.get('https://api.cloud.189.cn/open/oauth2/getAccessTokenBySsKey.action', params=params,headers=headers).json()
return response['accessToken']
def login4MergedClient(token):
timestamp = str(int(time.time()))
appsignature = hmac_sha1_hex('fe5734c74c2f96a38157f420b32dc995',f'AppKey=600100885&Operate=POST&RequestURI=/login4MergedClient.action&Timestamp={timestamp}')
param = f'isCache=1&jgOpenId=1114a89792bbaa8d350&deviceModel=iPhone%206s%20Plus&exRetryTimes=1&accessToken={token}&networkAccessMode=WIFI&telecomsOperator=&idfa=00000000-0000-0000-0000-000000000000&clientType=TELEIPHONE&version=10.3.3&model=iPhone&osFamily=iOS&osVersion=15.8.3&clientSn=02676BE3DD-8D86-4B4F-A666-749D1D5C9FF8'
encrypted_param = aes_cbc_encrypt(param, aes_key, aes_iv)
epkey = encrypt_aes_key("bf8395f745c04f23")
pkId = generateRsakey()
headers = {
'Host': 'api.cloud.189.cn',
'content-type': 'application/x-www-form-urlencoded',
'epver': '2',
'accept': '*/*',
'epway': '3',
'timestamp': timestamp,
'appsignature': appsignature,
'accept-language': 'zh-CN,zh-Hans;q=0.9',
'x-request-id': '26E11B6CBEB94F77A2E5615C20C06175',
'epkey': epkey,
'appkey': '600100885',
'user-agent': 'Cloud189/8 CFNetwork/1410.0.3 Darwin/22.6.0',
}
data = {
'pkId': pkId,
'param': encrypted_param,
}
try:
response = requests.post('https://api.cloud.189.cn/login4MergedClient.action', headers=headers, data=data).text
ciphertext = re.search(r'<ciphertext>(.*?)</ciphertext>', response, re.DOTALL).group(1)
user_data = unquote(aes_cbc_decrypt(ciphertext, aes_key, aes_iv))
# print(user_data)
login_Name = re.search(r'<loginName>(.*?)</loginName>', user_data, re.DOTALL).group(1)
session_Key = re.search(r'<sessionKey>(.*?)</sessionKey>', user_data, re.DOTALL).group(1)
sessionSecret = re.search(r'<sessionSecret>(.*?)</sessionSecret>', user_data, re.DOTALL).group(1)
familySessionKey = re.search(r'<familySessionKey>(.*?)</familySessionKey>', user_data, re.DOTALL).group(1)
return login_Name, session_Key,sessionSecret,familySessionKey
except Exception as e:
print(e)
return False
def day_sign(sS,session_key):
gmt_time = datetime.utcnow().strftime('%a, %d %b %Y %H:%M:%S GMT')
signature = hmac_sha1_hex(sS,f'SessionKey={session_key}&Operate=GET&RequestURI=/mkt/userSign.action&Date={gmt_time}')
headers = {
'Host': 'api.cloud.189.cn',
'x-request-id': '26E11B6CBEB94F77A2E5615C20C06113',
'signature': signature,
'date': gmt_time,
'accept-language': 'zh-cn',
'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_8_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 Ecloud/10.3.3 (iPhone; 02676BE3DD-8D86-4B4F-A666-749D1D5C9FF8; appStore) iOS/15.8.3',
'sessionkey': session_key,
'accept': '*/*',
}
params = {
'clientType': 'TELEIPHONE',
'version': '10.3.3',
'model': 'iPhone',
'osFamily': 'iOS',
'osVersion': '15.8.3',
'clientSn': '02676BE3DD-8D86-4B4F-A666-852D1D5C9FF8',
}
response = requests.get('https://api.cloud.189.cn/mkt/userSign.action', params=params, headers=headers).text
if 'userSignResult' in response:
print('【天翼云盘】签到成功:' + re.search(r'<resultTip>(.*?)</resultTip>', response, re.DOTALL).group(1))
log('【天翼云盘】签到成功:' + re.search(r'<resultTip>(.*?)</resultTip>', response, re.DOTALL).group(1))
else:
print('【天翼云盘】签到失败:' + response)
log('【天翼云盘】签到失败:' + response)
def ssoLoginMerge(sk,skF,token):
print("注意" * 35 )
session = requests.Session()
timestamp = str(int(time.time()))
api_headers = {
'Host': 'm.cloud.189.cn',
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'user-agent': 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_8_3 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 Ecloud/10.3.3 iOS/15.8.3 clientId/02676BE3DD-8D86-4B4F-A666-749D1D5C9FF8 clientModel/iPhone proVersion/1.0.5',
'accept-language': 'zh-CN,zh-Hans;q=0.9',
'referer': 'https://m.cloud.189.cn/zt/2024/green-task-system/index.html?uxChannel=10021132000'
}
session.headers.update(api_headers)
params = {
'sessionKey': sk,
'sessionKeyFm': skF,
'eAccessToken': token,
'redirectUrl': 'https://m.cloud.189.cn/zt/2024/green-task-system/index.html?uxChannel=10021132000',
'rand': f'6947_{timestamp}',
}
# 获取cookie数据
session.get('https://m.cloud.189.cn/ssoLoginMerge.action', params=params)
# 签到
params = {
'sessionKey': sk,
'activityId': 'ACT2024cztx',
}
response = session.get('https://m.cloud.189.cn/market/signInNew.action', params=params)
if response.json().get('result'):
print('【绿色能量活动】签到成功')
log('【绿色能量活动】签到成功')
params = {
'sessionKey': sk,
'activityId': 'ACT2024cztx',
}
response = session.get('https://m.cloud.189.cn/market/signInNewInfo.action', params=params)
print('【绿色能量活动】已签到,今天是本周第' + str(response.json().get('data')) + '天签到')
else:
print('【绿色能量活动】签到失败:' + response.text)
log('【绿色能量活动】签到失败:' + response.text)
print("\n" + "-" * 50)
print('【绿色能量活动】获取新人专属任务')
params = {
'sessionKey': sk,
'activityId': 'ACT2024cztx',
'random': '0.48929593893531875',
'taskType': '1',
}
response = session.get('https://m.cloud.189.cn/market/getGreenTaskList.action', params=params).json()
new_task = get_task_info(response)
if len(new_task) > 0:
print('【绿色能量活动】获取到' + str(len(new_task)) + '个未完成新人专属任务')
for task in new_task:
task_id = task["taskId"]
task_name = task["taskName"]
data = {
'activityId': 'ACT2024cztx',
'sessionKey': sk,
'taskId': task_id,
}
response = session.post('https://m.cloud.189.cn/market/doGreenTask.action', data=data)
if response.json().get('data'):
print(f'【绿色能量活动--->新人专属任务】 任务完成: {task_name}')
else:
print(f'【绿色能量活动--->新人专属任务】 任务已跳过: {task_name}')
time.sleep(1)
else:
print('【绿色能量活动】新人专属任务已完成,跳过操作')
print("-" * 50 + "\n")
print("-" * 50)
print('【绿色能量活动】获取AI任务')
params = {
'sessionKey': sk,
'activityId': 'ACT2024cztx',
'random': '0.3382804414050936',
'taskType': '2',
}
response = session.get('https://m.cloud.189.cn/market/getGreenTaskList.action', params=params).json()
AI_task = get_task_info(response)
if len(AI_task) > 0:
print('【绿色能量活动】获取到' + str(len(AI_task)) + '个未完成日常AI任务')
for task in AI_task:
task_id = task["taskId"]
task_name = task["taskName"]
data = {
'activityId': 'ACT2024cztx',
'sessionKey': sk,
'taskId': task_id,
}
response = session.post('https://m.cloud.189.cn/market/doGreenTask.action', data=data)
if response.json().get('data'):
print(f'【绿色能量活动--->日常AI任务】 任务完成: {task_name} ')
else:
print(f'【绿色能量活动--->日常AI任务】 任务已跳过: {task_name} ')
time.sleep(1)
else:
print('【绿色能量活动】日常AI任务已完成,跳过操作')
print("-" * 50 + "\n")
print("-" * 50)
print('【绿色能量活动】获取绿动任务')
params = {
'sessionKey': sk,
'activityId': 'ACT2024cztx',
'random': '0.3382804414050936',
'taskType': '3',
}
response = session.get('https://m.cloud.189.cn/market/getGreenTaskList.action', params=params).json()
AI_task = get_task_info(response)
if len(AI_task) > 0:
print('【绿色能量活动】获取到' + str(len(AI_task)) + '个未完成绿动任务')
for task in AI_task:
task_id = task["taskId"]
task_name = task["taskName"]
data = {
'activityId': 'ACT2024cztx',
'sessionKey': sk,
'taskId': task_id,
}
response = session.post('https://m.cloud.189.cn/market/doGreenTask.action', data=data)
if response.json().get('data'):
print(f'【绿色能量活动--->绿动任务】 任务完成: {task_name} ')
else:
print(f'【绿色能量活动--->绿动任务】 任务已跳过: {task_name} ')
time.sleep(1)
else:
print('【绿色能量活动】绿动任务已完成,跳过操作')
print("-" * 50 + "\n")
# 获取绿色能量数据
params = {
'sessionKey': sk,
'activityId': 'ACT2024cztx',
}
response = requests.get('https://m.cloud.189.cn/market/getGreenLevelList.action', params=params).json()
print('【绿色能量活动】目前能量:' + str(response['data']['userScore']) + 'g')
log('【绿色能量活动】目前能量:' + str(response['data']['userScore']) + 'g'+ "\n")
print("注意" * 35 + "\n")
def main():
z = 1
for ck in cloud189_token:
try:
print('=' * 60 + '\n')
print(f'登录第{z}个账号')
print('=' * 60 + '\n')
login_result = login4MergedClient(ck)
print('\n开始签到操作>>>>>>>>>>')
if isinstance(login_result, tuple):
sessionKey = login_result[1]
sessionSecret = login_result[2]
login_name = login_result[0]
print(f'【{login_name}】登录成功')
log(f'【{login_name}】登录成功')
print('获取到的临时Session_key:' + sessionKey)
day_sign(sessionSecret, sessionKey)
print("★" * 35 + "\n")
ssoLoginMerge(sessionKey, login_result[3], ck)
else:
print(f'第{z}个账号:获取sessionKey失败,请检查accessToken是否正确')
log(f'第{z}个账号:获取sessionKey失败,请检查accessToken是否正确')
z = z + 1
except Exception as e:
print('未知错误' + str(e))
if __name__ == '__main__':
main()
try:
send_notification_message(title='天翼云盘签到') # 发送通知
except Exception as e:
print('推送出错:' + str(e))
解析
本文脚本为天翼云盘的最新签到脚本,主要用途如下:
使用在手机端抓到的 cloud189
accessToken
完成 天翼云盘登录;执行 "每日签到"(
/mkt/userSign.action
),输出签到结果;进入 "绿色能量活动" 页面,自动执行 每日/新手/绿动任务 并汇总当前能量;
支持 多账号(环境变量
cloud189_token
里用&
或@
分隔);运行结束可通过
notify.send
(若存在)统一消息推送。
关键变量
环境变量
cloud189_token
:一个或多个 accessToken,从 APP 抓包获取。
例:export cloud189_token="tokenA&tokenB"
固定的 AES key/iv 与 RSA 公钥:用于与接口对接时的加解密/签名。
主要方法
main() | cloud189_token 中的每个账号:登录 → 日常签到 → 绿色能量活动(签到+任务)→ 累计日志;最后尝试调用 send_notification_message() 推送汇总。 |
login4MergedClient(token) | 核心登录:accessToken 走 /login4MergedClient.action ,请求参数先 AES-CBC 加密,AES 密钥再用 RSA 公钥加密(epkey )。解析返回 XML 的 <ciphertext> ,AES 解密后得到 loginName / sessionKey / sessionSecret / familySessionKey 。 |
day_sign(sessionSecret, sessionKey) | 天翼云盘每日签到:userSign.action 组合字符串签名(HMAC-SHA1 ,key 为 sessionSecret ),带 SessionKey 、Date(GMT) 请求,解析 <resultTip> 成功提示。 |
ssoLoginMerge(sk,skF,token) | 绿色能量活动:
sessionKey/skF/accessToken 访问 m.cloud.189.cn/ssoLoginMerge.action 建立活动站点会话;随后: 1) market/signInNew.action 活动签到;2) getGreenTaskList.action 拉取任务(新手/AI/绿动三类);3) doGreenTask.action 逐项提交;4) getGreenLevelList.action 获取当前能量值。 |
get_task_info(data) | status == False ),返回 taskId/taskName 列表。 |
send_notification_message(title) | notify.send ,发送聚合日志到外部通知渠道。 |
aes_cbc_encrypt/ decrypt 、encrypt_aes_key 、md5_encrypt 、hmac_sha1_hex | |
generateRsakey() |
generateRsaKey.action pkId (配合登录接口)。 |
log() / 全局 send_msg | send_notification_message 推送。 |
四、执行流程(简版)
读取
cloud189_token
(多账号)。对每个账号:
a.login4MergedClient(token)
→ 拿sessionKey / sessionSecret / familySessionKey
;
b.day_sign(sessionSecret, sessionKey)
→ 主站每日签到;
c.ssoLoginMerge(sessionKey, familySessionKey, token)
→ 活动站点签到与任务;所有账号处理完后,调用
send_notification_message('天翼云盘签到')
推送汇总。
注意:
本文部分变量已做脱敏处理,仅用于测试和学习研究,禁止用于商业用途,不能保证其合法性,准确性,完整性和有效性,请根据情况自行判断。技术层面需要提供帮助,可以通过打赏的方式进行探讨。
【相关文章】
没有评论:
发表评论