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
!lembretee!listarlembretespara criar e visualizar lembretes.
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
- Configurar o projeto e instalar discord.py
Crie uma nova pasta e um ambiente virtual. Executepip install discord.pypara instalar a biblioteca. Nenhuma biblioteca de banco de dados extra é necessária, pois sqlite3 já vem com Python. - Criar o módulo auxiliar do banco de dados
Escreva um arquivo chamadodatabase.py. Dentro, defina uma funçãoinit_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 INTEGERemessage TEXT. - Escrever as funções de inserir e excluir
No mesmo módulo, escrevaadd_reminder(timestamp, channel_id, user_id, message)eremove_reminder(reminder_id). Use consultas parametrizadas para prevenir injeção de SQL. - Escrever a função de consulta para lembretes pendentes
Escrevaget_due_reminders()que retorna todas as linhas ondetimestamp <= current_time. Também escrevaget_user_reminders(user_id)para o comando de listar. - Criar o script principal do bot
Embot.py, importe discord, commands de discord.ext, asyncio e seu módulo de banco de dados. Inicialize o bot comcommands.Bot(command_prefix='!'). - Implementar o verificador de lembretes em segundo plano
Use o decorador@tasks.loop(seconds=10)de discord.ext.tasks. Definaasync def check_reminders()que chamaget_due_reminders(). Para cada linha, envie a mensagem para o canal usandobot.get_channel(row[2]), depois chameremove_reminder(row[0]). - Adicionar o comando !lembrete
Use@bot.command()e analise o argumento de tempo. Aceite formatos como30s,5m,1h. Converta para um timestamp Unix adicionando o atraso atime.time(). Insira o lembrete no banco de dados e responda com uma confirmação. - Adicionar o comando !listarlembretes
Consulteget_user_reminders(ctx.author.id). Formate os resultados em um embed ou texto simples. Se não houver lembretes, responda com uma mensagem simples. - Iniciar o bot
No eventoon_ready, chameinit_db()e depoischeck_reminders.start(). Execute o bot combot.run('SEU_TOKEN'). - Testar o bot
Convide o bot para um servidor de teste. Digite!lembrete 10s Mensagem de testee 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.
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.