如何在AWS SES+Lambda+CloudWatch定时邮件中附加S3文件并指定附件名
Python版本附件名异常问题修复
问题根因
错误出在这两行代码:
fileObj = s3.get_object( Key=object_name, Bucket='testing') key = str(fileObj)
s3.get_object返回的是S3接口的响应对象,直接转字符串后是包含响应元数据的无序内容,后续用os.path.basename(key)拿到的自然是无效的随机字符串,直接导致附件名异常。
修复方案
删掉无效的文件名生成逻辑,直接用已知的object_name作为文件名即可,修改后的相关代码段如下:
# 删掉原来的key = str(fileObj)、file_name = os.path.basename(key)两行 tmp_file_name = '/tmp/TEST.pdf' s3.download_file(bucket_name, object_name, tmp_file_name) ATTACHMENT= tmp_file_name # 后续设置附件头的时候直接指定文件名 att.add_header('Content-Disposition','attachment',filename='TEST.pdf')
修改后附件名就会正常显示为TEST.pdf。
Node.js版本定时发送S3最新附件功能实现
实现逻辑
- 调用
s3.listObjectsV2接口获取指定桶内的所有对象,按LastModified时间倒序排序,取第一个就是最新上传的文件 - 下载最新文件到Lambda临时目录
/tmp - 改用SES的
sendRawEmail接口发送带附件的MIME格式邮件,用nodemailer库简化邮件构造(需要先把nodemailer加入依赖打包上传到Lambda)
完整修改后的代码
const AWS = require('aws-sdk'); const nodemailer = require('nodemailer'); const fs = require('fs'); const path = require('path'); AWS.config.update({ region: 'eu-west-2' }) const ses = new AWS.SES(); const s3 = new AWS.S3(); // 替换为你的S3桶名 const S3_BUCKET = '你的S3桶名称'; exports.handler = async (event) => { try { // 1. 获取S3桶内最新文件 const listRes = await s3.listObjectsV2({ Bucket: S3_BUCKET }).promise(); const sortedFiles = listRes.Contents.sort((a,b) => b.LastModified - a.LastModified); const latestFile = sortedFiles[0]; const latestFileName = latestFile.Key; // 2. 下载最新文件到临时目录 const fileRes = await s3.getObject({ Bucket: S3_BUCKET, Key: latestFileName }).promise(); const tmpFilePath = path.join('/tmp', latestFileName); fs.writeFileSync(tmpFilePath, fileRes.Body); // 3. 构造带附件的邮件 let transporter = nodemailer.createTransport({ SES: ses }); const mailOptions = { from: 'xyz@xyz.com', to: 'abc@abc.com', subject: 'Daily Email', text: 'Hello: \n\n Good Morning: Here is your 9am Alert!!! \n\n', attachments: [ { filename: latestFileName, path: tmpFilePath } ] }; // 4. 发送邮件 await transporter.sendMail(mailOptions); console.log('Successfully sent email with latest S3 attachment!!!'); } catch (error) { console.error('An error occured: ', error); throw error; } };
注意事项
- Lambda执行角色需要添加S3桶的
s3:ListBucket、s3:GetObject权限 - 打包代码前先安装nodemailer依赖:
npm install nodemailer
内容的提问来源于stack exchange,提问作者Riz Kler
相关产品推荐
相关产品推荐

