Event WebhookをHerokuで受けてSlackに通知する
- 2020年12月22日
- by 吉田 健人
- Category: 技術ネタ
こんにちは!SendGridサポートチームの吉田です。
SendGridで送ったメールの到達やバウンス等の各イベントを通知する機能として、Event Webhookがあります。基本的な紹介とPythonによる動作確認例は以前ブログ記事にしましたが、それをSlackに通知する形で実装してみました。トップ画像のようなフローです。
今回は、クラウド上でアプリケーションを開発・運用できるPaaS「Heroku」を使いました。Event Webhookではイベント情報を任意のURLにPOSTできますが、これをHerokuにおいたPythonスクリプトで受け、適切に整形した上でSlackに受け渡します。
必要なものは以下の通りです。
Slackの準備
最初に、イベントの投稿先であるSlackを準備します。Slackには、決まった形のJSONをPOSTすると指定のチャンネルに投稿できるIncoming Webhookという機能があります。手順はこちらの公式ドキュメントに記載されている通りで、複雑ではありません。最初に「App」を作成しますが、名前を「Event Webhook」としておきます(この名前でSlackに投稿されます)。投稿先のWorkspaceを選択してAppを作成したら、Appのホーム画面からIncoming Webhookのページを開いて有効化し、投稿するチャンネルを選びます。すると、投稿したい内容をPOSTするURLを取得できます。
Herokuへのデプロイ
次にローカル上で、HerokuのAppの準備をしていきます。
まず新しいディレクトリを作成し、そこでGitのリポジトリとHerokuのAppを作成します。Appの名前はAppのURLに用いられるため、Heroku内でユニークである必要があります。ここではevent-webhook-slackとしました。
$ git init $ heroku create event-webhook-slack Creating ⬢ event-webhook-slack... done https://event-webhook-slack.herokuapp.com/ | https://git.heroku.com/event-webhook-slack.git
環境が整ったら、Appに必要な3つのファイルを用意していきます。
1. index.py
最初は動作の肝となるPythonスクリプトです。名前はindex.pyとします。
import os, requests from flask import Flask, request from json import dumps slack_incoming_webhook = os.environ['SLACK_INCOMING_WEBHOOK'] app = Flask(__name__) @app.route('/', methods=['POST']) def main(): data_list = request.get_json() block_list = [] for data in data_list: dumped = dumps(data, indent=2) event_name = data["event"] block_list.append({'type': 'section', 'text': {'type': 'mrkdwn', 'text': f'*{event_name}*```{dumped}```'}}) headers = {'Content-Type': 'application/json'} slack_json = dumps({'blocks': block_list}) requests.post(slack_incoming_webhook, headers=headers, data=slack_json) return "" if __name__ == '__main__': app.run(debug=True, host='0.0.0.0', port=int(os.environ.get('PORT', 3000)))
Event WebhookのPOST内容を受け取り、Slack投稿用にデータを整形するスクリプトになっています。POSTを受け取るまでは以前書いたブログと同じ流れなので、そちらの説明も参考にしてください。受け取ったデータは、Slackが定義しているペイロードの形に変換しています。一つのPOSTに複数のイベントが含まれる可能性があるので、Slackの投稿メッセージのBlockという形式を用いて、一つのイベントごとに一つのブロックを割り当てています。各ブロックの中では、イベントの種類を太字で、POSTされたEvent WebhookのJSON全体をコードブロックで表示するようマークダウンを指定しています(18行目)。どういうJSONを指定するとSlackにどんなメッセージが投稿されるかは、ブラウザ上でも試すことができ便利です。
2. requirements.txt
index.py中で必要なPythonライブラリを指定したファイルです。以下のようにpipコマンドで作成します。
$ pip freeze > requirements.txt
3. Procfile
Heroku上で実行するコマンドを定義したファイルです。拡張子は必要ありません。中身は以下の通りです。
web: python index.py
ここまでできたら、ディレクトリ配下のファイルをコミット、デプロイします。
$ git add * $ git commit -m "Commit to heroku" $ git push heroku master
デプロイが完了すると、AppのURLが表示されます。今回の場合は、https://sg-event-webhook.herokuapp.com/となります。これは後で用います。
index.pyの中ではSlackのIncoming WebhookのURLを環境変数として取得するようにしているので(5行目)、最後に、先ほどSlackで取得したURLをHerokuのAppの環境変数として設定します。
$ heroku config:set SLACK_INCOMING_WEBHOOK=https://hooks.slack.com/services/hoge/huga
HerokuにおけるPythonアプリの作成方法については、公式のGet Startedページも参考になります。
SendGridの設定と挙動確認
最後にSendGridのEvent Webhookの設定をして動作を確認するだけです。設定はSendGridダッシュボード上から可能です。詳細は以前のブログを参考にしてみてください。以前の記事とはWebhookの通知先URLだけが異なり、今回は、取得したHeroku AppのURL https://sg-event-webhook.herokuapp.com/ を指定します。「Test Your Integration」ボタンを押して、Slackにイベントが通知されることを確認してください!
今回は手軽にEvent Webhookの通知を受け取る例として、Slackへの投稿を紹介してみました。Integromatなどのウェブサービス連携ツールでもっと簡単に通知することも可能なので、機会があれば紹介したいと思います。今回の仕組みは私が実際に利用しているもので、Event Webhookの挙動を見るためにPOSTされたJSONをそのまま表示させています。このようなカスタマイズの柔軟さがノーコードツールにはないプログラムの強みでしょうか。
実際の運用上、メールのバウンスを管理したり、マーケティングメールの開封率を測ったりするには、Slack等への通知だけではなくDBへのデータの蓄積等も必要になると思いますが、Event Webhookに触れるきっかけとして本記事が参考になれば幸いです!