You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过Webhook获取SendGrid C#邮件的投递/退信状态?

问题分析与解决方案

为什么发送响应里拿不到投递/退信状态

SendGrid的SendEmailAsync返回的响应仅表示邮件已成功提交到SendGrid的发送队列,并不代表最终投递结果。邮件的投递、退信、打开等状态都是异步发生的,SendGrid会通过配置的Event Webhook将这些事件推送到你的指定URL,而非在发送请求的响应中返回。

另外你代码中设置了msg.SetBypassBounceManagement(true),这个配置会跳过SendGrid的退信管理机制,可能导致退信事件无法正常触发。如果需要获取退信状态,建议移除该行(默认就是false)。

如何通过Webhook接收投递状态

1. 创建接收Webhook的API端点(以ASP.NET Core为例)

你需要在自己的服务中创建一个公开可访问的POST接口,用于接收SendGrid推送的事件数据:

using Microsoft.AspNetCore.Mvc;
using SendGrid.Helpers.EventWebhook;

[ApiController]
[Route("api/sendgrid/webhook")]
public class SendGridWebhookController : ControllerBase
{
    // 从SendGrid后台获取的Webhook签名密钥,用于验证请求合法性
    private readonly string _webhookSigningSecret = "你的签名密钥";

    [HttpPost]
    public IActionResult ReceiveWebhookEvents()
    {
        // 验证请求是否来自SendGrid(可选但强烈推荐)
        var isValidRequest = EventWebhookUtility.VerifySignature(
            Request.Headers,
            Request.Body,
            _webhookSigningSecret,
            300); // 允许的时间误差(秒)

        if (!isValidRequest)
        {
            return Unauthorized();
        }

        // 重置请求流(验证时已读取过)
        Request.Body.Position = 0;

        // 解析SendGrid推送的事件列表
        var events = EventWebhookUtility.ParseEvents(Request.Body);

        // 逐个处理不同类型的事件
        foreach (var evt in events)
        {
            switch (evt.EventType)
            {
                case "delivered":
                    HandleDelivered(evt);
                    break;
                case "bounced":
                    HandleBounced(evt);
                    break;
                case "dropped":
                    HandleDropped(evt);
                    break;
                case "opened":
                    HandleOpened(evt);
                    break;
                // 可扩展处理click、spamreport等其他事件
            }
        }

        // 返回200确认接收,SendGrid会停止重试推送
        return Ok();
    }

    private void HandleDelivered(Event evt)
    {
        var toEmail = evt.Email;
        var deliveryTime = evt.Timestamp;
        // 此处可将投递状态存入数据库或触发业务逻辑
    }

    private void HandleBounced(Event evt)
    {
        var toEmail = evt.Email;
        var bounceReason = evt.Reason;
        var bounceCode = evt.Status;
        // 处理退信逻辑,比如标记收件邮箱为无效
    }

    private void HandleDropped(Event evt)
    {
        var toEmail = evt.Email;
        var dropReason = evt.Reason;
        // 处理邮件被丢弃的情况(如地址无效、被反垃圾系统拦截)
    }

    private void HandleOpened(Event evt)
    {
        var toEmail = evt.Email;
        var openTime = evt.Timestamp;
        // 处理邮件打开统计逻辑
    }
}

2. 关键配置注意事项

  • 签名验证:在SendGrid后台的Event Webhook设置中开启"Sign Webhook Requests",获取签名密钥后加入代码验证,防止伪造请求。
  • 事件类型勾选:在SendGrid后台配置Webhook时,必须勾选需要接收的事件类型(如Bounce、Delivered、Dropped),否则对应事件不会被推送。
  • 公网可访问性:你的Webhook URL必须能被公网访问,本地开发可使用ngrok等工具将本地端口映射到公网。

3. 调整发送代码

移除退信管理跳过设置,确保SendGrid能正常处理退信事件:

// 移除此行,或改为SetBypassBounceManagement(false)
// msg.SetBypassBounceManagement(true);

总结

  1. SendGrid发送响应仅代表邮件提交成功,投递状态需通过Event Webhook异步获取。
  2. 创建公开API端点接收并解析Webhook事件,根据事件类型处理对应业务逻辑。
  3. 确保SendGrid后台配置正确的事件类型和签名验证,调整发送代码中的退信管理设置。

内容的提问来源于stack exchange,提问作者Kranthi Vardhan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 19:37:37