Como Implementar Paginação em Bot do Discord com Componentes de Botão
🔍 WiseChecker

Como Implementar Paginação em Bot do Discord com Componentes de Botão

Mensagens de bots do Discord que exibem listas longas de itens, como membros do servidor, resultados de pesquisa ou rankings, tornam-se ilegíveis quando ultrapassam algumas linhas. A paginação divide esse conteúdo em páginas menores que os usuários podem navegar usando botões interativos. Os Componentes de Botão do Discord fornecem uma maneira nativa e limpa de adicionar botões de avançar, retroceder e número de página diretamente abaixo do seu embed ou mensagem. Este artigo explica como construir um sistema de paginação usando os Componentes de Botão do Discord em um bot Python com discord.py, cobrindo as importações necessárias, criação de botões e lógica de paginação.

Principais Pontos: Paginação com Botões no discord.py

  • discord.ui.View e discord.ui.Button: Classes principais para criar linhas de botões interativos em embeds ou mensagens.
  • Funções de callback personalizadas: Cada botão deve ter um callback que atualiza o conteúdo do embed e o índice da página.
  • Dados das páginas armazenados em uma lista: Organize seu conteúdo em uma lista de strings ou embeds, onde cada índice representa uma página.

ADVERTISEMENT

Entendendo os Componentes de Botão do Discord para Paginação

Os Componentes de Botão do Discord fazem parte do framework de Interação introduzido na API v8. Diferente da antiga paginação baseada em reações, os botões são persistentes, não exigem que o bot aguarde reações e podem ser desabilitados quando o usuário chega na primeira ou última página. A classe discord.ui.View é usada para conter um ou mais botões. Cada botão é uma instância de discord.ui.Button com um parâmetro style que controla sua cor: discord.ButtonStyle.primary para azul, discord.ButtonStyle.secondary para cinza, discord.ButtonStyle.success para verde, discord.ButtonStyle.danger para vermelho e discord.ButtonStyle.link para botões de URL.

Para implementar a paginação, você precisa de uma forma de rastrear qual página o usuário está visualizando. Isso geralmente é feito armazenando o índice da página como um atributo da classe View. Quando um botão é clicado, o método callback atualiza o conteúdo do embed para mostrar os dados do novo índice de página. A linha de botões pode conter até cinco botões por linha, então um layout comum usa três botões: um botão “Anterior”, um botão de rótulo “Página X de Y” desabilitado e um botão “Próximo”. O botão de rótulo pode ser substituído por uma exibição de texto simples ou omitido se você preferir dois botões.

Antes de escrever o código, certifique-se de que seu bot tenha a intent message_content ativada se você planeja ler o conteúdo da mensagem, e o escopo application_commands se usar comandos de barra. O exemplo neste artigo usa um comando de barra para acionar a mensagem paginada, mas a mesma View pode ser anexada a qualquer mensagem enviada pelo bot.

Passos para Implementar Paginação em Bot do Discord com Botões

Os passos a seguir assumem que você tem um bot do Discord funcionando com discord.py versão 2.0 ou superior instalada. Se estiver usando uma versão mais antiga, atualize com pip install -U discord.py. O exemplo cria uma lista paginada de 20 itens, exibindo 5 itens por página, totalizando 4 páginas.

  1. Importe os módulos necessários
    Inicie seu script importando discord e as classes necessárias: import discord e from discord.ext import commands. Você também precisa de discord.ui.View, discord.ui.Button e discord.Embed.
  2. Defina uma classe View personalizada
    Crie uma classe que herda de discord.ui.View. Dentro do método __init__, aceite parâmetros para a lista de páginas e opcionalmente o ID do autor para restringir interações dos botões. Defina self.pages = pages, self.current_page = 0 e chame super().__init__(). Em seguida, adicione os botões usando self.add_item().
  3. Crie os callbacks dos botões
    Defina dois métodos assíncronos decorados com @discord.ui.button. O primeiro método lida com o botão “Anterior”. Ele verifica se self.current_page > 0, decrementa o índice da página e chama self.update_embed(interaction). O segundo método lida com o botão “Próximo”, incrementa o índice da página se self.current_page < len(self.pages) - 1 e chama o mesmo método de atualização.
  4. Escreva o método de atualização do embed
    Crie um método assíncrono chamado update_embed que recebe um parâmetro interaction. Dentro, construa um novo discord.Embed usando self.pages[self.current_page] como descrição. Opcionalmente, defina o rodapé para mostrar "Página X de Y". Em seguida, chame await interaction.response.edit_message(embed=new_embed, view=self) para atualizar a mensagem original.
  5. Desabilite os botões nos limites
    No método update_embed, após construir o embed, percorra self.children e desabilite o botão Anterior quando self.current_page == 0 e desabilite o botão Próximo quando self.current_page == len(self.pages) - 1. Isso impede que os usuários cliquem em botões que não têm efeito.
  6. Crie um comando de barra para acionar a paginação
    Defina um grupo de comandos de barra ou um comando simples que gere a lista de páginas. Por exemplo, uma lista de 20 strings: pages = [f"Item {i+1}" for i in range(20)]. Em seguida, divida a lista em grupos de 5: page_texts = ['\n'.join(pages[i:i+5]) for i in range(0, len(pages), 5)]. Envie a primeira página como um embed e passe a instância da View com todas as páginas.
  7. Restrinja as interações dos botões ao autor do comando
    Em cada callback do botão, verifique if interaction.user.id != self.author_id: return. Isso impede que outros usuários naveguem pelas páginas de uma mensagem que não iniciaram. Armazene self.author_id no método __init__ da View.
  8. Lide com casos extremos
    Se a lista de páginas estiver vazia, envie uma mensagem dizendo que não há dados disponíveis. Se houver apenas uma página, desabilite ambos os botões desde o início. Você também pode adicionar um timeout à View passando timeout=180 para o __init__ pai para parar de ouvir após 3 minutos.

ADVERTISEMENT

Erros Comuns e Limitações

Botões param de funcionar após o primeiro clique

Isso geralmente acontece porque a View não é passada de volta na chamada edit_message. Sempre inclua view=self no método edit_message. Se você esquecer, o Discord remove os componentes de botão da mensagem após a primeira interação.

Vários usuários podem clicar nos mesmos botões

Por padrão, qualquer usuário pode clicar nos botões de uma mensagem. Para restringir a interação ao autor original do comando, armazene o ID do usuário autor na View e verifique-o em cada callback. Se a verificação falhar, ignore a interação ou responda com uma mensagem efêmera dizendo "Você não pode controlar esta paginação."

O conteúdo da página não é atualizado visualmente

Certifique-se de que você está editando a mensagem original, não enviando uma nova. Use interaction.response.edit_message() ou interaction.edit_original_response(). Se você usar interaction.response.send_message(), uma nova mensagem aparecerá em vez de atualizar a atual.

Botões aparecem, mas não são clicáveis

Isso pode ocorrer se o bot não tiver a permissão send_messages no canal ou se a mensagem foi enviada antes do bot estar pronto. Verifique também se o parâmetro timeout da View não está definido como 0, o que desabilitaria imediatamente todos os botões.

Estilos de Botão de Paginação: Padrão vs Personalizado

Item Estilo Padrão do Botão Estilo Personalizado do Botão
Aparência do botão Usa discord.ButtonStyle.primary (azul) para ambos Anterior e Próximo Usa discord.ButtonStyle.secondary (cinza) ou discord.ButtonStyle.success (verde) para Próximo
Texto do rótulo Setas simples como ◀ e ▶ ou palavras "Anterior" e "Próximo" Emoji personalizado ou caracteres Unicode, por exemplo, ⬅️ e ➡️
Estado desabilitado Botões ficam acinzentados quando nas páginas de limite Mesmo comportamento, mas você também pode alterar o rótulo para "Início" ou "Fim" quando desabilitado
Complexidade de implementação Baixa — apenas dois botões com callbacks básicos Média — requer verificar o índice da página para atualizar os rótulos dinamicamente

O estilo do botão não afeta a funcionalidade. Escolha um estilo que combine com o tema do seu bot. Para acessibilidade, certifique-se de que os rótulos dos botões indiquem claramente a direção, como "Anterior" e "Próximo", em vez de símbolos ambíguos.

Agora você tem um sistema de paginação funcional usando Componentes de Botão do Discord. Comece testando com um conjunto de dados pequeno para confirmar que os botões atualizam o embed corretamente. Em seguida, tente adicionar um terceiro botão que pula para uma página específica digitando um número. Para uso avançado, armazene a View em um dicionário persistente indexado pelo ID da mensagem para que a paginação sobreviva a reinicializações do bot.

ADVERTISEMENT