この記事では質問をしたら以下のように自動で返答をしてくれるDiscordのBotを作成します。
概要
3月1日、遂にOpenAIが「ChatGPT」のAPIを提供開始ました。
これは言語モデル、gpt-3.5-turboを搭載しており、価格は$0.002/1000tokensとなっています。以前の言語モデル、Davinciと比較すると、1000トークンあたりの価格が1/10となっていてよりリーズナブルになっています。
トークンの計算は、英語の場合1単語あたり1トークンですが、日本語の場合は複雑になっています。
日本語のトークンの数が知りたい場合、OpenAIのプレイグラウンドで確認することができます。
例えば、「This is a pen」だと4トークン、「これはペンです」だと8トークンとなっています。
対象読者
- JavaScriptをある程度理解している人
- VScodeをあらかじめインストールしている人
- これからDiscord botを開発する人
開発環境
MacOS Ventura(v13.2.1)
VScode(v1.76)
Node.js(v18.14.0)
npm(v9.3.1)
環境の作成
- 任意の場所にコードを入れるファイルを作成します
私の場合、書類フォルダの中に"Discord_gptchat"という名前のフォルダを作成しました。(名前はなんでも可) - VScodeを開き、作ったフォルダを読み込みます。
- package.jsonの作成
以下のコマンドをターミナルで実行します。
npm init
色々とオプションを聞かれるので次のようにしてください。("は入力しない)
{
"name": "bot",
"version": "1.0.0",
"description": "",",
"main": "bot/index.js,",
"scripts": {
"test": "echo "Error: no test specified" && exit 1"
},
"author": ",
"license": "ISC"
}
Is this OK? (yes) y
- Discoed.js,dotenv,openaiをインストール
以下のコマンドをターミナルで実行します
npm install discord.js dotenv openai
discord.jsはDiscordのライブラリ
dotenvは.envを読み込めるようになるモジュール
openaiはOpenAIのライブラリ
となっています。
完了するとこのようなファイル構成になっています。
botというフォルダを一番外のフォルダ内に作成した後、index.jsというファイルをbotの中に作成します。
そして、下記のコマンドで.envファイルを作成します。
touch .env
各種トークンの取得
discordのトークン取得
- Discordの開発者ポータルにアクセスし、Discordのアカウントでログインします。
- New Applicationを選択ます。
- 任意の名前を入力し、チェックマークをクリックしCreateボタンをクリックします。
- 画面左側のメニューバーでBotを選択した後、Add botをクリックします。
- するとこのような画面になります
- 下にスクロールし、以下のように設定し、セーブしてください
- 最後に一番上まで戻り、View Tokenを押しトークンを取得してください。(後で使用するのでどこかにメモしておいてください)
OpenAIのAPIキー取得
以下のサイトにアクセスし、アカウントが既にある場合はログイン、無い場合は新規作成をし、secret keyを取得してください。
.envファイルの編集
以下のように書いてください。
OPENAI_API_KEY=取得したOpenAIのシークレットキー
BOT_TOKEN=取得したDiscord botのトークン
コードの作成
以下のコードを先ほど作ったindex.jsに保存します。
// dotenvを使って、環境変数を読み込む
require("dotenv").config();
// 必要なモジュールを読み込む
var fs = require("fs");
const { Client, GatewayIntentBits } = require("discord.js");
const Discord = require("discord.js");
// Discordクライアントを初期化する
const client = new Discord.Client({
intents: Object.values(Discord.IntentsBitField.Flags),
});
// OpenAIのAPIキーを設定する
const { Configuration, OpenAIApi } = require("openai");
const configuration = new Configuration({
apiKey: process.env.OPENAI_API_KEY,
});
const openai = new OpenAIApi(configuration);
// Discordクライアントが起動すると、一度だけ呼び出される関数を定義する
client.once("ready", () => {
console.log(`${client.user.tag} Ready`);
});
// Discordクライアントが起動すると、一度だけ呼び出される関数を定義する
client.on("ready", async () => {
// コマンドを定義する
const chat = [
{
name: "gpt",
description: "質問したら答えが返ってきます",
options: [
{
type: 3,
name: "質問",
description: "質問したい文を入れてください",
required: true,
},
],
},
];
// コマンドを登録する
await client.application.commands.set(chat);
});
// インタラクション(コマンド)が作成されたときに呼び出される関数を定義する
client.on("interactionCreate", async (interaction) => {
// インタラクションがコマンドでなければ、何もしない
if (!interaction.isCommand()) return;
// インタラクションがどのコマンドかを取得する
const command = interaction.commandName;
// gptコマンドが呼び出された場合、OpenAIに質問を送信する
if (command === "gpt") {
// 質問を取得する
const question = interaction.options.getString("質問");
console.log(question); // 質問がコンソールに出力される
// interactionの返信を遅延する
await interaction.deferReply();
// OpenAIに質問を送信し、回答を取得する
(async () => {
try {
const completion = await openai.createChatCompletion({
model: "gpt-3.5-turbo",
messages: [{ role: "user", content: `${question}` }],
});
const answer = completion.data.choices[0].text;
await interaction.editReply(
`${question}\n>>${completion.data.choices[0].message.content.trim()}\r\n`
);
} catch (error) {
console.error(error);
await interaction.editReply(`エラーが発生しました: ${error.message}`);
}
})();
}
});
//Discordクライアントにログイン
client.login(process.env.BOT_TOKEN);
詳しい説明は省略しますが、/gptというスラッシュコマンドを作成し、コマンドの引数に質問を入力しています。
下の部分でgpt-3-turboのオプションを設定しています。ここを変える事で動作が変わります。詳細は、詳細はOpenAIのドキュメンテーションを参照してください。
// OpenAIに質問を送信し、回答を取得する
(async () => {
try {
const completion = await openai.createChatCompletion({
model: "gpt-3.5-turbo",
messages: [{ role: "user", content: `${question}` }],
});
Discord botの招待
Discordの開発者ポータルを開きOAuth2→URL Generatorを押します。
そして、以下のように設定します。
一番下にGENERATED URLというものがあるので、それをコピーします。
コピーしたリンクを開くとどのサーバーに追加するかを選択できるので、追加するサーバーを選択しbotを入れます。
実行
以下のコマンドをターミナルで打ち込むと、botが起動します。
node bot/index.js
Discord上で以下のように、/gpt 質問と入力し、送信します。
すると以下のような返答になりました。
ChatGPTと同じような動作をしています。
おわりに
結構サクッと書いていますが結構情報量が少なくコーディングに時間がかかりました。
Discord.jsは情報が少なかったのですが、ChatGPTを使って質問するのがGoogleで検索するよりも明らかに効率が良いことに驚きました。
このAPIを使えば様々なことに転用できそうですね。
最後まで見ていただきありがとうございました!