在AWS Lambda中用Python SMTP发送SES多收件人邮件的问题
在AWS Lambda中通过SES SMTP添加多个收件人(含CC)的解决方案
问题描述
在AWS Lambda中使用SES的SMTP方式发送邮件,希望给To字段添加多个邮箱地址,同时支持CC收件人。尝试合并To和CC地址为rcpt变量后,调用server.sendmail时出现以下错误:
{ "errorMessage": "'NoneType' object is not iterable", "errorType": "TypeError", "stackTrace": [ " File \"/var/task/lambda_function.py\", line 89, in lambda_handler\n server.sendmail(msg['From'], msg['rcpt'], msg.as_string())\n", " File \"/var/lang/lib/python3.8/smtplib.py\", line 889, in sendmail\n for each in to_addrs:\n" ] }
错误原因
- 代码中尝试访问
msg['rcpt'],但从未给MIMEMultipart对象设置过rcpt邮件头,导致返回None,而smtplib.sendmail需要可迭代的收件人列表。 - 原代码未正确处理
CC字段的邮件头和实际收件人列表。
解决方案
步骤1:定义多收件人地址
将To和CC设置为逗号分隔的邮箱字符串,支持多个地址:
sender = "default_01@gmail.com" to = "janedoe@gmail.com,alice@example.com" # 多个To地址用逗号分隔 cc = "johndoe@gmail.com,bob@example.com" # 多个CC地址用逗号分隔
步骤2:处理收件人列表
拆分并合并To和CC地址,同时清理可能的空格:
# 拆分地址并去除空格,避免因空格导致的无效地址 to_list = [addr.strip() for addr in to.split(",")] cc_list = [addr.strip() for addr in cc.split(",")] rcpt_list = to_list + cc_list # 合并所有收件人列表
步骤3:正确设置邮件头
给邮件添加To和CC头字段,让收件人能看到完整的收件人信息:
msg = MIMEMultipart() msg['Subject'] = "test" msg['From'] = sender msg['To'] = to # 直接用逗号分隔的字符串作为To头 msg['CC'] = cc # 添加CC头字段
步骤4:修正sendmail调用
sendmail的第二个参数需要传入所有收件人的列表(To+CC),而不是邮件头的某个字段:
server.sendmail(sender, rcpt_list, msg.as_string())
完整修正后的lambda_handler函数
def lambda_handler(event, context): data = get_data() body = build_table(data, 'blue_light') sender = "default_01@gmail.com" to = "janedoe@gmail.com,alice@example.com" cc = "johndoe@gmail.com,bob@example.com" smtphost = 'email-smtp.###############' # 处理收件人列表 to_list = [addr.strip() for addr in to.split(",")] cc_list = [addr.strip() for addr in cc.split(",")] rcpt_list = to_list + cc_list msg = MIMEMultipart() msg['Subject'] = "test" msg['From'] = sender msg['To'] = to msg['CC'] = cc body1 = """<H3>Hello, <br> Below is today's report on bucket listings""" body3 = """ <br> Please reach out to BI national ops dashboard for more information: https://test.com <br> regards, <br> BI Ops Team """ body_content = body1+body+body3 msg.attach(MIMEText(body_content, "html")) msg.attach(MIMEText(body_content, 'plain')) server = smtplib.SMTP(smtphost) server.starttls() server.login(ACCESS_KEY, SECRET_KEY) server.sendmail(sender, rcpt_list, msg.as_string()) server.quit() return("email sent successfully.")
关键说明
- SMTP协议中,
CC的实现是将邮件发送给所有To和CC地址,因此sendmail需要接收完整的收件人列表。 - 邮件头的
To和CC仅用于展示给收件人,和实际发送的地址列表是两个独立的部分,必须同时正确配置。
内容的提问来源于stack exchange,提问作者Dinho
相关产品推荐
相关产品推荐

