7
14

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.

Discord.py 初学者に向けて

Last updated at Posted at 2022-10-23

1. はじめに

Discord.pyとは...?

  • DiscordのAPIラッパーをPython向けに書いたモジュール
  • 主に非同期処理で動いている。例えば関数はasync def hoge():で動いてるし、処理はawaitを使う。

2. Pythonの基本構文

コレが分かっていないと作ってエラーが出ても特定できず解決が難しいです。
先にpythonを軽く理解してからコーディングに入ったほうがいいかも。

文字列(str)と数値(int)

  • ""(ダブルクォーテーション)で囲うと文字列になる
  • 数値の場合は""をつけない
number = 3
string = "Hello Python!"

変数とprint()関数

#変数名 = 代入する値(strまたはint)
i = "Hello World!"
print(i)

演算子

  • 数値同士で演算子を使うとそのまま四則演算の結果になる
  • 文字列同士だと連結される
#結果:9
i = 3 + 6

#結果:7
i = 12 - 5

#結果:10
i = 50 / 5

#結果:1(10割る3の余り)
i = 10 % 3
#結果:Hello World!
i = "Hello" + "World!"

3. 雛形(1) discord.Client()を使う方法

※Discord.py 1.7.3を使った場合です

bot.py
import discord

intents = discord.Intents.all()

TOKEN = "ここにTOKENを張り付けてください"

bot = discord.Client(intents=intents)

@bot.event
async def on_ready():
    print(f"""
Bot logged!
bot user name:{bot.user.name}
bot user id:{bot.user.id}
    """)

@bot.event
async def on_message(message):
    if message.content == "!hoge":
        await message.channel.send(f"こんにちは!{message.author.mention}さん!")

if __name__ == "__main__":
    bot.run(TOKEN)

これで一通り動くと思います。
ただDiscord Developers Portalに行ってBotアカウントのIntentsをすべてONにしなきゃいけません。じゃないと動かないです

なおdiscord.Client()方式は今後の学習の妨げになるので、構文が簡単だからってすべてこれにしないほうがいいです。SlashCommand組むときに泣きます。

4.雛形(2) commands.Botを使う方法

bot.py
import discord
from discord.ext import commands

TOKEN = "ここにTOKENを入れてください"

intents = discord.Intents.all()
bot = commands.Bot(command_prefix="!", intents=intents)
bot.remove_command("help") #最初から入っているhelpコマンドを消す。消したほうがいいかも??

@bot.event
async def on_ready():
    print(f"""
Bot logged!
bot user name:{bot.user.name}
bot user id:{bot.user.id}
    """)

@bot.command()
async def hoge(ctx):
    await ctx.send(f"こんにちは!{ctx.author.mention}さん!")

@bot.command()
async def return(ctx, arg):
    await ctx.send(f"あなたが入力した内容はこれですね?\n{arg.content}")

@bot.event
async def on_message(message):
    if message.content == "a":
        await message.channel.send("")
    await bot.process_commands(message) #これつけないとon_messageが着火しません

bot.run(TOKEN)

基本的にこのひな形であればだいたいなんでも作れると思います。pycordやnextcord使うときはちょっと書き換えしないといけませんが汗
なお、commands.Botを継承したclassを使ってやるのもいいかもしれないです。

bot.py
import discord
from discord.ext import commands

TOKEN = "ここにTOKENを入れてください"

class Hogebot(commands.Bot):
    def __init__(self, command_prefix, intents, description=None):
        super().__init__(
                        command_prefix=command_prefix,
                        intents=intents,
                        description=description
                        )

    async def on_ready(self):
        print(f"""
Bot logged!
bot user name:{self.user.name}
bot user id:{self.user.id}
        """)
        await self.change_presense(activity=discord.Game(name=f"{len(self.guilds)}servers"))

intents = discord.Intents.all()
bot = Hogebot(command_prefix="!", intents=intents)
bot.remove_command("help") #最初から入っているhelpコマンドを消す。消したほうがいいかも??

@bot.command()
async def hoge(ctx):
    await ctx.send(f"こんにちは!{ctx.author.mention}さん!")

@bot.command()
async def return(ctx, arg):
    await ctx.send(f"あなたが入力した内容はこれですね?\n{arg.content}")

@bot.event
async def on_message(message):
    if message.content == "a":
        await message.channel.send("")
    await bot.process_commands(message) #これつけないとon_messageが着火しません

if __name__ == "__main__":
    bot.run(TOKEN)

5.SlashCommandについて

SlashCommandは便宜上Discord.py 2.0.0にて紹介させていただきます。
つきましてはDiscord.py2.0.0をダウンロードするため、以下のコマンドを実行するようにしてください

Windowsの場合
$ python -m pip install discord.py==2.0.0

$ python -m pip install discord==2.0.0

Windows以外の方は

Windows以外の場合
$ python3 -m pip install discord==2.0.0

$ python3 -m pip install discord.py==2.0.0

SlashCommandとはまず何か。
下の画像を見てもらえばわかるんですが端的に言えば「コマンドをわかりやすくしたもの」です。
/と打つだけで一覧が出てきたり、コマンドが被ってもしっかり反応します。さらにはこれらはあなただけに表示されていますなどのものも作れます。
なお、d.py V2.0には標準搭載されています。
ちなみに、Discord Developers Portalにてbotapplications.commands両方に権限を与え、新しい招待リンクで再度Botを認証する必要があります。
Image from Gyazo

雛型です。

bot.py
import discord
from discord import app_commands

TOKEN = "ここにTOKENを入れてください"
GUILD = discord.Object(id=int("ここに試験用のサーバーIDを入れてください"))

intents = discord.Intents.all() #本番環境では適宜変更してください
class Client(discord.Client):
    def __init__(self, *, intents: discord.Intents):
        super().__init__(intents=intents)
        self.tree = app_commands.CommandTree(self)
    
    async def setup_hook(self):
        self.tree.copy_global_to(guild=GUILD)
        await self.tree.sync(guild=GUILD)

client = Client(intents=intents)

@client.event
async def on_ready():
    print(f"BotUsername:{bot.user.name} logged.")
    await client.change_presence(activity=discord.Game(name=f"{str(len(bot.guilds))} servers"))

@client.tree.command(
name="hello",
description="hello world"
)
async def hello(interaction: discord.Interaction):
    await interaction.response.send_message("Hello World!")

client.run(TOKEN)

重要なのは7行目のself.tree = app_commands.CommandTree(client)です。これを使ってスラッシュコマンドを作れます。
各コマンドの定義は

bot.py
@client.tree.command()

というデコレーターを使います。()内にname="",description=""といった属性(それぞれコマンドの名前と説明文)を入れてやると晴れてコマンドができます。
ちなみに18行目からの

bot.py
async def hello(interaction: discord.Interaction):
    await interaction.response.send_message("Hello World!")

が関数本体です。関数名はデコレーター内のname=""に合わせてください。また、受け取るメッセージは本来のContextとは違い、discord.Interactionを受け取ります。
詳細はこれを見たほうが早いかも??

6.各種discord.uiについて

discord.pyにはモーダルウィンドウ(下記画像参照)やセレクトメニューを作るためのdiscord.uiなどが存在します。
Image from Gyazo

実装方法はこんな感じ。

bot.py
class Modal(discord.ui.Modal):
    def __init__(self):
        super().__init__(
            title="なにか入力するところ",
            timeout=None
        )
        
        self.answer = discord.ui.TextInput(
            label="なんか入力してみてね!",
            style=discord.TextStyle.short,
            placeholder="例:HelloWorld!",
            required=True
        )
        self.add_item(self.answer)

    async def on_submit(self, interaction: discord.Interaction) -> None:
        return await interaction.response.send_message("あなたが入力したものはこれですね!\n{}".format(self.answer.value)")

これでスラッシュコマンドの実行関数にawait interaction.response.send_modal(Modal())を渡してあげるとモーダルウィンドウが出現します!やったね!

ボタンの実装方法はこんな感じ

bot.py
class ButtonView(discord.ui.View):
    def __init__(self):
        super().__init__(timeout=None)
    @discord.ui.button(label="ボタン~~", style=discord.ButtonStyle.primary, custom_id="persistent_view:btn")
    async def callback_btn(self, button: discord.ui.Button, interaction: discord.Interaction):
        await button.response.send_message("Hello World!")

ここで重要ポイント!!
discord.ui.ViewはBotが再起動するとインタラクションに失敗しました。と出るので
先ほどのスラッシュコマンドbotのひな型内にあったasync def setup_hook(self):という関数内にadd_view(ButtonView())で登録してあげる必要があります。
ただし、

discord.ui.View__init__内にあるsuper().__init__()にはtimeout=Noneと入れてあげてください
デコレーター@discord.ui.button()にはcustom_id=""を設定してあげてください

残りは今度書く...(疲れた)

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?