feat: X (Twitter) 机器人渠道 —— @提及派发任务并读取 thread 上下文(调研结论与实施计划)
- Dominant language
- TypeScript
- Stars
- 2.7k
- Forks
- 395
- Avg merge
- 21h 48m
- Merged PRs (30d)
- 776
Description
## 使用场景 / Use case
为 Cindy 增加 X (Twitter) 机器人渠道:用户在 X 上 @bot 即可派发任务,bot 读取 thread 原始上下文,交给 desktop 侧 agent 执行,最后回帖结果 —— 与现有 Slack / Telegram bot 同一产品形态。
## 当前问题 / Current limitation
Cindy 目前支持 Slack、Telegram(hook server 路线)与飞书、Discord(用户自带 token 路线),尚无 X 渠道。
## 调研结论(2026-07)
### X 平台能力对齐
- **实时 mention 推送可行**:X Activity API (XAA) 的 `post.mention.create` 事件(filter by `user_id`),persistent HTTP stream(`GET /2/activity/stream`)或 webhook 交付,亚秒级。mention 属私有事件,需 OAuth 2.0 user context 授权。断线补偿 `backfill_minutes` 上限 5 分钟。
- **thread 上下文可读**:回复链上溯(`referenced_tweets` expansion)+ `conversation_id` 检索;`conversation_id` 仅覆盖最近 7 天(recent search 窗口)。
- **平台政策约束**(X Developer Guidelines):
- 回复 @提及属 user-initiated,允许;但**每次交互最多 1 条回复**;
- AI 生成的回复需向 X 事先申请批准(Policy Support form),这是上线前置条件;
- 必须开启 Automated 账号标签、bio 声明运营者、关联真人账号、支持 opt-out;
- 2026-02 起自动化应用仅可回复先 @ / 引用了该 App 的帖子(与本产品形态天然一致)。
- **成本**(pay-per-use,2026-02 起):读 post $0.005、发 post $0.015、含链接 $0.20;月读上限 200 万条。
- **输出限制**:标准 280 字符;长推(25,000 字符)需 bot 账号有 X Premium;附件仅支持图片(`/2/media/upload` + `media.write`),不支持任意文件。
- **公开时间线无按钮组件**,Slack 那套交互卡(权限审批 / 提问 / plan review)无法直接搬移。
### 已定产品决策
- API 成本由服务端统一承担,配 per-user 配额与全局熔断护栏。
- **单条回复优先**:公开线一条长推收口(bot 账号购买 Premium,25,000 字符);仅在 agent 中途需要交互、产出超载或需要 slash 类操作时降级到 DM。
- ack 用点赞(like)而非回复,不消耗唯一回复名额。
- `turn.progress` 对 X provider 丢弃(无可编辑的进度载体;协议中本就是 latest-wins 帧,丢帧无害)。
- X 来源任务默认低交互权限模式(预置 allowlist),尽量避免中途交互。
- 7 天 `conversation_id` 窗口可接受,超窗不提示用户。
## 期望方案 / Proposed solution
走 **hook server + provider-neutral 协议**路线(与 Telegram 相同),不走用户自带 token 路线。理由:AI 回复审批发给单一官方 App、XAA 单 App 单 stream 需服务端扇出、webhook 需公网端点、pay-per-use 计费与断线补偿需要 always-on 服务端。
协议层(`provider.bind.*` / `provider.prefs.*` / `HOOK_FEATURE_PROVIDER_*`)已为多 provider 泛化,Telegram 已验证过此扩展路径。
### 实施顺序
1. **前置重构(本仓)**:`apps/desktop/src/main/hook-control/manager.ts` 中 telegram 专属的 transport / status / binding 状态目前是硬编码变量,先泛化为表驱动的 provider map,为第三个 provider 铺路;
2. **协议(cindy-protocol)**:`HOOK_PROVIDERS` 加 `'x'`、新增 feature 常量与测试;`TaskSource.im` 为开放集合,无需结构改动;
3. **服务端**(独立仓,不在本仓边界):XAA 订阅管理、OAuth 绑定、thread 抓取与预算护栏、长推纯文本渲染(markdown 降级)、like ack、DM 兜底;
4. **客户端接线(本仓)**:`config/endpoint*.json` 加 `xHookWsUrl`、settings UI(HookConnectionsSection 等)、session source 枚举与图标(Light/Dark 双模式)、localDb schema。
### 外部前置依赖
- 向 X 提交 AI reply 审批申请(周期不可控,应先行启动);
- 与 X 政策渠道确认:对先 @ 过 bot 的用户发起 DM 是否符合 solicited 语义、数据使用条款适用范围。
## 已考虑的替代方案 / Alternatives considered
- **用户自带 X App token 本地直连**(Discord 模式,`lizi-im` + `im/shared` 编排层):被否。AI 回复审批按 App 发放,不可能让每个用户自行申请;且 desktop 无公网端点、无法承担 always-on 的 stream 消费与计费管理。
- **轮询 mentions timeline 代替 XAA**:被否。延迟高、读配额烧钱快,且 XAA 已提供亚秒级推送。
- **公开线多条回复 / 流式进度**:被否。违反平台「每次交互最多 1 条回复」规则。
Contributor guide
Assessment
This issue has not been assessed yet.