SESでのメール受信についてエントリーを書いたのですが、実際にLambdaで転送して別のメールアドレスで受け取るまで。
Amazon SESについて(Route53登録→SESで受信→S3で保存)
えーSESでメール受信を行っても、そのメール自体を直接メールクライアントなどで見ることはできないようです。
メール自体中身が通常のメールクライアントで見れなければ意味はありません。
ということで、方法として調べたところ下記の方法があるようです。
- AmazonWorkMailを使う
- Lambdaで他のメールに転送(例えばgmailなど)
Amazon WorkMailとは
どうやらAWSアカウントで使えるようなgmailのようなサービスのようです。
これを使えば、一般のブラウザでメールが確認できますので、おそらく一番簡単ではないかと思います。
お金がかかるようですが・・・
説明しているサイトを見ると本当にgmailのような感じですね。手軽さで言えばこちらの方が良いかと思います。
Lambdaで他のメールに転送(例えばgmailなど)
結局、技術的に調査したいこともあり、今回はこちらを使いました。
Lambdaとは
サーバーを立ち上げずに、コードを実行したりすることができるサービスのようです。
すぐに思いつくのは
- 定期バッチ
- 何らかのイベントをトリガーにしてのアクション
などです。
サーバーを立ち上げずにできる・・というのはすごいですよね。
以前、職場のリーダー的な方から話を聞きましたが、その時は?状態でした。
今回実際に自分が使うことになり、色々検索してみるとクラウド上にアプリケーションを構築する手法としてサーバーレスというのが徐々に認知されているようですね・・
今回行ったケースは
SESでのメール受信→Rule SetでS3への保存とLambdaのある関数(メール送信)をactionに設定→Lambdaでメール送信
というパターンです。
これだけの設定ですが、色々大変でした・・
lambdaでの関数登録
まずはlambdaにてメールを送信する関数を登録しなければいけません。
旬の技術なので色々と参考リンクがあるのはありがたいですが・・・
今回のケース(SESをトリガーにしての転送)ですと、
- トリガー自体は必要なし(SESのRule Setで登録)
- アクセス許可のリソースには、Cloud Watch Logs、AWS Lambdaを追加
になります。
Cloud Watch Logsは必須ではないかもしれませんが、デバッグしたり、ログをみることができるのであった方が絶対いいでしょう。
実際の関数作成
実際のプログラムの登録ですが、オンラインでブラウザで登録できるエディタ環境があり、これに登録をします。(今回はしませんが、実際にコードを書いて、zipであげたりとかなどもできるようです。)
すごく嬉しいことに簡単にテストができます。
下記のようなコードで実際に送信をすることができました。
PHPもあるようですが、なにやらディフォルトではダメなようなのでPythonを選択。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 |
import boto3 import re from boto3.session import Session def lambda_handler(event, context): extract_mail(event) def extract_mail(event): #転送メールの送信元ドメイン名 DOMAIN_NAME = "ドメイン名" BUCKET_NAME = 'バケツ名' FOREWARD_MAIL = ['転送先メール'] REGION = 'us-east-1' session = Session(aws_access_key_id='アクセスキー', aws_secret_access_key='シークレットキー', region_name='リージョン') s3 = session.client('s3') ses = session.client('ses') messageId = event['Records'][0]['ses']['mail']['messageId'] #本来の送信者 MAIL_SOURCE = event['Records'][0]['ses']['mail']['source'] #転送メールの送信者 MAIL_FROM = MAIL_SOURCE.replace('@','=') + "@" + DOMAIN_NAME try: response = s3.get_object( Bucket = BUCKET_NAME, Key = messageId ) except Exception as e: raise e #メールヘッダの書き換え try: replaced_message = response['Body'].read().decode('utf-8') replaced_message = re.sub("\nTo: .+?\n", "\nTo: %s\n" % ", ".join(FOREWARD_MAIL), replaced_message,1) replaced_message = re.sub("\nFrom: .+?\n", "\nFrom: %s\n" % MAIL_FROM, replaced_message,1) replaced_message = re.sub("^Return-Path: .+?\n", "Return-Path: %s\n" % MAIL_FROM, replaced_message,1) except Exception as e: raise e try: response = ses.send_raw_email( Source = MAIL_FROM, Destinations= FOREWARD_MAIL, RawMessage={ 'Data': replaced_message } ) except Exception as e: raise e |
コード自体は下記URLのほぼコピペです(汗)
参考リンク
Amazon SESで受信したメールを転送したい
SESで受信したメールをLambdaを通して転送&S3に保存 – Lambda(Python)/S3/SES
少しハマった点や解決のポイントになりそうなところなど
- eventという変数をprintするとcloud watch logsにデータがはかれる→一度メールをSESに送り、print(event)する→そのjsonデータをテストデータとして登録し、テスト実行&デバッグすると開発がすごく簡単
- policyで引っかかるのでs3,ses共にpolicyの追加が必須。(関数単位のpolicyではなくロール単位でのpolicyを)。S3はアクセス権限→バケットポリシーから。SESはDomainsからIdentity Policiesから。
- Pythonはこれ以外にもs3などのファイル群を簡単に操作できるライブラリが多数あるようで、AWSとの親和性は高いかも。
色々格闘しまして、無事、メール転送までをすることができました。長かった・・・
[…] 実際にメールを転送して一般のメールクライアントでみる方法はこちら Amazon SESでの受信→S3→Lambdaでのメール転送 […]
[…] Amazon SESでの受信→S3→Lambdaでのメール転送 […]