6
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

DockerとPycordでDiscordbotの作り方

Last updated at Posted at 2023-04-10

はじめに

私が書いた記事を参考にDiscordBOTを作ってくれる方にcogsの使い方がわからんなどの話を聞いたりして、現在ほとんどDockerで環境を作ってそこで実行しているのであてになる記事になってないな、ということでDockerを使ってBOTを作成する方法を紹介したいと思った次第。

そんなわけでDockerでの環境構築からBOTの疎通確認レベルのコードを書いてきます。(Docker環境の構築については書きません)

前提

OS

  • Windos10 (ubuntuなどでもだいたい一緒)

インストールするもの

  • DockerDesktop
  • Python 3.10
    • py-cord

BOTの作成

ディレクトリの構成として以下のような状態を想定しています

.
┣━ docker-compose.yaml
┣━ Dockerfile
┣━ requirements.txt
┣━ .env
┗━ bot
    ┣━ main.py
    ┗━ cogs
        ┗━ sub.py

Dockerの構成

Dockerfile

Dockerfileはアプリケーションを実行するための環境を定義するものです。
そのため、ここではpythonのイメージを取得してrequirements.txtに書かれたライブラリをpip installするという事が書かれています。

Dockerfile
FROM python:3.10.5-alpine3.16
WORKDIR /usr/src/app
COPY requirements.txt ./
RUN pip install --no-cache-dir -r requirements.txt

requirements.txt

requirements.txtには必要なライブラリを記述します。
この時バージョンを指定することもできるので、現在ローカルの環境で使われているPycordのバージョンに合わせておくとトラブルが起きにくいです

requirements.txt
py-cord == 2.2.2

docker-compose.yaml

docker-compose.yamlを作成します。
イメージとしては以下のような事をしています。

  • Dockerfileのビルドを行いイメージとして利用する
  • ディレクトリをボリュームとしてマウント
  • 環境変数を渡す
  • コマンドの実行
docker-compose.yaml
version: '3.8'
services:
  bot:
    # . は現在docker-compose.yamlと同じディレクトリのDockerfileを指しています。
    # 複数のイメージを使う場合などは./botなどディレクトリを指定します。
    build: .
    volumes:
      # ./botのディレクトリを仮想環境の/usr/src/appにマウントする
      # rwと記述することで書き込みも可能なディレクトリとして認識される
      - ./bot:/usr/src/app:rw 
    environment:
      # ${}で囲んだものは.envファイルから環境変数を取得する
      - TOKEN=${TOKEN}
      - GUILDS=${GUILDS}
    command: ["python3", "main.py"]
    tty: true

.env

.envファイルは基本的にはBOTを動かすためのトークンの記述の他に実行するサーバーのIDなども一緒に定義しておきます

.env
# DiscordDevで発行したトークン
TOKEN="TOKEN" 
# DiscordサーバーのID(カンマ区切りで複数設定できるようにしてます)
GUILDS="000000000,000000000" 

BOTの構成

main.py

main.pyではbotをインスタンス化してcogsからコマンドなどを読み込む処理をします。
コマンドをこのファイルに書くと読みづらくなってしまうので基本書きません。

main.py
import discord
from discord.ext import commands
import os

# docker-composeから渡された環境変数の設定
TOKEN = os.getenv("TOKEN") 
GUILDS = [int(v) for v in os.getenv("GUILDS").split(",")]
# intentsの設定(エラーが出るまで基本defaultで良いです) 
intents = discord.Intents.default()

# debug_guildsは公開BOTの場合は必要ないです
bot = commands.Bot(
    debug_guilds=GUILDS,
    intents=intents
)

# botが動いてるか確認するだけのヤツ
@bot.event
async def on_ready():
    print(f"Bot名:{bot.user} On ready!!")

# cogsディレクトリにあるsub.pyを読み込む処理です
bot.load_extensions(
    "cogs.sub",
    # "cogs.hoge", # 複数読み込む場合は並べてかけます
    store=False # cog読み込み中にエラーが起きた時に止まる様に設定しています。
)
# botの起動
bot.run(TOKEN)

コマンドを増やしたい場合などはcogsにpythonファイル生やしてload_extensionsで読み込ませるというような使い方になると思います。

sub.py

sub.pyでは基本的にコマンドを定義していきます。
ここではcomというコマンドグループを定義し、その中にhelloというコマンドを定義しています。
実際に使うときはcom hello name: 名前のようなコマンドになります

sub.py
import discord
from discord.ext import commands
from discord import SlashCommandGroup, Option, SlashCommandOptionType

# main.pyで読み込ませるためのCogを継承したクラスを作成します。
class SubCog(commands.Cog):
    def __init__(self, bot):
        print("start sub init")
        self.bot = bot

    # comというコマンドグループを定義します
    com = SlashCommandGroup("com", "comコマンドのグループ")

    # comというコマンドグループにhelloコマンドを定義します
    @com.command(name="hello", description="挨拶するだけのコマンド")
    async def hello(
        self,
        ctx: discord.ApplicationContext,
        # name引数を受け取る様に設定します。
        name: Option(
            str,
            description="引数の説明",
        )
    ):
        # 引数の段階だと型がstr型かわかりにくいので注釈をつけてます
        name: str = name 
        # 名前にさんづけしてこんにちはするだけの処理
        await ctx.response.send_message(f"{name}さん、こんにちは!")

# main.pyのload_extensionsのが実行する実際の関数を定義します
def setup(bot):
    bot.add_cog(SubCog(bot)) #add_cog関数にSubCogのインスタンスを渡します

実行方法など

仮想環境上で先程書いてもらったmain.pyを実行するわけだが、Dockerの場合ほとんどPythonを直接実行するのとイメージは変わらない。

VSCodeなどでターミナルを開きdocker-compose.yamlがあるディレクトリに移動してdocker-compose buildコマンドを打ち込むだけでimageなどが用意され実行環境が整います。
image.png

実行環境が整ったらそのままdocker-compose upのコマンドを実行すれば実行がされます。
image.png

あとはコマンドを呼べるサーバーでcom hello name: 名前のように打ち込めばスラッシュコマンドが使える事が確認できると思います
image.png

終わりに

Pycordを使ったPythonのコードに関する部分などは疎通確認レベルのコードしか書いていません。
実際にbotを作成する場合はPycordなどのドキュメントを読んだりなんだりする必要が出てきます。

正直Discord.pyの方が公式で作られており、ドキュメントも日本語化されているのでオススメですが、DockerでBOTを動かす点でいえば一緒なので参考になれば、と思います。

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?