Event WebhookをHerokuで受けてSlackに通知する

Event WebhookをHerokuで受けてSlackに通知する

こんにちは!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を取得できます。

Cleate a Slack App

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

今回は手軽にEvent Webhookの通知を受け取る例として、Slackへの投稿を紹介してみました。Integromatなどのウェブサービス連携ツールでもっと簡単に通知することも可能なので、機会があれば紹介したいと思います。今回の仕組みは私が実際に利用しているもので、Event Webhookの挙動を見るためにPOSTされたJSONをそのまま表示させています。このようなカスタマイズの柔軟さがノーコードツールにはないプログラムの強みでしょうか。

実際の運用上、メールのバウンスを管理したり、マーケティングメールの開封率を測ったりするには、Slack等への通知だけではなくDBへのデータの蓄積等も必要になると思いますが、Event Webhookに触れるきっかけとして本記事が参考になれば幸いです!

メールを成功の原動力に

開発者にもマーケターにも信頼されているメールサービスを利用して、
時間の節約、スケーラビリティ、メール配信に関する専門知識を手に入れましょう。