はじめに

こんにちは!ミルディアの藤井です。この記事では、Bolt for Python を使って Slack bot を作成します。筆者は Windows プログラム経験はあるものの Web / Python 関連は初学者。 そんな著者が、Bolt フレームワークを使用して Slack bot を作成するまでの顛末です。

開発用PC は Windows 11。さて、どうなりますやら。

参考にした記事)
https://slack.dev/bolt-python/ja-jp/tutorial/getting-started-http

はじめの一歩編

さて、Slack botの世界へ足を踏み入れましょう。
ここでは、練習用の Slack ワークスペースを作って、Slack アプリ をワークスペースに登録します。

そもそも Slack bot とはなんぞや

Slack とやり取りするアプリのことです。

アプリサーバと Slack とのやり取りの形式に ソケットモードと HTTP モードとがありますが、この記事では HTTP モードを扱います。

練習用 Slack ワークスペースの作成

まずは、練習用の Slack ワークスペースを作ります

これは、いきなり本番に突入するのを避けるためであって、必須ではありませんが、作ったほうが良いでしょう。無料だし。

Slack アプリの登録

https://api.slack.com/apps/ にアクセスしたら、[Create New App] をクリックします。するとダイアログが表示されます。

何事も勉強なので、From scratch を選択。

アプリの名前「Flower」と、さっき作った ワークスペースをインストール先として設定します。

[Create App] をクリックすると、アプリが登録されます。

トークンとアプリをインストール

左サイドバーの「OAuth & Permissions」をクリックしてページを開き、「Bot Token Scopes」セクションまで下にスクロール。「Add an OAuth Scope」をクリックします。

chat:write を探してクリックすれば、メッセージを投稿するスコープが追加されます。

ページの上のほうの OAuth Tokens までスクロールし、「Install to <ワークスペース名>」をクリックします。

すると、 Slack の OAuth 確認画面 が表示されるので、Allow を押してインストールを承認しましょう。

すると Bot User OAuth Access Token が確認できるようになります。このトークンはあとで使います。

これで、FlowerVase ワークスペースに、アプリ Flower が登録されました!

Python設定編

ここでは、Windows PC で開発するために、Python の環境設定を行います。

Python のインストール

下記サイトなどを参考にして、Python をインストールします。https://www.python.jp/install/windows/install.html

プロジェクトフォルダの作成

適当なフォルダにプロジェクトフォルダを作成します。

> mkdir flower
> cd flower

仮想環境の作成

次に、めんどうな依存関係を管理するため、Python 仮想環境  をつくります。

参考にしたサイト)
https://packaging.python.org/en/latest/guides/installing-using-pip-and-virtual-environments/

pip のインストール

> py -m pip install --upgrade pip
> py -m pip --version

virtualenv のインストール

> py -m pip install --user virtualenv

仮想環境のインストール

> python -m venv .venv

仮想環境のアクティベート

> .venv\Scripts\activate

仮想環境の確認
プロジェクトフォルダ内の Python を指していることを確認します。

(.venv) > where python

仮想環境の終了

> .venv\Scripts\deactivate

トークンを仮想環境に設定する

アプリの設定時に作成された ボットトークン と 署名シークレット を環境変数として仮想環境に保存しましょう。

SLACK_SIGNING_SECRET:Basic Information ページの Signing Secret
SLACK_BOT_TOKEN: OAuth & Permissions ページの Bot User OAuth Token

仮想環境の環境変数にセットします。

(.venv)>SET SLACK_SIGNING_SECRET=XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
(.venv)>SET SLACK_BOT_TOKEN=xoxb-XXXXXXXXXXXXX-XXXXXXXXXXXXX-XXXXXXXXXXXXXXXXXXXXXXXX

アプリ作成のためのプロキシ初期設定

Slack とローカルに作ったサーバを通信させます。
初期設定のために、まずはダミーの bot を作成します。

Bolt フレームワークのインストール

仮想環境にBolt フレームワークをインストールします。

(.venv) > pip install slack_bolt

ダミーアプリファイルの作成

プロジェクトフォルダに「app.py」という名前の新しいファイルを作成し、以下のコードを記述します。

import os
from slack_bolt import App

# ボットトークンと署名シークレットを使ってアプリを初期化します
app = App(
    token=os.environ.get("SLACK_BOT_TOKEN"),
    signing_secret=os.environ.get("SLACK_SIGNING_SECRET")
)

# 'hello' を含むメッセージをリッスンします
@app.message("hello")
def message_hello(message, say):
    # イベントがトリガーされたチャンネルへ say() でメッセージを送信します
    say(f"Hey there <@{message['user']}>!")

# アプリを起動します
if __name__ == "__main__":
    app.start(port=int(os.environ.get("PORT", 3000)))

アプリの起動

> .venv\Scripts\activate
(.venv) > python app.py

「Bolt app is running! (development server)」と表示されればアプリ起動成功です。
Ctrl+c で停止しましょう。

アプリサーバ設定編

Slack でメッセージが投稿されたときに返事をするなど、イベントに反応するようにしましょう。

サーバを立てる

イベントのリスナーを指定するために 公開 URL が必要なので、サーバを立てます。ここでは、プロキシサービスを使って公開 URL を作成し、Slack からのリクエストをローカルPCにトンネリングします。

ngrok のインストール

ここでは、プロキシサービスとして ngrok を使います。
https://ngrok.com/
サインアップし、ログインすると、Authtoken が発行されます。

参考にしたサイト)
https://www.mgo-tec.com/blog-entry-ngrok-install.html

左ペインの Getting Started > Your Authtoken で確認できます。

Getting Started > Setup & Installation からバイナリをダウンロードし、unzip した  ngrok.exe をパスの通ったところに置きます。

その後、Getting Started > Command Line に記載の通り実行すると、Authtoken が適当なディレクトリに配置されます。

> ngrok config add-authtoken XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

サーバーアプリの起動

アプリを起動します。

> .venv\Scripts\activate
(.venv)> python app.py
Bolt app is running! (development server)

ngrok の起動

アプリが起動している状態で、別のコマンドプロンプトから

> ngrok http 3000

でトンネリングが開始されます。

Slackイベントのリッスン

Slack でのイベント(メッセージが投稿されたときや、メッセージに対するリアクションがつけられたときなど)をアプリでリッスンします。

アプリ管理ページでアプリをクリックします。次に、左サイドバーの「Event Subscriptions」をクリックします。「Enable Events」というラベルのスイッチをオンに切り替えます。

つぎに、Request URL に、ngrok でトンネリングしている URL に「/slack/events」を追加したものを設定していきます。

上の例なら、下記のようになります。

https://XXXX-XXXX-XXX-XXXX-XXXX-XXXX-XXXX-XXXX-XXXX.ngrok-free.app/slack/events

次に、どのイベントをリッスンするか設定します。

Subscribe to Bot Events で、Add Bot User Event ボタンから次の4つのイベントを追加します。

  • message.channels :アプリが参加しているパブリックチャンネルのメッセージをリッスン
  • message.groups :アプリが参加しているプライベートチャンネルのメッセージをリッスン
  • message.im :あなたのアプリとユーザーのダイレクトメッセージをリッスン
  • message.mpim :あなたのアプリが追加されているグループ DM をリッスン

設定できたら、Save Changes で保存しましょう。

警告が出たら、OAuth 確認画面 で、Allow を押してインストールを承認しましょう。

Slack 上でテスト

ここまで出来たら、もう動くはずです。 Slack で ”hello” と投稿してみましょう。

アプリを作ろう編

とりあえず動いたので、機能を追加していきます。

インタラクティブイベントのリッスン

アプリ設定ページに戻って、Interactivity & Shortcuts ページを開きます。

Interactivity を ON にし、Request URL には、さきほどと同じ、 ngrok でトンネリングしている URL に 「/slack/events」を追加したものを設定します。
これで、bot のメッセージにボタンなどをつけることができるようになりました。

import os
from slack_bolt import App

# ボットトークンと署名シークレットを使ってアプリを初期化します
app = App(
    token=os.environ.get("SLACK_BOT_TOKEN"),
    signing_secret=os.environ.get("SLACK_SIGNING_SECRET")
)

# 'hello' を含むメッセージをリッスンします
@app.message("bloom")
def message_bloom(message, say):
    # イベントがトリガーされたチャンネルへ say() でメッセージを送信します
    say(
        blocks=[
            {
                "type": "section",
                "text": {"type": "mrkdwn", "text": f"<@{message['user']}>、何を咲かせますか?"}
            },
            {
                "type": "actions",
                "elements": [
                    {
                        "type": "button",
                        "text": {"type": "plain_text", "text":"ひまわり"},
                        "style": "primary","action_id": "button_sunflower_click"
                    },
                    {
                        "type": "button",
                        "text": {"type": "plain_text", "text":"チューリップ"},
                        "style": "primary","action_id": "button_tulip_click"
                    }
                ]
            }
        ],
        text=f"Hey there <@{message['user']}>!"
    )

@app.action("button_sunflower_click")
def action_button_sunflower_click(body, ack, say):
    # アクションを確認したことを即時で応答します
    ack()
    # チャンネルにメッセージを投稿します
    say(f":sunflower:<@{body['user']['id']}>:sunflower:")

@app.action("button_tulip_click")
def action_button_tulip_click(body, ack, say):
    # アクションを確認したことを即時で応答します
    ack()
    # チャンネルにメッセージを投稿します
    say(f":tulip:<@{body['user']['id']}>:tulip:")

# アプリを起動します
if __name__ == "__main__":
    app.start(port=int(os.environ.get("PORT", 3000)))

おわりに

以上、Slack bot を動かすまでを駆け足で紹介いたしました。できれば行き詰ったお話をしたかったのですが、終始スムーズにいきました。最近のドキュメントは親切ですね。Windows であるゆえの問題もありませんでした。

本稿があなたの Slack ライフをすこしでも快適にできれば幸いです。