【AWS】AWS初心者がRoute53＋SES＋S3＋Lambdaを使って、独自ドメインに送られてきたメールをGmailに転送してみた

皆さんこんにちは！！

今回はRoute53で登録した独自ドメインを使って、メールをGmailで受け取る方法を書いていきます。

例えば、``support@example.com``に送信したメールを自分のGmail``mymail@gmail.com``に飛ばすイメージです。

実際に``suppor@gmail.com``で受け取ったメールをS3にプッシュするのですが、いちいちS3にアクセスしてダウンロードして見るなんてやってられないですよね。

なので、Gmailに飛ばしちゃいましょう！！

#はじめに#

Route53で独自ドメインを登録してある前提で話を進めていきます。

なので、まだRoute53で独自ドメインを登録していない方は登録してから本記事をご覧ください。

登録方法は色々あると思うので、僕が書いた記事でよければご覧ください。

[AWS初心者がお名前ドットコム、S3、CloudFront、CertificateManager、Route53を使ってHTTPS化されたサイトを公開してみた（パート①）](https://qiita.com/akki-memo/items/7c3b7ee4434cd39f7475)

それでは早速説明していきます！

#ドメイン認証#

サービス検索欄から「SES」と入力

リージョンは**必ず「us-east-1」**にしてください！！！

なぜかと言うと、例えば東京リージョンだとこの後行うルールの設定を行うことができません。

言い換えれば、東京リージョンでは**メールを受け取ることができない**んです。

なので、説明と同じように「us-east-1」にしてください！

そしたら、左のメニュー欄から「Domains」をクリック

「Verify a New Domain」をクリック

Route53に登録しているドメイン名を入力

「Generate DKIM Setteings」は今回は使わないのですが、送信用のための設定です。

メールの送信は行わないという方でもも一応チェックを入れておきましょう。

すると、色々と認証情報が出てくると思います。

少し下に行き、「Use Route53」をクリック

全ての項目にチェック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954754/a315683d-b389-9de0-847d-3f6b80e48915.png)

少し時間が経つとこのようになります。

verifiedにならない場合はドメイン情報が間違っているのでもう一度やり直してください。

#メールアドレス認証#

次にメール認証を行います。

左のメニュー欄から「Email Address」をクリック

「Verify a New Email Address」をクリック

お使いのGmailアドレスを入力。

すると、入力したメールアドレス宛に届いたリンクをクリック

認証が成功すればOKです！

#ルール設定#

さぁ、先ほど注意したルール設定です。

左のメニュー欄から「Rule Sets」をクリック

リージョンは**us-east-1**になっていますか？？？

興味のある方はap-northeast-1にして見て下さい。

「Rule Sets」ができないはずです。

そしたら、「Create a New Rule Set」をクリック

##Recipient設定##

「Recipient」にはRoute53に登録したドメイン名を入力してください。

``support@example.com``ではなく``example.com``のように@の前のsupportは付けなくて大丈夫です！

こうすることで``example.com``のドメインで送信されたメールを全て受け取れます。

また、特定のメールアドレスのみ受け取りたい方は``support@example.com``のようにしてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954754/3976ff49-1d61-471f-5972-9b6109651b28.png)

このように追加したドメインのステータスがVerifiedになっていればOK！

「Add Recipient」をクリック

「Next Step」をクリック

##Actions設定##

次に受け取ったメールをS3に保存するための設定を行います。

タイプをは「S3」を選択し、「S3 bucket*」では「Create S3 Bucket」を選択。

適当に名前を入力

この後にLambdaで作成した関数をここで定義するので覚えておいてください。

その他の設定はいじらずに「Next Step」をクリック

##ルール設定##

「Rule name*」に適当な名前を入力

その他の設定はいじらずに「Next Step」をクリック

「Create Rule」でルールを作成してください。

無事ルールが作成されればOK！！

これで送られてきたメールをS3に保存することができます！

#IAMロールの作成#

次に、Lambda関数を実行するためのIAMロールの作成を行います。

サービス検索欄から「IAM」と入力

左のメニュー欄から「ロール」を選択

「ロールの作成」

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954754/b973cea3-ad59-2566-3d1d-375521bb8230.png)

一般的なユースケースから「Lambda」を選択

以下のポリシーを追加してください。

・AmazonS3FullAccess
・AmazonSESFullAccess
・AWSLambdaBasicExecutionRole

そしたら作成してください。

無事作成されればOK！

#Lambda関数の作成#

次はS3に保存したメール内容をGmailへと転送する関数を作成します。

サービス検索欄から「Lambda」と検索

「関数の作成」をクリック

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/954754/e3dc64bd-cd66-5ccb-9083-f967d0205d68.png)

画像のようにランタイム→「Python 3.7」、実行ロール→「既存のロールを使用する」を選択し今作ったIAMロールを選択。

そしたら作成してください。

関数のコードで以下のソースコードをコピペ

```lambda-function.py
import os
import boto3
import email

import re
import logging

s3_client = boto3.client('s3')
ses_client = boto3.client('ses')

logger = logging.getLogger()
logger.setLevel(logging.INFO)

ORIGINAL_ADDRESS = 'support@example.com'
FORWARD_ADDRESS = 'mymail@gmail.com'
S3_BUCKET_NAME = 'BUCKET_NAME'
SES_REGION = 'us-east-1'

def parse_mail(raw_message):

    from_name = 'No Name'

    pattern = re.compile(r'^From:\s*(.+?)$', re.MULTILINE)
    m = re.search(pattern, raw_message)
    if m:
        from_name = m.group(1)[:-1]
        
    replaced_message = raw_message.replace(ORIGINAL_ADDRESS, FORWARD_ADDRESS)
    replaced_message = re.sub(r'^From:\s*.+?$', r'From: "%s" <%s>' % (from_name, ORIGINAL_ADDRESS), replaced_message, flags=re.MULTILINE)
    replaced_message = re.sub(r'^Return-Path:\s*.+?$', r'Return-Path: "%s" <%s>' % (from_name, ORIGINAL_ADDRESS), replaced_message, flags=re.MULTILINE)
    replaced_message = re.sub(r'^Sender:\s*.+?$', r'Sender: "%s" <%s>' % (from_name, ORIGINAL_ADDRESS), replaced_message, flags=re.MULTILINE)

    return replaced_message

def send_mail(message):

    ses = boto3.client('ses', region_name=SES_REGION)

    ses.send_raw_email(
        Source = FORWARD_ADDRESS,
        Destinations=[
            FORWARD_ADDRESS
        ],
        RawMessage={
            'Data': message
        }
    )

def lambda_handler(event, context):
    try:
    
        record = event['Records'][0]
        
        s3_object = s3_client.get_object(
            Bucket = S3_BUCKET_NAME,
            Key = record['ses']['mail']['messageId'])

        raw_message = s3_object["Body"].read().decode('utf-8')
        message = parse_mail(raw_message)
        send_mail(message)

        logger.info('SUCCESS')
        
    except Exception:
        logger.critical(
            'Execution failed. Exception encountered',
            exc_info=True)
    
    logger.info('FAILED')
```

各自、以下は変更してください。

```
ORIGINAL_ADDRESS = 'support@example.com'
FORWARD_ADDRESS = 'mymail@gmail.com'
S3_BUCKET_NAME = 'BUCKET_NAME'
SES_REGION = 'us-east-1'
```

そしたら「Deploy」してください。

#ルール設定#

これでラストです！

サービス検索欄から「SES」と検索

左のメニュー欄から「Rule Sets」を選択

「View Active Ruel Set」をクリックし、先ほど作成したルールをクリックしてください。

「Actions」からタイプを「Lambda」と選択し、今作った関数を指定してください。

「Save Rule」をクリックして保存してください。

#テスト#

これで``support@example.com``に送ったメールは全て``mymail@gmail.com``に転送されます。

実際にメールを送ってみてください。

もし届かない場合は、恐らくLambdaで作成した関数でのエラーログ（CloudWatch）を見ればどこでエラーが起きているか確認できます。

いかがだったでしょうか？

長くて大変だったけど、達成感はすごいあった。

近々独自ドメインでメールを送信する方法も書くので、ぜひ良かったらそちらもご覧ください！

以上、「【AWS】AWS初心者がRoute53＋SES＋S3＋Lambdaを使って、独自ドメインに送られてきたメールをGmailに転送してみた」でした！

また、何か間違っていることがあればご指摘頂けると幸いです。

他にも初心者さん向けに記事を投稿しているので、時間があれば他の記事も見て下さい！！

あと、最近「ココナラ」で環境構築のお手伝いをするサービスを始めました。

気になる方はぜひ一度ご相談ください！

Thank you for reading

#参考記事#

以下、この記事を書くにあたって参考にさせて頂いた記事です。

・[Gmail + AWSで独自ドメインのメールを受信する](https://qiita.com/komakomako/items/a1ed84b58b46eb434cf2)
・[Amazon SESを使って独自ドメインのメールをGmailで受け取る](https://machinanette.com/2019/06/19/amazon-ses%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%A6%E7%8B%AC%E8%87%AA%E3%83%89%E3%83%A1%E3%82%A4%E3%83%B3%E3%81%AE%E3%83%A1%E3%83%BC%E3%83%AB%E3%82%92gmail%E3%81%A7%E5%8F%97%E3%81%91%E5%8F%96%E3%82%8B/)