Skip to content

Commit f814d86

Browse files
committed
✨ Add simple_modal.py example
Signed-off-by: Paillat-dev <[email protected]>
1 parent 28d9689 commit f814d86

File tree

1 file changed

+136
-0
lines changed

1 file changed

+136
-0
lines changed
Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
import os
2+
3+
from dotenv import load_dotenv
4+
5+
import discord
6+
from discord import components
7+
8+
load_dotenv()
9+
10+
MAZE = True # 👀
11+
12+
13+
bot = discord.Bot(
14+
default_command_integration_types={discord.IntegrationType.user_install, discord.IntegrationType.guild_install},
15+
default_command_contexts={
16+
discord.InteractionContextType.guild,
17+
discord.InteractionContextType.bot_dm,
18+
discord.InteractionContextType.private_channel,
19+
},
20+
)
21+
22+
23+
def create_modal(user: discord.User | discord.Member) -> components.Modal:
24+
modal = components.Modal(
25+
components.TextDisplay(
26+
f"""Input below your announcement's title, description, and user to mention in the announcement{", as well as attached images" if MAZE else ""}."""
27+
),
28+
components.Label(
29+
components.TextInput(
30+
style=discord.TextInputStyle.short,
31+
placeholder="Launching py-cord next !",
32+
custom_id="v1:announcement_title",
33+
required=True,
34+
),
35+
label="Announcement Title",
36+
description="The title of your announcement",
37+
),
38+
components.Label(
39+
components.TextInput(
40+
style=discord.TextInputStyle.paragraph,
41+
placeholder="Today is the day we launch py-cord next !\nyada yada\n...",
42+
custom_id="v1:announcement_content",
43+
required=True,
44+
),
45+
label="Announcement Content",
46+
description="The content of your announcement. Supports Markdown.",
47+
),
48+
components.Label(
49+
components.MentionableSelect(
50+
default_values=[components.DefaultSelectOption(id=user.id, type="user")],
51+
custom_id="v1:announcement_mentions",
52+
min_values=0,
53+
max_values=4,
54+
required=False,
55+
),
56+
label="Mentioned Users and Roles",
57+
description="The users and roles to mention in your announcement (if any)",
58+
),
59+
title="Create an Announcement",
60+
custom_id="v1:announcement_modal",
61+
)
62+
if MAZE:
63+
modal.components.append(
64+
components.Label(
65+
components.FileUpload(min_values=0, max_values=5, required=False, custom_id="v1:announcement_images"),
66+
label="Images to attach",
67+
description="Attach up to 5 images to your announcement. Supports PNG only.",
68+
)
69+
)
70+
return modal
71+
72+
73+
@bot.slash_command()
74+
async def create_announcement(ctx: discord.ApplicationContext):
75+
await ctx.send_modal(create_modal(ctx.author))
76+
77+
78+
def create_announcement(
79+
title: str, content: str, mentions: list[discord.User | discord.Role], attachments: list[discord.Attachment]
80+
) -> components.Container:
81+
container = components.Container(
82+
components.TextDisplay(f"# {title}"),
83+
)
84+
if mentions:
85+
container.components.append(components.TextDisplay(" ".join(m.mention for m in mentions)))
86+
container.components.append(components.TextDisplay(content))
87+
if attachments:
88+
container.components.append(
89+
components.MediaGallery(
90+
*(
91+
components.MediaGalleryItem(
92+
url=attachment.url,
93+
)
94+
for attachment in attachments
95+
)
96+
)
97+
)
98+
99+
return container
100+
101+
102+
@bot.modal_listener("v1:announcement_modal")
103+
async def announcement_modal_listener(
104+
interaction: discord.ModalInteraction[
105+
components.PartialTextDisplay,
106+
components.PartialLabel[components.PartialTextInput],
107+
components.PartialLabel[components.PartialTextInput],
108+
components.PartialLabel[components.PartialMentionableSelect],
109+
components.PartialLabel[components.PartialFileUpload],
110+
],
111+
):
112+
assert interaction.channel is not None, "Channel is None"
113+
assert isinstance(interaction.channel, discord.abc.Messageable), "Channel is not a messageable channel"
114+
title = interaction.components[1].component.value.strip()
115+
content = interaction.components[2].component.value.strip()
116+
117+
mentions: list[discord.User | discord.Role] = []
118+
119+
for m_id in interaction.components[3].component.values:
120+
mentions.append(interaction.roles.get(int(m_id)) or interaction.users[int(m_id)])
121+
122+
if MAZE:
123+
attachments: list[discord.Attachment] = [
124+
interaction.attachments[att_id] for att_id in interaction.components[4].component.values
125+
]
126+
else:
127+
attachments = []
128+
129+
container = create_announcement(title, content, mentions, attachments)
130+
try:
131+
await interaction.channel.send(components=[container])
132+
except discord.Forbidden:
133+
await interaction.respond(components=[container])
134+
135+
136+
bot.run(os.getenv("TOKEN_2"))

0 commit comments

Comments
 (0)