Discord bot × ChatGPT APIで爆速しゃべり相手構築

# はじめに

- 家族間で使えるchatgpt botをDiscordに導入する
- その時のログ
- エンジニア初学者の備忘録（クソ適当）

# 構成

- Ubuntu 22.04 オンプレ鯖
- Gitでの管理がクソ楽なのでdockerコンテナで起動する

# やっていく

### Botのアカウント作成

https://discord.com/developers/applications

Discord Developer partalのアカウントが必要らしい

右上の**new Application**からbot名を入力

![スクリーンショット 2024-03-23 20.31.17.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3504047/d6b24639-5fc7-a1cc-b52a-76ce0e76a290.png)

bot名は適当

![スクリーンショット 2024-03-23 20.34.30.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3504047/00dcfbe1-68e9-56cc-750c-8394a5405994.png)

家族の相棒の人形をbotの写真に設定

ちなみにのこたん（しろたんの亜種）という人形、かわいい（どうでもいい）

![スクリーンショット 2024-03-23 22.21.03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3504047/fa5d9f07-7915-4add-6cfe-1117e14be5de.png)

ついでにこれら権限を許可しといてください

### botをサーバーに参加させてみよう

OAuth2 → `bot`, `applications.commands`にチェックを入れます

![スクリーンショット 2024-03-23 20.40.34.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3504047/6715a407-4e4c-8604-cf78-626d675cb46d.png)

これはbotとして動作させる、コマンドをサーバーで利用するために必須。

絶対やっておきましょう

下の方に行くと、**GENERATED URL**というものがあります。これをコピペして開く

![スクリーンショット 2024-03-23 20.43.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3504047/ea16efd2-a0e8-54f1-7240-877faa822d3e.png)

参加させたいサーバーを選んで参加させます〜

![スクリーンショット 2024-03-23 20.45.43.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3504047/d74a54a0-7fb2-eb8c-5132-d034b275e319.png)

参加してそう！ok

あとは適当にロールを管理者権限で付けておきましょう〜

### Botの構築（環境構築編）

とりあえず以下がドキュメント

https://discordpy.readthedocs.io/ja/latest/index.html

軽く読んでみると、

- python3.8で動作する
- `python3 -m pip install -U discord.py` でライブラリは入る
- 依存関係にあるライブラリが必要

これらをコンテナの起動時に実行してあげる必要があるわけですな（小並感）

じゃあこれを`docker-compose.yaml`と`Dockerfile`に書いてあげます

`docker-compose.yaml`

```
version: '3.8'
services:
  bot:
    build: .
    env_file:
      - .env
    volumes:
      - .:/bot
    command: python3 bot.py
```

`Dockerfile`

```
# Pythonイメージの使用
FROM python:3.8-slim

# 必要なシステム依存関係のインストール
RUN apt-get update && apt-get install -y \
    python3-dev \
    libnacl-dev \
    libffi-dev \
    && rm -rf /var/lib/apt/lists/*
    
# python-dotenvのインストール
RUN python3 -m pip install -U python-dotenv

# 作業ディレクトリの設定
WORKDIR /bot

# discord.pyのインストール
RUN python3 -m pip install -U discord.py

# Botのコードをコピー
COPY . .

# Botを実行
CMD ["python3", "./bot.py"]
```

では、早速環境構築の儀を行う

```
$ docker-compose build
$ docker-compose up
```

![スクリーンショット 2024-03-23 21.54.29.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3504047/50844d89-9175-fe1f-78c4-f62e63531d7b.png)

docker「bot.py」がねえぞ！！！！ばか！！！！！！！って出たら完了

### botの構築（本体制作）

やる前にドキュメントの最小構成試してみるか〜

ディレクトリにbot.pyを作ります

`bot.py`

```
import discord
import os
from dotenv import load_dotenv

load_dotenv()  # .envファイルから環境変数を読み込む

intents = discord.Intents.default()
intents.message_content = True

client = discord.Client(intents=intents)

@client.event
async def on_ready():
    print(f'We have logged in as {client.user}')

@client.event
async def on_message(message):
    if message.author == client.user:
        return

    if message.content.startswith('$hello'):
        await message.channel.send('Hello!')

client.run(os.getenv('DISCORD_TOKEN'))
```

少し改造して`.env`から読み込むようにしてあります。`.env`というファイルを作って、Discordのトークンを入れてあげましょう

では早速

```
$ docker-compose up
```

立ち上げて、Shard ID None has connected to Gateway何ちゃら何ちゃらみたいなの出たら成功

この時点でbotは動作しているので、discordでチェックしてみましょう！

![スクリーンショット 2024-03-23 22.27.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3504047/2e5b7ecb-9ddd-653d-2a71-b5b816631c70.png)

おk ちゃんと動いているみたいで安心。

早速OpenAIのChatGPT - APIを組み入れていくぅ！！！！

まずはAPIを発行（以下からどうぞ）

https://platform.openai.com/api-keys

プラスでChatGPT-API使用するにはクライアントライブラリが必要なのでDockerfileに`openai`を追加します。

`Dockerfile` （以下を追加）

```
# OpenAIライブラリのインストール
RUN python3 -m pip install -U openai
```

それでは実際に`bot.py`を書いていきます。

```
import discord
import os
from dotenv import load_dotenv
from openai import OpenAI

# .envファイルから環境変数を読み込む
load_dotenv()

# 環境変数からDiscord Botのトークンを設定
TOKEN = os.getenv('DISCORD_TOKEN')

# Discord Botのクライアントを作成
client = discord.Client(intents=discord.Intents.all())

# Discord Bot起動時
@client.event
async def on_ready():
    print(f'{client.user} has connected to Discord!')

@client.event
async def on_message(message):
    if message.author == client.user:
        return

    # noko_data.txtからプロンプトテンプレートを読み込む
    with open('noko_data.txt', 'r') as file:
        prompt_template = file.read().strip()

    openai_clent = OpenAI(api_key=os.getenv('OPENAI_API_KEY'))

    messages = [
        {"role": "system", "content": prompt_template},
        {"role": "user", "content": message.content}
    ]

    completion = openai_clent.chat.completions.create(
        model="gpt-3.5-turbo",
        messages=messages,
        temperature=0.7,
        max_tokens=150
    )
    
    response = completion.choices[0].message.content

    # 応答を送信する
    await message.channel.send(response)

# Discord Botを起動する
client.run(TOKEN)
```

参考：chatgptのドキュメント

https://github.com/openai/openai-python

それでは一度buildしなおして起動してみます（.envファイルにopenaiのkeyを追加するのを忘れずに）

また、`prompt_template`としてキャラデータを読み込んでいます。要らなければ消してもらっておk

![スクリーンショット 2024-03-24 1.22.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3504047/6258a6d8-c1b4-344a-3b48-f01f1f0efda1.png)

よしレスポンスもおk

完成（みんなはbotの権限周りの設定しっかりやろうね）