テックブログ

エルカミーの技術ブログです

👁️‍🗨️ Slackで社内文書検索 3/4回(Slackからのコマンドとメッセージの受信編)

関連記事

  1. Slackで社内文書検索 1/4回(Slack APIアプリの作成と設定編)
  2. Slackで社内文書検索 2/4回(Vertex AI Searchのアプリの作成とデータストアの自動更新編)
  3. Slackで社内文書検索 3/4回(Slackからのコマンドとメッセージの受信編)
  4. Slackで社内文書検索 4/4回(任意のLLMによる回答生成編)
はじめに

この記事は、「Slackで社内文書検索 2/4回(Vertex AI Searchのアプリの作成とデータストアの自動更新編)」の続きです。

開発の流れは以下の通りです。

💡
開発の流れ
  1. Slack APIアプリの作成と設定
  2. Vertex AI Searchのアプリの作成とデータストアの自動更新
  3. Slackからのコマンドとメッセージの受信
  4. 任意のLLMによる回答生成

今回はSlackからのコマンドとメッセージの受信について説明していきます。

概要

今回は以下の処理のうち、コマンドとメッセージを送信からHTTPレスポンスを返すまでの処理を説明します。

image block
Slackからのコマンドとメッセージの受信

GCPのプロダクトの都合上、Pub/Sub、Cloud Functionsの順で作成したほうが良いので、処理の流れとは逆に説明していきます。

1. トピックの作成

ここでは、コマンドとメッセージを保持する役割のPub/Subのトピックを作成します。

Pub/Sub は、メッセージを生成するサービスを、それらのメッセージを処理するサービスと切り離す、非同期のスケーラブルなメッセージング サービスです。

まず、GCPのPub/Subに移動し、トピックのページのトピックを作成を選択する。

image block

次に、トピックの作成ページのトピックIDに任意の名前を入力して作成を選択します。トピックID以外はデフォルトのままにしています。

image block

これでトピックの作成は終了です!

トピックIDは後ほど必要になるので控えておいてください。

2. リクエストを受け取り、HTTPレスポンスを返すファンクション

今回作成するファンクションの作成方法は前回の記事と変わらないので、こちらを参照してください。ただし、前回の記事と異なる部分があります。その部分は以下に従ってください。

📌
変更内容
  1. トリガー
    1. HTTPSのみ(未認証の呼び出しを許可に変更する部分は変わりません)
    2. トリガーの追加を行う必要はありません。
  2. ランタイム環境変数
    1. 以下の4つを追加
      名前
      PROJECT_ID Google Cloud のプロジェクトID
      TOPIC_NAME こちらで作成したトピックID
      SLACK_BOT_TOKEN アプリの認証に用いるトークン
      SLACK_SIGNNG_SECRET リクエストの認証に用いるサイン
      SLACK_BOT_TOKENの場所
      1. Slack APIのページに移動
      2. 作成したアプリを選択
      3. サイドバーのOAuth & Permissonsを選択
      4. OAuth Tokens for Your WorkspaceBot User OAuth Tokenをコピー
      SLACK_SIGNNG_SECRETの場所
      1. Slack APIのページに移動
      2. 作成したアプリを選択
      3. サイドバーのBasic Informationを選択
      4. App CredentialsSigning SecretShowを押す
  3. main.py
    code
    import json
    import os
    
    import functions_framework
    from google.cloud import pubsub_v1
    
    
    PROJECT_ID = os.getenv("GOOGLE_CLOUD_PROJECT")
    publisher = pubsub_v1.PublisherClient()
    TOPIC_NAME = os.getenv("TOPIC_NAME")
    
    
    def publish_message(command, message):
        topic_path = publisher.topic_path(PROJECT_ID, TOPIC_NAME)
        message_json = json.dumps(
            {
                "data": {"command": command, "message": message},
            }
        )
        message_bytes = message_json.encode("utf-8")
        try:
            publisher.publish(topic_path, data=message_bytes)
            return "Message published."
        except Exception as e:
            print(e)
            return (e, 500)
    
    
    @functions_framework.http
    def slack_event(request):
    		# リクエストからcommandを取り出す
        command = request.form.get("command")
    		# リクエストからメッセージ部分を取り出す
        text = request.form.get("text")
        publish_message(command, text)
        return "Message received successfully"
  4. requirements.txt
    code
    functions-framework==3.*
    slack-bolt==1.13.0
    python-box[all]~=6.0
    google-cloud-pubsub==2.7.0
    langchain==0.0.175
    llama-index==0.6.9
    pytz
    html2text
  5. エントリポイント
    1. slack_eventに変更

以上でファンクションの作成は終了です!

ファンクションの作成後、Slack APIのコマンドのRequest URLで使用するURLを取得します。

Cloud Functionsで作成したファンクションを選択すると、その画面の中にURLが表示されるので、それをコピーします。

image block

コピーしたURLはコマンドのRequest URLに張り付けてください。

これで、Slackからのリクエストからメッセージとコマンドと取り出して、Pub/Subにその内容をパブリッシュすることができます!

検証として、Slackからコマンドとメッセージを送信して、Cloud FunctionsやPub/Subのログにリクエストやメッセージが残るか確かめてみてください。

最後に

今回は、Slackからのコマンドとメッセージの受信について説明しました。Pub/Subを用いて、Slack APIの3秒レスポンスルールへの対応を取りました!また、今回作成したファンクションのURLをSlackで社内文書検索 1/4回(Slack APIアプリの作成と設定編)のRequest URLに用いることを注意してください。次は任意のLLMによる回答生成について説明します。

参考