O que o módulo de schedule resolve
A maioria dos bots de Discord precisa executar tarefas com base em tempo. Limpar avisos expirados, sincronizar contagens de membros, publicar resumos diários e alternar mensagens de status são operações que acontecem independentemente da ação do usuário. O módulo de schedule oferece uma API orientada por decorators para definir esses jobs em segundo plano, para que você declare a lógica de tempo ao lado dos métodos do seu serviço em vez de gerenciar timers brutos.
O módulo oferece suporte a quatro tipos de job que cobrem padrões de agendamento diferentes. Jobs cron rodam em agendas baseadas em calendário usando expressões cron padrão. Intervals se repetem em intervalos fixos em milissegundos. Timeouts disparam uma vez após um atraso. Jobs after-online disparam uma vez depois que o bot se conecta totalmente ao Discord. Juntos, esses quatro tipos cobrem os cenários de agendamento mais comuns.
O módulo de schedule é um pacote separado (@spraxium/schedule) que se conecta ao framework por meio do sistema padrão de módulos. Ele analisa seus providers em busca de métodos decorados no boot, registra tudo em um registro central e gerencia o ciclo de vida automaticamente. Você não precisa iniciar nem parar timers manualmente.
Quando agendamento é a ferramenta certa
Use o módulo de schedule quando o trabalho deve acontecer por causa do tempo, e não por causa de uma ação do usuário ou de um evento do Discord. Jobs de limpeza, ciclos de atualização, lembretes, sincronizações periódicas e tarefas após a inicialização costumam se encaixar muito bem aqui.
Se uma tarefa só deve acontecer depois que o usuário pedir explicitamente, mantenha essa lógica em um command ou handler de interação em vez de forçá-la para dentro de um job agendado. Automação baseada em tempo e fluxos acionados pelo usuário ficam mais fáceis de manter quando permanecem separados.
Tipos de job em resumo
Cada tipo de job corresponde a um decorator que você aplica a um método dentro de um serviço injetável. O decorator informa ao scheduler quando e como executar aquele método. Os quatro decorators aceitam um objeto de opções para nomear, desabilitar e controlar o comportamento na inicialização.
| Decorator | Disparo | Repete | Caso de uso |
|---|---|---|---|
| @Cron | Expressão cron | Sim | Tarefas recorrentes baseadas em calendário |
| @Interval | Milissegundos fixos | Sim | Polling, heartbeats e sincronizações periódicas |
| @Timeout | Atraso em milissegundos | Não | Inicialização atrasada de execução única |
| @AfterOnline | Atraso após o bot ficar ready | Não | Tarefas de setup após a conexão |
Ciclo de vida em runtime
O módulo de schedule opera em duas fases que acompanham a sequência de boot do framework. Entender essas fases ajuda você a prever quando cada tipo de job começa a executar e por que @AfterOnline existe como um decorator separado, em vez de ser apenas uma variação de cron.
Fase de boot
Na inicialização da aplicação, o framework analisa todos os providers e registra cada método decorado com @Cron, @Interval ou @Timeout. Jobs com runOnInit ativado executam imediatamente nessa fase. Os timers de interval e timeout começam a contar a partir desse momento.
Fase ready
Depois que o cliente do Discord emite o evento ready, o framework registra todos os jobs @AfterOnline e inicia seus timers de atraso. Essa separação existe porque algumas tarefas precisam de uma conexão ativa com o Discord, como buscar dados de guild ou enviar mensagens de boas-vindas. Executá-las durante o boot falharia, porque o client ainda não está conectado.
Gerenciamento em runtime
Depois que todos os jobs são registrados, o ScheduleService oferece uma API pública para pausar, retomar, destruir e disparar jobs manualmente pelo nome. Você pode injetar ScheduleService em qualquer provider para controlar jobs de forma programática a partir de slash commands, prefix commands ou endpoints HTTP.
Setup mínimo
Para usar o módulo de schedule, instale o pacote @spraxium/schedule, crie um arquivo de configuração com defineSchedule e registre ScheduleModule na sua aplicação. O módulo é global por padrão, então você só precisa registrá-lo uma vez. Depois disso, qualquer provider em qualquer módulo pode usar os decorators de schedule.
import { defineSchedule } from '@spraxium/schedule';
export default defineSchedule({
timezone: 'America/Sao_Paulo',
});O módulo de schedule usa MemoryDriver por padrão, armazenando o estado dos jobs em memória. Em bots distribuídos que executam vários shards ou processos, troque para RedisScheduleDriver para evitar execuções duplicadas.
Orientação operacional
Jobs agendados devem ser escritos com idempotência em mente. Se um processo reiniciar ou um driver distribuído repetir a coordenação, um job bem projetado precisa ser seguro para executar duas vezes sem corromper o estado.
Também é uma boa prática dar nomes explícitos aos jobs importantes por meio das opções do decorator. Jobs nomeados são mais fáceis de inspecionar, pausar, retomar ou disparar manualmente depois pelo serviço de schedule.
Estrutura do projeto
Um bot típico com tarefas agendadas organiza esses jobs como providers de serviço dentro de feature modules. Cada serviço agrupa jobs relacionados, e o arquivo de configuração fica no diretório config do projeto ao lado das configurações de prefix e dos outros plugins.