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


LambdaでNodemailerを使う機会があったのでメモを残します

Nodemailerとは

Node.jsで簡単にメールを送ることができるモジュールです。
公式 https://nodemailer.com/about/
npmのページ https://www.npmjs.com/package/nodemailer

やりたいこと

S3に置いているPDFファイルを添付したメールを送信する

手順

  1. メールアドレスの認証
  2. 必要な権限を付与
  3. ローカルでモジュールを準備
  4. Lambdaのコンソール画面でzipをアップロード

1. メールアドレスの認証

サンドボックス解除前のSESは、差出人や宛先に指定するメールアドレスの認証が必要です。

  1. SES Homeを開く
  2. Email Addresses > Verify a New Email Address
  3. メールアドレスを入力
  4. 「Amazon Web Services – Email Address Verification Request in region Asia Pacific (Tokyo)」というメールが届くのでメール内のリンクを踏む

2. 必要な権限を付与

  1. Lambdaの実行ロールの概要画面を開く
  2. インラインポリシーの追加
  3. SESのSendRawEmail、S3のGetObjectのアクセス許可を追加する

3. ローカルでモジュールを準備

  1. 適当なディレクトリを作成 mkdir test
  2. 初期化 npm init
  3. nodemailerインストール npm install nodemailer
  4. test/node_modulesが作られていることを確認
  5. test/index.jsを作成(中身はlambdaで動かしたいコード)
  6. node_modulesとindex.jsをまとめてzip化

4. Lambdaのコンソール画面でzipをアップロード

  1. 関数の画面を開く
  2. 「アップロード元」のリストから「.zipファイル」を選択
  3. ローカルで作成したzipファイルを指定してアップロード

今回使ったLambdaのコード

index.js
const AWS = require('aws-sdk')
const nodemailer = require('nodemailer')
const transporter = nodemailer.createTransport({
  SES: new AWS.SES({ apiVersion: '2010-12-01' }),
})
const s3 = new AWS.S3({ apiVersion: '2006-03-01' })
const fs = require('fs').promises

exports.handler = async (event) => {
  //S3に置いているPDFを/tmp配下にコピー
  const paramsForS3 = {
    Bucket: 'バケット名',
    Key: 'ファイル名',
  }
  const contents = await s3.getObject(paramsForS3).promise()
  const path = '/tmp/ファイル名'
  await fs.writeFile(path, contents.Body)

  // メール送信
  await transporter.sendMail({
    from: '差出人のメールアドレス',
    to: '宛先のメールアドレス',
    subject: 'メールの件名',
    text: 'メール本文',
    attachments: [
      {
        filename: '添付ファイル名', //元のファイル名とは別の名前で添付したい場合はここで設定(非必須項目)
        path: path,
      },
    ],
  })
}