Amazon SES を使用してNode.jsからメールを送信する

## 背景

AWS上で公開する予定のWebアプリケーションにおいて、ユーザーアカウントのパスワードリセットなどのタイミングでアプリケーションからメールを送信したい。

### 要件

- Route53 で登録しているドメイン名のアドレス (`support@xxx.yyy.zzz`) をFROMとする
- TOは任意のメールアドレス
- Node.jsから送信する

## 1. Amazon SESのセットアップ

### SESコンソールの表示

- AWSコンソールから `Simple Email Service` を選択  
Amazon SES はアジアパシフィック（東京）リージョンでは提供されていないので、サービスメニューの **グループ** では見つからない。表示を **A-Z** に変更するか、 `SES` で検索する。

- リージョンを選択する画面が表示される。 `米国東部（バージニア北部）` を選択  
（別に米国西部でも問題ないが、どのリージョンを選んだかは後に必要になるので覚えておく）

### ドメインの認証

(すでに `Route53` でドメイン名を取得・登録している前提)

- `Identity Management` > `Domains` を選択
- `Verify a New Domain` をクリック
- Domain名を入力、`Generate DKIM Settings` にチェックを入れて `Verify This Domain` をクリック
  - `DKIM` については下記参照。DNSに `CNAME` のエントリが2つ追加される。
- メールが送信されるので、その本文のリンクをクリック
- SESのコンソールで `verified` となっていることを確認

#### DKIM: DomainKeys Identified Mail

> ドメインキー・アイデンティファイド・メール（DKIM: DomainKeys Identified Mail）とは、電子メールの認証技術である。DKIMは、署名するMail transfer agent（MTA）から検証するMTAまで、ほぼエンド・ツー・エンドの完全性を提供する。多くの場合、署名するMTAが発信者に代わりDKIM-Signatureヘッダを追加し、また検証するMTAがDNSを通じて発信者の公開鍵を検索する事で、受信者に代わり署名の正当性を立証する。
> [ドメインキー・アイデンティファイド・メール - Wikipedia](https://ja.wikipedia.org/wiki/%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E3%82%AD%E3%83%BC%E3%83%BB%E3%82%A2%E3%82%A4%E3%83%87%E3%83%B3%E3%83%86%E3%82%A3%E3%83%95%E3%82%A1%E3%82%A4%E3%83%89%E3%83%BB%E3%83%A1%E3%83%BC%E3%83%AB)

### 送信先メールアドレスの登録

上限緩和申請を行うまでは **サンドボックス環境** が使用される。
サンドボックス環境ではメールは確認済みアドレスにのみ送信可能となる。
SESのコンソールからメールアドレスを登録する

- `Identity Management` > `Email Addresses` を選択
- `Verify a New Email Address` をクリック
- 受信可能なメールアドレスを登録
- メールが送信されるので、その本文のリンクをクリック
- SESのコンソールで `verified` となっていることを確認

### テストメールの送信

Route53で登録しているドメインのメールアドレスから送信先メールアドレスにメールが送信できるか確認する。

- `Identity Management` > `Domains` を選択
- 登録したドメインの左チェックボックスをクリック
- `Send a Test Email` をクリック
- ダイアログが表示されるので、以下の情報を入力して送信
  - FROMに `@` 以前を入力 (今回は `support` とする)
  - TOに **送信先メールアドレスの登録** で登録したメールアドレスを入力
  - Subject, Bodyは適当に入力
- メールが受信できていることを確認する


## 2. IAMユーザー登録

- AWSコンソールのヘッダーメニューでログインユーザー名をクリック
- `セキュリティ認証情報` をクリック
- ダイアログが表示されるので `Get Started with IAM Users` を選択
- `ユーザーを追加` をクリック
  - ウィザードを進め、適当なロールを作成して `AmazonSESFullAccess` の権限を与える
- アクセスキー、シークレットキーをコピペしておく

### credentialsファイルの作成

- `~/.aws/credentials` ファイルを作成する  
  **IAMユーザー登録** でメモしたアクセスキー、シークレットキーを貼り付け

```
[default]
aws_access_key_id=AK******************
aws_secret_access_key=NAB*************************************
```

すでに `credentials` ファイルが存在する場合は `[ses]` など適当なプロファイル名を付けて追記する。
複数プロファイルを登録した場合、環境変数 `AWS_PROFILE` で使用するプロファイルを指定する。


## 3. JavaScriptからメール送信

**aws-sdk** を使ってメールを送る。

```sh
npm install --save aws-sdk
```

```js:index.js
const AWS = require('aws-sdk');

// 米国東部（バージニア北部） - 西部なら us-west-2
AWS.config.update({ region: 'us-east-1' });
const ses = new AWS.SES();

const params = {
  Destination: {
    ToAddresses: [
      'kazunori.kimura.js@gmail.com',
    ],
  },
  Message: {
    Body: {
      Text: {
        Data: 'こんにちは、テストメールです',
        Charset: 'utf-8'
      },
    },
    Subject: {
      Data: 'こんにちは、こんにちは！',
      Charset: 'utf-8',
    },
  },
  // From
  Source: 'support@xxx.yyy.zzz',
};

ses.sendEmail(params, (err, res) => {
  if (err) {
    console.log(err);
  }
  console.log(res);
});
```

かんたん！

## 4. 上限緩和申請を行う

本番環境では任意のメールアドレスに送信することになるため、上限緩和申請を行う。
SESのコンソールにて **Email Sending** > **Sending Statistics** などを表示すると、画面上部に上限緩和申請への案内が表示される。

詳細は下記の記事を参照: [Amazon SESによるメール送信環境の構築と実践 ｜ DevelopersIO](https://dev.classmethod.jp/cloud/aws/amazon-ses-build-and-practice/#ses-build-production)

---

## 参考

- [E メールの送信方法 – アマゾン ウェブ サービス (AWS) -  https://aws.amazon.com/jp/getting-started/tutorials/send-an-email/](https://aws.amazon.com/jp/getting-started/tutorials/send-an-email/)
- [AWS SESでのメール送信環境を構築する(Amazon Simple Email Service) | https://www.ritolab.com/entry/72](https://www.ritolab.com/entry/72)