LoginSignup
0
0

【AWS】SESを使用してメールを送信する(nodejs)

Last updated at Posted at 2022-07-03

要件

検証済みのメールアドレス、もしくは検証済みのドメインでのみメール送受信可能です。あるタイミングでアプリケーションから任意のメールアドレスへメールを送信します。

※今記事のサンプルソースは下記のgithubをご参考ください。
サンプルソース

前提

  • Route53 で登録しているドメイン名のアドレス (support@xxx.yyy.zzz) をFROMとする
  • Node.js環境
  • AWSアカウント

ドメインの認証

SESのコンソール

  1. Amazon SES コンソールを開きます。
  2. ナビゲーションペインの [Create identities]をクリックします。
  3. Identity typeのDomainを選択します。
  4. DomainはRoute53で登録済みのドメインを記入します。
  5. [Create identities]ボタンをクリックします。

nodejs

nodejs経由の場合下記のドキュメントを参考
ドメイン ID の検証

// Load the AWS SDK for Node.js
var AWS = require('aws-sdk');
// Set region 
AWS.config.update({region: 'REGION'});

// Create the promise and SES service object
var verifyDomainPromise = new AWS.SES({apiVersion: '2010-12-01'}).verifyDomainIdentity({Domain: "DOMAIN_NAME"}).promise();

// Handle promise's fulfilled/rejected states
verifyDomainPromise.then(
  function(data) {
    console.log("Verification Token: " + data.VerificationToken);
  }).catch(
    function(err) {
    console.error(err, err.stack);
  });

送信元メールアドレスの登録(From)

送信元を登録しないといけません。SESのコンソールからの登録の場合、上記のドメイン登録はほぼ同じやり方です。
nodejs経由の場合は下記のソースをご参考ください。
また、送信先について、sandboxの場合、登録しないと送信できませんが、sandboxを解除したら、Toは自由で登録しなくても送信もできます。

// Load the AWS SDK for Node.js
var AWS = require('aws-sdk');
// Set region 
AWS.config.update({region: 'REGION'});

// Create promise and SES service object
var verifyEmailPromise = new AWS.SES({apiVersion: '2010-12-01'}).verifyEmailIdentity({EmailAddress: "ADDRESS@DOMAIN.EXT"}).promise();

// Handle promise's fulfilled/rejected states
verifyEmailPromise.then(
  function(data) {
    console.log("Email verification initiated");
   }).catch(
    function(err) {
    console.error(err, err.stack);
  });

送信者名の対応

送信者名を下記のように設定したら、送信者名の設定できます。

Source: '送信者名 <mail address>'

ただし、送信者名が日本語の場合は文字化けします。
送る時は送信者名をMIMEエンコードしてSourceパラメータに入れよう。
(メールアドレスまでエンコードはしない事)
sdk: libmime
サンプルソースコード:

var awsSdk = require('aws-sdk');
var libmime = require('libmime');
AWS.config.update({region: 'ap-northeast-1'})
const ses = new AWS.SES({apiVersion: '2010-12-01'})

exports.handler = (event, context, callback) => {

    // 送信先
    var to = ['送信先メールアドレス'];
    // 送信元
    var from = '送信者メールアドレス';
    // 送信者名
    var fromName = '私がメールを送ったマン';
    
    // 送信者名 MIMEエンコード
    fromName = libmime.encodeWord(fromName, 'Q');

    from = fromName + ' <' + from + '>';

    // 件名
    var subject = 'メールタイトル';

    // 本文
    var body = '本文です。';

    // SES 送信用 パラメータ
    var params = {
        Destination: {
            ToAddresses: [to]
        },
        Message: {
            Body: {
                Text: {
                    Data: body,
                    Charset: 'utf-8'
                }
            },
            Subject: {
                Data: subject,
                Charset: 'utf-8'
            }
        },
        Source: from
    };

    var email = ses.sendEmail(params, function(err, data){
        if(!err) {
            // 成功
            callback(null, data);
        }
    });
};

キャリアメールHTMLの対応

HTMLで送信したい場合、messageのbodyをHtmlにすれば、送信できますが、キャリアメールの場合、Htmlは文字化け発生してしまいます。

   var params = {
        Destination: {
            ToAddresses: [to]
        },
        Message: {
           Body: {
              Html: {
                Data: messageBody,
                Charset: 'utf-8'
              }
            },
            Subject: {
                Data: subject,
                Charset: 'utf-8'
            }
        },
        Source: from
    };

    var email = ses.sendEmail(params, function(err, data){
        if(!err) {
            // 成功
            callback(null, data);
        }
    });

こういう場合はマルチパート配信で書き換えます。

html to text

まずはhtmlのbodyをテキスト書き換えます。html-to-textのSDKを使いと、簡単に変換できます。

    const htmlToText = require('html-to-text')
    // html-to-textを使用してHTMLをテキストに変換
    const plainText = htmlToText.htmlToText(messageBody, {
      wordwrap: true, // 改行する
      ignoreImage: true // 画像を無視
    })

マルチパート配信(sendRawEmail)

sesのsendRawEmail関数を使います。

    // テキストとHTMLメッセージを結合してMultiPartメッセージを構築
    const multiPartMessage = `From: ${fromName} <${from}>\n`
      + `To: ${toAddresses.join(', ')}\n`
      + `Subject: ${title}\n`
      + 'MIME-Version: 1.0\n'
      + 'Content-Type: multipart/alternative;\n'
      + ' boundary="----=_Part_0_1234567890"\n\n'
      + '------=_Part_0_1234567890\n'
      + `Content-Type: text/plain; charset=utf-8\n\n${plainText}\n\n`
      + '------=_Part_0_1234567890\n'
      + `Content-Type: text/html; charset=utf-8\n\n${htmlMessage}\n\n`
      + '------=_Part_0_1234567890--'

    const params = {
      RawMessage: {
        Data: multiPartMessage
      },
      Destinations: toAddresses,
      Source: `${fromName} <${from}>\n`
    }
    return new Promise(function (resolve, reject) {
      ses.sendRawEmail(params, function (err, data) {
        if (err) {
          reject(err)
        } if (data) {
          resolve(data)
        }
      })
    })

上限緩和申請

  • Amazon SES サンドボックス
    詐欺行為や不正行為防止及びISPからのSPAM認定回避のため、新規ユーザーのアカウントは、サンドボックス(検証目的の環境)に配置され、動作の一部に制限を受けます。
    送信できるのは1日あたり200通まで、1秒あたり1メッセージまで。
    アカウントをサンドボックスの外に移動する手続きを行うと、制限が解除された環境で動作します。
    手続きには 1 営業日かかるそうです。

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0