Files
qinglong/脚本库/web版/账密/'未知用户',/2026-05-19_juejin_checkin_6f8a138b.js
2026-05-23 18:48:48 +00:00

564 lines
16 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// # Source: https://github.com/huwangkeji/juejin_checkin/blob/main/juejin_checkin.js
// # Raw: https://raw.githubusercontent.com/huwangkeji/juejin_checkin/main/juejin_checkin.js
// # Repo: huwangkeji/juejin_checkin
// # Path: juejin_checkin.js
// # UploadedAt: 2026-05-19T14:34:11Z
// # SHA256: 6f8a138b51c397220444c9312040dbe3407af5aeed4fa4467a36672aeb8bcfd1
// # Category: web版/账密
// # Evidence: web/H5关键词 + username/password/login
//
/*
* @name 掘金自动签到脚本
* @description 掘金社区每日签到 + 免费抽奖 + 沾喜气 + Bug消除支持Cookie自动签到
* @namespace https://juejin.cn
* @version 1.0.0
* @author CodeBuddy
*
* 【青龙面板使用说明】
* 1. 依赖管理 -> NodeJS -> 添加依赖: axios
* 2. 环境变量 (必填):
* - JUEJIN_COOKIE: 掘金Cookie (从浏览器开发者工具复制)
* - JUEJIN_AID: API参数aid (通常为2608)
* - JUEJIN_UUID: API参数uuid
* - JUEJIN_MSTOKEN: API参数msToken
* - JUEJIN_A_BOGUS: API参数a_bogus
* 3. 环境变量 (可选):
* - JUEJIN_COOKIE_2 ~ JUEJIN_COOKIE_5: 多账号Cookie
* - JUEJIN_NOTIFY: 是否推送通知 (默认true)
* 4. 定时规则: 30 6 * * * (每天早上6:30执行)
*
* 【参数获取方式】
* 1. 浏览器打开 https://juejin.cn 并登录
* 2. 按F12打开开发者工具 -> Network(网络)标签
* 3. 刷新页面,找到任意一个 api.juejin.cn 的请求
* 4. 在 Request Headers 中复制完整的 Cookie 值
* 5. 在 Query String Parameters 中复制 aid, uuid, msToken, a_bogus
* 6. 粘贴到青龙面板对应的环境变量中
* 7. Cookie和参数有效期约30天过期后需重新获取
*
* 【功能列表】
* - Cookie自动签到支持多账号
* - 每日签到
* - 免费抽奖
* - 沾喜气
* - Bug消除
* - 查询矿石余额/签到天数/幸运值
* - 青龙面板通知推送
*/
const axios = require('axios');
// ==================== 配置区域 ====================
const API_BASE = 'https://api.juejin.cn';
// 请求头
const DEFAULT_HEADERS = {
'User-Agent':
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/127.0.0.0 Safari/537.36',
'Referer': 'https://juejin.cn/',
'Origin': 'https://juejin.cn',
'Content-Type': 'application/json',
'sec-ch-ua': '"Not/A)Brand";v="99", "Chromium";v="148"',
'sec-ch-ua-mobile': '?0',
'sec-ch-ua-platform': '"Windows"',
};
// ==================== 工具函数 ====================
function log(msg) {
const now = new Date().toLocaleString('zh-CN', { timeZone: 'Asia/Shanghai' });
console.log(`[${now}] ${msg}`);
}
function sleep(ms) {
return new Promise((resolve) => setTimeout(resolve, ms));
}
/**
* 创建带Cookie和参数的axios实例
*/
function createApiClient(cookie, params) {
const instance = axios.create({
baseURL: API_BASE,
headers: {
...DEFAULT_HEADERS,
Cookie: cookie,
},
timeout: 30000,
});
// 请求拦截 - 自动添加查询参数
instance.interceptors.request.use((config) => {
if (params && Object.keys(params).length > 0) {
config.params = { ...config.params, ...params };
}
// POST请求body为空对象
if (config.method === 'post' && !config.data) {
config.data = {};
}
return config;
});
// 响应拦截
instance.interceptors.response.use(
(response) => {
const data = response.data;
// 处理空响应
if (data === '' || data === null || data === undefined) {
throw new Error('API返回空响应可能需要更新参数');
}
if (typeof data === 'object' && data.err_no !== 0) {
throw new Error(`API错误: [${data.err_no}] ${data.err_msg || '未知错误'}`);
}
return data.data;
},
(error) => {
if (error.response) {
const data = error.response.data;
if (data && typeof data === 'object' && data.err_no !== undefined) {
throw new Error(`API错误: [${data.err_no}] ${data.err_msg || '未知错误'}`);
}
throw new Error(`HTTP错误: ${error.response.status} ${error.response.statusText}`);
}
throw error;
}
);
return instance;
}
// ==================== API 调用 ====================
/**
* 检查今日签到状态
*/
async function getTodayStatus(api) {
try {
const data = await api.get('/growth_api/v1/get_today_status');
return data === true;
} catch (e) {
log('⚠️ 查询签到状态失败: ' + e.message);
return null;
}
}
/**
* 执行签到
*/
async function checkIn(api) {
try {
const data = await api.post('/growth_api/v1/check_in');
log('✅ 签到成功!');
return { success: true, data };
} catch (e) {
if (e.message.includes('15001') || e.message.includes('已签到') || e.message.includes('duplicate')) {
log('📌 今日已签到,无需重复签到');
return { success: true, already: true };
}
if (e.message.includes('3013')) {
log('📌 今日已签到 (3013)');
return { success: true, already: true };
}
if (e.message.includes('空响应')) {
log('⚠️ API返回空响应参数可能已过期建议重新获取');
return { success: false, error: e.message };
}
log('❌ 签到失败: ' + e.message);
return { success: false, error: e.message };
}
}
/**
* 获取签到天数统计
*/
async function getCounts(api) {
try {
const data = await api.get('/growth_api/v1/get_counts');
return data;
} catch (e) {
log('⚠️ 获取签到统计失败: ' + e.message);
return null;
}
}
/**
* 获取当前矿石数
*/
async function getCurrentPoint(api) {
try {
const data = await api.get('/growth_api/v1/get_cur_point');
return data;
} catch (e) {
log('⚠️ 获取矿石余额失败: ' + e.message);
return null;
}
}
/**
* 获取抽奖配置
*/
async function getLotteryConfig(api) {
try {
const data = await api.get('/growth_api/v1/lottery_config/get');
return data;
} catch (e) {
log('⚠️ 获取抽奖配置失败: ' + e.message);
return null;
}
}
/**
* 免费抽奖
*/
async function drawLottery(api) {
try {
const data = await api.post('/growth_api/v1/lottery/draw');
log('🎉 抽奖成功!奖品: ' + (data.lottery_name || '未知'));
return { success: true, data };
} catch (e) {
log('❌ 抽奖失败: ' + e.message);
return { success: false, error: e.message };
}
}
/**
* 沾喜气
*/
async function dipLucky(api) {
try {
// 先获取幸运用户列表
const luckyUsers = await api.post('/growth_api/v1/lottery_history/global_big', {
page_no: 1,
page_size: 5,
});
if (luckyUsers && luckyUsers.lotteries && luckyUsers.lotteries.length > 0) {
const historyId = luckyUsers.lotteries[0].history_id;
const data = await api.post('/growth_api/v1/lottery_lucky/dip_lucky', {
lottery_history_id: historyId,
});
log('🍀 沾喜气成功!幸运值: ' + (data.dip_value || 0));
return { success: true, data };
}
log('⚠️ 暂无可沾喜气的用户');
return { success: false };
} catch (e) {
log('❌ 沾喜气失败: ' + e.message);
return { success: false, error: e.message };
}
}
/**
* 获取我的幸运值
*/
async function getMyLucky(api) {
try {
const data = await api.post('/growth_api/v1/lottery_lucky/my_lucky');
return data;
} catch (e) {
log('⚠️ 获取幸运值失败: ' + e.message);
return null;
}
}
/**
* 查询用户信息 (验证Cookie有效性)
*/
async function getUserInfo(api) {
try {
const data = await api.get('/user_api/v1/user/get');
return data;
} catch (e) {
log('⚠️ Cookie无效或已过期: ' + e.message);
return null;
}
}
/**
* 获取Bug消除配置
*/
async function getBugFixConfig(api) {
try {
const data = await api.get('/growth_api/v1/bugfix/not_collect');
return data;
} catch (e) {
log('⚠️ 获取Bug配置失败: ' + e.message);
return null;
}
}
/**
* 消除Bug
*/
async function fixBug(api, bugId) {
try {
const data = await api.post('/growth_api/v1/bugfix/collect', {
bug_type: bugId,
});
log('🐛 Bug消除成功');
return { success: true, data };
} catch (e) {
log('❌ Bug消除失败: ' + e.message);
return { success: false, error: e.message };
}
}
// ==================== 青龙面板通知 ====================
/**
* 青龙面板通知推送
*/
async function sendNotify(title, content) {
if (process.env.JUEJIN_NOTIFY === 'false') {
log('📢 通知已禁用');
return;
}
try {
// 尝试加载青龙面板的通知模块
const notifyPath = require('path').join(process.cwd(), 'notify.js');
if (require('fs').existsSync(notifyPath)) {
const sendNotifyFn = require(notifyPath);
if (typeof sendNotifyFn === 'function') {
await sendNotifyFn(title, content);
log('📢 青龙通知已发送');
return;
}
}
// 尝试从全局加载
try {
const { sendNotify: qinglongNotify } = require('qlnotify');
await qinglongNotify(title, content);
log('📢 青龙通知已发送');
return;
} catch (e) {
// 忽略
}
log('📢 青龙通知模块未找到,仅控制台输出');
} catch (e) {
log('⚠️ 发送通知失败: ' + e.message);
}
}
// ==================== 单个账号签到流程 ====================
async function runAccount(cookie, params, index) {
const prefix = index > 1 ? `[账号${index}] ` : '';
log('');
log(`${prefix}═══════════════════════════════════════`);
log(`${prefix} 开始处理账号 ${index}`);
log(`${prefix}═══════════════════════════════════════`);
if (!cookie || cookie.trim().length === 0) {
log(`${prefix}❌ Cookie为空跳过`);
return null;
}
// 创建API客户端
const api = createApiClient(cookie, params);
// 验证Cookie有效性
log(`${prefix}🔍 验证Cookie...`);
const userInfo = await getUserInfo(api);
if (!userInfo) {
log(`${prefix}❌ Cookie已失效请重新获取`);
return {
success: false,
error: 'Cookie已失效',
userName: '未知用户',
};
}
const userName = userInfo.user_name || userInfo.nick_name || '未知用户';
log(`${prefix}✅ Cookie有效用户: ${userName}`);
// 签到
log(`${prefix}📅 执行签到...`);
const todayStatus = await getTodayStatus(api);
let signInResult = { success: true, already: todayStatus === true };
if (todayStatus === true) {
log(`${prefix}📌 今日已签到,跳过`);
} else if (todayStatus === false) {
signInResult = await checkIn(api);
if (!signInResult.success) {
log(`${prefix}🔄 签到失败1秒后重试...`);
await sleep(1000);
signInResult = await checkIn(api);
}
} else {
log(`${prefix}⚠️ 无法查询签到状态,直接尝试签到...`);
signInResult = await checkIn(api);
}
// 抽奖
log(`${prefix}🎰 执行抽奖...`);
const lotteryConfig = await getLotteryConfig(api);
let lotteryResult = { success: false };
if (lotteryConfig && lotteryConfig.free_count > 0) {
log(`${prefix}🎁 有 ${lotteryConfig.free_count} 次免费抽奖机会`);
lotteryResult = await drawLottery(api);
} else if (lotteryConfig) {
log(`${prefix}📌 今日免费抽奖次数已用完`);
}
// 沾喜气
log(`${prefix}🍀 沾喜气...`);
const dipResult = await dipLucky(api);
// Bug消除
log(`${prefix}🐛 消除Bug...`);
const bugConfig = await getBugFixConfig(api);
let bugFixResult = { success: false };
if (bugConfig && Array.isArray(bugConfig) && bugConfig.length > 0) {
const bug = bugConfig[0];
log(`${prefix}🔧 发现未消除的Bug: ${bug.bug_type}`);
bugFixResult = await fixBug(api, bug.bug_type);
} else {
log(`${prefix}📌 暂无Bug可消除`);
}
// 查询统计信息
log(`${prefix}📊 查询统计...`);
const counts = await getCounts(api);
const point = await getCurrentPoint(api);
const lucky = await getMyLucky(api);
if (counts) {
log(`${prefix}📅 连续签到: ${counts.cont_count || 0}`);
log(`${prefix}📅 累计签到: ${counts.sum_count || 0}`);
}
if (point !== null) {
log(`${prefix}💰 当前矿石: ${point}`);
}
if (lucky) {
log(`${prefix}🍀 幸运值: ${lucky.total_value || 0}`);
}
log(`${prefix}✅ 账号处理完成`);
return {
success: true,
userName,
signIn: signInResult,
lottery: lotteryResult,
dip: dipResult,
bugFix: bugFixResult,
counts,
point,
lucky,
};
}
// ==================== 主流程 ====================
async function main() {
log('═══════════════════════════════════════');
log(' 掘金自动签到脚本 v1.0.0');
log('═══════════════════════════════════════');
// 收集所有账号的配置
const accounts = [];
// 主账号
const mainCookie = process.env.JUEJIN_COOKIE || '';
const mainParams = {
aid: process.env.JUEJIN_AID || '2608',
uuid: process.env.JUEJIN_UUID || '',
msToken: process.env.JUEJIN_MSTOKEN || '',
a_bogus: process.env.JUEJIN_A_BOGUS || '',
spider: '0',
};
if (mainCookie) {
accounts.push({ cookie: mainCookie, params: mainParams });
}
// 多账号支持
for (let i = 2; i <= 5; i++) {
const cookie = process.env[`JUEJIN_COOKIE_${i}`] || '';
if (cookie) {
accounts.push({
cookie,
params: {
aid: process.env[`JUEJIN_AID_${i}`] || mainParams.aid,
uuid: process.env[`JUEJIN_UUID_${i}`] || '',
msToken: process.env[`JUEJIN_MSTOKEN_${i}`] || '',
a_bogus: process.env[`JUEJIN_A_BOGUS_${i}`] || '',
spider: '0',
},
});
}
}
if (accounts.length === 0) {
log('');
log('❌ 未配置Cookie请设置环境变量 JUEJIN_COOKIE');
log('');
log('【参数获取方式】');
log('1. 浏览器打开 https://juejin.cn 并登录');
log('2. 按F12打开开发者工具 -> Network(网络)标签');
log('3. 刷新页面,找到任意一个 api.juejin.cn 的请求');
log('4. 在 Request Headers 中复制完整的 Cookie 值');
log('5. 在 Query String Parameters 中复制 aid, uuid, msToken, a_bogus');
log('6. 粘贴到青龙面板对应的环境变量中');
log('');
process.exit(1);
}
log(`📱 共配置 ${accounts.length} 个账号`);
// 执行每个账号的签到
const results = [];
for (let i = 0; i < accounts.length; i++) {
const result = await runAccount(accounts[i].cookie, accounts[i].params, i + 1);
if (result) results.push(result);
}
// 生成通知内容
log('');
log('📢 发送通知...');
let notifyTitle = '掘金每日签到报告';
let notifyContent = '';
for (let i = 0; i < results.length; i++) {
const r = results[i];
const prefix = results.length > 1 ? `【账号${i + 1}` : '';
if (!r.success) {
notifyContent += `${prefix}${r.userName}: ${r.error}\n`;
continue;
}
notifyContent += `${prefix}👤 ${r.userName}\n`;
notifyContent += ` 📅 连续签到: ${r.counts?.cont_count || 0}\n`;
notifyContent += ` 📅 累计签到: ${r.counts?.sum_count || 0}\n`;
notifyContent += ` 💰 当前矿石: ${r.point ?? '未知'}\n`;
notifyContent += ` 🍀 幸运值: ${r.lucky?.total_value || 0}\n`;
notifyContent += ` ✅ 签到: ${r.signIn.already ? '今日已签到' : r.signIn.success ? '成功' : '失败'}\n`;
notifyContent += ` 🎰 抽奖: ${r.lottery.success ? '成功 - ' + (r.lottery.data?.lottery_name || '') : '未抽奖/失败'}\n`;
notifyContent += ` 🍀 沾喜气: ${r.dip.success ? '成功' : '失败'}\n`;
notifyContent += ` 🐛 Bug消除: ${r.bugFix.success ? '成功' : '无/失败'}\n`;
notifyContent += '\n';
}
await sendNotify(notifyTitle, notifyContent);
log('');
log('═══════════════════════════════════════');
log(' 脚本执行完成!');
log('═══════════════════════════════════════');
}
// 执行主函数
main().catch((error) => {
log('💥 脚本异常退出: ' + error.message);
console.error(error);
process.exit(1);
});