なんか面白そうな機能キタ――(゚∀゚)――!!
Qiita2回目の初心者です。
ということで、テキスト入力をさせるモーダルウィンドウを表示させることができるようになりました。
おもろいなぁって思ったので、メモ程度にQiita書かせていただきます。
また、環境はnextcordですが、Discord.pyとかpycordとかでも、バージョン2.0以上なら使えるので、import
の名前とかをAPIリファレンス又は勘をもとにリファクタリングしてください。
百聞は一見に如かず
まずは、コードを見てみましょう。
import nextcord
from nextcord.ext import commands
from nextcord import Interaction
bot = commands.Bot()
class FavoriteFoodModal(nextcord.ui.Modal):
def __init__(self):
super().__init__(
"好きな食べ物は何ですか?",
timeout=None,
)
self.food = nextcord.ui.TextInput(
label="食べ物",
style=nextcord.TextInputStyle.short,
placeholder="おにぎり",
required=True,
)
self.add_item(self.food)
async def callback(self, interaction: Interaction) -> None:
await interaction.response.send_message(f"好きな食べ物は{self.food.value}なんだね!")
return
@bot.slash_command(name="food", description="好きな食べ物を聞きます")
async def food_slash(interaction: Interaction):
modal = FavoriteFoodModal()
await interaction.response.send_modal(modal=modal)
bot.run("abcdefghijklmnopqrstuvwxyz.1234567890.abcdefghijklmnopqrstu")
モーダルウィンドウは、スラッシュコマンド
又はボタンなどのUI
のインタラクションにて表示させることができます。
上記コードの場合、スラッシュコマンドの/food
を送信すると、FavoriteFoodModal
のインスタンスを作成して、それをinteraction.response.send_modal
という関数に渡して実行されていって下のように表示されます。
明らかに「レバニラ」とかを要求してそうなモーダルの完成です。
試しに「レバニラ」なんて入力してあげると、
という風に、入力された値が返ってきます。
...ちょっとだけでいいから要約して。
まず、nextcord.ui.Modal
クラスを継承したクラスを作ります。
__init__
の中には、モーダルウィンドウのタイトルとタイムアウト時間を指定します。
次にself
内にnextcord.ui.TextInput
クラスを、ラベルなどのパラメーターの値を渡してインスタンス化します。
そしたらself.add_item
関数に先ほどのTextInput
を渡せば完了です。
モーダルで送信が行われた際にcallback
関数が実行されます。
値の取得は、self
内の先ほどインスタンス化したTextInput
のvalue
というやつが値らしいので、そっから取れます。
で、あとはメッセージ送信をするなり煮るなり焼くなりしてあげてください。
もうちょっとだけ詳しい仕様を解説するQ&A風コーナー
Q. モーダルウィンドウには複数個のテキストボックスをつけることができますか?
A. できます。
Q. ちなみに何個まで?
A. モーダルには最大で5つのテキストボックスをつけることができます。
Q. さっき言ってたラベルなどのパラメーター
って実際には何があるの?
A. なんかたくさんあります。
パラメーター | 変数型 | 説明 |
---|---|---|
label | str |
テキストボックスの上のラベル文 |
style | nextcord.TextInputStyle |
テキストボックスのスタイル(後述) |
*custom_id | str |
インタラクションに関するカスタムID |
*row | int |
モーダルの中でのテキストボックスの位置(0-4) |
*min_length | int |
最小文字数 |
*max_length | int |
最大文字数 |
*required | bool |
必須項目にするかどうか |
*default_value | str |
最初から入力されてるデフォルトの値 |
*placeholder | str |
後ろにうすーく見えるプレースホルダーの値 |
Q. テキストボックスのスタイルって?(nextcord.TextInputStyle
って?)
A. 1行だけのテキストボックス(nextcord.TextInputStyle.short
)か、複数行入力可能なテキストボックス(nextcord.TextInputStyle.paragraph
)かの違いです。
HTMLやってる人にわかりやすく伝えるなら、<input type="text">
か、<textarea>
かの違いです。
Q. 必須項目じゃないところで、なにも入れずに送信したらどうなるの?
A. value
に""
(何もない文字列)が返ってきます。
Q. スマートフォン/タブレット版Discordには対応してるの?
A. なぜか画面全体を覆いますが、普通にモーダルが表示されます。
Q. 上のコードコピペしたけど動かない!
A. もし、あなたの使っているラッパーがnextcord
でなければ、nextcord
というところをdiscord
に置き換えてみてください。(ごめんなさいあとは知りません)
Q. 自分で追加してみたけどCommand raised an exception: TypeError: Object of type TextInput is not JSON serializable
ってエラーが出て動かない!
A. 私も騙されましたが、TextInput
クラスをインスタンス化する際に、self.title
とかを使うと、そのエラーが発生します。
理由としては多分nextcord.ui.Modal
のクラス内で使われてるパラメーターを指定すると、当然それをTextInput
に置き換えて、それをサーバーに送信しようとしてなんか...こう...エラーが...ってことなんでしょう。
とりあえず、使いがちですがtitle
などのパラメーターの名称は使わないようにしましょう。
パラメーターの名称などはAPIリファレンスとかを見れば大体わかります。
自分でDiscord Developer Portal眺めて頑張って解決したんです。褒めてくだs((
今後に期待
ui.Modal
クラスとui.TextInput
クラスが分かれてるってことは、今後はラジオボタンとかチェックボックスとかをモーダルに配置できるようになるんでしょうかね...
そうなったら結構面白そうですよね~(個人の感想)
あと、テキストボックスって機能があるだけで、画像認証BOTなんかはさらなる機能向上とか出来ますよね?ね?(同業者からの圧)
おしまい
まず、記事内にミスがあったらご容赦ください。コメントでなんか言ってもらえたら嬉しいです。
今後はDiscordBOTに関する内容とかを、後世に残すつもりでQiitaで書いていけたらなーって思ってたりしてます。
私自身の作成しているDiscordBOTは、にらBOTというもので、まぁ...地道に頑張ってるので...少しでも応援していただいたら嬉しいです...
もし出来るなら、皆さんも一緒にプログラミングをして、周りから「チョット出来る奴」みたいな目で見てもらえるようになりましょう!
では!