disnake
128 строк · 4.6 Кб
1# SPDX-License-Identifier: MIT
2
3"""An example demonstrating two methods of sending modals and handling modal responses."""
4
5# pyright: reportUnknownLambdaType=false
6
7import asyncio
8import os
9
10import disnake
11from disnake.ext import commands
12
13bot = commands.Bot(command_prefix=commands.when_mentioned)
14
15
16# One way of sending modals is using a "high-level" implementation similar to views,
17# in which a class representing the modal is defined, complete with a callback and error handler.
18
19# Sent modals are stored internally for a certain amount of time, taking up some amount of memory.
20# Since there is no way of knowing whether the user closed the modal without submitting it,
21# they time out after 10 minutes by default, at which point they will be removed
22# from the internal storage, and any submission by the user will fail.
23# This timeout can be adjusted through the use of the `timeout` parameter of the modal class.
24
25
26class MyModal(disnake.ui.Modal):
27def __init__(self) -> None:
28components = [
29disnake.ui.TextInput(
30label="Name",
31placeholder="The name of the tag",
32custom_id="name",
33style=disnake.TextInputStyle.short,
34min_length=5,
35max_length=50,
36),
37disnake.ui.TextInput(
38label="Content",
39placeholder="The content of the tag",
40custom_id="content",
41style=disnake.TextInputStyle.paragraph,
42min_length=5,
43max_length=1024,
44),
45]
46super().__init__(title="Create Tag", custom_id="create_tag", components=components)
47
48async def callback(self, inter: disnake.ModalInteraction) -> None:
49tag_name = inter.text_values["name"]
50tag_content = inter.text_values["content"]
51
52embed = disnake.Embed(title=f"Tag created: `{tag_name}`")
53embed.add_field(name="Content", value=tag_content)
54await inter.response.send_message(embed=embed)
55
56async def on_error(self, error: Exception, inter: disnake.ModalInteraction) -> None:
57await inter.response.send_message("Oops, something went wrong.", ephemeral=True)
58
59
60@bot.slash_command()
61async def create_tag(inter: disnake.CommandInteraction):
62await inter.response.send_modal(modal=MyModal())
63
64
65# Similar to the views and low-level components duality,
66# you can also send modals using a more "low-level" implementation
67# without creating a custom modal class, and instead using event listeners.
68
69# Naturally, these are persistent, unlike modal classes which don't persist
70# over bot restarts and generally time out after a certain period of time.
71# Similarly, the listener approach doesn't impact memory usage for every sent modal
72# as much as the method shown above.
73
74
75@bot.slash_command()
76async def create_tag_low(inter: disnake.CommandInteraction):
77# Works same as the above code but using a low level interface.
78# It's recommended to use this if you don't want to increase cache usage.
79await inter.response.send_modal(
80title="Create Tag",
81custom_id="create_tag_low",
82components=[
83disnake.ui.TextInput(
84label="Name",
85placeholder="The name of the tag",
86custom_id="name",
87style=disnake.TextInputStyle.short,
88min_length=5,
89max_length=50,
90),
91disnake.ui.TextInput(
92label="Content",
93placeholder="The content of the tag",
94custom_id="content",
95style=disnake.TextInputStyle.paragraph,
96min_length=5,
97max_length=1024,
98),
99],
100)
101
102# Waits until the user submits the modal.
103try:
104modal_inter: disnake.ModalInteraction = await bot.wait_for(
105"modal_submit",
106check=lambda i: i.custom_id == "create_tag_low" and i.author.id == inter.author.id,
107timeout=600,
108)
109except asyncio.TimeoutError:
110# The user didn't submit the modal in the specified period of time.
111# This is done since Discord doesn't dispatch any event for when a modal is closed/dismissed.
112return
113
114tag_name = modal_inter.text_values["name"]
115tag_content = modal_inter.text_values["content"]
116
117embed = disnake.Embed(title=f"Tag created: `{tag_name}`")
118embed.add_field(name="Content", value=tag_content)
119await modal_inter.response.send_message(embed=embed)
120
121
122@bot.event
123async def on_ready():
124print(f"Logged in as {bot.user} (ID: {bot.user.id})\n------")
125
126
127if __name__ == "__main__":
128bot.run(os.getenv("BOT_TOKEN"))
129