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.
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.
- Importe os módulos necessários
Inicie seu script importando discord e as classes necessárias:import discordefrom discord.ext import commands. Você também precisa dediscord.ui.View,discord.ui.Buttonediscord.Embed. - Defina uma classe View personalizada
Crie uma classe que herda dediscord.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. Definaself.pages = pages,self.current_page = 0e chamesuper().__init__(). Em seguida, adicione os botões usandoself.add_item(). - 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 seself.current_page > 0, decrementa o índice da página e chamaself.update_embed(interaction). O segundo método lida com o botão “Próximo”, incrementa o índice da página seself.current_page < len(self.pages) - 1e chama o mesmo método de atualização. - Escreva o método de atualização do embed
Crie um método assíncrono chamadoupdate_embedque recebe um parâmetrointeraction. Dentro, construa um novodiscord.Embedusandoself.pages[self.current_page]como descrição. Opcionalmente, defina o rodapé para mostrar "Página X de Y". Em seguida, chameawait interaction.response.edit_message(embed=new_embed, view=self)para atualizar a mensagem original. - Desabilite os botões nos limites
No métodoupdate_embed, após construir o embed, percorraself.childrene desabilite o botão Anterior quandoself.current_page == 0e desabilite o botão Próximo quandoself.current_page == len(self.pages) - 1. Isso impede que os usuários cliquem em botões que não têm efeito. - 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. - Restrinja as interações dos botões ao autor do comando
Em cada callback do botão, verifiqueif interaction.user.id != self.author_id: return. Isso impede que outros usuários naveguem pelas páginas de uma mensagem que não iniciaram. Armazeneself.author_idno método__init__da View. - 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 passandotimeout=180para o__init__pai para parar de ouvir após 3 minutos.
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.