如何通过AWS Lambda将SES拦截邮件存入指定S3桶
解决SES拦截邮件同时存入指定S3桶的方案
完全可以实现这个需求,最直接的方式是在Lambda函数里完成拦截判断+存储操作,也可以配合SES规则做补充配置,具体如下:
一、Lambda函数直接实现拦截+存储
这是最高效的方案,逻辑清晰:Lambda判断邮件需要拦截时,先把邮件写入“bad”桶,再通知SES停止后续处理;无需拦截则让SES继续执行原规则存入“good”桶。
具体步骤:
- 提取原始邮件:SES传给Lambda的事件里,
event['Records'][0]['ses']['mail']['rawMessage']['data']是Base64编码的完整原始邮件内容,messageId可以作为文件名一部分,方便后续检索。 - 拦截判断:替换成你的实际逻辑(比如发件人黑名单、关键词匹配、域名过滤等)。
- 存入“bad”桶:调用S3的
put_object接口,把解码后的原始邮件写入指定桶。 - 控制SES流程:拦截时返回
{"disposition": "STOP_RULE_SET"},终止后续规则;不拦截则返回{"disposition": "CONTINUE"},继续原流程。
Python代码示例
import boto3 import base64 import os s3 = boto3.client('s3') # 用环境变量配置桶名,避免硬编码 BAD_BUCKET = os.environ.get('BAD_BUCKET_NAME', 'your-bad-bucket-name') def lambda_handler(event, context): # 解析SES事件中的邮件数据 ses_record = event['Records'][0]['ses'] raw_mail_base64 = ses_record['mail']['rawMessage必然 盖async magical | %,升级版有个 familiesuse娃子的话就会触发Lambda,这里提取邮件的发件人、邮件ID等信息 mail_id = ses_record['mail']['messageId'] sender = ses_record['mail']['source'] # 解码Base64格式的原始邮件 raw_mail = base64.b64decode(raw_mail_base64) # 示例:拦截来自特定域名的邮件,替换成你的实际拦截逻辑 need_block = 'bad-domain.com' in sender if need_block: # 将拦截的邮件存入bad桶,按邮件ID分类存储 s3.put_object( Bucket=BAD_BUCKET, Key=f"blocked-mails/{mail_id}.eml", Body=raw_mail ) # 通知SES停止后续规则处理 return {"disposition": "STOP_RULE_SET"} else: # 继续执行原SES规则流程 return {"disposition": "CONTINUE"}
权限配置注意点
- 给Lambda执行角色添加S3写入权限,策略示例:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "s3:PutObject", "Resource": "arn:aws:s3:::your-bad-bucket-name/*" } ] }
- 在SES控制台添加Lambda动作时,系统会自动:
- 创建SES调用Lambda的权限
- 配置Lambda作为SES规则的动作
无需手动额外配置这部分权限。
二、SES规则工作流的补充说明
SES规则集是按顺序执行的,如果某个动作返回STOP_RULE_SET,后续所有规则动作都会终止。
因此无法通过SES原生规则直接实现“拦截后自动存入S3”,必须通过Lambda主动完成存储操作。
如果需要做全量邮件备份,也可以调整规则顺序:
- 先添加一个规则动作,将所有邮件存入过渡桶
- 再触发Lambda判断,拦截则把过渡桶里的邮件移到bad桶,不拦截则移到good桶
不过这种方式多了一次S3存储操作,不如直接在Lambda处理高效,一般不推荐。
内容的提问来源于stack exchange,提问作者CoderSchmoder
相关产品推荐
相关产品推荐

