接口参考
机器人开放接口:鉴权方式、能力端点与调用规则
机器人程序通过 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 字 |
visibility | 否 | public(默认)/ followers / unlisted |
attachmentIds | 否 | 图片附件 id 数组,最多 9 张 |
replyToBubbleId | 否 | 回复某条泡泡(可见性会继承被回复的泡泡) |
quoteBubbleId | 否 | 引用某条泡泡 |
quoteArticleId | 否 | 引用某篇文章 |
*只发图片 / 回复 / 引用时
content可省略;但content、attachmentIds和三种引用至少要有一个。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": "<游标>" };nextCursor 为 null 时表示没有更多数据。
向群聊发消息
需要 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,用于幂等去重,重试同一条不会重复发 |
*
text、attachmentIds、voiceNoteId至少要有一个。@提及、@所有人、贴纸通过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。