297 lines
12 KiB
Python
297 lines
12 KiB
Python
# Source: https://github.com/lksky8/sign-ql/blob/main/jksign.py
|
||
# Raw: https://raw.githubusercontent.com/lksky8/sign-ql/main/jksign.py
|
||
# Repo: lksky8/sign-ql
|
||
# Path: jksign.py
|
||
# UploadedAt: 2025-12-07T17:42:50Z
|
||
# SHA256: b722f903ef41b1cab2540fc2a7b84bb51cb2e8d354783a225e3c364b0799a4e6
|
||
# Category: web版/账密
|
||
# Evidence: web/H5关键词 + username/password/login
|
||
|
||
"""
|
||
方舟健客app签到
|
||
作者:https://github.com/lksky8/sign-ql
|
||
日期:2025-12-5
|
||
|
||
使用方法:APP抓登录包获取refresh_token填入jktoken
|
||
|
||
支持多用户运行,多用户用&或者@隔开
|
||
|
||
则变量为
|
||
export jktoken="eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9........&eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9........"
|
||
|
||
每日签到一次即可
|
||
cron: 0 5 * * *
|
||
const $ = new Env("方舟健客签到");
|
||
"""
|
||
import time
|
||
import requests
|
||
import re
|
||
import os
|
||
import datetime
|
||
import hashlib
|
||
|
||
#推送开关,开启为True,关闭为False
|
||
push_message = True
|
||
|
||
|
||
def md5_encrypt(text):
|
||
md5_hash = hashlib.md5()
|
||
md5_hash.update(text.encode('utf-8'))
|
||
md5_result = md5_hash.hexdigest()
|
||
return md5_result
|
||
|
||
def time13():
|
||
now = datetime.datetime.now()
|
||
timestamp_ms = int(now.timestamp() * 1000) + (now.microsecond // 1000)
|
||
return timestamp_ms
|
||
|
||
|
||
def get_jkx():
|
||
a = time13() - 1500000000000
|
||
j = a % 999983
|
||
j2 = a % 9973
|
||
h = "6470"
|
||
md5_1 = md5_encrypt(f"39CC231D-C1F9-48DC-93DA-4CA0EA53C141{j}{h}")
|
||
md5_2 = md5_encrypt(f"{md5_1}{j2}{h}")
|
||
return f'{j}#{md5_2}#{j2}#{h}'
|
||
|
||
|
||
api_headers = {
|
||
'Host': 'acgi.jianke.com',
|
||
'Accept': 'application/json, text/plain, */*',
|
||
'Sec-Fetch-Site': 'same-site',
|
||
'Accept-Language': 'zh-CN,zh-Hans;q=0.9',
|
||
'platform': 'APP',
|
||
'Sec-Fetch-Mode': 'cors',
|
||
'Origin': 'https://app-hybrid.jianke.com',
|
||
'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 jiankeMall/6.47.0 JiankeMall/6.47.0',
|
||
'Referer': 'https://app-hybrid.jianke.com/',
|
||
'Content-Type': 'application/json;charset=utf-8',
|
||
'Sec-Fetch-Dest': 'empty',
|
||
}
|
||
|
||
api_headers2 = {
|
||
'Host': 'fe-acgi.jianke.com',
|
||
'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 jiankeMall/6.47.0',
|
||
'versionName': '6.47.0',
|
||
'X-JK-UDID': '39CC231D-C1F9-48DC-93DA-4CA0EA53C141',
|
||
'versionCode': '6470',
|
||
'X-JK-X': get_jkx(),
|
||
'platform': 'APP',
|
||
'Accept-Language': 'zh-Hans-CN;q=1',
|
||
'Accept': 'application/json',
|
||
'Content-Type': 'application/json',
|
||
}
|
||
|
||
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 refresh_token(token):
|
||
headers = {'Content-Type': 'application/json; charset=utf-8','User-Agent': 'Mozilla/5.0 (Linux; Android 10; MI 8 Build/QKQ1.190828.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/131.0.6778.135 Mobile Safari/537.36 jiankeMall/6.26.0(w1080*h2029)','Host': 'acgi.jianke.com','organizationCode': 'app.jianke'}
|
||
data = {'refreshToken': token }
|
||
response = requests.post('https://acgi.jianke.com/passport/account/refreshToken', json=data, headers=headers)
|
||
if '授权失败' in response.text:
|
||
print('账号刷新token已失效,请重新获取')
|
||
Log('账号刷新token已失效,请重新获取')
|
||
return False
|
||
else:
|
||
response_json = response.json()
|
||
if response_json['token_type'] == 'bearer':
|
||
print("账号token刷新成功,新的access_token已填入:\n" + response_json['access_token'])
|
||
return response_json['access_token']
|
||
else:
|
||
print("Failed to send POST request. Status Code:", response.status_code)
|
||
print("出错了:", response.text)
|
||
|
||
|
||
def do_sign(new_token,user_name):
|
||
# headers = api_headers2.copy()
|
||
# headers['Authorization'] = f'bearer {new_token}'
|
||
headers = {'Authorization':'bearer ' + new_token,'User-Agent': 'Mozilla/5.0 (Linux; Android 10; MI 8 Build/QKQ1.190828.002; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/131.0.6778.135 Mobile Safari/537.36 jiankeMall/6.26.0(w1080*h2029)','X-JK-X': get_jkx(),'versionName': '6.47.0','X-JK-UDID': '39CC231D-C1F9-48DC-93DA-4CA0EA53C141'}
|
||
dl = requests.put('https://acgi.jianke.com/v2/member/signConfig/sign', headers=headers)
|
||
dl_json = dl.json()
|
||
if dl.status_code == 200:
|
||
print(f"[{user_name}] 本次签到获得:{dl_json['coinNum']}金币,今天是本周第{dl_json['cumulativeNum']}天签到")
|
||
Log(f"\n{user_name}] 本次签到获得:{dl_json['coinNum']}金币,今天是本周第{dl_json['cumulativeNum']}天签到")
|
||
elif dl_json['message'] == '今日已签到':
|
||
print(f'[{user_name}] 今天已经签到了')
|
||
Log(f'\n[{user_name}] 今天已经签到了')
|
||
else:
|
||
print("出错了:", dl.text)
|
||
|
||
def today_question(new_token,task_id,user_name):
|
||
headers = api_headers.copy()
|
||
headers['Authorization'] = f'bearer {new_token}'
|
||
response = requests.get('https://acgi.jianke.com/support/coin/task/daily-tasks/today-question', headers=headers)
|
||
response_json = response.json()
|
||
if response_json['code'] == '0' and response_json['message'] == 'success':
|
||
print(f'[{user_name}]【每日一答】 任务获取成功')
|
||
question_id = response_json['data']['id']
|
||
rightChoice = response_json['data']['rightChoice']
|
||
json_data = {
|
||
'id': str(task_id),
|
||
'questionItem': {
|
||
'id': question_id,
|
||
'rightChoice': rightChoice,
|
||
'userChoice': rightChoice,
|
||
'roundNum': 1,
|
||
},
|
||
}
|
||
response = requests.post('https://acgi.jianke.com/support/coin/task/complete', headers=headers, json=json_data)
|
||
response_json = response.json()
|
||
if response_json['code'] == '0' and response_json['message'] == 'success':
|
||
print(f'[{user_name}]【每日一答】 任务完成')
|
||
Log(f'[{user_name}]【每日一答】 任务完成')
|
||
else:
|
||
print(f'[{user_name}]【每日一答】 {response_json["message"]}')
|
||
Log(f'[{user_name}]【每日一答】 {response_json["message"]}')
|
||
else:
|
||
print(f'[{user_name}]【每日一答】 任务获取失败')
|
||
Log(f'[{user_name}]【每日一答】 任务获取失败')
|
||
print(response.text)
|
||
|
||
def get_today_tasks(new_token, user_name):
|
||
headers = api_headers.copy()
|
||
headers['Authorization'] = f'bearer {new_token}'
|
||
response = requests.get('https://acgi.jianke.com/support/coin/task/daily-tasks', headers=headers)
|
||
if response.status_code == 200:
|
||
response_json = response.json()
|
||
task_list = []
|
||
for item in response_json['data']:
|
||
task_id = item['id']
|
||
task_name = item['taskName']
|
||
task_list.append({'task_id': task_id, 'task_name': task_name})
|
||
return task_list
|
||
else:
|
||
print(f'{user_name} 获取任务数据失败')
|
||
print(response.text)
|
||
return None
|
||
|
||
def do_task(new_token,user_name, task_id, task_name):
|
||
headers = api_headers.copy()
|
||
headers['Authorization'] = f'bearer {new_token}'
|
||
json_data = {
|
||
'id': str(task_id)
|
||
}
|
||
response = requests.post('https://acgi.jianke.com/support/coin/task/complete', headers=headers, json=json_data)
|
||
response_json = response.json()
|
||
if response_json['code'] == '0' and response_json['message'] == 'success':
|
||
print(f'[{user_name}]【{task_name}】 任务完成')
|
||
Log(f'[{user_name}]【{task_name}】 任务完成')
|
||
else:
|
||
print(f'[{user_name}]【{task_name}】 {response_json["message"]}')
|
||
Log(f'[{user_name}]【{task_name}】 {response_json["message"]}')
|
||
|
||
def task_receive(new_token, user_name, task_id,task_name):
|
||
headers = api_headers.copy()
|
||
headers['Authorization'] = f'bearer {new_token}'
|
||
json_data = {
|
||
'id': task_id,
|
||
}
|
||
response = requests.post('https://acgi.jianke.com/support/coin/task/receive', headers=headers, json=json_data)
|
||
response_json = response.json()
|
||
if response_json['code'] == '0' and response_json['message'] == 'success':
|
||
print(f'[{user_name}]【{task_name}】 任务奖励:领取成功')
|
||
elif response_json['message'] == '奖励领取失败':
|
||
print(f'[{user_name}]【{task_name}】 任务奖励:领取失败')
|
||
Log(f'[{user_name}]【{task_name}】 任务奖励:领取失败')
|
||
else:
|
||
print('奖励领取失败')
|
||
print(response.text)
|
||
|
||
def get_coin(new_token, user_name):
|
||
headers = api_headers.copy()
|
||
headers['Authorization'] = f'bearer {new_token}'
|
||
response = requests.get('https://acgi.jianke.com/v1/coin/balance', headers=headers)
|
||
if response.status_code == 200:
|
||
response_json = response.json()
|
||
print(f'[{user_name}] 当前健康币:{response_json["balance"]}')
|
||
Log(f'[{user_name}] 当前健康币:{response_json["balance"]}')
|
||
else:
|
||
print('获取金币数失败')
|
||
print(response.text)
|
||
|
||
def get_userinfo(new_token):
|
||
headers = api_headers2.copy()
|
||
headers['Authorization'] = f'bearer {new_token}'
|
||
response = requests.get('https://fe-acgi.jianke.com/v5/userCenter', headers=headers)
|
||
response_json = response.json()
|
||
if response_json['statusCode'] == 200:
|
||
return response_json['data']['memberInfo']['nickName']
|
||
else:
|
||
print('获取用户信息失败')
|
||
print(response.text)
|
||
return None
|
||
|
||
|
||
if __name__ == '__main__':
|
||
if 'jktoken' in os.environ:
|
||
jktoken = re.split("@|&", os.environ.get("jktoken"))
|
||
print(f'查找到{len(jktoken)}个账号')
|
||
else:
|
||
jktoken = []
|
||
print('未填写 jktoken 变量')
|
||
|
||
if jktoken:
|
||
try:
|
||
z = 1
|
||
for ck in jktoken:
|
||
print(f'登录第{z}个账号')
|
||
print('----------------------\n')
|
||
access_token = refresh_token(ck)
|
||
if access_token:
|
||
user_nickname = get_userinfo(access_token)
|
||
print(f'[{user_nickname}] 刷新token成功')
|
||
print('\n开始签到操作>>>>>>>>>>\n')
|
||
do_sign(access_token, user_nickname)
|
||
print('\n开始执行任务>>>>>>>>>>\n')
|
||
task_data = get_today_tasks(access_token, user_nickname)
|
||
if task_data:
|
||
for task in task_data:
|
||
task_id = task['task_id']
|
||
task_name = task['task_name']
|
||
# print(f'[{user_nickname}] 开始执行任务:{task_name}')
|
||
if task_name == '每日一答':
|
||
today_question(access_token, task_id, user_nickname)
|
||
time.sleep(1)
|
||
task_receive(access_token, user_nickname, task_id, task_name)
|
||
time.sleep(2)
|
||
continue
|
||
if task_name == '下单返币':
|
||
continue
|
||
if task_name == '打开健客医生App':
|
||
continue
|
||
do_task(access_token, user_nickname, task_id, task_name)
|
||
time.sleep(1)
|
||
task_receive(access_token, user_nickname, task_id, task_name)
|
||
time.sleep(3)
|
||
get_coin(access_token, user_nickname)
|
||
print('\n----------------------')
|
||
z = z + 1
|
||
except Exception as e:
|
||
print('未知错误:' + str(e))
|
||
if push_message:
|
||
try:
|
||
send_notification_message(title='方舟健客') # 发送通知
|
||
except Exception as e:
|
||
print('推送失败:' + str(e))
|
||
|