如何通过AWS SNS向动态邮箱地址发送通知?
解决方案
AWS SNS原生的订阅机制是静态绑定端点的,无法直接根据每条消息的内容动态确定发送目标邮箱。不过可以通过以下两种方案实现你的需求,其中第一种更贴合“简便”的要求:
方案1:用Lambda作为中间层,调用SES发送邮件
虽然你提到倾向SNS方案,但如果目标邮箱是动态的(未提前订阅SNS),这是最直接的实现方式:
- 将Lambda配置为SNS主题的唯一订阅者
- Lambda收到SNS消息后,解析消息体/属性中的目标邮箱地址
- 直接调用SES的
SendEmail接口发送邮件
示例Lambda代码(Python)
import boto3 import json # 初始化SES客户端 ses_client = boto3.client('ses') def lambda_handler(event, context): # 解析SNS事件中的消息内容 sns_record = event['Records'][0]['Sns'] message_data = json.loads(sns_record['Message']) # 从消息中提取目标邮箱和邮件内容 target_email = message_data.get('target_email') email_subject = message_data.get('subject', '默认主题') email_body = message_data.get('body', '') # 调用SES发送邮件 try: response = ses_client.send_email( Source='你的已验证发件邮箱@example.com', Destination={'ToAddresses': [target_email]}, Message={ 'Subject': {'Data': email_subject}, 'Body': {'Text': {'Data': email_body}} } ) return {'statusCode': 200, 'message': '邮件发送成功', 'response': response} except Exception as e: return {'statusCode': 500, 'error': str(e)}
注意事项
- 需要在SES中验证发件邮箱(或域名)
- 给Lambda配置
ses:SendEmail的IAM权限 - 如果发送到未验证的外部邮箱,需要将SES账户从“沙箱模式”升级
方案2:基于已订阅邮箱的SNS动态发送
如果目标邮箱已经提前订阅了SNS主题(完成了确认),可以通过Lambda动态选择对应的订阅ARN发送:
- Lambda作为SNS主题的订阅者,解析消息中的目标邮箱
- 通过
list_subscriptions_by_topic接口查询该邮箱对应的订阅ARN - 调用SNS的
Publish接口,指定TargetArn为该订阅ARN发送消息
示例Lambda代码(Python)
import boto3 import json sns_client = boto3.client('sns') def lambda_handler(event, context): sns_record = event['Records'][0]['Sns'] topic_arn = sns_record['TopicArn'] message_data = json.loads(sns_record['Message']) target_email = message_data.get('target_email') message_content = message_data.get('content') # 查询当前主题下的所有订阅,找到目标邮箱对应的ARN subscriptions = sns_client.list_subscriptions_by_topic(TopicArn=topic_arn)['Subscriptions'] try: target_sub_arn = next(sub['SubscriptionArn'] for sub in subscriptions if sub['Endpoint'] == target_email) except StopIteration: return {'statusCode': 404, 'error': '目标邮箱未订阅该主题'} # 发送消息到指定订阅 response = sns_client.publish( TargetArn=target_sub_arn, Message=message_content ) return {'statusCode': 200, 'response': response}
注意事项
- 目标邮箱必须已完成SNS订阅确认
- 给Lambda配置
sns:ListSubscriptionsByTopic和sns:Publish的IAM权限
内容的提问来源于stack exchange,提问作者Mausam
相关产品推荐
相关产品推荐

