跳到主要内容

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

字段类型说明
callbackDataWeChatTextInput | WeChatVoiceInput | WeChatWorkTextInput | WeChatWorkVoiceInput微信回调消息数据
triggerSrcstring消息来源:WXSubscription(订阅号)、WXService(服务号)、WXMiniapp(小程序)、WXCustomerService(微信客服)
wxVerifyboolean微信 AppId 的认证状态

WeChatTextInput(公众号/小程序文本消息)

字段类型说明
contentstring消息内容
createTimenumber消息创建时间
fromUserNamestring发送者 OpenId
toUserNamestring接收者
msgIdstring消息 ID
msgTypestring消息类型

WeChatVoiceInput(公众号/小程序语音消息)

字段类型说明
formatstring语音格式
mediaIdstring语音媒体 ID
createTimenumber消息创建时间
fromUserNamestring发送者 OpenId
toUserNamestring接收者
msgIdstring消息 ID
msgTypestring消息类型

WeChatWorkTextInput(微信客服文本消息)

字段类型说明
externalUserIdstring外部用户 ID
openKfIdstring客服 ID
originnumber消息来源
sendTimenumber发送时间
msgIdstring消息 ID
msgTypestring消息类型
text.contentstring消息内容

WeChatWorkVoiceInput(微信客服语音消息)

字段类型说明
externalUserIdstring外部用户 ID
openKfIdstring客服 ID
originnumber消息来源
sendTimenumber发送时间
msgIdstring消息 ID
msgTypestring消息类型
voice.mediaIdstring语音媒体 ID

返回参数

WeChatTextOutput

对于已认证的公众号,需要返回同步回复消息:

字段类型说明
Contentstring回复内容
CreateTimenumber创建时间戳
FromUserNamestring发送方(公众号)
ToUserNamestring接收方(用户)
MsgTypestring消息类型,固定为 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));
};

部署

完成代码开发后,将函数部署到云函数或云托管:

  1. 在云开发控制台创建函数型云托管服务
  2. 上传代码并部署
  3. 在云开发 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 回复,建议:

  • 分段发送
  • 提示用户发送「继续」获取后续内容
  • 在提示词中限制回复长度