LoginSignup
1
0

More than 1 year has passed since last update.

Slack Bolt for Pythonを使ったBot作成のハマりどころ

Last updated at Posted at 2021-09-27

色々とやってきた中で、ちゃんとドキュメント読めばわかるけど、なんとなくで実装してるとハマっちゃうよねというネタをちょこちょこと追加していくページ

ログに何も流れてこないとき

スコープの理解が浅いときに起こりがちな奴。
コード的には問題なくても、スコープが適切に振られていないと全くデータを読み取れません。
この部分をしっかりと設定してから、インストールしましょう。

自社アプリの場合は管理画面インストールしてしまうので意識する必要ほとんどないのですが、他のワークスペースへのインストールができる様な実装にするときちんと実装しないと動きません。

スコープ自体はアプリ管理画面のここで追加します。
Slack_API__Applications___Leave_a_Nest_Co__ltd__Slack.png

よく使いそうなものをまとめたもの

export SLACK_SCOPES=chat:write,users:read,users:read.email,channels:history,groups:history,im:history,mpim:history,channels:join,groups:write,im:write,mpim:write,channels:read,app_mentions:read

環境変数に格納してから、botのインストールをしないと動きません。注意しましょう。

botへのメンションからモーダルは呼び出せない

メンションというか、Event APIからは呼べません。
モーダルを使う条件は以下の通り

ショートカット実行、ボタンクリック、セレクトメニューの選択、スラッシュコマンドなどのようにユーザーからの能動的なアクションに同期的に応答する場合のみ trigger_id が発行され、それを使ってモーダルを開くことができます

ということなので、実装する場合はこれらを使った実装にするか、メンション→chat.postEphemeralでボタンブロック付きのpostを送信→ボタンクリックでモーダル呼び出し
のような実装になります。

モーダルのsubmitボタンを押した後にclient.views_updateは使えない

このページを見ているとできそうに見えるのですが、実際はできません。
Submitボタンを押した後にモーダルを更新する場合は
ack()
で空のレスポンスボディで応答するのではなく、
ack(response_action="update", view={})
という形式でresponse bodyを更新します。
ack()で応答する=モーダルを閉じるという意味になるので、ここに書いてある形で実装すると、body: {‘ok’: False, ‘error’: ‘not_found’}が返ってきて、モーダルが閉じて何も起こりません。
ack(response_action="update", view={})
のviewの中身を更新した情報で埋めてあげると、更新がうまくいきました。

逆に、モーダル内のボタン等による遷移の場合

こちらについてはviews_updateで更新する

タイムスタンプの取得方法

スレッドにchat.postMessageしたい時にはthread_tsを取得する必要があります。
この際に検討すべき状態には3種類あり

  • スレッドが紐付かない単体のpostの場合
  • スレッドが紐付いた、親postの場合
  • スレッドが紐付いた、スレッド内postの場合

となっています。
この3パターンにおいて、thread_tsを取得するのですが、その方法はこれです。

try:
    conversations_replies = client.conversations_replies(
        channel=event['item']['channel'],
        ts=event['item']['ts']
    )
except SlackApiError as e:
    print("Error fetching conversations_replies: {}".format(e))
if conversations_replies["messages"][0].get("thread_ts") is not None:#スレッドにpostが存在する場合
    ts = conversations_replies["messages"][0]["thread_ts"]
else:#スレッドが紐付かない単体のpostの場合
    ts = conversations_replies["messages"][0]["ts"]

vent['item']['channel']とevent['item']['ts']はそれぞれの場所で取得方法が変わってきますので適宜置き換えて下さい。
スレッドが紐付かない単体のpostの場合にはthread_tsが存在しません。そのためtsで取得します。
一方、スレッドにメッセージが存在する場合は、親postにもthread_tsが存在します。これはtsと同じ値が入っています。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0