当 Think agent 应直接接收并回复 Chat SDK webhook 时使用 messenger。Think 拥有 webhook 路由、持久回复 fiber、对话路由,以及流式投递回提供商。
安装 Think 包与你使用的提供商适配器:
npm install @cloudflare/think agents ai @chat-adapter/telegram提供商适配器从提供商专用子路径导出,未使用的适配器不会打进 Worker bundle。
import { Think } from "@cloudflare/think";
import {
defineMessengers,
ThinkMessengerStateAgent,
} from "@cloudflare/think/messengers";
import telegramMessenger from "@cloudflare/think/messengers/telegram";
export { ThinkMessengerStateAgent };
export class SupportAgent extends Think {
getMessengers() {
return defineMessengers({
telegram: telegramMessenger({
token: this.env.TELEGRAM_BOT_TOKEN,
userName: "support_bot",
secretToken: this.env.TELEGRAM_WEBHOOK_SECRET_TOKEN,
}),
});
}
}import { Think } from "@cloudflare/think";
import {
defineMessengers,
ThinkMessengerStateAgent,
} from "@cloudflare/think/messengers";
import telegramMessenger from "@cloudflare/think/messengers/telegram";
export { ThinkMessengerStateAgent };
export class SupportAgent extends Think<Env> {
getMessengers() {
return defineMessengers({
telegram: telegramMessenger({
token: this.env.TELEGRAM_BOT_TOKEN,
userName: "support_bot",
secretToken: this.env.TELEGRAM_WEBHOOK_SECRET_TOKEN,
}),
});
}
}默认 telegram key 下,在以下地址注册 Telegram webhook:
https://<your-worker>/messengers/telegram/webhookWebhook 模式下 telegramMessenger() 需要 secretToken,除非你传自定义 verifyWebhook 或显式 verifyWebhook: false 退出验证。
若一个 Think agent 拥有多个 Telegram bot,为每个提供商使用不同的 Chat SDK 适配器名称:
defineMessengers({
support: telegramMessenger({
adapterName: "support-telegram",
token: this.env.SUPPORT_TELEGRAM_BOT_TOKEN,
userName: "support_bot",
secretToken: this.env.SUPPORT_TELEGRAM_WEBHOOK_SECRET_TOKEN,
}),
sales: telegramMessenger({
adapterName: "sales-telegram",
token: this.env.SALES_TELEGRAM_BOT_TOKEN,
userName: "sales_bot",
secretToken: this.env.SALES_TELEGRAM_WEBHOOK_SECRET_TOKEN,
}),
});defineMessengers({
support: telegramMessenger({
adapterName: "support-telegram",
token: this.env.SUPPORT_TELEGRAM_BOT_TOKEN,
userName: "support_bot",
secretToken: this.env.SUPPORT_TELEGRAM_WEBHOOK_SECRET_TOKEN,
}),
sales: telegramMessenger({
adapterName: "sales-telegram",
token: this.env.SALES_TELEGRAM_BOT_TOKEN,
userName: "sales_bot",
secretToken: this.env.SALES_TELEGRAM_WEBHOOK_SECRET_TOKEN,
}),
});重复适配器名称会在启动时失败,避免提供商在共享 Chat SDK 运行时互相覆盖。
根 Think agent 在框架子 agent 路由与 Think 内部路由之后、用户 onRequest 回退之前处理 messenger webhook 路由。Messenger 路由仅限根级。在子 agent 类上定义 getMessengers() 不会为该子 agent 创建 webhook 路由。
默认 Think 回复私信与提及。新提及会订阅 Chat SDK 线程,同线程后续提及仍被观察,但普通已订阅线程消息与按钮操作被忽略,除非你选择加入:
telegramMessenger({
token: this.env.TELEGRAM_BOT_TOKEN,
userName: "support_bot",
secretToken: this.env.TELEGRAM_WEBHOOK_SECRET_TOKEN,
respondTo: ["direct-message", "mention", "subscribed-thread", "action"],
});telegramMessenger({
token: this.env.TELEGRAM_BOT_TOKEN,
userName: "support_bot",
secretToken: this.env.TELEGRAM_WEBHOOK_SECRET_TOKEN,
respondTo: ["direct-message", "mention", "subscribed-thread", "action"],
});操作事件转为 Think 用户消息,含操作 id、值、源消息 id 与发起用户。钩子或工具内需要提供方专用操作详情时用 getMessengerContext()?.action。操作为可选启用,避免交互式卡片意外触发模型轮次。
默认对话模式为每个 Chat SDK 线程一个 Think 子 agent。避免群聊、私信与频道意外共享记忆。
所有 messenger 流量共享一个 Think 会话时用根 agent 作为对话:
telegramMessenger({
token: this.env.TELEGRAM_BOT_TOKEN,
userName: "support_bot",
secretToken: this.env.TELEGRAM_WEBHOOK_SECRET_TOKEN,
conversation: "self",
});telegramMessenger({
token: this.env.TELEGRAM_BOT_TOKEN,
userName: "support_bot",
secretToken: this.env.TELEGRAM_WEBHOOK_SECRET_TOKEN,
conversation: "self",
});路由依赖租户、频道、线程或用户时用解析器:
telegramMessenger({
token: this.env.TELEGRAM_BOT_TOKEN,
userName: "support_bot",
secretToken: this.env.TELEGRAM_WEBHOOK_SECRET_TOKEN,
conversation(event) {
return {
target: "subagent",
name: `tenant:${event.thread.channelId ?? event.thread.id}`,
};
},
});telegramMessenger({
token: this.env.TELEGRAM_BOT_TOKEN,
userName: "support_bot",
secretToken: this.env.TELEGRAM_WEBHOOK_SECRET_TOKEN,
conversation(event) {
return {
target: "subagent",
name: `tenant:${event.thread.channelId ?? event.thread.id}`,
};
},
});Messenger 状态由 agents/chat-sdk 支持。从 Worker 模块导出 ThinkMessengerStateAgent 以便子 agent 路由解析。生产应用无需为此仅 facet 的状态 class 单独 Durable Object 绑定或迁移。测试工具可能仍需显式绑定。
Think 用流式 chat() 路径回复。根 agent 启动幂等托管 fiber、解析对话目标、调用 target.chat(message, callback),由提供商投递策略发布或编辑可见消息。
恢复快照仅存储可序列化事件与 Chat SDK 线程数据。流式传输开始前重启,Think 可重放答案。流式传输开始后重启,Think 发布配置的中断消息,而非冒险重复部分答案。
投递错误默认用通用用户可见消息,避免将内部异常详情发布到外部聊天。自定义安全消息时重写 delivery.errorResponseText。
Messenger 轮次期间 getMessengerContext() 返回发起事件的提供商、线程、作者、消息、能力与附件元数据。提示词、工具或钩子需要频道专用行为时使用。
const messenger = this.getMessengerContext();
if (messenger?.thread.isDirectMessage === false) {
// Adjust behavior for group chats.
}const messenger = this.getMessengerContext();
if (messenger?.thread.isDirectMessage === false) {
// Adjust behavior for group chats.
}尚无 Think 辅助方法的提供商用 chatSdkMessenger():
chatSdkMessenger({
adapter,
provider: "custom",
userName: "custom_bot",
verifyWebhook(request) {
return request.headers.get("x-custom-signature") === expectedSignature;
},
});chatSdkMessenger({
adapter,
provider: "custom",
userName: "custom_bot",
verifyWebhook(request) {
return request.headers.get("x-custom-signature") === expectedSignature;
},
});每个自定义 messenger 必须提供 verifyWebhook 或显式 verifyWebhook: false。
examples/think-chat-sdk 示例演示 Think 原生 getMessengers() 路径与小型 Vite 仪表板,经 Agent WebSocket 检查根 Think 对话。
examples/chat-sdk-messenger 示例演示更大的手动入口 agent,含管理仪表板、菜单处理与应用自有回复 fiber。简单的 Think 原生路径用 getMessengers()。需自有 Chat SDK 运行时与控制面 UI 时参考该示例。底层状态适配器见 Chat SDK 状态。