23
基于 Cloudflare Workers 的 113.la 自动登录签到脚本,支持手动触发、定时任务和 Telegram 推送。
功能特性
- 自动登录 113.la
- 自动调用签到接口 POST /api/check-in
- 支持手动访问链接触发签到
- 支持 Cloudflare Cron 定时执行
- 支持 Telegram 推送签到结果
文件说明#
- [113签到.txt]:Workers 脚本源码
ts/*
Cloudflare Workers 版 113.la 自动登录签到
环境变量:
BASE_URL=https://113.la
USERNAME=你的账号或邮箱
PASSWORD=你的密码
TOKEN=手动触发路径,默认 auto
TG_TOKEN=Telegram Bot Token,可留空
TG_ID=Telegram Chat ID,可留空
*/
const DEFAULT_CONFIG = {
BASE_URL: "https://113.la",
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
环境变量配置#
在 Worker 的 Settings -> Variables 中添加以下变量:
| 变量名 | 示例值 | 说明 |
|---|---|---|
BASE_URL |
https://113.la |
论坛地址 |
USERNAME |
your@email.com |
登录账号或邮箱 |
PASSWORD |
your_password |
登录密码 |
TOKEN |
auto |
手动触发路径 |
TG_TOKEN |
123456:ABC... |
Telegram Bot Token,可留空 |
TG_ID |
123456789 |
Telegram Chat ID,可留空 |
建议优先使用环境变量,不要把账号密码直接写死在代码中。
手动测试
假设你的 Worker 域名是:
texthttps://113la-checkin.xxx.workers.dev
手动签到
访问:
texthttps://113la-checkin.xxx.workers.dev/auto
Telegram 测试推送
访问:
texthttps://113la-checkin.xxx.workers.dev/tg
返回结果示例
签到成功
text签到成功!获得 5 金币 | 连续 3 天 | 最长 10 天
今日已签到
text今日已签到(日期:2026-05-22)
执行失败
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 - 如果论坛接口更新,脚本可能需要同步调整
快速开始
ts1. 创建 Worker
2. 粘贴脚本
3. 配置环境变量
4. 访问 /auto 测试
5. 添加 Cron 定时任务
免责声明
本脚本仅供学习与个人自动化使用,请自行承担使用风险,并遵守目标站点的相关规则。
不忘初心,方得始终。
回复讨论
0
登录后可参与回复讨论。
当前还没有回复,欢迎成为第一个参与讨论的人。
文明发言,理性讨论