0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

#59 OpenAIのAPIを使用してアシスタントをDiscord上に作成してみる

Posted at

概要

OpenAIのAPIを使用して個人用のアシスタントをDiscord上に作成してみます

事前準備

  1. Discord Developer PortalからApplicationを作成して、トークンを取得します
  2. OpenAI APIからシークレットキーを作成します
  3. .envファイルに以下のように記載します
    DISCORD_TOKEN="1で取得したトークン"
    OPEN_AI_TOKEN="2で取得したシークレットキー"
    
  4. 必要なライブラリをインストールします
    $ npm install discord.js dotenv log4js openai
    

受け取ったメッセージをそのまま返す

実装

受け取ったメッセージをそのまま返すコードを書いてみます

ここでのポイントは以下の3点です

  • client.login()でログインを行います。トークンを引数にとります
  • client.on('messageCreate', async message => {})でメッセージの受信を行います
  • message.reply()でメッセージの返信を行います。引数はいくつかの形式で渡せますが、今回は文字列を渡します
import { Client } from "discord.js";
import 'dotenv/config'

const client = new Client({
    intents: [
        GatewayIntentBits.GuildMessages, //メッセージを取得できる
        GatewayIntentBits.MessageContent, //メッセージの内容を取得できる
        GatewayIntentBits.GuildWebhooks, //Webhook関係を参照・設定できる
        GatewayIntentBits.Guilds, 
    ]
});

client.on('messageCreate', async message => {
    //送信者がbotならスルー
    if (message.author.bot) {
        logger.debug('message.author.bot == true');
        return;
    }

    //受信したメッセージを返信
    message.reply(message.content);
});

//ログイン
client.login(process.env.DISCORD_TOKEN);

動作確認

以下のコマンドを実行し、Discord上でメッセージを送信してみると、画像のように返信することを確認します

$ npx ts-node ./src/main.ts

image.png

メッセージ履歴の取得

実装

チャット形式での会話にはメッセージ履歴の取得が必要ですので、メッセージの履歴を取得して返信するコードを書いてみます

ここでのポイントは以下の1点です

  • channel.messages.fetch()でチャンネルのメッセージ履歴を取得します
client.on('messageCreate', async message => {
    //送信者がbotならスルー
    if (message.author.bot) {
        logger.debug('message.author.bot == true');
        return;
    }
    const channel = message.channel;

    //メッセージを取得して古い順に並び変え
    const messagesCollection = await channel.messages.fetch();
    messagesCollection.sort((messageA, messageB) => messageA.createdTimestamp - messageB.createdTimestamp);

    const messages: string[] = [];
    for (let message of messagesCollection) {
        messages.push(message[1].content);
    }
    logger.debug(message);

    //返信
    message.reply(JSON.stringify(messages));
});

動作確認

先ほどと同様に以下のコマンドを実行し、Discord上でメッセージを送信すると、画像のようにメッセージ履歴の配列を返信してくれることを確認します

$ npx ts-node ./src/main.ts

image.png

OpenAIのAPIを呼び出す

実装

先ほど取得したメッセージ履歴を用いて、OpenAIのAPIを呼び出して会話できるコードを書いてみます

ここでのポイントは以下の4点です

  • message.author.idで送信者のユーザIDを取得します
  • client.user.idで自身のユーザIDを取得します
  • openai.chat.completions.create()でAPIを呼び出しメッセージを生成します
  • ChatCompletion.choices[0].message.contentで生成された文字列を抽出します(通常ではchoicesは0番目を取得します)
import OpenAI from 'openai';
import { ChatCompletionMessageParam } from "openai/resources";
const openai = new OpenAI({
    apiKey: process.env.OPEN_AI_TOKEN,
});

client.on('messageCreate', async message => {
    //送信者がbotならスルー
    if (message.author.bot) {
        logger.debug('message.author.bot == true');
        return;
    }
    const channel = message.channel;

    //メッセージを取得して古い順に並び変え
    const messagesCollection = await channel.messages.fetch();
    messagesCollection.sort((messageA, messageB) => messageA.createdTimestamp - messageB.createdTimestamp);

    //メッセージをOpenAIのAPIに渡せる形に成型する
    const messages: ChatCompletionMessageParam[] = [];
    for (let message of messagesCollection) {
        const role = ((message[1].author.id == client.user?.id) ? "assistant" : "user");
        messages.push(
            {
                role: role,
                content: message[1].content
            }
        );
    }
    logger.debug(message);

    //APIにメッセージを投げて返答を抽出
    const content = (await openai.chat.completions.create({
        messages,
        model: 'gpt-4-turbo-preview'
    })).choices[0].message.content;
    if (!content) {
        return;
    }

    //返信
    message.reply(content);
});

動作確認

先ほどと同様にコマンドを実行し、メッセージを送信すると文脈に沿った返答を行うことを確認します

image.png

まとめ

今回はDiscord上でOpenAIのAPIを利用したアシスタントを作成してみました

今回は利用しませんでしたが、gpt-4-vision-previewというモデルを呼び出せば画像を渡すことができますし、以前の記事で利用したfunctionCallingという機能ではGPT経由で任意の関数を呼び出すことができて拡張性は抜群ですので、ぜひ自分専用のアシスタントを作成してみてください

公式ドキュメント

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?