🌊

【discord.py】モーダルの使い方

2024/10/21に公開

初めましての方は初めまして。ap12と申します。
記事を書くのは初めてなので、拙い部分等が多いと思います。
大目に見てやってください()

1.まずモーダルって何?

discordのモーダルは以下のようなものを指します。

簡単に言えば、テキスト入力欄がある画面です。
上のテキストボックスは1行のみ、下のテキストボックスは複数行入力できます。

2.どのように実装するの?

なにはともあれ、まずは実際のコードを見てみましょう。

import discord
from discord.ext import commands

# 変数botを作成する
bot = commands.Bot("!", intents=discord.Intents.all())


# TestModalの内容を決定する
# 括弧内のdiscord.ui.modalはTestModalに継承されます
class TestModal(discord.ui.Modal):
    # TestModal()されたときに呼び出されます
    def __init__(self) -> None:
        # スーパークラスの__init__を呼び出します
        super().__init__(title="Test Modal", timeout=None, custom_id="test-modal-1")
        
        # self.text1 と self.text2 に discord.ui.TextInput を設定します。
        self.text1 = discord.ui.TextInput(label="Example Input Field")
        self.text2 = discord.ui.TextInput(
            label="Example Long Input Field", style=discord.TextStyle.long
        )
        
        # このモーダル(自身)に discord.ui.TextInput を追加します。
        self.add_item(self.text1)
        self.add_item(self.text2)

    # モーダルが送信されたときに実行されるコード
    async def on_submit(self, interaction: discord.Interaction) -> None:
        # メッセージを送信する
        await interaction.response.send_message(
            f"送信された!\n{self.text1.value}\n\n{self.text2.value}"
        )


# on_readyはイベントということを伝える
@bot.event
async def on_ready():
    # botが開始された後にコマンドを同期する
    await bot.tree.sync()


# コマンドとして定義する
@bot.tree.command(name="modal-test")
async def modal_test(i: discord.Interaction):
    # コマンドが実行されたときに実行される
    await i.response.send_modal(TestModal())

# botを開始する
bot.run("トークン")

上記のコードは実際に画像のモーダルを表示するコードです。
クラスやその継承についてはこの記事では解説しません。
別の方の方が分かりやすく解説されていると思います(他力本願)

モーダルは送信後、discord.ui.TextInputvalueに入力された値を設定します。

各部の解説

super().__init__(title="Test Modal", timeout=None, custom_id="test-modal-1")

スーパークラス(この場合discord.ui.Modal)の__init__(初期化メソッド)を呼び出します。
ここで、モーダルのタイトルやタイムアウト(制限時間)を設定します。

self.text1 = discord.ui.TextInput(label="Example Input Field")

これは、self.text1にTextInputを作成して設定するためのものです。
selfはクラス内で共通になる値です(詳細には違う)
self.text1に対してTextInputを設定すると、ほかのメソッド(この場合on_submit)でも同じ値self.text1として参照できます。

self.add_item(self.text1)

では、self.text1をモーダルに追加しています。
一見add_itemは定義されていないように見えますが、継承元(discord.ui.Modalの継承元discord.ui.View)で定義されているため、問題なく動作します。

async def on_submit(self, interaction: discord.Interaction):
    ...

discord.pyでは、モーダルが送信された後on_submitが呼び出されます。
また呼び出される前にadd_itemで追加されたアイテムに対してdiscord側からの応答が適応されるため、値はself.text1.valueにて参照することができます。

discordでは、モーダルの送信ボタンが押されるとインタラクションが発行されます。
なおインタラクションについてはこの記事では詳しく解説しません。

3.詳しい仕様について

  • モーダルには現在最大5個までテキストボックスを付けることができます。
  • テキストボックスのスタイルについてはdiscord.TextStyle.shortdiscord.TextStyle.longが設定できます。
  • min_lengthmax_lengthプロパティで長さを制限できます
  • defaultプロパティで初期値を設定できます
  • placeholderプロパティで説明書きを追加できます
  • requiredプロパティでは、必須項目かどうか設定できます。必須項目はテキストを入力しないと送信できなくなります。
  • rowプロパティはそのテキストボックスの位置を指定します。何も指定しない(None)の場合には追加順になります。

4.今後の期待

今後はやはりラジオボタンや、セレクトボックスを設置できるようになってほしいですね。
できることの幅が増えそうです。

5.おわりに

初めて記事を書きましたが、いかがでしたでしょうか。
ミスがあったり、文章が拙かったりしますが、大目に見ていただけると嬉しいです()
より詳細な内容やプロパティはdiscord.py公式ドキュメントを見るといいでしょう。
ありがとうございました。

Discussion