チラシの裏の書き置き

技術的な話をするブログのタイトルじゃない気がする

Amazon SESで受信したメールをGmailに転送して送信元へちゃんと返信できるようにしてみた

前回はSESを使ってGmailからメールを送信できるようにしましたが、今回は逆?に、SESで受信したメールをGmailへ転送し、かつ送信元へちゃんと返信できるよう設定します。

tech.taiko19xx.net

準備

最初に、SESで受信したメールをPOP3とかIMAPを使ってメーラーで受信する手段はありません
その代わり、ドキュメントにあるように、メール受信に応じて下記の5種類のアクションが実行されます。

  • S3への受信(+SNS通知)
  • SNSのトピック公開
  • Lambda実行
  • バウンス応答
  • WorkMailへ転送

ちなみにアクションは組み合わせができ、ヘッダ追加とか処理終了的な指定もできます。

その中で、今回行いたい「転送」的なアクションはWorkMailのみとなっています。(SNS通知はちょっと用途が違う)
そうすると、Lambda実行して関数内から転送させるのが一番良さそうです。

Lambdaでメール送受信の色々を一から調整するのは大変なので、今回は下記のライブラリを使用します。

github.com

どんな動きをするかというと、SESがLambdaをキック→Lambdaに渡したメッセージIDのオブジェクトをS3から取得→Reply-toを付けるなどして、オブジェクトの中身を指定したアドレスに転送、という処理を行ってくれます

設定

基本的にはライブラリのREADMEにある通りの設定をポチポチして、Lambda関数とかロールを作ればOKです。

ライブラリの exampleindex.jspackage.json があるので、両方手元に落として npm install しておきます。
次に index.js 内の overrides.config を次の感じで書き換えます。

  var overrides = {
    config: {
      fromEmail: "転送時のFromのアドレス",
      subjectPrefix: "件名に付けたいプレフィックス",
      emailBucket: "保存先S3バケット",
      emailKeyPrefix: "S3オブジェクトのプレフィックス",
      forwardMapping: {
          "受信したアドレス": [
              "転送先アドレス"
          ]
      }
    }
  };

forwardMapping の受信したアドレス(キーの部分)はユーザ名(@より前)のみやドメイン(@より後)のみの指定もできます。また、転送先アドレスも複数指定できます。
詳しくはライブラリ内のindex.jsを...。

続けてLambda関数を作成しますが、ランタイムはNode.js 6.10にして、ロールは下記のロールで作成します。 ロール内の S3-BUCKET-NAME は受信メールを保存する先のS3バケット名に置換します。

{
   "Version": "2012-10-17",
   "Statement": [
      {
         "Effect": "Allow",
         "Action": [
            "logs:CreateLogGroup",
            "logs:CreateLogStream",
            "logs:PutLogEvents"
         ],
         "Resource": "arn:aws:logs:*:*:*"
      },
      {
         "Effect": "Allow",
         "Action": "ses:SendRawEmail",
         "Resource": "*"
      },
      {
         "Effect": "Allow",
         "Action": [
            "s3:GetObject",
            "s3:PutObject"
         ],
         "Resource": "arn:aws:s3:::S3-BUCKET-NAME/*"
      }
   ]
}

logs のあたりは作成時に付与されるやつですが、それに加えてSESによるメール送信とS3のオブジェクト取得書き込みのロールも付与しています。

設定後はnode_modulesごとzipで固めてアップロードします。
READMEにあるように、関数のタイムアウトを10秒に広げて保存すれば完了です。

f:id:taiko19xx:20180501161118p:plain zipのアップ後はこんな表示が出たので、いちいち変更する度に固めてアップロードしないといけないのは面倒ですね...。

お次はSESの設定をします。 事前にドメインやメールアドレスの認証をしておく必要があるので注意。前回の記事を参照してください。

f:id:taiko19xx:20180501161131p:plain Create Ruleで新しいルールを追加します。 (Rule Setが無い場合は事前に作成。前回を参照)

f:id:taiko19xx:20180419005426p:plain Recipientsでは受信したいメールアドレスを指定します。

f:id:taiko19xx:20180501161138p:plain Actionsは最初にS3を指定してバケットやプレフィックスを指定し、次にLambdaを実行するようにします。
Lambda側は作成した関数を指定、Invocation TypeはEventにします。

f:id:taiko19xx:20180501161145p:plain ルール名を適当に入れておきます。その他はそのまま。

f:id:taiko19xx:20180501161157p:plain 内容に問題がなければ、Create Ruleを押して完了です。

テスト

f:id:taiko19xx:20180501163053p:plain こんな感じで、捨てアドのサービスから送信してみます。(メールアドレスは認証済み)

f:id:taiko19xx:20180501163105p:plain 送信して少し待つと、Gmailのアドレスに転送されてきました。

f:id:taiko19xx:20180501163120p:plain Reply-toが設定されているので、返信しようとすると送信元アドレスに対して送信できます。

おわり

受信したメールを転送して、送信してきたアドレスに対して返信できるようになりました。
認証の部分は前回と共通ですが、今回はLambdaの設定が必要なので前回とは違った意味でハードルがあったかもしれません。ほとんどコピペで済みますが...。

これで、前回の手順と合わせれば、Gmail+SES+Lambda+S3の組み合わせでメールを送受信できる環境が整います。
特に問題もなさそうなので、様子を見て今のドメインで運用してるメールまるごと移行してみたいですね。