async def send_to(self, dest, content=None, files=None, embed=None, allowed_mentions=AllowedMentions(everyone=False, roles=False), send_as_slash_command=True, hidden=False, reference=None, mention_author=None, fail_on_dm=None, view=None): msg = None if fail_on_dm and isinstance(dest, (DMChannel, User, Member)): return None if isinstance(dest, Webhook): msg = await dest.send(content, username=self.bot_name, avatar_url=self.bot_avatar, embed=embed, files=files, wait=True, allowed_mentions=allowed_mentions, view=view or ui.View()) elif self.slash_command and send_as_slash_command: kwargs = {"content": content, "ephemeral": hidden} if embed: kwargs["embeds"] = [embed] if view: kwargs["view"] = view if self.sent_first_slash_command: msg = InteractionWebhook(await self.slash_command[1].send(**kwargs), True) # webhook else: await self.slash_command[0].send_message(**kwargs) # no return msg = InteractionWebhook(self.slash_command[2], False) if not self.first_slash_command: self.first_slash_command = msg if not self.sent_first_slash_command: self.sent_first_slash_command = True else: msg = await dest.send(content, embed=embed, files=files, allowed_mentions=allowed_mentions, reference=reference, mention_author=mention_author, view=view) self.bot_responses.append(msg.id) return msg
def view_func(ctx): ui_elements = func(ctx) if not isinstance(ui_elements, list): ui_elements = [ui_elements] ui_view = ui.View(timeout=None) for ui_element in ui_elements: ui_element.callback = ctx.interaction_payload.callback ui_view.add_item(ui_element) return ui_view
def create_view(dropdown: InformationDropdown, link: str) -> ui.View: """ Creates the discord.py View for the Discord message components (dropdowns and buttons). The discord UI is implemented onto the embed, where the user can choose what information about the kata they want, along with a link button to the kata itself. """ view = ui.View() view.add_item(dropdown) view.add_item(ui.Button(label="View the Kata", url=link)) return view
async def callback(self, interaction): mention = interaction.user.mention if mention not in self.users: self.users[mention] = self.label await interaction.response.pong() else: subview = ui.View() undo_button = ui.Button(label = "Undo", style = discord.ButtonStyle.danger) undo_button.callback = self.undo subview.add_item(undo_button) await interaction.response.send_message( content = ":x: | You've already responded.", ephemeral = True, view = subview )
async def trivia(self, ctx, category: typing.Optional[int] = -1): catstring = "" if category == -1 else f"&category={category}" json = f"https://opentdb.com/api.php?amount=1{catstring}" result = await utils.get_json(self.bot.session, json) if result["response_code"] == 1: raise utils.CustomCommandError( "Invalid category code", f"Consult `{ctx.clean_prefix}trivia categories` to see the available codes." ) result = result["results"][0] info = f"**{result['category']}** | {result['difficulty'].capitalize()}\n\n" embed = embeds.GENERIC.create(html.unescape(result["question"]), info, heading="Trivia") correct = random.randrange(0, 2 if result["type"] == "boolean" else 4) answers = result["incorrect_answers"] answers.insert(correct, result["correct_answer"]) embed.description += f"The correct answer will appear in **one minute.**" embed.set_footer(text=f"Courtesy of the Open Trivia Database.") view = ui.View() users = {} tuple( view.add_item(views.TriviaButton(answer, users)) for answer in answers) message = await ctx.send(embed=embed, view=view) await asyncio.sleep(60) embed.description = f"{info}The correct answer is: **{html.unescape(answers[correct])}**" updated = await message.channel.fetch_message(message.id) if updated is None: return #message deleted results = defaultdict(list) for user, answer in users.items(): results[answer].append(user) stats = "\n".join(f"- {a}: {','.join(u)} (**{len(u)}**)" for a, u in results.items()) if stats: embed.description += f"\n\n**Responses:**\n\u0020{stats}" await message.edit(embed=embed, view=None)
async def wait_for_press( ctx: commands.Context, items: List[PredItem], content: Optional[str] = None, embed: Optional[Embed] = None, *, timeout: float = 180.0, ) -> Any: """Wait for a single button press with customisable buttons. Only the original author will be allowed to use this. Parameters ---------- ctx : commands.Context Context to send message to items : List[PredItem] List of items to send as buttons content : Optional[str], optional Content of the message, by default None embed : Optional[Embed], optional Embed of the message, by default None timeout : float, optional Button timeout, by default 180.0 Returns ------- Any The defined reference of the clicked button Raises ------ ValueError An empty list was supplied asyncio.TimeoutError A button was not pressed in time. """ if not items: raise ValueError("The `items` argument cannot contain an empty list.") view = _PredView(timeout, ctx.author.id) # type:ignore for i in items: button = _PredButton(i.ref, i.style, i.label, i.row) view.add_item(button) message = await ctx.send(content=content, embed=embed, view=view) await asyncio.wait_for(view.pressed.wait(), timeout=timeout) emptyview = ui.View() for i in items: button = ui.Button( style=i.style if i.ref == view.ref else ButtonStyle.gray, label=i.label, row=i.row, disabled=True, ) emptyview.add_item(button) await message.edit(view=emptyview) emptyview.stop() return view.ref
async def wait_for_yes_no( ctx: commands.Context, content: Optional[str] = None, embed: Optional[Embed] = None, *, timeout: float = 180.0, ) -> bool: """Wait for a single button press of pre-defined yes and no buttons, returning True for yes and False for no. If you want to customise the buttons, I recommend you use the more generic `wait_for_press`. Only the original author will be allowed to use this. Parameters ---------- ctx : commands.Context Context to send message to content : Optional[str], optional Content of the message, by default None embed : Optional[Embed], optional Embed of the message, by default None timeout : float, optional Button timeout, by default 180.0 Returns ------- bool True or False, depending on the clicked button. Raises ------ asyncio.TimeoutError A button was not pressed in time. """ view = _PredView(timeout, ctx.author.id) # type:ignore view.add_item(_PredButton(True, ButtonStyle.blurple, "Yes")) view.add_item(_PredButton(False, ButtonStyle.blurple, "No")) message = await ctx.send(content=content, embed=embed, view=view) await asyncio.wait_for(view.pressed.wait(), timeout=timeout) emptyview = ui.View() emptyview.add_item( ui.Button( style=ButtonStyle.grey if view.ref is False else ButtonStyle.blurple, label="Yes", disabled=True, )) emptyview.add_item( ui.Button( style=ButtonStyle.grey if view.ref is True else ButtonStyle.blurple, label="No", disabled=True, )) await message.edit(view=emptyview) emptyview.stop() return view.ref
class CreateHelpChannelButton(ui.View): def __init__(self, bot: HelpCenterBot) -> None: """The view below the message in #ask-for-help, to create thread channels.""" super().__init__(timeout=None) self.bot = bot @ui.button(label="Nouveau / New", custom_id='create_help_channel', emoji="➕", style=discord.ButtonStyle.blurple) async def create_help_channel(self, __: ui.Button, inter: discord.Interaction) -> None: member = inter.guild.get_member( inter.user.id) or await inter.guild.fetch_member(inter.user.id) await inter.channel.set_permissions(member, send_messages=True) await self.bot.set_actual_language( inter.user) # define bot langage for the next text content = _( "**Give a title to your request.** \n" "*Do not send your whole problem, just a very concise description with maximum context. (Language, OS, library used...) *\n\n" "> Example: \"[Python - Discord.py] Is it possible to kick any one of a server with its id?\"" ) await inter.response.send_message(content, ephemeral=True) async def wait_for_title() -> Optional[discord.Message]: try: return await self.bot.wait_for( "message", check=lambda msg: msg.channel.id == inter.channel_id and msg.author.id == inter.user.id, timeout=300) except asyncio.TimeoutError: await inter.channel.set_permissions(member, overwrite=None) while (message := await wait_for_title()) and len(message.content) > 200: await self.bot.set_actual_language( inter.user) # define bot langage for the next text await inter.edit_original_message(content=_( "{0}\n\n" "⚠ **This is not your full message of the request, the title must be short (less than 100 characters)**.\n\n" "Your current request:```\n{1}\n```").format( content, message.content)) await message.delete() if not message: return # Timeout reached if message.type is discord.MessageType.thread_created: # The user can created a thread by him-self embed = discord.Embed() thread = inter.guild.get_channel(message.id) else: await message.delete() thread = await inter.channel.create_thread( name=f"{message.content[:100]}", auto_archive_duration=1440, type=discord.ChannelType.public_thread, reason="HelpCenter help-thread system.") await inter.channel.set_permissions(member, overwrite=None) view = ui.View() view.stop() view.add_item( ui.Button(label=_("Archive"), custom_id=f"archive_help_thread_{inter.user.id}")) view.add_item( ui.Button(label=_("Delete"), custom_id=f"delete_help_thread_{inter.user.id}")) await self.bot.set_actual_language( inter.user ) # redefine the language, if he was long to write his answer embed = discord.Embed(color=discord.Color.yellow(), title=message.content) embed.add_field( name=_("Ask your question."), value= _("Be as clear as possible, remember to send code if there is, or screens highlighting the problem! \n\n" "**\⚠️ Do not share passwords, bot tokens... if anyone in demand, warn a staff member** \⚠️" ), inline=False) embed.set_footer(text=_("⬇ click to archive the thread")) await thread.add_user(inter.user) await self.bot.set_actual_language(inter.user) embed.add_field( name=_('How to ask a question ?'), value= _(":ballot_box_with_check: have you searched on Google ? [Search](https://google.com/search?q={0})\n" ":ballot_box_with_check: have you read the doc ?\n" ":ballot_box_with_check: don't ask to ask, just ask. https://dontasktoask.com/\n" ":ballot_box_with_check: asking about your attempted solution rather than your actual problem. https://xyproblem.info/" ).format( parse.quote_plus(" ".join( word[:50] for word in message.content.split(' ')[:32]))), inline=False) await thread.send(embed=embed, view=view)