<目次>
SlackボットのInteractiveメッセージとは?使い方の手順もご紹介
やりたいこと/概要
STEP0:前提条件
STEP1:SlackボットでInteractiveの設定
STEP2:Pythonプログラム側に処理追記(リクエスト受付のエンドポイント+その処理)
STEP3:動かし方
SlackボットのInteractiveメッセージとは?使い方の手順もご紹介
やりたいこと/概要
STEP0:前提条件
⇒Slackボットを開発/デプロイ済み
STEP1:SlackボットでInteractiveの設定
STEP2:Pythonプログラム側に処理追記(リクエスト受付のエンドポイント+その処理)
import env from dotenv import load_dotenv from slack_bolt import App from slack_sdk import WebClient #Flask from flask import Flask, request from slack_bolt.adapter.flask import SlackRequestHandler #ソケットモード用 from slack_bolt.adapter.socket_mode import SocketModeHandler # 環境変数読み込み # load_dotenv(dotenv_path='.\.env') load_dotenv() # モードに応じて書き換え BOT_USER_ID = env.get_env_variable('BOT_USER_ID') # Botトークン(Flask) WEBAPPS_SLACK_TOKEN = env.get_env_variable('WEBAPPS_SLACK_TOKEN') WEBAPPS_SIGNING_SECRET = env.get_env_variable('WEBAPPS_SIGNING_SECRET') # Botトークン(ソケットモード) SOCK_SLACK_BOT_TOKEN = env.get_env_variable('SOCK_SLACK_BOT_TOKEN') SOCK_SLACK_APP_TOKEN = env.get_env_variable('SOCK_SLACK_APP_TOKEN') # Interactive応答をテストするための、3択の簡単なフォーム def get_feeling_block(target_user:str): blocks = [ { "type": "section", "text": { "type": "mrkdwn", "text": f"<@{target_user}>さん、今日の気分を教えてください:relaxed:" }, "accessory": { "type": "radio_buttons", "options": [ { "text": { "type": "plain_text", "text": ":one:いけてる:blush:", "emoji": True }, "value": "high" }, { "text": { "type": "plain_text", "text": ":two:普通:slightly_smiling_face:", "emoji": True }, "value": "medium" }, { "text": { "type": "plain_text", "text": ":three:いまいち:weary:", "emoji": True }, "value": "low" } ], "action_id": "radio_buttons-action" } } ] return blocks # モード入れ替え(WebAPサーバ実行=Flask/ローカル実行=ソケットモード) def app_mode_change(i_name): if i_name == "__main__": return App(token=SOCK_SLACK_BOT_TOKEN) else: return App(token=WEBAPPS_SLACK_TOKEN, signing_secret=WEBAPPS_SIGNING_SECRET) # グローバルオブジェクト s_app = app_mode_change(__name__) # Flaskクラスのインスタンス生成 app = Flask(__name__) app.config['JSON_AS_ASCII'] = False handler_flask, handler_socket = None,None #ソケットーモードの場合のハンドラ設定 if __name__ == "__main__": handler_socket = SocketModeHandler(app=s_app, app_token=SOCK_SLACK_APP_TOKEN, trace_enabled=True) #Flaskでのハンドラー設定 else: handler_flask = SlackRequestHandler(s_app) # Flask httpエンドポイント @app.route('/', methods=['GET', 'POST']) def home(): return "Hello World Rainbow 2!!" @app.route("/test", methods=['GET', 'POST']) def hello_test(): return "Hello, This is test.2!!" #イベント登録されたリクエストを受け付けるエンドポイント @app.route("/slack/events", methods=["POST"]) def slack_events(): return handler_flask.handle(request) ################## 追記START ################# # Interactive操作のリクエストを受け付けるエンドポイント @app.route("/slack/interactive", methods=["POST"]) def slack_interactive(): return handler_flask.handle(request) @s_app.action("button-action") @s_app.action("radio_buttons-action") def respondToFeelingSurvey(body, client:WebClient, ack): ack() # Slackのイベント情報から各種パラメータを取得 ts = body["container"]["message_ts"] user_id = body["user"]["id"] channel_id = body["container"]["channel_id"] feeling_id = body['actions'][0]['selected_option']['value'] feeling_text = "いけてる" if feeling_id == 'high' else "普通" if feeling_id == 'medium' else "いまいち" # もしボット以外の人からの投稿だった場合 if BOT_USER_ID != user_id: # 三択の選択内容をオウム返し client.chat_postMessage(channel=channel_id, thread_ts=ts, text=f"あなたは「{feeling_text}」を選択しました。") ################## 追記END ################# @s_app.event("message") def respondToRequestMsg(body, client:WebClient): # Slackのイベント情報から各種パラメータを取得 ts = body["event"]["ts"] user_id = body["event"]["user"] channel_id = body["event"]["channel"] # もしボット以外の人からの投稿だった場合 if BOT_USER_ID != user_id: # 三択の質問を返答 client.chat_postMessage(channel=channel_id, thread_ts=ts, blocks=get_feeling_block(user_id)) # __name__はPythonにおいて特別な意味を持つ変数です。 # 具体的にはスクリプトの名前を値として保持します。 # この記述により、Flaskがmainモジュールとして実行された時のみ起動する事を保証します。 # (それ以外の、例えば他モジュールから呼ばれた時などは起動しない) if __name__ == '__main__': EXEC_MODE = "SLACK_SOCKET_MODE" # Slack ソケットモード実行 if EXEC_MODE == "SLACK_SOCKET_MODE": handler_socket.start() # Flask Web/APサーバ 実行 elif EXEC_MODE == "FLASK_WEB_API": # Flaskアプリの起動 # →Webサーバが起動して、所定のURLからアクセス可能になります。 # →hostはFlaskが起動するサーバを指定しています(今回はローカル端末) # →portは起動するポートを指定しています(デフォルト5000) app.run(port=8000, debug=True)
def get_env_variable(key): env_variable_dict = { # ------------------------------------ # App名:xxxx # ------------------------------------ # BotユーザーID "BOT_USER_ID" : "Uxxx", # Botトークン(Flask) "WEBAPPS_SLACK_TOKEN" : "xoxb-xxx", "WEBAPPS_SIGNING_SECRET" : "xxx", # Botトークン(ソケットモード) "SOCK_SLACK_BOT_TOKEN" : "xoxb-xxx", "SOCK_SLACK_APP_TOKEN" : "xapp-xxx" } ret_val = env_variable_dict.get(key, None) return ret_val