Slackで質問に自動回答！ChatGPTとLangChainで社内FAQボットを作ってみた Part2

# 概要
本記事では、Slack BoltとChatGPT、LangChainを用いて社内FAQボットを開発する過程を、Partに分けて解説します。
Part1では独自データを回答するところまでを解説しました。
今回のPart2では、Slack Bolt for Pythonを使ってSlack Botの実装について解説します。

## Slackアプリ作成
まず、アプリ作成前に普段の業務の邪魔にならないようにテスト用の<ins>[ワークスペース](https://slack.com/get-started#/createnew)</ins>を作っておきましょう。アプリ作成ではソケットモードとHTTP方式の選択肢があります。デバッグするにはソケットモードが楽ですが、最終的にAWS Lambdaで動かすときにHTTP方式にする必要があるので、今回はHTTP方式で作り、デバッグ方法などを解説していきます。
Slackアプリの作り方は<ins>[Bolt入門ガイド](https://slack.dev/bolt-python/ja-jp/tutorial/getting-started-http)</ins>に丁寧に書かれています。

一応、私がやった手順も記載しておきます。
<ins>[slack api > Your APPs](https://api.slack.com/apps)</ins>から「__Create New App__」ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536199/387acc78-f043-e6d0-6006-e258c92a740b.png)

マニフェストから作成もできますが、今回はゼロからUIに従って構築するので「__From scratch__」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536199/39a7465b-0b94-3c25-0f7f-a9208902be47.png)

「__App Name__」の入力と __ワークスペース__ を選択し、「__Create App__」ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536199/37082467-4b49-9e50-8111-0fcaedc2854a.png)

アプリの __Basic Information__ ページが表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536199/6aa62749-ef11-ef0e-edab-18fc0a4ef108.png)

ページを下にスクロールすると __Signing Secret__ があり、これはあとで利用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536199/bc52b444-7c13-d587-6f37-9295cf849ff5.png)


まず、 __App Display Name__ を設定します。以前は設定しなくてもよかったのですが、仕様が変わったようで、設定しないとワークスペースへ追加するときにエラーとなります。
左サイドバーの「__App Home__」をクリックし、「__Your App’s Presence in Slack__」セクションの「__App Display Name__」の「__Edit__」ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536199/026b5037-dd62-76a7-3072-b84fd4f2d54d.png)

「__Display Name__」と「__Default username__」を入力し、「__Add__」ボタンをクリックします。Default usernameはSlackでメンションするときの名前になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536199/3ceb5dc8-836c-3071-462c-8655288d7228.png)

次にスコープ追加とトークン取得をします。
左サイドバーの「__OAuth & Permissions__」をクリックし、「__Bot Token Scopes__」セクションまで下にスクロールします。「__Add an OAuth Scope__」ボタンをクリックします。
__chat:write__ を追加します。これでアプリがメッセージを投稿できるようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536199/06b33339-a819-2e7a-284c-7c1e3cf03036.png)


OAuth & Permissions ページの一番上までスクロールし、「__Install to Workspace__」をクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536199/07ede227-bac2-af13-e318-7cffea3c6d35.png)

「__許可する__」ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536199/af51b72b-48fe-f797-f82a-e13fd2bba098.png)

 OAuth & Permissions ページが表示され、__Bot User OAuth Token__ が確認できます。このトークンはこのあと利用します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536199/5523e6a6-5d1e-2bc9-b7ca-3a939ca7d9ab.png)


## Bolt for PythonでBot実装
<ins>[Part1](https://qiita.com/i04046/items/8417aacc8433eea1d523)</ins>で作成したPythonプロジェクトに追加実装しますので、同一ディレクトリに「slack_app.py」というファイルを作成します。slack_bolt パッケージをインストールします。（仮想環境などの説明は省略していますが、必要に応じて作成してください。）
```python
pip install slack_bolt
```
Slackアプリ作成の __OAuth & Permissions ページのBot User OAuth Token__ と __Basic Information ページのSigning Secret__ が必要になります。
取得したキーは環境変数などに保存して、お使いになることをお勧めします。
以下のサンプルではSlackアプリにメンションしたメッセージへ応答します。
```python
import os
from slack_bolt import App

# ボットトークンと署名シークレットを使ってアプリを初期化します
# SLACK_BOT_TOKENはBot User OAuth Tokenを環境変数に登録したものを参照しています
# SLACK_SIGNING_SECRETはSigning Secretを環境変数に登録したものを参照しています
app = App(token=os.environ.get('SLACK_BOT_TOKEN'),
          signing_secret=os.environ.get('SLACK_SIGNING_SECRET'),
          process_before_response=True)

# chatbotにメンションが付けられたときのハンドラ
@app.event("app_mention")
def handle_mention(event, say):
    say("How can I help you today?")

#アプリを起動します（デフォルトポートは3000です）
if __name__ == "__main__":
    app.start()
```

実行すると、開発用Webサーバーで起動します。
```
Bolt app is running! (development server)
```
HTTP方式の場合は上記コードを実行するだけではやり取りできないので、デバッグ用にngrokというローカルで実行しているWebサーバーを外部に公開できるツールを使います。私の環境はWindowsなので、<ins>[ngrok公式サイト](https://ngrok.com/download)</ins>からZipファイルをダウンロード > 解凍 > exe実行と、これだけで動きます。(ちなみアカウント登録せずに使うと、2時間で外部公開のURLが無効になります。)
起動するとコマンドプロンプトのような画面が表示されます。
以下、デバッグのアプリに合わせてポート3000でコマンドを実行します。
```
ngrok http 3000
```

実行すると以下の画面が表示されます。 このあと __Forwarding__ のアドレス（ここでは、<foo>https:</foo>//b326-49-98-243-121.ngrok-free.app）を使います。
```
ngrok                                                                                                   (Ctrl+C to quit)

Try our new Traffic Inspector Dev Preview: https://ngrok.com/r/ti

Session Status                online
Account                       XXXXXX
Version                       3.7.0
Region                        Japan (jp)
Latency                       20ms
Web Interface                 http://127.0.0.1:4040
Forwarding                    https://b326-49-98-243-121.ngrok-free.app -> http://localhost:3000 

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

HTTP方式を利用する場合、イベントスクリプトを有効にする必要があります。[アプリ管理ページ](https://api.slack.com/apps)でアプリをクリックします。次に、左サイドバーの「__Event Subscriptions__」をクリックし、「__Enable Events__」というラベルのスイッチをオンに切り替えます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536199/a8924415-a0da-8b59-92ff-aed1de169540.png)

「__Request URL__」に先ほど起動したngrokのForwardingのアドレスと末尾に __/slack/events__ を入力します。正常に疎通できると確認済みになります。※ngrokは起動のたびにアドレスが変わるので、その都度アドレスの差し替えが必要になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536199/29318ba8-e867-f174-7c02-0a43c9954fea.png)

デバッグ側でもSlackからのイベントを正常に受信できています。
```
127.0.0.1 - - [01/Apr/2024 10:23:23] "POST /slack/events HTTP/1.1" 200 -
```

設定画面を少し下にスクロールして、「__Subscribe to bot events__」の「__Add Bot User Evnet__」ボタンをクリックし、__app_mentions:read__ を追加します。これで、Slackアプリにメンションされたメッセージが受信できるようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536199/be10d2a1-fb7c-fe78-b243-d9c38a517528.png)

右下隅にある「__Save Changes__」ボタンを押してください。画面上部に「これらの変更を有効にするには、アプリを再インストールしてください」という英語のメッセージが出てくるので、リンクをクリックして、ワークスペースに再インストールします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536199/ddb49a47-c3e6-8065-67e8-ffd4c9ad5f90.png)

これですべての準備が整ったので、Slackからメッセージを送ってみましょう。
まずは作成したSlackアプリをチャンネルに追加します。
そして、Slackアプリにメンションをつけてメッセージを送信します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536199/18af32a6-c1d0-1412-7f68-1b08528ebeac.png)

ソースで記述した固定のメッセージが返ってきました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/536199/f64f3b02-c08e-b0fc-a3d4-50c96929c77b.png)

ここまででSlack Boltを使った自作Botができました。
ただ、これだと独自データの回答ができていないので、次回はSlackから独自データを回答するように改造していきます。その過程でDockerを使ってLambda環境でデバッグもしていきます。

## 参考文献
https://the-simple.jp/slack-nobotuser

https://slack.dev/bolt-python/ja-jp/tutorial/getting-started-http

https://qiita.com/kujira_engineer/items/ce8f0f7e025324afc6b6