Rainbow Engine

IT技術を分かりやすく簡潔にまとめることによる学習の効率化、また日常の気付きを記録に残すことを目指します。

Python Slack

SlackボットのInteractiveメッセージとは?使い方の手順もご紹介

投稿日:2023年9月25日 更新日:

 

<目次>

SlackボットのInteractiveメッセージとは?使い方の手順もご紹介
 やりたいこと/概要
 STEP0:前提条件
 STEP1:SlackボットでInteractiveの設定
 STEP2:Pythonプログラム側に処理追記(リクエスト受付のエンドポイント+その処理)
 STEP3:動かし方

SlackボットのInteractiveメッセージとは?使い方の手順もご紹介

やりたいこと/概要

●やりたいこと
・SlackのInteractiveメッセージとは?を理解する
・実際にハンズオンで動かしてみる
 
●概要
Slackボットのインタラクティブメッセージ(Interactive Message)は、ユーザーとSlackボットの間で対話的な体験を提供するための機能です。
 
通常のSlackメッセージでは、テキストメッセージやファイルの共有などが主なコンテンツとなりますが、インタラクティブメッセージでは、ボタンやプルダウンメニュー、ラジオボタンなどの要素を組み合わせることができます。
 
インタラクティブメッセージを使用することで、ボットとの対話がより動的で参加型の体験になり、ユーザーが簡単にアクションを実行したり情報を入力したりできるようになります。
 
(動画)ラジオボタンに反応する例

STEP0:前提条件

ベースとなるSlackボットの疎通が済んでいること。
Slackボットを開発/デプロイ済み

STEP1:SlackボットでInteractiveの設定

(図111)
(図112)
(図113)

STEP2:Pythonプログラム側に処理追記(リクエスト受付のエンドポイント+その処理)

(サンプルプログラム)app.py
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)
 
(サンプルプログラム)env.py
→各値にはそれぞれ、ご自身の認証情報をセットしてください。
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

STEP3:動かし方

下記の記事のSTEP1~STEP7に沿って進める事で、動作確認ができます。

Adsense審査用広告コード


Adsense審査用広告コード


-Python, Slack
-

執筆者:


comment

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

関連記事

Pythonのdatapackage学習中に遭遇したエラー「StopIteration」と「AttributeError」の対応

(0)目次&概説 (1) 記事の目的 (2) エラー1:AttributeError: ‘generator’ object has no attribute ‘n …

Pythonでcsvのカラム名を変更する方法(Pandasのread_csvで読み込んだcsvのカラム名変更)

<目次> (1) Pythonでcsvのカラム名を変更する方法  (1-1) 構文①  (1-2) サンプルプログラム①  (1-3) 構文②  (1-4) サンプルプログラム② PythonのPan …

Slack APIで返信を一覧で取得する方法をご紹介(Python)

  <目次> (1) Slack APIで返信を一覧で取得する方法をご紹介(Python)  (1-0) やりたいこと  (1-1) STEP1:Slackアプリの準備  (1-1) STE …

PythonのPandas使用時に発生した「UnicodeEncodeError: ‘ascii’ codec can’t encode characters~」エラーの対処方法について

(0)目次&概説 (1) エラー対応1:UnicodeEncodeError  (1-1) 発生状況・エラーメッセージ   (1-1-1) エラーメッセージ   (1-1-2) エラーとなったソース …

Pythonの「Import “requests” could not be resolved from source Pylance」エラーの原因と対処について

  <目次> (1) Pythonの「Import “requests” could not be resolved from source Pylance」エラーの …

  • English (United States)
  • 日本語
Top