nodemailer icon indicating copy to clipboard operation
nodemailer copied to clipboard

SESv2 Support with AWS SDK v3

Open adamprescott opened this issue 3 years ago • 50 comments

Just wondering if there are any plans to add SESv2 Support with the v3 SDK?

If not, I'll have a go at submitting a PR to update ses-transport to detect the use of the V2 API with the V3 SDK.

My current work-around is this:

const Nodemailer = require('nodemailer');
const aws = require('@aws-sdk/client-sesv2');

class SendRawEmailCommand extends aws.SendEmailCommand{
	constructor(params) {
		const input = {
			Content: {
				Raw: {
					Data: params.RawMessage.Data
				}
			},
			FromEmailAddress: params.Source,
			Destination: {
				ToAddresses: params.Destinations
			},
		};
		super(input);
	}
}

const sesClient = new aws.SESv2({
	region: process.env.AWS_REGION,
	credentials: {
		accessKeyId: process.env.SES_ACCESS_KEY_ID,
		secretAccessKey: process.env.SES_SECRET_ACCESS_KEY,
	}
});

const transport = Nodemailer.createTransport({
	SES: {
		ses: sesClient,
		aws: {
			SendRawEmailCommand: SendRawEmailCommand
		}
	}
});

// transport.sendMail....etc...

adamprescott avatar Jun 27 '22 17:06 adamprescott

Is there any benefit in using client-sesv2 instead of client-ses? I don't have any plans to work on it myself, but if it is something that's really required, you could make a PR for it.

andris9 avatar Jul 06 '22 11:07 andris9

The SES v2 API supports e-mail messages up to 40MB in size. The v1 API only supports 10MB. There's also support for Contact Lists, Suppression List Management and the Deliverability Dashboard.

I'll have a go at forking the project and adding it in with updated tests 👍

adamprescott avatar Jul 06 '22 11:07 adamprescott

This issue is stale because it has been open for 30 days with no activity.

github-actions[bot] avatar Aug 06 '22 02:08 github-actions[bot]

any update on this? thanks

ezalorsara avatar Aug 08 '22 05:08 ezalorsara

any updates?

dyaacov avatar Aug 14 '22 04:08 dyaacov

Still on my todo list, I'll pick it up this Thursday and submit the PR 👍

  • [ ] Update the logical check here https://github.com/nodemailer/nodemailer/blob/master/lib/ses-transport/index.js#L262
  • [ ] and make sure the data gets mutated into the v2 API format show in original comment
  • [ ] Add new test(s) in here https://github.com/nodemailer/nodemailer/blob/master/test/ses-transport/ses-transport-test.js

adamprescott avatar Aug 15 '22 09:08 adamprescott

This works for me:

import AWS from 'aws-sdk';
const MailComposer = require('nodemailer/lib/mail-composer');
import fs from 'fs';
const Mustache = require('mustache');

const ses = new AWS.SESV2({
  apiVersion: '2019-09-27',
  accessKeyId: process.env.AWS_ACCESS_KEY,
  secretAccessKey: process.env.AWS_SECRET_ACCESS_KEY,
  region: process.env.AWS_REGION,
});

const isProduction = process.env.NODE_ENV === 'production';

const xxxTemplate = fs.readFileSync(`${__dirname}/xxx.template.html`, 'utf8').toString();

const generateRawMailData = (message) => {
  let mailOptions = {
    subject: message.subject,
    html: message.bodyHtml,
    attachments: message.attachments,
  };
  return new MailComposer(mailOptions).compile().build();
};

export default class NotificationsService {
  static sendEmail = async (to, cc, bcc, subject, params, attachments = [], from = '[email protected]', templateId = 'xxx') => {
    if (!isProduction) {
      to = '[email protected]';
      cc = [];
      bcc = [];
    }
    let html = '';
    let template = xxxTemplate;
    if (params.plain) {
      html = params.body;
    } else {
      html = Mustache.render(template, { ...params });
    }

    const message = {
      subject,
      bodyHtml: html,
      attachments,
    };

    params = {
      Content: { Raw: { Data: await generateRawMailData(message) } },
      Destination: {
        ToAddresses: Array.isArray(to) ? to : [to],
        BccAddresses: Array.isArray(bcc) ? bcc : [bcc],
      },
      FromEmailAddress: from,
    };

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

dyaacov avatar Aug 15 '22 17:08 dyaacov

This issue is stale because it has been open for 30 days with no activity.

github-actions[bot] avatar Sep 15 '22 02:09 github-actions[bot]

Hi, @adamprescott

Did you have time to dive in more in the code and make some changes?

ihmpavel avatar Sep 24 '22 13:09 ihmpavel

This issue is stale because it has been open for 30 days with no activity.

github-actions[bot] avatar Oct 25 '22 02:10 github-actions[bot]

Hi team 👋 . Very much waiting for this one. Any updates?

danilo-delbusso avatar Oct 25 '22 07:10 danilo-delbusso

This issue is stale because it has been open for 30 days with no activity.

github-actions[bot] avatar Nov 26 '22 02:11 github-actions[bot]

Looking forward to this one too

ihmpavel avatar Nov 26 '22 02:11 ihmpavel

Just passing by, this would be handy 👍

miller-productions avatar Dec 27 '22 05:12 miller-productions

This issue is stale because it has been open for 30 days with no activity.

github-actions[bot] avatar Jan 27 '23 02:01 github-actions[bot]

Not stale

Sparticuz avatar Jan 27 '23 12:01 Sparticuz

Any update on this? AWS has been moving away from SES v1. We also need to support large message size.

czhao-nsrecom avatar Feb 21 '23 16:02 czhao-nsrecom

Any update on this?

richterdennis avatar Mar 10 '23 13:03 richterdennis

SESV2 and SDK V3 are very different from the old SDK. It would require a lot of changes by the authors to catch up. I am able to use the new SDK with mimetext to send email with attachment via SESV2.

import {createMimeMessage} from 'mimetext';

czhao-nsrecom avatar Mar 10 '23 14:03 czhao-nsrecom

This issue is stale because it has been open for 30 days with no activity.

github-actions[bot] avatar Apr 10 '23 01:04 github-actions[bot]

@andris9 can you add the 'pinned' label so github will stop making it stale?

Sparticuz avatar Apr 10 '23 15:04 Sparticuz

any update on this? Badly need this.

mustakimkr avatar Apr 18 '23 17:04 mustakimkr

If you can' wait, you can use a module like mimetext to compose the raw email message including the attachments (rawMessge). Then send the message with SES v3 like

   const sendEmailCommand = new SendEmailCommand({
        Content: {
            Raw: {
                Data: Buffer.from(rawMessage),
            },
        },
        Destination: {
            ToAddresses: [mailAddress],
        },
        FromEmailAddress: "[email protected]"
    });
    const response = await sesClient.send(sendEmailCommand);

You will no longer use nodemailer.

czhao-nsrecom avatar Apr 19 '23 13:04 czhao-nsrecom

This issue is stale because it has been open for 30 days with no activity.

github-actions[bot] avatar May 20 '23 01:05 github-actions[bot]

@andris9 can you add the 'pinned' label so github will stop making it stale?

doesn't seem to be working?

danilo-delbusso avatar May 22 '23 10:05 danilo-delbusso

Any news about this update?

andrefelipeschulle avatar May 22 '23 21:05 andrefelipeschulle

@andris9 can you add the 'pinned' label so github will stop making it stale?

doesn't seem to be working?

Idk, according to the GitHub action, if there is 'pinned' label, marking as stale gets skipped. I wonder if pinning the issue is different than having a label 'pinned'?

Sparticuz avatar May 23 '23 10:05 Sparticuz

based on dyaacov comment above (old sdk), this works flawlessly for sdk v3:

import { SESv2Client, SendEmailCommand } from '@aws-sdk/client-sesv2';
import MailComposer = require('nodemailer/lib/mail-composer');

const sesv2Client = new SESv2Client({ region: process.env.AWS_REGION });
/* fill the mail options as usual , my email object looks like this
    {
        "from": {"name":"Sender", "address": "[email protected]"},
        "text_body": "some text",
        "subject": "Email Subject",
        "to": [{"name":" A,B", "address":"[email protected]"}],
        "cc": [{"address":"[email protected]"},{"address":"[email protected]"}],
    }
*/
const mailOptions = {
        from: email.from,
        subject: email['subject'] ? email.subject : '',
        html: email['html_body'] ? email.html_body : '',
        text: email['text_body'] ? email.text_body : '',
        to: email['to'] ? email.to : '',
        cc: email['cc'] ? email.cc : '',
        bcc: email['bcc'] ? email.bcc : '',
        attachments: hasAttachments ? email.attachments : [],
      };

const rawMailData = await new MailComposer(mailOptions).compile().build();

const input = {
          Content: {
            Raw: { Data: rawMailData },
          },
        };
const cmd = new SendEmailCommand(input);

const resp = await sesv2Client.send(cmd);

aymanmh avatar Jun 13 '23 23:06 aymanmh

This issue is stale because it has been open for 30 days with no activity.

github-actions[bot] avatar Jul 14 '23 02:07 github-actions[bot]

This issue was closed because it has been inactive for 14 days since being marked as stale.

github-actions[bot] avatar Jul 29 '23 01:07 github-actions[bot]