SendGrid Webhook无法接收多收件人邮件事件问题求助
这是个很常见的SendGrid Webhook问题,我来帮你拆解可能的原因和对应的解决办法:
可能的原因及解决方案
1. 未正确处理批量事件请求
SendGrid针对多收件人场景,不会给每个事件单独发起请求,而是会把多个事件打包成一个JSON数组发送给你的Webhook。你当前的代码直接对$data做json_decode,如果返回的是数组(批量事件),但你没有做遍历处理,就会误以为只收到了少量事件。
修复后的示例代码:
// 读取请求体数据 $data = file_get_contents('php://input'); // 转成关联数组,方便遍历处理批量事件 $events = json_decode($data, true); // 遍历所有事件进行处理 if (is_array($events)) { foreach ($events as $event) { // 这里可以把事件写入日志、数据库,或者做其他业务逻辑 error_log(print_r($event, true)); } }
2. 服务器超时或并发限制
当发送给5个收件人时,SendGrid可能同时发起多个Webhook请求,或者批量请求的体积更大。如果你的服务器处理速度慢、超时时间设置过短,或者有并发连接限制,就会导致部分请求无法被正常接收。
检查与优化方向:
- 查看服务器的
php.ini配置,确认max_execution_time(至少设为30秒以上)、post_max_size(建议10M以上)、upload_max_filesize是否足够。 - 检查服务器防火墙、安全组或CDN的请求频率限制,是否拦截了SendGrid的重复请求。
- 可以先返回200响应再处理事件,避免SendGrid因等待响应超时放弃重试:
// 先返回200状态码,告知SendGrid已收到请求 http_response_code(200); // 再异步处理事件数据(比如写入队列,后续再消费) $data = file_get_contents('php://input'); // ...后续处理逻辑
3. 未返回正确的响应状态码
SendGrid要求Webhook必须返回2xx系列状态码(比如200),如果你的脚本因为JSON解析失败、数据库写入错误等问题返回了4xx/5xx状态码,SendGrid会重试几次,但重试失败后就不会再发送该事件了。
验证与排查方法:
- 在脚本中加入错误日志,记录所有接收的数据和可能的错误:
error_log("Received Webhook data: " . $data); $events = json_decode($data, true); if (json_last_error() !== JSON_ERROR_NONE) { error_log("JSON解析错误: " . json_last_error_msg()); }
- 用Postman等工具模拟发送批量事件请求,检查脚本是否稳定返回200状态码。
4. php://input读取限制
在部分PHP配置或服务器环境(比如FastCGI)下,php://input可能存在无法读取、或只能读取一次的问题,导致部分事件数据丢失。
优化读取逻辑:
$data = file_get_contents('php://input'); if ($data === false) { error_log("读取php://input失败"); http_response_code(500); exit; }
内容的提问来源于stack exchange,提问作者Gowri




