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

在C#中发送带按钮的邮件:实现审批/驳回功能适配Gmail与Outlook

邮件内审批/驳回按钮兼容Gmail和Outlook的C#实现思路

方案一:通用HTML链接按钮(全客户端兼容)

这是最稳妥的方案,Gmail和Outlook都原生支持HTML邮件中的链接按钮,无需依赖特定客户端的扩展功能。

核心思路

  1. 后端API准备:暴露两个接口分别处理审批和驳回请求,比如:
    • POST/GET https://yourdomain.com/api/approval/approve
    • POST/GET https://yourdomain.com/api/approval/reject
      每个请求携带唯一的requestId标识审批项,同时添加签名参数(如HMAC生成的签名)防止恶意篡改。
  2. 构造HTML邮件:用带内联样式的<a>标签模拟按钮样式,链接到上述API。邮件客户端不支持外部样式表,所有样式必须写在标签内。
  3. C#发送邮件:使用MailKit(推荐,比原生System.Net.Mail更灵活)或MailMessage构造HTML格式的邮件并发送。

C#代码示例(用MailKit)

using MailKit.Net.Smtp;
using MimeKit;

var requestId = "unique-approval-request-001";
// 生成带签名的API链接(示例签名需替换为实际HMAC逻辑)
var signature = GenerateHmacSignature(requestId, "your-secret-key");
var approveUrl = $"https://yourdomain.com/api/approval/approve?requestId={requestId}&signature={signature}";
var rejectUrl = $"https://yourdomain.com/api/approval/reject?requestId={requestId}&signature={signature}";

var message = new MimeMessage();
message.From.Add(new MailboxAddress("审批系统", "approval@yourdomain.com"));
message.To.Add(new MailboxAddress("审批人", "approver@example.com"));
message.Subject = "请审批:XX项目申请";

var bodyBuilder = new BodyBuilder();
bodyBuilder.HtmlBody = $@"
<p>您好,请处理以下审批申请:</p>
<p>申请ID:{requestId}</p>
<p>
    <a href=""{approveUrl}"" style=""background: #28a745; border: none; color: white; padding: 12px 24px; text-align: center; text-decoration: none; display: inline-block; font-size: 16px; border-radius: 4px; margin-right: 10px;"">批准(Approve)</a>
    <a href=""{rejectUrl}"" style=""background: #dc3545; border: none; color: white; padding: 12px 24px; text-align: center; text-decoration: none; display: inline-block; font-size: 16px; border-radius: 4px;"">驳回(Reject)</a>
</p>";

message.Body = bodyBuilder.ToMessageBody();

// 发送邮件
using var client = new SmtpClient();
client.Connect("smtp.yourdomain.com", 587, false);
client.Authenticate("smtp-username", "smtp-password");
client.Send(message);
client.Disconnect(true);

// 辅助方法:生成HMAC签名
string GenerateHmacSignature(string requestId, string secretKey)
{
    using var hmac = new System.Security.Cryptography.HMACSHA256(System.Text.Encoding.UTF8.GetBytes(secretKey));
    var hashBytes = hmac.ComputeHash(System.Text.Encoding.UTF8.GetBytes(requestId));
    return Convert.ToBase64String(hashBytes);
}

方案二:Outlook原生按钮+Gmail降级方案

如果希望Outlook用户获得更原生的体验(按钮在邮件内直接触发请求,无需跳转浏览器),可以结合Outlook的Actionable Messages,同时给Gmail显示普通链接按钮。

核心思路

  1. Outlook Actionable Messages配置:在邮件中嵌入JSON-LD格式的Actionable Messages定义,Outlook会识别并显示原生按钮。需要提前在Microsoft 365后台验证你的域名,否则按钮会跳转到浏览器。
  2. Gmail降级处理:Gmail不支持Actionable Messages,因此同时保留HTML链接按钮,Gmail会自动忽略JSON-LD脚本,显示普通按钮。
  3. 后端API适配:支持POST请求(Actionable Messages默认用POST),并处理CORS(Outlook客户端会直接发起跨域请求)。

C#代码示例(添加Actionable Messages)

// 延续方案一的邮件构造逻辑,修改HtmlBody部分
bodyBuilder.HtmlBody = $@"
<p>您好,请处理以下审批申请:</p>
<p>申请ID:{requestId}</p>
<!-- Gmail显示的普通按钮 -->
<p>
    <a href=""{approveUrl}"" style=""background: #28a745; border: none; color: white; padding: 12px 24px; text-align: center; text-decoration: none; display: inline-block; font-size: 16px; border-radius: 4px; margin-right: 10px;"">批准(Approve)</a>
    <a href=""{rejectUrl}"" style=""background: #dc3545; border: none; color: white; padding: 12px 24px; text-align: center; text-decoration: none; display: inline-block; font-size: 16px; border-radius: 4px;"">驳回(Reject)</a>
</p>
<!-- Outlook识别的Actionable Messages -->
<script type=""application/ld+json"">
{{
    ""@context"": ""http://schema.org"",
    ""@type"": ""EmailMessage"",
    ""potentialAction"": [
        {{
            ""@type"": ""HttpActionHandler"",
            ""name"": ""批准"",
            ""url"": ""https://yourdomain.com/api/approval/approve"",
            ""method"": ""POST"",
            ""body"": ""{{\""requestId\"":\""{requestId}\""}}"",
            ""headers"": [{{""Content-Type"": ""application/json""}}]
        }},
        {{
            ""@type"": ""HttpActionHandler"",
            ""name"": ""驳回"",
            ""url"": ""https://yourdomain.com/api/approval/reject"",
            ""method"": ""POST"",
            ""body"": ""{{\""requestId\"":\""{requestId}\""}}"",
            ""headers"": [{{""Content-Type"": ""application/json""}}]
        }}
    ],
    ""description"": ""请审批该项目申请""
}}
</script>";

关键注意事项

  • 安全防护:必须对请求参数签名,防止恶意用户伪造审批请求;后端需验证签名和requestId的合法性,同时保证接口幂等(避免同一请求重复执行)。
  • 样式兼容性:所有CSS样式必须用内联方式写在标签内,避免使用类选择器或外部样式表,大部分邮件客户端不支持这些特性。
  • Outlook域名验证:使用Actionable Messages时,需在Microsoft 365 Admin Center验证你的发件域名,否则按钮会强制跳转浏览器。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 10:01:09