pythonとSendgridを使ってメールを半自動送信、さらにgoogle calendarに予定を書き込む方法

#pythonとSendgridを使ってメールを半自動送信、さらにgoogle calendarに予定を書き込む方法
---
インターン先で作ったメールの自動送信とgoogle calendarに予定を追加する方法についてここでまとめておこうと思います。
#今回作った仕組みの全体の流れ
1, curlコマンドを使って必要な情報(jsonファイル形式)をAWSに送る
2, AWSの中にデプロイ(アップロード)しているPythonを起動する。
3, pythonがsendgridとgoogle calendarにjson形式で必要な情報を送る。
4, sendgridのAPIが自動的にメールを送信する
5, google calendar APIが予定を自動的に追加する。

この五つのどれも一週間前までは全く分からなかったで、まずはその簡単な説明を書いておきます。
##curlコマンドとは？
curlコマンドとは、一言でいうと、"リクエストを送れるコマンド"と認識しています。Macを使っているひとは、最初からこのコマンドがですが、windowsを使っている人はいきなりはできないので、私はpostmanというソフトウェアをダウンロードしてそのアプリを使ってcurlコマンドを送っていました。このコマンドを使うと、jsonファイルを送ることができるので、そのファイルの中に必要な情報を入れて、その情報を送ることができます。
##AWSとは？
AWSとは、Amazonが提供しているクラウドプラットフォームの事です。でっかいサーバーという言葉が適切かはわかりませんが、僕はそう捉えてます。そこにPythonファイルを上げる(deploy)ことで、アプリケーションとして利用できるようになります。
##Sendgridとは？
Sendgridとは、メールを送信することができるサービスで、普通のメールだけではなく、HTMLメールという形式でもメールを送ることができますし、簡単にHTMLメールを作ることができます。とても便利でした。下の画像のような形で作れます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693681/3fad2153-fb92-8a8e-ec6d-8c590ca05b86.png)
#Pythonファイルに送る情報
まず、どのような情報をどうやって送っていたかを解説します。
下のコードが実際に僕が送っていたjsonファイルです。

```json

{
  "time": "time",
  "meeting_url": "meeting_url",
  "personal":[
     {
       "name": "name",
       "email": "email",
       "place": "place",
       "introduction": "introduction",
       "linkedin_url": "linkedin_url",
       "profile_image_url": "profile_image_url",
       "community": "community"
     },
     {
       "name": "name",
       "email": "email",
       "place": "place",
       "introduction": "introduction",
       "linkedin_url": "linkedin_url",
       "profile_image_url": "profile_image_url",
       "community": "community"
     }
  ]
}
```
今回私はマッチングサービスに携わらせていただいているのですが、私が作ったものはサービスの中でマッチングしたときに送るマッチングメール、ミーティングのリマインドメール、そしてレビューメールの3種類と、google calendarに情報を追加する仕組みです。この４つは上記の情報があればすべて生成することができました。そして、これを送るためのcurlコマンドは、

```
curl --location --request POST 'POSTするURL'\
--header 'Authorization: Authorization code'\ 
--header 'Content-Type: application/json'\ 
--data-raw '{
  "time": "time",
  "meeting_url": "meeting_url",
  "personal":[
     {
       "name": "name",
       "email": "email",
       "place": "place",
       "introduction": "introduction",
       "linkedin_url": "linkedin_url",
       "profile_image_url": "profile_image_url",
       "community": "community"
     },
     {
       "name": "name",
       "email": "email",
       "place": "place",
       "introduction": "introduction",
       "linkedin_url": "linkedin_url",
       "profile_image_url": "profile_image_url",
       "community": "community"
     }
  ]
}'
```
となっています。先述した通り、Macの場合、これをターミナルで実行するとそれだけで3通のメールとcalendarへの追加ができるようになります。


#google calendar編
次に、google calendarに自動で送信するコードについて紹介します。
とりあえず、コードを貼っておきます。

```python

def send_calendar(data):
    start_datetime=dateutil.parser.parse(data["parsed_time(開始時刻)"])
    end_datetime=start_datetime+datetime.timedelta(minutes=20)
    scopes = ["https://www.googleapis.com/auth/calendar.events"]
    secret_file = os.path.join(os.getcwd(), 'ファイル名.json')
    credentials = service_account.Credentials.from_service_account_file(secret_file, scopes=scopes, subject='件名')
    service = discovery.build('calendar', 'v3', credentials=credentials)
    summary='タイトル'
    location='場所'
    description="説明"
    
    event={
        'summary': summary,
        'location': location,
        'description': description,
        'start': {
            'dateTime': '開始時刻',
            'timeZone': "タイムゾーン"
        },
        'end': {
            'dateTime': '終了時刻',
            'timeZone': "タイムゾーン"
        },
        'attendees':[
            {
                'email': 'メールアドレス'
                },
            {
                'email': 'メールアドレス'
                },
            {
                'email': 'メールアドレス'
                }
        ],
        'organizer':{
            'email': '主催者メールアドレス'
        }
        }
        
    s = json.dumps(event, default=support_datetime_default)
    ev=service.events().insert(calendarId='カレンダーID', body=event, sendUpdates='all').execute()
    return make_response('',204)
```
eventという変数の中に必要な情報をすべて詰め込んでそれを下から2行目の```service.events().insert()```で一気に送るという感じになっています。eventの中の値を変化させることでもっといろんなことをgoogle calendarに追加することができます。詳細は[ここ](https://developers.google.com/calendar/v3/reference/events/insert)にあります。参考にしてみてください。そして、今登場した```event```の中身が、jsonファイル形式になっています。これから後も同じ形式でたくさんコードを書いていきます。

---

#Sendgrid編
Sendgridで自動的、というか設定次第で自動で任意の時間にメールを送れるようにする仕組みを解説します。今回もまた最初にコードを貼っておきます。

```python
def send_matching(data):
            
    url = '送り先のSendgridのURL'
    headers = {'Authorization': f'Bearer 各アカウントのAuthorization code'}
    review={
    "personalizations": [
        {
            "dynamic_template_data": {
                "first_name": data["name1"],
                "profile_image_url1": data["profile_image_url1"],
                "profile_image_url2": data["profile_image_url2"],
                "time": data["time"],
                "place": data["meeting_url"],
                "name1": data["name1"],
                "name2": data["name2"],
                "place1": data["place1"],
                "place2": data["place2"],
                "introduction1": data["introduction1"],
                "introduction2": data["introduction2"],
                "linkedin_url1": data["linkedin_url1"],
                "linkedin_url2": data["linkedin_url2"],
                "community": data["community"]
            },
            "to": [
                {
                    "email": "email送り先"
                    },
                {
                    "email": "email送り先"
                    }
            ],
            "cc": [
                {
                    "email": "カーボンコピー"
                    }
                ]      
        }
    ],
    "template_id": "使用するsendgridのメールテンプレートのID",
    "from": {
        "email": "email送信者"
    } 
}
    try:
        response = requests.post(url, headers=headers, json=review)
        print(review)
        print(vars(response))
        print(response.status_code)
    except Exception as e:
        print(e)

    return 0
```

このコードの中の```review```に注目してほしいのですが、sendgridでは様々な条件を指定してメールを送ることができます。この機能があるので予約送信なども簡単にできてしまいます。まず、```review```の中の大きなくくりの中に、
・"personalizations"
・"template_id"
・"from"
というのがあります。この層にはさらにたくさんの引数を入力することができて、
・reply_to
・subject
・content
・attachments
・sections
・headers
・categories
・custom_args
・send_at
・batch_id
・asm
・ip_pool_name
・mail_settings
・tracking_settings
というたくさんの値をセットすることができます。例えば、

```python
"send_at": 1612092888
```
という風にセットすればunixtimeの1612092888にメールが送信されます。さらに細かく載っているので、公式ホームページの[リンク](https://sendgrid.kke.co.jp/docs/API_Reference/Web_API_v3/Mail/index.html)も貼っておきます。
次に"template_id"について解説します。"template_id"とは。Sendgridの中のEmail APIのDynamic Templateを作った時に発行されるIDの事です。このDynamic Templateではノーコードで様々なHTMLメールを作ることができるため、とてもおすすめです。とても自由度が高いので満足いくまで作り込むことができます。そして、この"template_id"を指定してメールを送ることで、自分が作ったHTMLメールのデザインでメールを送ることができます。また、このtemplateを作るうえでもう一つ大事な要素があります。それはメールの引数の中にある"personalizations"です。この中身をもう一度表示します。

```python
"personalizations": [
        {
            "dynamic_template_data": {
                "first_name": data["name1"],
                "profile_image_url1": data["profile_image_url1"],
                "profile_image_url2": data["profile_image_url2"],
                "time": data["time"],
                "place": data["meeting_url"],
                "name1": data["name1"],
                "name2": data["name2"],
                "place1": data["place1"],
                "place2": data["place2"],
                "introduction1": data["introduction1"],
                "introduction2": data["introduction2"],
                "linkedin_url1": data["linkedin_url1"],
                "linkedin_url2": data["linkedin_url2"],
                "community": data["community"]
            },
            "to": [
                {
                    "email": "email送り先"
                    },
                {
                    "email": "email送り先"
                    }
            ],
            "cc": [
                {
                    "email": "カーボンコピー"
                    }
                ]      
        }
    ],
```
この"personalizations"の中には
・to
・cc
・bcc
・subject
・headers
・subsitutions
・custom_args
・send_at
という値が設定できます。ですがさらに"dynamic_template_data"という値も設定することができます。これはdynamic templatesの中で{{キー}}の形で書いた文字に代入することができます。![スクリーンショット (67).png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/693681/0ef901d1-a3ed-7c29-ee60-88122fc1e3dd.png)
このように{{name1}}などと書いておいて"dynamic_template_data"の中に

```
"name1": "Taro"
```
などと書いておけばメールで反映されてTaroという文字を送ることができます。そしてこの方法はメールの本文に使えるだけではなく、ボタンのリンクや、画像のURL指定にも応用ができます。つまり要約すると何でもできます。画像のURLを指定するには画像のHTMLを編集できるところへ移動して

```
src="{{表示したい画像のリンク}}"
```
と書けばOKです。プレビューには表示されませんが、値さえしっかりと指定すれば画像付きでメールを送ることも可能です。


---
今回私が学んだ内容はこのような感じです。もし何か間違っていることなどあれば指摘していただけたら幸いです。