twitter-cli xchat¶
XChat 端到端加密私信子命令。共 8 个 action:
| action | 输出格式 | 用途 |
|---|---|---|
enroll |
Envelope | 首次启用 XChat(生成密钥 + Juicebox 备份) |
status |
Envelope | 查询本地/服务端状态 |
reset-pin |
Envelope | 修改 PIN |
delete-account |
Envelope | 注销(不可逆) |
send |
Envelope | 单条加密/明文私信 |
send-batch |
BatchLine 三段式 | 批量统一文案 |
send-batch-custom |
BatchLine 三段式 | 批量自定义文案 |
receive |
BatchLine 三段式 | 拉取对话最近消息 |
所有命令使用 --keystore 参数指定本地密钥文件路径(也可通过 XCHAT_KEYSTORE 环境变量注入)。
全局约定¶
- stdout:严格 JSONL(一行一条 JSON)
- stderr:tracing 日志(默认
--log-level off) - 退出码:12 种确定性退出码(见
output-schema.md) - PIN 安全:所有
--pin/--old-pin/--new-pin参数标记hide_env_values=true,不会出现在--help输出里
enroll¶
启用 XChat(首次注册设备)。
| 参数 | 类型 | 环境变量 | 说明 |
|---|---|---|---|
--pin |
string | XCHAT_PIN |
用户 PIN(任意 unicode;推荐 4-6 位) |
--keystore |
path | XCHAT_KEYSTORE |
密钥文件路径,会被创建(0600 权限) |
输出:Envelope::success(EnrollPayload),含 user_id / key_version / registration_method / realms_registered。
错误码映射:
- DUPLICATE — 本地或服务端已 enroll
- AUTH_FAILED — PIN 不正确 / cookies 失效
- UNKNOWN — 复合错误 EnrollRollbackFailed(手动 delete-account --yes 清理)
status¶
查询本地 + 服务端 + 一致性状态。
输出字段:
{"success":true,"data":{
"enrolled":true,
"key_version":"1778485658072",
"registration_method":"CustomPin",
"local_keystore_exists":true,
"key_version_synced":true
},"error":null,"meta":{"module":"xchat","action":"status",...}}
reset-pin¶
twitter-cli xchat reset-pin \
--old-pin "$XCHAT_OLD_PIN" \
--new-pin "$XCHAT_NEW_PIN" \
--keystore ~/.config/x-api-rs/xchat.json
delete-account¶
不可逆。需要 --yes 标志确认。
twitter-cli xchat delete-account \
--pin "$XCHAT_CONFIRM_PIN" \
--keystore ~/.config/x-api-rs/xchat.json \
--yes
| 参数 | 环境变量 | 说明 |
|---|---|---|
--pin |
XCHAT_CONFIRM_PIN |
二次确认(Juicebox delete 协议层不校验 PIN,SDK 强制非空避免脚本误触发) |
--yes |
— | 缺失时直接 INVALID_ARGS |
send¶
发送单条 XChat 私信。SDK 根据收件人 enrollment 状态自动选路(明文 / 加密)。
twitter-cli xchat send \
--user-id 1234567890 \
--text "hello e2e" \
--keystore ~/.config/x-api-rs/xchat.json
| 参数 | 说明 |
|---|---|
--user-id |
收件人 Twitter user_id(数字串) |
--text |
消息内容(UTF-8,最大 10000 字符) |
--keystore |
密钥文件路径 |
输出:Envelope::success(SendPayload),含 success / message_id / event_id / sequence_id / timestamp_ms / warning / conversation_key_version。
warning 字段语义:
- "recipient_not_enrolled" — 对端未启用 XChat,已走明文+签名
- "encryption_implemented_unverified" ⚠️ — 双方都 enrolled,已走 AES-GCM 加密但 wire 格式未在真实抓包上对账
- "send_failed: <reason>" — 仅出现在批量场景
send-batch¶
批量并发发送同一条消息给多个用户。三段式 BatchLine 输出。
twitter-cli xchat send-batch \
--user-ids 111,222,333 \
--text "broadcast" \
--keystore ~/.config/x-api-rs/xchat.json
输出形态:
{"type":"header","command":"xchat send-batch","schema_version":"...","expected_count":3,"meta":{...}}
{"type":"item","index":0,"success":true,"data":{...},"error":null}
{"type":"item","index":1,"success":false,"data":null,"error":{...}}
{"type":"item","index":2,"success":true,"data":{...},"error":null}
{"type":"summary","total":3,"success_count":2,"fail_count":1,"elapsed_ms":...}
退出码:全部成功返回 0,任一失败返回 1。
send-batch-custom¶
twitter-cli xchat send-batch-custom \
--user-ids 111,222 \
--texts-file ./texts.txt \
--keystore ~/.config/x-api-rs/xchat.json
texts.txt 每行一条文案,与 --user-ids 严格按行号一一对应:
- 不会静默过滤空行 / 纯空白行(避免索引错位)
- 行数必须等于 --user-ids 数量,否则 INVALID_ARGS
- 空白文案会被业务层 validate_batch_message_input 拒绝
receive¶
拉取单个对话的最近消息,自动解码、解密(如果加密)、验签。
twitter-cli xchat receive \
--conv-id 984485658860208128:1973098228334960640 \
--limit 20 \
--keystore ~/.config/x-api-rs/xchat.json
| 参数 | 默认 | 说明 |
|---|---|---|
--conv-id |
— | 对话 ID(格式 <peer_id>:<self_id>,从 inbox 或对方 user_id + 本人 user_id 拼接) |
--limit |
20 | 拉取条数上限 |
输出形态(每条 Item 是一个 DecryptedMessage):
{"type":"header","command":"xchat receive","schema_version":"...","expected_count":null,"meta":{...}}
{"type":"item","index":0,"success":true,"data":{"event_id":"...","sender_id":"...","text":"...","encrypted":false,"signature_valid":true,"warning":null,...},"error":null}
{"type":"item","index":1,"success":false,"data":{...,"warning":"decrypt_failed",...},"error":null}
{"type":"summary","total":2,"success_count":1,"fail_count":1,"elapsed_ms":...}
success = warning is None。success=false 的 Item 仍然带 data(含 elaborate warning),便于上层调试。
data.warning 字段值:见 docs/api/xchat-enrollment.md Phase 3 章节。
错误码(CLI)¶
| 错误码 | 退出码 | 触发场景 |
|---|---|---|
AUTH_FAILED |
4 | cookies 失效 / PIN 错 / 未 enroll |
DUPLICATE |
9 | 已 enroll(enroll 时) |
NOT_FOUND |
8 | PeerNotEnrolled(对端未启用 XChat 但代码尝试加密) |
NETWORK |
5 | Juicebox / HTTP 通信失败 |
RATE_LIMIT |
6 | realm 速率限制 |
SERVER |
7 | 服务端状态与本地不一致 / ConversationKeyEstablishmentFailed |
UNKNOWN |
1 | EnrollRollbackFailed / KekDerivationFailed / 解码失败 |
INVALID_ARGS |
2 | PIN 为空 / 未传 --yes / 参数缺失 |
CONFIG_PARSE_ERROR |
12 | keystore 文件损坏 |
已知限制¶
| 限制 | 影响 |
|---|---|
| 加密 wire 格式未在真实双端抓包对账 | send 返回 warning="encryption_implemented_unverified" 时,消息能发出但对端是否解出未知 |
| 接收侧验签字节选取未确认 | receive 的 signature_valid 在多数情况下可能返回 None 而非 Some(true/false) |
| 群组 / 媒体附件 / 密钥轮换 | 留 Phase 4 |
完整 TODO 清单见源码 TODO(phase3.1-verify) / TODO(phase3.2-verify) 注释。
参考¶
- API 文档:
../api/xchat-enrollment.md - 协议逆向:
../architecture/xchat-e2e-reverse-engineering.md - 输出 schema:
output-schema.md