32
24

More than 1 year has passed since last update.

ChatGPT APIをSlackから利用できるようにしてみた

Last updated at Posted at 2023-03-02

はじめに

最近ChatGPTが流行ってますよね。
筆者も論文の要約や検索、英語翻訳などに利用させていただいております。
そんなChatGPTのAPIが2023/3/1に一般公開されたとのことで、Slackから簡単に利用できるようにしたい!!ということでAWSの勉強も兼ねて実装してみました。
備忘録的に記事を書いてみます!
今回のシステムの簡単なアーキテクチャ図はこちらになります!!
2.png
実際に遊んでみるとこんな感じです笑
16.png

実装

早速ですが、実装について説明していきます。
ステップとしては以下の3つです。
1. OpenAIのAPIキーの取得
2. SlackAppの作成
3. SlackAppの機能実装(AWS)

1. OpenAIのAPIキーの取得

これがないとChatGPT APIが利用できません。
ということで、OpenAIにアクセスして、アカウントを作成しましょう。

作成が完了したら、右上のPersonalからView API keysをクリックします。
18.png

その後Create new secret keyをクリックして、API keyを作成します。(この際に生成されたkeyは一度しか見れないので、忘れないようにどこかにメモしておきましょう!!
スクリーンショット 2023-03-02 20.53.50.png

OpenAIのAPIキーについてはこれで完了です!!

2. SlackAppの作成

次はSlack上でユーザからのメッセージを受け取り、ChatGPTに流すためのSlack Appを作成します。
ここでは、Slack Appの作成のみにとどめ、具体的な機能実装については3.で説明します。

Slack Appsにアクセスし、Create New Appをクリックします。
その後、From scratchを選択します。
名前やWorkspaceに関しては自由に設定してください。
1.png

Webhook URLの作成

アプリの作成が完了したら、外部サービスからSlackにメッセージを送信するためのWebhook URLを作成します。
Add New Webhook to Workspaceをクリックし、メッセージを送信するチャンネルを選択します。
作成された、URLはアプリの機能実装で利用するのでメモしておきましょう!!
スクリーンショット 2023-03-02 21.08.18.png

Event Subscriptionsの設定

Slackでは、ユーザのメッセージ送信などのイベントを受け取るために予めSubscribeするイベントを登録しておく必要があります。
以下の画像のように、ボットが追加されているチャンネルのメッセージ送信イベントを受け取るためにmessage.channelsイベントを登録するのですが、この操作を行うためにはイベントを送信するLambda関数の機能が必要となるため、後回しにします。
3.png

Slack Appをチャンネルに追加

作成したSlack Appをメッセージを送受信するためのチャンネルに追加しましょう。
Slackの追加したいチャンネルを開き左上にあるチャンネル名をクリックすると以下のような画面が出てきます。
そこでIntegrationsタブに移動し、AppsAdd appsから作成したSlack Appを選択することでチャンネルに追加できます。
これをしていないと、Slack Appがメッセージを受信できないのでメッセージを送信しても何も反応してくれなくなります。
10.png

とりあえず、これでSlack Appの作成は完了です。

3. Slack Appの機能実装

ここから、Slack Appの機能実装に入っていきます!!
今回はAWS LambdaとAPI gateway、Cloud9を利用していきます。
参考にした記事は、AWSを使ったslackチャットbotの構築Cisco WebexとAWS LambdaでOpenAI GPT-3のチャットボットを作るになります。

AWS Cloud9

まずはAWS Cloud9を使って、AWS Lambdaにデプロイするためのzipファイルを作成します。
pythonのopenaiライブラリのような標準ライブラリ以外を用いたい場合はAWS Lambdaでpipを使うことができないため、ファイルアップロード機能を用いる必要があります。
【AWS】Lambda上のPythonで外部ライブラリを使用する方法のように様々な方法でアップロードは可能ですが、今回はコマンド一つでアップロード可能ということで、AWS Cloud9を利用しました。

AWS Cloud9の作成

AWSのCloud9の画面に行き、Create environmentをクリックすると、以下のような画面に遷移します。
適当な名前を入力し、createをクリックします。(その他の設定に関してはデフォルトのままでいいと思います。)
スクリーンショット 2023-03-02 21.54.15.png

作成後は、インスタンスが立ち上がるまでに少し時間がかかると思います。
作成が完了し、EnvironmentsページからCloud9 IDEを開くためにOpenをクリックすると以下のような画面が出力されます。
スクリーンショット 2023-03-02 21.59.16.png

ライブラリのインストール

openaiをインストールします。
まず、python3.9のコンテナを起動し、そのコンテナ上でプロジェクトディレクトリの作成、ライブラリのインストールを行います。
Cloud9 IDEのコンソール上で以下のコマンドを入力します。

bash
# コンテナ作成
$ docker run -itd --name py3.9 python:3.9
# コンテナに入る
$ docker exec -it py3.9 bash
# ------コンテナ内------
$ cd
$ mkdir slack_chatgpt # プロジェクトディレクトリの作成
$ cd slack_chatgpt/
$ mkdir package #ライブラリをインストールするpackageディレクトリの作成
$ pip3 install --target ./package openai #openaiライブラリのインストール
$ exit #コンテナから出る
# ------コンテナ内------
$ docker cp py3.9:/root/slack_chatgpt ./ #コンテナ上のプロジェクトディレクトリをホストOSへコピー
$ cd slack_chatgpt/package/
$ zip -r ../my-deployment-package.zip . #ライブラリのzip化
$ cd ../
$ touch lambda_function.py #SlackAppの機能を実装するためのファイルを作成

Slack Appの機能を実装するpythonファイルの作成

ソースコードは以下の通りです。
基本的には、Slackメッセージの最初でSlack Appがメンションされているメッセージに対して、ChatGPTを用いた回答を返信するという機能となっています。
Slackからのリクエスト形式ChatGPTからのレスポンス形式を参考に実装しています。

lambda_function.py
import json 
import urllib.request 
import ssl
import logging
import openai
import os

openai.api_key = os.environ["OPENAI_API_KEY"]

# CloudwatchLogsのログ記憶ライブラリの使用
logger = logging.getLogger()
logger.setLevel(logging.INFO)

def lambda_handler(event, context): 

    # CloudwatchLogsで詳細なログを取得
    logging.info(json.dumps(event))
    
    # Slack Events APIの再送回避(参考URL:https://dev.classmethod.jp/articles/slack-resend-matome/)
    if "x-slack-retry-num" in event["headers"]:
        return {"statusCode": 200}
    
    # メッセージイベントのbodyを取得
    body = json.loads(event["body"])
    
    msg = ""
    
    # Event Subscriptionsのチャレンジステータスを返す
    if "challenge" in body:
        return {
          "statusCode": 200,
          "body": body["challenge"],
          "headers": {
            "content-type": "text/plain"
          }
        }
    elif "user" == body["event"]["blocks"][0]["elements"][0]["elements"][0]["type"]:
        if os.environ["SLACK_APP_ID"] == body["event"]["blocks"][0]["elements"][0]["elements"][0]["user_id"]:
            # メッセージの最初でSlackAppがメンションされていた場合
            for block in body["event"]["blocks"]:
                for elements in block["elements"]:
                    for element in elements["elements"]:
                        if element["type"] == "text":
                            # Slackのテキストやコードブロックなどを一つのmsgとして変数に格納
                            msg += element["text"]
        # ChatGPTにリクエストを送信
        completion = openai.ChatCompletion.create(
          model="gpt-3.5-turbo", 
          messages=[
              {"role": "user", "content": msg}
              ]
        )
        logging.info(completion)
        # ChatGPTからの返答をmsgに格納
        return_msg = completion["choices"][0]["message"]["content"]
    else:
        return
    
    # リクエストヘッダをJSONにする。
    req_headers = { 
        "Content-Type": "application/json", 
    } 

    # JSONにメッセージをつめる。 
    req_json_slack = { 
        "text": return_msg
    } 

    #リクエストを生成してSlackへ投げる。 
    req_slack = urllib.request.Request(os.environ["WEBHOOK_URL"], json.dumps(req_json_slack).encode(), req_headers) 
    urllib.request.urlopen(req_slack) 

ファイル作成が完了したら、zipパッケージにlambda_function.pyを追加します。

bash
$ zip -g my-deployment-package.zip lambda_function.py

このあとはLambdaの作業に移りますが、Cloud9からzipファイルのLambdaへのアップロードを行うのでCloud9 IDEは開いたままが良いと思います。

AWS Lambda

AWS Lambdaの作成

AWSのLambdaのページに行き、関数の作成を選択すると以下のような画面が出てきます。
適当な関数名とランタイムをpython3.9に設定して、関数の作成をクリックします。
スクリーンショット 2023-03-02 22.31.40.png

#### 環境変数の設定
lambda_function.pyで使用している環境変数の設定を行います。
作成したLamdaの設定タブに移動して、編集ボタンをクリックして、設定を行います。
キーのOPENAI_API_KEYWEBHOOK_URLはそれぞれ1. OpenAIのAPIキーの取得Webhook URLの作成で作成したものを設定します。
SLACK_APP_IDは以下の画像のような画面がSlack上で作成したアプリをクリックすることで表示されるのでMember IDをコピーして設定します。
スクリーンショット 2023-03-02 22.37.05.png
設定が完了すると以下のような画面になります。
11.png

ファイルのアップロード

ここで先程Cloud9で作成した、zipファイルをLambdaにアップロードします。
Cloud9のコンソールで以下のコマンドを入力します。(FunctionNameは自信がLambda作成時に設定した名前に置き換えてください)

bash
aws lambda update-function-code --function-name <FunctionName> --zip-file fileb://my-deployment-package.zip

AWS API Gateway

AWSのAPI Gatewayのページに行き、APIを作成をクリックします。
以下のような画面に遷移するのでHTTP APIの構築をクリックします。
スクリーンショット 2023-03-02 22.53.51.png
次の画面で統合を追加をクリックすると以下のような画面になるので、先程作成したLambda関数を選択します。
API名は適当なものをつけてください。
20.png
次のルートを設定ではデフォルトのままで良いですが、リソースパスは後々必要となるので覚えておいてください。
スクリーンショット 2023-03-02 22.53.15.png
Step3のステージを定義はデフォルトのままで良いので、Step4で作成をクリックすると完了です。

Event Subscriptionsの設定

ここで、Event Subscriptionsの設定で後回しにしていた設定を行います。
Event Subscriptionsのページに行き、Enable Eventsをonにすると以下のような画面になると思います。
3.png
ここで、Request URLに下記のAPI GatewayでURLを呼び出すのURLにAWS API Gatewayでのリソースパスを追加したURLを入力します。
入力後、Verifiedと緑の文字が表示されると認証成功です。
url verificationに関して詳しく知りたい方はどうぞ
12.png
成功後は、Subscribe to bot eventsタブからAdd Bot User Eventをクリックし、message.channelsを選択し、画面下部のSave Changesをクリックし、アプリのワークスペースへの再インストールを行います。

動作確認

皆様、お疲れさまでした。(筆者も書いてて疲れました笑)
また、ここまで、お読みいただき誠にありがとうございます!!
では、実装したSlackAPPを利用してみましょう!
メッセージの最初で作成したアプリをメンションして、メッセージを送信すると回答が返ってきます!!!(作成する前に聞いてみるべきでしたね...)
13.png

おわりに

今回、「ChatGPT APIを使いたい!」、「だったら普段から作りなれているSlack Appで作ってみるか!!」、「どうせならあまり使ったことないAWSで実装してみるか!!!」と思いつきで始め、なんとなくまとめてみたくなって筆をとった次第です笑
読みにくい、または分かりづらい、記事通りに実装したのに動かない、もっとこうした方が良い等がございましたらコメントいただけますとできる範囲で対応、修正していきたいと思います!
最後に、煽りスキルの高いChatGPTさんとの会話を載せて示させていただきます。
お付き合いいただき誠にありがとうございました:bow_tone1:
15.png

32
24
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
32
24