概要
BoltとPythonを使ってSlack Appをローカル上で実行する方法について解説します
前提
- Pythonを使用
- Docker、docker-compose.ymlを使用
- Poetryを使用
- Slackのワークスペースを作成済み
ディレクトリ構成
tree
.
├── .env
├── .gitignore
├── Makefile
├── README.md
├── application
│ ├── app.py
│ ├── poetry.lock
│ └── pyproject.toml
├── containers
│ └── python
│ └── Dockerfile
└── docker-compose.yml
Slack Appの作成
SlackのAppを以下のリンクから作成します
左のOAuth&PermissionsからBot Token Scopesへ移動し、Add an OAuth Scope
を押します
Bot User OAuth Tokenが表示されます
後ほど使用します
Basic Informationのページまで戻り、アプリトークンのセクションまで下にスクロールしGenerate Token and Scopesをクリックしてアプリレベルトークンを作成します
ソケットモードを有効にします
スライダーを右にスライドします
Bot Eventを追加します
今回は
- message.channels
- message.groups
- message.im
- message.mpim
を選択します
また、インタラクティブ機能を有効にすると、ボタン、選択メニュー、日付ピッカー、モーダル、ショートカットなどの機能が利用できるようになります
アプリ設定ページの「Interactivity & Shortcuts」にアクセスしてください
Slack App側の設定は以上です
環境構築
Python用のDockerfileを作成します
FROM python:3.12.3
ENV PYTHONDONTWRITEBYTECODE=1
ENV PYTHONUNBUFFERED=1
WORKDIR /code
COPY application/pyproject.toml /code/
# Initialize python project with Poetry
RUN pip install --upgrade pip && pip install poetry
RUN poetry install
Dockerfileを簡単に起動できるようdocker-composeを作成します
services:
app:
container_name: app
build:
context: .
dockerfile: containers/python/Dockerfile
volumes:
- ./application:/code
ports:
- "8000:8000"
command: poetry run python app.py
env_file:
- .env
PoetryでPythonのパッケージを管理したいのでpyproject.tomlを作成します
Slack Appを使用する際はslack-boltが必須なので追加します
[tool.poetry]
name = "slack-workflow-practice"
version = "0.1.0"
description = ""
authors = ["shun198"]
readme = "README.md"
[tool.poetry.dependencies]
python = "3.12.3"
slack-bolt = "^1.19.0"
[tool.poetry.group.dev.dependencies]
black = "^24.0.0"
isort = "^5.11.4"
[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"
[tool.isort]
line_length = 79
profile = "black"
[tool.black]
line-length = 79
include = '\.py$'
exclude = '''
(
/(
\.eggs # exclude a few common directories in the
| \.git # root of the project
| \.hg
| \.mypy_cache
| \.tox
| \.venv
| _build
| buck-out
| build
| dist
)/
)
'''
今回はパブリックチャンネルにhello
というメッセージを送ったらHey there というメッセージがアプリから送られ、 Click Me
というボタンが表示され、Click Me
を押した後にメンションされた状態でclicked the button
というメッセージをAppが送信するAppを作成します
import os
from slack_bolt import App
from slack_bolt.adapter.socket_mode import SocketModeHandler
# ボットトークンと署名シークレットを使ってアプリを初期化します
app = App(token=os.environ.get("SLACK_BOT_TOKEN"))
# 'hello' を含むメッセージをリッスンします
@app.message("hello")
def message_hello(message, say):
# イベントがトリガーされたチャンネルへ say() でメッセージを送信します
say(
blocks=[
{
"type": "section",
"text": {"type": "mrkdwn", "text": f"Hey there <@{message['user']}>!"},
"accessory": {
"type": "button",
"text": {"type": "plain_text", "text":"Click Me"},
"action_id": "button_click"
}
}
],
text=f"Hey there <@{message['user']}>!"
)
@app.action("button_click")
def action_button_click(body, ack, say):
# アクションを確認したことを即時で応答します
ack()
# チャンネルにメッセージを投稿します
say(f"<@{body['user']['id']}> clicked the button")
# アプリを起動します
if __name__ == "__main__":
SocketModeHandler(app, os.environ["SLACK_APP_TOKEN"]).start()
Appの検証
以下のようにhello
とメッセージを送り、Hey there というメッセージがアプリから送られ、Click Me
というボタンが表示されます
Click Me
を押した後にメンションされた状態でclicked the button
というメッセージをAppが送信したら成功です
参考