Como Criar um Sistema de Lembretes para Bot do Discord com Banco de Dados Persistente
🔍 WiseChecker

Como Criar um Sistema de Lembretes para Bot do Discord com Banco de Dados Persistente

Você quer um bot do Discord que lembre de compromissos mesmo após reiniciar. Um bot baseado em memória perde todos os lembretes agendados quando o processo para. Este artigo explica como construir um sistema de lembretes usando um banco de dados persistente para que os lembretes sobrevivam a falhas e reinicializações. Você aprenderá a armazenar dados de lembretes em SQLite, agendar tarefas com um loop e lidar com comandos de usuário.

Principais Conclusões: Construindo um Bot de Lembretes Persistente para Discord

  • Banco de dados SQLite para armazenamento: Armazena horário do lembrete, ID do canal, ID do usuário e texto da mensagem para que os dados persistam entre reinicializações.
  • Loop asyncio com agendamento de tarefas: Verifica o banco de dados a cada poucos segundos e envia lembretes pendentes sem bloquear o bot.
  • Manipulação de comandos com discord.py: Usa os comandos !lembrete e !listarlembretes para criar e visualizar lembretes.

ADVERTISEMENT

Como Funciona um Bot de Lembretes Persistente

Um bot de lembretes persistente armazena cada lembrete em um arquivo de banco de dados em vez de apenas na memória. Quando o bot inicia, ele carrega todos os lembretes pendentes do banco de dados e os reagenda. O bot então executa um loop em segundo plano que verifica lembretes pendentes a cada poucos segundos. Quando um lembrete está no horário, o bot envia uma mensagem para o canal especificado e exclui a linha do banco de dados.

Os componentes principais são:

Esquema do Banco de Dados

Você precisa de uma tabela com colunas para um ID único, o horário alvo como timestamp Unix, o ID do canal, o ID do usuário e a mensagem do lembrete. Usar SQLite mantém a configuração simples porque o Python inclui o módulo sqlite3 em sua biblioteca padrão.

Loop de Tarefa em Segundo Plano

Bots do Discord construídos com discord.py rodam em um loop de eventos asyncio. Você cria uma tarefa em segundo plano que executa a cada 10 segundos. A tarefa consulta o banco de dados por linhas onde o timestamp é menor que o horário atual. Para cada lembrete pendente, o bot envia a mensagem e exclui a linha.

Manipuladores de Comando

Você precisa de pelo menos dois comandos. O comando !lembrete analisa uma string de tempo e uma mensagem, insere uma nova linha no banco de dados e confirma o lembrete. O comando !listarlembretes busca todos os lembretes pendentes do usuário e os exibe.

Passos para Construir o Bot de Lembretes

  1. Configurar o projeto e instalar discord.py
    Crie uma nova pasta e um ambiente virtual. Execute pip install discord.py para instalar a biblioteca. Nenhuma biblioteca de banco de dados extra é necessária, pois sqlite3 já vem com Python.
  2. Criar o módulo auxiliar do banco de dados
    Escreva um arquivo chamado database.py. Dentro, defina uma função init_db() que cria a tabela de lembretes se ela não existir. A tabela deve ter colunas: id INTEGER PRIMARY KEY AUTOINCREMENT, timestamp INTEGER, channel_id INTEGER, user_id INTEGER e message TEXT.
  3. Escrever as funções de inserir e excluir
    No mesmo módulo, escreva add_reminder(timestamp, channel_id, user_id, message) e remove_reminder(reminder_id). Use consultas parametrizadas para prevenir injeção de SQL.
  4. Escrever a função de consulta para lembretes pendentes
    Escreva get_due_reminders() que retorna todas as linhas onde timestamp <= current_time. Também escreva get_user_reminders(user_id) para o comando de listar.
  5. Criar o script principal do bot
    Em bot.py, importe discord, commands de discord.ext, asyncio e seu módulo de banco de dados. Inicialize o bot com commands.Bot(command_prefix='!').
  6. Implementar o verificador de lembretes em segundo plano
    Use o decorador @tasks.loop(seconds=10) de discord.ext.tasks. Defina async def check_reminders() que chama get_due_reminders(). Para cada linha, envie a mensagem para o canal usando bot.get_channel(row[2]), depois chame remove_reminder(row[0]).
  7. Adicionar o comando !lembrete
    Use @bot.command() e analise o argumento de tempo. Aceite formatos como 30s, 5m, 1h. Converta para um timestamp Unix adicionando o atraso a time.time(). Insira o lembrete no banco de dados e responda com uma confirmação.
  8. Adicionar o comando !listarlembretes
    Consulte get_user_reminders(ctx.author.id). Formate os resultados em um embed ou texto simples. Se não houver lembretes, responda com uma mensagem simples.
  9. Iniciar o bot
    No evento on_ready, chame init_db() e depois check_reminders.start(). Execute o bot com bot.run('SEU_TOKEN').
  10. Testar o bot
    Convide o bot para um servidor de teste. Digite !lembrete 10s Mensagem de teste e aguarde 10 segundos. O bot deve enviar o lembrete no mesmo canal. Reinicie o bot e verifique se os lembretes pendentes ainda são disparados.

ADVERTISEMENT

Problemas Comuns e Casos Especiais

Bot Envia Lembretes Múltiplas Vezes

Se o loop em segundo plano for mais rápido que a operação de exclusão no banco de dados, o mesmo lembrete pode ser buscado duas vezes. Use um lock ou marque o lembrete como enviado com uma coluna booleana adicional. Alternativamente, exclua a linha dentro da mesma transação de banco de dados que a lê.

Erros de Análise de Tempo

Os usuários podem digitar !lembrete 5min em vez de 5m. Escreva um analisador robusto que remova espaços e aceite múltiplos formatos. Use regex para extrair o valor numérico e o caractere da unidade, depois converta adequadamente.

Bot Perde Conexão Durante um Lembrete

Se o bot desconectar enquanto envia um lembrete, a linha permanece no banco de dados. Após reconexão, o loop em segundo plano tentará novamente o lembrete. Isso é aceitável para a maioria dos casos. Para evitar envios duplicados, adicione uma coluna status com valores pending e sent. Atualize o status antes de enviar e exclua após confirmação.

Grande Número de Lembretes

SQLite lida com milhares de linhas sem problemas. Se você espera milhões, considere migrar para PostgreSQL. Para um servidor Discord típico, SQLite é suficiente.

SQLite vs Armazenamento em Memória para Lembretes

Item Banco de Dados SQLite Dicionário em Memória
Persistência de dados Sobrevive a reinicializações e falhas do bot Perdido ao reiniciar ou falhar
Complexidade de configuração Arquivo único, sem serviço externo Nenhuma configuração necessária
Capacidades de consulta Consultas SQL para filtragem e ordenação Iteração manual sobre dicionário Python
Escalabilidade Bom para milhares de lembretes Limitado pela RAM e tempo de vida do processo
Acesso concorrente Lida com múltiplas leituras com segurança Requer gerenciamento manual de locks

SQLite é a melhor escolha para qualquer bot que precise lembrar de lembretes entre reinicializações. Armazenamento em memória é aceitável apenas para testes temporários.

Agora você pode construir um bot do Discord que armazena lembretes em um banco de dados SQLite persistente. O bot usa um loop de tarefa em segundo plano para verificar lembretes pendentes a cada 10 segundos e os envia de forma confiável. Como próximo passo, adicione um comando !cancelarlembrete que exclui um lembrete específico pelo ID. Como melhoria avançada, implemente uma coluna timezone para que os usuários possam definir lembretes em seu fuso horário local.

ADVERTISEMENT