@chat-adapter/ 什么app (英语)
npm 软件包 :
@chat-adapter/whatsapp
企业云适配器 聊天SDK,使用 什么App商业云 API。 。 。 .
联合国 聊天-sdk.dev/适应者/官方/什么应用 指南: vercel.com/kb/chat-sdk (英语)
安装
pnpm add @chat-adapter/whatsapp
带CLI的脚手架
使用这个适配器预选的新WhatsApp机器人:
npx create-chat-sdk@latest my-bot --adapter whatsapp memory
访问 适配器目录 见其他官方和供应商官方适配器.
使用量
import { Chat } from "chat";
import { createWhatsAppAdapter } from "@chat-adapter/whatsapp";
const bot = new Chat({
userName: "mybot",
adapters: {
whatsapp: createWhatsAppAdapter(),
},
});
bot.onNewMention(async (thread, message) => {
await thread.post("Hello from WhatsApp!");
});
使用时 createWhatsAppAdapter() 证书由环境变量自动检测.
WhatsApp 商业设置
1. 创建 Meta 应用程序
- 转到 开发者. facebook.com/apps 页面存档备份,存于互联网档案馆
- 点击 创建 App选择 商业 类型
- 添加数据 怎样 产品到应用程序
- 转到 WhatsApp > API 设置 记住你 电话号码 财务报告和审定财务报表 访问托肯
2. 配置网点
- 转到 何为App > 配置 在您的 Meta 应用程序中
- 设定 回调 URL 改为
https://your-domain.com/api/webhooks/whatsapp - 设定 校验托肯 您选择的秘密字符串( 变为
WHATSAPP_VERIFY_TOKEN(中文(简体) ) - 订阅
messages网点字段
3. 获得全权证书
从你的Meta应用仪表板,复制:
- 应用程序保密 (单位:千美元) App 设置 > 基础,作为
WHATSAPP_APP_SECRET - 访问托肯 (单位:千美元) WhatsApp > API 设置,作为
WHATSAPP_ACCESS_TOKEN - 电话号码 (单位:千美元) WhatsApp > API 设置,作为
WHATSAPP_PHONE_NUMBER_ID
为了生产,生产一个永久的 系统用户调试 而不是临时出入证.
入境附件
即将到来的媒体附件暴露出一个懒惰者 fetchData()。媒体只从 Meta 下载 fbcdn.net 财务报告和审定财务报表 fbsbx.com 主机或配置的图形来源 。 下载拒绝私人和内部地址,限制为25 MB,30秒后暂停,访问符从不跟随这些主机的重定向. 通过自定义运输到 downloadMedia() ,通过代理程序下载.
配置
在不提供时,所有选项都从环境变量中自动检测出。 你可以打电话 createWhatsAppAdapter() 没有参数,如果env vars设置.
| 选项 | 需求 | 说明 |
|---|---|---|
accessToken | 无* | Meta访问令牌. 自动从 WHATSAPP_ACCESS_TOKEN |
appSecret | 无* | 用于网络验证 自动从 WHATSAPP_APP_SECRET |
phoneNumberId | 无* | Bot的电话号码ID。 自动从 WHATSAPP_PHONE_NUMBER_ID |
verifyToken | 无* | Webhook 验证机密. 自动从 WHATSAPP_VERIFY_TOKEN |
apiVersion | 没有 | 图表 API 版本( 默认为 v25.0(中文(简体) ) |
userName | 没有 | 用于自我信息检测的Bot用户名. 自动从 WHATSAPP_BOT_USERNAME (违约) whatsapp-bot(中文(简体) ) |
apiUrl | 没有 | 覆盖 Meta Graph API 基础 URL 。 自动从 WHATSAPP_API_URL |
logger | 没有 | 锁定实例( 默认为 ConsoleLogger("info")(中文(简体) ) |
* 运行时需要——通过配置或环境变量.
环境变量
WHATSAPP_ACCESS_TOKEN=... # Meta access token (permanent or system user token)
WHATSAPP_APP_SECRET=... # App secret for X-Hub-Signature-256 verification
WHATSAPP_PHONE_NUMBER_ID=... # Bot's phone number ID from Meta dashboard
WHATSAPP_VERIFY_TOKEN=... # User-defined secret for webhook verification
WHATSAPP_BOT_USERNAME=... # Optional, defaults to "whatsapp-bot"
WHATSAPP_API_URL=... # Optional, override the Meta Graph API base URL
Webhook 设置
WhatsApp使用两个webhook机制:
- 核查握手 (GET)——梅塔发送a
hub.verify_token挑战,必须与您的WHATSAPP_VERIFY_TOKEN。 。 。 . - 事件交付 (POST)——收到的信息、反应和交互式答复,通过
X-Hub-Signature-256。 。 。 .
// Next.js App Router example
import { bot } from "@/lib/bot";
export async function GET(request: Request) {
return bot.webhooks.whatsapp(request);
}
export async function POST(request: Request) {
return bot.webhooks.whatsapp(request);
}
特征
通讯
| 特性 | 支助 |
|---|---|
| 邮件 | 对 |
| 编辑信件 | 否(WhatsApp限制) |
| 删除信件 | 否(WhatsApp限制) |
| 流线 | 缓冲(累积后发送) |
| 标记为已读 | 对 |
| 自动切入 | 是( 4096 字符的分块) |
| 模板消息 | 是(通过) sendTemplate(中文(简体) ) |
丰富内容
| 特性 | 支助 |
|---|---|
| 交互式按钮 | 有(至多3个) |
| 链接按钮 | 部分( 单一链接按钮成为本地 CTA URL 消息) |
| 按键标题限制 | 20个字符 |
| 列出信件 | 对 |
| 文本倒转 | 是(对于 > 3个按钮) |
对话
| 特性 | 支助 |
|---|---|
| 反应 | 是( 添加并删除) |
| 打字指标 | 是( 需要最近输入的消息, 标记为已读, 并显示最多25秒) |
| 模式 | 对 |
| 打开管理部 | 对 |
打字指标
WhatsApp 支持通过 thread.startTyping() 或者说 adapter.startTyping(threadId)。 。 。 .
当机器人即将响应时使用它,可能需要几秒钟. 适配器使用线程历史中最近输入的消息ID,所以 startTyping() 只有在机器人收到消息后才能工作.
await thread.startTyping();
await thread.post({
markdown: "Thanks, I am checking that now.",
});
特定的行为 :
- 如果没有输入的信息背景,
startTyping()没有. - 输入指示器在bot发送回复时,或在WhatsApp平台超时后被解析.
读取收据
使用 thread.markAsRead() 在信件处理器中确认当前输入的消息:
await thread.markAsRead();
也可以通过入境 Message 或身份证。 何为App在对话中标记了该消息和先前的消息为已读. 它不允许将发送的消息ID标为已读,并建议在30天内确认输入的消息.
收到的消息类型
| 类型 | 支助 |
|---|---|
| 文本 | 对 |
| 图像 | 是(有标题) |
| 文档 | 是(有标题) |
| 音频/ 语音 | 对 |
| 视频 | 是(有标题) |
| 贴纸 | 对 |
| 地点 | 是( 已转换为映射 URL) |
| 交互式答复 | 是(按钮和列表) |
| 反应 | 对 |
信件历史
| 特性 | 支助 |
|---|---|
| 获取信件 | 否( CPI 限制) |
| 获取线索信息 | 对 |
交互式消息
卡片元素被自动转换为WhatsApp交互式消息:
- 3个或更少的按钮 ——作为WhatsApp回复按钮提供(每个标题最多20个字符)
- 3个以上的按钮 ——返回格式化文本
- 最大正文文本 - 1024个字符
当一个带有回复按钮的卡片也包含链接按钮时,每个链接按钮都会被附加到交互式信件正文中作为一个 Label: url 线条,因为WhatsApp回复按钮无法打开 URL.
链接按钮( CTA URL)
唯一互动元素为单一链接按钮的卡作为本地的 CTA URL 消息发送,并带有可抓取链接按钮. 只有在这些都持有时,卡片才会被推广:
- 链接按钮是卡片在每行动作中唯一的动作,包括被嵌入分节的行. 回复按钮,选择,收音机选择,或者第二个人气动作行保持文本倒置.
- URL 开始于
http://或者说https://标签是非空的。 其他计划(mailto:, (中文(简体) ),tel:,相对路径) 保留文本倒置,因为云API拒绝它们. - 该卡没有标题图像,也没有图像,表格,图表,或者内线链接到孩子. 文字,字段,分出分出者都很好.
- 该帖没有文件或附件. 当媒体伴有卡片时,适配器会保留单个字幕媒体发送,而字幕包括a
Label: url每个链接按钮的行.
按钮标签被切入到20个字符上,头部(名牌标题)被切入到60个,身体被切入到1024个. 不符合这些规则的卡片会回到格式化文本,其中链接按钮渲染为 Label: url。 。 。 .
模板消息
在24小时客户服务窗口外,WhatsApp只接受预先批准 模板消息启用 sendTemplate 开始由企业发起的对话:
const threadId = await adapter.openDM("15551234567");
await adapter.sendTemplate(threadId, {
name: "appointment_reminder",
language: "en",
components: [
{
type: "body",
parameters: [{ type: "text", text: "Tomorrow at 2pm" }],
},
],
});
模板必须在 WhatsApp 管理器 在他们发送之前。 模板上的快速回复按钮自带作为按钮响应到达并发送给您 onAction 管理者.
API 错误
非-2xx 图 API 响应抛出 WhatsAppApiError从 @chat-adapter/whatsapp它延伸 AdapterError,因此已经存在 instanceof AdapterError 检查还在继续.
import { WhatsAppApiError } from "@chat-adapter/whatsapp";
try {
await thread.post("Hello");
} catch (error) {
if (error instanceof WhatsAppApiError) {
console.error(error.code, error.errorCode, error.details, error.status);
}
throw error;
}
code: 共享AdapterError当失败映射到一个时代码 :RATE_LIMITED(HTTP 429,或Meta节流码,例如:130429财务报告和审定财务报表80007, (中文(简体) ),AUTH_FAILED(HTTP 401或Meta代码)0财务报告和审定财务报表190, (中文(简体) ),PERMISSION_DENIED(HTTP 403或Meta代码)3, (中文(简体) ),10,以及200改为299, (中文(简体) ),NOT_FOUND(HTTP 404) (韩语). 否则undefined。 。 。 .errorCode: Meta 的数字错误代码, 如130429providerMessage财务报告和审定财务报表type: 梅塔语error.message财务报告和审定财务报表error.type时details: 梅塔语error_data.details时status: HTTP 响应状态subcode财务报告和审定财务报表traceId: 梅塔语error_subcode财务报告和审定财务报表fbtrace_id时raw: 完整的解析反应机构(见WhatsAppGraphErrorBody类型),或者原文本,如果它无效 JSON
元建议使用 错误代码和细节 用于处理错误。 子代码是可选的,在"云"API中被贬值. 供应商字段缺失或畸形 undefined,并接受一个代理序列化为字符串的数字代码。 错误消息结合了操作, HTTP 状态和 Meta 的 error.message,或者非JSON身体的受限摘录.
这涵盖来自消息发送,模板,反应,读取收据,打字请求,媒体上传,以及媒体元数据请求的非-2xx回复. 运输故障和无法分割的应对机构抛出 NetworkError二进制媒体下载失败。 2xx 报告的答复 success: false 对于打字请求或读取的收件,丢入平话 AdapterError。成功 API 响应后仍可同步发送失败;这些 Webhook 错误不会被抛出为 WhatsAppApiError。 。 。 .
用户身份
WhatsApp 信件包括一个 业务范围用户ID 内 from_user_id 财务报告和审定财务报表 contacts[].user_id。有用户名的用户可能会省略电话 from 财务报告和审定财务报表 wa_id 字段.
适配器接受任一标识符. 当两者都可用时,它保存了现有的基于电话的线程ID,并作为别名存储了BSUID. 答复既包括 to 财务报告和审定财务报表 recipient根据Meta的API,电话号码优先。 仅发送 BSUID 线索 recipient。 。 。 .
Meta不支持 BSUID 接收者使用一tap,零tap,或复制码认证模板. 这些模板需要用户的电话号码.
在生产中使用持续状态适配器,所以身份别名能够活过重启. 适配器在 Meta 通过消耗来旋转一个 BSUID 时保留了 Canonic 线程 user_changed_number 财务报告和审定财务报表 user_changed_user_id 系统消息加 user_id_update webhook,它携带上个和当前 BSUID 。 订阅您的 Meta 应用程序到 user_id_update webhook 字段可以旋转到适配器。 当前电话、 BSUID、 父机 和用户名字段仍然可用 message.raw。 。 。 .
线索标识格式
whatsapp:{phoneNumberId}:{userWaId}
示例 whatsapp:1234567890:15551234567
最后一段是适配器的克能克用户标识. 它可能包含一个电话号码,一个BSUID,例如: US.13491208655302741918,或为线程连续性保留先前观察到的标识符.
解决问题
Webhook 校验失败
- 确认
WHATSAPP_VERIFY_TOKEN匹配您在 Meta 仪表板中输入的值 - 确保您的端点返回
hub.challenge获取请求的值
信件未到达
- 检查您订阅的
messagesmeta 应用程序设置中的 webhook 字段 - 校验
WHATSAPP_APP_SECRET正确——签字验证无声地拒绝无效有效载荷 - 确保在WhatsApp Business仪表板上注册和核实您的电话号码
“无效签名”错误
- 双检查
WHATSAPP_APP_SECRET匹配下方的值 App 设置 > 基础 - 适配器使用HMAC-SHA256来验证
X-Hub-Signature-256标题
托肯过期
- API Setup页面临时令牌在24小时后失效
- 对于生产,创建 系统用户 在Meta Business 套件中生成永久符号
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 (全文).
许可证
麻省理工学院