Rainbow Engine

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

IT技術 (Technology)

Slackでボットを開発する手順をご紹介(Python)

投稿日:2022年12月26日 更新日:

 

<目次>

(1) Slackでボットを開発する手順をご紹介(Python)
 (1-0) やりたいこと
 (1-1) STEP1:Slackアプリの作成と疎通
 (1-2) STEP2:Slackアプリのイベント受信/応答をソケットモード(Webソケット通信)で疎通
 (1-3) STEP3:Slackアプリのイベント受信/応答をURL経由(https通信)で疎通
 (1-4) STEP4:Webアプリをクラウド上にデプロイ(Azure App Service)して疎通
 (1-5) STEP5:Slackアプリのサーバ側処理(Pythonプログラム)の作成
 (1-6) STEP6:Slackアプリのエンドポイントを本番用に修正
 (1-7) STEP7:疎通テスト

(1) Slackでボットを開発する手順をご紹介(Python)

(1-0) やりたいこと

・Slack Appでボット用アプリを作り、イベント(例:チャンネルに投稿時)に対して反応するような、簡易的なボットを作る。
・イベント(例:チャンネルに投稿時)が発生すると、裏側でAzure App Service上にデプロイしたPythonアプリ(FlaskとBoltで実装)が動く
 
<最終ゴールイメージ>
(図100)

(動画142)

Slackボットを開発する上でキーとなる考え方

Slackではイベント(投稿など)が起きると、指定したURLに対してイベント(POSTリクエスト)を発行します。
なので、Python等で作るボットは「Webサービス」として構築します。つまり、Webサーバ上で24時間365日リクエストを受けて&レスポンスを応答できる状況で、受け付けたリクエストに対してPythonの処理を動かす形の仕組みにします。
Webサーバは「Flask」等のWebサーバのフレームワークを使います。ローカル端末をサーバ代わりにしてテストする場合はSlackの「ソケットモード」機能を使うか、あとは「ngrok」等を使って、ローカル端末をWebサーバとして使う事もできます。

前提知識①:画面の開発(Bolt)

SlackアプリはSlack-APIを用いて以下のような処理を実装できます。
・モーダル画面(子ウィンドウ)などの対話的なUI
・各種イベントに対する自動処理(例:投稿に対して、リアクションに対して)
・リッチなメッセージ
しかしながら、APIをコールする処理を1から作るのは手間もかかり煩雑なため、Slackでは「Bolt」というフレームワークを提供しています。

(1-1) STEP1:Slackアプリの作成と疎通

↓こちらの記事内の手順(STEP1~STEP5)を全て実施します。
(手順)
(概要)
・Slackアプリを新規作成し、Botの権限設定やワークスペースへのリリースを行います。
・crulコマンドで試しにチャンネルに投稿できるかを疎通します。
(図121)STEP1イメージ図

(1-2) STEP2:Slackアプリのイベント受信/応答をソケットモード(Webソケット通信)で疎通

↓こちらの記事内の手順(STEP1~STEP6)を全て実施します。
(手順)
(概要)
・Slackアプリに対して、Event Subscriptionから検知するイベントを設定します・
・Slackアプリに対して、ソケットモードを有効化して、ワークスペースにリリースします。
・ソケットモードを使って、ローカル端末とWeb Socket通信を介してやり取りします。
・それにより、ローカル端末をサーバーに見立てて、Slackアプリがボットの様に動作します。
(図122)STEP2イメージ図

(1-3) STEP3:Slackアプリのイベント受信/応答をURL経由(https通信)で疎通

↓こちらの記事内の手順(STEP1~STEP7)を全て実施します。
(手順)
(概要)
・Slackアプリ側のイベント設定で、指定したエンドポイント(/slack/events)に対して、イベント(例:メンションされた時)の発生時にPOSTリクエストを発行するように設定します。
・Pythonの軽量WebサーバのフレームワークであるFlaskを使って、上記Slackアプリのイベント(HTTP POSTリクエスト)を受け付けます。
・その際に、ngrokを使ってグローバルIPをプライベートIPに変換する事で、ローカル端末上で動くPythonアプリをWEB/APサーバに見立てる事が出来ます。
(図123)STEP3イメージ図

(1-4) STEP4:Webアプリをクラウド上にデプロイ(Azure App Service)して疎通

↓こちらの記事内の手順(STEP1~STEP4)を全て実施します。
(手順)
→FlaskアプリをAzure App Serviceにデプロイする手順(★IT0652)
(図124)STEP4イメージ図

(1-5) STEP5:Slackアプリのサーバ側処理(Pythonプログラム)の作成

STEP4が完了すると、最終形のアーキテクチャ構成での疎通が完了した事になります。
後は業務アプリ(Python)を次のSTEP5でもう一歩踏み込んだものに差し替えて動かしていきます。
Pythonのプログラムを下記のサンプルプログラムに差し替えます。
(サンプルプログラム)
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

# モードに応じて書き換え
BOT_USER_ID = "Uxxxxxxx"
# Botトークン(Flask)
WEBAPPS_SLACK_TOKEN = "xoxb-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
WEBAPPS_SIGNING_SECRET = "[ご自身のSigning Secret]"

# Botトークン(ソケットモード)
SOCK_SLACK_BOT_TOKEN = "xoxb- xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx""
SOCK_SLACK_APP_TOKEN = "xapp-1-xxxxxxxxxxxx-xxxxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxx"

# モード入れ替え(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エンドポイント
# 疎通確認用1
@app.route('/', methods=['GET', 'POST'])
def home():
    return "Hello World Rainbow 2!!"
# 疎通確認用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)

@s_app.event("message")
def respondToRequestMsg(body, client:WebClient):

    event = body.get('event', {})

    # 投稿のチャンネルID、ユーザーID、投稿内容を取得
    channel_id = event.get('channel')
    user_id = event.get('user')
    text = event.get('text')

    # # もしボット以外の人からの投稿だった場合
    if BOT_USER_ID != user_id:               
        # オウム返しを実行
        client.chat_postMessage(channel=channel_id, text=text)

# __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)
(図125)

(1-6) STEP6:Slackアプリのエンドポイントを本番用に修正

・⓪Azure App ServiceのURLを確認
(図130)
・①URLをAzure App Serviceのものに変更し、末尾にPython側で待ち受ける「/slack/events」を追記
URL:https://[ご自身のAzure App ServiceURL]/slack/events
(図131)
・②ワークスペースに再インストール
(図132)

(1-7) STEP7:疎通テスト

・疎通①:https://rainbow-sample-app1.azurewebsites.net
(図141①)

(図141②)


疎通②:https://rainbow-sample-app1.azurewebsites.net/test
(図141③)

(図141④)


・テスト:投稿するとBOTがオウム返しされる
(図142)

(動画142)

Adsense審査用広告コード


Adsense審査用広告コード


-IT技術 (Technology)
-

執筆者:


comment

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

関連記事

プロセス構成図の書き方とサンプルのご紹介

  <目次> (1) プロセス構成図の書き方とサンプルのご紹介  (1-1) プロセス構成図の目的  (1-2) プロセス構成図の書き方  (1-3) プロセス構成図のサンプル (1) プロ …

ユーザーストーリーマッピングとは?

  <目次> (1) ユーザーストーリーマッピングとは?  (1-1) 「ユーザーストーリーマッピング」の概要  (1-2) 「ユーザーストーリーマッピング」の利点  (1-3) 「ユーザー …

ワークフローを簡単に作成できるツールとその手順をご紹介(Zapier導入)

  <目次> (1) ワークフローを簡単に作成できるツールとその手順をご紹介(Zapier導入)  (1-1) STEP1:Zapierのアカウント作成  (1-2) STEP2:Zapie …

プロセスとは? Linuxの例も交えてご紹介

  <目次> (1) プロセスとは? Linuxの例も交えてご紹介  (1-1) プロセスとは?  (1-2) プロセスの構成要素  (1-3) プロセスの状態遷移 (1) プロセスとは? …

Miroのプラン比較の調査をしてみた

  <目次> (1) Miroのプラン比較の調査をしてみた  (1-1) 目的  (1-2) 調査結果   (1-2-1) 各プランの概要   (1-2-2) 機能比較の補足 (1) Mir …

  • English (United States)
  • 日本語
Top