如何在 `Node aws-sdk` sendRawEmail 函数中发送 PDF 附件?

Posted

技术标签:

【中文标题】如何在 `Node aws-sdk` sendRawEmail 函数中发送 PDF 附件?【英文标题】:How can send PDF attachment in `Node aws-sdk` sendRawEmail function? 【发布时间】:2018-08-28 02:03:43 【问题描述】:

我想使用 sendRawEmail(Node: aws-sdk) 功能在附件中发送 PDF 文件,我尝试了很多方法,电子邮件发送成功,但 PDF 变得简单。 请更正我的代码并帮助解决它。

代码在这里:

try 
    data = fs.readFileSync('files/demo-invoice-new.pdf', 'utf8');

    console.log(data.toString());

    var ses_mail = "From: 'AWS SES Attchament Configuration' <" + SOURCE_EMAIL + ">\n";
    ses_mail = ses_mail + "To: " + toEmail + "\n";
    ses_mail = ses_mail + "Subject: AWS SES Attachment Example\n";
    ses_mail = ses_mail + "MIME-Version: 1.0\n";
    ses_mail = ses_mail + "Content-Type: multipart/mixed; boundary=\"NextPart\"\n\n";
    ses_mail = ses_mail + "--NextPart\n";
    ses_mail = ses_mail + "Content-Type: text/html; charset=us-ascii\n\n";
    ses_mail = ses_mail + "This is the body of the email.\n\n";
    ses_mail = ses_mail + "--NextPart\n";
    ses_mail = ses_mail + "Content-Type: application/octet;\n";
    ses_mail = ses_mail + "Content-Disposition: attachment; filename=\"demo-invoice-new.pdf\"\n\n";
    ses_mail = ses_mail + data.toString('utf8') + "\n\n";
    ses_mail = ses_mail + "--NextPart--";

    var params = 
        RawMessage:  Data: new Buffer(ses_mail) ,
        Destinations: [toEmail],
        Source: "'AWS SES Attchament Configuration' <" + SOURCE_EMAIL + ">'"
    ;

    console.log(params);

    var sendPromise = new AWS.SES(AWS_SES_CONFIG).sendRawEmail(params).promise();

    return sendPromise.then(
        data => 
            console.log(data);
            return data;
        ).catch(
        err => 
            console.error(err.message);
            throw err;
        );
 catch (e) 
    console.log('Error:', e.stack);

【问题讨论】:

【参考方案1】:

您好,对于偶然发现此问题的任何人,我设法使用 nodemailer 和 SESV2 解决了它,我有 base64 编码数据,因此您的脚本可能与我的有点不同,但下面的 sn-p 应该会给您一个想法...这是我的解决方案,希望对某人有所帮助:

const MailComposer = require("nodemailer/lib/mail-composer");
const AWS = require("aws-sdk");

const generateRawMailData = (message) => 
    let mailOptions = 
        from: message.fromEmail,
        to: message.to,
        subject: message.subject,
        text: message.bodyTxt,
        html: message.bodyHtml,
        attachments: message.attachments.map(a => ( filename: a.name, content: a.data, encoding: 'base64' ))
    ;
    return new MailComposer(mailOptions).compile().build();
;

const exampleSendEmail = async () => 
    var message = 
        fromEmail: "sender@server.com",
        to: "receiver@sender.com",
        subject: "Message title",
        bodyTxt: "Plaintext version of the message",
        bodyHtml: "<p>HTML version of the message</p>",
        attachments: [
            name: 'hello.txt',
            data: 'aGVsbG8gd29ybGQ='
        ]
    ;

    let ses = new AWS.SESV2(),
    params = 
      Content:  Raw:  Data: await generateRawMailData(message)  ,
      Destination: 
        ToAddresses: message.to,
        BccAddresses: message.bcc,
      ,
      FromEmailAddress: message.fromEmail,
      ReplyToAddresses: message.replyTo,
    ;

  return ses.sendEmail(params).promise();

【讨论】:

【参考方案2】:

SES 原始消息must be base64-encoded。因此,您需要将文件内容作为缓冲区并将其编码为 base64 字符串附件。此外,您不需要为原始消息数据创建新缓冲区,因为它已经接受字符串数据类型。

可选:您也可以省略Destinations 参数,因为您已经在原始消息数据中提供了To 字段。 (您也可以提供CcBcc 字段)

你可以试试这个例如:

data = fs.readFileSync("files/demo-invoice-new.pdf");

var ses_mail = "From: 'AWS SES Attchament Configuration' <" + SOURCE_EMAIL + ">\n";
ses_mail += "To: " + toEmail + "\n";
ses_mail += "Subject: AWS SES Attachment Example\n";
ses_mail += "MIME-Version: 1.0\n";
ses_mail += "Content-Type: multipart/mixed; boundary=\"NextPart\"\n\n";
ses_mail += "--NextPart\n";
ses_mail += "Content-Type: text/html\n\n";
ses_mail += "This is the body of the email.\n\n";
ses_mail += "--NextPart\n";
ses_mail += "Content-Type: application/octet-stream; name=\"demo-invoice-new.pdf\"\n";
ses_mail += "Content-Transfer-Encoding: base64\n";
ses_mail += "Content-Disposition: attachment\n\n";
ses_mail += data.toString("base64").replace(/([^\0]76)/g, "$1\n") + "\n\n";
ses_mail += "--NextPart--";

var params = 
    RawMessage: Data: ses_mail,
    Source: "'AWS SES Attchament Configuration' <" + SOURCE_EMAIL + ">'"
;

注意/([^\0]76)/ 正则表达式替换会中断您的长行,以确保邮件服务器不会在存在编码附件时抱怨邮件行太长,这可能会导致瞬态反弹。 (见RFC 5321)

【讨论】:

如果在 AWS API 请求中省略 Destinations 参数,它将响应 400 Bad request 错误。我想说这个参数可以为空,因为提供了收件人、抄送和密送电子邮件地址。

以上是关于如何在 `Node aws-sdk` sendRawEmail 函数中发送 PDF 附件?的主要内容,如果未能解决你的问题,请参考以下文章

如何从 CloudFoundry 向 AWS-sdk 提供凭证

连接到 AWS-SDK 时的 Node.js 303 永久重定向

如何在 lambda 函数中包含 javascript aws-sdk?

为啥我在 s3 上的访问被拒绝(使用适用于 Node.js 的 aws-sdk)?

缺少依赖项:./node_modules/node-pre-gyp/lib/info.js 中的 aws-sdk

bcrypt,将../node_modules/node-pre-gyp/lib/publish.js中的错误序列化:未找到模块:错误:无法解析'aws-sdk'