@chat-adapter/x

中文文档
4.44.0发布于 2026/11/02MITTypeScriptES Module构建来源已验证近 30 天下载 39.4万

X (Twitter) Chat SDK 的适配器: 回复引用, 直接发送信件, 并用 X API v2 从您的 bot 账户发布, 加上从 @ chat- adapter/ x/ chat 子路径加密的 XChat 对话

中文使用文档
文档目录41 节
  1. 安装
  2. 带CLI的脚手架
  3. 使用量
  4. X 设置
  5. 1. 创建 X 应用程序
  6. 2. 登记网点
  7. 3. 环境变量
  8. 托肯刷新
  9. Webhook 设置
  10. 特征
  11. 通讯
  12. 丰富内容
  13. 对话
  14. 信件历史
  15. 线索标识格式
  16. 自动化政策
  17. XChat( 加密信件)
  18. 使用量
  19. XChat 设置
  20. 1. 注册加密密钥
  21. 2. 创建网点
  22. 3. 订阅聊天活动
  23. Webhook 路线
  24. 配置
  25. 环境变量
  26. 特征
  27. 通讯
  28. 丰富内容
  29. 对话
  30. 信件历史
  31. 在团体中提及行为
  32. 线索标识格式
  33. 加密注释
  34. 解决问题
  35. CRC 验证失败
  36. 未抵达的事件
  37. 在 Webhook POSTs 上的"无效签名"
  38. 信件解密, 但机器人从未在组中回复
  39. 张贴时没有对话键
  40. AI 编码代理
  41. 许可证

X adapter for Chat SDK

@ 聊天适应器/ x

npm 软件包 : @chat-adapter/x

Agent Stack MIT License

X (twitter) 适配器,用于 聊天SDK,使用 X API v2 (英语) 编辑 X 活动 API答复公众提及,举行管理部对话,张贴博特账户,以及类似张贴.

联合国 聊天-sdk.dev/适应者/正式/x 指南: vercel.com/kb/chat-sdk (英语)

安装

pnpm add @chat-adapter/x

带CLI的脚手架

要用这个适配器预选的新X机器人脚手架:

npx create-chat-sdk@latest my-bot --adapter x memory

访问 适配器目录 见其他官方和供应商官方适配器.

使用量

import { Chat } from "chat";
import { createXAdapter } from "@chat-adapter/x";

const bot = new Chat({
  userName: "mybot",
  adapters: {
    x: createXAdapter(),
  },
});

bot.onNewMention(async (thread, message) => {
  await thread.post(`Hi @${message.author.userName}!`);
});

bot.onDirectMessage(async (thread, message) => {
  await thread.post("Hello from X!");
});

使用时 createXAdapter() 证书由环境变量自动检测.

X 设置

1. 创建 X 应用程序

  1. 转到 X 开发者门户网站 并创建工程和 App
  2. 下 键和符号,复制 API 密钥 这变成了 X_CONSUMER_SECRET
  3. 启用 OAuth 2.0 数据 带有范围的用户认证 tweet.read, (中文(简体) ), tweet.write, (中文(简体) ), users.read, (中文(简体) ), dm.read, (中文(简体) ), dm.write, (中文(简体) ), like.write,以及 offline.access
  4. 完成 Bot 账户的 OAuth 2.0 流量 。 将访问符作为 X_USER_ACCESS_TOKEN,或存储 X_CLIENT_ID 加号 X_REFRESH_TOKEN 让适配器管理令牌刷新

2. 登记网点

X通过 X 活动 API设置它一次在 X 开发者控制台,它为您处理认证:

  1. 注册您的 Webhook URL(https://your-domain.com/api/webhooks/x) (中文(简体) ). 它必须是没有港口的公共HTTPS. X 立即发出 CRC 挑战,适配器自动回答
  2. 为适配器占用的事件创建订阅 : post.mention.create, (中文(简体) ), dm.received,以及 dm.sent (私人活动,所以机器人用户必须先授权您的应用)

订阅和webhook管理是一次性设置,而不是适配器运行时间. 如果您不使用控制台来脚本它,活动 API 端点是认证选择并针对操作的,并且不完全匹配已发布的 spec(在测试中创建一个需要的私事订阅 OAuth 1.0a 用户上下文,同时列出和删除只使用应用程序无记名符号),所以控制台是比较简单的路径.

3. 环境变量

X_CONSUMER_SECRET=...      # App API key secret, used for webhook CRC and signature verification

# Auth option A: static access token
X_USER_ACCESS_TOKEN=...    # OAuth 2.0 user-context access token for outbound calls

# Auth option B: managed OAuth refresh (recommended for long-running bots)
X_CLIENT_ID=...            # OAuth 2.0 client ID
X_REFRESH_TOKEN=...        # OAuth 2.0 refresh token (requires the offline.access scope)
X_CLIENT_SECRET=...        # Optional, only for confidential clients
X_ENCRYPTION_KEY=...       # Optional, base64 32-byte key to encrypt persisted tokens

X_USER_ID=...              # Bot account user ID. Optional if omitted it is fetched from /2/users/me; the adapter requires a resolvable bot id and fails init otherwise
X_USERNAME=...             # Optional, bot @handle for mention detection (fetched when omitted)
X_API_BASE_URL=...         # Optional, override the X API base URL

托肯刷新

X OAuth 2.0用户代号为短寿命(约2小时). 与 X_CLIENT_ID 财务报告和审定财务报表 X_REFRESH_TOKEN 设置,适配器在到期前刷新访问令牌,并在您的状态适配器中坚持旋转的刷新令牌,因此机器人能够活下来重启。 设定 X_ENCRYPTION_KEY 以存储加密的 AES-256-GCM 令牌.

或者,通过一个符号提供者并插入您自己的刷新逻辑 :

import { createXAdapter } from "@chat-adapter/x";

const adapter = createXAdapter({
  userAccessToken: async () => refreshTokenFromMyStore(),
});

Webhook 设置

X使用两种由适配器处理的webhook机制:

  1. 《儿童权利公约》的挑战 X发送一个 crc_token 适配器用HMAC -SHA256响应 以您的消费者秘密为键 X 重新验证小时数
  2. 事件交付 活动活动: x-twitter-webhooks-signature 标题, 对照原始请求体进行校验
// Next.js App Router example
import { bot } from "@/lib/bot";

export async function GET(request: Request) {
  return bot.webhooks.x(request);
}

export async function POST(request: Request) {
  return bot.webhooks.x(request);
}

特征

通讯

特性支助
邮件有(提醒答复和模式草案)
高级员额对(channel.post 打开 x:public(中文(简体) )
编辑信件只有职位(适用X编辑资格规则)
删除信件员额和自己的管理部活动
流线缓冲(累计一次员额)
打字指标没有

丰富内容

特性支助
卡片格式纯文本倒置
按钮否( 链接按钮渲染为文本)
表格ASC 二届理事会
模块没有
图像上传是(png、jpeg、webp;每个员额最多4个;以及模式草案)

通过粘接图像 files (或 attachments)在消息上;适配器通过X块媒体端点上传每个端点(initialize 接下来 append 接下来 finalize并附上返回者 media_id职位或管理部。 一个帖子可以携带有或没有文字的媒体.

await thread.post({
  markdown: "France lead the title race",
  files: [{ data: pngBuffer, filename: "odds.png", mimeType: "image/png" }],
});

媒体上传需要 media.write 在 OAuth 2.0 令牌上显示 tweet.write。用 media.write 用 403 包含或上传失败 .

对话

特性支助
提及对(post.mention.create(中文(简体) )
模式对(dm.received 编号 : dm.sent(中文(简体) )
反应只喜欢emoji.heart 或者说 "like"(中文(简体) )
用户查询对

信件历史

特性支助
获取信件通过 API 的 DMs , 缓存的帖子
获取单个消息通过API、DM从缓存中的员额

线索标识格式

x:post:{conversationId}   # public post threads (channel: x:public)
x:dm:{participantUserId}  # direct message with a single user

实例: x:post:1943467279943467279, (中文(简体) ), x:dm:783214X DM Webhooks不携带对话id,只有参与者ids,因此DMs被另一个参与者的用户id所线程: openDM("783214") 返回时 x:dm:783214,并发送路径到 POST /2/dm_conversations/with/783214/messages顶级职位通过 channel.post 编辑 x:public 频道.

自动化政策

X 执行 自动化规则。在部署机器人之前:

  • 在发送自动答复或模式草案之前获得明确同意,并立即履行退出义务
  • 在账户配置中披露机器人身份
  • 从不发送批量、复制或主动的自动化内容
  • 只使用正式的 API( 不刮取或浏览器自动化)

适配器默认是严格的:它从不流出后编辑,大声拒绝不支持的交互,只有在您的处理者决定时才回答.

XChat( 加密信件)

XChat是X的加密消息产品. 它从船上飞来 @chat-adapter/x/chat 此软件包的子路径, 因此它安装在 @chat-adapter/x 添加无 依赖性, 除非你导入它 .

import { createXchatAdapter } from "@chat-adapter/x/chat";

XChat 密码堆栈(@xdevplatform/chat-xdk, (中文(简体) ), @xdevplatform/xdk, (中文(简体) ), juicebox-sdk)被宣布为可选的对等依赖。 安装它们 并行 @chat-adapter/x 当你使用这个子路径.

使用量

import { Chat } from "chat";
import { createXchatAdapter } from "@chat-adapter/x/chat";
import { createMemoryState } from "@chat-adapter/state-memory";

const bot = new Chat({
  userName: "mybot",
  adapters: {
    xchat: createXchatAdapter(),
  },
  state: createMemoryState(),
});

// DMs always
bot.onDirectMessage(async (thread, message) => {
  await thread.post(`You said: ${message.text}`);
});

// Group chats when the bot is @mentioned
bot.onNewMention(async (thread, message) => {
  await thread.post(`You said: ${message.text}`);
});

接通网路(如. app/api/webhooks/xchat/route.ts 在下一个.js中:

import { bot } from "@/lib/bot";

export async function GET(request: Request) {
  return bot.webhooks.xchat(request);
}

export async function POST(request: Request) {
  return bot.webhooks.xchat(request);
}

使用时 createXchatAdapter() 证书由环境变量自动检测。 机器人的 @ handle 解决自 GET /2/users/me 在启动时,请提及检测工作,而没有任何硬编码.

XChat 设置

1. 注册加密密钥

机器人账户需要注册的公用钥匙和一个Juicebox后置的私人钥匙商店,然后才能参与加密的对话:

  1. 生成密钥pairs with chat-xdk (单位:千美元)generateKeypairs()(中文(简体) )
  2. 通过 POST /2/users/{id}/public_keys
  3. 在 Juicebox 中用 PIN 存储私钥(chat.setup(pin)(中文(简体) )

适配器在启动时用相同的 PIN 解锁密钥(XCHAT_PIN) (中文(简体) ). 登记是每个账户的一次性步骤——见 聊天- xdk 文档 为了整个流动.

2. 创建网点

注册一个webhook URL,使 X 活动 API 能够传送事件(文档:

curl -X POST "https://api.x.com/2/webhooks" \
  -H "Authorization: Bearer $APP_BEARER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://your-domain.com/api/webhooks/xchat"}'

X 用 CRC 挑战验证 URL (参见 Webhook 路线 ),所以终点必须在创建"网络呼克"之前进行直播.

也可以创建和管理 Webhooks 和活动订阅 X 开发者门户 而不是通过API.

3. 订阅聊天活动

创建 活动订阅 用于装有 bot 的 OAuth2 用户代号的机器人用户 :

curl -X POST "https://api.x.com/2/activity/subscriptions" \
  -H "Authorization: Bearer $BOT_USER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "event_type": "chat.received",
    "filter": {"user_id": "YOUR_BOT_USER_ID"},
    "tag": "bot-chat-received",
    "webhook_id": "YOUR_WEBHOOK_ID"
  }'

订阅 chat.conversation_join 如果你希望机器人在加入一个组时发出一个欢迎信息.

Webhook 路线

X发出两种请求:

  1. 《儿童权利公约》的挑战 (GET) - (英语) ?crc_token=... 以HMAC -SHA256的代号 以你的应用软件的消费者秘密为键 适配器回答这个,所以路线也去.
  2. 事件交付 (POST)——聊天活动,由适配器通过 x-twitter-webhooks-signature 头曰.
import { bot } from "@/lib/bot";

export async function GET(request: Request) {
  return bot.webhooks.xchat(request);
}

export async function POST(request: Request) {
  return bot.webhooks.xchat(request);
}

不要在您的操作器上签名 。 挑战与 POST 签名使用相同的密钥,算法,以及 sha256= 前缀,所以一个处理器可以使 HMAC 任意 crc_token 成为签名预告器:一个呼叫者可以通过一个被伪造的事件体作为符号,并将响应重放为 x-twitter-webhooks-signature如上所示,路径通过适配器;在签名前拒绝错误的CRC标志.

配置

在不提供时,所有选项都从环境变量中自动检测出.

选项需求说明
botToken 编号 : accessToken无*OAuth2 机器人账户用户访问令牌. 自动从 XCHAT_BOT_TOKEN 或者说 X_ACCESS_TOKEN
pin没有Juicebox PIN; 设定时, 密钥会自动解锁 initialize()自动从 XCHAT_PIN
consumerSecret为网友应用消费者秘密来验证Webhook签名. 自动从 X_CONSUMER_SECRET。 。 。 . 需要接收网点: X 在每个 POST 上签名,所以没有它,每个 POST 会被以 401 拒绝. 投票部署不需要
disableWebhookVerification没有在不验证其HMAC的情况下接受 Webhook POST. 自动从 X_DISABLE_WEBHOOK_VERIFICATION。只有在上游层验证签名时才使用。 未推荐生产
editSafetyDelayMs没有新发布消息的最小年龄(ms)必须在发送第一次编辑前到达,所以接收客户端已经存储了原始编辑目标. 默认为 5000· ; 0 禁用等号
sendReadReceipts没有在处理器运行前发送每个发送的输入信件的读取收据( 默认) true(中文(简体) )
userName没有瓶子 @ handle 用于检测 。 自动从 X_BOT_USERNAME,以其他方式解决 GET /2/users/me
welcomeMessage没有当机器人加入一个组时发布消息 . false 禁用; 省略使用默认解释@mention- to-reply
verifySignatures没有要求在收到的信件上签名( 默认) true) (中文(简体) ). X_VERIFY_SIGNATURES=false 选择退出
signingKeyVersion没有签名密钥版本覆盖 。 通常在 initialize()自动从 X_SIGNING_KEY_VERSION
apiBaseUrl没有媒体 REST 调用的基准 URL( 默认为 https://api.x.com(中文(简体) )
apiHeaders没有在每个 X API 请求上都添加了信头 。 除非它包括一个 User-Agent,适配器预置 chat-sdk-xchat/<version> 到客户端的默认值,所以聊天SDK流量可以识别
logger没有锁定实例( 默认为 ConsoleLogger("info")(中文(简体) )

* 运行时需要——通过配置或环境变量.

环境变量

XCHAT_BOT_TOKEN=xcbot_...          # OAuth2 user token for the bot account
XCHAT_PIN=...                      # Juicebox PIN for key unlock
X_CONSUMER_SECRET=...              # App secret (CRC + webhook signature verification)
X_BOT_USERNAME=...                 # Optional @handle override; resolved from /2/users/me otherwise
X_VERIFY_SIGNATURES=true           # Optional; set false to accept unverifiable messages

特征

通讯

特性支助
邮件是( 加密 + 签名)
集体答复是(对触发消息的引用答复)
编辑信件是(加密了针对原始序列 ID 的编辑事件;只有机器人自己的短信). 首个新消息的编辑会持续到消息 editSafetyDelayMs 旧的,所以接收客户端在编辑到来之前就存储了原件
删除信件是( 全部删除: 本地签名的删除动作会删除每个参与者的信件; 只有机器人自己的信件)
流线有限(消息编辑工作,但第一次编辑时间为 editSafetyDelayMs快速的逐个更新是粗糙的)
读取收据是(通过发送的每封送入信件,使对话提前读取水印,除非 sendReadReceipts: false; 调用 thread.markAsRead() 手动控制)
TTL 传播是( 复制人继承输入信件的消失消息- TTL)

丰富内容

特性支助
标记没有客户端渲染 — 向外的标记下字面显示为纯文本(表格为例外,见下文)
URL / @mention 实体是(在外出文本中被检测出,作为可挖掘链接和提及药丸提供)
邮政卡是(第一个) x.com/.../status/... 正在发送的文本自动附件中的 URL)
媒体出去是(文件加密流并经由三步媒体上传流程上传)
媒体是(通过懒惰下载披露的附件+解密) fetchData()(中文(简体) )
卡片/ 按钮/ 模式否( XChat 没有交互式信件表面)
表格ASCII 代码块

对话

特性支助
提及是 (结构上提及实体, 刷新到机器人, 纯文本) @handle 倒计时)
添加/ 删除反应对
即将出现的反应是(按程序进行) onReaction(中文(简体) )
打字指标是(在操作员运行时,每3次保留一次)
模式对
分组聊天对(g-前置对话ID)
集团加入欢迎是( 可通过 welcomeMessage(中文(简体) )
打开管理部对(openDM(userId) 重用已有的对讲机或运行新密钥交换机; 要求收件人设置加密聊天器)

信件历史

特性支助
获取信件对(GET /2/chat/conversations/{id}/events,批次解密)
获取线索信息对
列表线索没有

在团体中提及行为

chat.onNewMention(handler) 给提到机器人的团体信息起火。 当 :

  1. 内容丰富 提及实体 包括机器人的@handle或用户ID——权威信号,或
  2. 这是一个 刷新复制 给机器人的一条信息,或者
  3. 它的纯文本包含 @handle (当没有实体存在时倒计时).

对没有提及机器人的群组信息,请登记 chat.onNewMessage(handler) 没有规律.

线索标识格式

xchat:{conversationId}
  • 1:1 个对话 : xchat:1234567890-9876543210 (均为参与者身份)
  • 分组对话 : xchat:g123456789 (不公开) g- 前置标识)

REST 路径使用另一个参与者的用户ID进行 1:1 个对讲和 g... 组的ID;适配器自动转换.

加密注释

  • 对话键通过 KeyChange 事件并被缓存到每个谈话和密钥版本。 当一个密钥在发送时间丢失时,适配器会获取最近的对话事件取出一个.
  • 以参与者的签名密钥(取自 GET /2/users/{id}/public_keys 和缓存)。 与 verifySignatures: true (默认),不可验证信件被删除.
  • 媒体使用流传加密与消息文本分开加密;消息带有 media_hash_key 用于下载和解密blob.

解决问题

CRC 验证失败

  • 确认 X_CONSUMER_SECRET 匹配您的应用程序在开发者门户网站上的消费者秘密
  • 对策必须是 {"response_token": "sha256=<base64 HMAC>"} 获取请求

未抵达的事件

  • 校验订阅存在 : GET /2/activity/subscriptions 与应用程序无记名标志
  • 确认订阅 webhook_id 在網址上标出您的活端点
  • 订阅更改需要几分钟才能提供

在 Webhook POSTs 上的"无效签名"

  • 适配器验证 x-twitter-webhooks-signature 由 HMAC-SHA256 键入 X_CONSUMER_SECRET 确定是同一个软件拥有网页

信件解密, 但机器人从未在组中回复

  • 组回复需要提及 —— 请检查发送者是否真的提及了机器人的手柄( 来自 /2/users/me),或使用 { allGroupMessages: true }

张贴时没有对话键

  • 机器人只能发送到对话中与它共享一个对话密钥(即有人先给机器人发信息,将其添加到组中,或者机器人自己打开对话通过) openDM(userId)) (中文(简体) ). openDM 要求接收者设置加密聊天,服务器则要求接收者在接受第一个消息之前信任bot(例如跟随它).

AI 编码代理

如果您使用OpenAI Codex, Claude Code, 或 Cursor 等AI编码代理, 在写入代码前安装 Chat SDK 技能, 使其了解 SDK API, 适配器模式, 以及项目常规 .

npx skills add vercel/chat

技术参考文献 node_modules/chat/docs,加上已发布的软件包中的适配器指南和启动模板.

您也可以安装 Vercel 插件 包括Chat SDK技术与专家代理、代理斜线命令以及更多:

npx plugins add vercel/vercel-plugin

插件是可选的;单是技能就足以用Chat SDK来构建.

关于可代理阅读的文件,见 聊天- sdk.dev/llms.txt (页数索引)或 聊天- sdk.dev/llms- full.txt (全文).

许可证

麻省理工学院

版本与发布记录

@chat-adapter/x 共发布 15 个版本,首次发布于 2026/07/07;过去 12 个月发布了 15 个版本。最新版本附带 npm provenance 构建来源证明,可追溯到公开的 CI 构建记录。

版本发布日期距今
4.44.0latest2026/11/026 天前
4.43.02026/10/1921 天前
4.42.02026/10/1425 天前
4.41.12026/09/291 个月前
4.41.02026/09/181 个月前
4.40.02026/09/052 个月前

关于 @chat-adapter/x 的常见问题

@chat-adapter/x 是什么?

X (Twitter) Chat SDK 的适配器: 回复引用, 直接发送信件, 并用 X API v2 从您的 bot 账户发布, 加上从 @ chat- adapter/ x/ chat 子路径加密的 XChat 对话

如何安装 @chat-adapter/x?

在项目目录运行 npm install @chat-adapter/x,或使用 pnpm add / yarn add / bun add。

@chat-adapter/x 支持 TypeScript 吗?

支持。包内自带 TypeScript 类型声明(package.json 声明了 types 入口),安装后即可获得类型提示,无需再安装 @types 包。

@chat-adapter/x 支持 ESM 还是 CommonJS?

以 ES Module 形式发布,推荐使用 import 引入。在 CommonJS 项目中,Node.js 20.19+ / 22.12+ 可以直接 require() 不含顶层 await 的 ES Module,更早的版本需要改用动态 import()。

@chat-adapter/x 需要什么版本的 Node.js?

package.json 的 engines 字段要求 Node.js >=20。版本不符时 npm 默认只给出警告,开启 engine-strict 后会拒绝安装。

@chat-adapter/x 可以商用吗?

@chat-adapter/x 使用 MIT 许可。宽松许可:允许商业使用、修改和再分发,通常只需在分发时保留原版权与许可声明。以上为概括,不构成法律意见,请以许可原文为准。

@chat-adapter/x 的下载量有多少?

根据 npm 官方下载统计,@chat-adapter/x 在 2026/10/10 – 2026/11/08 这 30 天内被下载 393,816 次,日均约 13,127 次。下载量会把 CI 构建、镜像同步和作为其他包依赖的安装一并计入,适合横向比较热度,不能直接等同于使用人数。

@chat-adapter/x 还在维护吗?

最新版本 4.44.0 发布于 2026/11/02(6 天前);至今共发布 15 个版本,其中过去 12 个月发布了 15 个;首次发布于 2026/07/07。发布频率只是参考信号:功能稳定的工具可能很少需要更新,建议结合源码仓库的 issue 和提交记录判断。