-
I made a simple embed pagination class a while ago, which worked flawlessly while I was using it. But recently one of the bots I made, when I ran the help command using this class- (which was working previously mind you), now no longer works. The pagination class is here as follows: import discord
from typing import List
class EmbedPageView(discord.ui.View):
def __init__(self, pages: List[discord.Embed], timeout=None, nodelete=False):
super().__init__(timeout=timeout)
self.pages = pages
self.current_page = 0
self.page_count = len(pages)
self.page_counter.label = f"1/{self.page_count}"
self.update_buttons()
if nodelete:
self.remove_item(self.close)
async def show_page(self, page_num, interaction):
self.current_page = page_num
embed = self.pages[page_num]
self.page_counter.label = f"{page_num + 1}/{self.page_count}"
self.update_buttons()
await interaction.response.edit_message(embed=embed, view=self)
def update_buttons(self):
self.to_start.disabled = self.previous_page.disabled = self.current_page == 0
self.next_page.disabled = self.to_end.disabled = self.current_page == self.page_count - 1
self.page_counter.disabled = self.page_count == 1
@discord.ui.button(emoji="⏪", style=discord.ButtonStyle.primary)
async def to_start(self, interaction, button):
await self.show_page(0, interaction)
@discord.ui.button(emoji="◀️", style=discord.ButtonStyle.primary)
async def previous_page(self, interaction, button):
if self.current_page > 0:
await self.show_page(self.current_page - 1, interaction)
@discord.ui.button(label="Placeholder", style=discord.ButtonStyle.secondary)
async def page_counter(self, interaction, button):
modal = GotoPageModal(interaction.message, self)
modal.text_input.placeholder = f"Input a number from 1 - {self.page_count}"
await interaction.response.send_modal(modal)
@discord.ui.button(emoji="▶️", style=discord.ButtonStyle.primary)
async def next_page(self, interaction, button):
if self.current_page < self.page_count - 1:
await self.show_page(self.current_page + 1, interaction)
@discord.ui.button(emoji="⏩", style=discord.ButtonStyle.primary)
async def to_end(self, interaction, button):
await self.show_page(self.page_count - 1, interaction)
@discord.ui.button(label="Close", style=discord.ButtonStyle.red, row=2)
async def close(self, interaction, button):
await interaction.response.defer()
self.stop()
await interaction.message.delete()
class GotoPageModal(discord.ui.Modal):
text_input = discord.ui.TextInput(label="Page Number", style=discord.TextStyle.short)
def __init__(self, message: discord.Message, view: EmbedPageView):
super().__init__(timeout=None, title="Go to Page")
self.message = message
self.view = view
async def on_submit(self, interaction: discord.Interaction):
page_num = int(self.text_input.value) - 1
if 0 <= page_num < self.view.page_count:
await self.view.show_page(page_num, interaction)
else:
valid_range = f"Valid page range: 1-{self.view.page_count}"
await interaction.response.send_message(f"Invalid page number. {valid_range}", ephemeral=True) Previously, I could supply it a list of embeds, and pressing the buttons would edit the message to change which embed is shown. It worked quite well. Now however, when you press a button it gives you a failed interaction error Output is quite generic, but I'll supply it anyways. Nov 21 14:38:33 raspberrypi python[9356]: [2024-11-21 14:38:33] [ERROR ] discord.ui.view: Ignoring exception in view <EmbedPageView timeout=900.0 children=5> f>
Nov 21 14:38:33 raspberrypi python[9356]: Traceback (most recent call last):
Nov 21 14:38:33 raspberrypi python[9356]: File "/home/---/vpy/lib/python3.11/site-packages/discord/ui/view.py", line 430, in _scheduled_task
Nov 21 14:38:33 raspberrypi python[9356]: await item.callback(interaction)
Nov 21 14:38:33 raspberrypi python[9356]: File "/home/---/Bot/Test/Classes/Views/EmbedPages.py", line 55, in next_page
Nov 21 14:38:33 raspberrypi python[9356]: await self.show_page(self.current_page + 1, interaction)
Nov 21 14:38:33 raspberrypi python[9356]: File "/home/---/Bot/Test/Classes/Views/EmbedPages.py", line 25, in show_page
Nov 21 14:38:33 raspberrypi python[9356]: await interaction.response.edit_message(embed=embed, view=self)
Nov 21 14:38:33 raspberrypi python[9356]: File "/home/---/vpy/lib/python3.11/site-packages/discord/interactions.py", line 990, in edit_message
Nov 21 14:38:33 raspberrypi python[9356]: await adapter.create_interaction_response(
Nov 21 14:38:33 raspberrypi python[9356]: File "/home/---/vpy/lib/python3.11/site-packages/discord/webhook/async_.py", line 221, in request
Nov 21 14:38:33 raspberrypi python[9356]: raise NotFound(response, data)
Nov 21 14:38:33 raspberrypi python[9356]: discord.errors.NotFound: 404 Not Found (error code: 10062): Unknown interaction I can add defer statements before those interactions, which does get rid of the 404 error, however it just results in the button doing nothing. Which was not a problem previously. To add further context, here's a use case of the class in the form of a help command. import discord
from discord import app_commands
from discord.ext import commands
from collections import OrderedDict
from ...Views.EmbedPages import EmbedPageView
class HelpCog(commands.Cog, name="Help"):
def __init__(self, bot):
self.bot = bot
@commands.hybrid_command(name="help", description="Displays this message")
async def help(self, ctx: commands.Context):
categories = await self.get_command_categories(ctx)
embeds = []
for category, commands_list in categories.items():
commands_chunks = [commands_list[i:i + 7] for i in range(0, len(commands_list), 7)]
for i, commands_chunk in enumerate(commands_chunks):
embed = discord.Embed(
title=f"Command Category - `{category}" + (f" ({i + 1})" if i > 0 else "") + "`",
description="Here are the available commands:\n\n", color=discord.Color.blue())
for command in commands_chunk:
if command.hidden:
continue
embed.description += f"> `{command.qualified_name}` - {command.description}\n\n"
embeds.append(embed)
view = EmbedPageView(embeds, nodelete=True)
view.message = await ctx.reply(embed=embeds[0], view=view, allowed_mentions=discord.AllowedMentions.none())
async def get_command_categories(self, ctx):
commands_list = sorted(self.bot.commands, key=lambda c: (c.cog_name or "", c.name))
categories = OrderedDict()
for command in commands_list:
cog_name = command.cog_name or "No Category"
if cog_name == "Help":
continue # Exclude help, because there's only one command, and it's self-explanatory
if isinstance(command, commands.Group):
subcommands = sorted(command.commands, key=lambda c: c.name) # Sort subcommands alphabetically
filtered_subcommands = []
for subcommand in subcommands:
try:
await subcommand.can_run(ctx)
filtered_subcommands.append(subcommand)
except commands.CheckFailure:
pass
categories.setdefault(cog_name, []).extend(filtered_subcommands)
else:
try:
await command.can_run(ctx)
categories.setdefault(cog_name, []).append(command)
except commands.CheckFailure:
pass
categories = OrderedDict(sorted(categories.items(), key=lambda x: x[0]))
return categories
async def setup(bot):
await bot.add_cog(HelpCog(bot)) So the question is - has anything changed on Discord's or the libraries end, and do I have to update things? Or am I simply going insane? Haha. Help is appreciated. |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment 1 reply
-
This is Discord bug and will be fixed eventually. |
Beta Was this translation helpful? Give feedback.
This is Discord bug and will be fixed eventually.