こんにちは、Slack で公式 SDK の開発に従事している @seratch と申します。
これから Slack の Python SDK について日本語のチュートリアルを書いていく予定で、この記事はそれらのエントリーページにしようと思っています。ご興味あれば、ぜひこの記事をストックしておいてください (良いと思ったら LGTM もぜひ)
え! Slack に Python 公式 SDK なんてあったの?
・・と思った方も多いかもしれません。Python で Slack の Incoming Webhooks や Web API を使うとき、requests
のような HTTP クライアントやコミュニティで開発された PyPI パッケージを使っている例をよく見かけます。Slack API は簡単に扱えることを重視して提供されていますので、もちろんそのようなやり方でも全く問題ありません!
しかし、公式 SDK を使えば、新しい API や機能への対応が容易になったり、パラメーターが非推奨になったときにいち早くワーニングログが出たり、細かい落とし穴にハマらずに済むかもしれません。
公式 SDK の開発者としては、ぜひ日本の皆さんにももっと使っていただけたらと思い、この記事を書くことにしました。
どのようなパッケージがあるのか
2021 年現在、Slack は以下の PyPI パッケージを提供しています。前半の二つが現在アクティブに開発されているものです。この記事では slack-sdk と slack-bolt について解説する記事を順次リンクしていきます。
PyPI パッケージ/ウェブサイト | 説明 |
---|---|
・slack-sdk ・slack.dev/python-slack-sdk/ ・GitHub リポジトリ |
最新の Python SDK で全ての機能(Web API、Incoming Webhooks、リクエスト署名、ソケットモード、Audit Logs API、SCIM API、OAuth フロー、RTM)をサポートしている。 |
・slack-bolt ・slack.dev/bolt-python/ ・GitHub リポジトリ |
ユーザーとのインタラクションやイベント API を扱うためのフルスタックフレームワーク。ソケットモード、Django、Flask、FastAPI などのメジャーなフレームワークとのアダプターが提供されており、Slack アプリ開発の本質的な実装だけに集中することができる。Web フレームワークへのアダプターなしで動作する場合 slack-sdk のみに依存し、より抽象化されたレイヤーを提供する。 |
以下の二つは旧来のパッケージです。引き続きメンテナンスされていますが、少なくとも新しいアプリでは上の二つを使うようにしてください
PyPI パッケージ/ウェブサイト/GitHub リポジトリ | 説明 |
---|---|
・slackclient ・slack.dev/python-slackclient/ ・GitHub リポジトリ |
slack-sdk の旧バージョンで slack-sdk への移行を推奨している。現在もメンテナンスされているが、今後新機能の追加はされない。Web API、Incoming Webhooks、RTM API、リクエスト署名にのみ対応している。 |
・slackeventsapi ・github.com/slackapi/python-slack-events-api |
イベント API を Flask アプリで受信するためのライブラリ。Bolt の ack() のような 3 秒タイムアウトへの考慮はない。現在もメンテナンスされているが、slack-bolt への移行を推奨している。 |
とにかくはじめよう
pip install でパッケージを入手しましょう。どちらのパッケージも Python 3.6 以上で動作しますので python3 --version
でバージョンを確認してください。
この記事では Poetry を使って説明していきますが、pip でインストールするなら
pip3 install slack-sdk
のようになります。Bolt を使う場合は pip3 install slack-bolt
だけで OK です。slack-bolt
は slack-sdk
に依存しているので slack-bolt
をインストールすれば slack-sdk
も自動的にインストールされます。
では、ここからは Poetry を使っていきましょう。インストールしていない人はこちらを参考にしてください。
# 新しいプロジェクトを作成
poetry new my-awesome-slack-app
cd my-awesome-slack-app/
# 必要に応じて poetry env use 3.9 など
# virtualenv を有効化
poetry shell
# slack-sdk を追加
poetry add slack-sdk
# とりあえずインストールしたパッケージが使えているか確認
echo 'from slack_sdk.web import WebClient
client = WebClient()
response = client.api_test()
print(response)' > api_test.py
python api_test.py
# 以下のステップで Slack の API 呼び出しに使えるトークンを設定してください
#
# 1) https://api.slack.com/apps であらかじめ Slack アプリを作成
# 2) OAuth & Permissions のページで chat:write scope を追加
# 3) Install to Workspace ボタンからワークスペースへのインストールを実行
# 4) 発行された xoxb- か xoxp- で始まるトークンを環境変数に設定
#
export SLACK_API_TOKEN='xoxb-{your own token}'
# 以下のコードを実行するとトークンのメタ情報が取得できるはず
echo 'import os
from slack_sdk.web import WebClient
client = WebClient(token=os.environ["SLACK_API_TOKEN"])
response = client.auth_test()
print(response)' > auth_test.py
python auth_test.py
# #random チャンネルにメッセージを投稿してみる
echo 'import os
from slack_sdk.web import WebClient
client = WebClient(token=os.environ["SLACK_API_TOKEN"])
response = client.chat_postMessage(text=":wave: こんにちは!", channel="#random")
print(response)' > say_hi.py
python say_hi.py
という感じになります。
Incoming Webhooks の例に興味があれば、代わりに以下のようにしてみてください。
export SLACK_WEBHOOK_URL='https://hooks.slack.com/services/T11111/B11111/xxxxxxx'
echo 'import os
from slack_sdk.webhook import WebhookClient
webhook = WebhookClient(os.environ["SLACK_WEBHOOK_URL"])
response = webhook.send(text=":wave: こんにちは!")
print(f"status: {response.status_code} body: {response.body}")' > webhook.py
python webhook.py
これらを何度か実行すると Slack のチャンネルには「 こんにちは!」が溢れ(私がテストで何回も実行しただけの話なんですが・・)
ターミナル上の出力は以下のようになるはずです。
$ poetry new my-awesome-slack-app
Created package my_awesome_slack_app in my-awesome-slack-app
$ cd my-awesome-slack-app/
$ ls
README.rst my_awesome_slack_app pyproject.toml tests
$ poetry shell
Creating virtualenv my-awesome-slack-app in /path-to-app/my-awesome-slack-app/.venv
Spawning shell within /path-to-app/my-awesome-slack-app/.venv
. /path-to-app/my-awesome-slack-app/.venv/bin/activate
bash-3.2$ . /path-to-app/my-awesome-slack-app/.venv/bin/activate
(.venv) bash-3.2$ poetry add slack-sdk
Using version ^3.5.1 for slack-sdk
Updating dependencies
Resolving dependencies... (0.7s)
Writing lock file
Package operations: 9 installs, 0 updates, 0 removals
• Installing pyparsing (2.4.7)
• Installing attrs (21.2.0)
• Installing more-itertools (8.7.0)
• Installing packaging (20.9)
• Installing pluggy (0.13.1)
• Installing py (1.10.0)
• Installing wcwidth (0.2.5)
• Installing pytest (5.4.3)
• Installing slack-sdk (3.5.1)
(.venv) bash-3.2$ echo 'from slack_sdk.web import WebClient
> client = WebClient()
> response = client.api_test()
> print(response)' > api_test.py
(.venv) bash-3.2$ python api_test.py
{'ok': True, 'args': {}}
(.venv) bash-3.2$ export SLACK_BOT_TOKEN='xoxb-11111111111-xxxxxxxxxxxxxxx'
(.venv) bash-3.2$ echo 'import os
> from slack_sdk.web import WebClient
> client = WebClient(token=os.environ["SLACK_API_TOKEN"])
> response = client.auth_test()
> print(response)' > auth_test.py
(.venv) bash-3.2$ python auth_test.py
{'ok': True, 'url': 'https://xxx.slack.com/', 'team': 'xxx', 'user': 'my-awesome-bot', 'team_id': 'T111', 'user_id': 'U111', 'bot_id': 'B111', 'is_enterprise_install': False}
(.venv) bash-3.2$ echo 'import os
> from slack_sdk.web import WebClient
> client = WebClient(token=os.environ["SLACK_API_TOKEN"])
> response = client.chat_postMessage(text=":wave: こんにちは!", channel="#random")
> print(response)' > say_hi.py
(.venv) bash-3.2$ python say_hi.py
{'ok': True, 'channel': 'C111', 'ts': '1621562691.008000', 'message': {'bot_id': 'B111', 'type': 'message', 'text': ':wave: こんにちは!', 'user': 'U111', 'ts': '1621562691.008000', 'team': 'T111', 'bot_profile': {'id': 'B111', 'deleted': False, 'name': 'My App', 'updated': 1584342729, 'app_id': 'A111', 'icons': {'image_36': 'https://avatars.slack-edge.com/xxx_36.jpg', 'image_48': 'https://avatars.slack-edge.com/xxx_48.jpg', 'image_72': 'https://avatars.slack-edge.com/xxx_72.jpg'}, 'team_id': 'T111'}}}
(.venv) bash-3.2$ export SLACK_WEBHOOK_URL='https://hooks.slack.com/services/T11111/B11111/xxxxxxx'
(.venv) bash-3.2$ echo 'import os
> from slack_sdk.webhook import WebhookClient
> webhook = WebhookClient(os.environ["SLACK_WEBHOOK_URL"])
> response = webhook.send(text=":wave: こんにちは!")
> print(f"status: {response.status_code} body: {response.body}")' > webhook.py
(.venv) bash-3.2$ python webhook.py
status: 200 body: ok
今後公開予定の記事
以下の記事をこれから一つずつ書いていく予定です。これら以外に知りたい情報がありましたら、この記事のコメントで教えてください!
- Slack Python SDK で Incoming Webhooks を使おう(英語ドキュメント)
- Slack Python SDK でチャンネルにメッセージを投稿しよう(英語ドキュメント)
- Slack Python SDK でチャンネルにファイルをアップロードしよう(英語ドキュメント)
- Bolt for Python でソケットモードのアプリをつくろう(日本語ドキュメント)
- Bolt for Python でモーダルを使った申請フォームを作ろう
- Bolt for Python で複数のワークスペースで使える Slack アプリをつくろう
- asyncio ベースのアプリで Slack Web API を利用しよう(英語ドキュメント)
英語でもよろしければ、全ての内容は https://slack.dev/python-slack-sdk/ と https://slack.dev/bolt-python/ にあります。今すぐ情報を知りたい方は、英語のドキュメントを参考にしてください。
また、Bolt for Python の GitHub リポジトリには様々なサンプルコードがありますので、チェックしてみてください。
https://github.com/slackapi/bolt-python/tree/main/examples
ぜひ公式 SDK を使って Slack をより便利にする創意工夫を楽しんでください!それではまた