使用来自 node.js 的 AWS SES 在邮件中上传 .jpg 图像附件

Posted

技术标签:

【中文标题】使用来自 node.js 的 AWS SES 在邮件中上传 .jpg 图像附件【英文标题】:upload .jpg image attachment in mail using AWS SES from node.js 【发布时间】:2017-08-04 12:33:06 【问题描述】:

以下是来自https://github.com/andrewpuch/aws-ses-node-js-examples 的代码,其中有一个发送和发送电子邮件的示例,带有附件,

我已经修改了代码以从 aws s3 获取图像文件并将其与邮件作为附件一起发送,当我为文本文件执行此操作时,它工作得很好,但是当我发送图像时,我在邮件中由于图像已损坏,因此无法查看。

当我尝试使用苹果照片应用程序打开时,它显示元数据丢失,当我尝试使用 utf8、utf-8 和 UTF- 时,我还在邮件标题中添加了 Content-Transfer-Encoding: base64 8 in Content-Transfer-Encoding在标题中我从aws得到以下响应


  "message": "Unknown encoding: utf8",
  "code": "InvalidParameterValue",
  "time": "2017-03-14T08:42:43.571Z",
  "requestId": "2e220c33-0892-11e7-8a5a-1114bbc28c3e",
  "statusCode": 400,
  "retryable": false,
  "retryDelay": 29.798455792479217

我修改后的代码用邮件发送图像附件,我什至尝试将缓冲区编码为 utf-8,base-64,在这上面浪费了足够的时间,不知道为什么它被破坏了,如果有人以前这样做过,帮帮我

// Require objects.
var express = require('express');
var app = express();
var aws = require('aws-sdk');

// Edit this with YOUR email address.
var email = "*******@gmail.com";

// Load your AWS credentials and try to instantiate the object.
aws.config.loadFromPath(__dirname + '/config.json');

// Instantiate SES.
var ses = new aws.SES();
var s3 = new aws.S3();

// Verify email addresses.
app.get('/verify', function (req, res) 
    var params = 
        EmailAddress: email
    ;

    ses.verifyEmailAddress(params, function (err, data) 
        if (err) 
            res.send(err);
        
        else 
            res.send(data);
        
    );
);

// Listing the verified email addresses.
app.get('/list', function (req, res) 
    ses.listVerifiedEmailAddresses(function (err, data) 
        if (err) 
            res.send(err);
        
        else 
            res.send(data);
        
    );
);

// Deleting verified email addresses.
app.get('/delete', function (req, res) 
    var params = 
        EmailAddress: email
    ;

    ses.deleteVerifiedEmailAddress(params, function (err, data) 
        if (err) 
            res.send(err);
        
        else 
            res.send(data);
        
    );
);

// Sending RAW email including an attachment.
app.get('/send', function (req, res) 
    var params =  Bucket: 's3mailattachments', Key: 'aadhar.jpg' ;
    var attachmentData;
    s3.getObject(params, function (err, data) 
        if (err)
            console.log(err, err.stack); // an error occurred
        else 
            console.log(data.ContentLength);
            console.log(data.ContentType);
            console.log(data.Body);
            var ses_mail = "From: 'AWS Tutorial Series' <" + email + ">\n";
            ses_mail = ses_mail + "To: " + email + "\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: image/jpeg; \n";
            ses_mail = ses_mail + "Content-Disposition: attachment; filename=\"aadhar.jpg\"\n";
            ses_mail = ses_mail + "Content-Transfer-Encoding: base64\n\n"
            ses_mail = ses_mail + data.Body;
            ses_mail = ses_mail + "--NextPart";


            var params = 
                RawMessage:  Data: new Buffer(ses_mail) ,
                Destinations: [email],
                Source: "'AWS Tutorial Series' <" + email + ">'"
            ;

            ses.sendRawEmail(params, function (err, data) 
                if (err) 
                    res.send(err);
                
                else 
                    res.send(data);
                
            );

        
    );
);

// Start server.
var server = app.listen(3003, function () 
    var host = server.address().address;
    var port = server.address().port;

    console.log('AWS SES example app listening at http://%s:%s', host, port);
);

【问题讨论】:

一个小的改进 - new Buffer(string) 现在已弃用,因此使用它的代码可以替换为 Buffer.from(string) 【参考方案1】:

首先,您的 MIME 消息格式不正确。最后一行应该是--NextPart-- 而不仅仅是--NextPart

您还应该使用Buffer.from(data.Body).toString('base64')data.Body 数组转换为其base64 字符串表示,如下所示:

var ses_mail = "From: 'AWS Tutorial Series' <" + email + ">\n";
ses_mail += "To: " + email + "\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; charset=us-ascii\n\n";
ses_mail += "This is the body of the email.\n\n";
ses_mail += "--NextPart\n";
ses_mail += "Content-Type: image/jpeg; \n";
ses_mail += "Content-Disposition: attachment; filename=\"aadhar.jpg\"\n";
ses_mail += "Content-Transfer-Encoding: base64\n\n"
ses_mail += Buffer.from(data.Body).toString('base64');
ses_mail += "--NextPart--";

然后,您可以将ses_mail 字符串作为原始消息数据传递为RawMessage: Data: ses_mail ,而不是RawMessage: Data: new Buffer(ses_mail)

【讨论】:

+1,干得好,你能不能提一下为什么我应该只使用base64而不是其他的,即使你在低级别解释这些东西也很好,我无法将编码的东西包裹在我的周围头 因为我们需要将与您的ses_mail 字符串变量连接的图像数据的字符串表示形式。我想你会有兴趣阅读this。【参考方案2】:

解决此问题的另一种方法是将您的 nodemailer MailOptions 参数(内联图像附件 cid:aadhar 和所有)传递给 nodemailer composer 为您生成缓冲区数据,如下所示:

import MailComposer from 'nodemailer/lib/mail-composer';

new MailComposer( mailOptions )
    .compile()
    .build(( err, Data ) => 
        if( err !== null ) 
            process.stderr.write( err ); // for example
            return;
        
        ses.sendRawEmail(
            RawMessage: 
                Data
            
        );
    );

Ps:我正在使用笨重的callback 技术来最小化答案的复杂性。随意将构建调用包装在一个 Promise 中并 async/wait 您的缓冲区数据,然后您可以将这些数据分别传递给您的 ses.sendRawEmail 方法。

【讨论】:

以上是关于使用来自 node.js 的 AWS SES 在邮件中上传 .jpg 图像附件的主要内容,如果未能解决你的问题,请参考以下文章

通过 aws ses 在 node.js 中发送带有附件的邮件

如何使用 node.js 动态设置 aws ses TemplateData?

Node.Js AWS SES - 发送电子邮件时的 ETIMEDOUT

AWS SES PHP SDK 请求需要来自经过验证的域?

Ruby/node.js + Amazon SES:是不是有 Amazon SES API?

Node.js Nodemailer 和 SES - 错误:未定义传输方法