跳转至

Twitter API 详细规格

本文档详细说明 Twitter 私信和图片上传 API 的规格和使用要求。

目录


私信 API

API 端点

  • URL: https://x.com/i/api/1.1/dm/new2.json
  • 方法: POST
  • Content-Type: application/json

必需的 HTTP 请求头

Host: x.com
Authorization: Bearer AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA
X-Csrf-Token: {从 cookies 提取 ct0}
X-Client-Uuid: {随机生成的 UUID v4}
X-Client-Transaction-Id: {Base64 编码的随机字符串}
Cookie: {完整的 cookies 字符串}
Content-Type: application/json
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36...

URL 查询参数

必需的查询参数:

ext=mediaColor,altText,mediaStats,highlightedLabel,voiceInfo,birdwatchPivot,superFollowMetadata,unmentionInfo,editControl,article
include_ext_alt_text=true
include_ext_limited_action_results=true
include_reply_count=1
tweet_mode=extended
include_ext_views=true
include_groups=true
include_inbox_timelines=true
include_ext_media_color=true
supports_reactions=true
supports_edit=true

请求体格式

纯文本私信

{
    "conversation_id": "{user_id}-{current_user_id}",
    "recipient_ids": false,
    "request_id": "{UUID v4}",
    "text": "{message}",
    "cards_platform": "Web-12",
    "include_cards": 1,
    "include_quote_count": true,
    "dm_users": true
}

带图片私信

{
    "conversation_id": "{user_id}-{current_user_id}",
    "recipient_ids": false,
    "request_id": "{UUID v4}",
    "text": "{message}",
    "cards_platform": "Web-12",
    "include_cards": 1,
    "include_quote_count": true,
    "dm_users": true,
    "attachment": {
        "type": "media",
        "media": {
            "id": "{media_id_string from upload}"
        }
    }
}

注意media_id 来自图片上传接口返回的 media_id_string 字段。

成功响应

HTTP 200,JSON 包含 entries 字段表示成功。

认证信息提取

从 cookies 字符串中提取认证信息:

  1. CSRF Token (ct0): 正则匹配 ct0=([^;]+)
  2. Auth Token: 正则匹配 auth_token=([^;]+)
  3. User ID: 从 twid 提取,支持三种格式:
  4. twid=u%3D{user_id} (URL 编码)
  5. twid="u={user_id}" (带引号)
  6. twid=u={user_id} (不带引号)

图片上传 API

三阶段上传流程

Twitter 图片上传采用三阶段流程:INIT → APPEND → FINALIZE

每个阶段都是独立的 HTTP 请求,必须按顺序执行。


INIT 阶段 - 初始化上传

API 端点: - URL: https://upload.x.com/i/media/upload.json?command=INIT&total_bytes={size}&media_type=image/jpeg&media_category={category} - 方法: POST - 状态码: 200 (成功)

请求头:

Host: upload.x.com
Authorization: Bearer AAAAAAAAAAAAAAAAAAAAANRILgAAAAAAnNwIzUejRCOuH5E6I8xnZz4puTs%3D1Zv7ttfk8LF81IUq16cHjhLTvJu4FA33AGWWjCpTnA
X-Csrf-Token: {从 cookies 提取 ct0}
X-Twitter-Auth-Type: OAuth2Session
Accept: */*
Origin: https://x.com
Referer: https://x.com/
Accept-Language: zh-CN,zh;q=0.9
Priority: u=1, i
Cookie: {完整的 cookies 字符串}

响应格式:

{
    "media_id": 1234567890,
    "media_id_string": "1234567890",
    "expires_after_secs": 86400
}


APPEND 阶段 - 上传图片数据

API 端点: - URL: https://upload.x.com/i/media/upload.json?command=APPEND&media_id={media_id}&segment_index=0 - 方法: POST - Content-Type: multipart/form-data - 状态码: 204 (成功)

Multipart 字段: - field name: media - filename: blob - content-type: application/octet-stream - 数据: 图片二进制内容

请求头: 与 INIT 阶段相同


FINALIZE 阶段 - 完成上传

API 端点: - URL: https://upload.x.com/i/media/upload.json?command=FINALIZE&media_id={media_id}&original_md5={md5} - 方法: POST - 状态码: 201 (成功)

请求头: 与 INIT 阶段相同

重试策略: - 500 错误时自动重试,最多 2 次 - 重试等待时间: 第 1 次 2 秒,第 2 次 4 秒


支持的媒体类别

pub enum MediaCategory {
    BannerImage,  // "banner_image" - 横幅图片
    TweetImage,   // "tweet_image" - 推文图片
    DmImage,      // "dm_image" - 私信图片
}

选择建议: - 发送私信图片 → 使用 DmImage - 发布推文图片 → 使用 TweetImage - 更新个人资料横幅 → 使用 BannerImage


错误处理

常见错误码

HTTP 状态码 含义 处理方式
401 认证失败 检查 cookies 是否有效
403 无权限 检查账号状态
429 请求过于频繁 实施速率限制
500 服务器错误 自动重试(仅限 FINALIZE 阶段)

重试建议

  • INIT 阶段:失败后立即停止,不重试
  • APPEND 阶段:失败后立即停止,不重试
  • FINALIZE 阶段:500 错误自动重试 2 次,其他错误不重试

安全性约束

  1. 不在日志中输出完整的 cookies 或 token
  2. 验证消息长度 ≤ 10000 字符
  3. 验证 user_id 非空
  4. 使用 HTTPS 确保传输安全
  5. 定期刷新 cookies 避免过期

性能考虑

  1. 批量发送默认无并发限制 - 可根据账号限制自行调整
  2. 请求超时设置为 30 秒
  3. 使用连接池复用 HTTP 连接
  4. 图片上传前计算 MD5,避免重复上传

相关文档