# 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))