この記事は公開されてから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を使用するので、以下のように設定します。
SES受信設定
Management ConsoleでSESの画面を開くと、[Email Receiving]というメニューが増えています。[Rule Sets]でCreate a Receipt Rule
をクリックします。
Recipients
SES側で受信するドメイン、またはメールアドレスを登録します。ここではドメインを登録します。
登録してからVerify domain
をクリックします。
SESがドメインを認証するためのTXTレコードが表示されます。表示されたレコードをDNSへ登録します。今回はRoute 53を使用しているので、Use Route 53
をクリックすれば設定が完了します。
Actions
受信メールに対する処理を設定します。
今回は、以下の処理を設定しました。
- S3:S3バケットへ受信データをファイルとして保存します
- Lambda:受信データをDynamoDBへ保存するファンクションを設定しました(DymanoDBのテーブルは事前に作成します)
- Stop:処理を終了します
Lambdaの[Invocation type]はEvent
を設定しています。
Rule details
受信ルールの詳細を設定します。TLS対応やSPAM、ウィルスのスキャンを設定できます。
Review
内容を確認してCreate Rule
をクリックします。
メール送信確認
以下のようにメールを送信します。
S3への保存
以下のように、指定した場所にファイルとして保存されます。
Lambdaの実行
CloudWatch LogsにLambdaの実行ログが出力されます。
また、Lambdaの内容通りDynamoDBへデータとして保存されます。
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から直接後続処理を行うとシンプルに処理が行えますので、活用してみては如何でしょうか?