ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

AWS 文档示例库中的 Amazon SES v2 优惠券周刊邮件场景:从联系人列表到模板化群发的完整实践指南

AWS 文档示例库中的 Amazon SES v2 优惠券周刊邮件场景:从联系人列表到模板化群发的完整实践指南 示例工程教程后端【免费下载链接】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 文档示例仓库aws-doc-sdk-examples中的 SES v2 Coupon Newsletter 场景 为核心完整讲解如何利用 Amazon Simple Email Service (SES) v2 构建一套订阅征集 → 欢迎邮件 → 模板化优惠券群发 → 监控复盘 → 资源清理的邮件营销闭环。读完本文你将掌握CreateContactList、CreateContact、ListContacts、SendEmailSimple 与 Template 两种格式等 SES v2 核心 API 的调用方式、错误处理约定、沙箱限速策略以及基于 RFC 5233 子地址plus addressing的免骚扰测试方案并能在 Java、Python、Rust、.NET 四套官方 SDK 实现中直接复用。场景概述五个阶段构成的邮件营销闭环该场景README.md演示了如何用 Amazon SES v2 向一组联系人发送优惠券周刊官方 SPECIFICATION.md 将其拆解为五个可独立执行、可测试的阶段Prepare the Application准备应用为发件/回复邮箱地址创建已验证的邮件身份email identity创建联系人列表contact list用于存储订阅者。Gather Subscriber Email Addresses收集订阅者让订阅者提供邮箱地址完成订阅向每位新订阅者发送欢迎邮件。Send the Coupon Newsletter发送优惠券周刊创建优惠券周刊邮件模板获取联系人列表中的订阅者使用模板向每位订阅者逐封发送邮件在邮件中加入退订链接Unsubscribe links与退订头Unsubscribe headers遵循批量邮件最佳实践。Monitor and Review监控与复盘在 AWS 控制台查看本次营销活动的仪表盘与指标。特别提醒由于本场景通过子地址复用最少的邮箱数量来展示 SES 联系人列表特性邮件服务商很可能会将测试邮件标记为 Spam因此需要检查垃圾邮件文件夹以确认邮件确实发出。Clean up清理删除模板删除联系人列表可选删除发件人已验证邮箱身份。这一流程被dotnetv3/SESv2/NewsLetterWorkflow/Sesv2Scenario/NewsletterWorkflow.cs中的注释精确复述参见 NewsletterWorkflow.cs可以作为跨语言实现的统一行为契约。前置条件根据 README.md 的 Prerequisites 一节运行本场景前需要AWS 账户具备使用 Amazon SES v2 的权限可选已验证的邮件身份域名或邮箱地址用于发件地址。若不存在场景运行时会自动创建可选当账户处于 SES 沙箱时已验证的目标地址。该地址不会被场景自动创建需要提前在 SES 控制台完成验证。值得注意的是SES 沙箱账户默认只能发送到已验证地址且发送速率受限。因此场景源码中专门在发送邮件之间加入了节流延迟详见后文沙箱限速小节。使用的 AWS 服务与 API 动作该场景只依赖一个 AWS 服务Amazon Simple Email Service (SES) v2。README 中列出的 SES v2 API 动作及其在仓库中的对应实现位置如下API 动作用途仓库实现位置CreateEmailIdentity创建并验证发件邮箱身份newsletter.pyCreateContactList创建联系人列表newsletter.pyCreateEmailTemplate创建优惠券邮件模板newsletter.pyCreateContact向列表添加订阅者联系人newsletter.pySendEmailSimple 格式发送欢迎邮件newsletter.pyListContacts获取联系人列表中的全部订阅者newsletter.pySendEmailTemplate 格式模板化群发优惠券周刊newsletter.pyDeleteContactList删除联系人列表连带删除其中所有联系人newsletter.pyDeleteEmailTemplate删除邮件模板newsletter.pyDeleteEmailIdentity可选删除发件邮箱身份newsletter.pyPython 端完整动作清单还可参见 sesv2 目录 README 的 Single actions 一节。阶段一准备应用创建身份、列表与模板SPECIFICATION.md的 Prepare the Application 一节详细定义了本阶段的三个操作及其参数、错误约定三个步骤均遵循已存在则跳过AlreadyExistsException可安全忽略的幂等设计。1. 创建邮件身份CreateEmailIdentity参数EmailIdentity取用户提供的已验证邮箱错误约定AlreadyExistsException身份已存在跳过并继续下一步NotFoundException身份不存在场景失败并提示用户提供的邮箱未验证LimitExceededException邮箱身份数量达到上限场景失败并提示。Python 实现通过捕获ClientError并判断错误码实现幂等逻辑newsletter.pytry: self.ses_client.create_email_identity(EmailIdentityself.verified_email) print(fEmail identity {self.verified_email} created successfully.) except ClientError as e: # If the email identity already exists, skip and proceed if e.response[Error][Code] AlreadyExistsException: print(fEmail identity {self.verified_email} already exists.) else: raise e在沙箱环境中用户需要点击验证邮件中的链接完成验证之后才能作为发件地址使用。2. 创建联系人列表CreateContactList参数ContactListName固定为weekly-coupons-newsletter错误约定AlreadyExistsException列表已存在则跳过LimitExceededException达到联系人列表数量上限则场景失败。3. 创建邮件模板CreateEmailTemplate参数TemplateName固定为weekly-couponsTemplateContentSubjectWeekly Coupons NewsletterHtml读取coupon-newsletter.html文件内容Text读取coupon-newsletter.txt文件内容模板中必须包含退订链接使用占位符{{amazonSESUnsubscribeUrl}}错误约定AlreadyExistsException跳过、LimitExceededException失败。Python 实现见 newsletter.py模板的 HTML 与纯文本内容通过load_file_content辅助函数从本地文件读取。阶段二收集订阅者子地址变体与欢迎邮件RFC 5233 子地址plus addressing测试方案这一阶段的核心技巧是子地址扩展subaddress extensions即 RFC 5233 定义的 plus addressing在邮箱本地部分插入后缀例如把userexample.com扩展为userses-weekly-newsletter-1example.com userses-weekly-newsletter-2example.com userses-weekly-newsletter-3example.com这样只需一个真实收件箱即可创建 3 个不同的联系人用于演示 SES 联系人列表的完整功能同时将测试所需的真实邮箱数量降到最低这也是 README 提醒邮件可能被标记为 Spam的原因——同一域下的子地址批量接收在邮件服务商眼中形似群发垃圾邮件。Python 中生成变体的函数get_subaddress_variants按第一个0x40拆分本地部分与域名部分newsletter.pydef get_subaddress_variants(base_email, num_variants): user_part, domain_part base_email.split() variants [ f{user_part}ses-weekly-newsletter-{i}{domain_part} for i in range(1, num_variants 1) ] return variants.NET 实现NewsletterWorkflow.cs采用同样的Split()拼接逻辑。Java 实现位于 NewsletterWorkflow.java。为每个变体创建联系人并发送欢迎邮件对每个子地址变体执行两步CreateContact将邮箱加入weekly-coupons-newsletter联系人列表。参数为ContactListName与EmailAddressAlreadyExistsException表示该联系人已存在跳过即可。SendEmailSimple 格式发送欢迎邮件参数如下见 SPECIFICATION.mdFromEmailAddress使用阶段一获取的verified_emailDestination.ToAddresses当前生成的子地址变体Content.Simple.Subject.DataWelcome to the Weekly Coupons NewsletterContent.Simple.Body.Text.Data读取welcome.txt文件Content.Simple.Body.Html.Data读取welcome.html文件。Python 中 Simple 格式的完整调用newsletter.pyself.ses_client.send_email( FromEmailAddressself.verified_email, Destination{ToAddresses: [email]}, Content{ Simple: { Subject: {Data: Welcome to the Weekly Coupons Newsletter}, Body: { Text: {Data: welcome_text}, Html: {Data: welcome_html}, }, } }, )沙箱限速源码注释明确说明# 1 email per second in sandbox mode, remove in production.因此每次发送后sleep(1.1)秒newsletter.py。规范文档要求沙箱模式下每封邮件间隔 2 秒.NET 实现使用await Task.Delay(2000)NewsletterWorkflow.cs。若账户已移出沙箱生产模式可移除该延迟。阶段三发送优惠券周刊模板化群发1. 获取联系人ListContacts调用ListContacts参数ContactListName为weekly-coupons-newsletter。若抛NotFoundException说明联系人列表不存在场景失败并提示newsletter.py。2. 逐封发送模板邮件SendEmail Template对列表中的每一个联系人单独调用一次SendEmail这是跟踪送达与退订的前提切勿批量ToAddresses参数如下Destination.ToAddresses取自ListContacts响应中的单个邮箱Content.Template.TemplateNameweekly-couponsContent.Template.TemplateData一个 JSON 字符串包含唯一键coupons其值为优惠券对象数组每个对象含唯一键details结构见sample_coupons.jsonFromEmailAddress阶段一的已验证邮箱ListManagementOptions.ContactListNameweekly-coupons-newsletter用于正确填充退订头Unsubscribe headers与模板中的{{amazonSESUnsubscribeUrl}}值。Python 实现newsletter.pyself.ses_client.send_email( FromEmailAddressself.verified_email, Destination{ToAddresses: [email_address]}, Content{ Template: { TemplateName: TEMPLATE_NAME, TemplateData: coupon_items, } }, ListManagementOptions{ContactListName: CONTACT_LIST_NAME}, ).NET 实现同样强调为使用联系人列表进行列表管理每次仅向一个地址发送NewsletterWorkflow.cs。SendEmail 的典型错误处理规范文档要求对以下错误给出明确的失败提示错误码含义场景行为AccountSuspendedException账户被暂停失败提示用户账户已暂停MailFromDomainNotVerifiedException发件域名未验证失败提示发件域名未验证MessageRejected邮件内容无效被拒失败提示消息内容无效SendingPausedException账户发送被暂停失败提示发送当前暂停Python 的send_coupon_newsletter通过print_error输出错误信息后继续处理下一联系人newsletter.py。模板渲染机制Mustache 风格占位符模板文件 coupon-newsletter.html 使用 SES 支持的 Mustache 风格模板语法将TemplateData中的 JSON 数据渲染进邮件ul {{#each coupons}} li{{details}}/li {{/each}} /ul{{#each coupons}}遍历coupons数组{{details}}输出每个元素的details字段纯文本版本 coupon-newsletter.txt 使用相同语法输出项目符号列表。邮件末尾通过{{amazonSESUnsubscribeUrl}}渲染由 SES 根据ListManagementOptions.ContactListName自动生成的退订链接pa href{{amazonSESUnsubscribeUrl}}Unsubscribe/a/p纯文本版本对应Unsubscribe: {{amazonSESUnsubscribeUrl}}优惠券数据样例sample_coupons.jsonTemplateData的 JSON 结构定义在 sample_coupons.json{ coupons: [ { details: 20% off on all electronics }, { details: Buy one, get one free on books }, { details: 15% off on home appliances }, { details: Free shipping on orders over $50 }, { details: 25% off on outdoor gear }, { details: 10% off on groceries } ] }阶段四监控与复盘场景运行到该阶段会打印提示引导用户前往 AWS 控制台的 SES Homepagehttps://console.aws.amazon.com/ses/home查看账户级仪表盘、发送指标与邮件活动数据然后等待用户按键继续。Python 实现见monitor_and_review方法newsletter.py.NET 版本还会尝试在交互模式下用默认浏览器直接打开控制台页面NewsletterWorkflow.cs。阶段五资源清理清理顺序固定且所有删除操作都遵循不存在则跳过NotFoundException可安全忽略DeleteContactList删除联系人列表。注意该操作会连带删除列表内的全部联系人无需逐个调用删除联系人 API见 SPECIFICATION.mdDeleteEmailTemplate删除weekly-coupons模板DeleteEmailIdentity可选删除邮箱身份前必须询问用户因为重新验证邮箱需要额外操作。Python 实现见clean_up方法newsletter.py删除身份前通过input(Do you want to delete the email identity? (y/n) )征询用户意见。仓库中的多语言实现与测试佐证该场景在仓库中实现了四套语言版本README 的 Implementations 一节Javajavav2/example_code/ses/README.md核心实现为 NewsletterWorkflow.javaPythonpython/example_code/sesv2/README.md核心实现为 newsletter.py运行命令python newsletter_scenario/newsletter.pyRustrustv1/examples/ses/README.md源码位于rustv1/examples/ses/src/newsletter.rs.NETdotnetv3/SESv2/README.md核心实现为 NewsletterWorkflow.cs在含.sln的目录执行dotnet run即可运行。各实现共享一组资源文件统一存放在 scenarios/features/sesv2_weekly_mailer/resources 目录welcome.html/welcome.txt欢迎邮件 HTML 与纯文本内容coupon-newsletter.html/coupon-newsletter.txt优惠券周刊模板的 HTML 与纯文本内容sample_coupons.json模板变量数据。运行时需要把这些文件复制到实现项目的资源目录。例如 Java 实现注释要求从scenarios/features/sesv2_weekly_mailer/resources复制到项目的resources/coupon_newsletter目录见 NewsletterWorkflow.javaPython README 则要求复制到newsletter_scenario所在目录。测试方面Python 提供了完整的单元测试 newsletter_test.py覆盖了各阶段的主要路径与错误分支prepare_application成功、身份已存在、NotFoundException、LimitExceededExceptiongather_subscriber_email_addresses成功、联系人已存在跳过、MessageRejected发送失败send_coupon_newsletter成功、联系人列表不存在、单封发送失败但不中断整体流程clean_up成功、各删除目标不存在时跳过。例如测试test_send_coupon_newsletter_error_send_email_failed验证了一封失败不影响其余联系人继续发送的行为newsletter_test.py。Java 端对应测试位于 NewsletterWorkflowTest.java。运行建议与注意事项在 SES 沙箱中运行时目标地址必须预先验证且发送速率受限请保留 1~2 秒的邮件间隔移到生产环境后应移除节流延迟以提升吞吐。权限遵循最小化原则仅授予本场景所需的最小 IAM 权限避免过度授权。成本提示运行该场景含测试可能产生 AWS 费用建议使用 Free Tier 或在确认行为后再执行完整流程。退订合规模板中的{{amazonSESUnsubscribeUrl}}与ListManagementOptions.ContactListName组合是 SES 自动处理退订、遵循批量邮件最佳实践的关键务必保留不要硬编码退订链接。测试辅助资源场景的生成过程文档含各步骤内容与样本文件说明保存在 scenarios/features/sesv2_weekly_mailer/content 目录可作为编写类似工作流的参考蓝本。通过本场景读者可以完整掌握基于 SES v2 联系人列表与模板引擎搭建订阅制邮件系统的标准套路用CreateEmailIdentity建立可信发件身份、用CreateContactList/CreateContact管理订阅者、用SendEmail的 Simple/Template 双格式分别发送欢迎邮件与个性化群发并依托ListManagementOptions自动获得退订能力——这正是规模化、合规化邮件运营所需的最小可复用骨架。Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. SPDX-License-Identifier: Apache-2.0赞分享示例工程教程后端【免费下载链接】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 .NET 构建 Amazon SES v2 优惠券新闻邮件工作流从联系人列表到模板化群发使用 AWS SDK for .NET 构建 Amazon SES v2 优惠券新闻邮件工作流从联系人列表到模板化群发 Amazon SES v2 API 是示例工程教程后端基于 Amazon SES v2 构建周度优惠券订阅邮件工作流从联系人群组到模板化群发的完整实战指南基于 Amazon SES v2 构建周度优惠券订阅邮件工作流从联系人群组到模板化群发的完整实战指南 导读本文以 AWS 代码示例仓库aws doc sd示例工程教程后端Amazon SES v2 周度优惠券订阅邮件工作流从联系列表、邮件模板到取消订阅的完整实现指南Amazon SES v2 周度优惠券订阅邮件工作流从联系列表、邮件模板到取消订阅的完整实现指南 本文基于 aws doc sdk examples 仓库中示例工程教程后端创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表