Slack API のイベントを Django で受け取るには

Slack には、チャンネルへのメッセージ投稿やリアクションの追加など、ワークスペース内で発生するさまざまなアクションをリアルタイムに通知してくれる Event Subscriptions(イベント購読)機能があります。
この機能を活用すれば、Slack 上の操作をトリガーにして独自の処理を実行するボットやツールを構築できます。

本記事では、Django で構築したサーバーで Slack API のイベントを受け取る方法を解説します。あわせて、Slack の管理画面でエンドポイント URL を登録する際に必要となる URL 認証(url_verification)の実装方法も紹介します。

実装コード

まずは処理の全体像を示します。
以下のビューを作成し、その URL を Slack の Event Subscriptions に登録することで、Slack からのイベント通知を受信できるようになります。

@method_decorator(csrf_exempt, name="dispatch")
class SlackMessageManagerView(ViewMixin, View):
    """Slack の Webhook URL"""
    def post(self, request: HttpRequest, *args: Any, **kwargs: Any) -> HttpResponse:
        try:
            body_data = json.loads(request.body.decode("utf-8"))
            match body_data["type"]:
                case "url_verification":
                    return JsonResponse(body_data)

コードの解説

このビューのポイントを順に説明します。

まず、Slack からのリクエストは POST メソッドで送信されるため、post メソッドで受け取ります。また、Slack は Django の CSRF トークンを送信しないため、csrf_exempt デコレーターで CSRF 検証を無効にしています。

リクエストボディを JSON としてパースした後、body_data["type"] でイベントの種類を判別し、match 文で処理を分岐させます。

上記のサンプルコードに含まれている "url_verification" は、Slack の管理画面にエンドポイント URL を登録する際に Slack が送信する認証リクエストへの応答です。Slack は認証用のチャレンジトークンをリクエストボディに含めて送信してくるため、そのデータをそのまま JSON レスポンスとして返すことで認証が完了します。

この match 文に case を追加していくことで、メッセージ受信(event_callback)など、さまざまなイベントに対する独自の処理を実装できます。

まとめ

Django で Slack API のイベントを受け取るには、CSRF を無効にしたビューを作成し、リクエストボディの type フィールドでイベントの種類を判別して処理を分岐させます。
まずは url_verification による認証を実装し、Slack の管理画面にエンドポイントを登録できる状態を作ったうえで、必要なイベントへの対応を順次追加していくのがスムーズな進め方です。