57

bt.sb 自动签到脚本

基于 Cloudflare Workersbbs.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,进入:

text
Workers & Pages

然后:

  1. 点击 Create
  2. 选择 Create Worker
  3. 输入一个名称,例如:
text
btsb-checkin
  1. 创建完成后进入编辑器
  2. 删除默认代码
  3. 把 [btsb签到.txt] 的内容完整粘贴进去
  4. 点击 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 域名是:

text
https://btsb-checkin.xxx.workers.dev

手动签到

访问:

text
https://btsb-checkin.xxx.workers.dev/auto

Telegram 测试推送

访问:

text
https://btsb-checkin.xxx.workers.dev/tg

返回结果示例

签到成功

text
签到成功!获得 5 女仆币 | 连续 3 天 | 最长 10 天

今日已签到

text
今日已签到(日期:2026-05-21)

执行失败

text
签到失败: 请配置 BASE_URL、USERNAME、PASSWORD

定时任务配置

进入 Worker 的:

text
Settings -> Triggers -> Cron Triggers

添加一个 Cron 表达式,例如:

cron
0 1 * * *

这表示每天执行一次。

时间说明

Cloudflare Cron 使用的是 UTC 时间

  • 0 1 * * * = 每天 UTC 01:00
  • 对应北京时间 09:00
  • 对应新加坡时间 09:00

如果你希望每天早上自动签到,这个时间比较合适。


Telegram 推送配置

如果你想收到签到结果通知,可以配置 Telegram。

获取 Bot Token

  1. 打开 Telegram
  2. 搜索 @BotFather
  3. 创建一个机器人
  4. 获取 Bot Token

格式类似:

text
123456789:AAxxxxxxxxxxxxxxxxxxxxxxxxxxxx

获取 Chat ID

  1. 先给机器人发送一条消息
  2. 再通过 Telegram API 或相关机器人工具获取 Chat ID

格式类似:

text
123456789

配置完成后,脚本在签到成功或失败时都会自动推送消息。


常见问题

登录失败

可能原因:

  • 账号或密码错误
  • 论坛登录接口发生变化
  • 账号触发了风控

签到失败

可能原因:

  • 登录成功但签到接口返回异常
  • 论坛修改了接口结构
  • 当前账号无签到权限

Telegram 没收到消息

请检查:

  • TG_TOKEN 是否正确
  • TG_ID 是否正确
  • 机器人是否已经收到过你的消息

使用建议

  • 先手动访问一次 /auto 确认能正常签到
  • 测试通过后再添加 Cron 定时任务
  • 不要公开分享自己的账号密码、Worker 地址或 Telegram Token
  • 如果论坛接口更新,脚本可能需要同步调整

快速开始

text
1. 创建 Worker 2. 粘贴脚本 3. 配置环境变量 4. 访问 /auto 测试 5. 添加 Cron 定时任务

免责声明

本脚本仅供学习与个人自动化使用,请自行承担使用风险,并遵守目标站点的相关规则。

这个用户还没有留下简介。

回复讨论
2

登录后可参与回复讨论。

文明发言,理性讨论
laosiji OP·5小时前
偏店浪人·5小时前