WhatsApp¶
概述¶
WhatsApp Channel通过WhatsApp Business API接入,支持Cloud API和On-Premises API。
官方文档: https://developers.facebook.com/docs/whatsapp
接入方式: WhatsApp Business Account + Access Token
API版本: Cloud API v19.0 / On-Premises API v2.57.2
支持消息类型: 文本、图片、文档、音频、视频、位置、模板消息
配置参数¶
Config 结构体¶
type Config struct {
PhoneNumberID string // 电话号码ID
AccessToken string // 访问令牌
AppSecret string // 应用密钥(用于Webhook验证)
VerifyToken string // 验证令牌(用于Webhook验证)
WebhookURL string // Webhook地址
BusinessAccountID string // 商业账号ID(可选)
}
参数详细说明¶
| 参数名 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
phone_number_id |
string | 是 | - | WhatsApp电话号码ID |
access_token |
string | 是 | - | Facebook永久访问令牌 |
app_secret |
string | 否 | "" | Facebook应用密钥 |
verify_token |
string | 否 | "" | Webhook验证令牌 |
webhook_url |
string | 否 | "" | Webhook接收地址 |
business_account_id |
string | 否 | "" | WhatsApp商业账号ID |
phonenumberid¶
- 数据类型:
string - 格式: 数字字符串,如
123456789012345 - 获取方式:
- 登录Facebook开发者控制台
- 进入WhatsApp应用 → API设置
- 找到"电话号码ID"
access_token¶
- 数据类型:
string - 格式: 长字符串,如
EAAB... - 获取方式:
- 在Facebook开发者控制台生成
- 必须是永久令牌(System User Token)
- 需要
whatsapp_business_messaging权限
app_secret¶
- 数据类型:
string - 用途: 验证Webhook请求的签名
- 获取方式: Facebook应用设置 → 基本 → 应用密钥
verify_token¶
- 数据类型:
string - 用途: Webhook订阅验证
- 要求: 任意字符串,与Facebook后台配置一致
完整配置示例¶
YAML配置¶
channels:
- name: whatsapp-business
type: whatsapp
config:
phone_number_id: "123456789012345"
access_token: "EAABxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
app_secret: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
verify_token: "your-verify-token"
webhook_url: "https://your-domain.com/webhook/whatsapp"
business_account_id: "1234567890123456"
Go代码配置¶
import (
"github.com/example/gort/pkg/channel/whatsapp"
)
config := whatsapp.Config{
PhoneNumberID: "123456789012345",
AccessToken: "EAABxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
AppSecret: "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
VerifyToken: "your-verify-token",
WebhookURL: "https://your-domain.com/webhook/whatsapp",
BusinessAccountID: "1234567890123456",
}
ch, err := whatsapp.NewWhatsAppChannel("whatsapp-business", config)
if err != nil {
log.Fatal(err)
}
功能支持¶
消息类型¶
| 消息类型 | 支持状态 | 说明 |
|---|---|---|
| 文本消息 | ✅ | 普通文本 |
| 图片消息 | ✅ | 支持URL或file_id |
| 文档消息 | ✅ | 任意文件类型 |
| 音频消息 | ✅ | 语音消息 |
| 视频消息 | ✅ | 视频文件 |
| 位置消息 | ✅ | 地理位置 |
| 模板消息 | ✅ | 需要预批准模板 |
能力矩阵¶
GetCapabilities() 返回:
- TextMessages: true
- MarkdownMessages: false
- ImageMessages: true
- FileMessages: true
- AudioMessages: true
- VideoMessages: true
- LocationMessages: true
- TemplateMessages: true
- ReadReceipts: false
- TypingIndicators: false
前置要求¶
1. Facebook开发者账号¶
- 需要有效的Facebook开发者账号
- 需要验证的企业身份
2. WhatsApp Business Account¶
- 创建WhatsApp商业账号
- 添加并验证电话号码
- 完成商业验证流程
3. 权限申请¶
需要申请以下权限:
- whatsapp_business_messaging
- whatsapp_business_management
常见配置问题¶
问题1: 电话号码ID无效¶
现象: API返回"Invalid phone number ID"
原因: - PhoneNumberID错误 - 电话号码未验证
解决:
问题2: Access Token无效¶
现象: 返回"Invalid OAuth 2.0 access token"
原因: - Token过期 - 缺少必要权限
解决:
1. 生成新的永久Token
2. 确保包含 whatsapp_business_messaging 权限
问题3: 超出服务窗口¶
现象: 返回"Message failed to send because more than 24 hours have passed"
原因: 用户24小时内未发送消息
解决: - 使用预批准的模板消息 - 引导用户先发送消息
发送消息示例¶
发送文本消息¶
msg := &message.Message{
ID: "msg-1",
ChannelID: "whatsapp-business",
Direction: message.DirectionOutbound,
To: message.UserInfo{ID: "1234567890"}, // 电话号码
Content: "Hello WhatsApp!",
Type: message.MessageTypeText,
}
err := ch.SendMessage(ctx, msg)
发送模板消息¶
msg := &message.Message{
ID: "msg-2",
ChannelID: "whatsapp-business",
Direction: message.DirectionOutbound,
To: message.UserInfo{ID: "1234567890"},
Content: "template_name",
Type: message.MessageTypeTemplate,
}
msg.SetMetadata("language_code", "zh_CN")
msg.SetMetadata("parameters", map[string]string{
"1": "参数1",
"2": "参数2",
})
err := ch.SendMessage(ctx, msg)
安全建议¶
- Token保护: Access Token具有长期有效性,请妥善保管
- Webhook验证: 使用AppSecret验证Webhook签名
- HTTPS强制: Webhook必须使用HTTPS
- 权限最小化: 只申请必要的权限
错误代码参考¶
| 错误 | 说明 |
|---|---|
ErrPhoneNumberIDEmpty |
缺少电话号码ID |
ErrAccessTokenEmpty |
缺少访问令牌 |
ErrInvalidSignature |
Webhook签名验证失败 |
ErrTemplateNotApproved |
模板未通过审核 |
ErrOutsideServiceWindow |
超出24小时服务窗口 |