Rainbow Engine

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

IT技術 (Technology)

Slackで自動返信の投稿をするボットをPythonで作る手順(ngrokでローカルPCをサーバーに見立てて)

投稿日:2022年7月28日 更新日:

 

<目次>

(1) Slackで自動返信の投稿をするボットをPythonで作る手順(ngrokでローカルPCをサーバーに見立てて)
 (1-1) STEP1:Slackアプリの新規作成&権限付与
 (1-2) STEP2:Python⇒Slackへのメッセージ投稿の疎通
 (1-3) STEP3:「ngrok」のインストール
 (1-4) STEP4:Python環境にflaskをインストール
 (1-5) STEP5:Slackでイベント発行&受取りの準備
 (1-6) STEP6:Pythonコードの作成(最終版)
 (1-7) STEP7:疎通テスト

(1) Slackで自動返信の投稿をするボットをPythonで作る手順(ngrokでローカルPCをサーバーに見立てて)

全体像としては次のような感じで、Slackアプリがクライアント相当の位置づけで、指定のアドレス(例:http://a05f-106-131-76-39.ngrok.io)に対してPOSTリクエストを送ります。ngrokでこのリクエストを検知し、ローカルのアドレス(例:http://localhost:5000)に対してリクエストを転送します。その転送されたリクエストをFlaskで捌いて、レスポンス(応答)として投稿や画面などを返却します。
 
(図100)

(1-1) STEP1:Slackアプリの新規作成&権限付与

(1-2) STEP2:Python⇒Slackへのメッセージ投稿の疎通

 

(1-3) STEP3:「ngrok」のインストール

「ngrok」は「パブリックなIPアドレスやドメイン」を「ローカルのWebサーバ」にルーティングできるツールです。これをインストールする事で、ご自身のローカル端末をWebサーバ代わりにする事が出来ます。
 
(図111①)
(図111②)

(図111③)

(1-4) STEP4:Python環境にflaskをインストール

Flaskは軽量のマイクロWebサービスで、Webサーバの用途で使います。
 
・①コマンドプロンプト等で以下のコマンドを実行し、flaskをインストールします。
> pip install flask
(図121①)
 
・②Flask実行用のPythonコードを追記します。
(サンプル)
from flask import Flask

app = Flask(__name__)
@app.route('/', methods=['GET', 'POST'])
def helloworld():
    return "Hello World!"

if __name__ == "__main__":
    app.run(debug=True)
(図121②)
・③実行するとwebサーバが起動し、ブラウザからURLを入力すると「Hello World」が描画されます。
(図121③)

(参考)Flaskについてもう少し知りたい方は下記もご参照ください

 

(1-5) STEP5:Slackでイベント発行&受取りの準備

Slackの「イベント」は例えば、誰かがチャンネルに投稿したり、誰かがメンションされたり、誰かがチャンネルに参加したり、そういったSlackで起きる各種の出来事が「イベント」です。今回は作ったアプリが特定の「イベント」をWebサーバ(今回はngrok+Flask)で検知できるように設定します。
・①「slackeventsapi」モジュールのインストール
Python側でSlackのイベントを受け取るモジュールである「slackeventsapi」をインストールします。
> pip install slackeventsapi
> pip install slackclient

(図130①-1)
(図130①-2)

・②ご自身のSlackアプリ画面で左メニューから「Signing Secret」のキーの値を取得します。

 
(図130②)
(図130③)

・③取得したSigning Secretの値を使い、Python側でイベントを処理するためのSlackEventAdapterインスタンスを生成するコード等を追加。

 
(サンプル)※あくまで途中経過をチェックする目的であり、最終形のコードではありません
import slack
from flask import Flask
from slackeventsapi import SlackEventAdapter

SLACK_SIGNING_SECRET = 'XXXXX'
SLACK_BOT_TOKEN = 'xoxb-XXXXXX'
post_channel = '[投稿先チャンネル]'
post_text = "[投稿メッセージ]"
app = Flask(__name__)

####【イベント受付 追記START】####
# Slackから来たイベントを受け付けるためのインスタンスを生成
slack_event_adapter = SlackEventAdapter(
    SLACK_SIGNING_SECRET,'/slack/events',app)
####【イベント受付 追記END】####

@app.route('/', methods=['GET', 'POST'])
def respond_message():
    # トークンを指定してWebClientのインスタンスを生成
    client = slack.WebClient(token=SLACK_BOT_TOKEN)
    # chat_postMessageメソッドでメッセージ投稿
    client.chat_postMessage(channel=post_channel, text=post_text)
    return post_channel+'チャンネルにメッセージ:'+post_text+'を投稿しました'

if __name__ == "__main__":
    app.run(debug=True)

(図130④)

 
ここまで問題なく来ている場合、実行すると次の様にFlaskが起動した状態でURL(例:http://127.0.0.1:5000/)をブラウザに入力すると、指定したチャンネルに”Hello World”が投稿されます。
 
(動画130⑤)
 
 
・④ngrokをダブルクリックで起動する
(図130⑥)
・⑤次のコマンドでグローバルアドレスを取得。Flaskのポート番号はデフォルト「5000」です。

> ngrok http [ポート番号]
 
(図130⑦)

・⑥「Forwarding」の列にグローバルIPアドレスが表示されるので、そちらを控えます(次で使います)。
意味合いとしては「グローバルアドレス:https://d112-49-106-215-201.ngrok.io」を「ローカルホストのアドレス:http://localhost:5000」にマッピングしてくれています。
Session Status                online
Session Expires               1 hour, 56 minutes
Version                       2.3.40
Region                        United States (us)
Web Interface                 http://127.0.0.1:4040
Forwarding                    http://d112-49-106-215-201.ngrok.io -> http://localhost:5000
Forwarding                    https://d112-49-106-215-201.ngrok.io -> http://localhost:5000

Connections                   ttl     opn     rt1     rt5     p50     p90
                              0       0       0.00    0.00    0.00    0.00

(図130⑧)

・⑦Slackアプリ画面で左メニューの「Event Subscriptions」→「Enable Events」をOFFからONに変更
(図131①-1)

(補足)「Event Subscription」設定について
・チャンネル上で起きるイベント(例:誰かが投稿した、メンションしたなど)を検知するための仕組みが「Event Subscription」設定。
・その中でも「Request URL」という設定があります。これは、検知対象のイベントが発生した時に、指定したURLに対してHTTPプロトコルの「POST」リクエストを送ります。
・このURLを、ご自身でPython等から作成したAPIに指定する事で、イベント発生時にご自身でプログラミングした処理を実行させる事ができます。

 
・⑧「Request URL」のチェック用に、Pythonプログラム全体を次のように書き換える
(サンプル:Validationチェック通過用)
※あくまでValidationチェックを通過する目的であり、最終形のコードではありません
from flask import Flask, request, jsonify
app = Flask(__name__)

@app.route('/slack/events', methods=['GET', 'POST'])
def respond_message():
    # Slackから送られてくるPOSTリクエストのBodyの内容を取得
    json =  request.json
    print(json)
    # レスポンス用のJSONデータを作成
    # 受け取ったchallengeのKey/Valueをそのまま返却する
    d = {'challenge' : json["challenge"]}
    # レスポンスとしてJSON化して返却
    return jsonify(d)

if __name__ == "__main__":
    app.run(debug=True)
 
(図131①-2)
・⑨「Request URL」にイベント発行先URLを指定します。
⇒「先程のグローバルアドレス」に「/slack/events」を追記したURL
(図131②)
 
・⑩「Subscribe to bot events」で「message.channel」を追加
(図131③)

(図131④)
・⑪アプリをワークスペースに再インストール
(図132①)

(図132②)

目次にもどる

(1-6) STEP6:Pythonコードの作成(最終版)

(サンプル)最終形のコード
import slack
from flask import Flask
from slackeventsapi import SlackEventAdapter
SLACK_SIGNING_SECRET = 'a045c2b352f561e746d7dc162aa40f21'
SLACK_BOT_TOKEN = 'xoxb-2928218983906-3134145028820-OhTdoMy2EB9WjqvyqKNq7ZQ0'

app = Flask(__name__)

# トークンを指定してWebClientのインスタンスを生成
client = slack.WebClient(token=SLACK_BOT_TOKEN)
# ボットのユーザーIDを取得
BOT_USER_ID = client.api_call("auth.test")['user_id']

# Slackから来たイベントを受け付けるためのインスタンスを生成
# 第1引数:Singing Secretキーを指定
# 第2引数:イベントの送り先(ルートURL以降の部分)
# 第3引数:イベントの送り先のWebサーバ(今回はFlaskのインスタンス)
slack_event_adapter = SlackEventAdapter(
    SLACK_SIGNING_SECRET,'/slack/events',app)

# メッセージが投稿された事を検知してイベントを発行
@slack_event_adapter.on('message')

# 誰かの投稿に対してオウム返しする関数
# payloadはSlack APIが送ってくるデータで、投稿に関する情報を保持している
def respond_message(payload):
    # payloadの中の'event'に関する情報を取得し、もし空なら空のディクショナリ{}をあてがう
    event = payload.get('event', {})
    # 投稿のチャンネルID、ユーザーID、投稿内容を取得
    channel_id = event.get('channel')
    user_id = event.get('user')
    text = event.get('text')

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

if __name__ == "__main__":
    app.run(debug=True)
(図133①)

目次にもどる

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

試しに、ボットを入れたどこかのチャンネルで投稿をすると、ボットが反応してオウム返し(同じ内容を返信)してくれる事を確認します。
 
(動画141)
 
(図142)

Adsense審査用広告コード


Adsense審査用広告コード


-IT技術 (Technology)

執筆者:


comment

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

関連記事

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

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

Azure DevOpsのReposをデスクトップアプリで操作する方法についてご紹介

  <目次> (1) Azure DevOpsのReposをデスクトップアプリで操作する方法についてご紹介  (1-1) 「GitHub Desktop」の導入手順  (1-2) 「GitH …

SSLCertVerificationError [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: unable to get local issuer certificateエラーが出る原因と対処

  <目次> (1) SSLCertVerificationError [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed: …

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

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

C#でテキストファイルを読み込む方法(サンプルプログラム付き)

  <目次> (1) C#でテキストファイルを読み込む方法(サンプルプログラム付き)  (1-1) 構文  (1-2) 事前準備  (1-3) サンプルプログラム  (1-4) ご参考:使用 …

  • English (United States)
  • 日本語
Top