AWSでメールを受信してLambdaで処理する
AWSでメールを受信してLambdaで処理するには以下の方法があります。
- SES→S3, SES→Lambda
- SES→SNS→Lambda
大きなメールを受信したい場合は1を選びます。1はS3にメールを格納してから読みに行くため、サイズの大きなメールも受信できます。2では160kB以下のメールしか受信できません。
SESとLambdaを異なるリージョンに配置したい場合は2を選びます。SESから直接Lambdaを実行する場合は同じリージョンでなければならない制約がありますが、SNSを経由させると異なるリージョンに配置できます。LambdaをVPCに配置して内部APIを叩きたい場合などに便利です。
なお、大きなメールを受信する要件と異なるリージョンに配置する要件の両方が必要な場合はLambdaからLambdaを呼び出すといった工夫が必要になります。よい方法があったら教えてください!
SES→Lambda
Lambdaでは下記のようなイベントを受け取ります。
{ "Records": [ { "eventSource": "aws:ses", "eventVersion": "1.0", "ses": { "mail": { "timestamp": "2017-11-20T05:17:16.168Z", "source": "送り元メールアドレス", "messageId": "****", "destination": [ "宛先メールアドレス" ], "headersTruncated": false, "headers": [ { "name": "Return-Path", "value": "<送り元メールアドレス>" }, ...snip... ], "commonHeaders": { "returnPath": "送り元メールアドレス", "from": [ "送り元メールアドレス" ], "date": "Mon, 20 Nov 2017 05:17:02 +0000", "to": [ "宛先メールアドレス" ], "messageId": "<****@mail.gmail.com>", "subject": "Re: foo" } }, "receipt": { "timestamp": "2017-11-20T05:17:16.168Z", "processingTimeMillis": 876, "recipients": [ "宛先メールアドレス" ], "spamVerdict": { "status": "PASS" }, "virusVerdict": { "status": "PASS" }, "spfVerdict": { "status": "PASS" }, "dkimVerdict": { "status": "PASS" }, "dmarcVerdict": { "status": "GRAY" }, "action": { "type": "Lambda", "functionArn": "arn:aws:lambda:us-west-2:****:function:****", "invocationType": "Event" } } } } ] }
本文が必要な場合はS3からメールを取得してパースします。
SES→SNS→Lambda
Lambdaでは下記のようなイベントを受け取ります。
{ "Records": [ { "EventSource": "aws:sns", "EventVersion": "1.0", "EventSubscriptionArn": "arn:aws:sns:us-west-2:****:****:38d16b3b-58f7-431b-9dbe-0362b0bcd7f2", "Sns": { "Type": "Notification", "MessageId": "8472fe29-c0fc-5e8d-8292-acb870a91f3e", "TopicArn": "arn:aws:sns:us-west-2:****:****", "Subject": "Amazon SES Email Receipt Notification", "Message": "...メールのJSON文字列...", "Timestamp": "2017-11-24T05:28:53.510Z", "SignatureVersion": "1", "Signature": "...snip...", "SigningCertUrl": "https://sns.us-west-2.amazonaws.com/SimpleNotificationService-****.pem", "UnsubscribeUrl": "https://sns.us-west-2.amazonaws.com/?Action=Unsubscribe&SubscriptionArn=arn:aws:sns:us-west-2:****:****:38d16b3b-58f7-431b-9dbe-0362b0bcd7f2", "MessageAttributes": {} } } ] }
Record.Sns.Message
には下記のようなメールオブジェクトが入っています。
{ "notificationType": "Received", "mail": { "timestamp": "2017-11-24T05:28:52.922Z", "source": "送り元メールアドレス", "messageId": "****", "destination": [ "宛先メールアドレス" ], "headersTruncated": false, "headers": [ { "name": "Return-Path", "value": "<送り元メールアドレス>" }, ...snip... ], "commonHeaders": { "returnPath": "送り元メールアドレス", "from": [ "送り元メールアドレス" ], "date": "Fri, 24 Nov 2017 05:28:38 +0000", "to": [ "宛先メールアドレス" ], "messageId": "<****@mail.gmail.com>", "subject": "Re: test" } }, "receipt": { "timestamp": "2017-11-24T05:28:52.922Z", "processingTimeMillis": 569, "recipients": [ "宛先メールアドレス" ], "spamVerdict": { "status": "PASS" }, "virusVerdict": { "status": "PASS" }, "spfVerdict": { "status": "PASS" }, "dkimVerdict": { "status": "PASS" }, "dmarcVerdict": { "status": "GRAY" }, "action": { "type": "SNS", "topicArn": "arn:aws:sns:us-west-2:****:****", "encoding": "UTF8" } }, "content": "...メールのヘッダと本文..." }
本文を取得するにはJSONの content
をパースします。