35
bt.sb 自动签到脚本
基于 Cloudflare Workers 的 bbs.bt.sb 自动登录签到脚本,支持手动触发、定时任务和 Telegram 推送。
功能特性
- 自动登录
bbs.bt.sb - 自动调用签到接口
POST /api/check-in - 支持手动访问链接触发签到
- 支持 Cloudflare Cron 定时执行
- 支持 Telegram 推送签到结果
文件说明
- [btsb签到.txt]:Workers 脚本源码
ts/* Cloudflare Workers 版 bt.sb 自动登录签到 环境变量: BASE_URL=https://bbs.bt.sb USERNAME=你的账号或邮箱 PASSWORD=你的密码 TOKEN=手动触发路径,默认 auto TG_TOKEN=Telegram Bot Token,可留空 TG_ID=Telegram Chat ID,可留空 */ const DEFAULT_CONFIG = { BASE_URL: "https://bbs.bt.sb", USERNAME: "your_email_or_username", PASSWORD: "your_password", TOKEN: "auto", TG_TOKEN: "", TG_ID: "", }; export default { async fetch(request, env) { const config = getConfig(env); const { pathname } = new URL(request.url); if (pathname === "/tg") { const result = await sendTelegram(config, "测试推送"); return textResponse(result || "未配置 Telegram"); } if (pathname === `/${config.token}` || pathname === "/") { return runCheckIn(config); } return textResponse("Worker is running"); }, async scheduled(_controller, env) { await runCheckIn(getConfig(env)); }, }; function getConfig(env = {}) { const baseUrl = String(env.BASE_URL || DEFAULT_CONFIG.BASE_URL).replace(/\/+$/, ""); return { baseUrl, username: env.USERNAME || DEFAULT_CONFIG.USERNAME, password: env.PASSWORD || DEFAULT_CONFIG.PASSWORD, token: env.TOKEN || DEFAULT_CONFIG.TOKEN, tgToken: env.TG_TOKEN || DEFAULT_CONFIG.TG_TOKEN, tgId: env.TG_ID || DEFAULT_CONFIG.TG_ID, }; } async function runCheckIn(config) { try { validateConfig(config); const auth = await login(config); const message = await checkIn(config, auth); await sendTelegram(config, message); return textResponse(message); } catch (error) { const message = `签到失败: ${error.message}`; await sendTelegram(config, message); return textResponse(message, 500); } } function validateConfig(config) { if (!config.baseUrl || !config.username || !config.password) { throw new Error("请配置 BASE_URL、USERNAME、PASSWORD"); } } async function login(config) { const response = await fetch(`${config.baseUrl}/api/auth/login`, { method: "POST", headers: jsonHeaders({ Origin: config.baseUrl, Referer: `${config.baseUrl}/login`, }), body: JSON.stringify({ login: config.username, password: config.password, captchaToken: "", builtinCaptchaCode: "", powNonce: "", addonFields: {}, }), }); const text = await response.text(); const data = parseJson(text); if (!response.ok) { throw new Error(`登录请求失败: ${response.status} ${shortText(text)}`); } if (data?.success === false || data?.ok === false || isErrorCode(data?.code) || data?.status >= 400) { throw new Error(`登录失败: ${extractMessage(data, text)}`); } const cookie = (response.headers.get("set-cookie") || "") .split(/,(?=[^;]+?=)/g) .map((item) => item.split(";")[0].trim()) .filter(Boolean) .join("; "); const token = data?.token || data?.accessToken || data?.access_token || data?.data?.token || data?.data?.accessToken || data?.data?.access_token || ""; if (!cookie && !token) { throw new Error(`登录成功但未获取到认证信息: ${shortText(text)}`); } return { cookie, token }; } async function checkIn(config, auth) { const headers = jsonHeaders({ Origin: config.baseUrl, Referer: config.baseUrl, }); if (auth.cookie) headers.Cookie = auth.cookie; if (auth.token) headers.Authorization = `Bearer ${auth.token}`; const response = await fetch(`${config.baseUrl}/api/check-in`, { method: "POST", headers, body: JSON.stringify({ action: "check-in" }), }); const text = await response.text(); const data = parseJson(text); const payload = data?.data ?? data ?? {}; if (!response.ok) { if (response.status === 401 || response.status === 403) { throw new Error(`登录态失效或无权限 (${response.status})`); } throw new Error(`签到请求失败: ${response.status} ${shortText(text)}`); } if (payload.alreadyCheckedIn) { return `今日已签到(日期:${payload.date || "未知"})`; } if ( typeof payload.points !== "undefined" || typeof payload.currentStreak !== "undefined" || typeof payload.maxStreak !== "undefined" ) { return `签到成功!获得 ${payload.points ?? 0} 女仆币 | 连续 ${payload.currentStreak ?? 0} 天 | 最长 ${payload.maxStreak ?? 0} 天`; } const message = extractMessage(data, text); if (message) { return message; } throw new Error(`无法识别签到响应: ${shortText(text)}`); } async function sendTelegram(config, message) { if (!config.tgToken || !config.tgId) { return ""; } const time = new Date(Date.now() + 8 * 60 * 60 * 1000) .toISOString() .slice(0, 19) .replace("T", " "); await fetch(`https://api.telegram.org/bot${config.tgToken}/sendMessage`, { method: "POST", headers: jsonHeaders(), body: JSON.stringify({ chat_id: config.tgId, text: `执行时间: ${time}\n${message}`, }), }); return "Telegram 推送成功"; } function extractMessage(data, fallback = "") { return ( data?.message || data?.msg || data?.error || data?.detail || data?.data?.message || data?.data?.msg || data?.data?.error || data?.data?.detail || shortText(fallback) ); } function jsonHeaders(extra = {}) { return /** @type {Record<string, string>} */ ({ "Content-Type": "application/json", Accept: "application/json, text/plain, */*", "User-Agent": "Mozilla/5.0", ...extra, }); } function parseJson(text) { try { return JSON.parse(text); } catch { return null; } } function isErrorCode(code) { return typeof code === "number" && code !== 0 && code !== 200; } function shortText(text, max = 200) { const clean = String(text || "").replace(/\s+/g, " ").trim(); return clean.length > max ? `${clean.slice(0, max)}...` : clean; } function textResponse(text, status = 200) { return new Response(text, { status, headers: { "Content-Type": "text/plain; charset=UTF-8" }, }); }
部署方式
1. 创建 Cloudflare Worker
登录 Cloudflare,进入:
textWorkers & Pages
然后:
- 点击
Create - 选择
Create Worker - 输入一个名称,例如:
textbtsb-checkin
- 创建完成后进入编辑器
- 删除默认代码
- 把 [btsb签到.txt] 的内容完整粘贴进去
- 点击
Save and Deploy
环境变量配置
在 Worker 的 Settings -> Variables 中添加以下变量:
| 变量名 | 示例值 | 说明 |
|---|---|---|
BASE_URL |
https://bbs.bt.sb |
论坛地址 |
USERNAME |
[email protected] |
登录账号或邮箱 |
PASSWORD |
your_password |
登录密码 |
TOKEN |
auto |
手动触发路径 |
TG_TOKEN |
123456:ABC... |
Telegram Bot Token,可留空 |
TG_ID |
123456789 |
Telegram Chat ID,可留空 |
建议优先使用环境变量,不要把账号密码直接写死在代码中。
手动测试
假设你的 Worker 域名是:
texthttps://btsb-checkin.xxx.workers.dev
手动签到
访问:
texthttps://btsb-checkin.xxx.workers.dev/auto
Telegram 测试推送
访问:
texthttps://btsb-checkin.xxx.workers.dev/tg
返回结果示例
签到成功
text签到成功!获得 5 女仆币 | 连续 3 天 | 最长 10 天
今日已签到
text今日已签到(日期:2026-05-21)
执行失败
text签到失败: 请配置 BASE_URL、USERNAME、PASSWORD
定时任务配置
进入 Worker 的:
textSettings -> Triggers -> Cron Triggers
添加一个 Cron 表达式,例如:
cron0 1 * * *
这表示每天执行一次。
时间说明
Cloudflare Cron 使用的是 UTC 时间。
0 1 * * *= 每天 UTC 01:00- 对应北京时间
09:00 - 对应新加坡时间
09:00
如果你希望每天早上自动签到,这个时间比较合适。
Telegram 推送配置
如果你想收到签到结果通知,可以配置 Telegram。
获取 Bot Token
- 打开 Telegram
- 搜索
@BotFather - 创建一个机器人
- 获取 Bot Token
格式类似:
text123456789:AAxxxxxxxxxxxxxxxxxxxxxxxxxxxx
获取 Chat ID
- 先给机器人发送一条消息
- 再通过 Telegram API 或相关机器人工具获取
Chat ID
格式类似:
text123456789
配置完成后,脚本在签到成功或失败时都会自动推送消息。
常见问题
登录失败
可能原因:
- 账号或密码错误
- 论坛登录接口发生变化
- 账号触发了风控
签到失败
可能原因:
- 登录成功但签到接口返回异常
- 论坛修改了接口结构
- 当前账号无签到权限
Telegram 没收到消息
请检查:
TG_TOKEN是否正确TG_ID是否正确- 机器人是否已经收到过你的消息
使用建议
- 先手动访问一次
/auto确认能正常签到 - 测试通过后再添加 Cron 定时任务
- 不要公开分享自己的账号密码、Worker 地址或 Telegram Token
- 如果论坛接口更新,脚本可能需要同步调整
快速开始
text1. 创建 Worker 2. 粘贴脚本 3. 配置环境变量 4. 访问 /auto 测试 5. 添加 Cron 定时任务
免责声明
本脚本仅供学习与个人自动化使用,请自行承担使用风险,并遵守目标站点的相关规则。
这个用户还没有留下简介。