使用 AWS SDK for .NET 构建 Amazon SES v2 优惠券新闻邮件工作流:从联系人列表到模板化群发
发布时间:2026/9/25 2:36:17来源:尧图网络
示例工程教程后端【免费下载链接】aws-doc-sdk-examplesWelcome to the AWS Code Examples Repository. This repo contains code examples used in the AWS documentation, AWS SDK Developer Guides, and more. For more information, see the Readme.md file below.项目地址https://gitcode.com/gh_mirrors/aw/aws-doc-sdk-examples点击查看免费下载Amazon SES v2 API 是 AWS 提供的可靠、可扩展且经济高效的邮件发送服务。本文基于 aws-doc-sdk-examples 仓库中dotnetv3/SESv2目录下的官方示例完整讲解如何使用 AWS SDK for .NETAWSSDK.SimpleEmailV2实现一个「优惠券新闻邮件Coupon Newsletter」端到端工作流创建邮件身份Email Identity、创建联系人列表Contact List与邮件模板Email Template、用子地址subaddress扩展模拟 3 位订阅者、发送欢迎邮件、按模板群发新闻邮件并最终清理全部资源。读完本文你将掌握 SES v2 从入门到生产级实践所需的全部核心 API 调用、参数含义与常见异常处理。示例概览与代码结构示例所在位置与文件构成本示例位于仓库的 dotnetv3/SESv2/NewsLetterWorkflow 目录核心文件如下文件作用Sesv2Scenario/SESv2Wrapper.cs对IAmazonSimpleEmailServiceV2的 9 个单项 API 调用的封装类Sesv2Scenario/NewsletterWorkflow.cs控制台应用入口串联整个五步工作流Sesv2Scenario/Sesv2Scenario.csproj项目文件声明 SDK 与依赖包Sesv2Tests/SESv2WrapperTests.cs基于 Moq xUnit 的单元测试Sesv2Tests/Sesv2Tests.csproj测试项目文件NewsLetterWorkflow.sln解决方案文件README.md工作流的独立说明文档resources/目录模板与数据的静态资源文件resources 目录下包含 5 个资源文件coupon-newsletter.html新闻邮件 HTML 模板、coupon-newsletter.txt新闻邮件纯文本模板、sample_coupons.json优惠券占位数据、welcome.html与welcome.txt欢迎邮件模板。单动作 API 与场景的划分仓库把示例分为两类单动作Single actions只调用单个服务函数本示例共 9 个CreateContactSESv2Wrapper.cs#L30CreateContactListSESv2Wrapper.cs#L74CreateEmailIdentitySESv2Wrapper.cs#L116CreateEmailTemplateSESv2Wrapper.cs#L172DeleteContactListSESv2Wrapper.cs#L223DeleteEmailIdentitySESv2Wrapper.cs#L265DeleteEmailTemplateSESv2Wrapper.cs#L307ListContactsSESv2Wrapper.cs#L344SendEmailSESv2Wrapper.cs#L381场景Scenarios在同一服务内多次调用不同函数完成一项完整任务即 NewsletterWorkflow.cs 中的新闻邮件场景。环境准备与前置条件通用前置条件运行本示例前需满足 dotnetv3/README.md 中的通用要求安装 .NET SDK示例项目目标框架为net6.0见 Sesv2Scenario.csproj。拥有 AWS 账户及具备 Amazon SES 权限的 IAM 身份。完成 AWS 凭据配置例如设置AWS_ACCESS_KEY_ID与AWS_SECRET_ACCESS_KEY环境变量或使用 AWS SDK for .NET 支持的共享凭据文件等其他认证方式。场景专属资源准备根据 NewsLetterWorkflow/README.md 的 Resources 一节可选一个已验证的邮件身份邮箱地址或域名用于发送地址。如果尚不存在工作流会在运行时自动创建并触发验证流程。可选仅当账户处于 SES 沙箱 Sandbox 时一个已验证的收件地址。此地址不会由工作流自动创建需要提前在 SES 控制台完成验证。提示SES 新账户默认处于沙箱模式只能向已验证的收件地址发送邮件且发送配额极低生产环境需提交申请解除沙箱限制。费用与权限提醒运行本代码可能产生 AWS 账户费用运行测试同样可能产生费用。建议遵循最小权限原则least privilege仅为代码授予完成任务所需的最低权限。本代码未在所有 AWS 区域经过测试请参考 AWS 区域服务可用性确认 SES v2 在目标区域的支持情况。工作流的五个核心步骤工作流定义于 NewsletterWorkflow.cs整体分五步准备应用创建已验证邮件身份、创建联系人列表、创建邮件模板。收集订阅者邮箱提示用户输入基础邮箱用子地址扩展生成 3 个变体逐个加入联系人列表并发送欢迎邮件。发送优惠券新闻邮件从联系人列表拉取全部联系人使用模板 优惠券数据逐一向每位联系人发送。监控与回顾引导用户在 AWS 控制台查看发送活动与指标。清理资源删除联系人列表连带删除其中所有联系人、删除模板、可选删除邮件身份。入口Main方法通过Host.CreateDefaultBuilder建立依赖注入容器注册IAmazonSimpleEmailServiceV2与SESv2Wrapper瞬态服务随后依次调用PrepareApplication→GatherSubscriberEmailAddresses→SendCouponNewsletter→MonitorAndReview→Cleanup。核心 API 调用逐一详解下面结合 SESv2Wrapper.cs 的源码逐一说明 9 个 API 的用法、参数与异常处理。创建邮件身份CreateEmailIdentityAsyncpublic async TaskCreateEmailIdentityResponse CreateEmailIdentityAsync(string emailIdentity) { var request new CreateEmailIdentityRequest { EmailIdentity emailIdentity }; var response await _sesClient.CreateEmailIdentityAsync(request); return response; }EmailIdentity参数可以是单个邮箱地址或整个域名传域名时会自动读取并验证该域名的 DNS 记录。返回的CreateEmailIdentityResponse包含IdentityType如EMAIL_ADDRESS等信息。创建后 SES 会向邮箱发送验证邮件或要求配置 DKIM 等 DNS 记录邮箱验证完成前发送能力受限。该方法在 SESv2Wrapper.cs#L116 中捕获并抛出AlreadyExistsException、ConcurrentModificationException、LimitExceededException、NotFoundException、TooManyRequestsException等异常。创建联系人列表CreateContactListAsyncpublic async Taskbool CreateContactListAsync(string contactListName) { var request new CreateContactListRequest { ContactListName contactListName }; var response await _sesClient.CreateContactListAsync(request); return response.HttpStatusCode HttpStatusCode.OK; }联系人列表Contact List是订阅者邮箱的集合也是实现退订管理List Management的基础。本示例使用固定名称weekly-coupons-newsletter见 NewsletterWorkflow.cs#L51。该方法在 SESv2Wrapper.cs#L74 中处理AlreadyExistsException视为成功、LimitExceededException超出列表数量上限与TooManyRequestsException。创建邮件模板CreateEmailTemplateAsyncpublic async Taskbool CreateEmailTemplateAsync(string templateName, string subject, string htmlContent, string textContent) { var request new CreateEmailTemplateRequest { TemplateName templateName, TemplateContent new EmailTemplateContent { Subject subject, Html htmlContent, Text textContent } }; var response await _sesClient.CreateEmailTemplateAsync(request); return response.HttpStatusCode HttpStatusCode.OK; }TemplateContent同时包含Subject、Html、Text三个字段纯文本与 HTML 版本可并存客户端按能力自动选择。本示例模板名为weekly-coupons主题为Weekly Coupons NewsletterNewsletterWorkflow.cs#L52-L53。模板内容从 coupon-newsletter.html 与coupon-newsletter.txt读取其中 HTML 使用 Handlebars 风格的占位符{{#each coupons}}...{{/each}}与{{details}}并预留了{{amazonSESUnsubscribeUrl}}退订链接占位符。在 SESv2Wrapper.cs#L172 中处理AlreadyExistsException、LimitExceededException、TooManyRequestsException。创建联系人CreateContactAsyncpublic async Taskbool CreateContactAsync(string emailAddress, string contactListName) { var request new CreateContactRequest { EmailAddress emailAddress, ContactListName contactListName }; var response await _sesClient.CreateContactAsync(request); return response.HttpStatusCode HttpStatusCode.OK; }将单个邮箱加入指定联系人列表。AlreadyExistsException被当作幂等成功处理返回true。在 SESv2Wrapper.cs#L30 中同时处理NotFoundException联系人列表不存在与TooManyRequestsException。列出联系人ListContactsAsyncpublic async TaskListContact ListContactsAsync(string contactListName) { var request new ListContactsRequest { ContactListName contactListName }; var response await _sesClient.ListContactsAsync(request); return response.Contacts; }返回该联系人列表下的全部Contact对象其中包含EmailAddress属性用于后续逐人发送。失败时返回空列表并打印NotFoundException/TooManyRequestsException信息SESv2Wrapper.cs#L344。发送邮件SendEmailAsync这是本示例最复杂的 APISESv2Wrapper.cs#L381支持两种发送模式public async Taskstring SendEmailAsync(string fromEmailAddress, Liststring toEmailAddresses, string? subject, string? htmlContent, string? textContent, string? templateName null, string? templateData null, string? contactListName null) { var request new SendEmailRequest { FromEmailAddress fromEmailAddress }; if (toEmailAddresses.Any()) request.Destination new Destination { ToAddresses toEmailAddresses }; // 模板发送模式 if (!string.IsNullOrEmpty(templateName)) { request.Content new EmailContent { Template new Template { TemplateName templateName, TemplateData templateData } }; } // 简单邮件发送模式 else { request.Content new EmailContent { Simple new Message { Subject new Content { Data subject }, Body new Body { Html new Content { Data htmlContent }, Text new Content { Data textContent } } } }; } // 启用联系人列表退订管理 if (!string.IsNullOrEmpty(contactListName)) request.ListManagementOptions new ListManagementOptions { ContactListName contactListName }; var response await _sesClient.SendEmailAsync(request); return response.MessageId; }参数说明FromEmailAddress发件人地址必须是已验证的邮件身份。toEmailAddresses收件人列表。若要使用联系人列表的退订管理功能一次只能发送给一个地址见 NewsletterWorkflow.cs#L287 中的注释说明。templateNametemplateData模板发送模式。TemplateData是 JSON 字符串用于填充模板占位符例如sample_coupons.json中的{coupons: [...]}数据。contactListName设置ListManagementOptionsSES 会自动在邮件中注入退订链接与退订标头List-Unsubscribe符合批量邮件最佳实践。返回值MessageId可用来在 SES 控制台追踪单封邮件的发送结果。异常处理覆盖了 SES 发送阶段的典型错误AccountSuspendedException账户被永久限制发送、MailFromDomainNotVerifiedException发件域未验证、MessageRejectedException邮件内容无效、SendingPausedException账户暂停发送、TooManyRequestsException超出发送速率限制。三个删除操作三个删除 API 结构完全对称均以HttpStatusCode HttpStatusCode.OK判定成功并各自处理NotFoundException、ConcurrentModificationException与TooManyRequestsExceptionDeleteContactListAsyncSESv2Wrapper.cs#L223删除联系人列表连带删除列表内全部联系人。DeleteEmailIdentityAsyncSESv2Wrapper.cs#L265删除已验证的邮件身份。DeleteEmailTemplateAsyncSESv2Wrapper.cs#L307删除邮件模板。场景中的关键实现细节用子地址扩展模拟多位订阅者真实场景中联系人是不同的真实用户但本示例为了演示联系人列表功能只向用户索要一个「基础邮箱」然后用子地址扩展subaddress extension生成 3 个变体NewsletterWorkflow.cs#L214-L217var baseEmailAddressParts _baseEmailAddress!.Split(); for (int i 1; i 3; i) { string emailAddress ${baseEmailAddressParts[0]}ses-weekly-newsletter-{i}{baseEmailAddressParts[1]}; await _sesv2Wrapper.CreateContactAsync(emailAddress, _contactListName); // ...发送欢迎邮件 await Task.Delay(2000); // 沙箱模式下两次发送之间等待 2 秒 }例如基础地址userexample.com会生成userses-weekly-newsletter-1example.com、userses-weekly-newsletter-2example.com、userses-weekly-newsletter-3example.com三个收件人。这利用了主流邮箱对子地址的投递语义所有子地址都会投递到同一个真实邮箱。注意README 明确提醒——由于该工作流刻意用子地址最小化真实邮箱数量来演示联系人列表特性邮件服务商很可能会将这类邮件标记为垃圾邮件请在垃圾邮件文件夹中确认邮件是否送达。沙箱模式下的发送节奏在 GatherSubscriberEmailAddresses 中每次发送欢迎邮件后调用await Task.Delay(2000)等待 2 秒。源码注释说明这是「if the account is in the SES Sandbox」的适配因为沙箱账户有严格的每秒发送速率限制。模板数据填充与退订管理发送新闻邮件时SendCouponNewsletterstring couponsData await File.ReadAllTextAsync(_resourcesFilePathLocation _couponsDataFile); foreach (var contact in contacts) { await _sesv2Wrapper.SendEmailAsync(fromEmailAddress, new Liststring { contact.EmailAddress }, null, null, null, _templateName, couponsData, _contactListName); }模板内容coupon-newsletter.html使用{{#each coupons}}遍历 sample_coupons.json 中的coupons数组为每项渲染{{details}}如「20% off on all electronics」。同时传入_contactListName启用ListManagementOptions使 SES 在邮件中自动添加退订链接和退订标头这属于批量邮件发送bulk email的最佳实践。资源文件路径工作流通过_resourcesFilePathLocation ../../../../resources/引用资源NewsletterWorkflow.cs#L61运行时需保证该相对路径可解析到NewsLetterWorkflow/resources/目录。交互式控制台体验工作流全程通过Console.ReadLine()与用户交互输入已验证邮箱、输入基础邮箱、确认是否删除邮件身份GetYesNoResponse接受y/n并通过Process.Start调用系统默认浏览器打开https://console.aws.amazon.com/ses/home供用户查看发送指标。项目配置与依赖Sesv2Scenario.csproj 中声明的关键依赖包名版本用途AWSSDK.SimpleEmailV23.7.303Amazon SES v2 API 官方 SDKAWSSDK.Extensions.NETCore.Setup3.7.300将 AWS 服务注册进 .NET 依赖注入容器Microsoft.Extensions.Hosting/DependencyInjection8.0.0宿主与依赖注入Microsoft.Extensions.Configuration(.Json)8.0.0配置加载测试项目 Sesv2Tests.csproj 使用xunit2.4.2、Moq4.20.70、Microsoft.NET.Test.Sdk17.5.0并通过Xunit.Extensions.Ordering保证测试按顺序执行。编译、运行与测试编译与运行根据 dotnetv3/README.md 的「Building and running the code examples」说明进入包含.csproj文件的目录后执行dotnet run或在 IDE 中直接运行。部分项目可能包含settings.json配置文件可在编译前按自身账户与资源修改也可以新增settings.local.json应用运行时自动加载本地设置。运行测试测试说明见 dotnetv3/README.md。测试项目位于 Sesv2Tests可在解决方案内运行dotnet test运行测试同样可能产生 AWS 账户费用。单元测试覆盖的五个阶段SESv2WrapperTests.cs 使用 Moq 模拟IAmazonSimpleEmailServiceV2接口不发起真实 AWS 调用按[Order(1)]至[Order(5)]的顺序覆盖整个工作流测试方法覆盖步骤Mock 的服务调用TestPrepareApplication准备应用CreateEmailIdentityAsync、CreateContactListAsync、CreateEmailTemplateAsyncTestGatherSubscriberEmailAddresses收集订阅者CreateContactAsync、SendEmailAsyncTestSendCouponNewsletter发送新闻邮件ListContactsAsync、SendEmailAsyncTestMonitorAndReview监控回顾无纯控制台逻辑非交互模式TestCleanup清理资源DeleteContactListAsync、DeleteEmailTemplateAsync、DeleteEmailIdentityAsync测试通过NewsletterWorkflow._sesv2Wrapper sESv2Wrapper;将 Mock 包装器注入工作流静态字段并把_verifiedEmail、_baseEmailAddress预置为testexample.com使场景各步骤可在无真实凭据的环境下被验证。与其他示例的关系及更多资源本示例是dotnetv3目录下众多服务示例之一通用构建与运行指引统一存放在 dotnetv3/README.md。若需了解传统 Amazon SES v1 的 .NET 用法可参考仓库中的 dotnetv3/SES 示例。SES v2 API 开发者指南与 API 参考详见 NewsLetterWorkflow/README.md 的 Additional resources 一节SDK for .NET 的 SES v2 命名空间为Amazon.SimpleEmailV2客户端接口IAmazonSimpleEmailServiceV2。小结本文以 dotnetv3/SESv2/README.md 为骨架结合仓库源码完整呈现了 AWS SDK for .NET 操作 Amazon SES v2 的 9 个核心 API 与一个可运行的新闻邮件场景。掌握这些内容后你可以直接复用SESv2Wrapper的封装模式快速搭建自己的邮件身份管理、联系人列表运营与模板化群发系统其中的异常处理、沙箱节奏控制与退订管理ListManagementOptions设计也是生产级邮件服务的关键参考。赞分享示例工程教程后端【免费下载链接】aws-doc-sdk-examplesWelcome to the AWS Code Examples Repository. This repo contains code examples used in the AWS documentation, AWS SDK Developer Guides, and more. For more information, see the Readme.md file below.项目地址https://gitcode.com/gh_mirrors/aw/aws-doc-sdk-examples点击查看免费下载相关推荐使用 AWS SDK for C 操作 Amazon SES从发信、模板到收件规则的全套代码示例指南使用 AWS SDK for C 操作 Amazon SES从发信、模板到收件规则的全套代码示例指南 导读 本指南基于 aws doc sdk examp示例工程教程后端使用 AWS SDK for C 构建基于 Amazon Aurora Serverless 与 Amazon SES 的 Item Tracker Web 应用使用 AWS SDK for C 构建基于 Amazon Aurora Serverless 与 Amazon SES 的 Item Tracker Web示例工程教程后端使用 Boto3AWS SDK for Python操作 Amazon SES身份验证、模板邮件、IP 过滤器与收件规则完整实战指南使用 Boto3AWS SDK for Python操作 Amazon SES身份验证、模板邮件、IP 过滤器与收件规则完整实战指南 Amazon Sim后端云原生创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
网站建设高端定制企业官网