Spraxium logoSpraxium

Primeiros Passos

Introdução orientada por arquitetura para criar um bot com Spraxium do zero até um grafo de módulos em execução. Cobre pré-requisitos, geração do projeto, estrutura de pastas, fluxo de bootstrap e as regras centrais da arquitetura.

O que é o Spraxium

Spraxium é um framework TypeScript construído sobre o Discord.js que entrega a camada de arquitetura que o Discord.js propositalmente não tenta resolver sozinho. O Discord.js cuida da comunicação de baixo nível com o gateway, incluindo WebSocket, REST, eventos crus e modelos de dados. O Spraxium entra a partir daí e organiza a aplicação com módulos, injeção de dependência, pipeline de guards, lifecycle hooks e uma sequência de boot determinística, para que o bot sempre suba do mesmo jeito.

Cada funcionalidade vive no próprio módulo, com fronteiras claras e dependências explícitas. O container de DI resolve e injeta tudo automaticamente: você declara o que cada classe precisa, e o framework faz a amarração.

Pré-requisitos

Antes de começar, você precisa de três coisas:

  • Node.js 20 ou superior. O Spraxium acompanha as versões LTS atuais. Você pode conferir a versão instalada rodando node -v no terminal, e tanto a LTS 20 quanto a LTS 22 são suportadas.
  • Um token de bot do Discord. Crie uma aplicação no Discord Developer Portal, adicione um Bot e copie o token. É ele que permite ao seu bot se autenticar no gateway do Discord.
  • Um projeto TypeScript. O scaffold da CLI já monta o tsconfig.json com experimentalDecorators e emitDecoratorMetadata ativados, que são obrigatórios para o sistema de DI baseado em decorators usado pelo Spraxium.

Nunca exponha o token do bot

O token funciona como a senha do bot. Quem tiver acesso a ele consegue assumir o controle total da aplicação. Sempre deixe esse valor no .env e garanta que o .env esteja listado no .gitignore. O scaffold do Spraxium já adiciona essa proteção automaticamente.

Use um servidor de teste

Durante o desenvolvimento, a melhor prática é apontar o bot para um servidor privado seu. Assim você consegue registrar slash commands instantaneamente no escopo da guild e testar interações sem afetar usuários reais. Também vale a pena manter esse ambiente separado de qualquer servidor de produção para não misturar comandos, permissões ou rate limits.

Gerando o projeto

Use o comando de criação para gerar um projeto com a estrutura de pastas correta, configuração TypeScript pronta e dependências já instaladas. A CLI pergunta qual template você quer usar, qual package manager prefere e se deve inicializar um repositório Git.

npx @spraxium/cli@latest new my-bot

Estrutura inicial

Cada arquivo da base tem uma função arquitetural específica:

Estrutura mínima
main.ts
app.env.ts
app.module.ts
default.module.ts
spraxium.config.ts
.env
  • main.ts: faz apenas o bootstrap; valida ambiente e sobe o framework
  • app.env.ts: descreve o schema tipado das variáveis de ambiente antes da conexão com o Discord
  • app.module.ts: raiz de composição; importa módulos de feature e não concentra regra de negócio
  • modules/: uma pasta por domínio de funcionalidade

Bootstrap

O main.ts é o único arquivo que encosta diretamente na factory do framework. É ali que você valida variáveis de ambiente, cria a aplicação, carrega o grafo de módulos e abre a conexão com o Discord.

snippet.ts
import { IntentPreset, SpraxiumFactory } from '@spraxium/core';
import { EnvValidator } from '@spraxium/env';
import { AppEnv } from './app.env';
import { AppModule } from './app.module';

async function main(): Promise<void> {
  const env = EnvValidator.validate(AppEnv);
  const app = await SpraxiumFactory.create({ token: env.token });

  app.useModule(AppModule);
  app.intents(IntentPreset.Standard);

  await app.listen();
}

main();

EnvValidator.validate lê o .env e valida cada campo contra o AppEnv. Se algum valor estiver ausente ou inválido, a execução falha imediatamente, antes mesmo do Discord conectar. Já o app.listen() resolve o grafo de DI, instancia providers, registra listeners e só depois faz login no gateway.

Módulo raiz

O AppModule é a raiz de composição. Ele importa módulos de feature, mas não deve concentrar providers nem listeners de negócio. Sempre que um novo domínio surgir no bot, o caminho natural é criar um módulo próprio e importá-lo aqui.

src/app.module.ts
import { Module } from '@spraxium/common';
import { DefaultModule } from './modules/default/default.module';

@Module({
  imports: [DefaultModule],
})
export class AppModule {}

Regras centrais da arquitetura

Existem três regras que sustentam o funcionamento do framework:

  • Um módulo por domínio de funcionalidade. Cada parte do bot, seja moderação, comandos, eventos ou integrações externas, deve ter o próprio módulo. Dependências entre áreas passam por imports e exports explícitos, não por estado global compartilhado.
  • Injeção de dependência em tudo. Evite instanciar serviços manualmente com new. O ideal é declarar dependências no construtor e deixar o container resolver tudo. Isso reduz acoplamento, facilita teste com mocks e mantém o ciclo de vida sob controle do framework.
  • Validação antes da conexão com o Discord. O grafo inteiro é resolvido antes do login. Se houver configuração inválida ou dependência faltando, o erro aparece no boot, com contexto claro, em vez de surgir só quando alguém usa um comando em produção.