PythonでChatGPTのSlackbotを作る
概要
何番煎じか分かりませんが、PythonでChatGPTのSlackbotを作ってみます。
動機
今後ChatGPTのような大規模言語モデルのAPIを開発に取り込むのは必須スキルになってくると思っているので最初の一歩として一番簡単そうなChatGPTのSlackbotから始めてみようと思った次第です。
Pythonの経験はほとんどないのですがChatGPTによって未知の技術でも短期間でキャッチアップが可能になっていると思うのでせっかくなのでPythonでやってみます。
ChatGTP4に以下のプロンプトを渡す事でスタートしました。
# お願い
あなたはプロのITエンジニアです。
これから私がPythonを学ぶ為のサポートをお願いします。
# 前提条件
- 私はWebフロントエンドをメインに開発を行っているエンジニアです
- プログラミング、アルゴリズム、ネットワークの基礎知識はあります
- AWS等のクラウドサービスに対する理解もあります
- 得意な言語はTypeScript、その次に得意な言語はGoです
# 私の開発環境
MacBook Pro 14インチ 2021年モデル、Apple M1 Max、メモリ64 GBを利用しています。
MacOSのバージョンは13.3.1です。
# 最終目標
ChatGPTのAPIを使ってSlackBotを実装したいです。
言語はPython、フレームワークはFlaskを利用します。
デプロイ先は https://fly.io にします。
一歩ずつ考えていきましょう。
Python環境の構築
ChatGPTからはHomebrewでのインストールが提示されたが asdf
でバージョン管理をしたかったので以下の手順でPythonをインストール。
1. Pythonプラグインをインストール
asdf plugin add python
2. インストール可能なPythonのバージョンを確認
asdf list all python
2023年4月14日時点では 3.11.3
が最新安定版である事を確認出来た。
3. 最新安定版のPythonをインストール
asdf install python 3.11.3
4. 特定プロジェクトで最新安定版のPythonを使うように設定
以下のリポジトリに成果物をアップしていきます。
git cloneしてローカルで先程インストールした最新安定版のPythonを設定します。
asdf local python 3.11.3
// Python 3.11.3 が表示されたので問題なさそう
python --version
PyCharmのインストール
JetBrains All Products Packの課金勢なのでPyCharmを使っていく。
自分でも手順は分かるが一応ChatGPTに質問したのでこの通りやってみる。
Homebrew
を使って管理したいので、ここだけChatGPTの提案とは違い brew install --cask
でインストールする。
brew install --cask pycharm
PyCharmの基本設定
昔自分が書いたGoLandの初期設定記事。
同じJetBrains製品なのでこれを見ながらやる。
エディタの設定
個人的にはこのあたりを有効にしておきたい。
Preferences → Editor → General
- Remove trailing blank lines at the end of saved files - ON「行末の不要なスペースやタブを保存時に削除する」
- Ensure every saved file ends with a line break - ON「保存されたファイルの最後が改行で終わるようにする」
Preferences → Editor → General → Appearance
- Show line number - ON「行番号の表示」
- Show method separators - ON「メソッドの区切り線」
- Show whitespaces - ON「空白の表示」
目に優しいTheme(Solarized Theme)をインストールする
以下の通り。最近更新が止まっているのが気になるが他に代替が見つかるまではこのTeemaを使おうと思う。
メモリ割り当てを増やす & メモリインジケーターを有効にする
メモリ64GBのMacなので多めに割り当てる。(16000MBに設定した)
メモリインジケーターも表示させておく。
GitHub Copilotの設定
以下を参考に有効化する。
設定後なぜか1分ほど利用出来なかったが問題なく利用出来るようになった。
PyCharmにPythonインタープリタの設定
ここからはChatGPTに教えてもらった通りに進めてみる。
which python
を実行すると ~/.asdf/shims/python
が出力されるが実体は ~/.asdf/installs/python/3.11.3/bin/python
に存在するようだ。
以下のようにプロジェクトに Python 3.11.3 を設定する。
Virtualenv Environmentを選択する事で仮想環境も作成してくれるようだ。
PyCharmのターミナルを使っていれば仮想環境を自動的にアクティブにしてくれるようだ。
しかし Warp 等の別のターミナルを使う場合は明示的に以下のコマンドをプロジェクトルートで実行して仮想環境をアクティブにする必要がある。
source venv/bin/activate
Flaskで簡単なメッセージを返すAPIを作る
本格的にBotを作る前に最初の一歩としてJSONを返すだけのAPIを実装する。
仮想環境がアクティブな状態で以下を実行。
pip install Flask
app.py
を作成する。
from flask import Flask, jsonify
app = Flask(__name__)
@app.route('/api/data', methods=['GET'])
def get_data():
data = {
'key': 'value',
'numbers': [1, 2, 3]
}
return jsonify(data)
if __name__ == '__main__':
app.run(debug=True)
python app.py
を実行して curl -v http://127.0.0.1:5000/api/data
でアクセスすると以下のレスポンスが返ってきたので成功。
* Trying 127.0.0.1:5000...
* Connected to 127.0.0.1 (127.0.0.1) port 5000 (#0)
> GET /api/data HTTP/1.1
> Host: 127.0.0.1:5000
> User-Agent: curl/7.87.0
> Accept: */*
>
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< Server: Werkzeug/2.2.3 Python/3.11.3
< Date: Fri, 14 Apr 2023 16:31:08 GMT
< Content-Type: application/json
< Content-Length: 61
< Connection: close
<
{
"key": "value",
"numbers": [
1,
2,
3
]
}
* Closing connection 0
Slackbotに必要なトークンを取得する
以下はChatGPTの回答。このまま進めていく。
Slackアプリの作成:
まずはじめに、[Slack API](https://api.slack.com/apps) ページにアクセスし、右上の「Create New App」ボタンをクリックして、新しいSlackアプリを作成します。
アプリ名とワークスペースの選択:
アプリ名を入力し、開発用のワークスペースを選択して、「Create App」ボタンをクリックします。
Botの追加:
作成したアプリの管理画面に移動し、「Add features and functionality」セクションの「Bots」をクリックして、Botを追加します。
Botトークンの取得:
Botを追加した後、「OAuth & Permissions」ページにアクセスして、「Bot Token」をコピーします。このトークンは、BotとしてSlack APIにアクセスする際に使用します。トークンを安全な場所に保存しておいてください。
Botへの権限の追加:
必要に応じて、Botに権限を追加してください。「OAuth & Permissions」ページの「Scopes」セクションで、「Bot Token Scopes」に必要な権限を追加できます。例えば、メッセージを送信するためには chat:write 権限が必要です。
Botのインストール:
権限を追加したら、アプリをワークスペースにインストールします。「OAuth & Permissions」ページの上部にある「Install App」ボタンをクリックし、指示に従ってインストールを完了させてください。
OpenAI のAPI keyを作成
以下のページから作成します。
どうせ後で必要になるので以下のページから支払い方法を登録しておく。
最初の試作品
以下の通り。これはGPT4が提案してきたコードそのまま。
スレッドに返信して欲しかったりするので、そこはこの後で対応していく。
ちなみにまだデプロイはしてなくて ngrok でローカルのサーバーを一時的に公開して動作確認を行っている。
import os
import json
import requests
from flask import Flask, request
from slack_bolt import App
from slack_bolt.adapter.flask import SlackRequestHandler
# 環境変数の読み込み
bot_token = os.environ["SLACK_BOT_TOKEN"]
slack_signing_secret = os.environ["SLACK_SIGNING_SECRET"]
openai_api_key = os.environ["OPENAI_API_KEY"]
API_ENDPOINT = 'https://api.openai.com/v1/chat/completions'
# Flaskアプリケーションの設定
app = Flask(__name__)
slack_app = App(token=bot_token, signing_secret=slack_signing_secret)
handler = SlackRequestHandler(slack_app)
# メッセージイベントのリスナーを設定
@slack_app.event("app_mention")
def command_handler(body, say):
text = body["event"]["text"]
# ChatGPTによる応答の生成
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {openai_api_key}"
}
data = {
"model": "gpt-3.5-turbo",
"messages": [{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": f"{text}"}],
"max_tokens": 2048,
"n": 1,
"stop": None,
"temperature": 0.5,
}
response = requests.post(API_ENDPOINT, headers=headers, data=json.dumps(data))
response = response.json()
# Slackに返答を送信
reply = response["choices"][0]["message"]["content"].strip()
say(reply)
# Slackイベントのエンドポイント
@app.route("/slack/events", methods=["POST"])
def slack_events():
return handler.handle(request)
if __name__ == "__main__":
app.run(debug=True)
Slackのスレッドに返信する & 会話履歴を渡すように変更
下記の通り。ただこのままだと割と早くトークンの上限数に達してしまうのと、conversations
が永続化されていないのでDB等に保存するようにしないとサーバーの再起動で会話履歴が消滅してしまう。
import os
import json
import requests
from flask import Flask, request
from slack_bolt import App
from slack_bolt.adapter.flask import SlackRequestHandler
# 環境変数の読み込み
bot_token = os.environ["SLACK_BOT_TOKEN"]
slack_signing_secret = os.environ["SLACK_SIGNING_SECRET"]
openai_api_key = os.environ["OPENAI_API_KEY"]
API_ENDPOINT = 'https://api.openai.com/v1/chat/completions'
# Flaskアプリケーションの設定
app = Flask(__name__)
slack_app = App(token=bot_token, signing_secret=slack_signing_secret)
handler = SlackRequestHandler(slack_app)
conversations = {}
def handle_conversation(thread_ts, user_message):
if thread_ts not in conversations:
conversations[thread_ts] = [{"role": "system", "content": "You are a helpful assistant."}]
conversations[thread_ts].append({"role": "user", "content": user_message})
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {openai_api_key}"
}
data = {
"model": "gpt-3.5-turbo",
"messages": conversations[thread_ts],
"n": 1,
"stop": None,
"temperature": 0.5,
}
response = requests.post(API_ENDPOINT, headers=headers, data=json.dumps(data))
response = response.json()
reply = response["choices"][0]["message"]["content"].strip()
conversations[thread_ts].append({"role": "assistant", "content": reply})
return reply
# メッセージイベントのリスナーを設定
@slack_app.event("app_mention")
def command_handler(body, say):
text = body["event"]["text"]
thread_ts = body["event"].get("thread_ts", None) or body["event"]["ts"]
# ChatGPTによる応答の生成
reply = handle_conversation(thread_ts, text)
# Slackに返答を送信
say(text=reply, thread_ts=thread_ts)
# Slackイベントのエンドポイント
@app.route("/slack/events", methods=["POST"])
def slack_events():
return handler.handle(request)
if __name__ == "__main__":
app.run(debug=True)
ngrokで外部公開する時はデフォルトの5000ポートだと何かと競合しているのか正常につなぐ事が出来なかった。
以下のように 5002
ポートで対応。
ngrok http 5002
LangChain
LangChainを使うと会話履歴の保持やTools機能を使ってGoogle検索の検索結果から回答を生成なんかも出来るようだ。
という訳でコードを書き変えた。(ついでに猫の人格を設定した)
from langchain import PromptTemplate, LLMChain
from langchain.llms import OpenAIChat
from langchain.chains.conversation.memory import ConversationBufferWindowMemory
# 環境変数にAPIキーを設定
import os
OPENAI_API_KEY = os.environ["OPENAI_API_KEY"]
def create_conversational_chain():
llm = OpenAIChat(model_name="gpt-3.5-turbo", openai_api_key=OPENAI_API_KEY)
template = """あなたは親切な猫です。人間と会話をしています。
{chat_history}
人間: {input}
猫:"""
prompt = PromptTemplate(
input_variables=["chat_history", "input"], template=template
)
memory = ConversationBufferWindowMemory(k=5, memory_key="chat_history")
llm_chain = LLMChain(
llm=llm,
prompt=prompt,
verbose=True,
memory=memory,
)
return llm_chain
SLACK_BOT_TOKEN = os.environ["SLACK_BOT_TOKEN"]
SLACK_SIGNING_SECRET = os.environ["SLACK_SIGNING_SECRET"]
from flask import Flask, request
from slack_bolt import App
from slack_bolt.adapter.flask import SlackRequestHandler
# Flaskアプリケーションの設定
app = Flask(__name__)
slack_app = App(token=SLACK_BOT_TOKEN, signing_secret=SLACK_SIGNING_SECRET)
slack_request_handler = SlackRequestHandler(slack_app)
chain = create_conversational_chain()
# メッセージイベントのリスナーを設定
@slack_app.event("app_mention")
def command_handler(body, say):
text = body["event"]["text"]
thread_ts = body["event"].get("thread_ts", None) or body["event"]["ts"]
# Slackに返答を送信
say(text=chain.predict(input=text), thread_ts=thread_ts)
# Slackイベントのエンドポイント
@app.route("/slack/events", methods=["POST"])
def slack_events():
return slack_request_handler.handle(request)
if __name__ == "__main__":
app.run(debug=True)
LinterとFormatter
ChatGPTに聞いたり、調べてみたりしたが割と色々なツールがあってどれが一強というのはなさそう。
Linterは flake8、Formatterは black を利用する事にした。
以下でインストール
pip install flake8
pip install black
タスクランナーとしてはGoと同じくMakefileが使われている傾向があるようなので以下のMakefileも用意した。
.PHONY: lint format
lint:
flake8 .
format:
black .
flake8
の設定ファイルを追加。
[flake8]
exclude = venv
black
の設定ファイルを追加。
[tool.black]
exclude = 'venv'
Linter, Formatterの適応を実施したあとのソースコード
from langchain import PromptTemplate, LLMChain
from langchain.llms import OpenAIChat
from langchain.chains.conversation.memory import ConversationBufferWindowMemory
from flask import Flask, request
from slack_bolt import App
from slack_bolt.adapter.flask import SlackRequestHandler
import os
OPENAI_API_KEY = os.environ["OPENAI_API_KEY"]
def create_conversational_chain():
llm = OpenAIChat(model_name="gpt-3.5-turbo", openai_api_key=OPENAI_API_KEY)
template = """あなたは親切な猫です。人間と会話をしています。
{chat_history}
人間: {input}
猫:"""
prompt = PromptTemplate(
input_variables=["chat_history", "input"], template=template
)
memory = ConversationBufferWindowMemory(k=5, memory_key="chat_history")
llm_chain = LLMChain(
llm=llm,
prompt=prompt,
verbose=True,
memory=memory,
)
return llm_chain
SLACK_BOT_TOKEN = os.environ["SLACK_BOT_TOKEN"]
SLACK_SIGNING_SECRET = os.environ["SLACK_SIGNING_SECRET"]
# Flaskアプリケーションの設定
app = Flask(__name__)
slack_app = App(token=SLACK_BOT_TOKEN, signing_secret=SLACK_SIGNING_SECRET)
slack_request_handler = SlackRequestHandler(slack_app)
chain = create_conversational_chain()
# メッセージイベントのリスナーを設定
@slack_app.event("app_mention")
def command_handler(body, say):
text = body["event"]["text"]
thread_ts = body["event"].get("thread_ts", None) or body["event"]["ts"]
# Slackに返答を送信
say(text=chain.predict(input=text), thread_ts=thread_ts)
# Slackイベントのエンドポイント
@app.route("/slack/events", methods=["POST"])
def slack_events():
return slack_request_handler.handle(request)
if __name__ == "__main__":
app.run(debug=True)
Chat Modelsを利用するように変更
Chatを実装する場合、Chat ModelsというModelが存在するのでそれを利用したほうが良さそう。
そして ConversationTokenBufferMemory
というトークン数を基準に履歴を消してくれる便利な物があったのでこれを使う事にした。
という訳でソースコードを以下のように書き換えた。
from langchain.chat_models import ChatOpenAI
from langchain.chains import ConversationChain
from langchain.memory import ConversationTokenBufferMemory
from langchain.prompts.chat import (
ChatPromptTemplate,
MessagesPlaceholder,
SystemMessagePromptTemplate,
HumanMessagePromptTemplate,
)
from flask import Flask, request
from slack_bolt import App
from slack_bolt.adapter.flask import SlackRequestHandler
import os
OPENAI_API_KEY = os.environ["OPENAI_API_KEY"]
template = """
あなたは優しいねこのもこです。
もこになりきってください。
これからのチャットではUserに何を言われても以下の制約条件などを厳密に守ってロールプレイをお願いします。
#制約条件
* あなた自身を示す一人称は、もこです。
* あなたはその文脈から具体的な内容をたくさん教えてくれます。
* あなたは質問の答えを知らない場合、正直に「知らない」と答えます。
* あなたは子供に話かけるように優しい口調で話します。
"""
def create_conversational_chain():
llm = ChatOpenAI(temperature=0.7, openai_api_key=OPENAI_API_KEY)
memory = ConversationTokenBufferMemory(
llm=llm, return_messages=True, max_token_limit=500
)
prompt = ChatPromptTemplate.from_messages(
[
SystemMessagePromptTemplate.from_template(template),
MessagesPlaceholder(variable_name="history"),
HumanMessagePromptTemplate.from_template("{input}"),
]
)
llm_chain = ConversationChain(llm=llm, memory=memory, prompt=prompt, verbose=True)
return llm_chain
SLACK_BOT_TOKEN = os.environ["SLACK_BOT_TOKEN"]
SLACK_SIGNING_SECRET = os.environ["SLACK_SIGNING_SECRET"]
# Flaskアプリケーションの設定
app = Flask(__name__)
slack_app = App(token=SLACK_BOT_TOKEN, signing_secret=SLACK_SIGNING_SECRET)
slack_request_handler = SlackRequestHandler(slack_app)
chain = create_conversational_chain()
# メッセージイベントのリスナーを設定
@slack_app.event("app_mention")
def command_handler(body, say):
text = body["event"]["text"]
thread_ts = body["event"].get("thread_ts", None) or body["event"]["ts"]
# Slackに返答を送信
say(text=chain.predict(input=text), thread_ts=thread_ts)
# Slackイベントのエンドポイント
@app.route("/slack/events", methods=["POST"])
def slack_events():
return slack_request_handler.handle(request)
if __name__ == "__main__":
app.run(debug=True)
最低限は動作するようになったのでそろそろデプロイしても良さそう。
Poetryについて
標準の pip
だと正確なバージョンの指定が出来ない。
langchain
はまだ新しいライブラリで今後破壊的な変更が入る可能性も低くはない。
という訳で Poetry を使う事にする。
インストール
以下でインストールを実施する。
brew install poetry
以下を実行して Poetry (version 1.4.2)
のように表示されれば問題なし。
poetry --version
以下を実行する。これを実行するとプロジェクトのディレクトリ配下に仮想環境を作ってくれるようになる。
プロジェクト配下に仮想環境があったほうが分かりやすいので実施しておく。
poetry config virtualenvs.in-project true
ちなみに現状の設定に関しては poetry config --list
で確認出来る。
先程設定した virtualenvs.in-project
が true
になっている事を確認出来る。
初期設定
以下を実施する。
poetry init
対話式のインターフェースに従って入力していく。
poetryで仮想環境を作成する
以下を実行して仮想環境を作成。
poetry install
この時点では何も依存packageを選択していないので、以下のようなエラーが出るが仮想環境の作成自体は出来ている。
/Users/myusername/gitrepos/chat-gpt-slack-bot/chat_gpt_slack_bot does not contain any element
zsh: exit 1 poetry instal
PyCharmの公式ドキュメントを見ながらやっていく。
PyCharm → Project: Project名(私の環境だとchat-gpt-slack-bot) → Python Interpreter → Add Interpreterから設定する。
仮想環境をアクティベートする
以下のコマンドを実行する。
poetry shell
例によってPyCharmのターミナルを開くと最初からアクティベートされた状態になっている。
必要なpackageを追加
Poetryでは以下のコマンドで必要なpackageを追加するようだ。
poetry add <package_name>
最終的に必要なpackageは以下の通りなので以下を実行する。
poetry add slack-bolt langchain Flask tiktoken flake8 black openai
まだ試していないがpackageを削除する時は以下のように実行するらしい。
poetry remove <package_name>
fly.io
へのデプロイ
事前準備
コンテナで起動する為の準備をする。
Pythonだと gunicorn
というHTTPサーバーを利用する事が多いようだ。
という訳でpackageを追加する。
poetry add gunicorn
app.py
を変更してログを標準出力するように設定する。
from flask import Flask
import logging
from logging import StreamHandler
// 中略
# Flaskアプリケーションの設定
app = Flask(__name__)
# ログの設定↓を追加
stream_handler = StreamHandler()
stream_handler.setLevel(logging.INFO)
app.logger.addHandler(stream_handler)
app.logger.setLevel(logging.INFO)
Dockerfileの追加
最初にDockerfileを作成する。
docker build -t chat-gpt-slack-bot .
以下で先程Buildしたイメージが存在する事を確認。
docker images
コンテナを起動。
docker container run -d -p 5002:5000 -e OPENAI_API_KEY=$OPENAI_API_KEY -e SLACK_BOT_TOKEN=$SLACK_BOT_TOKEN -e SLACK_SIGNING_SECRET=$SLACK_SIGNING_SECRET -e FLASK_DEBUG=1 chat-gpt-slack-bot
ngrok http 5002
で一時的にコンテナのURLを開放して動作確認。
ログを確認して起動してリクエストを正常に受け付けている事を確認。
# acf172cd54b8 はコンテナID
docker logs -f acf172cd54b8
# acf172cd54b8 はコンテナID
docker container stop acf172cd54b8
flyctl
の追加
GitHub認証でアカウントを作成出来るのでアカウントを作成する。
今回作成したSlackbotは無料枠で利用出来るが今後の為に一応カード登録を済ませておく。
確か東京リージョンにデプロイする為にもカード登録が必須だった気がする。(未確認)
CLIツールをインストールする。
brew install flyctl
以下で認証を実施する。
flyctl auth login
初期化を実施する。
# デプロイ対象のアプリケーションディレクトリに移動
cd chat-gpt-slack-bot
flyctl launch
ここから対話型のIFとなる。
Choose an app name
と聞かれるのでアプリ名を入力。
Choose a region for deployment
でTokyo, Japanを選択。
データベースの作成(Would you like to set up a Postgresql database now?
) は今回使わないのでNo。
Redis(Would you like to set up an Upstash Redis database now?
) も今回使わないのでNo。
Would you like to deploy now?
と今すぐデプロイするか聞かれるが先に環境変数を登録したいのでNoを選択。
これで fly.toml
が自動生成される。
環境変数の登録
以下のコマンドで環境変数を登録する。
flyctl secrets set -a アプリ名 SLACK_BOT_TOKEN=実際の値を指定
flyctl secrets set -a アプリ名 SLACK_SIGNING_SECRET=実際の値を指定
flyctl secrets set -a アプリ名 OPENAI_API_KEY=実際の値を指定
デプロイ
ここまで準備が出来たら以下のコマンドでデプロイを実行する。
flyctl deploy
実行ログを見るとDockerイメージのBuildしてレジストリに登録してアプリケーションをデプロイしている様子が分かる。
デフォルトだと https://{アプリ名}.fly.dev
でアクセス可能になるようだ。
Slack APIの設定側で Event Subscriptions のURLを https://{アプリ名}.fly.dev/slack/events
に変更して正常動作する事が確認出来た。
ステージング環境の作成(実際には試していない)
以下はChatGPTが教えてくれた手順。
公式のドキュメントも一応確認してみたが動きそうではある。
今回ステージング環境は作らないが今後の為に一応メモしておく。
ステージング用アプリ作成
以下で作成出来る、GUIで作っても問題はなさそう。
flyctl apps create myapp-staging
ステージング用アプリの設定ファイルを作成
以下でコピーを作成。
cp fly.toml fly.staging.toml
中を開いて app
のところだけステージング用の物に変更。
ステージング用アプリ向けの環境変数を登録。
flyctl secrets set -a myapp-staging SLACK_BOT_TOKEN=実際の値を指定
flyctl secrets set -a myapp-staging SLACK_SIGNING_SECRET=実際の値を指定
flyctl secrets set -a myapp-staging OPENAI_API_KEY=実際の値を指定
ステージング用設定ファイルを指定してデプロイします。
flyctl deploy -c fly.staging.toml
以下に対応内容をまとめたPRを貼っておく。
デプロイの自動化
main
ブランチにマージされたタイミングでデプロイを実行するようにしたい。
Vercelのようにリポジトリとの連携だけで自動デプロイを行う仕組みは存在しない模様。
しかし以下に公式からGitHubActionsのサンプルが記載されているので、これを見ながらやってみる。
https://fly.io/user/personal_access_tokens からアクセストークンを発行する。
公式の通り FLY_API_TOKEN
という名前でGitHubActionsのSecretsとして登録する。
最終的には以下のようにした。
name: deploy to production
on:
push:
branches:
- main
jobs:
deploy:
name: Deploy app
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- uses: superfly/flyctl-actions/setup-flyctl@master
- run: flyctl deploy --remote-only
env:
FLY_API_TOKEN: ${{ secrets.FLY_API_TOKEN }}
ubuntu-22.04
は ubuntu-latest
と書いても良いがバージョンを固定したほうがWorkflowが安定するのであえてこう書いている。
この辺の情報は下記のGitHubの公式リポジトリを参考にした。
対応時のPRのURLも載せておく。
今後対応する事
一旦Slackbotの作成はここまでにする。というのもSlackbotを作っている最中にLLMを組み込んだWebサービスを作りたくなったのでそっちを始めようと思う。
ここまで作成したSlackbotは本当に最低限の機能しかない。本格的に利用するには最低でも以下のような対応を実施していく必要がある。
- Slackbotのタイムアウト対応、このままだとGPTからのレスポンスに時間がかかる場合タイムアウトが発生してしまう、この記事 のようにリクエストを受け付ける部分とレスポンスを返す部分を別プロセスにする必要がありそう。
- 会話履歴をDBに保存するようにする。
次にやるべき事をメモする為のスクラップを作成した。