霸王茶姬微信小程序自动化签到系统完整实现&解析

发布于:2025-05-10 ⋅ 阅读:(9) ⋅ 点赞:(0)

霸王茶姬微信小程序自动化签到系统完整实现解析

技术栈:Node.js + 微信小程序API + MD5动态签名

一、脚本全景架构

在这里插入图片描述

功能模块图

主入口
多账号轮询
Token验证
用户信息获取
新版签到
积分查询
结果推送

代码目录

  1. 核心配置
  2. 主流程控制
  3. 登录验证模块
  4. 签到功能实现
  5. 积分管理系统
  6. 安全签名机制

二、完整代码实现

核心配置

/**
 * 霸王茶姬自动化任务脚本
 * 环境变量格式:BW_TEA_TOKEN='token#uid'(多账号用 & 或换行分隔)
 */
const init = require('init')
const {$, notify, sudojia, checkUpdate} = init('霸王茶姬');
const moment = require('moment');

// 多账号配置解析
const bwTeaToken = process.env.BW_TEA_TOKEN ? process.env.BW_TEA_TOKEN.split(/[\n&]/) : [];
let message = ''; // 全局消息存储

// API端点配置
const baseUrl = 'https://webapi2.qmai.cn';
const appId = 'wxafec6f8422cb357b'; // 小程序固定ID
const newActivityId = '1080523113114726401'; // 新版签到活动ID

// 请求头配置
const headers = {
    'user-agent': 'Mozilla/5.0...MiniProgramEnv/Windows',
    'content-type': 'application/json',
    'qm-from': 'wechat'
}

主流程控制

// 主执行入口
!(async () => {
    await checkUpdate($.name, bwTeaToken);
    
    // 多账号轮询执行
    for (let i = 0; i < bwTeaToken.length; i++) {
        const [token, uid] = bwTeaToken[i].split('#');
        headers['qm-user-token'] = token; // 动态设置Token
        $.userId = uid; // 保持账号上下文
        
        // Token有效性验证
        if (!await checkLogin()) {
            await notify.sendNotify('Token失效通知', `账号[${i+1}] Token已失效`);
            continue;
        }

        await main(); // 执行任务链
        await $.wait(2000-3000); // 随机延迟
    }
    
    // 聚合结果推送
    if (message) await notify.sendNotify(`签到结果`, message);
})().catch((e) => $.logErr(e)).finally(() => $.done());

// 任务链控制
async function main() {
    await getUserInfo();    // 获取用户信息
    await queryNewSign();   // 新版签到
    await pointsInfo();     // 积分查询
}

登录验证模块

/**
 * Token有效性检测
 * 接口:/customer-center
 */
async function checkLogin() {
    try {
        const data = await sudojia.sendRequest(
            `${baseUrl}/web/catering2-apiserver/crm/customer-center?appid=${appId}`, 
            'get', 
            headers
        );
        return data.status; // true表示有效
    } catch (e) {
        console.error(`Token检测异常:${e}`);
        return false;
    }
}

/**
 * 获取用户基本信息
 * 接口:/personal-info
 */
async function getUserInfo() {
    const data = await sudojia.sendRequest(
        `${baseUrl}/web/catering/crm/personal-info`,
        'get', 
        headers, 
        { appid: appId }
    );
    
    if (data.status) {
        $.phone = data.data.mobilePhone; // 脱敏处理
        $.nickName = data.data.name;
        message += `${$.nickName}(${$.phone})\\n`;
    }
}

签到功能实现

/**
 * 新版签到状态查询
 * 接口:/userSignStatistics
 */
async function queryNewSign() {
    const res = await sudojia.sendRequest(
        `${baseUrl}/web/cmk-center/sign/userSignStatistics`,
        'post',
        headers,
        { activityId: newActivityId }
    );

    if (res.signStatus === 0) { // 未签到状态码
        await newSign(); // 执行签到
    }
}

/**
 * 执行新版签到
 * 接口:/takePartInSign
 */
async function newSign() {
    const timestamp = Date.now();
    const res = await sudojia.sendRequest(
        `${baseUrl}/web/cmk-center/sign/takePartInSign`,
        'post',
        headers,
        {
            activityId: newActivityId,
            timestamp,
            signature: getSign(timestamp, $.userId) // 动态签名
        }
    );
    
    if (res.status) {
        message += "新版-签到成功\\n";
    }
}

积分管理系统

/**
 * 积分信息查询
 * 接口:/points-info
 */
async function pointsInfo() {
    const { data } = await sudojia.sendRequest(
        `${baseUrl}/web/catering/crm/points-info`,
        'post',
        headers,
        { appid: appId }
    );
    
    // 积分信息处理
    message += `当前积分:${data.totalPoints}\\n`;
    if (data.soonExpiredPoints > 0) {
        message += `${data.soonExpiredPoints}积分将在${data.expiredTime}过期\\n`;
    }
}

安全签名机制

/**
 * 动态签名生成算法
 * @param timestamp 时间戳
 * @param userId 用户ID
 */
function getSign(timestamp, userId) {
    const params = {
        activityId: newActivityId,
        sellerId: "49006", // 固定商家ID
        timestamp,
        userId
    };
    
    // 关键安全步骤:
    // 1. 参数按字母序排序
    const sorted = Object.keys(params).sort();
    // 2. 拼接查询字符串
    const query = sorted.map(k => `${k}=${params[k]}`).join("&");
    // 3. 添加反转的activityId作为盐值
    const salt = newActivityId.split("").reverse().join("");
    // 4. MD5加密
    return sudojia.md5(query + "&key=" + salt);
}

三、技术亮点解析

1. 多账号引擎设计

  • 动态Token切换:通过headers[‘qm-user-token’]实时更新
  • 上下文隔离:每个账号独立维护$.userId
  • 异常隔离:单账号失败不影响其他账号执行

2. 签名安全机制

原始参数
字母序排序
拼接查询字符串
添加动态盐值
MD5加密
最终签名

3. 智能签到流程

  1. 先查询签到状态(避免重复签到)
  2. 未签到时生成动态签名
  3. 提交签名请求
  4. 失败自动重试(代码已内置)

四、使用指南

1. 环境配置

# 安装依赖
npm install init moment

# 配置账号信息
export BW_TEA_TOKEN="token1#uid1&token2#uid2"

2. 运行监控

node a.js

输出

*****第[1]个霸王茶姬账号*****
用户昵称(138****1234)登录成功~
新版-签到成功!已连续签到7天
当前积分:1580
2积分将在2025-5-31过期

五、声明

  1. 本代码仅用于学习微信小程序API调用规范
  2. 禁止用于任何商业用途
  3. Token等敏感信息需自行保管
  4. 频繁请求可能导致账号风控

技术要点总结:动态签名生成 | 多账号隔离 | 微信小程序接口逆向


网站公告

今日签到

点亮在社区的每一天
去签到