mirror of
https://github.com/hex-ci/smzdm_script.git
synced 2026-10-28 19:23:43 +08:00
feat(smzdm): 🚀 更新 App 版本并优化请求签名与风控对抗
* 升级 `APP_VERSION` 至 `11.1.95`,并同步更新 `APP_VERSION_REV`。
* 引入服务器时间同步机制:通过 `SERVER_TIME_URL` 获取服务端时间,解决本地时间偏差导致的签名失效问题。
* 优化签名算法:改进 `signFormData` 的实现,确保参数排序与空格处理符合最新 App 逻辑。
* 增强风控对抗能力:
* 引入 `waitHuman` 模拟人类行为的等待机制,替换原有的固定 `wait`。
* 在任务执行逻辑中加入随机打乱(Shuffle)机制,降低行为模式特征。
* 增加对 WAF/风控拦截(如 403/429 错误或 HTML 验证码页)的识别与处理逻辑。
* 完善功能细节:
* 支持 `SMZDM_COMMENT` 环境变量配置多条文案(使用 `|` 分隔),实现随机评论以降低风险。
* 修复签到逻辑,支持 `CREATE_CENTER_VIEW` 和 `IS_INSTALL_ZHANGDAMA` 等新增参数。
* 优化任务列表获取,增加对 `is_install_zhangdama` 字段的支持。
* 文档更新:在 `README.md` 中补充了新增任务类型及环境变量的使用说明。
This commit is contained in:
@@ -20,6 +20,10 @@
|
||||
* 关注用户
|
||||
* 关注栏目
|
||||
* 关注品牌
|
||||
* 站外浏览
|
||||
* 打开第三方 App
|
||||
* 开启推送
|
||||
* 创建桌面签到快捷方式
|
||||
* 限时累计活动
|
||||
* 全民众测能量值任务
|
||||
|
||||
@@ -62,7 +66,7 @@ ql repo https://github.com/hex-ci/smzdm_script.git "smzdm_" "" "env.js|bot.js|se
|
||||
* `SMZDM_SK`: 这个值是可选值,会自动计算,如果你一定想用自己的,可以抓取,是从安卓 App 的 `https://user-api.smzdm.com/checkin` 请求参数中抓包抓到的,多用户可以用 `&` 分隔,或者使用多个同名环境变量,顺序要保持与 `SMZDM_COOKIE` 多用户顺序一致。
|
||||
* `SMZDM_USER_AGENT_APP`: 这个值是可选值,是指 APP 的 User-Agent,从 APP 的 API 请求头中抓包得到,建议抓取 Android 的 User-Agent,不填使用脚本默认值。
|
||||
* `SMZDM_USER_AGENT_WEB`: 这个值是可选值,是指 APP 中访问网页的 User-Agent,一般在 APP 内的转盘网页中抓包得到,建议抓取 Android 的 User-Agent,不填使用脚本默认值。
|
||||
* `SMZDM_COMMENT`: 如果要完成评论文章的任务请设置这个环境变量,环境变量的内容是评论的文案,文案要大于 10 个汉字,建议用比较个性化的文案,脚本发布评论后会删除这条评论,但是为防止删除失败的情况,请尽量用好一点的文案,防止被判定为恶意灌水。
|
||||
* `SMZDM_COMMENT`: 如果要完成评论文章的任务请设置这个环境变量,环境变量的内容是评论的文案,文案要大于 10 个汉字,建议用比较个性化的文案,脚本发布评论后会删除这条评论,但是为防止删除失败的情况,请尽量用好一点的文案,防止被判定为恶意灌水。可以写多条文案(用换行或 `|` 分隔,每条都要大于 10 个汉字),脚本每次随机选一条,避免每天发同样的内容。
|
||||
* `SMZDM_CROWD_SILVER_5`: 每日抽奖任务默认只进行免费抽奖,如要进行 5 碎银子的抽奖,请设置这个环境变量的值为 `yes`,请注意,只有在没有免费抽奖的时候,才会执行非免费抽奖,而且,这个抽奖不是转盘抽奖。
|
||||
* `SMZDM_CROWD_KEYWORD`: 抽奖关键词,执行非免费抽奖时,会优先选择包含此关键词的抽奖,如果未找到包含此关键词的抽奖,则会随机选择一个。
|
||||
* `SMZDM_TASK_TESTING`: 是否运行全民众测能量值任务,如要运行此任务,请设置这个环境变量的值为 `yes`,否则不运行。
|
||||
|
||||
134
bot.js
134
bot.js
@@ -3,28 +3,62 @@ const got = require('got');
|
||||
|
||||
// ------------------------------------
|
||||
|
||||
const APP_VERSION = '10.4.26';
|
||||
const APP_VERSION_REV = '866';
|
||||
const APP_VERSION = '11.1.95';
|
||||
const APP_VERSION_REV = '1195';
|
||||
|
||||
const DEFAULT_USER_AGENT_APP = `smzdm_android_V${APP_VERSION} rv:${APP_VERSION_REV} (Redmi Note 3;Android10.0;zh)smzdmapp`;
|
||||
const DEFAULT_USER_AGENT_WEB = `Mozilla/5.0 (Linux; Android 10.0; Redmi Build/Redmi Note 3; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/95.0.4638.74 Mobile Safari/537.36 smzdm_android_V${APP_VERSION} rv:${APP_VERSION_REV} (Redmi;Android10.0;zh) jsbv_1.0.0 webv_2.0 smzdmapp`;
|
||||
|
||||
const SIGN_KEY = 'apr1$AwP!wRRT$gJ/q.X24poeBInlUJC';
|
||||
|
||||
const ZHUANZAI_AB = '';
|
||||
|
||||
// 无法从设备侧还原的本地开关取值,与全新安装的 APP 行为一致
|
||||
const CREATE_CENTER_VIEW = '';
|
||||
const IS_INSTALL_ZHANGDAMA = '0';
|
||||
|
||||
// APP 用 HTTP Date 头作为签名时间,且偏差超过 5 分钟会重新获取
|
||||
const SERVER_TIME_URL = 'https://app-api.smzdm.com/get_server_time';
|
||||
const SERVER_TIME_MAX_AGE = 5 * 60 * 1000;
|
||||
|
||||
// ------------------------------------
|
||||
|
||||
let serverTime = 0;
|
||||
let serverTimeFetchedAt = 0;
|
||||
|
||||
const reVersion = /(smzdm_android_V|smzdm\s|iphone_smzdmapp\/)([\d.]+)/i;
|
||||
const reRev = /rv:([\d.]+)/i;
|
||||
|
||||
const randomStr = (len = 18) => {
|
||||
const char = '0123456789';
|
||||
let str = '';
|
||||
// request_key = 8 位随机数 + 秒级时间戳
|
||||
const requestKey = () => `${Math.floor(Math.random() * 90000000) + 10000000}${Math.floor(Date.now() / 1000)}`;
|
||||
|
||||
for (let i = 0; i < len; i++) {
|
||||
str += char.charAt(Math.floor(Math.random() * char.length));
|
||||
const getServerTime = async () => {
|
||||
if (serverTime && Date.now() - serverTimeFetchedAt <= SERVER_TIME_MAX_AGE) {
|
||||
return serverTime;
|
||||
}
|
||||
|
||||
return str;
|
||||
try {
|
||||
// APP 直接读 HTTP Date 头,不关心状态码,取不到才回退本地时间
|
||||
const response = await got(SERVER_TIME_URL, {
|
||||
method: 'GET',
|
||||
throwHttpErrors: false,
|
||||
retry: {
|
||||
limit: 0
|
||||
}
|
||||
});
|
||||
|
||||
const date = new Date(response.headers.date).getTime();
|
||||
|
||||
if (date) {
|
||||
serverTime = date;
|
||||
serverTimeFetchedAt = Date.now();
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
console.log(`获取服务器时间失败,使用本地时间: ${error.message}`);
|
||||
}
|
||||
|
||||
return serverTime || Date.now();
|
||||
};
|
||||
|
||||
const parseJSON = (str) => {
|
||||
@@ -39,19 +73,20 @@ const parseJSON = (str) => {
|
||||
const removeTags = (str) => str.replace(/<[^<]+?>/g, '');
|
||||
|
||||
// 添加公共参数并签名数据
|
||||
const signFormData = (data) => {
|
||||
const signFormData = async (data) => {
|
||||
const newData = {
|
||||
weixin: 1,
|
||||
basic_v: 0,
|
||||
f: 'android',
|
||||
v: APP_VERSION,
|
||||
time: `${Math.round(new Date().getTime() / 1000)}000`,
|
||||
time: `${Math.round((await getServerTime()) / 1000)}000`,
|
||||
zhuanzai_ab: ZHUANZAI_AB,
|
||||
...data
|
||||
};
|
||||
|
||||
const keys = Object.keys(newData).filter(key => newData[key] !== '').sort();
|
||||
const signData = keys.map(key => `${key}=${String(newData[key]).replace(/\s+/, '')}`).join('&');
|
||||
const sign = crypto.createHash('md5').update(`${signData}&key=${SIGN_KEY}`).digest('hex').toUpperCase();
|
||||
const signData = keys.map(key => `${key}=${newData[key]}`).join('&');
|
||||
const sign = crypto.createHash('md5').update(`${signData.replace(/ /g, '')}&key=${SIGN_KEY}`).digest('hex').toUpperCase();
|
||||
|
||||
return {
|
||||
...newData,
|
||||
@@ -74,7 +109,7 @@ const requestApi = async (url, inputOptions = {}) => {
|
||||
Object.keys(options.data).forEach(key => options.data[key] === undefined && delete options.data[key]);
|
||||
|
||||
if (options.sign !== false) {
|
||||
options.data = signFormData(options.data);
|
||||
options.data = await signFormData(options.data);
|
||||
}
|
||||
|
||||
const gotOptions = {
|
||||
@@ -139,10 +174,22 @@ const requestApi = async (url, inputOptions = {}) => {
|
||||
})
|
||||
};
|
||||
|
||||
const updateCookie = (cookie, name, value) => {
|
||||
const re = new RegExp(`(^|;)${name}=[^;]+;`, 'ig');
|
||||
// APP 每次请求都用自己维护的字段重建 Cookie,缺失的字段需要补上
|
||||
const setCookie = (cookie, name, value) => {
|
||||
const re = new RegExp(`(^|;)\\s*${name}=[^;]+`, 'i');
|
||||
|
||||
return cookie.replace(re, `$1${name}=${encodeURIComponent(value)};`);
|
||||
if (re.test(cookie)) {
|
||||
return cookie.replace(re, `$1${name}=${encodeURIComponent(value)}`);
|
||||
}
|
||||
|
||||
return `${cookie.replace(/;?\s*$/, ';')} ${name}=${encodeURIComponent(value)};`;
|
||||
};
|
||||
|
||||
// APP 不发送这些历史字段,保留会导致请求与 APP 不一致
|
||||
const removeCookie = (cookie, name) => {
|
||||
const re = new RegExp(`(^|;)\\s*${name}=[^;]+;?`, 'ig');
|
||||
|
||||
return cookie.replace(re, '$1');
|
||||
};
|
||||
|
||||
const getEnvCookies = () => {
|
||||
@@ -179,6 +226,14 @@ const wait = (minSecond, maxSecond) => {
|
||||
return new Promise(resolve => setTimeout(resolve, randomSecond * 1000));
|
||||
};
|
||||
|
||||
const waitHuman = async (minSecond, maxSecond) => {
|
||||
await wait(minSecond, maxSecond);
|
||||
|
||||
if (Math.random() < 0.05) {
|
||||
await wait(15, 45);
|
||||
}
|
||||
};
|
||||
|
||||
// ------------------------------------
|
||||
|
||||
class SmzdmBot {
|
||||
@@ -190,16 +245,23 @@ class SmzdmBot {
|
||||
|
||||
// 处理 cookie
|
||||
this.androidCookie = this.cookie.replace('iphone', 'android').replace('iPhone', 'Android');
|
||||
this.androidCookie = updateCookie(this.androidCookie, 'smzdm_version', APP_VERSION);
|
||||
this.androidCookie = updateCookie(this.androidCookie, 'device_smzdm_version', APP_VERSION);
|
||||
this.androidCookie = updateCookie(this.androidCookie, 'v', APP_VERSION);
|
||||
this.androidCookie = updateCookie(this.androidCookie, 'device_smzdm_version_code', APP_VERSION_REV);
|
||||
this.androidCookie = updateCookie(this.androidCookie, 'device_system_version', '10.0');
|
||||
this.androidCookie = updateCookie(this.androidCookie, 'apk_partner_name', 'smzdm_download');
|
||||
this.androidCookie = updateCookie(this.androidCookie, 'partner_name', 'smzdm_download');
|
||||
this.androidCookie = updateCookie(this.androidCookie, 'device_type', 'Android');
|
||||
this.androidCookie = updateCookie(this.androidCookie, 'device_smzdm', 'android');
|
||||
this.androidCookie = updateCookie(this.androidCookie, 'device_name', 'Android');
|
||||
this.androidCookie = setCookie(this.androidCookie, 'v', APP_VERSION);
|
||||
this.androidCookie = setCookie(this.androidCookie, 'device_smzdm_version_code', APP_VERSION_REV);
|
||||
this.androidCookie = setCookie(this.androidCookie, 'device_system_version', '10.0');
|
||||
this.androidCookie = setCookie(this.androidCookie, 'apk_partner_name', 'smzdm_download');
|
||||
this.androidCookie = setCookie(this.androidCookie, 'partner_name', 'smzdm_download');
|
||||
this.androidCookie = setCookie(this.androidCookie, 'device_smzdm', 'android');
|
||||
this.androidCookie = setCookie(this.androidCookie, 'f', 'android');
|
||||
this.androidCookie = setCookie(this.androidCookie, 'basic_v', '0');
|
||||
|
||||
[
|
||||
'smzdm_version',
|
||||
'device_smzdm_version',
|
||||
'device_type',
|
||||
'device_name'
|
||||
].forEach(name => {
|
||||
this.androidCookie = removeCookie(this.androidCookie, name);
|
||||
});
|
||||
}
|
||||
|
||||
getHeaders() {
|
||||
@@ -215,7 +277,7 @@ class SmzdmBot {
|
||||
Accept: '*/*',
|
||||
'Accept-Language': 'zh-Hans-CN;q=1',
|
||||
'Accept-Encoding': 'gzip',
|
||||
'request_key': randomStr(18),
|
||||
'request_key': requestKey(),
|
||||
'User-Agent': userAgent,
|
||||
Cookie: this.androidCookie
|
||||
};
|
||||
@@ -242,6 +304,18 @@ class SmzdmBot {
|
||||
getOneByRandom(listing) {
|
||||
return listing[Math.floor(Math.random() * listing.length)];
|
||||
}
|
||||
|
||||
// 打乱顺序
|
||||
getShuffled(listing) {
|
||||
const result = listing.slice();
|
||||
|
||||
for (let i = result.length - 1; i > 0; i--) {
|
||||
const j = Math.floor(Math.random() * (i + 1));
|
||||
[result[i], result[j]] = [result[j], result[i]];
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
@@ -250,5 +324,9 @@ module.exports = {
|
||||
removeTags,
|
||||
parseJSON,
|
||||
getEnvCookies,
|
||||
wait
|
||||
getServerTime,
|
||||
CREATE_CENTER_VIEW,
|
||||
IS_INSTALL_ZHANGDAMA,
|
||||
wait,
|
||||
waitHuman
|
||||
};
|
||||
|
||||
428
library_task.js
428
library_task.js
@@ -1,4 +1,10 @@
|
||||
const { SmzdmBot, requestApi, removeTags, wait } = require('./bot');
|
||||
const {
|
||||
SmzdmBot,
|
||||
requestApi,
|
||||
removeTags,
|
||||
wait,
|
||||
waitHuman
|
||||
} = require('./bot');
|
||||
|
||||
// ------------------------------------
|
||||
|
||||
@@ -13,8 +19,10 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
async doTasks(tasks) {
|
||||
let notifyMsg = '';
|
||||
|
||||
for (let i = 0; i < tasks.length; i++) {
|
||||
const task = tasks[i];
|
||||
const list = this.getShuffled(tasks);
|
||||
|
||||
for (let i = 0; i < list.length; i++) {
|
||||
const task = list[i];
|
||||
|
||||
// 待领取任务
|
||||
if (task.task_status == '3') {
|
||||
@@ -24,7 +32,7 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
|
||||
notifyMsg += `${isSuccess ? '🟢' : '❌'}领取[${task.task_name}]奖励${isSuccess ? '成功' : '失败!请查看日志'}\n`;
|
||||
|
||||
await wait(5, 15);
|
||||
await waitHuman(5, 15);
|
||||
}
|
||||
// 未完成任务
|
||||
else if (task.task_status == '2') {
|
||||
@@ -34,7 +42,7 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
|
||||
notifyMsg += this.getTaskNotifyMessage(isSuccess, task);
|
||||
|
||||
await wait(5, 15);
|
||||
await waitHuman(5, 15);
|
||||
}
|
||||
// 分享任务
|
||||
else if (task.task_event_type == 'interactive.share') {
|
||||
@@ -42,7 +50,7 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
|
||||
notifyMsg += this.getTaskNotifyMessage(isSuccess, task);
|
||||
|
||||
await wait(5, 15);
|
||||
await waitHuman(5, 15);
|
||||
}
|
||||
// 抽奖任务
|
||||
else if (task.task_event_type == 'guide.crowd') {
|
||||
@@ -52,7 +60,7 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
notifyMsg += this.getTaskNotifyMessage(isSuccess, task);
|
||||
}
|
||||
|
||||
await wait(5, 15);
|
||||
await waitHuman(5, 15);
|
||||
}
|
||||
// 关注用户任务
|
||||
else if (task.task_event_type == 'interactive.follow.user') {
|
||||
@@ -60,7 +68,7 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
|
||||
notifyMsg += this.getTaskNotifyMessage(isSuccess, task);
|
||||
|
||||
await wait(5, 15);
|
||||
await waitHuman(5, 15);
|
||||
}
|
||||
// 关注栏目任务
|
||||
else if (task.task_event_type == 'interactive.follow.tag') {
|
||||
@@ -68,7 +76,7 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
|
||||
notifyMsg += this.getTaskNotifyMessage(isSuccess, task);
|
||||
|
||||
await wait(5, 15);
|
||||
await waitHuman(5, 15);
|
||||
}
|
||||
// 关注品牌
|
||||
else if (task.task_event_type == 'interactive.follow.brand') {
|
||||
@@ -76,7 +84,7 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
|
||||
notifyMsg += this.getTaskNotifyMessage(isSuccess, task);
|
||||
|
||||
await wait(5, 15);
|
||||
await waitHuman(5, 15);
|
||||
}
|
||||
// 收藏任务
|
||||
else if (task.task_event_type == 'interactive.favorite') {
|
||||
@@ -84,7 +92,7 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
|
||||
notifyMsg += this.getTaskNotifyMessage(isSuccess, task);
|
||||
|
||||
await wait(5, 15);
|
||||
await waitHuman(5, 15);
|
||||
}
|
||||
// 点赞任务
|
||||
else if (task.task_event_type == 'interactive.rating') {
|
||||
@@ -92,21 +100,67 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
|
||||
notifyMsg += this.getTaskNotifyMessage(isSuccess, task);
|
||||
|
||||
await wait(5, 15);
|
||||
await waitHuman(5, 15);
|
||||
}
|
||||
// 评论任务
|
||||
else if (task.task_event_type == 'interactive.comment') {
|
||||
if (process.env.SMZDM_COMMENT && String(process.env.SMZDM_COMMENT).length > 10) {
|
||||
const { isSuccess } = await this.doCommentTask(task);
|
||||
const comment = this.getCommentContent();
|
||||
|
||||
if (comment) {
|
||||
const { isSuccess } = await this.doCommentTask(task, comment);
|
||||
|
||||
notifyMsg += this.getTaskNotifyMessage(isSuccess, task);
|
||||
|
||||
await wait(5, 15);
|
||||
await waitHuman(5, 15);
|
||||
}
|
||||
else {
|
||||
this.$env.log('🟡请设置 SMZDM_COMMENT 环境变量后才能做评论任务!');
|
||||
}
|
||||
}
|
||||
// 站外浏览任务
|
||||
else if (task.task_event_type == 'interactive.view.zhanwai') {
|
||||
const { isSuccess } = await this.doViewZhanwaiTask(task);
|
||||
|
||||
notifyMsg += this.getTaskNotifyMessage(isSuccess, task);
|
||||
|
||||
await waitHuman(5, 15);
|
||||
}
|
||||
// 打开第三方 App 任务
|
||||
else if (task.task_event_type == 'interactive.open_third_party_app') {
|
||||
const { isSuccess } = await this.doOpenThirdPartyTask(task);
|
||||
|
||||
notifyMsg += this.getTaskNotifyMessage(isSuccess, task);
|
||||
|
||||
await waitHuman(5, 15);
|
||||
}
|
||||
// 开启推送任务
|
||||
else if (task.task_event_type == 'guide.open_app_push') {
|
||||
const { isSuccess } = await this.doOpenAppPushTask(task);
|
||||
|
||||
notifyMsg += this.getTaskNotifyMessage(isSuccess, task);
|
||||
|
||||
await waitHuman(5, 15);
|
||||
}
|
||||
// 创建桌面签到快捷方式任务
|
||||
else if (task.task_event_type == 'guide.create_app_checkin_shortcut') {
|
||||
const { isSuccess } = await this.doCreateCheckinShortcutTask(task);
|
||||
|
||||
notifyMsg += this.getTaskNotifyMessage(isSuccess, task);
|
||||
|
||||
await waitHuman(5, 15);
|
||||
}
|
||||
// 爆料任务,静默跳过
|
||||
else if (task.task_event_type == 'publish.baoliao_new') {
|
||||
continue;
|
||||
}
|
||||
// 下载张大妈任务
|
||||
else if (task.task_event_type == 'interactive.download_zhangdama') {
|
||||
this.$env.log(`跳过[${task.task_name}]任务:APP 只跳转下载页,没有完成接口`);
|
||||
}
|
||||
// 未知类型
|
||||
else {
|
||||
this.$env.log(`跳过[${task.task_name}]任务:未知类型 ${task.task_event_type}`);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -117,8 +171,23 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
return `${isSuccess ? '🟢' : '❌'}完成[${task.task_name}]任务${isSuccess ? '成功' : '失败!请查看日志'}\n`;
|
||||
}
|
||||
|
||||
// APP 在列表场景下用 article_hash_id 作为文章标识
|
||||
getArticleId(article) {
|
||||
return article.article_hash_id || article.article_id;
|
||||
}
|
||||
|
||||
// 随机取一条评论文案,多条时用换行或 | 分隔
|
||||
getCommentContent() {
|
||||
const words = String(process.env.SMZDM_COMMENT || '')
|
||||
.split(/[\n|]/)
|
||||
.map(word => word.trim())
|
||||
.filter(word => word.length > 10);
|
||||
|
||||
return words.length > 0 ? this.getOneByRandom(words) : '';
|
||||
}
|
||||
|
||||
// 执行评论任务
|
||||
async doCommentTask(task) {
|
||||
async doCommentTask(task, content) {
|
||||
this.$env.log(`开始任务: ${task.task_name}`);
|
||||
|
||||
const articles = await this.getArticleList(20);
|
||||
@@ -132,12 +201,15 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
// 随机选一篇文章来评论
|
||||
const article = articles[Math.floor(Math.random() * articles.length)];
|
||||
|
||||
// 先打开文章
|
||||
await this.getArticleDetail(article.article_id);
|
||||
|
||||
await wait(3, 10);
|
||||
|
||||
const {isSuccess, data } = await this.submitComment({
|
||||
articleId: article.article_id,
|
||||
channelId: article.article_channel_id,
|
||||
content: process.env.SMZDM_COMMENT
|
||||
content
|
||||
});
|
||||
|
||||
if (!isSuccess) {
|
||||
@@ -160,7 +232,7 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
}
|
||||
|
||||
this.$env.log('领取奖励');
|
||||
await wait(5, 15);
|
||||
await waitHuman(5, 15);
|
||||
|
||||
return await this.receiveReward(task.task_id);
|
||||
}
|
||||
@@ -219,12 +291,14 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
|
||||
await wait(3, 10);
|
||||
|
||||
const articleId = this.getArticleId(article);
|
||||
|
||||
if (article.article_price) {
|
||||
// 点值
|
||||
await this.rating({
|
||||
method: 'worth_cancel',
|
||||
type: 3,
|
||||
id: article.article_id,
|
||||
id: articleId,
|
||||
channelId: article.article_channel_id
|
||||
});
|
||||
|
||||
@@ -233,7 +307,7 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
await this.rating({
|
||||
method: 'worth_create',
|
||||
type: 1,
|
||||
id: article.article_id,
|
||||
id: articleId,
|
||||
channelId: article.article_channel_id
|
||||
});
|
||||
|
||||
@@ -242,7 +316,7 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
await this.rating({
|
||||
method: 'worth_cancel',
|
||||
type: 3,
|
||||
id: article.article_id,
|
||||
id: articleId,
|
||||
channelId: article.article_channel_id
|
||||
});
|
||||
}
|
||||
@@ -250,7 +324,7 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
// 点赞
|
||||
await this.rating({
|
||||
method: 'like_cancel',
|
||||
id: article.article_id,
|
||||
id: articleId,
|
||||
channelId: article.article_channel_id
|
||||
});
|
||||
|
||||
@@ -258,7 +332,7 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
|
||||
await this.rating({
|
||||
method: 'like_create',
|
||||
id: article.article_id,
|
||||
id: articleId,
|
||||
channelId: article.article_channel_id
|
||||
});
|
||||
|
||||
@@ -266,7 +340,7 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
|
||||
await this.rating({
|
||||
method: 'like_cancel',
|
||||
id: article.article_id,
|
||||
id: articleId,
|
||||
channelId: article.article_channel_id
|
||||
});
|
||||
|
||||
@@ -274,7 +348,7 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
|
||||
await this.rating({
|
||||
method: 'like_create',
|
||||
id: article.article_id,
|
||||
id: articleId,
|
||||
channelId: article.article_channel_id
|
||||
});
|
||||
|
||||
@@ -282,13 +356,13 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
|
||||
await this.rating({
|
||||
method: 'like_cancel',
|
||||
id: article.article_id,
|
||||
id: articleId,
|
||||
channelId: article.article_channel_id
|
||||
});
|
||||
}
|
||||
|
||||
this.$env.log('领取奖励');
|
||||
await wait(5, 15);
|
||||
await waitHuman(5, 15);
|
||||
|
||||
return await this.receiveReward(task.task_id);
|
||||
}
|
||||
@@ -312,12 +386,12 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
|
||||
const article = this.getOneByRandom(articles);
|
||||
|
||||
articleId = article.article_id;
|
||||
articleId = this.getArticleId(article);
|
||||
channelId = article.article_channel_id;
|
||||
}
|
||||
else if (task.task_redirect_url.link_type === 'tag') {
|
||||
// 从 Tag 获取文章
|
||||
const articles = await this.getArticleListFromTag(task.task_redirect_url.link_val, task.task_redirect_url.link_title, 20);
|
||||
// 从标签/话题获取文章
|
||||
const articles = await this.getArticleListFromTag(task.task_redirect_url.link_val, 20);
|
||||
|
||||
if (articles.length < 1) {
|
||||
return {
|
||||
@@ -327,7 +401,7 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
|
||||
const article = this.getOneByRandom(articles);
|
||||
|
||||
articleId = article.article_id;
|
||||
articleId = this.getArticleId(article);
|
||||
channelId = article.article_channel_id;
|
||||
}
|
||||
else if (task.task_redirect_url.link_val == '0' || !task.task_redirect_url.link_val) {
|
||||
@@ -342,7 +416,7 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
|
||||
const article = this.getOneByRandom(articles);
|
||||
|
||||
articleId = article.article_id;
|
||||
articleId = this.getArticleId(article);
|
||||
channelId = article.article_channel_id;
|
||||
}
|
||||
else {
|
||||
@@ -362,6 +436,7 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
|
||||
await wait(3, 10);
|
||||
|
||||
// 先取消
|
||||
await this.favorite({
|
||||
method: 'destroy',
|
||||
id: articleId,
|
||||
@@ -385,7 +460,7 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
});
|
||||
|
||||
this.$env.log('领取奖励');
|
||||
await wait(5, 15);
|
||||
await waitHuman(5, 15);
|
||||
|
||||
return await this.receiveReward(task.task_id);
|
||||
}
|
||||
@@ -410,6 +485,7 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
await this.follow({
|
||||
method: 'destroy',
|
||||
type: 'user',
|
||||
keywordId: user.keyword_id,
|
||||
keyword: user.keyword
|
||||
});
|
||||
|
||||
@@ -419,6 +495,7 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
await this.follow({
|
||||
method: 'create',
|
||||
type: 'user',
|
||||
keywordId: user.keyword_id,
|
||||
keyword: user.keyword
|
||||
});
|
||||
|
||||
@@ -428,6 +505,7 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
await this.follow({
|
||||
method: 'destroy',
|
||||
type: 'user',
|
||||
keywordId: user.keyword_id,
|
||||
keyword: user.keyword
|
||||
});
|
||||
}
|
||||
@@ -436,7 +514,7 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
}
|
||||
|
||||
this.$env.log('领取奖励');
|
||||
await wait(5, 15);
|
||||
await waitHuman(5, 15);
|
||||
|
||||
return await this.receiveReward(task.task_id);
|
||||
}
|
||||
@@ -456,7 +534,7 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
};
|
||||
}
|
||||
|
||||
lanmuId = tag.lanmu_id;
|
||||
lanmuId = tag.keyword_id;
|
||||
|
||||
await wait(3, 10);
|
||||
}
|
||||
@@ -467,7 +545,7 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
// 获取栏目信息
|
||||
const tagDetail = await this.getTagDetail(lanmuId);
|
||||
|
||||
if (!tagDetail.lanmu_id) {
|
||||
if (!tagDetail.keyword_id) {
|
||||
this.$env.log('获取栏目信息失败!');
|
||||
|
||||
return {
|
||||
@@ -480,8 +558,8 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
await this.follow({
|
||||
method: 'destroy',
|
||||
type: 'tag',
|
||||
keywordId: tagDetail.lanmu_id,
|
||||
keyword: tagDetail.lanmu_info.lanmu_name
|
||||
keywordId: tagDetail.keyword_id,
|
||||
keyword: tagDetail.keyword
|
||||
});
|
||||
|
||||
await wait(3, 10);
|
||||
@@ -489,8 +567,8 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
await this.follow({
|
||||
method: 'create',
|
||||
type: 'tag',
|
||||
keywordId: tagDetail.lanmu_id,
|
||||
keyword: tagDetail.lanmu_info.lanmu_name
|
||||
keywordId: tagDetail.keyword_id,
|
||||
keyword: tagDetail.keyword
|
||||
});
|
||||
|
||||
await wait(3, 10);
|
||||
@@ -498,12 +576,12 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
await this.follow({
|
||||
method: 'destroy',
|
||||
type: 'tag',
|
||||
keywordId: tagDetail.lanmu_id,
|
||||
keyword: tagDetail.lanmu_info.lanmu_name
|
||||
keywordId: tagDetail.keyword_id,
|
||||
keyword: tagDetail.keyword
|
||||
});
|
||||
|
||||
this.$env.log('领取奖励');
|
||||
await wait(5, 15);
|
||||
await waitHuman(5, 15);
|
||||
|
||||
return await this.receiveReward(task.task_id);
|
||||
}
|
||||
@@ -546,7 +624,7 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
});
|
||||
|
||||
this.$env.log('领取奖励');
|
||||
await wait(5, 15);
|
||||
await waitHuman(5, 15);
|
||||
|
||||
return await this.receiveReward(task.task_id);
|
||||
}
|
||||
@@ -578,7 +656,7 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
}
|
||||
}
|
||||
|
||||
await wait(5, 15);
|
||||
await waitHuman(5, 15);
|
||||
|
||||
const result = await this.joinCrowd(data);
|
||||
|
||||
@@ -589,7 +667,7 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
}
|
||||
|
||||
this.$env.log('领取奖励');
|
||||
await wait(5, 15);
|
||||
await waitHuman(5, 15);
|
||||
|
||||
return await this.receiveReward(task.task_id);
|
||||
}
|
||||
@@ -633,7 +711,7 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
await this.shareDailyReward(article.article_channel_id);
|
||||
await this.shareCallback(article.article_id, article.article_channel_id);
|
||||
|
||||
await wait(5, 15);
|
||||
await waitHuman(5, 15);
|
||||
}
|
||||
|
||||
this.$env.log('领取奖励');
|
||||
@@ -649,7 +727,18 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
let articles = [];
|
||||
let isRead = true;
|
||||
|
||||
if (task.article_id == '0') {
|
||||
// APP 按任务给的浏览时长决定行为,为 0 时不打开文章页
|
||||
const seconds = parseInt(task.view_seconds) || 0;
|
||||
const readSeconds = seconds > 0 ? (parseInt(task.task_redirect_url.browse_task_second) || seconds) : 0;
|
||||
|
||||
if (seconds === 0 && task.article_id != '0') {
|
||||
isRead = false;
|
||||
articles = [{
|
||||
article_id: task.article_id,
|
||||
article_channel_id: task.channel_id
|
||||
}];
|
||||
}
|
||||
else if (task.article_id == '0') {
|
||||
isRead = true;
|
||||
articles = await this.getArticleList(task.task_even_num - task.task_finished_num);
|
||||
|
||||
@@ -681,8 +770,15 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
}
|
||||
}
|
||||
|
||||
this.$env.log('模拟阅读文章');
|
||||
await wait(20, 50);
|
||||
if (readSeconds > 0) {
|
||||
const dwell = readSeconds + Math.floor(Math.random() * 10);
|
||||
|
||||
this.$env.log(`模拟阅读文章 ${dwell} 秒`);
|
||||
await wait(dwell, dwell + 5);
|
||||
}
|
||||
else {
|
||||
await wait(3, 10);
|
||||
}
|
||||
|
||||
const { isSuccess, response } = await requestApi('https://user-api.smzdm.com/task/event_view_article_sync', {
|
||||
method: 'post',
|
||||
@@ -701,7 +797,7 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
this.$env.log(`完成阅读失败!${response}`);
|
||||
}
|
||||
|
||||
await wait(5, 15);
|
||||
await waitHuman(5, 15);
|
||||
}
|
||||
|
||||
this.$env.log('领取奖励');
|
||||
@@ -710,6 +806,58 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
return await this.receiveReward(task.task_id);
|
||||
}
|
||||
|
||||
// 上报任务完成事件
|
||||
async reportTaskEvent(url, task) {
|
||||
const { isSuccess, response } = await requestApi(url, {
|
||||
method: 'post',
|
||||
headers: this.getHeaders(),
|
||||
data: {
|
||||
task_id: task.task_id
|
||||
}
|
||||
});
|
||||
|
||||
if (isSuccess) {
|
||||
this.$env.log('任务事件上报成功。');
|
||||
}
|
||||
else {
|
||||
this.$env.log(`任务事件上报失败!${response}`);
|
||||
}
|
||||
|
||||
await waitHuman(5, 15);
|
||||
|
||||
this.$env.log('领取奖励');
|
||||
|
||||
return await this.receiveReward(task.task_id);
|
||||
}
|
||||
|
||||
// 执行站外浏览任务
|
||||
async doViewZhanwaiTask(task) {
|
||||
this.$env.log(`开始任务: ${task.task_name}`);
|
||||
|
||||
return await this.reportTaskEvent('https://user-api.smzdm.com/task/event_view_zhanwai', task);
|
||||
}
|
||||
|
||||
// 执行打开第三方 App 任务
|
||||
async doOpenThirdPartyTask(task) {
|
||||
this.$env.log(`开始任务: ${task.task_name}`);
|
||||
|
||||
return await this.reportTaskEvent('https://user-api.smzdm.com/task/event_view_third_party_app', task);
|
||||
}
|
||||
|
||||
// 执行开启推送任务
|
||||
async doOpenAppPushTask(task) {
|
||||
this.$env.log(`开始任务: ${task.task_name}`);
|
||||
|
||||
return await this.reportTaskEvent('https://user-api.smzdm.com/task/open_app_push', task);
|
||||
}
|
||||
|
||||
// 执行创建桌面签到快捷方式任务
|
||||
async doCreateCheckinShortcutTask(task) {
|
||||
this.$env.log(`开始任务: ${task.task_name}`);
|
||||
|
||||
return await this.reportTaskEvent('https://user-api.smzdm.com/task/create_app_checkin_shortcut', task);
|
||||
}
|
||||
|
||||
// 关注/取关
|
||||
async follow({keywordId, keyword, type, method}) {
|
||||
let touchstone = '';
|
||||
@@ -775,9 +923,9 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
headers: this.getHeaders(),
|
||||
data: {
|
||||
nav_id: 0,
|
||||
page: 1,
|
||||
type: 'user',
|
||||
time_code: ''
|
||||
time_code: '',
|
||||
limit: 20
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1008,17 +1156,13 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
|
||||
// 获取文章列表
|
||||
async getArticleList(num = 1) {
|
||||
const { isSuccess, data, response } = await requestApi('https://article-api.smzdm.com/ranking_list/articles', {
|
||||
const { isSuccess, data, response } = await requestApi('https://article-api.smzdm.com/ranking_list/article_and_biji', {
|
||||
headers: this.getHeaders(),
|
||||
data: {
|
||||
tab: '2',
|
||||
order: '1',
|
||||
offset: 0,
|
||||
channel_id: 76,
|
||||
tab: 2,
|
||||
order: 0,
|
||||
limit: 20,
|
||||
exclude_article_ids: '',
|
||||
stream: 'a',
|
||||
ab_code: 'b'
|
||||
exclude_article_ids: ''
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1050,12 +1194,13 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
|
||||
// 获取栏目信息
|
||||
async getTagDetail(id) {
|
||||
const { isSuccess, data, response } = await requestApi('https://common-api.smzdm.com/lanmu/config_data', {
|
||||
const { isSuccess, data, response } = await requestApi('https://app-api.smzdm.com/common/config_data', {
|
||||
headers: this.getHeaders(),
|
||||
data: {
|
||||
middle_page: '',
|
||||
tab_selects: '',
|
||||
redirect_params: id
|
||||
id,
|
||||
type: 'lanmu',
|
||||
calendar_time: '',
|
||||
token: this.token
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1063,7 +1208,7 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
return data.data;
|
||||
}
|
||||
else {
|
||||
this.$env.log(`获取栏目信息失败!${response}`);
|
||||
this.$env.log(`获取栏目信息失败: ${response}`);
|
||||
|
||||
return {};
|
||||
}
|
||||
@@ -1071,13 +1216,11 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
|
||||
// 获取栏目列表
|
||||
async getTagByRandom() {
|
||||
const { isSuccess, data, response } = await requestApi('https://dingyue-api.smzdm.com/tuijian/search_result', {
|
||||
const { isSuccess, data, response } = await requestApi('https://dingyue-api.smzdm.com/dy/user/dingyue/tuijian_search', {
|
||||
method: 'post',
|
||||
headers: this.getHeaders(),
|
||||
data: {
|
||||
time_code: '',
|
||||
nav_id: '',
|
||||
type: 'tag',
|
||||
limit: 20
|
||||
type: 'tag'
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1097,12 +1240,10 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
headers: this.getHeaders(),
|
||||
data: {
|
||||
comment_flow: '',
|
||||
hashcode: '',
|
||||
lastest_update_time: '',
|
||||
uhome: 0,
|
||||
imgmode: 0,
|
||||
article_channel_id: 0,
|
||||
h5hash: ''
|
||||
article_channel_id: 0
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1139,24 +1280,30 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
|
||||
// 收藏
|
||||
async favorite({id, channelId, method}) {
|
||||
const data = {
|
||||
touchstone_event: this.getTouchstoneEvent({
|
||||
event_value: {
|
||||
aid: id,
|
||||
cid: channelId,
|
||||
is_detail: true
|
||||
},
|
||||
sourceMode: '我的_我的任务页',
|
||||
sourcePage: `Android/长图文/P/${id}/`,
|
||||
upperLevel_url: '个人中心/赚奖励/'
|
||||
}),
|
||||
token: this.token,
|
||||
id,
|
||||
channel_id: channelId
|
||||
};
|
||||
|
||||
if (method === 'create') {
|
||||
data.sub_channel_id = '2';
|
||||
}
|
||||
|
||||
const { isSuccess, response } = await requestApi(`https://user-api.smzdm.com/favorites/${method}`, {
|
||||
method: 'post',
|
||||
headers: this.getHeaders(),
|
||||
data: {
|
||||
touchstone_event: this.getTouchstoneEvent({
|
||||
event_value: {
|
||||
aid: id,
|
||||
cid: channelId,
|
||||
is_detail: true
|
||||
},
|
||||
sourceMode: '我的_我的任务页',
|
||||
sourcePage: `Android/长图文/P/${id}/`,
|
||||
upperLevel_url: '个人中心/赚奖励/'
|
||||
}),
|
||||
token: this.token,
|
||||
id,
|
||||
channel_id: channelId
|
||||
}
|
||||
data
|
||||
});
|
||||
|
||||
if (isSuccess) {
|
||||
@@ -1236,36 +1383,29 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
if (isSuccess) {
|
||||
return data.data;
|
||||
}
|
||||
else {
|
||||
this.$env.log(`获取品牌信息失败!${response}`);
|
||||
|
||||
return {};
|
||||
}
|
||||
this.$env.log(`获取品牌信息失败!${response}`);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
// 根据栏目信息获取文章列表
|
||||
async getArticleListFromLanmu(id, num = 1) {
|
||||
const lanmuDetail = await this.getTagDetail(id);
|
||||
|
||||
if (!lanmuDetail.lanmu_id) {
|
||||
if (!lanmuDetail.keyword_id) {
|
||||
return [];
|
||||
}
|
||||
|
||||
const { isSuccess, data, response } = await requestApi('https://common-api.smzdm.com/lanmu/list_data', {
|
||||
const tabParams = lanmuDetail.tab && lanmuDetail.tab[0] ? lanmuDetail.tab[0].params : '';
|
||||
|
||||
const { isSuccess, data, response } = await requestApi('https://app-api.smzdm.com/common/list_data', {
|
||||
headers: this.getHeaders(),
|
||||
data: {
|
||||
price_lt: '',
|
||||
order: '',
|
||||
category_ids: '',
|
||||
price_gt: '',
|
||||
referer_article: '',
|
||||
tag_params: '',
|
||||
mall_ids: '',
|
||||
time_sort: '',
|
||||
params: lanmuDetail.params,
|
||||
tab_params: tabParams,
|
||||
page: 1,
|
||||
params: id,
|
||||
limit: 20,
|
||||
tab_params: lanmuDetail.tab[0].params
|
||||
limit: 20
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1279,6 +1419,29 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
}
|
||||
}
|
||||
|
||||
// 根据标签/话题获取文章列表
|
||||
async getArticleListFromTag(id, num = 1) {
|
||||
const { isSuccess, data, response } = await requestApi('https://article-api.smzdm.com/shaiwu/shaiwu_juhe_new', {
|
||||
headers: this.getHeaders(),
|
||||
data: {
|
||||
page: 1,
|
||||
size: 20,
|
||||
tag_id: id,
|
||||
tab_id: '0',
|
||||
middle_page: ''
|
||||
}
|
||||
});
|
||||
|
||||
if (isSuccess) {
|
||||
return data.data.rows.slice(0, num);
|
||||
}
|
||||
else {
|
||||
this.$env.log(`获取文章列表失败: ${response}`);
|
||||
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
// 点赞
|
||||
async rating({id, channelId, method, type}) {
|
||||
const { isSuccess, response } = await requestApi(`https://user-api.smzdm.com/rating/${method}`, {
|
||||
@@ -1332,7 +1495,6 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
upperLevel_url: '好物社区/首页/全部/',
|
||||
sourceRoot: '社区'
|
||||
}),
|
||||
is_like: 3,
|
||||
reply_from: 3,
|
||||
smiles: 0,
|
||||
atta: 0,
|
||||
@@ -1381,58 +1543,6 @@ class SmzdmTaskBot extends SmzdmBot {
|
||||
};
|
||||
}
|
||||
|
||||
// 获取 Dingyue 状态
|
||||
async getDingyueStatus(name) {
|
||||
const { isSuccess, data, response } = await requestApi('https://dingyue-api.smzdm.com/dingyue/follow_status', {
|
||||
method: 'post',
|
||||
headers: this.getHeaders(),
|
||||
data: {
|
||||
rules: JSON.stringify([{
|
||||
type: 'tag',
|
||||
keyword: name
|
||||
}])
|
||||
}
|
||||
});
|
||||
|
||||
if (isSuccess) {
|
||||
return data;
|
||||
}
|
||||
else {
|
||||
this.$env.log(`获取订阅状态失败: ${response}`);
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
// 根据 Tag ID 获取文章列表
|
||||
async getArticleListFromTag(id, name, num = 1) {
|
||||
const status = this.getDingyueStatus(name);
|
||||
|
||||
const { isSuccess, data, response } = await requestApi('https://tag-api.smzdm.com/theme/detail_feed', {
|
||||
headers: this.getHeaders(),
|
||||
data: {
|
||||
article_source: 1,
|
||||
past_num: 0,
|
||||
feed_sort: 2,
|
||||
smzdm_id: status.smzdm_id,
|
||||
tag_id: id,
|
||||
name,
|
||||
time_sort: 0,
|
||||
page: 1,
|
||||
article_tab: 0,
|
||||
limit: 20
|
||||
}
|
||||
});
|
||||
|
||||
if (isSuccess) {
|
||||
// 取前 num 个做任务
|
||||
return data.data.rows.slice(0, num);
|
||||
}
|
||||
else {
|
||||
this.$env.log(`获取文章列表失败: ${response}`);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
// 通过 url 获取文章 channel_id
|
||||
async getArticleChannelIdForTesting(url) {
|
||||
const { isSuccess, response } = await requestApi(url, {
|
||||
|
||||
@@ -6,7 +6,16 @@ cron: 10 8 * * *
|
||||
*/
|
||||
|
||||
const Env = require('./env');
|
||||
const { SmzdmBot, requestApi, removeTags, getEnvCookies, wait } = require('./bot');
|
||||
const {
|
||||
SmzdmBot,
|
||||
requestApi,
|
||||
removeTags,
|
||||
getEnvCookies,
|
||||
wait,
|
||||
waitHuman,
|
||||
CREATE_CENTER_VIEW,
|
||||
IS_INSTALL_ZHANGDAMA
|
||||
} = require('./bot');
|
||||
const notify = require('./sendNotify');
|
||||
const CryptoJS = require('crypto-js');
|
||||
|
||||
@@ -49,7 +58,7 @@ class SmzdmCheckinBot extends SmzdmBot {
|
||||
🏅碎银: ${data.data.pre_re_silver}
|
||||
🏅补签卡: ${data.data.cards}`;
|
||||
|
||||
await wait(3, 10);
|
||||
await waitHuman(3, 10);
|
||||
|
||||
const vip = await this.getVipInfo();
|
||||
|
||||
@@ -85,22 +94,24 @@ class SmzdmCheckinBot extends SmzdmBot {
|
||||
});
|
||||
|
||||
if (isSuccess) {
|
||||
const msg1 = `${data.data.normal_reward.reward_add.title}: ${data.data.normal_reward.reward_add.content}`;
|
||||
const normal = data.data.normal_reward;
|
||||
|
||||
let msg2 = '';
|
||||
// reward_add 为空说明今天没有奖励增加(已领过或没有),退回展示签到卡片文案
|
||||
const msg1 = normal.reward_add.title
|
||||
? `${normal.reward_add.title}: ${normal.reward_add.content}`
|
||||
: removeTags(normal.gift.content);
|
||||
|
||||
if (data.data.normal_reward.gift.title) {
|
||||
msg2 = `${data.data.normal_reward.gift.title}: ${data.data.normal_reward.gift.content_str}`;
|
||||
}
|
||||
else {
|
||||
msg2 = `${data.data.normal_reward.gift.sub_content}`;
|
||||
}
|
||||
const msg2 = normal.gift.title
|
||||
? `${normal.gift.title}: ${normal.gift.content_str}`
|
||||
: normal.gift.sub_content;
|
||||
|
||||
$.log(`${msg1}\n${msg2}\n`);
|
||||
const msg = [msg1, msg2].filter(text => text).join('\n');
|
||||
|
||||
$.log(`${msg}\n`);
|
||||
|
||||
return {
|
||||
isSuccess,
|
||||
msg: `${msg1}\n${msg2}\n\n`
|
||||
msg: `${msg}\n\n`
|
||||
};
|
||||
}
|
||||
else {
|
||||
@@ -129,7 +140,7 @@ class SmzdmCheckinBot extends SmzdmBot {
|
||||
};
|
||||
}
|
||||
|
||||
await wait(5, 10);
|
||||
await waitHuman(5, 10);
|
||||
|
||||
const { isSuccess, data, response } = await requestApi('https://user-api.smzdm.com/checkin/extra_reward', {
|
||||
method: 'post',
|
||||
@@ -159,13 +170,17 @@ class SmzdmCheckinBot extends SmzdmBot {
|
||||
async isContinueCheckin() {
|
||||
const { isSuccess, data, response } = await requestApi('https://user-api.smzdm.com/checkin/show_view_v2', {
|
||||
method: 'post',
|
||||
headers: this.getHeaders()
|
||||
headers: this.getHeaders(),
|
||||
data: {
|
||||
is_install_zhangdama: IS_INSTALL_ZHANGDAMA
|
||||
}
|
||||
});
|
||||
|
||||
if (isSuccess) {
|
||||
const result = data.data.rows.find(item => item.cell_type == '18001');
|
||||
// 连续签到的卡片,直接按有没有 checkin_continue 来找
|
||||
const result = data.data.rows.find(item => item.cell_data && item.cell_data.checkin_continue);
|
||||
|
||||
return result.cell_data.checkin_continue.continue_checkin_reward_show;
|
||||
return !!(result && result.cell_data.checkin_continue.continue_checkin_reward_show);
|
||||
}
|
||||
else {
|
||||
$.log(`查询是否有额外奖励失败!${response}`);
|
||||
@@ -179,7 +194,8 @@ class SmzdmCheckinBot extends SmzdmBot {
|
||||
method: 'post',
|
||||
headers: this.getHeaders(),
|
||||
data: {
|
||||
token: this.token
|
||||
token: this.token,
|
||||
create_center_view: CREATE_CENTER_VIEW
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -6,7 +6,14 @@ cron: 20 8 * * *
|
||||
*/
|
||||
|
||||
const Env = require('./env');
|
||||
const { SmzdmBot, requestApi, parseJSON, getEnvCookies, wait } = require('./bot');
|
||||
const {
|
||||
SmzdmBot,
|
||||
requestApi,
|
||||
parseJSON,
|
||||
getEnvCookies,
|
||||
wait,
|
||||
waitHuman
|
||||
} = require('./bot');
|
||||
const notify = require('./sendNotify');
|
||||
|
||||
// ------------------------------------
|
||||
@@ -34,7 +41,7 @@ class SmzdmLotteryBot extends SmzdmBot {
|
||||
const vipId1 = await this.getActivityIdFromVip('https://m.smzdm.com/topic/bwrzf5/516lft');
|
||||
|
||||
if (vipId1) {
|
||||
await wait(3, 10);
|
||||
await waitHuman(3, 10);
|
||||
|
||||
notifyMsg += `转盘抽奖ID: ${vipId1}\n`;
|
||||
notifyMsg += await this.draw(vipId1);
|
||||
@@ -42,13 +49,13 @@ class SmzdmLotteryBot extends SmzdmBot {
|
||||
}
|
||||
|
||||
$.log();
|
||||
await wait(5, 15);
|
||||
await waitHuman(5, 15);
|
||||
$.log();
|
||||
|
||||
const vipId2 = await this.getActivityIdFromVip('https://m.smzdm.com/topic/zhyzhuanpan/cjzp/');
|
||||
|
||||
if (vipId2) {
|
||||
await wait(3, 10);
|
||||
await waitHuman(3, 10);
|
||||
|
||||
notifyMsg += `转盘抽奖ID: ${vipId2}\n`;
|
||||
notifyMsg += await this.draw(vipId2);
|
||||
|
||||
@@ -6,7 +6,14 @@ cron: 20 14 * * *
|
||||
*/
|
||||
|
||||
const Env = require('./env');
|
||||
const { requestApi, removeTags, getEnvCookies, wait } = require('./bot');
|
||||
const {
|
||||
requestApi,
|
||||
removeTags,
|
||||
getEnvCookies,
|
||||
wait,
|
||||
waitHuman,
|
||||
IS_INSTALL_ZHANGDAMA
|
||||
} = require('./bot');
|
||||
const notify = require('./sendNotify');
|
||||
const { SmzdmTaskBot } = require('./library_task');
|
||||
|
||||
@@ -25,21 +32,21 @@ class SmzdmNormalTaskBot extends SmzdmTaskBot {
|
||||
|
||||
const { tasks } = await this.getTaskList();
|
||||
|
||||
await wait(5, 10);
|
||||
await waitHuman(5, 10);
|
||||
|
||||
let notifyMsg = '';
|
||||
|
||||
notifyMsg = await this.doTasks(tasks);
|
||||
|
||||
$.log('查询是否有限时累计活动阶段奖励');
|
||||
await wait(5, 15);
|
||||
await waitHuman(5, 15);
|
||||
|
||||
// 领取活动奖励
|
||||
const { detail } = await this.getTaskList();
|
||||
|
||||
if (detail.cell_data && detail.cell_data.activity_reward_status == '1') {
|
||||
$.log('有奖励,领取奖励');
|
||||
await wait(5, 15);
|
||||
await waitHuman(5, 15);
|
||||
|
||||
const { isSuccess } = await this.receiveActivity(detail.cell_data);
|
||||
|
||||
@@ -56,7 +63,10 @@ class SmzdmNormalTaskBot extends SmzdmTaskBot {
|
||||
async getTaskList() {
|
||||
const { isSuccess, data, response } = await requestApi('https://user-api.smzdm.com/task/list_v2', {
|
||||
method: 'post',
|
||||
headers: this.getHeaders()
|
||||
headers: this.getHeaders(),
|
||||
data: {
|
||||
is_install_zhangdama: IS_INSTALL_ZHANGDAMA
|
||||
}
|
||||
});
|
||||
|
||||
if (isSuccess) {
|
||||
|
||||
207
smzdm_testing.js
207
smzdm_testing.js
@@ -6,7 +6,7 @@ cron: 20 15 * * *
|
||||
*/
|
||||
|
||||
const Env = require('./env');
|
||||
const { requestApi, getEnvCookies, wait } = require('./bot');
|
||||
const { requestApi, getEnvCookies, wait, waitHuman } = require('./bot');
|
||||
const notify = require('./sendNotify');
|
||||
const { SmzdmTaskBot } = require('./library_task');
|
||||
|
||||
@@ -21,13 +21,28 @@ class SmzdmTestingTaskBot extends SmzdmTaskBot {
|
||||
|
||||
// 主函数
|
||||
async run() {
|
||||
let notifyMsg = await this.doTestingTasks();
|
||||
|
||||
await waitHuman(5, 10);
|
||||
|
||||
notifyMsg += await this.getEnergyList();
|
||||
|
||||
await waitHuman(5, 10);
|
||||
|
||||
notifyMsg += await this.getWinCouponList();
|
||||
|
||||
return notifyMsg;
|
||||
}
|
||||
|
||||
// 执行众测能量值任务
|
||||
async doTestingTasks() {
|
||||
const activityId = await this.getTestingActivityId();
|
||||
|
||||
if (!activityId) {
|
||||
return '';
|
||||
return this.wafBlocked ? '🟡众测任务未执行:接口被 WAF/风控拦截\n' : '';
|
||||
}
|
||||
|
||||
await wait(5, 10);
|
||||
await waitHuman(5, 10);
|
||||
|
||||
const activityInfo = await this.getTestingActivityInfo(activityId);
|
||||
|
||||
@@ -35,87 +50,71 @@ class SmzdmTestingTaskBot extends SmzdmTaskBot {
|
||||
return '';
|
||||
}
|
||||
|
||||
await wait(5, 10);
|
||||
await waitHuman(5, 10);
|
||||
|
||||
let notifyMsg = await this.doTasks(activityInfo.activity_task.default_list);
|
||||
|
||||
await wait(3, 5);
|
||||
|
||||
// 查询当前拥有的能量数量, 以及过期时间
|
||||
notifyMsg += await this.getMyTestingInfo();
|
||||
|
||||
return notifyMsg || '无可执行任务';
|
||||
return await this.doTasks(activityInfo.activity_task.default_list);
|
||||
}
|
||||
|
||||
// 获取当前能量值任务的活动 ID
|
||||
async getTestingActivityId() {
|
||||
$.log('获取活动 ID');
|
||||
// 众测接口被 WAF 拦时返回 403、429 或 HTML 验证码页,不是 JSON
|
||||
isWafBlocked(response) {
|
||||
return /WAF|验证码|<!DOCTYPE html>|<script|Response code 40[13]|Response code 429|ECONNRESET|ETIMEDOUT/i.test(String(response));
|
||||
}
|
||||
|
||||
const { isSuccess, data, response } = await requestApi('https://zhiyou.m.smzdm.com/task/task/ajax_get_activity_id', {
|
||||
// 请求众测接口,被 WAF 拦时置标记并返回 false
|
||||
async requestTestingApi(url, data) {
|
||||
const { response } = await requestApi(url, {
|
||||
method: 'get',
|
||||
data: {
|
||||
'from': 'zhongce'
|
||||
},
|
||||
data,
|
||||
headers: {
|
||||
...this.getHeadersForWeb(),
|
||||
Origin: 'https://test.m.smzdm.com',
|
||||
Referer: 'https://test.m.smzdm.com/'
|
||||
}
|
||||
},
|
||||
parseJSON: false
|
||||
});
|
||||
|
||||
if (isSuccess) {
|
||||
return data.data.activity_id;
|
||||
}
|
||||
else {
|
||||
$.log(`获取活动 ID 失败!${response}`);
|
||||
if (this.isWafBlocked(response)) {
|
||||
this.wafBlocked = true;
|
||||
|
||||
$.log('🔴众测任务接口被 WAF 拦截,本次跳过众测任务');
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
const json = JSON.parse(response);
|
||||
|
||||
if (json.error_code == '0') {
|
||||
return json.data;
|
||||
}
|
||||
|
||||
$.log(`众测接口返回错误:${json.error_msg}`);
|
||||
}
|
||||
catch (e) {
|
||||
$.log(`众测接口返回异常:${String(response).slice(0, 150)}`);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// 获取众测能量值任务的活动 ID
|
||||
async getTestingActivityId() {
|
||||
$.log('获取众测活动 ID');
|
||||
|
||||
const data = await this.requestTestingApi('https://zhiyou.m.smzdm.com/task/task/ajax_get_activity_id', {
|
||||
'from': 'zhongce'
|
||||
});
|
||||
|
||||
return data ? data.activity_id : false;
|
||||
}
|
||||
|
||||
// 获取活动下的所有任务
|
||||
async getTestingActivityInfo(id) {
|
||||
$.log('获取活动信息');
|
||||
$.log('获取众测活动信息');
|
||||
|
||||
const { isSuccess, data, response } = await requestApi('https://zhiyou.m.smzdm.com/task/task/ajax_get_activity_info', {
|
||||
method: 'get',
|
||||
data: {
|
||||
'activity_id': id
|
||||
},
|
||||
headers: this.getHeadersForWeb()
|
||||
return await this.requestTestingApi('https://zhiyou.m.smzdm.com/task/task/ajax_get_activity_info', {
|
||||
'activity_id': id
|
||||
});
|
||||
|
||||
if (isSuccess) {
|
||||
return data.data;
|
||||
}
|
||||
else {
|
||||
$.log(`获取活动信息失败!${response}`);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// 众测中心-必中券信息查询
|
||||
async getMyTestingInfo() {
|
||||
$.log('获取必中券信息');
|
||||
|
||||
const { isSuccess, data, response } = await requestApi('https://test.m.smzdm.com/win_coupon/user_data', {
|
||||
method: 'get',
|
||||
headers: this.getHeadersForWeb()
|
||||
});
|
||||
|
||||
if (isSuccess) {
|
||||
const msg = `当前拥有必中券: ${data.data.my_energy.my_energy_total}\n必中券过期时间: ${data.data.my_energy.energy_expired_time}`;
|
||||
|
||||
$.log(msg);
|
||||
|
||||
return `\n${msg}\n`;
|
||||
}
|
||||
else {
|
||||
$.log(`获取个人必中券信息失败!${response}`);
|
||||
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
// 领取奖励
|
||||
@@ -125,10 +124,11 @@ class SmzdmTestingTaskBot extends SmzdmTaskBot {
|
||||
data: {
|
||||
'task_id': taskId
|
||||
},
|
||||
headers: this.getHeadersForWeb()
|
||||
headers: this.getHeadersForWeb(),
|
||||
parseJSON: false
|
||||
});
|
||||
|
||||
if (isSuccess) {
|
||||
if (!this.isWafBlocked(response) && isSuccess) {
|
||||
$.log('领取成功!');
|
||||
|
||||
return {
|
||||
@@ -136,14 +136,77 @@ class SmzdmTestingTaskBot extends SmzdmTaskBot {
|
||||
msg: ''
|
||||
};
|
||||
}
|
||||
else {
|
||||
$.log(`领取任务奖励失败!${response}`);
|
||||
|
||||
return {
|
||||
isSuccess,
|
||||
msg: '领取任务奖励失败!'
|
||||
};
|
||||
$.log(`领取任务奖励失败!${String(response).slice(0, 150)}`);
|
||||
|
||||
return {
|
||||
isSuccess: false,
|
||||
msg: '领取任务奖励失败!'
|
||||
};
|
||||
}
|
||||
|
||||
// 能量值数量、过期时间与明细
|
||||
async getEnergyList() {
|
||||
$.log('查询能量值');
|
||||
|
||||
const { isSuccess, data, response } = await requestApi('https://test-api.smzdm.com/win_coupon/energy_list', {
|
||||
method: 'get',
|
||||
headers: this.getHeaders(),
|
||||
data: {
|
||||
'page': 1
|
||||
}
|
||||
});
|
||||
|
||||
if (!isSuccess) {
|
||||
$.log(`查询能量值失败!${response}`);
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
const myEnergy = data.data.my_energy || {};
|
||||
const list = data.data.list || [];
|
||||
|
||||
let msg = `🏅能量值: ${myEnergy.my_energy_total}\n🏅能量值过期时间: ${myEnergy.energy_expired_time}\n`;
|
||||
|
||||
if (list.length > 0) {
|
||||
msg += `🏅能量值明细:\n${list.map(item => ` ${item.article_title}`).join('\n')}\n`;
|
||||
}
|
||||
|
||||
$.log(msg);
|
||||
|
||||
return `${msg}\n`;
|
||||
}
|
||||
|
||||
// 必中券列表
|
||||
async getWinCouponList() {
|
||||
$.log('查询必中券列表');
|
||||
|
||||
const { isSuccess, data, response } = await requestApi('https://test-api.smzdm.com/win_coupon/win_coupon_list', {
|
||||
method: 'get',
|
||||
headers: this.getHeaders(),
|
||||
data: {
|
||||
'page': 1,
|
||||
'type': '0'
|
||||
}
|
||||
});
|
||||
|
||||
if (!isSuccess) {
|
||||
$.log(`查询必中券列表失败!${response}`);
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
const list = data.data.list || [];
|
||||
|
||||
if (list.length < 1) {
|
||||
return '🏅暂无必中券\n';
|
||||
}
|
||||
|
||||
const msg = `🏅必中券 ${list.length} 项:\n${list.map(item => ` ${item.article_title}`).join('\n')}\n`;
|
||||
|
||||
$.log(msg);
|
||||
|
||||
return msg;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user