跳转至

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(首次注册设备)。

twitter-cli xchat enroll \
  --pin "$XCHAT_PIN" \
  --keystore ~/.config/x-api-rs/xchat.json
参数 类型 环境变量 说明
--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

查询本地 + 服务端 + 一致性状态。

twitter-cli xchat status --keystore ~/.config/x-api-rs/xchat.json

输出字段

{"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 Nonesuccess=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" 时,消息能发出但对端是否解出未知
接收侧验签字节选取未确认 receivesignature_valid 在多数情况下可能返回 None 而非 Some(true/false)
群组 / 媒体附件 / 密钥轮换 留 Phase 4

完整 TODO 清单见源码 TODO(phase3.1-verify) / TODO(phase3.2-verify) 注释。

参考