【Node.js】Amazon SESで添付ファイル付きメールを送信する

2021.03.30

吉川@広島です。

Node.js で SES を使った添付ファイル付きメール送信の検証をしたので共有します。

サンプルコード

今回のサンプルを GitHub リポジトリに置きました。

dyoshikawa/aws-ses-node-with-file-sample

sendEmail と sendRawEmail

aws-sdk-js を使って SES メール送信をしたい場合に、まず選択肢に上がってくるのは sendEmail でしょう。
下記に公式のサンプルコードも紹介されています。

使用した E メールの送信Amazon SES

しかし、 sendEmail ではファイル添付はできないようです。
そのため、 sendRawEmail を使う必要があります。

以下は公式の SendRawEmail についてのドキュメントより引用です。

Amazon SES API を使用して raw E メールを送信する

SMTP プロトコルはもともと 7 ビット ASCII 文字のみを含む E メールメッセージを送信するように設計されていました。この仕様により、ASCII 以外のテキストエンコード (Unicode など)、バイナリコンテンツ、または添付ファイルでは SMTP が不十分になります。多目的インターネットメール拡張‎ (MIME) 標準は、SMTP を使用して、他の多くの種類のコンテンツを送信できるようにするために開発されたものです。

MIME 標準には、メッセージ本文を複数のパートに分割し、パートごとに、どのような操作を行うかを指定する機能があります。たとえば、E メールメッセージ本文の、あるパートはプレーンテキスト、別のパートは HTML という場合があります。さらに、 MIME では、E メールメッセージに 1 つ以上の添付ファイルを含めることができます。メッセージの受取人は、E メールクライアント内から添付ファイルを見たり、保存したりできます。

sendRawEmail を nodemailer 越しに使う

で、どう使うかですが、 APIリファレンス では、

 var params = {
  Destinations: [
  ], 
  FromArn: "", 
  RawMessage: {
   Data: <Binary String>
  }, 
  ReturnPathArn: "", 
  Source: "", 
  SourceArn: ""
 };

このようなサンプルコードが示されています。
この中の Data に決まった書式の文字列でメールの内容を指定する必要があるようです。

先程も紹介した SendRawEmail のドキュメントにその例と説明がありますが、これを自前で構築する処理を書くのはなかなか大変に思えます。
このへんを良い感じにやってくれるラッパーを使いたいですよね。

Amazon SES で添付ファイル付きメールを送る

こちらの記事では mailcomposer というパッケージが紹介されているのですが、確認すると Archive 状態になっていました。
npmtrends で類似パッケージを調べたところ、今だと nodemaiiler を使うのが良さそうでした。
mailcomposer と同じ開発者が関わっているので後継なのかもしれません。

nodemailer に SES TRANSPORT という機能が用意されているのでありがたく使わせてもらいましょう。

SES TRANSPORT :: Nodemailer

というわけで、以下のコードで添付ファイル付きメールの送信の動作確認ができました。

import AWS from 'aws-sdk'
import * as dotenv from 'dotenv' // AWS アクセスキーなどをセットするための dotenv
import nodemailer from 'nodemailer'

const main = async () => {
  dotenv.config()

  const transporter = nodemailer.createTransport({
    SES: new AWS.SES({ apiVersion: '2010-12-01', region: 'ap-northeast-1' }), // SESインスタンスを渡す
  })

  const result = await transporter.sendMail({
    from: 'test@example.com', // テスト用メールアドレス
    to: 'test@example.com', // テスト用メールアドレス
    subject: 'タイトル',
    text: '本文',
    attachments: [ // ここで添付ファイルを指定する
      {
        filename: 'sample.png', // 任意
        path: './sample.png',  // 実際に指定した位置にファイルを配置する
      },
    ],
  })

  console.log(result.messageId)
}

main()

テスト用メールアドレスは下記の手順で検証する必要があります。

Amazon SESによるメール送信環境の構築と実践 送信元の確認

以上、参考になれば幸いです。

関連記事

Python版実装は下記で紹介しています。

LambdaからSESで画像付きのメールを送信する