Bottender项目Messenger消息发送全指南
概述
Messenger作为全球最大的即时通讯平台之一,为开发者提供了丰富的消息发送能力。Bottender框架通过统一的API抽象,让开发者能够轻松构建功能强大的Messenger聊天机器人。本文将深入探讨Bottender中Messenger消息发送的完整技术栈,涵盖从基础文本到高级模板的各种消息类型。
消息类型详解
1. 文本消息(Text Messages)
文本消息是最基础也是最常用的消息类型,适用于大多数对话场景。
// 基础文本发送
async function SendGreeting(context) {
await context.sendText('您好!欢迎使用我们的服务!');
}
// 带表情和格式的文本
async function SendFormattedText(context) {
await context.sendText('🎉 恭喜您成功完成注册!\n\n您的账户详情:\n• 用户名: user123\n• 注册时间: 2024-01-15');
}
2. 富媒体消息(Rich Media Messages)
富媒体消息包括图片、视频、音频和文件,提供更丰富的用户体验。
2.1 URL方式发送
// 通过URL发送媒体文件
async function SendMediaByURL(context) {
await context.sendImage('https://example.com/products/image1.jpg');
await context.sendVideo('https://example.com/demo/video.mp4');
await context.sendAudio('https://example.com/audio/welcome.mp3');
await context.sendFile('https://example.com/docs/manual.pdf');
}
2.2 附件ID方式发送(推荐生产环境)
// 使用Facebook缓存的附件ID
async function SendMediaByAttachmentId(context) {
await context.sendImage({ attachmentId: '1854626884821032' });
await context.sendVideo({ attachmentId: '1854626884821033' });
await context.sendAudio({ attachmentId: '1854626884821034' });
await context.sendFile({ attachmentId: '1854626884821035' });
}
2.3 流和缓冲区方式
const fs = require('fs');
// 使用文件流发送
async function SendMediaByStream(context) {
await context.sendImage(fs.createReadStream('assets/image.jpg'));
await context.sendVideo(fs.createReadStream('assets/video.mp4'));
}
// 使用缓冲区发送
async function SendMediaByBuffer(context, imageBuffer, videoBuffer) {
await context.sendImage(imageBuffer, { filename: 'product.jpg' });
await context.sendVideo(videoBuffer, { filename: 'tutorial.mp4' });
}
3. 模板消息(Template Messages)
模板消息提供结构化的交互体验,是构建复杂对话流程的关键。
3.1 通用模板(Generic Template)
async function SendProductCatalog(context) {
await context.sendGenericTemplate([
{
title: "优质咖啡豆",
imageUrl: 'https://example.com/images/coffee-beans.jpg',
subtitle: "来自哥伦比亚的精选阿拉比卡咖啡豆",
defaultAction: {
type: 'web_url',
url: 'https://example.com/products/coffee-beans',
webviewHeightRatio: 'tall',
},
buttons: [
{
type: 'postback',
title: '加入购物车',
payload: 'ADD_TO_CART_COFFEE',
},
{
type: 'web_url',
title: '查看详情',
url: 'https://example.com/products/coffee-beans/details',
}
],
},
{
title: "陶瓷咖啡杯",
imageUrl: 'https://example.com/images/coffee-cup.jpg',
subtitle: "手工制作,容量350ml",
buttons: [
{
type: 'postback',
title: '加入购物车',
payload: 'ADD_TO_CART_CUP',
}
],
}
]);
}
3.2 按钮模板(Button Template)
async function SendActionButtons(context) {
await context.sendButtonTemplate('请选择您需要的服务:', [
{
type: 'web_url',
url: 'https://example.com/booking',
title: '在线预约',
},
{
type: 'postback',
title: '客服咨询',
payload: 'CUSTOMER_SERVICE',
},
{
type: 'phone_number',
title: '电话联系',
payload: '+1234567890',
}
]);
}
3.3 收据模板(Receipt Template)
async function SendOrderConfirmation(context, orderData) {
await context.sendReceiptTemplate({
recipientName: orderData.customerName,
orderNumber: orderData.orderId,
currency: 'CNY',
paymentMethod: '微信支付',
timestamp: Math.floor(Date.now() / 1000).toString(),
elements: orderData.items.map(item => ({
title: item.name,
subtitle: item.description,
quantity: item.quantity,
price: item.price,
currency: 'CNY',
imageUrl: item.imageUrl,
})),
address: {
street1: orderData.shippingAddress.street,
city: orderData.shippingAddress.city,
postalCode: orderData.shippingAddress.postalCode,
state: orderData.shippingAddress.province,
country: 'CN',
},
summary: {
subtotal: orderData.subtotal,
shippingCost: orderData.shippingFee,
totalTax: orderData.tax,
totalCost: orderData.totalAmount,
}
});
}
3.4 媒体模板(Media Template)
async function SendMediaWithActions(context) {
await context.sendMediaTemplate([
{
mediaType: 'image',
attachmentId: '1854626884821032',
buttons: [
{
type: 'web_url',
url: 'https://example.com/promotion',
title: '立即购买',
},
{
type: 'postback',
title: '收藏商品',
payload: 'SAVE_ITEM',
}
],
}
]);
}
4. 快速回复(Quick Replies)
快速回复提供即时交互选项,引导用户进行下一步操作。
4.1 文本快速回复
async function SendTextQuickReplies(context) {
await context.sendText('请选择您感兴趣的产品类别:', {
quickReplies: [
{
contentType: 'text',
title: '📱 电子产品',
payload: 'CATEGORY_ELECTRONICS',
imageUrl: 'https://example.com/icons/electronics.png'
},
{
contentType: 'text',
title: '👕 服装鞋帽',
payload: 'CATEGORY_CLOTHING',
imageUrl: 'https://example.com/icons/clothing.png'
},
{
contentType: 'text',
title: '🏠 家居用品',
payload: 'CATEGORY_HOME',
imageUrl: 'https://example.com/icons/home.png'
}
]
});
}
4.2 用户信息快速回复
async function SendUserInfoQuickReplies(context) {
await context.sendText('为了更好的为您服务,请提供以下信息:', {
quickReplies: [
{
contentType: 'user_phone_number',
},
{
contentType: 'user_email',
}
]
});
}
5. 高级功能
5.1 个性化发送(Persona)
async function SendWithPersona(context) {
await context.sendText('您好,我是客服小助手!', {
personaId: '1234567890123456', // 预先创建的Persona ID
});
}
5.2 发送状态指示
async function SendWithTypingIndicator(context) {
// 显示"正在输入"状态
await context.sendText('正在为您查询信息...', {
delay: 2000, // 延迟2秒发送
typing: true // 显示输入指示
});
// 实际发送消息
await context.sendText('查询完成!这是您需要的信息...');
}
最佳实践
消息发送策略
错误处理和重试机制
async function sendMessageWithRetry(context, messageFunction, maxRetries = 3) {
let attempts = 0;
while (attempts < maxRetries) {
try {
await messageFunction(context);
return true;
} catch (error) {
attempts++;
console.error(`发送消息失败 (尝试 ${attempts}/${maxRetries}):`, error);
if (attempts >= maxRetries) {
// 最终失败处理
await context.sendText('抱歉,消息发送失败,请稍后重试。');
return false;
}
// 等待指数退避时间
await new Promise(resolve =>
setTimeout(resolve, Math.pow(2, attempts) * 1000)
);
}
}
}
// 使用示例
async function sendImportantMessage(context) {
await sendMessageWithRetry(context, async () => {
await context.sendText('重要通知:您的订单已发货!');
});
}
性能优化建议
-
媒体文件优化:
- 使用Attachment ID缓存常用媒体资源
- 压缩图片和视频文件大小
- 使用CDN加速媒体文件加载
-
消息批量处理:
async function sendBatchMessages(context, messages) { for (const message of messages) { await context.sendText(message); // 添加适当延迟避免速率限制 await new Promise(resolve => setTimeout(resolve, 100)); } } -
模板消息复用:
// 预定义常用模板 const commonTemplates = { welcome: { title: "欢迎使用我们的服务", imageUrl: "https://example.com/welcome.jpg", buttons: [/* ... */] }, product: { title: "产品推荐", imageUrl: "https://example.com/product.jpg", buttons: [/* ... */] } }; async function sendPredefinedTemplate(context, templateKey, data) { const template = { ...commonTemplates[templateKey], ...data }; await context.sendGenericTemplate([template]); }
速率限制和注意事项
速率限制策略
重要注意事项
-
Attachment ID作用域:Attachment ID是页面作用域的,开发环境和生产环境需要分别上传
-
消息大小限制:
- 文本消息:640个字符
- 模板消息:最多10个元素
- 快速回复:最多13个按钮
-
兼容性考虑:
- 考虑不同设备上的显示效果
- 测试各种网络条件下的加载性能
- 确保备用方案(如fallback URL)
总结
Bottender为Messenger消息发送提供了强大而灵活的API体系。通过掌握各种消息类型的特性和最佳实践,开发者可以构建出用户体验优秀、功能丰富的聊天机器人应用。关键是要根据具体业务场景选择合适的消息类型,并充分考虑性能优化和错误处理机制。
记住,良好的消息设计不仅要考虑技术实现,更要关注用户体验和对话流程的自然性。通过合理的消息结构和交互设计,可以显著提升用户满意度和转化率。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



