APC 技術ブログ

株式会社エーピーコミュニケーションズの技術ブログです。

株式会社 エーピーコミュニケーションズの技術ブログです。

Bolt Framework × PythonでSlack Botを作る(ボイラープレート編@2023.11版)

こんにちは!ACSD松崎です。OpenAI APIがリリースされてから、Slack Botを作る機会が個人的に増えました。それを踏まえて今日は、SlackのBolt Frameworkを使って、ChatBotの叩き台を作るチュートリアル手順をまとめたいと思います。

前提

  • PythonでBolt Frameworkを使って、Slack Botを構築します。
  • Bolt FrameworkではSlack Botを実行する何らかのComputing Nodeの用意が必要となります。この手順では、任意のLinux VM上で、docker composeを使ってSlack Botを動かします。
  • Slackのサーバー側とクライアント側の通信にはSocket Modeを利用します。
  • 各種クレデンシャルの管理には、docker composeの .env ファイルを利用します

手順

1. Slack GUIを操作し、appを作成する

まず最初にSlackの管理画面にアクセスし、 Create New App をクリックします。 https://api.slack.com/apps/new

遷移後の画面にて、 From scratch を選択します。

次の画面では、Slack Botのアプリケーション名とBotを導入するSlackスペース名を選択して Create App を選択します。

Slack Appの管理画面に遷移しますので、左サイドバーの OAuth & Permissions をクリックし、Bot Token Scopes セクションまで下にスクロールします。

Add an OAuth Scope をクリックし、以下の権限を付与します。※動作確認用に広めに権限を付与しています。不要な権限については、アプリのビジネスロジック実装後に削除することをお勧めします。

- app_mentions:read
- channels:history
- chat:write
- groups:history
- im:history
- mpim:history
- users:read

その後、画面をスクロールし最上部に戻り、 Install to workspace をクリックします。

遷移後の画面で 許可する を選択します。

遷移後の画面で、 Bot User OAuth Token の欄にある Copy をクリックし、クリップボードに保管されたTokenをローカルのメモ帳に記録します。このTokenは後程使います。

次に、画面左部のサイドバーより Basic Information に移動します。

App-Level Tokens にて Generate Token and Scopes をクリックします。

Token nameを入力後、Scopeにて connections:write を選択し、 Generate をクリックします。

Copy をクリックし、クリップボードに保管されたTokenをローカルのメモ帳に記録します。このTokenは後程使います。

最後に、画面左部のサイドバーより Socket Mode に移動します。

Connect using Socket Mode 配下の Enable Socket Mode のトグルボタンをおして、Socket Modeを有効化します。

ここまでで、Slack GUI上の作業は一端完了となります。

2. Linux上でPython×Bolt FrameworkにてBotを実装する

Linux VM上で、Slack ClientのPythonの実装を作っていきます。

まずは、pythonの仮想環境を作成します。

$ mkdir my-slackbot
$ cd my-slackbot/

$ python3 -m venv .venv
$ source ./.venv/bin/activate

次に、requirements.txtを作成し、それを元にpip installを実行します。 ※requirements.txtを使うのは、後工程となるアプリのDocker化の際に再利用するためです。

 $ cat requirements.txt
slack-bolt==1.18.0
slack-sdk==3.21.3

$ pip install --no-cache-dir -r requirements.txt
Collecting slack-bolt==1.18.0
  Downloading slack_bolt-1.18.0-py2.py3-none-any.whl (194 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 194.6/194.6 KB 5.3 MB/s eta 0:00:00
Collecting slack-sdk==3.21.3
  Downloading slack_sdk-3.21.3-py2.py3-none-any.whl (276 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 276.5/276.5 KB 134.5 MB/s eta 0:00:00
Installing collected packages: slack-sdk, slack-bolt
Successfully installed slack-bolt-1.18.0 slack-sdk-3.21.3

環境変数についても、後段のDocker化のタイミングで .env に保存しますが、ここでは一端、Linuxの環境変数として宣言します。 SLACK_BOT_TOKEN には、前段で保存の Bot User OAuth Token の値を、また、 SLACK_APP_TOKEN には前段で取得の App-Level Token の値を入力してください。

export SLACK_BOT_TOKEN=xoxb-<ボットトークン>
export SLACK_APP_TOKEN=<アプリレベルトークン>

ここまでで、事前作業が一通り完了しましたので、ここからは実際にSlack Botを実装していきます。 まずは、もっともシンプルな構成のアプリを作成し、起動に成功することを確認しましょう。

$ cat app.py
import os

from slack_bolt import App
from slack_bolt.adapter.socket_mode import SocketModeHandler

# ボットトークンとソケットモードハンドラーを使ってアプリを初期化します
app = App(token=os.environ.get("SLACK_BOT_TOKEN"))

# アプリを起動します
if __name__ == "__main__":
    SocketModeHandler(app, os.environ["SLACK_APP_TOKEN"]).start()

$ python3 app.py
⚡️ Bolt app is running!

無事、起動に成功したら、今度はSlackからのメッセージを受信し、返信する処理を追加します。まず以下のようにコードを修正し、

import json
import os

from slack_bolt import App
from slack_bolt.adapter.socket_mode import SocketModeHandler

# ボットトークンとソケットモードハンドラーを使ってアプリを初期化します
app = App(token=os.environ.get("SLACK_BOT_TOKEN"))

@app.message("hello")
def message_hello(message, say):
    print(json.dumps(message,indent=2))
    print("message received")

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

# アプリを起動します
if __name__ == "__main__":
    SocketModeHandler(app, os.environ["SLACK_APP_TOKEN"]).start()

次に、Slack GUIの画面に戻り、 Event Subscriptions を選択します。いったん、Botが参加可能な場所全てのメッセージをリッスンさせる設定にします。 ※本記事の手順では message.channels のみでもOKです。

これで、Slackのイベントがpythonで実装のSlak Botに通知されるようになりました。早速、動作確認をしてみましょう。

任意のSlackチャンネルを開き作成したBotの名前をメンションすると以下のダイアログがポップアップしますので、 チャンネルに追加する を選択します。

再度、Botの名前をメンションし、応答が返ってくることを確認します。

3. アプリケーションをDockerコンテナ化する

最後に、ここまで作成したアプリを docker compose コマンドで操作できるようにしていきます。

まずは、docker composeにクレデンシャルを環境変数経由で読み込ませるために.env を以下のように作成します。

$ cat ./.env
SLACK_BOT_TOKEN=xoxb-xxx
SLACK_APP_TOKEN=xapp-xxx

次にDockerfileを作成します。

$ cat Dockerfile

# Python3.8をベースとするDockerイメージを指定
FROM python:3.8-slim-buster

# ワーキングディレクトリを設定
WORKDIR /app

# アプリケーションの依存関係をコピー
COPY requirements.txt .

# 依存関係をインストール
RUN pip install --no-cache-dir -r requirements.txt

# アプリケーションのソースをコピー
COPY . .

# アプリケーションのエントリーポイントを指定
CMD [ "python", "./app.py" ]

最後に、docker composeファイルを作成します。

$ cat docker-compose.yml
version: '3.8'
services:
  python-gpt:
    build: .
    environment:
      - SLACK_BOT_TOKEN=${SLACK_BOT_TOKEN}
      - SLACK_APP_TOKEN=${SLACK_APP_TOKEN}
      - SLACK_BOT_ID=${SLACK_BOT_ID}
      - OPENAI_API_KEY=${OPENAI_API_KEY}

ここまでの作業が完了しましたら、以下3点を確認してください。

  1. docker compose up -d --build でコンテナの起動に成功すこと
  2. ↑ の完了後、 docker ps を実行し、コンテナが異常終了しないで起動し続けていること
  3. Slackチャンネル上からSlack Botをメンションし、応答が返ってくること

終わりに

いかがでしたでしょうか?このような感じで、叩き台となる実装が動く状態を作ったうえで、実際のビジネスロジックを乗せていく進め方をすると、開発がインクリメンタルなり捗るかと思います。

私達ACS事業部はAzure・AKSなどのクラウドネイティブ技術を活用した内製化のご支援をしております。ご相談等ありましたらぜひご連絡ください。

www.ap-com.co.jp

また、一緒に働いていただける仲間も募集中です!
今年もまだまだ組織規模拡大中なので、ご興味持っていただけましたらぜひお声がけください。

www.ap-com.co.jp

本記事の投稿者: Shin Matsuzaki
個人ブログ