メールに添付されたCSVファイルの取り込み→加工→転送をAWSのサーバレスで構築する方法の考察 part2 添付ファイル取り込み編

# やりたいこと（part1と同様）
下記工程を人の手でやっていたところを自動化したいそう。
なんとなくAWSだけで構築できそうなので考えてみた
1. データが記入されたCSVファイルをメールで受け取る
1. 受けとったCSVファイルを確認する
1. 記入内容にミスが無ければサーバに格納
1. 記入内容にミスがあれば、記入列を色付けして返信
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3138153/171c6913-74eb-e300-c5f5-4fec69e93cc7.png)

↑イメージこんな感じ。
を
↓こんな感じにしてみようかと。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3138153/b56b9815-c46b-f3b0-a7e6-4dac73253f7c.png)
1. SESでSCVファイルが添付されたメールを受信する
1. 受信したメールをS3に格納
1. S3格納をトリガーにLambda発火
1. LambdaでCSVファイルの加工を行う。（記入ミスがある場合SESを使用して返信）
1. 加工したCSVファイルをS3に格納
1. 時間発火（EventBridge+Lambda）でCSVファイルをserverに送信（FTPかな？）

って感じです。
とりあえずやってみよう。笑笑

# 受信したメールから添付ファイルを取得する
ここの部分ですね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3138153/aed1d15f-fc9c-8262-0fe6-19ca7e8127ef.png)
SESでメールを受信すると、メール本文とか添付ファイルとかが1つのファイルとしてS3に保存されるので、添付ファイルのみを抜き取る必要がありますね。

## Lambda関数の作成
S3に保存されているデータから、添付ファイルのみを抜きだします。
学生のころはCとかJava人間だったんですけど、社会人になってPythonの便利さを知り快感を得た人間なので。
今回は（これからもずっと）Pythonで開発していきます。笑笑

「Lambda」→「関数」→「関数の作成」でLambdaを作成します。
関数名：いい感じの名前
ランタイム：Python 3.9
です。
![19.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3138153/0e4a6d89-16a4-8c69-5c1c-cc32acaa08be.png)

以下コードです。
part1で作成したS3に"file/"プレフィックスを追加して、そこに添付ファイルのみを保存します。
~~~python:mailreceive.py
import boto3
import base64
import email
import urllib.parse
import json
from logging import getLogger, INFO

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

s3 = boto3.resource('s3')

def lambda_handler(event, context):
    print("--------- logger.info の出力 ---------")
    logger.info(json.dumps(event))
    
    # S3のデータ取得
    bucket = event['Records'][0]['s3']['bucket']['name']
    key = urllib.parse.unquote_plus(event['Records'][0]['s3']['object']['key'], encoding='utf-8')
    messageid = key.split("/")[1]
    
    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():
            print("maintype : " + part.get_content_maintype())
            if part.get_content_maintype() == 'multipart':
                continue
            # ファイル名の取得
            attach_fname = part.get_filename()
            print(attach_fname)

            # ファイルの場合
            if attach_fname:
                # fileに添付ファイルを保存する
                attach_data = part.get_payload(decode=True)
                bucket_source = s3.Bucket(bucket)
                bucket_source.put_object(ACL='private', Body=attach_data,
                                         Key='file' + "/" + attach_fname, 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
~~~


Lambdaの発火条件を設定します。
「トリガーを追加」から、S3にメールが保存されたらLambdaが発火するように設定します。
・バケット：part1で作成したS3
・イベントタイプ：PUT
・プレフィックス：メールを保存しているプレフィックス
![24.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3138153/badcdee3-ace3-0f2a-debb-46099f6c675d.png)

# メールを送信してみる
part1と同様にCSVファイルを添付してメールを送信してみます。
![25.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3138153/ee94c04a-51a6-f872-134d-3634bcae7423.png)

"file/"配下に添付ファイルのみが格納されました！！
![26.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3138153/9817ec80-59f0-1a9b-a08a-9c6bbf184947.png)

# part2終わり！
受信したメールから添付ファイルを抜き出すことができました。
次はこれを返信する方法ですね〇

今回作成したコードはGithubで公開しているので自由にどうぞ笑笑
次↓
[メールに添付されたCSVファイルの取り込み→加工→転送をAWSのサーバレスで構築する方法の考察 part3 添付ファイル送信編](https://qiita.com/bakuchiku/items/8f72e7bd7a3b1e19badd "メールに添付されたCSVファイルの取り込み→加工→転送をAWSのサーバレスで構築する方法の考察 part3 添付ファイル送信編")