Files
smzdm_script/smzdm_task.js
Hex 0b71d792b8 feat(smzdm): 🚀 优化风控对抗逻辑并完善签到/任务流程
* **风控对抗增强**:
    * 更新 `APP_VERSION` 至 `11.1.98`。
    * 引入 `device_id` 确定性派生机制,通过 `userId` 结合 `DEVICE_SALT` 生成固定的设备串,解决跨运行设备不一致问题。
    * 优化 `sk` (设备签名) 生成逻辑,支持基于派生设备串自动计算。
    * 增加 `Cookie` 完整性检查,自动检测并提示缺失 `device_id`、`device_rid`、`z_dr` 等关键字段。
* **签到流程优化**:
    * 引入 `getCheckinCard` 接口,先渲染签到卡片以获取最新的连签状态,确保奖励判断准确。
    * 移除硬编码的 `IS_INSTALL_ZHANGDAMA` 参数。
* **任务处理优化**:
    * 增加 `getCaptchaType` 逻辑,在领取任务失败时识别验证码类型(滑块/图形),并友好提示用户手动操作。
    * 完善 `getArticleDetail` 接口,支持传递 `hashcode` 以匹配 APP 端跳转逻辑。
* **文档更新**:
    * 更新 `README.md`,详细说明 `SMZDM_SK` 的使用逻辑、设备字段缺失的影响以及如何正确抓包。
2026-10-22 01:20:56 +08:00

254 lines
5.5 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
/*
smzdm 每日任务脚本
项目地址: https://github.com/hex-ci/smzdm_script
cron: 20 14 * * *
*/
const Env = require('./env');
const {
requestApi,
removeTags,
getEnvCookies,
wait,
waitHuman,
CREATE_CENTER_VIEW,
IS_INSTALL_ZHANGDAMA
} = require('./bot');
const notify = require('./sendNotify');
const { SmzdmTaskBot } = require('./library_task');
// ------------------------------------
const $ = new Env('smzdm 每日任务');
class SmzdmNormalTaskBot extends SmzdmTaskBot {
constructor(cookie) {
super(cookie, $);
}
// 主函数
async run() {
$.log('获取任务列表');
const { tasks } = await this.getTaskList();
await waitHuman(5, 10);
let notifyMsg = '';
notifyMsg = await this.doTasks(tasks);
$.log('查询是否有限时累计活动阶段奖励');
await waitHuman(5, 15);
// 领取活动奖励
const { detail } = await this.getTaskList();
if (detail.cell_data && detail.cell_data.activity_reward_status == '1') {
$.log('有奖励,领取奖励');
await waitHuman(5, 15);
const { isSuccess } = await this.receiveActivity(detail.cell_data);
notifyMsg += `${isSuccess ? '🟢' : '❌'}限时累计活动阶段奖励领取${isSuccess ? '成功' : '失败!请查看日志'}\n`;
}
else {
$.log('无奖励');
}
return notifyMsg || '无可执行任务';
}
// 获取任务列表
async getTaskList() {
const { isSuccess, data, response } = await requestApi('https://user-api.smzdm.com/task/list_v2', {
method: 'post',
headers: this.getHeaders(),
data: {
is_install_zhangdama: IS_INSTALL_ZHANGDAMA
}
});
if (isSuccess) {
let tasks = [];
if (data.data.rows[0]?.cell_data?.activity_task?.default_list_v2) {
data.data.rows[0].cell_data.activity_task.default_list_v2.forEach(item => {
tasks = tasks.concat(item.task_list);
});
return {
tasks: tasks,
detail: data.data.rows[0]
};
}
else {
$.log(`任务列表获取失败!${response}`);
return {
tasks: [],
detail: {}
};
}
}
else {
$.log(`任务列表获取失败!${response}`);
return {
tasks: [],
detail: {}
};
}
}
// 领取活动奖励
async receiveActivity(activity) {
$.log(`领取奖励: ${activity.activity_name}`);
const { isSuccess, data, response } = await requestApi('https://user-api.smzdm.com/task/activity_receive', {
method: 'post',
headers: this.getHeaders(),
data: {
activity_id: activity.activity_id
}
});
if (isSuccess) {
$.log(removeTags(data.data.reward_msg));
return {
isSuccess
};
}
else {
$.log(`领取奖励失败!${response}`);
return {
isSuccess
};
}
}
// 领取任务奖励
async receiveReward(taskId) {
const robotToken = await this.getRobotToken();
if (robotToken === false) {
return {
isSuccess: false,
msg: '领取任务奖励失败!'
};
}
// 客户端初始化验证码组件时就会查一次,用来说明被要求的是哪种验证码
const captchaType = await this.getCaptchaType();
const { isSuccess, data, response } = await requestApi('https://user-api.smzdm.com/task/activity_task_receive', {
method: 'post',
headers: this.getHeaders(),
data: {
robot_token: robotToken,
geetest_seccode: '',
geetest_validate: '',
geetest_challenge: '',
captcha: '',
task_id: taskId
}
});
if (isSuccess) {
const msg = removeTags(data.data.reward_msg);
$.log(msg);
return {
isSuccess,
msg
};
}
// 110202 = 服务端要求人机验证,空验证码一定过不了
if (data.error_code == '110202') {
const type = captchaType === 'geetest' ? '滑块' : '图形';
$.log(`🟡[${taskId}] 领取需要${type}验证码,脚本无法通过,请到 APP 内手动领取`);
return {
isSuccess: false,
msg: '需要验证码'
};
}
$.log(`领取任务奖励失败!${response}`);
return {
isSuccess,
msg: '领取任务奖励失败!'
};
}
// 验证码类型:geetest 走滑块,其余走图形
async getCaptchaType() {
const { isSuccess, data, response } = await requestApi('https://user-api.smzdm.com/getcaptcha/switch', {
method: 'post',
headers: this.getHeaders(),
data: {
token: this.token,
create_center_view: CREATE_CENTER_VIEW
}
});
if (isSuccess && data.data) {
return data.data.type || '';
}
$.log(`获取验证码配置失败!${response}`);
return '';
}
}
!(async () => {
const cookies = getEnvCookies();
if (cookies === false) {
$.log('\n请先设置 SMZDM_COOKIE 环境变量');
return;
}
let notifyContent = '';
for (let i = 0; i < cookies.length; i++) {
const cookie = cookies[i];
if (!cookie) {
continue;
}
if (i > 0) {
$.log();
await wait(10, 30);
$.log();
}
const sep = `\n****** 账号${i + 1} ******\n`;
$.log(sep);
const bot = new SmzdmNormalTaskBot(cookie);
const msg = await bot.run();
notifyContent += `${sep}${msg}\n`;
}
$.log();
await notify.sendNotify($.name, notifyContent);
})().catch((e) => {
$.log('', `❌ ${$.name}, 失败! 原因: ${e}!`, '')
}).finally(() => {
$.done();
});