跳转至

DM 模块(私信)

dm 模块提供私信发送和收件箱查询功能,支持单条发送、批量并发发送和收件箱翻页。

目录


dm send — 发送单条私信

向指定用户发送一条私信,可选附带媒体附件。

语法

twitter-cli [全局 flags] dm send \
  --user-id <ID> \
  --text <STRING> \
  [--media-id <ID>]

参数

参数 类型 必填 说明
--user-id <ID> string 目标用户的 Twitter 数字 ID(非用户名)
--text <STRING> string 消息内容,最大 10000 字符
--media-id <ID> string 媒体附件 ID(来自 upload image 命令的返回值)

成功示例

twitter-cli --cookies-file cookies.txt dm send \
  --user-id 783214 \
  --text "Hello from twitter-cli!"

输出(单行 JSONL):

{"success":true,"data":{"user_id":"783214","event_id":"1811234567890123456","message":"Message sent successfully","media_id":null},"error":null,"meta":{"module":"dm","action":"send","elapsed_ms":519,"timestamp":"2026-04-17T10:45:00Z","cli_version":"1.0.0","schema_version":"1.0"}}

带媒体附件:

# 先上传图片获取 media_id
media_id=$(twitter-cli --cookies-file cookies.txt upload image \
  --file photo.jpg --category dm-image | jq -r '.data.media_id_string')

# 发送带图片的私信
twitter-cli --cookies-file cookies.txt dm send \
  --user-id 783214 \
  --text "请看这张图片" \
  --media-id "$media_id"

失败示例

{"success":false,"data":null,"error":{"code":"NOT_FOUND","message":"用户 999999 不存在或无法接收私信","retryable":false,"retry_after_secs":null,"docs_url":null,"recovery_actions":["确认 user_id 是否正确","检查目标用户是否开放私信权限"],"issue_url":null,"details":{"http_status":403}},"meta":{"module":"dm","action":"send","elapsed_ms":312,"timestamp":"2026-04-17T10:46:00Z","cli_version":"1.0.0","schema_version":"1.0"}}

data 字段说明

字段 类型 说明
user_id string 目标用户 ID(与输入相同)
event_id string 私信事件 ID(Twitter 的 snowflake ID)
message string 成功描述(固定为 "Message sent successfully"
media_id string | null 媒体 ID(如果发送了媒体附件)

常见错误

错误码 原因 解决方法
INVALID_ARGS --text 超过 10000 字符 截断文本
AUTH_FAILED cookies 过期 重新导出 cookies
NOT_FOUND 用户不存在或禁止私信 确认用户 ID,检查对方隐私设置
RATE_LIMIT 发送过于频繁 等待 retry_after_secs 后重试

dm send-batch — 批量发送私信

并发向多个用户发送私信。支持统一文案和从文件读取自定义文案两种模式。输出为三段式 BatchLine 格式(header / item / summary)。

语法

twitter-cli [全局 flags] dm send-batch \
  --user-ids <ID,ID,...> \
  (--text <STRING> | --texts-file <PATH>) \
  [--media-id <ID>]

参数

参数 类型 必填 说明
--user-ids <ID,...> string 逗号分隔的用户 ID 列表(如 783214,6253282,1234
--text <STRING> string 二选一 所有用户使用相同的文案
--texts-file <PATH> path 二选一 自定义文案文件,每行一条,行数必须与 user-ids 数量一致
--media-id <ID> string 所有用户共享同一个媒体附件 ID

--text--texts-file 必须二选一,不可同时使用。

texts-file 格式

每行一条文案,行数必须与 --user-ids 中的 ID 数量完全相同:

你好,张三!欢迎使用我们的服务。
你好,李四!感谢您的支持。
你好,王五!祝您使用愉快。

统一文案示例

twitter-cli --cookies-file cookies.txt dm send-batch \
  --user-ids 783214,6253282,1234567890 \
  --text "批量通知:系统维护将于明日进行"

自定义文案示例

twitter-cli --cookies-file cookies.txt dm send-batch \
  --user-ids 783214,6253282,1234567890 \
  --texts-file messages.txt

BatchLine 输出(完整 5 行示例)

{"type":"header","command":"dm send-batch","schema_version":"1.0","expected_count":3,"meta":{"module":"dm","action":"send-batch","timestamp":"2026-04-17T10:45:00Z","cli_version":"1.0.0"}}
{"type":"item","index":0,"success":true,"data":{"user_id":"783214","event_id":"1811234567890123456","message":"Message sent successfully","media_id":null}}
{"type":"item","index":1,"success":false,"error":{"code":"NOT_FOUND","message":"用户 6253282 不存在或无法接收私信","retryable":false,"retry_after_secs":null,"recovery_actions":["确认 user_id 是否正确"]}}
{"type":"item","index":2,"success":true,"data":{"user_id":"1234567890","event_id":"1811234567890123457","message":"Message sent successfully","media_id":null}}
{"type":"summary","total":3,"success_count":2,"fail_count":1,"elapsed_ms":1820}

解析批量结果

# 统计成功/失败数
twitter-cli --cookies-file cookies.txt dm send-batch \
  --user-ids 783214,6253282 --text "Hello" | \
  grep '"type":"summary"' | jq '{total: .total, ok: .success_count, fail: .fail_count}'

# 提取失败的 user_id 用于重试
twitter-cli ... | \
  grep '"type":"item"' | \
  jq -r 'select(.success == false) | .error.message' 

item 字段说明

字段 类型 说明
type string 固定 "item"
index number 在 user-ids 列表中的位置(从 0 开始)
success bool 是否发送成功
data object | null dm send 的 data(成功时)
error object | null 错误详情(失败时)

summary 字段说明

字段 类型 说明
total number 目标用户总数
success_count number 成功发送数量
fail_count number 失败数量
elapsed_ms number 批量操作总耗时(毫秒)

常见错误

错误码 原因 解决方法
INVALID_ARGS --texts-file 行数与 user-ids 数量不符 确认文件行数与 ID 数一致
INVALID_ARGS 同时指定 --text--texts-file 只使用其中一个
RATE_LIMIT 批量触发速率限制 减少批次大小,添加间隔

dm inbox — 查询收件箱

获取最近的私信收件箱更新记录。

语法

twitter-cli [全局 flags] dm inbox [--max <N>]

参数

参数 类型 必填 说明
--max <N> number 返回的最大条目数,默认 20

成功示例

twitter-cli --cookies-file cookies.txt dm inbox --max 5

输出:

{"success":true,"data":{"entries":[{"conversation_id":"783214-6253282","last_message_id":"1811234567890123456","last_message_text":"Hello from twitter-cli!","participants":["783214","6253282"],"unread_count":0},{"conversation_id":"783214-1234567890","last_message_id":"1811234567890123400","last_message_text":"Test message","participants":["783214","1234567890"],"unread_count":1}],"next_cursor":"1811234567890123300","entry_count":2},"error":null,"meta":{"module":"dm","action":"inbox","elapsed_ms":421,"timestamp":"2026-04-17T10:45:00Z","cli_version":"1.0.0","schema_version":"1.0"}}

失败示例

{"success":false,"data":null,"error":{"code":"AUTH_FAILED","message":"Twitter 返回 401,cookies 可能已过期","retryable":false,"retry_after_secs":null,"docs_url":"https://x-api-rs.es007.com/cli/getting-started/#cookies","recovery_actions":["重新从浏览器导出 cookies"],"issue_url":null,"details":{"http_status":401}},"meta":{"module":"dm","action":"inbox","elapsed_ms":128,"timestamp":"2026-04-17T10:46:00Z","cli_version":"1.0.0","schema_version":"1.0"}}

data 字段说明

字段 类型 说明
entries array 会话列表
entries[].conversation_id string 会话 ID(格式:user1_id-user2_id
entries[].last_message_id string 最新一条消息的 ID
entries[].last_message_text string 最新消息预览文本
entries[].participants string[] 会话参与者 ID 列表
entries[].unread_count number 未读消息数
next_cursor string | null 翻页游标(为 null 表示没有更多数据)
entry_count number 本次返回的条目数

翻页方式

inbox 不直接支持 --cursor 参数(使用最新消息 ID 自动分页)。如需历史数据,使用 Inbox 模块的 Python API(client.inbox.get_user_updates)更灵活。

常见错误

错误码 原因 解决方法
AUTH_FAILED 认证失败 更新 cookies
RATE_LIMIT 查询过于频繁 降低查询频率