[新機能]Amazon SES でメール受信が出来るようになりました!

Amazon SES
318件のシェア(そこそこ話題の記事)

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

ウィスキー、シガー、パイプをこよなく愛する大栗です。
先ほどAmazon SESのアップデートで、メール受信が可能になったので検証してみました。SESはメール送信専用のサービスでしたが、受信も出来るようになったので様々なユースケースに対応できるのではないかと思います。

2015/09/29 11:50 JST追記:Lambda Action、SNS Actionでメール本文が取得できないことを記述

SESでメール受信

先日SendGridを使ってAPI Gateway+Lambdaでメール受信を行う方法について紹介しましたが、AWSサービスで可能になりました(息の短いブログだった、、、でも、シンプルなWebhookだったらSendGridの方が良いかもしれません)。
以下の図のように、受信専用のSESのSMTPエンドポイントでメールを受信して、後続処理を行えます。

試してみる

実際にSESを使ってメール受信をしてみます。

ドメイン設定

最初に、受信対象メールのドメインを設定します。以下のSMTPエンドポイントに向けてDNSでMXレコードを作成します。

リージョン 受信用SMTPエンドポイント
米国東部 (バージニア北部) inbound-smtp.us-east-1.amazonaws.com
米国西部 (オレゴン) inbound-smtp.us-west-2.amazonaws.com
EU (アイルランド) inbound-smtp.eu-west-1.amazonaws.com

今回はRoute 53を使用するので、以下のように設定します。

Route_53_Management_Console

SES受信設定

Management ConsoleでSESの画面を開くと、[Email Receiving]というメニューが増えています。[Rule Sets]でCreate a Receipt Ruleをクリックします。

Recipients

SES側で受信するドメイン、またはメールアドレスを登録します。ここではドメインを登録します。
登録してからVerify domainをクリックします。

SES_Management_Console

SESがドメインを認証するためのTXTレコードが表示されます。表示されたレコードをDNSへ登録します。今回はRoute 53を使用しているので、Use Route 53をクリックすれば設定が完了します。

SES_Management_Console

Actions

受信メールに対する処理を設定します。

SES_Management_Console

今回は、以下の処理を設定しました。

  1. S3:S3バケットへ受信データをファイルとして保存します
  2. Lambda:受信データをDynamoDBへ保存するファンクションを設定しました(DymanoDBのテーブルは事前に作成します)
  3. Stop:処理を終了します

Lambdaの[Invocation type]はEventを設定しています。

Rule details

受信ルールの詳細を設定します。TLS対応やSPAM、ウィルスのスキャンを設定できます。

SES_Management_Console

Review

内容を確認してCreate Ruleをクリックします。

SES_Management_Console

メール送信確認

以下のようにメールを送信します。

メールを作成_-_oguri_hajime_classmethod_jp_-_Classmethod_jp_メール

S3への保存

以下のように、指定した場所にファイルとして保存されます。

S3_Management_Console

Lambdaの実行

CloudWatch LogsにLambdaの実行ログが出力されます。

CloudWatch_Management_Console

また、Lambdaの内容通りDynamoDBへデータとして保存されます。

DynamoDB_·_AWS_Console

Lambdaで扱う時の内容は、以下の形式になります。Recordは配列なので、複数メールを同時に処理する可能性があると思われます。Lambdaの[Invocation type]の設定がRequestResponseの場合は1件のみになると考えられます(未確認)。
なお、Lambda、SNSではメール本文が取得できないようなので、S3に保存したオブジェクトから内容を取得する必要がありそうです。そのためLambdaでメール本文を扱う場合には、一旦ActionでS3保存を設定して、その通知先としてLambdaを実行する必要がようです。
Contents of Notifications for Amazon SES Email Receiving

{
    "Records": [
        {
            "eventSource": "aws:ses",
            "eventVersion": "1.0",
            "ses": {
                "mail": {
                    "timestamp": "2015-09-28T22:51:45.545Z",
                    "source": "oguri-hajime@example.com",
                    "messageId": "obvvhljau9enjkfeh5rko0qgkl22hcatqudgido1",
                    "destination": [
                        "ses@receiving-with-ses.example.com"
                    ],
                    "headersTruncated": false,
                    "headers": [
                        {
                            "name": "Return-Path",
                            "value": "<oguri-hajime@example.com>"
                        },
                        {
                            "name": "Received",
                            "value": "from ss06.activegate-ss.jp (ss06.activegate-ss.jp [223.27.116.84]) by inbound-smtp.us-east-1.amazonaws.com with SMTP id obvvhljau9enjkfeh5rko0qgkl22hcatqudgido1 for ses@receiving-with-ses.oguri.example.com; Mon, 28 Sep 2015 22:51:45 +0000 (UTC)"
                        },
                        {
                            "name": "Received",
                            "value": "from ([10.0.5.215]) (envelope sender: <oguri-hajime@example.com>) by ss06.activegate-ss.jp with Active!gate esmtp server; Tue, 29 Sep 2015 07:51:10 +0900"
                        },
                        {
                            "name": "Received",
                            "value": "from ([209.85.215.43]) (envelope sender: <oguri-hajime@example.com>) by mail.activegate-ss.jp with TransWARE esmtp server; Tue, 29 Sep 2015 07:51:10 +0900"
                        },
                        {
                            "name": "Received",
                            "value": "by laer8 with SMTP id r8so48030621lae.2 ; Mon, 28 Sep 2015 15:51:06 -0700 (PDT)"
                        },
                        {
                            "name": "DKIM-Signature",
                            "value": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=example.com; s=google; h=mime-version:from:date:message-id:subject:to:content-type; bh=IhTDHR+i15G5QIm764nlmpI6eH36zP+UkLDJ5GbEKz8=; b=lw0/cH61AgvfTUwWD0MkCXNFshhn3PEa9jJMfr7f8ZIgkZxTqwFJQxIm5c+b3hKf04 EeSwP+BATnrwA4HszDJT50YXjseneXrqsa+bPjIKyeaHf0nIsIvJ8WFaKgBhQoZ2jPyx sm8jDn9sX2voFRgEpfbdD26w7orrVV51l9QC0="
                        },
                        {
                            "name": "X-Google-DKIM-Signature",
                            "value": "v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:from:date:message-id:subject:to :content-type; bh=IhTDHR+i15G5QIm764nlmpI6eH36zP+UkLDJ5GbEKz8=; b=EM5wCJhbo+5O34XnoFkRSKGMAhB47hJOgGOAWy1BFgQzj+6lYZWJOighzi+Edoc6Bx 0lYR/WmOa4gPr2NxCXDL9mOBOO9VovQgEXjC+kyrVN3NDal/f+jLS17p6je64txpUBah uB6ge1H1HWyee8+d2kAuuoNd7YRfKgD2EGcbkH+EIAQ/CX2rOs7f+Cgfs+LPBFd+1g3i MLhSNX0jQocrRzkMutkUNfAyaUcYapDfZDMx2OqLd91OJX3yicBz+/+VGE/4WkrDFRTk nQJRlznSiRltBLfRhzUZUXf5WZLDJ+d5aAMG5R/oN6jv2VGO0yTeJKwitOXrpJHg9Ppo YsIQ=="
                        },
                        {
                            "name": "X-Gm-Message-State",
                            "value": "ALoCoQn246QVws48ToJKsOrKRABCDEFHGI0xKDQJ8ZDC0qw0VHFPbv9cjc/XKcmSW91p34W3RJQs5/sy56vnV5Ic725lZFw8zqwxZYUGmSTsWJS01oepxWEag4c50uz4/xvrCthkApaCoNNCuy7sDSItNyr0RUqgx8CdBeWVdWR1Bzb3WLWmIRc="
                        },
                        {
                            "name": "X-Received",
                            "value": "by 10.25.19.73 with SMTP id j70mr4130289lfi.29.1443480666771; Mon, 28 Sep 2015 15:51:06 -0700 (PDT)"
                        },
                        {
                            "name": "X-Received",
                            "value": "by 10.25.19.73 with SMTP id j70mr4130281lfi.29.1443480665912; Mon, 28 Sep 2015 15:51:05 -0700 (PDT)"
                        },
                        {
                            "name": "MIME-Version",
                            "value": "1.0"
                        },
                        {
                            "name": "Received",
                            "value": "by 10.25.199.18 with HTTP; Mon, 28 Sep 2015 15:50:46 -0700 (PDT)"
                        },
                        {
                            "name": "From",
                            "value": "大栗宗 <oguri-hajime@example.com>"
                        },
                        {
                            "name": "Date",
                            "value": "Tue, 29 Sep 2015 07:50:46 +0900"
                        },
                        {
                            "name": "Message-ID",
                            "value": "<CAOgvZW4-zpoVVtsHBmk5UW11U12mQbEsT89DmK3otN5TmqWbXw@mail.gmail.com>"
                        },
                        {
                            "name": "Subject",
                            "value": "テストタイトル1"
                        },
                        {
                            "name": "To",
                            "value": "ses <ses@receiving-with-ses.example.com>"
                        },
                        {
                            "name": "Content-Type",
                            "value": "multipart/alternative; boundary=001a11408078551e510520d68803"
                        }
                    ],
                    "commonHeaders": {
                        "returnPath": "oguri-hajime@example.com",
                        "from": [
                            "\"大栗宗\" <oguri-hajime@example.com>"
                        ],
                        "date": "Tue, 29 Sep 2015 07:50:46 +0900",
                        "to": [
                            "ses <ses@receiving-with-ses.example.com>"
                        ],
                        "messageId": "<CAOgvZW4-zpoVVtsHBmk5UW11U12mQbEsT89DmK3otN5TmqWbXw@mail.gmail.com>",
                        "subject": "テストタイトル1"
                    }
                },
                "receipt": {
                    "timestamp": "2015-09-28T22:51:45.545Z",
                    "processingTimeMillis": 1087,
                    "recipients": [
                        "ses@receiving-with-ses.example.com"
                    ],
                    "spamVerdict": {
                        "status": "PASS"
                    },
                    "virusVerdict": {
                        "status": "PASS"
                    },
                    "spfVerdict": {
                        "status": "PASS"
                    },
                    "dkimVerdict": {
                        "status": "PASS"
                    },
                    "action": {
                        "type": "Lambda",
                        "topicArn": "arn:aws:sns:us-east-1:123456789012:ses-test-2",
                        "functionArn": "arn:aws:lambda:us-east-1:123456789012:function:ReceiveSES",
                        "invocationType": "Event"
                    }
                }
            }
        }
    ]
}

さいごに

先日はSendGrid+API Gateway+Lambdaを使って同様のメール受信処理を試してみたのですが、SESから直接後続処理を行うとシンプルに処理が行えますので、活用してみては如何でしょうか?