55
Help us understand the problem. What are the problem?

posted at

updated at

Organization

Python で Slack API や Webhook を扱うなら公式 SDK(slack-sdk/slack-bolt)を使おう

こんにちは、Slack で公式 SDK の開発に従事している @seratch と申します。

これから Slack の Python SDK について日本語のチュートリアルを書いていく予定で、この記事はそれらのエントリーページにしようと思っています。ご興味あれば、ぜひこの記事をストックしておいてください :wave: (良いと思ったら 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 のみに依存し、より抽象化されたレイヤーを提供する。

以下の二つは旧来のパッケージです。引き続きメンテナンスされていますが、少なくとも新しいアプリでは上の二つを使うようにしてください :bow:

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-boltslack-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 のチャンネルには「:wave: こんにちは!」が溢れ(私がテストで何回も実行しただけの話なんですが・・)

ターミナル上の出力は以下のようになるはずです。

$ 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

今後公開予定の記事

以下の記事をこれから一つずつ書いていく予定です。これら以外に知りたい情報がありましたら、この記事のコメントで教えてください!

英語でもよろしければ、全ての内容は 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 をより便利にする創意工夫を楽しんでください!それではまた :wave:

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
55
Help us understand the problem. What are the problem?