SendGridのイベントをLogic Apps経由でSlackに通知する

メール配信したい場合、AWSではSESがありますが、AzureではSendGridを使用することが推奨されています。
SendGridをガッツリ使う場合は、配信失敗の監視など、運用も考慮する必要がありますのでそのあたりを書いていきます。

# SendGridアカウント準備
* 公式ページを参照してSendGridアカウントを用意しましょう。
[SendGrid アカウントの作成](https://docs.microsoft.com/ja-jp/azure/sendgrid-dotnet-how-to-send-email#create-a-sendgrid-account)

* Azure上でSendGridアカウントを作成したら、ポータルのSendGridアカウント画面より[Manage]を押してSendGrid管理画面を開きます。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/f6fcee1e-69fb-2239-3026-c504e9c6452d.png)
<br>

* こんな感じです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/020b4b4a-9200-8bb2-d818-ae99ab4f2115.png)

# まずは送信制限の監視から
プランによって月のメール送信数の上限が決まっているのでまずはこれを監視したいと思います。
※この図は全プランを表示しているわけではありません
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/b6c0c706-e43a-cbd2-0116-5ca7b020f351.png)
<br>

* [Settings]→[Alert Settings]を選択します
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/a761380d-362a-f7ef-51ed-99e617bdea10.png)
<br>

* [New Alert]を選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/ecc846a8-e3a4-3248-b107-fc0d3e647ed4.png)
<br>

* 上限の何％使ったら通知させるかと、通知先のメールアドレスを入力すればOKです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/61053d87-73ca-7a6d-5b75-2a2690f60688.png)
<br>

# メール配信の失敗を検知させる
次にメール配信に失敗した場合の検知を考えてみます。
Event Webhookという、何かイベントが発生したら指定したURLにPOSTする機能があったのでこれが使えそうです。

SendGridからの送信先を直接SlackのIncoming WebhookのURLに指定しても通知できないので、一度LogicAppsを間に入れて、JSONをパースしてからSlackに通知する必要があります。

## Logic Apps準備
* 公式ページを参照してLogic Appsを作成しましょう。
[ロジックアプリを作成する](https://docs.microsoft.com/ja-jp/azure/logic-apps/quickstart-create-first-logic-app-workflow#create-your-logic-app)

* HTTP要求トリガーを作成します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/5687dc4b-8b93-709b-dddd-019471dd04e7.png)
<br>

* 一旦ここではこのまま[アクションの追加]を選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/7b11b236-5edd-01ec-fe29-a427f4eeb491.png)
<br>

* Slackアクションの[投稿メッセージ]を選択します。Slackアカウント認証を求められたら自分のSlackIDとパスワードを入れて認証させます。
* チャネルは任意のものを、メッセージテキストには[本文]をそのまま入力します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/a55fc3db-9a42-5d92-0780-39aa1f64ecd5.png)
<br>

* この状態で[保存]します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/96bfd425-fad8-63ea-8888-667822b20405.png)
<br>

* 保存するとHTTP POST URLが発行されるので、このURLをコピーしておきます
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/a366b190-b4f7-b4e3-00b5-b86809464676.png)
<br>

## SendGrid Event Webhook準備
* SendGrid管理画面に戻って、[Settings]→[Mail Settings]を選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/f6de7c3d-64ad-fcfa-a281-a90c6d8ef184.png)
<br>

* [Event Notification]を選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/4ba59314-ce3f-b01c-ca56-f3c5456bf584.png)
<br>

* 検知したいイベントを選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/6628085c-53c9-91b6-ca9b-d84b9bfecd0c.png)
<br>

* HTTP POST URLに先程のURLを入れて、[Test Your Integration]を押します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/97633155-fd56-a2e7-dd71-b8cdedd7325d.png)
<br>

* しばらく待つと、SlackにJSON生データが送られてくるはずです。見辛いので次にメッセージの見栄えをよくしたいと思います。

## JSONパース
* Logic Appsに戻って、HTTP要求の[サンプルのペイロードを使用してスキーマを生成する]を選択します。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/2290c608-95a9-d6e3-0607-a8dff5421717.png)
<br>

* ここに、さっきSlackで受信したJSONを丸々コピペします。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/c1a97f8a-f21a-cce7-a06e-dff12ac03a02.png)
<br>

* JSONスキーマが自動生成されればOKです。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/8a19688e-316d-045f-aba4-c829711765b1.png)
<br>

* 次にSlack投稿メッセージを選択すると、先程は本文しか選べなかったけど、色々選べるようになっていると思います。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/f5dac1c9-e00d-c13e-74a9-4e84b8c0df57.png)
<br>

* メッセージテキストに細かく項目を入れていきます。通知するオブジェクトは適宜変えて下さい。
  ※ここでJSONスキーマオブジェクトを選択すると、なぜか「For each」の中に入ります。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/89a6655f-03bb-13c9-447a-0b6762e1ad6e.png)
<br>

* この状態で保存しましょう。これで準備完了です。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/148ddf6d-0224-fb08-2109-e8484505317e.png)
<br>

# テストしてみる
存在しない宛先にメールを送ってちゃんと検知するか試してみます。

* Cloud Shell (PowerShell) を開きます。やり方は公式サイトで。
[Azure Cloud Shell PowerShell のクイックスタート
](https://docs.microsoft.com/ja-jp/azure/cloud-shell/quickstart-powershell)

* 以下をコピペして実行します。中身は適宜変えてください。$MailToには存在しないメールアドレスを入れてください。

```powershell
$SmtpServer = 'smtp.sendgrid.net'
$Port = 587
$UserName = 'azure_xxxxxxxxxxxxxxxxxxxxx@azure.com'
$Password = '[your password]'

$MailFrom = 'test@example.com'
$MailTo = '[your mail]'
$Subject = 'Test Mail'
$Body = 'This is test'

$pwd = ConvertTo-SecureString -String $Password -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential $UserName,$pwd

Send-MailMessage -UseSsl -From $MailFrom -To $MailTo -Subject $Subject -Body $Body -SmtpServer $SmtpServer -Port $Port -Credential $cred
```

* こんな感じで通知されれば成功です！  
![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/80559e51-c077-3ba1-fc65-d2ce0671cdb1.png)
<br>

# Logic Appsの失敗を検知する
せっかくメール配信の失敗を検知できるようになったのに、なんらかのエラーでLogic Apps自体が失敗した場合、メール配信失敗を検知することができません。

Logic Appsの監視はメトリックアラートで実現できます。
Runs Failedメトリックが1以上のときに検知するように設定しましょう。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/180335/fb8ac110-ba9f-5350-ce12-0ca8442e89ac.png)
<br>