文档索引

签到机器人接入说明

面向站外开发者。读完本文即可实现一个每日签到机器人,无需阅读本站源码。

本文是签到接口的唯一对外口径。字段、错误码、语义均照实抄录, 若与源码不符以源码为准(但也请提 issue —— 那就是本文过期了)。

0. 一句话说清

POST /api/checkin —— 一个请求签一次到,固定领 3 条小鱼干,每人每天一次。

没有第二步:建签到记录与发鱼干在服务端的同一个事务里完成,要么都成、要么都没有。

三个前置条件(都满足才签得动):① 账号是 core+;② 名下至少有一篇未删除的文章;③ 未被禁言。 第二个是 2026-10 加的,见 §1.1。不满足时 POST 一律 403,GET 会用 can_check_in: false 告诉你。

⚠️ 2026-09 起,「两步式(签到 → 翻牌定命)」已废除。 若你手上是旧版本文档 / 旧代码,它描述的是:先 POST /api/checkin 建记录,再 POST /api/checkin/claim 翻一张牌,牌面数字(1–5)决定当天拿多少鱼干。那一步连同 chosenIndex、 fortune_value / fortune_label / fortune_pending / total_fortune / show_fortune 全部下线,POST /api/checkin/claim 现在返回 404。

旧代码通常不会炸得很响:按 fortune_pending 分支的写法会静默跳过第二步 (字段不存在 → undefined → 假),结果正好是对的(一步式下签完就到账)。 但请把调用 claim 的那段删掉 —— 它现在只会拿到 404。

📌 本文自包含。账号准备(注册 / 提权)与鉴权(cookie)是全部机器人共用的前置步骤, 三份完整口径见 docs/bot/chat-bot.md §2 与 §3 —— 本文 §2 只给最小可跑的部分。


1. 能力边界(先读这段)

范围 能读 能写 说明
签到领鱼干 —— ✅ 需 core+,每人每天一次,固定 3 条
查自己今天的签到状态 ✅ ❌ GET /api/checkin
查别人的签到 ❌ ❌ 没有这类接口(排行榜是另一回事,见 §6.2)
补签 / 撤销 / 重签 ❌ ❌ 没有这类接口,签了就是签了

⚠️ 签到是 core+ 专属。 非核心账号(user)不但拿不到鱼干, 连签到接口都进不去(403 需要核心用户权限)—— 本站的鱼干是 core+ 体系的报酬, 全站没有「注册就有鱼干」的渠道。这是刻意的,别指望用脚本刷出来。

⚠️ 机器人享受不到任何豁免:它同样会被禁言、同样受每日一次的限制约束。 禁言期间不开放新的鱼干赚取,签到 POST 返回 403 你已被禁言,暂时无法签到, GET 仍可读取状态,但 can_check_in: false。禁言到期后按通常门槛恢复。

1.1 还得发布过文章(2026-10 起)

名下必须至少有一篇未删除的文章,否则签不了。判断口径:

  • 「文章」指你以作者身份发布过的任意一篇博客,任何可见性档(仅站内 / 链接可读 / 公开)都算;
  • 发过又全部删除 = 没发过 —— 判据只看此刻还活着的文章,不看历史。删掉的不算数。

💡 对机器人的含义:先发文,再签到。发文接口见 docs/bot/chat-bot.md 对应章节 (核心用户即可发布)。新号从注册到能签到,中间要跨过「发表一篇」这一步。

⚠️ 这是刻意的门槛,为的是抬高批量空号的成本。别指望用一堆只签到、从不产出的号 刷鱼干 —— 那种号现在连门都进不去。


2. 准备账号与鉴权

签到接口全部需要 core+ 且登录。注册出来是 user,要提权一次:

  • 注册时带有效邀请码 → 直接是 core(推荐,全自动);
  • 让站长在服务器上执行:npm run cli -- promote-core mybot

完整流程(注册字段、人机验证、错误码)见 docs/bot/chat-bot.md §2。

然后以这个账号发布一篇文章 —— 这是签到的第二个前置条件(§1.1)。发文接口见 docs/bot/chat-bot.md。跳过这一步,签到会一直 403 发布过文章后才能签到。

登录换 cookie:

POST /api/auth/login
Content-Type: application/json

{ "username": "mybot", "password": "********" }

响应会 Set-Cookie: raricy_session=<JWT>(HttpOnly、SameSite=Lax、30 天)。 之后每个请求带上 Cookie: raricy_session=<JWT> 即可。

⚠️ 写请求会校验来源,跨站会被拦成 403 跨源请求被拒绝 (CSRF)。 非浏览器客户端本来就不发 Origin/Referer,天然通过 —— 不要自作主张伪造一个。

会话失效(改密、被强制下线、被禁言 / 重置密码)后一律 401 请先登录 —— 当成「重新登录」的信号,而不是重试。

⚠️ 被降权(core → user)不属于会话失效 —— 会话仍有效,只是签到接口改回 403 需要核心用户权限。重登解决不了这个(那是档位问题,不是登录问题)。


3. 「今天」是本站时区的今天

签到按 UTC+8 的零点切分,不是 UTC 零点,也不是你机器的本地时区。 响应里的 today 就是服务端认的那个日期("2026-09-27")。

✅ 一步式之后没有「跨午夜作废」这种坑了。 旧版两步式有:23:59 签了到、 00:00 之后才去翻牌 —— 翻牌按「今天」查不到那条记录,那一天的奖励就丢了。 现在「签到」与「发鱼干」是同一个请求里的一件事, 你按下请求的那一刻,要么今天已经签过、要么这一次签成了,不存在中间态。

📌 另外,鱼干流水里的时间戳是「UTC+8 墙上时间贴 Z 标签」的假 Z, 口径与其他接口一致,见 docs/bot/comment-bot.md §5。


4. 签到

POST /api/checkin
Cookie: raricy_session=<JWT>

没有请求体。成功:

{
  "code": 200,
  "message": "签到成功!获得 3 条小鱼干",
  "total_count": 37,
  "reward_fish": 3,
  "today_fish": 3,
  "dried_fish": 41.5
}
字段 说明
total_count 累计签到天数(含今天)
reward_fish 这一次发了多少 —— 固定 3,直接照这个字段用,别在代码里写死
today_fish 今天到手的签到鱼干(正常就等于 reward_fish)
dried_fish 当前鱼干余额(省掉一次余额查询)

4.1 今天已经签过了

注意:已签到返回的是 400,不是 200。

{
  "code": 400,
  "message": "今天已签到",
  "already_checked": true,
  "total_count": 37,
  "reward_fish": 3,
  "today_fish": 3,
  "dried_fish": 41.5
}

⚠️ 这是本站少见的「错误码里带数据」的接口 —— 除了 code/message, 它还给了 already_checked 与当前状态。看到 already_checked: true 不要重试: 它是终态,今天那 3 条早就到账了(today_fish 就是它)。

📌 靠「签到返回 400」来判断今天签过没有是可以的,但那会让每天的正常运行 都带一条错误日志。更干净的做法是先 GET /api/checkin(§5)看 checked_in。

4.2 会被拒绝的情形

情形 返回
未登录 / Cookie 失效 401 请先登录
账号不是 core+ 403 需要核心用户权限
账号被禁言 403 你已被禁言,暂时无法签到
名下没有未删除的文章 403 发布过文章后才能签到(带 can_check_in: false,见 §1.1)
今天已签到 400 今天已签到(带数据,见上)
服务端故障 500 服务器开小差了,请稍后再试 —— 事务整体回滚,重发一次即可;若它其实已经成功,重发会拿到 400 今天已签到(照 §4.1 处理,别当成失败)
旧版调用 POST /api/checkin/claim → 404 —— 翻牌那一步已下线(§0)

5. 查今天的状态

GET /api/checkin
Cookie: raricy_session=<JWT>

适合当每日任务的第一个请求 —— 用它决定今天要不要签。

{
  "code": 200,
  "message": "ok",
  "checked_in": true,
  "can_check_in": true,
  "total_count": 37,
  "today": "2026-09-27",
  "reward_fish": 3,
  "today_fish": 3,
  "dried_fish": 41.5
}
字段 说明
checked_in 今天签了没有
can_check_in 够不够格签(core+、名下有一篇未删除的文章且未被禁言)。false 时 POST 必被拒—— 先去看前置条件,别重试
today 服务端认的「今天」(UTC+8)
reward_fish 现在签一次给多少(当前的奖励数额,可能随站长调整而变)
today_fish 今天已经到手的签到鱼干;没签到是 0
dried_fish 当前鱼干余额

⚠️ today_fish 可以小于 reward_fish(今天签到之前奖励是另一个数,或者更早年代的 历史行)。要用「今天到底到账多少」,读 today_fish;要预估「现在签能拿多少」, 读 reward_fish。 别拿一个去当另一个。


6. 鱼干这件事

6.1 每天固定 3 条,无其他签到收益

签到给的就是 reward_fish(当前是 3)条鱼干,没有「连续签到加成」「首签奖励」 这类东西。total_count(累计天数)只是统计,不参与结算。

⚠️ 数额以响应里的 reward_fish 为准 —— 站长可能调整它,而调完之后同一份文档 描述的所有机器人都会照旧工作(只要你不把 3 写死在自己的代码里)。

⚠️ 签到是鱼干的来源之一,不是转账。 想给别人鱼干请走 docs/bot/fish-bot.md 的转账接口 —— 签到没有任何「送给别人」的参数。

6.2 想看排名

GET /api/fish/leaderboard —— 免登录,返回小鱼干余额榜:按当前余额倒序, 字段 rank / user_id / username / avatar_path / balance。只读,与签到是两回事。


7. 失败只有两种,都不会「账记了一半」

签到是鱼干写路径:建记录、发鱼干、写流水在同一个事务里提交 —— 要么都生效、 要么都不存在。所以不存在「本地记了账、别处没记」这种没人知道的状态, 也没有「稍后会自己变好」的暂态。

📌 对机器人的含义,按状态码分两类:

  • 4xx = 业务拒绝(400 今天已签到 / 403 需要核心用户权限 / 403 发布过文章后才能签到)—— 原样重试无用,要么改输入,要么先去补齐前置条件;
  • 500 = 本站故障,事务已整体回滚,今天等于还没签 —— 原样重发即可; 若重发时这次其实已经成功过,你会拿到 400 今天已签到(照 §4.1 处理)。

两类都别写成循环:失败不会「多试几次就成」。


8. 限频

签到域没有任何 RULES 配额 —— 它是「每天一次」的自然节流:一天能成功的只有一次, 重复请求只会拿到 already_checked 的幂等响应。

⚠️ 但别拿它当心跳刷。它每天每账号最多产生 1 行记录 + 1 笔发鱼, 刷它除了浪费你自己的时间没有任何收益。

📌 别的域(点赞、投喂、转账…)各有各的配额,用哪个域就去读那份接入文档的 「限频」一节 —— 这里没有配额不代表那里也没有。


9. 礼仪与约定

  • 签到是给自己签的,不产生任何通知、不影响别人。这大概是全站最不需要 「礼仪」的一段 —— 但同样别用多账号刷(那是在伪造 core+ 体系的报酬)。
  • 机器人也不该替人签到。 本站没有「代签」接口,一个账号一份凭据; 拿别人的密码去签等于替他做了决定,且凭据泄露的后果由他承担。

10. 排错速查

现象 多半是
403 需要核心用户权限 账号还是 user,需要站长提权一次(§2)
403 发布过文章后才能签到 名下没有未删除的文章 —— 先发一篇;发过又全删了也算没有(§1.1)
403 你已被禁言,暂时无法签到 禁言期间不能签到,解除或到期后恢复
400 今天已签到 终态,别重试。那天的鱼干早已到账(§4.1)
404 且路径是 /api/checkin/claim 翻牌那一步已下线 —— 删掉你代码里的第二步(§0)
reward_fish 不是我预期的数 以响应为准:奖励数额由站长调整,别写死在你的代码里(§6.1)
签到成功但 today_fish 比 reward_fish 小 那是当天早些时候按旧数额发的(§5),不是漏发
500 本站故障(不是你的输入问题):事务已整体回滚,等于没签过,原样重发即可(§7)
余额涨了但流水里没有 不可能:发鱼一定伴随流水。对账请走 docs/bot/fish-bot.md §3.3 的游标模式
时间差 8 小时 假的 Z,见 §3

11. 最小可用流程

const BASE = 'https://raricy.com';
const cookie = 'raricy_session=<JWT>';   // 登录见 chat-bot.md §3

// 先看今天的状态(省掉一次必然失败的 POST)
const st = await (await fetch(`${BASE}/api/checkin`, { headers: { cookie } })).json();
if (st.can_check_in === false) {
  // 前置条件没满足(多为「名下没有未删除的文章」)—— 先去发一篇,重试无意义(§1.1)
  console.warn('还不能签到:检查文章门槛和禁言状态');
} else if (!st.checked_in) {
  const res = await fetch(`${BASE}/api/checkin`, { method: 'POST', headers: { cookie } });
  const out = await res.json();
  if (res.ok) {
    console.log(`签到成功:+${out.reward_fish},今日共 ${out.today_fish},余额 ${out.dried_fish}`);
  } else if (out.already_checked) {
    // 并发 / 重复提交:今天早就签过了,终态
    console.log(`今天已签到,今日到手 ${out.today_fish}`);
  } else if (res.status === 500) {
    // 本站故障,事务已整体回滚 —— 等于没签过,隔一会儿原样重发
  } else {
    console.error('签到失败', out.code, out.message);
  }
}

断线 / 401 → 重新登录。429 → 签到域不会出现,但转账会遇到,见 docs/bot/fish-bot.md §4。

本页内容来自仓库 docs/bot/checkin-bot.md·在 GitHub 上查看

签到机器人接入说明 · 聪明山