<目次>
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