如何在Node.js服务器通过AWS SDK用SES发送带PDF附件的邮件
用Node.js + AWS SES发送带PDF附件的邮件(无需第三方模块)
没问题,我来帮你搞定这个需求!既然不能把S3桶设为公开,直接通过SES把PDF作为附件发送是完全可行的,而且全程只用官方AWS SDK和Node.js内置模块,不用依赖第三方工具,也不会泄露凭证。下面是具体的实现步骤:
前期准备
首先要确保两件事:
- 你的EC2实例已经通过IAM角色获得了
ses:SendEmail(或ses:SendRawEmail)的权限(这比硬编码凭证安全得多,EC2会自动获取角色权限) - 你的AWS SES已经验证了发件邮箱或域名(SES要求发件人必须经过验证,否则会拒绝发送请求)
步骤1:安装官方AWS SDK
虽然你不想用第三方模块,但AWS官方的SDK是完全可信的,直接安装SES客户端即可:
npm install @aws-sdk/client-ses
步骤2:读取EC2上的PDF文件并编码
用Node.js内置的fs模块读取本地PDF文件,然后转换成Base64编码——这是SES要求的附件格式:
const fs = require('fs').promises; const { SESClient, SendEmailCommand } = require("@aws-sdk/client-ses"); // 初始化SES客户端,EC2上配置了IAM角色的话,不需要额外传入凭证 const sesClient = new SESClient({ region: "你的AWS区域,比如us-east-1" });
步骤3:构造邮件参数并发送
这里用SendEmailCommand,它支持直接添加附件,不需要手动构造复杂的MIME消息,非常方便:
async function sendEmailWithAttachment() { // 读取PDF文件并转换为Base64编码 const pdfBuffer = await fs.readFile("/path/to/your/file.pdf"); // 替换成EC2上PDF的实际路径 const pdfBase64 = pdfBuffer.toString("base64"); // 构造邮件参数 const emailParams = { Source: "已验证的发件邮箱 <sender@yourdomain.com>", Destination: { ToAddresses: ["recipient@example.com"], // 收件人邮箱 }, Message: { Subject: { Data: "请查收附件中的PDF文件", Charset: "UTF-8", }, Body: { Text: { Data: "您好,这是您需要的PDF文档,请查看附件。", Charset: "UTF-8", }, // 如果需要HTML格式的邮件内容,可以添加Html字段 // Html: { // Data: "<p>您好,这是您需要的PDF文档,请查看附件。</p>", // Charset: "UTF-8", // } }, }, Attachments: [ { Filename: "用户手册.pdf", // 收件人看到的附件文件名 ContentType: "application/pdf", Content: pdfBase64, }, ], }; try { const response = await sesClient.send(new SendEmailCommand(emailParams)); console.log("邮件发送成功!Message ID:", response.MessageId); } catch (error) { console.error("邮件发送失败:", error); } } // 调用发送函数 sendEmailWithAttachment();
可选:使用SES模板发送带附件的邮件
如果你想用SES的邮件模板(比如统一邮件样式),可以用SendTemplatedEmailCommand,附件的添加方式和上面一致:
const { SendTemplatedEmailCommand } = require("@aws-sdk/client-ses"); async function sendTemplatedEmailWithAttachment() { const pdfBuffer = await fs.readFile("/path/to/your/file.pdf"); const pdfBase64 = pdfBuffer.toString("base64"); const templateParams = { Source: "sender@yourdomain.com", Destination: { ToAddresses: ["recipient@example.com"] }, Template: "你的SES模板名称", // 替换成你在SES中创建的模板名 TemplateData: JSON.stringify({ username: "张三" }), // 模板中的变量 Attachments: [ { Filename: "用户手册.pdf", ContentType: "application/pdf", Content: pdfBase64, }, ], }; try { const response = await sesClient.send(new SendTemplatedEmailCommand(templateParams)); console.log("模板邮件发送成功!Message ID:", response.MessageId); } catch (error) { console.error("模板邮件发送失败:", error); } }
关键注意事项
- 文件大小限制:SES对单封邮件(包括所有附件)的大小限制是10MB,确保你的PDF不超过这个上限
- Base64编码正确性:必须正确将文件Buffer转换成Base64,否则附件会损坏无法打开
- 区域匹配:SES客户端的区域要和你创建SES资源的区域一致,否则会报错
- 收件人限制:如果你的SES还在沙盒模式,只能发送给已验证的收件人邮箱,要发送给任意收件人需要升级到生产模式
这样就能完美实现你的需求了,全程没有用到第三方模块,也不需要把PDF上传到S3。
内容的提问来源于stack exchange,提问作者Yonatan Vainer
相关产品推荐
相关产品推荐

