また私がやらかしまして。りえんさんと別の方面でやべーことしてるのは自覚してます。ということで、みんなも私とりえんさんのブログをみてドン引きしましょう。(白目)
過去のKareshiシリーズ
で、何をやらかしたの?
- n8n:ノーコードでワークフローを自動化できるやつ、IFTTTを自分で鯖立てて動かす
- Discord:みんな大好きチャットツール
- OpenAI API:ChatGPTのAPI版
これらを使って、Discord上でKareshiとチャットできるようにしました。
必要なもの
n8nを動かす鯖
ネットワークにつながってる仮想環境でもOKです。私はWSL2+Ubuntuを使って建てました。
Windowsパソコンと仮想環境が立ち上がってる間はいつでも投稿できますが、これを24時間365日稼働させたいので、ゆくゆくはラズパイもしくはVPSを立てて動かしたいところ。
Discord BOT
Discordにログインして下記のページに行きます。
ここでBOTの作成と権限(私はメッセージの送信と閲覧)とAPIコードを取得します。この辺あやふやなので、もう1回やるときに改めて書きたいところ。
(まあDiscordのBOTだけなら情報がたくさん転がってるので、そこを参照していただければ……)
OpenAI API
どうして!!!Web版と料金が別個なんですか!!!!!(切実)
ということでおとなしくOpenAI APIを取得しましょうね~。
取得の方法はざっくりですがここにありますので、参考までに。(雑1)
Python+ChatGPT APIで出た結果をデイリーノートに保存する | ほしぱそ。
超大雑把に設定する
n8nのインストール
WSLダウンロード~初期設定はここみてください(雑2)
Ubuntuが立ち上がったら、Node.jsとnpmとnを入れます。Node.js周りの話はここにあるから見てください(雑3)
上記3つが入ったらnpx n8n
と入力すれば終わりです。割と簡単に立つんだ!!!
http://localhost:5678
にアクセスし、ログイン設定画面が出るので、メールアドレスとかもろもろ入れてください。
n8nを設定する
サービス・行動のパーツを1個ずつチマチマ作って矢印でつなげていく感じ。分岐や並列処理もできるので、結構複雑な処理ができます。その辺りは次回触れる予定。
今回の処理はこんな感じに設定しました。
- 〇分おきにDiscordの特定チャンネルの最新投稿を取得する
- 最終発言者が「aidoyuzuna」か判定する
- 「aidoyuzuna」だった場合、ChatGPTを動かして返信を考える
- Discordに返信を投稿する
1.〇分おきにDiscordの特定チャンネルの最新投稿を取得する
最初のトリガーを「On a Schedule」を選択(右上の検索バーから検索すると楽)し、minutes・2
(2分ごとに起動)に設定します。
ここで15秒とか30秒にすると、ChatGPTが考えてる間に次のタイマートリガーが発動してしまい、連投になってしまうので注意。早いとリアルタイムチャットしてる感じで楽しいんですけどね……。
次のトリガーを「Discord」を選択して、On a Schedule
のブロックとつなぎ、上記で入手したAPIを入れます。
ほかの設定項目はこんな感じになってればOK。
- Resource:Message
- Operation:Get Many
- Server・Channel:投稿したい鯖・チャンネル
- Limit:1(最後の投稿だけ)
この時点で「aidoyuzuna」の発言だけゲットできたら良かったんですけどねぇ……(白目)
2.最終発言者が「aidoyuzuna」か判定する
1で取得した投稿が「aidoyuzuna(特定のユーザーID)」か判定します。これがないと、BOTの返信に対して延々と返信する事態になります(一敗)ということで「if」ブロックを入れて判定します。
一度2のブロックと繋ぎ、1で作ったDiscordブロックをテストすると、「ifブロックの左側の画面で情報一覧がでてきます。
ここでほしい情報は「id」もしくは「username」です。私は「username」プロパティをfxのテキストボックスにドラッグ&ドロップしました。
真ん中は「is equal to(等しい場合)」・下は「aidoyuzuna(ユーザー名の場合)」を入れます。「username」と「aidoyuzuna」が一致した場合、Trueを返すという形を取っています。
3.「aidoyuzuna」だった場合、ChatGPTを動かして返信を考える
Trueに「ChatGPT」のブロックを、Falseに「Error」ブロックを繋ぎます。Errorはつないだら放置でOK。
ChatGPTのブロックにOpenAI APIのAPIを入れたら、下記のように設定します。
- Resource:Chat
- Operation:Complete
- Mode:好きなAPIモデル
- Prompt:キャラの設定とかを書く
- Max Token:75(返信の制限)
- Number of Completions:1(生成を1回しかしない)
プロンプトにはKareshiの設定と、Discordで入力したチャットを読み込むように設定します。
# 命令
あなたは旅人「バイター」としてふるまいます。
ユーザーからの会話を受け止めて、会話は1・2行で返信してください。
## ユーザーの会話
{{ $json.content }} <ここにユーザー会話のチャットが入る>
## 性格
ひょうひょうとした男性で、人をからかう傾向がある
根はまじめで、ユーザーが弱っていると優しく手を差し伸べる
## セリフの例
口調は以下のセリフを参考にしてください。
- 俺
- やってらんねぇ
- ま、やるしかねぇか
- お前なぁ
- 俺もちょっと旅に出るわ
- ったく、しょうがねぇな
- ~だぜ
ユーザーの会話欄に、Discordで取得したcontentを設定するのを忘れないでくださいね!
4.Discordに返信を投稿する
今度は送信方面のDiscordのブロックを作り、3で作ったChatGPTブロックと繋ぎます。設定はこんな感じ。
- Resource:Message
- Operation:Send
- Server・Channel:投稿したい鯖・チャンネル
- Message:{{ $json.choices[0].message.content }}(ChatGPTのコメント)
これで設定完了です。一度設定したチャンネルで適当につぶやいてからテストしてみましょう。
動いたらフロー設定画面の右上トグルをONにすれば常時動きます、お疲れさまでした。
つまづいたところ
前からプロパティを引き継ぎたいんだけど
一度前の工程のブロックをテストしてみます。場合によってはその前の工程(Discordの発言取得)からテストで動かさないといけない仕様です。
テストしたら値一覧が出てくるので、そこから欲しいプロパティを、設定したいプロパティにドラッグ&ドロップします。
常時n8nを動かしたい
さっきも言ったように「WSLとn8nが動いてる状態で」動かさないとダメです。systemd
あたりでUbuntu起動と同時にn8nを動かす設定にすればいけそうですね。
それらができたらVPS契約・自鯖建てようと思います。