ibot-前缀的Agent接入微信回调消息
本文介绍如何为 ibot- 前缀的 Agent 实现微信平台回调消息处理,在公众号、小程序客服、微信客服等场景中实现 AI 自动回复。
概述
ibot- 前缀的 Agent 是云开发提供的函数型 Agent,通过实现 wxSendMessage 方法,可以接收并处理微信平台的回调消息。
支持的微信平台
| 平台 | triggerSrc 值 | 回复模式 |
|---|---|---|
| 微信小程序客服 | WXMiniapp | 始终异步 |
| 微信服务号 | WXService | 同步(已认证)/ 异步(未认证) |
| 微信订阅号 | WXSubscription | 同步(已认证)/ 异步(未认证) |
| 微信客服 | WXCustomerService | 始终异步 |
核心接口
wxSendMessage 方法
ibot- Agent 需要实现 wxSendMessage 方法用于处理微信回调消息:
wxSendMessage(input: WxSendMessageInput): Promise<WeChatTextOutput>
API 路由:POST /v1/aibot/bots/:botId/wx-send-message
当微信用户发送消息时,云开发会将消息转发到此接口,由你的 ibot- Agent 进行处理。
输入参数
WxSendMessageInput
| 字段 | 类型 | 说明 |
|---|---|---|
| callbackData | WeChatTextInput | WeChatVoiceInput | WeChatWorkTextInput | WeChatWorkVoiceInput | 微信回调消息数据 |
| triggerSrc | string | 消息来源:WXSubscription(订阅号)、WXService(服务号)、WXMiniapp(小程序)、WXCustomerService(微信客服) |
| wxVerify | boolean | 微信 AppId 的认证状态 |
WeChatTextInput(公众号/小程序文本消息)
| 字段 | 类型 | 说明 |
|---|---|---|
| content | string | 消息内容 |
| createTime | number | 消息创建时间 |
| fromUserName | string | 发送者 OpenId |
| toUserName | string | 接收者 |
| msgId | string | 消息 ID |
| msgType | string | 消息类型 |
WeChatVoiceInput(公众号/小程序语音消息)
| 字段 | 类型 | 说明 |
|---|---|---|
| format | string | 语音格式 |
| mediaId | string | 语音媒体 ID |
| createTime | number | 消息创建时间 |
| fromUserName | string | 发送者 OpenId |
| toUserName | string | 接收者 |
| msgId | string | 消息 ID |
| msgType | string | 消息类型 |
WeChatWorkTextInput(微信客服文本消息)
| 字段 | 类型 | 说明 |
|---|---|---|
| externalUserId | string | 外部用户 ID |
| openKfId | string | 客服 ID |
| origin | number | 消息来源 |
| sendTime | number | 发送时间 |
| msgId | string | 消息 ID |
| msgType | string | 消息类型 |
| text.content | string | 消息内容 |
WeChatWorkVoiceInput(微信客服语音消息)
| 字段 | 类型 | 说明 |
|---|---|---|
| externalUserId | string | 外部用户 ID |
| openKfId | string | 客服 ID |
| origin | number | 消息来源 |
| sendTime | number | 发送时间 |
| msgId | string | 消息 ID |
| msgType | string | 消息类型 |
| voice.mediaId | string | 语音媒体 ID |
返回参数
WeChatTextOutput
对于已认证的公众号,需要返回同步回复消息:
| 字段 | 类型 | 说明 |
|---|---|---|
| Content | string | 回复内容 |
| CreateTime | number | 创建时间戳 |
| FromUserName | string | 发送方(公众号) |
| ToUserName | string | 接收方(用户) |
| MsgType | string | 消息类型,固定为 text |
快速开始
步骤 1:创建项目
使用 @cloudbase/aiagent-framework 框架创建项目:
npm init -y
npm install @cloudbase/aiagent-framework
步骤 2:实现 wxSendMessage 方法
const { BotCore, BotRunner } = require("@cloudbase/aiagent-framework");
class MyBot extends BotCore {
/**
* 处理微信回调消息
* @param {import('@cloudbase/aiagent-framework').WxSendMessageInput} input
* @returns {Promise<import('@cloudbase/aiagent-framework').WeChatTextOutput>}
*/
async wxSendMessage(input) {
const { callbackData, triggerSrc, wxVerify } = input;
// 获取用户消息内容
let userMessage = '';
if (callbackData.msgType === 'text') {
// 文本消息
userMessage = callbackData.content || callbackData.text?.content || '';
} else if (callbackData.msgType === 'voice') {
// 语音消息 - 可调用语音转文字
const voiceResult = await this.tools.speechToText({
mediaId: callbackData.mediaId || callbackData.voice?.mediaId,
});
userMessage = voiceResult.Result;
}
// 调用大模型生成回复
const reply = await this.generateReply(userMessage);
// 根据认证状态返回不同格式
if (wxVerify && (triggerSrc === 'WXSubscription' || triggerSrc === 'WXService')) {
// 已认证的公众号:同步返回
return {
Content: reply,
CreateTime: Math.floor(Date.now() / 1000),
FromUserName: callbackData.toUserName,
ToUserName: callbackData.fromUserName,
MsgType: 'text',
};
} else {
// 未认证或小程序/微信客服:异步发送
await this.tools.sendWxMessage({
toUser: callbackData.fromUserName || callbackData.externalUserId,
content: reply,
triggerSrc,
});
return {};
}
}
/**
* 生成 AI 回复
*/
async generateReply(userMessage) {
// 这里实现你的 AI 回复逻辑
// 可以调用大模型、知识库等
const result = await this.tools.chat({
messages: [{ role: 'user', content: userMessage }],
});
return result.content;
}
}
exports.main = function (event, context) {
return BotRunner.run(event, context, new MyBot(context));
};
步骤 3:处理不同平台的消息
根据 triggerSrc 区分不同平台,进行差异化处理:
class MyBot extends BotCore {
async wxSendMessage(input) {
const { callbackData, triggerSrc, wxVerify } = input;
switch (triggerSrc) {
case 'WXMiniapp':
return this.handleMiniappMessage(callbackData);
case 'WXSubscription':
return this.handleSubscriptionMessage(callbackData, wxVerify);
case 'WXService':
return this.handleServiceMessage(callbackData, wxVerify);
case 'WXCustomerService':
return this.handleWorkWxMessage(callbackData);
default:
console.log('未知消息来源:', triggerSrc);
return {};
}
}
// 处理小程序客服消息(始终异步)
async handleMiniappMessage(data) {
const reply = await this.generateReply(data.content);
await this.tools.sendWxMessage({
toUser: data.fromUserName,
content: reply,
triggerSrc: 'WXMiniapp',
});
return {};
}
// 处理订阅号消息
async handleSubscriptionMessage(data, wxVerify) {
const reply = await this.generateReply(data.content);
if (wxVerify) {
// 已认证:同步返回
return {
Content: reply,
CreateTime: Math.floor(Date.now() / 1000),
FromUserName: data.toUserName,
ToUserName: data.fromUserName,
MsgType: 'text',
};
} else {
// 未认证:异步发送
await this.tools.sendWxMessage({
toUser: data.fromUserName,
content: reply,
triggerSrc: 'WXSubscription',
});
return {};
}
}
// 处理服务号消息
async handleServiceMessage(data, wxVerify) {
// 逻辑与订阅号类似
return this.handleSubscriptionMessage(data, wxVerify);
}
// 处理微信客服消息(始终异步)
async handleWorkWxMessage(data) {
const reply = await this.generateReply(data.text.content);
await this.tools.sendWxMessage({
toUser: data.externalUserId,
content: reply,
triggerSrc: 'WXCustomerService',
openKfId: data.openKfId,
});
return {};
}
}
完整示例
结合 BotCore 的聊天记录功能
const { BotCore, BotRunner } = require("@cloudbase/aiagent-framework");
class MyBot extends BotCore {
async wxSendMessage(input) {
const { callbackData, triggerSrc, wxVerify } = input;
// 获取用户消息
const userMessage = this.extractMessage(callbackData);
const userId = callbackData.fromUserName || callbackData.externalUserId;
// 创建聊天记录对
const { updateBotRecord } = await this.createRecordPair({
userContent: userMessage,
});
// 获取历史消息用于上下文
const history = await this.getHistoryMessages({ size: 10 });
// 调用大模型
const reply = await this.tools.chat({
messages: [
...history,
{ role: 'user', content: userMessage },
],
});
// 更新 Bot 记录
await updateBotRecord({ content: reply.content });
// 返回或发送消息
if (wxVerify && (triggerSrc === 'WXSubscription' || triggerSrc === 'WXService')) {
return {
Content: reply.content,
CreateTime: Math.floor(Date.now() / 1000),
FromUserName: callbackData.toUserName,
ToUserName: callbackData.fromUserName,
MsgType: 'text',
};
} else {
await this.tools.sendWxMessage({
toUser: userId,
content: reply.content,
triggerSrc,
openKfId: callbackData.openKfId,
});
return {};
}
}
extractMessage(data) {
if (data.content) return data.content;
if (data.text?.content) return data.text.content;
return '';
}
}
exports.main = function (event, context) {
return BotRunner.run(event, context, new MyBot(context));
};
部署
完成代码开发后,将函数部署到云函数或云托管:
- 在云开发控制台创建函数型云托管服务
- 上传代码并部署
- 在云开发 AI 控制台关联 Agent 与服务
注意事项
1. 超时处理
微信平台对消息回复有时间限制:
- 公众号:5 秒内需返回响应,否则微信会重试
- 小程序/微信客服:采用异步模式,无严格时间限制
建议对于复杂的 AI 处理,统一使用异步模式发送消息。
2. 消息去重
微信可能会重复推送同一条消息,建议根据 msgId 进行去重:
async wxSendMessage(input) {
const { callbackData } = input;
// 检查是否已处理过
const processed = await this.checkMessageProcessed(callbackData.msgId);
if (processed) {
return {}; // 已处理,直接返回
}
// 标记为已处理
await this.markMessageProcessed(callbackData.msgId);
// 继续处理消息...
}
3. 回复长度限制
微信对单条消息有长度限制(约 2000 字符),对于较长的 AI 回复,建议:
- 分段发送
- 提示用户发送「继续」获取后续内容
- 在提示词中限制回复长度