跳到主要内容
Logo2SOMEone

接口参考

机器人开放接口:鉴权方式、能力端点与调用规则

机器人程序通过 HTTPS 调用平台开放接口。所有请求都发往 https://2some.ren,鉴权统一用请求头携带运行密钥:

x-api-key: sk_xxxxxxxx

验证身份

启动时建议先做一次身份校验,确认密钥有效且确实是机器人密钥:

curl https://2some.ren/api/auth/get-session \
  -H "x-api-key: $TWOSOMEONE_BOT_API_KEY"

返回的 user.accountType 应为 "bot"user.id 即机器人的 botUserId

发布泡泡

需要 bubble.create 能力。

curl -X POST https://2some.ren/api/v1/bubbles \
  -H "x-api-key: $TWOSOMEONE_BOT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"content": "你好,泡泡!详情 → https://example.com/article"}'
字段必填说明
content是*文本内容,不超过 500 字
visibilitypublic(默认)/ followers / unlisted
attachmentIds图片附件 id 数组,最多 9 张
replyToBubbleId回复某条泡泡(可见性会继承被回复的泡泡)
quoteBubbleId引用某条泡泡
quoteArticleId引用某篇文章

*只发图片 / 回复 / 引用时 content 可省略;但 contentattachmentIds 和三种引用至少要有一个。quoteBubbleId / quoteArticleId / quoteLetterId 三选一,不能同时引用多个。

机器人发图片需注意

attachmentIds 是接口支持的字段,但它要求先把图片上传拿到附件 id,而上传接口 /api/v1/media/upload-url 目前只对真人会话开放,不接受机器人运行密钥。所以机器人实际能发的是文本 + 链接 + 回复 + 引用;要让机器人发图片需要官方单独开通上传入口。回复和引用对机器人是可用的,适合做「自动回复某话题」「转发引用外部内容并加点评」。

成功返回 { "success": true, "id": "<bubbleId>" },泡泡地址为 https://2some.ren/bubble/<bubbleId>

内容规则

  • 内容会经过平台审核,违规内容发布失败
  • #词语 会成为话题标签;@用户名真实通知对应用户——转发外部内容时建议把 @ 替换为全角 ,避免误打扰
  • 机器人发布的 public 原创泡泡会进入关注它的人的关注流(并可能触发粉丝推送);回复和引用类不会扩散到关注流。机器人高频发 public 泡泡会打扰粉丝,请控制节奏
  • 写操作有频率限制,收到 429 时请退避重试

读取自己的泡泡

需要 bubble.read 能力。机器人只能读自己发布的内容,常用于「判断哪些内容已经发过」的去重场景。

curl "https://2some.ren/api/v1/bubbles?authorId=<botUserId>&limit=50" \
  -H "x-api-key: $TWOSOMEONE_BOT_API_KEY"
参数说明
authorId必填,机器人自己的 botUserId
limit每页条数,最大 50
cursor翻页游标,取上一页返回的 nextCursor

返回 { "success": true, "items": [...], "nextCursor": "<游标>" }nextCursornull 时表示没有更多数据。

向群聊发消息

需要 chat.send 能力,且机器人已被安装到该群聊

curl -X POST "https://2some.ren/api/v1/chat/conversations/<conversationId>/messages" \
  -H "x-api-key: $TWOSOMEONE_BOT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text": "今晚 8 点开播,记得来!"}'

群聊消息不止能发纯文本,下面这些字段都可以带:

字段必填说明
text否*文本内容,最长 8000 字
attachmentIds图片 / 文件附件 id 数组,最多 9 个(需先上传,见下方提醒)
voiceNoteId语音消息 id(不能和 attachmentIds 同时发)
parentMessageId回复某条消息(填被回复消息的 id)
clientMessageId客户端生成的 UUID,用于幂等去重,重试同一条不会重复发

*textattachmentIdsvoiceNoteId 至少要有一个。@提及、@所有人、贴纸通过 blocks 字段发送,其中 @所有人只有群主或管理员能用,贴纸必须单独成条。

机器人发图片 / 语音需注意

和发泡泡一样,attachmentIds / voiceNoteId 需要先上传媒体拿到 id,而上传接口暂不对机器人运行密钥开放。所以机器人在群里实际能稳定发的是文本、回复(parentMessageId)和链接卡片;要发图片 / 语音需官方单独开通上传入口。

常见错误

下表针对机器人 runtime 发布接口(发泡泡 / 发消息):

状态码含义处理建议
401密钥无效或已被轮换检查密钥,必要时重新 key rotate
403能力不足或越权(如读他人内容、@所有人无权限)确认机器人具备对应能力且未越界
400参数错误(超 500 字、内容违规、附件超 9 张等)按返回的 error 字段修正
429触发频率限制指数退避后重试(如 1s、2s、4s)

创建机器人(用账号密钥调管理接口)时,若用户名已被占用会返回 409

完整示例

一个最小可运行的 Node.js 机器人(Node 20+,零依赖)。保存为 bot.mjs,然后 TWOSOMEONE_BOT_API_KEY=sk_xxx node bot.mjs 运行:

// bot.mjs — 顶层 await 需要 ESM,文件后缀用 .mjs(或在 package.json 设 "type": "module")
const BASE = "https://2some.ren";
const KEY = process.env.TWOSOMEONE_BOT_API_KEY;

async function api(path, init = {}) {
  const res = await fetch(`${BASE}${path}`, {
    ...init,
    headers: { "x-api-key": KEY, "Content-Type": "application/json", ...init.headers },
  });
  const body = await res.json();
  if (!res.ok || body.success === false) throw new Error(body.error ?? `HTTP ${res.status}`);
  return body;
}

// 验证身份
const { user } = await api("/api/auth/get-session");
if (user?.accountType !== "bot") throw new Error("不是机器人密钥");

// 发一条泡泡
const { id } = await api("/api/v1/bubbles", {
  method: "POST",
  body: JSON.stringify({ content: `大家好,我是 ${user.username} 🤖` }),
});
console.log(`已发布:${BASE}/bubble/${id}`);

更完整的实战范例(RSS 拉取、无状态去重、GitHub Actions 免服务器部署)见官方模板仓库 leaperone/2someone-news-bot