SESで受信したメールからLambda(python)で添付ファイル(テキストファイル)を取得してみる
どうも!大阪オフィスの西村祐二です。
今回はSESで受信したメールをS3に保存し、そのメールに添付ファイルがあれば、 Lambdaを使って添付ファイルを取得し、別バケットへ保存してみたいと思います。
※本エントリーでは、添付ファイルの対象をテキストファイルのみとしております。 また、掲載しているプログラムは動作確認のためのサンプルコードとして捉えてください。 本番で利用する場合は、事前検証及び、リトライ処理やエラー処理、 ファイル名が日本語であったときの処理など考慮してください。
処理の流れ
- SESで受信したメールをS3バケットに保存する
- S3をトリガーにLambda Functionが起動する
- Lambdaによってメールの添付ファイルを別バケットへ保存する
事前準備
SESでメール受信設定
下記ブログを参考にSESでメールを受信、受信したメールをS3に保存するように設定します。
Lambdaの設定
- ランタイム:Python3.6
- トリガー:S3(put) ※メールを受信するバケット
- ロール設定:S3の権限を付与してください
処理の内容
eventから得られるメールの名前よりオブジェクトを取得し、pythonのemailライブラリで メールに添付されているファイルを取得する。
import boto3 import base64 import email import urllib.parse s3 = boto3.resource('s3') def lambda_handler(event, context): # 添付ファイルを保存したいS3バケット名を指定 save_attachment_bucket = 'your-bucket-name' # Get the object from the event and show its content type bucket = event['Records'][0]['s3']['bucket']['name'] key = urllib.parse.unquote_plus(event['Records'][0]['s3']['object']['key'], encoding='utf-8') try: response = s3.meta.client.get_object(Bucket=bucket, Key=key) email_body = response['Body'].read().decode('utf-8') email_object = email.message_from_string(email_body) for part in email_object.walk(): # ContentTypeがmultipartの場合は実際のコンテンツはさらに中のpartにあるので読み飛ばす if part.get_content_maintype() == 'multipart': continue # ファイル名の取得 filename = part.get_filename() print(filename) # ファイル名がなければ飛ばす if not filename: continue else: # メールフォルダ内のfileディレクトリに添付ファイルを保存する attach_data = part.get_payload(decode=True) bucket_source = s3.Bucket(save_attachment_bucket) obj = bucket_source.put_object(ACL='private', Body=attach_data, Key='file' + "/" + filename, ContentType='text/plain') return 'end' except Exception as e: print(e) print('Error getting object {} from bucket {}. Make sure they exist and your bucket is in the same region as this function.'.format(key, bucket)) raise e
テスト
実際にSES宛にファイルを添付したメールを送信し、添付ファイルが別バケットに出力されるかテストしてみます。
利用するテキストファイル
添付するテキストファイルの本文には英語と日本語と記号が記載されています。
message test 日本語テスト 記号テスト !@#$%^&*()_+|~{}:”>?<`,./;’[]
一つのファイルを添付して送信してみる
▼SESへファイルを添付したメールを送信します。
▼想定通り、メールが保存されているバケット内のfileバケットに添付ファイルが保存されています。
S3からローカルにファイルをダウンロードし、中身を確認しても添付したファイルと同じであることがわかります。
複数ファイルを添付して送信してみる
▼メールに添付するファイル名を「ses-attach2.txt」「ses-attach3.txt」として、SESへ送信します。
▼想定通り、添付した2つのファイルがメールがfileバケットに保存されています。
さいごに
いかがだったでしょうか。 Lambdaを使って、SESで受信したメールから添付ファイルを取得してみました。 pythonのemailライブラリを使えば、ある程度容易に受信したメールの解析ができそうです。 誰かの参考になれば幸いです。