This commit is contained in:
jiahuigithub authored and GitHub committed 2025-12-08 13:18:09 +08:00
1 parent 551b945e60
commit 77b4a2f5fe
3 files changed
+1272 -308

No files matched your search

+464
View File
@@ -0,0 +1,464 @@
// 青龙脚本 - 星妈会自动任务
// 30 0 * * * xmyx.js
// 使用方法:在青龙面板中添加环境变量 XMH_COOKIE,多账号换行
// 环境变量格式:cuk值(可选备注)
// 示例:
// wSWQiOiIxIiwic2l25tKNA7BQuLVgf36dv7fheE5mEQi744fpzBiP7573mUX6yHvXhEMfqyuLoa7YymNuEzAHHh8rQSV5gpnXCcaXQfdXUCwd8dmwgyWXWMU6svEybBVBc4bLChq6PFQGNpoBatKdQQk
// wSWQiOiIxIiwic2l25tKNA7BQuLVgXfu6A5zs1CqL11PPghn23mgGmCbV7LmLFZsGf4fxZex68XaC3adKe5vssytNrfb7QPcMeNudgbQLvg8xoMSK3mnncdqrCSK6KNbmdrrHeq2S9gmjdfAAsUbH8Jg # 我的账号1
// wSWQiOiIxIiwic2l25tKNA7BQuLVgXCbJsU79CeJUS8inM6PyM7eGX8xL2kcy99Naz41C2qycwEhu1EK7imYASNPsEFsXGK8bcpHpYA3wYnPEJZ8rRXok5CxdLfdKvWU1u6mJpw1Kz3AMxWh6gh31d1E # 老婆的账号
const $ = init();
// 优先使用青龙面板自带的 sendNotify
const notify = $.isNode() ? (() => {
try {
return require('./sendNotify');
} catch (e) {
console.log('⚠️ sendNotify 加载失败,通知功能将不可用');
return null;
}
})() : '';
const API_HOST = "https://momclub.feihe.com";
// 初始化函数
function init() {
return {
isNode: () => typeof process !== 'undefined' && process.version,
http: require('axios'),
wait: (ms) => new Promise(resolve => setTimeout(resolve, ms)),
log: console.log
};
}
// 任务类型映射
const TASK_TYPES = {
CHECKIN: "checkIn", // 签到
BROWSE_PAGE: "receive", // 浏览任务
COMPLETE: "complete" // 完成类任务
};
let allAccounts = [];
let totalCredits = 0;
let currentAccount = 1;
class XingMaHui {
constructor(cuk, index, remark = '') {
this.cuk = cuk;
this.index = index;
this.remark = remark;
this.accountName = remark ? `账号${index}(${remark})` : `账号${index}`;
this.creditsEarned = 0;
this.taskResults = [];
this.userInfo = null;
this.initialPoints = 0; // 初始积分
this.finalPoints = 0; // 最终积分
}
// 生成请求头
getHeaders() {
return {
'Host': 'momclub.feihe.com',
'cuk': this.cuk,
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/132.0.0.0 Safari/537.36 MicroMessenger/7.0.20.1781(0x6700143B) NetType/WIFI MiniProgramEnv/Windows WindowsWechat/WMPF WindowsWechat(0x63090a13) UnifiedPCWindowsWechat(0xf2541022) XWEB/16467',
'xweb_xhr': '1',
'Content-Type': 'application/json',
'Accept': '*/*',
'Sec-Fetch-Site': 'cross-site',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Dest': 'empty',
'Referer': 'https://servicewechat.com/wxc83b55d61c7fc51d/41/page-frame.html',
'Accept-Encoding': 'gzip, deflate, br',
'Accept-Language': 'zh-CN,zh;q=0.9',
'Priority': 'u=1, i'
};
}
// 生成时间戳
getMockTime() {
return Date.now();
}
// 发送请求
async request(url, method = 'GET', data = null) {
const headers = this.getHeaders();
try {
let response;
const config = {
headers: headers,
timeout: 10000
};
if (method === 'GET') {
response = await $.http.get(url, config);
} else {
response = await $.http.post(url, data, config);
}
if (response.status === 200) {
return response.data;
} else {
console.log(`❌ 请求失败: ${response.status}`);
return null;
}
} catch (error) {
console.log(`❌ 请求异常: ${error.message}`);
return null;
}
}
// 获取用户信息
async getUserInfo() {
const url = `${API_HOST}/pmall/c/user/memberInfo`;
const result = await this.request(url);
if (result && result.code === "000000" && result.data) {
this.userInfo = result.data;
return this.userInfo;
} else {
console.log(`❌ 获取用户信息失败: ${result ? result.message : '网络错误'}`);
return null;
}
}
// 查询单个任务结果
async querySingleTaskResult(taskName) {
const url = `${API_HOST}/pmall/c/activity/todo/queryTodoResult`;
const result = await this.request(url);
if (result && result.code === "000000" && result.data) {
// 查找特定任务的结果
const taskResult = result.data.find(task => task.taskName === taskName);
if (taskResult) {
const credits = taskResult.actualCredits || 0;
console.log(`🎉 任务【${taskName}】获得积分: ${credits}`);
this.taskResults.push(`✅ ${taskName} +${credits}积分`);
this.creditsEarned += credits;
return credits;
}
}
return 0;
}
// 查询所有任务结果
async queryAllTaskResults() {
const url = `${API_HOST}/pmall/c/activity/todo/queryTodoResult`;
const result = await this.request(url);
if (result && result.code === "000000" && result.data) {
let total = 0;
result.data.forEach(task => {
const credits = task.actualCredits || 0;
total += credits;
console.log(`📊 ${task.taskName}: +${credits}积分`);
});
console.log(`🎉 今日已获得积分: ${total}`);
return total;
} else {
console.log(`❌ 查询任务结果失败: ${result ? result.message : '未知错误'}`);
return 0;
}
}
// 获取任务列表
async getTaskList() {
const url = `${API_HOST}/pmall/c/activity/todo/list?mockTime=${this.getMockTime()}`;
const result = await this.request(url);
if (result && result.code === "000000") {
return result.data;
} else {
console.log(`❌ 获取任务列表失败: ${result ? result.message : '网络错误'}`);
return null;
}
}
// 执行签到
async doCheckIn(activityId, taskName) {
const url = `${API_HOST}/pmall/c/activity/todo/checkIn`;
const data = {
"activityId": activityId,
"mockTime": this.getMockTime()
};
const result = await this.request(url, 'POST', data);
if (result && result.code === "000000") {
console.log(`✅ ${taskName} 完成`);
// 查询签到结果
await $.wait(1000);
await this.querySingleTaskResult(taskName);
return true;
} else {
console.log(`❌ ${taskName} 失败: ${result ? result.message : '未知错误'}`);
return false;
}
}
// 执行浏览任务
async doBrowseTask(activityId, taskName) {
const url = `${API_HOST}/pmall/c/activity/todo/receive`;
const data = {
"activityId": activityId,
"mockTime": this.getMockTime()
};
const result = await this.request(url, 'POST', data);
if (result && result.code === "000000") {
console.log(`✅ ${taskName} 完成`);
// 查询任务结果
await $.wait(1000);
await this.querySingleTaskResult(taskName);
return true;
} else {
console.log(`❌ ${taskName} 失败: ${result ? result.message : '未知错误'}`);
return false;
}
}
// 执行完成类任务
async doCompleteTask(activityId, taskName) {
const url = `${API_HOST}/pmall/c/activity/todo/complete`;
const data = {
"activityId": activityId,
"mockTime": this.getMockTime()
};
const result = await this.request(url, 'POST', data);
if (result && result.code === "000000") {
console.log(`✅ ${taskName} 完成`);
// 查询任务结果
await $.wait(1000);
await this.querySingleTaskResult(taskName);
return true;
} else {
console.log(`❌ ${taskName} 失败: ${result ? result.message : '未知错误'}`);
return false;
}
}
// 执行所有任务
async doAllTasks() {
console.log(`\n🚀 开始执行 ${this.accountName} 任务...`);
// 首先获取用户信息(初始积分)
console.log('📡 获取初始用户信息...');
await this.getUserInfo();
if (this.userInfo) {
this.initialPoints = this.userInfo.points;
console.log(`📊 初始积分: ${this.initialPoints}`);
}
// 获取任务列表
const taskData = await this.getTaskList();
if (!taskData) {
console.log('❌ 获取任务列表失败,跳过该账号');
return;
}
// 执行签到任务
if (taskData.checkInTodo) {
const checkInId = taskData.checkInTodo.id;
const taskName = taskData.checkInTodo.name;
await this.doCheckIn(checkInId, taskName);
await $.wait(2000);
}
// 执行其他任务
if (taskData.taskTodo && taskData.taskTodo.length > 0) {
for (const task of taskData.taskTodo) {
const taskId = task.id;
const taskName = task.name;
const taskType = task.taskTodoExtra?.type;
console.log(`\n🚀 处理任务: ${taskName}`);
// 根据任务类型执行不同的操作
switch (taskType) {
case 'BROWSE_PAGE':
await this.doBrowseTask(taskId, taskName);
break;
case 'AddQw':
case 'FirstOrder':
// 这些任务需要手动完成,跳过
console.log(`⏭️ 跳过需要手动完成的任务: ${taskName}`);
break;
default:
await this.doCompleteTask(taskId, taskName);
break;
}
// 短暂延迟,避免请求过快
await $.wait(2000);
}
}
// 查询所有任务结果汇总
console.log(`\n📋 任务完成汇总:`);
await this.queryAllTaskResults();
// 重新获取用户信息以获取最终积分
console.log('\n📡 获取最终用户信息...');
await this.getUserInfo();
if (this.userInfo) {
this.finalPoints = this.userInfo.points;
console.log(`📊 最终积分: ${this.finalPoints}`);
const actualIncrease = this.finalPoints - this.initialPoints;
console.log(`🎊 实际积分增加: ${actualIncrease}`);
}
console.log(`🎊 ${this.accountName} 任务执行完成`);
}
// 获取任务结果
getResults() {
return {
accountName: this.accountName,
credits: this.creditsEarned,
tasks: this.taskResults,
userInfo: this.userInfo,
initialPoints: this.initialPoints,
finalPoints: this.finalPoints
};
}
}
// 解析环境变量(支持备注)
function parseCookies(cookieStr) {
const cookies = [];
const lines = cookieStr.split('\n').filter(line => line.trim());
lines.forEach((line, index) => {
const parts = line.split('#');
const cuk = parts[0].trim();
const remark = parts[1] ? parts[1].trim() : '';
if (cuk) {
cookies.push({
cuk: cuk,
index: index + 1,
remark: remark
});
}
});
return cookies;
}
// 主函数
async function main() {
console.log("🚀 星妈会自动任务开始执行...\n");
// 读取环境变量
const cookieStr = process.env.XMH_COOKIE || '';
if (!cookieStr) {
console.log("❌ 未找到有效的cuk配置,请检查环境变量 XMH_COOKIE");
return;
}
// 解析cookies
const cookieList = parseCookies(cookieStr);
if (cookieList.length === 0) {
console.log("❌ 未找到有效的cuk配置,请检查环境变量 XMH_COOKIE");
return;
}
console.log(`📝 找到 ${cookieList.length} 个账号\n`);
// 显示账号信息
cookieList.forEach(cookie => {
console.log(` ${cookie.index}. ${cookie.remark || '未备注'}`);
});
console.log('');
// 初始化账号实例
for (const cookie of cookieList) {
allAccounts.push(new XingMaHui(cookie.cuk, cookie.index, cookie.remark));
}
// 依次执行每个账号的任务
for (const account of allAccounts) {
currentAccount = account.index;
await account.doAllTasks();
totalCredits += account.creditsEarned;
// 账号间延迟
if (account.index < allAccounts.length) {
console.log("\n⏳ 等待5秒后处理下一个账号...\n");
await $.wait(5000);
}
}
// 汇总结果
await showSummary();
}
// 显示汇总结果
async function showSummary() {
console.log("\n" + "=".repeat(70));
console.log("🎉 星妈会任务执行汇总");
console.log("=".repeat(70));
let summaryMessage = `星妈会任务完成情况:\n\n`;
let consoleMessage = ``;
for (const account of allAccounts) {
const results = account.getResults();
// 显示用户基本信息
if (results.userInfo) {
summaryMessage += `📱 ${results.accountName}:\n`;
summaryMessage += ` 手机号:${results.userInfo.mobile}\n`;
summaryMessage += ` 会员等级:${results.userInfo.gradeName}\n`;
summaryMessage += ` 初始积分:${results.initialPoints}\n`;
summaryMessage += ` 最终积分:${results.finalPoints}\n`;
summaryMessage += ` 实际增加:${results.finalPoints - results.initialPoints}积分\n`;
consoleMessage += `📱 ${results.accountName}:\n`;
consoleMessage += ` 📞 手机号:${results.userInfo.mobile}\n`;
consoleMessage += ` ⭐ 会员等级:${results.userInfo.gradeName}\n`;
consoleMessage += ` 📥 初始积分:${results.initialPoints}\n`;
consoleMessage += ` 📤 最终积分:${results.finalPoints}\n`;
consoleMessage += ` 📈 实际增加:${results.finalPoints - results.initialPoints}积分\n`;
} else {
summaryMessage += `📱 ${results.accountName}:\n`;
summaryMessage += ` ❌ 用户信息获取失败\n`;
consoleMessage += `📱 ${results.accountName}:\n`;
consoleMessage += ` ❌ 用户信息获取失败\n`;
}
// 显示任务完成情况
summaryMessage += ` 今日获得:${results.credits}积分\n`;
consoleMessage += ` 🎉 今日获得:${results.credits}积分\n`;
if (results.tasks.length > 0) {
summaryMessage += ` 完成任务:\n`;
consoleMessage += ` ✅ 完成任务:\n`;
results.tasks.forEach(task => {
summaryMessage += ` ${task}\n`;
consoleMessage += ` ${task}\n`;
});
}
summaryMessage += `\n`;
consoleMessage += `\n`;
}
summaryMessage += `📊 总计:${allAccounts.length} 个账号,今日共获得 ${totalCredits} 积分`;
consoleMessage += `📊 总计:${allAccounts.length} 个账号,今日共获得 ${totalCredits} 积分`;
console.log(consoleMessage);
// 发送通知
if ($.isNode() && notify) {
await notify.sendNotify("星妈会任务完成", summaryMessage);
}
}
// 运行脚本
main().catch(error => {
console.log(`❌ 脚本执行出错: ${error}`);
if ($.isNode() && notify) {
notify.sendNotify("星妈会任务异常", `执行过程中出现错误: ${error}`);
}
});
+808
View File
@@ -0,0 +1,808 @@
/*
================================================================================
脚本名称: 飞鹤|北纬47度好物(原星妈优选)
30 0 * * * xmyx.js
脚本作者: Leiyiyan
创建日期: 2024-10-08
最后更新: 2024-12-03
================================================================================
【功能说明】
飞鹤|北纬47度好物小程序 每日签到、自动完成任务
【使用方法】
1. 青龙面板配置:
- 进入青龙面板 → 环境变量
- 添加变量名:xmtoken
- 变量值:每行一个token(支持多账号)
2. 环境变量格式(三种方式任选其一):
方式1(推荐):换行分隔
token1
token2
token3
方式2:&符号分隔
token1&token2&token3
方式3:@符号分隔
token1@token2@token3
【获取Token】
方法1:抓包获取
- 抓包地址:https://www.feihevip.com/api/starMember/getMemberInfo
- 抓取请求头中的 token 字段
方法2:使用抓包工具(推荐使用 Quantumult X 或 Surge)
[Script]
http-response ^https?:\/\/www\.feihevip\.com\/api\/starMember\/getMemberInfo script-path=xmyx.js, requires-body=true, timeout=60, tag=星妈优选获取Cookie
[MITM]
hostname = www.feihevip.com
【定时任务】
建议每天早上0点30分执行
cron: 30 0 * * *
【图标】
https://raw.githubusercontent.com/leiyiyan/resource/main/icons/xmyx.png
================================================================================
⚠️【免责声明】
================================================================================
1、此脚本仅用于学习研究,不保证其合法性、准确性、有效性,请根据情况自行判断,
本人对此不承担任何保证责任。
2、由于此脚本仅用于学习研究,您必须在下载后 24 小时内将所有内容从您的计算机
或手机或任何存储设备中完全删除,若违反规定引起任何事件本人对此均不负责。
3、请勿将此脚本用于任何商业或非法目的,若违反规定请自行对此负责。
4、此脚本涉及应用与本人无关,本人对因此引起的任何隐私泄漏或其他后果不承担
任何责任。
5、本人对任何脚本引发的问题概不负责,包括但不限于由脚本错误引起的任何损失
和损害。
6、如果任何单位或个人认为此脚本可能涉嫌侵犯其权利,应及时通知并提供身份证明,
所有权证明,我们将在收到认证文件确认后删除此脚本。
7、所有直接或间接使用、查看此脚本的人均应该仔细阅读此声明。本人保留随时更改
或补充此声明的权利。一旦您使用或复制了此脚本,即视为您已接受此免责声明。
================================================================================
*/
const $ = new Env("星妈优选");
const ckName = "xmtoken";
//-------------------- 一般不动变量区域 -------------------------------------
$.appid = "wx4205ec55b793245e";
const Notify = 1;//0为关闭通知,1为打开通知,默认为1
// 优先使用青龙面板自带的 sendNotify,如果不存在则使用本地的
const notify = $.isNode() ? (() => {
try {
// 尝试加载青龙面板的 sendNotify
return require('./sendNotify');
} catch (e) {
try {
// 如果青龙的不存在,尝试加载本地的
return require('./sendNotify');
} catch (err) {
console.log('⚠️ sendNotify 加载失败,通知功能将不可用');
return null;
}
}
})() : '';
// 初始化 got 库
if ($.isNode()) {
try {
$.initGotEnv();
} catch (e) {
console.log('⚠️ got 库初始化失败,部分功能可能受限');
}
}
let envSplitor = ["\n", "&", "@"]; //多账号分隔符,优先使用换行符
// 从环境变量读取 token,支持多账号
// 环境变量名: xmtoken
// 格式: 多个token用@或换行分隔,例如: token1@token2@token3
var userCookie = ($.isNode() ? process.env[ckName] : $.getdata(ckName)) || '';
let userList = [];
let userIdx = 0;
let userCount = 0;
// 调试
$.is_debug = ($.isNode() ? process.env.IS_DEDUG : $.getdata('is_debug')) || 'false';
// 为多用户准备的通知数组
$.notifyList = [];
// 为通知准备的空数组
$.notifyMsg = [];
//---------------------- 自定义变量区域 -----------------------------------
const appid = 'xmyx'
const appKey = 'TwUQ01lKS1Km5zlV2f7amsZc5EQYkTbv'
//---------------------- 脚本入口函数 -----------------------------------
async function main() {
try {
$.log('\n' + '='.repeat(50));
$.log('🎯 开始执行任务');
$.log('='.repeat(50) + '\n');
// 仅调用一次 getTaskList
let taskList = [];
if (userList.length > 0) {
taskList = await userList[0].getTaskList();
$.log(`� 获取到 ${taskList.length} 个账号任务\n`);
}
for (let user of userList) {
$.log(`\n${'─'.repeat(50)}`);
$.log(`📱 账号 ${user.index} 开始执行`);
$.log('─'.repeat(50));
// 先获取用户信息
const userInfoBefore = await user.getUserInfo();
if (userInfoBefore) {
const { userName, score, level, mobile } = userInfoBefore;
user.userName = userName;
user.avatar = userInfoBefore.avatar;
user.mobile = mobile;
$.log(`� 用户: ${userName || '未知'}${mobile ? ` (${mobile})` : ''}`);
$.log(`💰 当前积分: ${score} | 等级: ${level}`);
}
const flag = await user.getSignInfo();
if (user.ckStatus) {
// 完成任务
if (taskList.length > 0) {
$.log(`\n📝 开始执行任务列表...`);
for(let task of taskList) {
await user.tofinish(task.taskName, task.taskType);
await $.wait(1000 * (task.completeTaskDuration?task.completeTaskDuration:3))
await user.completeTask(task.taskName, task.taskType);
await $.wait(user.getRandomTime());
}
}
// 查询最终用户信息
const userInfoAfter = await user.getUserInfo();
if (userInfoAfter) {
const { score, level, userName, avatar, mobile } = userInfoAfter;
user.avatar = avatar;
user.userName = userName;
user.mobile = mobile;
await user.refreshToken(user.token);
const earnedPoints = userInfoBefore ? score - userInfoBefore.score : 0;
$.log(`\n✨ 任务完成`);
$.log(`� 用户:分 ${userName}${mobile ? ` (${mobile})` : ''}`);
$.log(`💰 最终积分: ${score} ${earnedPoints > 0 ? `(+${earnedPoints})` : ''}`);
$.log(`⭐ 等级: ${level}`);
$.title = `今日任务已全部完成`;
// 通知消息包含手机号/fullName
const displayName = mobile ? `${userName} (${mobile})` : userName;
DoubleLog(`「${displayName}」积分: ${score}${earnedPoints > 0 ? ` (+${earnedPoints})` : ''}, 等级: ${level}`);
}
} else {
//将ck过期消息存入消息数组
$.notifyMsg.push(`❌账号${user.userName || user.index} >> Token已失效`)
}
//账号通知
$.notifyList.push({ "id": user.index, "avatar": user.avatar, "message": $.notifyMsg });
//清空数组
$.notifyMsg = [];
}
$.log(`\n${'='.repeat(50)}`);
$.log(`✅ 所有账号执行完成`);
$.log('='.repeat(50) + '\n');
} catch (e) {
$.log(`⛔️ main run error => ${e}`);
throw new Error(`⛔️ main run error => ${e}`);
}
}
class UserInfo {
constructor(user) {
//默认属性
this.index = ++userIdx;
this.token = user.token || user;
this.userId = user.userId;
this.userName = user.userName;
this.avatar = user.avatar;
this.ckStatus = true;
this.doFlag = { "true": "✅", "false": "⛔️" };
//请求封装
this.baseUrl = ``;
this.host = "https://www.feihevip.com/api";
this.headers = {
"Host": "www.feihevip.com",
"token": this.token,
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_8 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.48(0x1800302b) NetType/4G Language/zh_CN",
"Referer": "https://servicewechat.com/wx4205ec55b793245e/366/page-frame.html",
"fhAppid": appid,
"source": 1
}
this.getRandomTime = () => randomInt(1e3, 3e3);
this.fetch = async (o) => {
try {
if (typeof o === 'string') o = { url: o };
if (o?.url?.startsWith("/")) o.url = this.host + o.url
const res = await Request({ ...o, headers: o.headers || this.headers, url: o.url || this.baseUrl })
// debug(res, o?.url?.replace(/\/+$/, '').substring(o?.url?.lastIndexOf('/') + 1));
if (res?.code == 40001) throw new Error(res?.message || `用户需要去登录`);
return res;
} catch (e) {
this.ckStatus = false;
$.log(`⛔️ 请求发起失败!${e}`);
}
}
}
// 签到
async getSignInfo() {
try {
const { fhNonceStr, fhTimestamp, fhSign } = getSignature();
const opts = {
url: '/member/signin/getSignInfo',
type: "get",
params: {
signType: 1
},
headers: Object.assign({}, this.headers, {
fhNonceStr,
fhTimestamp,
fhSign
})
}
const res = await this.fetch(opts);
if (!res?.data) {
$.log(`⚠️ 签到信息获取失败`);
return;
}
const { signStatus } = res.data;
if (signStatus === 1) {
$.log(`✅ 今日已签到`);
}
if (signStatus === 2) {
await this.signin();
}
} catch (e) {
this.ckStatus = false;
$.log(`⛔️ 签到失败: ${e}`);
}
}
// 签到
async signin() {
try {
const { fhNonceStr, fhTimestamp, fhSign } = getSignature();
const res = await this.fetch({
url: '/member/signin/sign',
type: 'post',
params: {},
headers: Object.assign({}, this.headers, {
fhNonceStr,
fhTimestamp,
fhSign
})
});
if (res.code === '200') {
$.log(`✅ 签到成功`);
} else {
$.log(`✅ 签到失败:${res.msg}`);
}
} catch (e) {
this.ckStatus = false;
$.log(`⛔️ 执行任务今日签到失败! ${e}`);
}
}
// 获取任务列表
async getTaskList() {
try {
const { fhNonceStr, fhTimestamp, fhSign } = getSignature();
const opts = {
url: '/member/signin/getTaskList',
type: "get",
headers: Object.assign({}, this.headers, {
fhNonceStr,
fhTimestamp,
fhSign
})
}
const res = await this.fetch(opts);
debug(res, `获取任务列表`);
if (res?.code == '200' && res?.data) {
return res.data;
} else {
$.log(`⛔️ 获取任务列表失败! ${res?.msg}\n`);
return [];
}
} catch (e) {
this.ckStatus = false;
$.log(`⛔️ 获取任务列表失败! ${e}`);
return [];
}
}
// 执行任务
async tofinish(taskName, taskType) {
try {
const { fhNonceStr, fhTimestamp, fhSign } = getSignature();
const opts = {
url: '/member/signin/tofinish',
type: "get",
params: {
taskType
},
headers: Object.assign({}, this.headers, {
fhNonceStr,
fhTimestamp,
fhSign
})
}
const res = await this.fetch(opts);
debug(res, `执行任务: ${taskName}`)
if (res?.code == '200') {
$.log(` 🚀 开始: ${taskName}`);
} else {
$.log(` ⚠️ ${taskName}: ${res?.msg}`);
}
} catch (e) {
this.ckStatus = false;
$.log(` ⛔️ ${taskName} 失败: ${e}`);
}
}
// 完成任务
async completeTask(taskName, taskType) {
try {
const { fhNonceStr, fhTimestamp, fhSign } = getSignature();
const opts = {
url: '/member/signin/completeTask',
type: "get",
params: {
taskType
},
headers: Object.assign({}, this.headers, {
fhNonceStr,
fhTimestamp,
fhSign
})
}
const res = await this.fetch(opts);
debug(res, `完成任务: ${taskName}`)
if(res?.code == '200') {
if(res?.data) {
const point = res?.data?.awardSendPoints;
$.log(` ✅ 完成: ${taskName} +${point}积分`);
}else{
$.log(` ℹ️ ${taskName} 已完成`);
}
}else{
$.log(` ⛔️ ${taskName} 失败: ${res?.msg}`);
}
} catch (e) {
this.ckStatus = false;
$.log(` ⛔️ ${taskName} 异常: ${e}`);
}
}
// 获取用户信息
async getUserInfo() {
try {
const { fhNonceStr, fhTimestamp, fhSign } = getSignature({});
const opts = {
url: '/starMember/getMemberInfo',
type: "post",
dataType: "json",
headers: Object.assign({}, this.headers, {
fhNonceStr,
fhTimestamp,
fhSign
}),
body: {}
}
const res = await this.fetch(opts);
debug(res, `查询用户信息`)
if(res?.code == '200' && res?.data) {
// 积分
const score = res?.data?.memberPoints?.scoreValue;
// 等级
const level = res?.data?.memberGrade?.currentGrade;
// 用户名
const userName = res?.data?.baseInfo?.nickName;
// 头像
const avatar = res?.data?.baseInfo?.headImgUrl;
// 手机号(从多个可能的字段中获取,优先使用看起来像手机号的)
let mobile = '';
const possibleFields = [
res?.data?.baseInfo?.mobile,
res?.data?.baseInfo?.fullName,
res?.data?.mobile
];
// 找到第一个看起来像手机号的字段(11位数字)
for (const field of possibleFields) {
if (field && /^1\d{10}$/.test(field)) {
mobile = field;
break;
}
}
// 如果没找到手机号格式的,就用 fullName 或 crmId
if (!mobile) {
mobile = res?.data?.baseInfo?.fullName || res?.data?.crmId || '';
}
return { score, level, userName, avatar, mobile };
}else{
$.log(`⛔️ 查询用户信息失败! ${res?.msg}\n`);
}
} catch (e) {
this.ckStatus = false;
$.log(`⛔️ 查询用户信息失败! ${e}`);
}
}
// 刷新token
async refreshToken(token) {
try {
const { fhNonceStr, fhTimestamp, fhSign } = getSignature2();
const options = {
url: `https://mom.feihe.com/program/token/refreshToken`,
type: "get",
headers: {
"Host": "mom.feihe.com",
"token": token,
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_8 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.48(0x1800302b) NetType/4G Language/zh_CN",
"Referer": "https://servicewechat.com/wx4205ec55b793245e/366/page-frame.html",
"fhAppid": 'xmh',
"source": 1,
fhNonceStr,
fhTimestamp,
fhSign
}
};
//post方法
let result = await Request(options);
let refreshToken = result?.data;
if (refreshToken) {
// 更新当前用户的token
this.token = refreshToken;
this.headers.token = refreshToken;
$.log(`🎉 刷新 token 成功`)
debug(result, '获取token');
} else {
$.log(`⚠️ 刷新 token 返回为空`)
}
} catch (e) {
$.log(`⛔️ 刷新 Token 失败: ${e}`)
}
}
}
async function getCookie() {
if ($request && $request.method === 'OPTIONS') return;
const header = ObjectKeys2LowerCase($request.headers);
const token = header.token;
const body = $.toObj($response.body);
if (!(body?.data)) {
$.msg($.name, `❌获取Cookie失败!`, "")
return;
}
// 积分
const score = body?.data?.memberPoints?.scoreValue;
// ID
const unionId = body?.data?.unionId;
// 用户名
const userName = body?.data?.baseInfo?.nickName;
// 头像
const avatar = body?.data?.baseInfo?.headImgUrl;
const newData = {
"userId": unionId,
"avatar": avatar,
"token": token,
"userName": userName,
}
userCookie = userCookie ? JSON.parse(userCookie) : [];
const index = userCookie.findIndex(e => e.userId == newData.userId);
userCookie[index] ? userCookie[index] = newData : userCookie.push(newData);
$.setjson(userCookie, ckName);
$.msg($.name, `🎉${newData.userName}更新token成功!`, ``);
}
//自动生成token
async function getWxToken(code) {
try {
const { fhNonceStr, fhTimestamp, fhSign } = getSignature({code});
const options = {
url: `https://www.feihevip.com/api/wechat/auth/miniAssets`,
type: "post",
dataType: "json",
headers: {
"Host": "www.feihevip.com",
"token": '',
"User-Agent": "Mozilla/5.0 (iPhone; CPU iPhone OS 15_8 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 MicroMessenger/8.0.48(0x1800302b) NetType/4G Language/zh_CN",
"Referer": "https://servicewechat.com/wx4205ec55b793245e/366/page-frame.html",
"fhAppid": appid,
"source": 1,
fhNonceStr,
fhTimestamp,
fhSign
},
body: {
code
}
};
//post方法
let result = await Request(options);
let token = result?.data?.token;
debug(result, '获取token');
return token;
} catch (e) {
$.log(`❌getWxToken run error => ${e}`)
}
}
//检查code服务器
async function checkCodeServer(appid) {
// 环境变量
$.codeServer = $.isNode() ? process.env["CODESERVER_ADDRESS"] : $.getdata('@codeServer.address');
// 需要获取的微信列表,用,分隔
$.wxId = ($.isNode() ? process.env["CODESERVER_WXID"] : $.getdata('@codeServer.wxId')).split(",");
// 获取codeList
let codeList = await Promise.all($.wxId.map(e => getCode(e)));
async function getCode(wxId) {
try {
const options = {
url: `${$.codeServer}/api/Common/JSLogin`,
headers: { "accept": "application/json", "content-type": "application/json" },
body: JSON.stringify({
'wxId': wxId,
'appId': appid
})
};
let res = await $.http.post(options);
res = $.toObj(res?.body);
return res?.Data?.code;
} catch (e) {
$.log(e);
}
}
debug(codeList);
!codeList.length
? $.log(`❌获取code授权失败!请检查服务器运行是否正常 => 尝试读取数据持久化 `)
: $.log(`✅获取code授权成功!当前code数量为${codeList.length}`);
let userList = await Promise.all(codeList.map(async (code) => {
const token = await getWxToken(code);
const newToken = await refreshToken(token);
debug(newToken)
return { "token": newToken };
}));
userList = userList.filter(value => Object.keys(value).length !== 0)
return userList;
}
//检查环境变量
async function checkEnv() {
try {
if (!userCookie) {
throw new Error(`❌未检测到环境变量 ${ckName},请先配置`);
}
let usersToAdd = [];
// 如果是字符串,尝试解析
if (typeof userCookie === 'string') {
// 尝试解析为JSON
try {
const parsed = JSON.parse(userCookie);
if (Array.isArray(parsed)) {
usersToAdd = parsed;
} else {
usersToAdd = [parsed];
}
} catch (e) {
// 不是JSON格式,按分隔符处理
const separator = envSplitor.find(s => userCookie.includes(s)) || envSplitor[0];
const tokens = userCookie.split(separator).map(t => t.trim()).filter(Boolean);
usersToAdd = tokens.map(token => ({ token }));
}
} else if (Array.isArray(userCookie)) {
usersToAdd = userCookie;
} else {
usersToAdd = [userCookie];
}
if (!usersToAdd.length) {
throw new Error(`❌未找到有效的token数据`);
}
userList.push(...usersToAdd.map(n => new UserInfo(n)).filter(Boolean));
userCount = userList.length;
console.log(`✅ 共找到 ${userCount} 个账号`);
return true;
} catch (e) {
throw new Error(`❌checkEnv run error => ${e}`)
}
}
//请求二次封装
async function Request(o) {
if (typeof o === 'string') o = { url: o };
try {
if (!o?.url) throw new Error('[发送请求] 缺少 url 参数');
// type => 因为env中使用method处理post的特殊请求(put/delete/patch), 所以这里使用type
let { url: u, type, headers = {}, body: b, params, dataType = 'form', resultType = 'data' } = o;
// post请求需要处理params参数(get不需要, env已经处理)
const method = type ? type?.toLowerCase() : ('body' in o ? 'post' : 'get');
const url = u.concat(method === 'post' ? '?' + $.queryStr(params) : '');
const timeout = o.timeout ? ($.isSurge() ? o.timeout / 1e3 : o.timeout) : 1e4
// 根据jsonType处理headers
if (dataType === 'json') headers['Content-Type'] = 'application/json;charset=UTF-8';
// post请求处理body
const body = b && dataType == 'form' ? $.queryStr(b) : $.toStr(b);
const request = { ...o, ...(o?.opts ? o.opts : {}), url, headers, ...(method === 'post' && { body }), ...(method === 'get' && params && { params }), timeout: timeout }
const httpPromise = $.http[method.toLowerCase()](request)
.then(response => resultType == 'data' ? ($.toObj(response.body) || response.body) : ($.toObj(response) || response))
.catch(err => $.log(`❌请求发起失败!原因为:${err}`));
// 使用Promise.race来强行加入超时处理
return Promise.race([
new Promise((_, e) => setTimeout(() => e('当前请求已超时'), timeout)),
httpPromise
]);
} catch (e) {
console.log(`❌请求发起失败!原因为:${e}`);
}
};
//生成随机数
function randomInt(n, r) {
return Math.round(Math.random() * (r - n) + n)
};
//控制台打印
function DoubleLog(data) {
if (data && $.isNode()) {
console.log(`${data}`);
$.notifyMsg.push(`${data}`)
} else if (data) {
console.log(`${data}`);
$.notifyMsg.push(`${data}`)
}
};
//调试
function debug(t, l = 'debug') {
if ($.is_debug === 'true') {
$.log(`\n-----------${l}------------\n`);
$.log(typeof t == "string" ? t : $.toStr(t) || `debug error => t=${t}`);
$.log(`\n-----------${l}------------\n`)
}
};
//对多账号通知进行兼容
async function SendMsgList(l) {
await Promise.allSettled(l?.map(u => SendMsg(u.message.join('\n'), u.avatar)));
};
//账号通知
async function SendMsg(n, o) {
n && (0 < Notify ? $.isNode() ? await notify.sendNotify($.name, n) : $.msg($.name, $.title || "", n, {
"media-url": o
}) : console.log(n))
};
//转换为小写
function ObjectKeys2LowerCase(obj) { return Object.fromEntries(Object.entries(obj).map(([k, v]) => [k.toLowerCase(), v])) };
// 获取签名
function getSignature(data) {
const json = data ? JSON.stringify(data) : ''
const fhNonceStr = getFhNonceStr({ length: 16 })
const fhTimestamp = getTimestamp()
const signString = `fhAppid${appid}fhNonceStr${fhNonceStr}fhTimestamp${fhTimestamp}${json}${appKey}`
// debug(signString + '->' + md5(signString).toUpperCase(), '签名字符串')
return {
fhNonceStr,
fhTimestamp,
fhSign: md5(signString).toUpperCase()
}
}
function getSignature2() {
const fhNonceStr = getFhNonceStr({ length: 16 })
const fhTimestamp = getTimestamp()
const signString = `fhAppidxmhfhNonceStr${fhNonceStr}fhTimestamp${fhTimestamp}98d9fe9b613a479dbcb111ca261e3ce1`
// debug(signString + '->' + md5(signString).toUpperCase(), '签名字符串')
return {
fhNonceStr,
fhTimestamp,
fhSign: md5(signString).toUpperCase()
}
}
// 获取10位时间戳
function getTimestamp() {
return +String(Date.now()).slice(0, 10)
}
// 获取随机字符串
function getFhNonceStr(t) { var e, r, n = "", o = (t = function (t) { return t || (t = {}), { length: t.length || 8, numeric: "boolean" != typeof t.numeric || t.numeric, letters: "boolean" != typeof t.letters || t.letters, special: "boolean" == typeof t.special && t.special, exclude: Array.isArray(t.exclude) ? t.exclude : [] } }(t)).length; t.exclude; var i = function (t) { var e = ""; t.numeric && (e += "0123456789"), t.letters && (e += "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"), t.special && (e += "!$%^&*()_+|~-=`{}[]:;<>?,./"); for (var r = 0; r <= t.exclude.length; r++)e = e.replace(t.exclude[r], ""); return e }(t); for (e = 1; e <= o; e++)n += i.substring(r = Math.floor(Math.random() * i.length), r + 1); return n }
//---------------------- 主程序执行入口 -----------------------------------
!(async () => {
if (typeof $request != "undefined") {
await getCookie();
} else {
if (!(await checkEnv())) throw new Error(`❌未检测到ck,请添加环境变量`);
if (userList.length > 0) await main();
}
})()
.catch(e => $.notifyMsg.push(e.message || e))
.finally(async () => {
// 新增:获取随机古诗词
let poetry = await getRandomPoetry();
// 合并所有通知消息
let finalMessage = [poetry]; // 将诗词放在开头
let avatars = [];
// 处理账号通知
for (const user of $.notifyList) {
if (user.message.length > 0) {
finalMessage.push(`📱 账号${user.id}\n${user.message.join('\n')}`);
avatars.push(user.avatar);
}
}
// 添加错误通知
if ($.notifyMsg.length > 0) {
finalMessage.push(`❌ 错误信息:\n${$.notifyMsg.join('\n')}`);
}
if (finalMessage.length > 0) {
// 合并消息并发送
const combinedMessage = finalMessage.join('\n\n──────────────\n\n');
const firstValidAvatar = avatars.find(avatar => avatar) || '';
await SendMsg(combinedMessage, firstValidAvatar);
}
$.done({ ok: 1 });
});
// 新增:获取随机古诗词函数
async function getRandomPoetry() {
try {
const url = 'https://v2.jinrishici.com/sentence';
const res = await Request({
url,
headers: {
'X-User-Token': '+SBGb0hF88lM7xdBcWe4t4jQCMeBXBzJ' // 示例token,建议申请自己的
}
});
if (res?.data?.content) {
return `📜 ${res.data.content}\n —— ${res.data.origin.author}《${res.data.origin.title}》`;
}
} catch (e) {
$.log('获取诗词失败,使用默认句子');
}
// 备用默认句子
const defaultPoems = [
'及时当勉励,岁月不待人。——陶渊明《杂诗》',
'会当凌绝顶,一览众山小。——杜甫《望岳》',
'长风破浪会有时,直挂云帆济沧海。——李白《行路难》'
];
return `📜 ${defaultPoems[Math.floor(Math.random() * defaultPoems.length)]}`;
}
/** ---------------------------------固定不动区域----------------------------------------- */
// prettier-ignore
//From chavyleung's Env.js
function Env(t, e) { class s { constructor(t) { this.env = t } send(t, e = "GET") { t = "string" == typeof t ? { url: t } : t; let s = this.get; return "POST" === e && (s = this.post), new Promise(((e, r) => { s.call(this, t, ((t, s, a) => { t ? r(t) : e(s) })) })) } get(t) { return this.send.call(this.env, t) } post(t) { return this.send.call(this.env, t, "POST") } } return new class { constructor(t, e) { this.name = t, this.http = new s(this), this.data = null, this.dataFile = "box.dat", this.logs = [], this.isMute = !1, this.isNeedRewrite = !1, this.logSeparator = "\n", this.encoding = "utf-8", this.startTime = (new Date).getTime(), Object.assign(this, e), this.log("", `🔔${this.name}, 开始!`) } getEnv() { return "undefined" != typeof $environment && $environment["surge-version"] ? "Surge" : "undefined" != typeof $environment && $environment["stash-version"] ? "Stash" : "undefined" != typeof module && module.exports ? "Node.js" : "undefined" != typeof $task ? "Quantumult X" : "undefined" != typeof $loon ? "Loon" : "undefined" != typeof $rocket ? "Shadowrocket" : void 0 } isNode() { return "Node.js" === this.getEnv() } isQuanX() { return "Quantumult X" === this.getEnv() } isSurge() { return "Surge" === this.getEnv() } isLoon() { return "Loon" === this.getEnv() } isShadowrocket() { return "Shadowrocket" === this.getEnv() } isStash() { return "Stash" === this.getEnv() } toObj(t, e = null) { try { return JSON.parse(t) } catch { return e } } toStr(t, e = null) { try { return JSON.stringify(t) } catch { return e } } getjson(t, e) { let s = e; if (this.getdata(t)) try { s = JSON.parse(this.getdata(t)) } catch { } return s } setjson(t, e) { try { return this.setdata(JSON.stringify(t), e) } catch { return !1 } } getScript(t) { return new Promise((e => { this.get({ url: t }, ((t, s, r) => e(r))) })) } runScript(t, e) { return new Promise((s => { let r = this.getdata("@chavy_boxjs_userCfgs.httpapi"); r = r ? r.replace(/\n/g, "").trim() : r; let a = this.getdata("@chavy_boxjs_userCfgs.httpapi_timeout"); a = a ? 1 * a : 20, a = e && e.timeout ? e.timeout : a; const [i, o] = r.split("@"), n = { url: `http://${o}/v1/scripting/evaluate`, body: { script_text: t, mock_type: "cron", timeout: a }, headers: { "X-Key": i, Accept: "*/*" }, timeout: a }; this.post(n, ((t, e, r) => s(r))) })).catch((t => this.logErr(t))) } loaddata() { if (!this.isNode()) return {}; { this.fs = this.fs ? this.fs : require("fs"), this.path = this.path ? this.path : require("path"); const t = this.path.resolve(this.dataFile), e = this.path.resolve(process.cwd(), this.dataFile), s = this.fs.existsSync(t), r = !s && this.fs.existsSync(e); if (!s && !r) return {}; { const r = s ? t : e; try { return JSON.parse(this.fs.readFileSync(r)) } catch (t) { return {} } } } } writedata() { if (this.isNode()) { this.fs = this.fs ? this.fs : require("fs"), this.path = this.path ? this.path : require("path"); const t = this.path.resolve(this.dataFile), e = this.path.resolve(process.cwd(), this.dataFile), s = this.fs.existsSync(t), r = !s && this.fs.existsSync(e), a = JSON.stringify(this.data); s ? this.fs.writeFileSync(t, a) : r ? this.fs.writeFileSync(e, a) : this.fs.writeFileSync(t, a) } } lodash_get(t, e, s = void 0) { const r = e.replace(/\[(\d+)\]/g, ".$1").split("."); let a = t; for (const t of r) if (a = Object(a)[t], void 0 === a) return s; return a } lodash_set(t, e, s) { return Object(t) !== t || (Array.isArray(e) || (e = e.toString().match(/[^.[\]]+/g) || []), e.slice(0, -1).reduce(((t, s, r) => Object(t[s]) === t[s] ? t[s] : t[s] = Math.abs(e[r + 1]) >> 0 == +e[r + 1] ? [] : {}), t)[e[e.length - 1]] = s), t } getdata(t) { let e = this.getval(t); if (/^@/.test(t)) { const [, s, r] = /^@(.*?)\.(.*?)$/.exec(t), a = s ? this.getval(s) : ""; if (a) try { const t = JSON.parse(a); e = t ? this.lodash_get(t, r, "") : e } catch (t) { e = "" } } return e } setdata(t, e) { let s = !1; if (/^@/.test(e)) { const [, r, a] = /^@(.*?)\.(.*?)$/.exec(e), i = this.getval(r), o = r ? "null" === i ? null : i || "{}" : "{}"; try { const e = JSON.parse(o); this.lodash_set(e, a, t), s = this.setval(JSON.stringify(e), r) } catch (e) { const i = {}; this.lodash_set(i, a, t), s = this.setval(JSON.stringify(i), r) } } else s = this.setval(t, e); return s } getval(t) { switch (this.getEnv()) { case "Surge": case "Loon": case "Stash": case "Shadowrocket": return $persistentStore.read(t); case "Quantumult X": return $prefs.valueForKey(t); case "Node.js": return this.data = this.loaddata(), this.data[t]; default: return this.data && this.data[t] || null } } setval(t, e) { switch (this.getEnv()) { case "Surge": case "Loon": case "Stash": case "Shadowrocket": return $persistentStore.write(t, e); case "Quantumult X": return $prefs.setValueForKey(t, e); case "Node.js": return this.data = this.loaddata(), this.data[e] = t, this.writedata(), !0; default: return this.data && this.data[e] || null } } initGotEnv(t) { this.got = this.got ? this.got : require("got"), this.cktough = this.cLine truncated
// md5
function md5(md5str) {
var createMD5String = function (string) { var x = Array(); var k, AA, BB, CC, DD, a, b, c, d; var S11 = 7, S12 = 12, S13 = 17, S14 = 22; var S21 = 5, S22 = 9, S23 = 14, S24 = 20; var S31 = 4, S32 = 11, S33 = 16, S34 = 23; var S41 = 6, S42 = 10, S43 = 15, S44 = 21; string = uTF8Encode(string); x = convertToWordArray(string); a = 1732584193; b = 4023233417; c = 2562383102; d = 271733878; for (k = 0; k < x.length; k += 16) { AA = a; BB = b; CC = c; DD = d; a = FF(a, b, c, d, x[k + 0], S11, 3614090360); d = FF(d, a, b, c, x[k + 1], S12, 3905402710); c = FF(c, d, a, b, x[k + 2], S13, 606105819); b = FF(b, c, d, a, x[k + 3], S14, 3250441966); a = FF(a, b, c, d, x[k + 4], S11, 4118548399); d = FF(d, a, b, c, x[k + 5], S12, 1200080426); c = FF(c, d, a, b, x[k + 6], S13, 2821735955); b = FF(b, c, d, a, x[k + 7], S14, 4249261313); a = FF(a, b, c, d, x[k + 8], S11, 1770035416); d = FF(d, a, b, c, x[k + 9], S12, 2336552879); c = FF(c, d, a, b, x[k + 10], S13, 4294925233); b = FF(b, c, d, a, x[k + 11], S14, 2304563134); a = FF(a, b, c, d, x[k + 12], S11, 1804603682); d = FF(d, a, b, c, x[k + 13], S12, 4254626195); c = FF(c, d, a, b, x[k + 14], S13, 2792965006); b = FF(b, c, d, a, x[k + 15], S14, 1236535329); a = GG(a, b, c, d, x[k + 1], S21, 4129170786); d = GG(d, a, b, c, x[k + 6], S22, 3225465664); c = GG(c, d, a, b, x[k + 11], S23, 643717713); b = GG(b, c, d, a, x[k + 0], S24, 3921069994); a = GG(a, b, c, d, x[k + 5], S21, 3593408605); d = GG(d, a, b, c, x[k + 10], S22, 38016083); c = GG(c, d, a, b, x[k + 15], S23, 3634488961); b = GG(b, c, d, a, x[k + 4], S24, 3889429448); a = GG(a, b, c, d, x[k + 9], S21, 568446438); d = GG(d, a, b, c, x[k + 14], S22, 3275163606); c = GG(c, d, a, b, x[k + 3], S23, 4107603335); b = GG(b, c, d, a, x[k + 8], S24, 1163531501); a = GG(a, b, c, d, x[k + 13], S21, 2850285829); d = GG(d, a, b, c, x[k + 2], S22, 4243563512); c = GG(c, d, a, b, x[k + 7], S23, 1735328473); b = GG(b, c, d, a, x[k + 12], S24, 2368359562); a = HH(a, b, c, d, x[k + 5], S31, 4294588738); d = HH(d, a, b, c, x[k + 8], S32, 2272392833); c = HH(c, d, a, b, x[k + 11], S33, 1839030562); b = HH(b, c, d, a, x[k + 14], S34, 4259657740); a = HH(a, b, c, d, x[k + 1], S31, 2763975236); d = HH(d, a, b, c, x[k + 4], S32, 1272893353); c = HH(c, d, a, b, x[k + 7], S33, 4139469664); b = HH(b, c, d, a, x[k + 10], S34, 3200236656); a = HH(a, b, c, d, x[k + 13], S31, 681279174); d = HH(d, a, b, c, x[k + 0], S32, 3936430074); c = HH(c, d, a, b, x[k + 3], S33, 3572445317); b = HH(b, c, d, a, x[k + 6], S34, 76029189); a = HH(a, b, c, d, x[k + 9], S31, 3654602809); d = HH(d, a, b, c, x[k + 12], S32, 3873151461); c = HH(c, d, a, b, x[k + 15], S33, 530742520); b = HH(b, c, d, a, x[k + 2], S34, 3299628645); a = II(a, b, c, d, x[k + 0], S41, 4096336452); d = II(d, a, b, c, x[k + 7], S42, 1126891415); c = II(c, d, a, b, x[k + 14], S43, 2878612391); b = II(b, c, d, a, x[k + 5], S44, 4237533241); a = II(a, b, c, d, x[k + 12], S41, 1700485571); d = II(d, a, b, c, x[k + 3], S42, 2399980690); c = II(c, d, a, b, x[k + 10], S43, 4293915773); b = II(b, c, d, a, x[k + 1], S44, 2240044497); a = II(a, b, c, d, x[k + 8], S41, 1873313359); d = II(d, a, b, c, x[k + 15], S42, 4264355552); c = II(c, d, a, b, x[k + 6], S43, 2734768916); b = II(b, c, d, a, x[k + 13], S44, 1309151649); a = II(a, b, c, d, x[k + 4], S41, 4149444226); d = II(d, a, b, c, x[k + 11], S42, 3174756917); c = II(c, d, a, b, x[k + 2], S43, 718787259); b = II(b, c, d, a, x[k + 9], S44, 3951481745); a = addUnsigned(a, AA); b = addUnsigned(b, BB); c = addUnsigned(c, CC); d = addUnsigned(d, DD) } var tempValue = wordToHex(a) + wordToHex(b) + wordToHex(c) + wordToHex(d); return tempValue.toLowerCase() }; var rotateLeft = function (lValue, iShiftBits) { return (lValue << iShiftBits) | (lValue >>> (32 - iShiftBits)) }; var addUnsigned = function (lX, lY) { var lX4, lY4, lX8, lY8, lResult; lX8 = (lX & 2147483648); lY8 = (lY & 2147483648); lX4 = (lX & 1073741824); lY4 = (lY & 1073741824); lResult = (lX & 1073741823) + (lY & 1073741823); if (lX4 & lY4) { return (lResult ^ 2147483648 ^ lX8 ^ lY8) } if (lX4 | lY4) { if (lResult & 1073741824) { return (lResult ^ 3221225472 ^ lX8 ^ lY8) } else { return (lResult ^ 1073741824 ^ lX8 ^ lY8) } } else { return (lResult ^ lX8 ^ lY8) } }; var F = function (x, y, z) { return (x & y) | ((~x) & z) }; var G = function (x, y, z) { return (x & z) | (y & (~z)) }; var H = function (x, y, z) { return (x ^ y ^ z) }; var I = function (x, y, z) { return (y ^ (x | (~z))) }; var FF = function (a, b, c, d, x, s, ac) { a = addUnsigned(a, addUnsigned(addUnsigned(F(b, c, d), x), ac)); return addUnsigned(rotateLeft(a, s), b) }; var GG = function (a, b, c, d, x, s, ac) { a = addUnsigned(a, addUnsigned(addUnsigned(G(b, c, d), x), ac)); return addUnsigned(rotateLeft(a, s), b) }; var HH = function (a, b, c, d, x, s, ac) { a = addUnsigned(a, addUnsigned(addUnsigned(H(b, c, d), x), ac)); return addUnsigned(rotateLeft(a, s), b) }; var II = function (a, b, c, d, x, s, ac) { a = addUnLine truncated
var WordToHexValue = "", WordToHexValueTemp = "", lByte, lCount; for (lCount = 0; lCount <= 3; lCount++) {
lByte = (lValue >>> (lCount * 8)) & 255; WordToHexValueTemp = "0" + lByte.toString(16);
WordToHexValue = WordToHexValue + WordToHexValueTemp.substr(WordToHexValueTemp.length - 2, 2)
} return WordToHexValue
}; var uTF8Encode = function (string) { string = string.toString().replace(/\x0d\x0a/g, "\x0a"); var output = ""; for (var n = 0; n < string.length; n++) { var c = string.charCodeAt(n); if (c < 128) { output += String.fromCharCode(c) } else { if ((c > 127) && (c < 2048)) { output += String.fromCharCode((c >> 6) | 192); output += String.fromCharCode((c & 63) | 128) } else { output += String.fromCharCode((c >> 12) | 224); output += String.fromCharCode(((c >> 6) & 63) | 128); output += String.fromCharCode((c & 63) | 128) } } } return output }; return createMD5String(md5str)
};
-308
View File
@@ -1,308 +0,0 @@
/*
青龙脚本:星妈会自动任务 + 自动获取 cuk(通用 code_url)
作者:ChatGPT 整合最终版
环境变量:
soy_wxid_data → 多个 wxid,换行分隔
soy_codeurl_data → 通用 code 获取地址
流程:
wxid → 请求 code → 请求 autologin → 得到 cuk →
构造 XMH_COOKIE 内容执行星妈会任务
*/
const axios = require("axios");
const notify = require('./sendNotify');
// =======================
// 工具
// =======================
function sleep(ms){ return new Promise(res => setTimeout(res, ms)); }
function parseEnvList(name) {
const raw = process.env[name] || "";
return raw.split("\n").map(x => x.trim()).filter(x => x);
}
function parseEnvStr(name) {
return (process.env[name] || "").trim();
}
// =======================
// 第1步:读取环境变量
// =======================
const wxidList = parseEnvList("soy_wxid_data");
const codeUrl = parseEnvStr("soy_codeurl_data");
if (wxidList.length === 0 || !codeUrl) {
console.log("❌ 环境变量为空,请检查 soy_wxid_data 或 soy_codeurl_data");
process.exit(0);
}
console.log(`🟢 读取到 ${wxidList.length} 个账号`);
console.log(`🟢 通用 code_url: ${codeUrl}`);
// =======================
// 第2步:获取 code
// =======================
async function getCode(wxid) {
try {
const body = { appid: "wxc83b55d61c7fc51d", wxid };
const res = await axios.post(codeUrl, body, { timeout: 10000 });
if (res.data?.status && res.data?.Data?.code) {
console.log(`⭐ 获取 code 成功: ${wxid}`);
return res.data.Data.code;
}
} catch (e) {
console.log(`❌ 获取 code 失败:${wxid} →`, e.message);
}
return null;
}
// =======================
// 第3步:code → cuk
// =======================
async function getCuk(code){
const api = `https://momclub.feihe.com/pmall/c/login/autologin?code=${code}`;
try {
const res = await axios.get(api, {
headers: {
"cuk": "undefined",
"User-Agent": "Mozilla/5.0",
"Content-Type": "application/json"
},
timeout: 10000
});
if (res.data?.code === "000000") {
const cuk = res.data.data.cuk;
console.log(`🎉 cuk 获取成功`);
return cuk;
}
} catch (e) {
console.log(`❌ cuk 获取失败:`, e.message);
}
return null;
}
// =======================
// 构造最终 XMH_COOKIE 列表
// =======================
async function buildCookieList() {
const result = [];
for (let i=0;i<wxidList.length;i++){
const wxid = wxidList[i];
console.log(`\n========== 账号 ${i+1} ==========`);
const code = await getCode(wxid);
if (!code) continue;
await sleep(1500);
const cuk = await getCuk(code);
if (!cuk) continue;
result.push(`${cuk}#${wxid}`);
await sleep(2000);
}
return result;
}
// =======================
// 星妈会任务类
// =======================
const API_HOST = "https://momclub.feihe.com";
function init() {
return {
isNode: () => true,
http: axios,
wait: (ms) => new Promise(resolve => setTimeout(resolve, ms)),
log: console.log
};
}
const $ = init();
class XingMaHui {
constructor(cuk, index, remark='') {
this.cuk = cuk;
this.index = index;
this.remark = remark;
this.accountName = remark ? `账号${index}(${remark})` : `账号${index}`;
this.creditsEarned = 0;
this.taskResults = [];
this.userInfo = null;
this.initialPoints = 0;
this.finalPoints = 0;
}
getHeaders(){
return {
'Host': 'momclub.feihe.com',
'cuk': this.cuk,
'User-Agent': 'Mozilla/5.0',
'Content-Type': 'application/json'
};
}
async request(url, method="GET", data=null){
try {
const config = { headers: this.getHeaders(), timeout: 10000 };
let res = null;
if (method === "GET") {
res = await $.http.get(url, config);
} else {
res = await $.http.post(url, data, config);
}
return res.data;
} catch (e) {
console.log("❌ 请求异常:", e.message);
return null;
}
}
async getUserInfo(){
const url = `${API_HOST}/pmall/c/user/memberInfo`;
const r = await this.request(url);
if (r?.code === "000000") {
this.userInfo = r.data;
return r.data;
}
return null;
}
async getTaskList(){
const url = `${API_HOST}/pmall/c/activity/todo/list?mockTime=${Date.now()}`;
const r = await this.request(url);
if (r?.code === "000000") return r.data;
return null;
}
async queryTaskCredits(name){
const url = `${API_HOST}/pmall/c/activity/todo/queryTodoResult`;
const r = await this.request(url);
if (r?.code === "000000") {
const t = r.data.find(x => x.taskName === name);
return t?.actualCredits || 0;
}
return 0;
}
async doCheckIn(id, name){
const url = `${API_HOST}/pmall/c/activity/todo/checkIn`;
const data = { activityId:id, mockTime: Date.now() };
console.log(`➡ 签到:${name}`);
const r = await this.request(url, "POST", data);
if (r?.code === "000000") {
const c = r.data.credits || 1;
this.creditsEarned += c;
this.taskResults.push(`签到 ${name} +${c}`);
}
}
async doNormalTask(id, name){
console.log(`➡ 普通任务:${name}`);
const r1 = await this.request(`${API_HOST}/pmall/c/activity/todo/receive`, "POST",
{activityId:id, mockTime:Date.now()}
);
if (r1?.code !== "000000") return;
await $.wait(1000);
const r2 = await this.request(`${API_HOST}/pmall/c/activity/todo/complete`, "POST",
{activityId:id, mockTime:Date.now()}
);
if (r2?.code !== "000000") return;
await $.wait(1000);
const credits = await this.queryTaskCredits(name);
this.creditsEarned += credits;
this.taskResults.push(`${name} +${credits}`);
}
async doAllTasks(){
console.log(`\n⭐ 开始执行 ${this.accountName}`);
await this.getUserInfo();
if (this.userInfo) this.initialPoints = this.userInfo.points;
const list = await this.getTaskList();
if (!list) return;
if (list.checkInTodo) await this.doCheckIn(list.checkInTodo.id, list.checkInTodo.name);
if (list.taskTodo) {
for (const t of list.taskTodo) {
const type = t.taskTodoExtra?.type;
if (type === "AddQw" || type === "FirstOrder") continue;
await this.doNormalTask(t.id, t.name);
}
}
await this.getUserInfo();
if (this.userInfo) this.finalPoints = this.userInfo.points;
}
getResults(){
return {
account: this.accountName,
initial: this.initialPoints,
final: this.finalPoints,
gained: this.creditsEarned,
tasks: this.taskResults,
user: this.userInfo
};
}
}
// =======================
// 主执行
// =======================
(async () => {
console.log("\n🚀 开始获取 cuk ...\n");
const cookieList = await buildCookieList();
if (cookieList.length === 0) {
console.log("❌ 无法获取任何 cuk,退出");
return;
}
console.log(`\n⭐ 总共获取 ${cookieList.length} 个 cuk\n`);
const allAccounts = [];
let totalCredits = 0;
for (let i=0;i<cookieList.length;i++){
const [cuk, remark] = cookieList[i].split("#");
const acc = new XingMaHui(cuk, i+1, remark);
allAccounts.push(acc);
}
console.log("🚀 开始执行星妈会任务...\n");
for (const acc of allAccounts){
await acc.doAllTasks();
totalCredits += acc.creditsEarned;
await sleep(3000);
}
// 汇总结果
let msg = "🎉 星妈会任务完成\n\n";
for (const acc of allAccounts){
const r = acc.getResults();
msg += `📍 ${r.account}
手机号:${r.user?.mobile || "未知"}
初始积分:${r.initial}
最终积分:${r.final}
本次获得:${r.gained}
任务:
${r.tasks.map(t=>" - "+t).join("\n")}
-------------------\n`;
}
msg += `\n⭐ 今日总积分:${totalCredits}`;
console.log(msg);
await notify.sendNotify("星妈会任务完成", msg);
})();