如何判断WhatsApp Cloud API是否可发送非模板消息
WhatsApp Cloud API 主动发送非模板消息的错误捕获方案
问题背景
在WhatsApp Cloud API中,主动发起与用户的对话时仅允许发送模板消息。但实际测试中,发送纯文本、图片等非模板消息时,API会返回成功响应,却没有真正将消息送达用户。需要在这种场景下获取明确的错误提示,而非虚假的成功反馈。
核心原因
WhatsApp Cloud API的即时响应仅代表请求已被接收,不代表消息已成功投递。当主动发送非模板消息时,消息会被系统拦截,但API不会在即时响应中返回错误,而是通过Webhook事件通知消息的最终状态。
解决方案
1. 配置Webhook接收消息状态通知
在Facebook开发者后台配置Webhook,订阅messages和message_statuses事件。当消息被拦截或投递失败时,WhatsApp会向你的Webhook地址发送包含错误信息的回调。
2. 优化PHP发送代码的错误处理
当前代码存在格式错误:使用http_build_query($data)发送JSON格式请求,这会导致数据解析异常。先修复这个问题,同时完善cURL的错误捕获逻辑:
class ApiWhatsapp { private $TOKEN = ""; private $VERSION = ""; private $PHONE_NUMBER_ID = ""; private $BUSINESS_ACCOUNT = ""; function __construct() { global $conectado; $select = "SELECT FIRST 1 * FROM IDSWHATS"; $arrayIds = $conectado->select($select); foreach ($arrayIds as $ids) { $this->TOKEN =$ids->TOKEN; $this->VERSION =$ids->VERSION; $this->PHONE_NUMBER_ID =$ids->PHONE_NUMBER_ID; $this->BUSINESS_ACCOUNT =$ids->BUSINESS_ACCOUNT; } if (!$this->TOKEN) { throw new Exception("credentials not found"); } } function sendMessageText($to, $text) { $url = 'https://graph.facebook.com/'.$this->VERSION.'/'.$this->PHONE_NUMBER_ID.'/messages'; $data = [ "messaging_product" => "whatsapp", "recipient_type" => "individual", "to" => $to, "type" => "text", "text" => [ "preview_url" => false, "body" => $text ] ]; $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_POST, true); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); // 生产环境建议开启SSL验证 curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); $headers = array( "Accept: application/json", "Content-Type: application/json", "Authorization: Bearer " . $this->TOKEN ); curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); // 修复:发送JSON字符串而非query字符串 curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data)); $resp = curl_exec($curl); // 捕获cURL请求级别的错误 if(curl_errno($curl)){ $error_msg = curl_error($curl); curl_close($curl); throw new Exception("cURL Error: " . $error_msg); } curl_close($curl); $response = json_decode($resp); // 检查API返回的显性错误(其他场景适用) if(isset($response->error)){ throw new Exception("API Error: " . $response->error->message); } return $response; } }
3. 处理Webhook回调获取投递失败信息
当消息因非模板被拦截时,Webhook会收到如下格式的状态通知:
{ "object": "whatsapp_business_account", "entry": [ { "id": "10xxxxxx", "changes": [ { "value": { "messaging_product": "whatsapp", "metadata": { "display_phone_number": "1xxxxxx", "phone_number_id": "1xxxxxx" }, "statuses": [ { "id": "wamid.HBgMNTUzMTczNTgxNDUzFQIAERgSRjM3RDYzMUUyMkY2Rjk5OTJEAA==", "status": "failed", "timestamp": "169xxxxxx", "recipient_id": "553173581453", "error": { "code": 131004, "title": "Template Required", "message": "Template message is required for first message from business." } } ] }, "field": "messages" } ] } ] }
你需要在Webhook接收脚本中解析该回调,提取错误代码和信息,用于日志记录或后续处理。
关键说明
- 即时API响应仅确认请求提交成功,消息最终状态必须通过Webhook获取。
- 主动发送非模板消息的典型错误代码为
131004,对应提示为"Template message is required for first message from business"。 - 修复代码中的JSON格式问题是基础,否则可能引发其他不可预期的错误。
内容的提问来源于stack exchange,提问作者Alan Willian Duarte
相关产品推荐
相关产品推荐

