загрузите вложение изображения .jpg по почте с помощью AWS SES из node.js

Ниже приведен код из http://github(How%20to%20use%20aws%20ses), где есть пример для отправки и отправки по электронной почте с вложением,

Я изменил код, чтобы получить файл изображения из aws s3 и отправить его по почте в виде вложения, когда я сделал это для текстового файла, он работал отлично, но когда я отправил изображение, по почте я не смог увидеть изображение, так как оно повреждено.

когда я попытался открыть приложение для фотографий Apple, он показал, что метаданные отсутствуют, также я добавил Content-Transfer-Encoding: base64 в заголовок сообщения, когда я попытался использовать utf8, utf-8 и UTF-8 в < strong> 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);
});

person Murali Krishna    schedule 14.03.2017    source источник
comment
Незначительное улучшение - new Buffer(string) теперь устарело, поэтому код, в котором он используется, можно было бы заменить на Buffer.from(string)   -  person Sunil Kumar    schedule 04.12.2020


Ответы (2)


Во-первых, ваше сообщение MIME плохо отформатировано. Последняя строка должна быть --NextPart--, а не просто --NextPart.

Вы также должны преобразовать массив data.Body в его строковое представление base64, используя new Buffer(data.Body).toString('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 += new Buffer(data.Body).toString('base64');
ses_mail += "--NextPart--";

Затем вы можете передать строку ses_mail как необработанные данные сообщения как RawMessage: { Data: ses_mail } вместо RawMessage: { Data: new Buffer(ses_mail) }.

person Khalid T.    schedule 14.03.2017
comment
+1, отличная работа, не могли бы вы упомянуть, почему я должен использовать только base64, а не другие, это хорошо, даже если вы объясните вещи на низком уровне, я не могу обернуть кодировку вокруг моей головы - person Murali Krishna; 14.03.2017
comment
Потому что нам нужно строковое представление данных изображения, которое будет объединено с вашей строковой переменной ses_mail. Думаю, вам будет интересно прочитать это. - person Khalid T.; 14.03.2017

Другой способ решить эту проблему - передать параметр MailOptions вашего nodemailer (встроенные вложения изображений cid: aadhar и все остальное) в композитор nodemailer, создавая для вас такие данные буфера:

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, чтобы минимизировать сложность ответа. Не стесняйтесь заключить вызов сборки в обещание и async / wait для данных вашего буфера, которые затем можно передать вашему ses.sendRawEmail методу отдельно.

person Stephen Isienyi    schedule 14.01.2021