Começando com o Core
Entenda o papel do runtime, a estrutura do Template Bot e o caminho percorrido até o primeiro comando responder.
O modelo mental#
O Core não substitui o Discord.js. Ele organiza o ciclo de vida ao redor dele.
Você declara
Cada arquivo registra um comando, evento, task ou interação no Client.
O Core carrega
O auto-loader percorre settings.baseDir, importa os módulos e valida os registros.
O runtime executa
Cooldown, fila, contexto de guild e respostas são preparados antes do seu execute.
Estrutura do Template Bot#
A estrutura já separa código carregado automaticamente de helpers importados explicitamente.
src/├─ Bot.ts # ponto de entrada├─ Discord/│ ├─ Commands/ # slash, prefixo e menus de contexto│ ├─ Events/ # eventos do Discord.js│ ├─ Interactions/ # modais, callbacks, prompts e paginações│ └─ Tasks/ # rotinas periódicas├─ Shared/│ ├─ Settings/Client.ts # LibsClient, token e intents│ ├─ Settings/Database.ts # plugin opcional de banco│ ├─ Emojis/ # emojis do aplicativo│ └─ Translate/ # idiomas└─ Utils/ # regras e helpers importados por módulos| Pasta | Carregamento | Use para |
|---|---|---|
Discord/Commands | Automático | Comandos slash, prefixados e menus de contexto |
Discord/Events | Automático | Eventos emitidos pelo Discord.js |
Discord/Interactions | Automático | Modais, prompts, paginações e callbacks registrados |
Discord/Tasks | Automático | Rotinas globais ou executadas por servidor |
Shared e Utils | Explícito | Configuração, serviços e regras reutilizáveis |
Configure o Client#
O LibsClient estende o cliente do Discord.js e adiciona os registradores do ecossistema.
import { GatewayIntentBits, LibsClient, type AppConfig} from '@ninenity/core'const Client = new LibsClient<AppConfig>({ intents: [ GatewayIntentBits.Guilds, GatewayIntentBits.GuildMessages, GatewayIntentBits.MessageContent, GatewayIntentBits.GuildMembers ], token: process.env.BOT_TOKEN || process.env.DISCORD_TOKEN, config: {}})export default Client| Intent | Necessário quando |
|---|---|
Guilds | Quase sempre: slash commands, canais, cargos e configuração por servidor |
GuildMessages | O bot observa mensagens ou usa comandos prefixados |
MessageContent | O conteúdo textual das mensagens precisa ser lido |
GuildMembers | Entradas, saídas, cargos ou dados completos de membros são usados |
Inicialize o runtime#
Ninenity.init() prepara plugins e auto-loader antes de Client.login() abrir a conexão com o Discord.
import 'dotenv/config'import { Ninenity } from '@ninenity/core'import Client from './Shared/Settings/Client'import { databasePlugin } from './Shared/Settings/Database'Ninenity.init({ bots: [Client], plugins: databasePlugin ? { database: databasePlugin } : undefined, settings: { baseDir: __dirname }})Client.login()- 1Variáveis são carregadas
O import de
dotenv/configdisponibiliza o token e integrações antes de criar o Client. - 2O runtime recebe os bots
botsaceita mais de um Client, mas cada bot mantém seus próprios registradores e timers. - 3Módulos são encontrados
baseDiraponta parasrcem desenvolvimento e paradistapós o build. - 4O login começa
Depois dos registros,
Client.login()conecta e conclui as etapas de bootstrap.
Crie o primeiro módulo#
O arquivo só precisa importar o Client compartilhado e fazer seu registro no escopo do módulo.
import { SlashCommandBuilder, type SlashInputCommandInteraction} from '@ninenity/core'import Client from '../../Shared/Settings/Client'Client.slash({ data: new SlashCommandBuilder() .setName('ping') .setDescription('Mostra a latência atual.'), cooldown: '3s', execute: async (interaction: SlashInputCommandInteraction) => { await interaction.reply('Pong!') }})Você não importa Ping.ts em Bot.ts. O auto-loader encontra o arquivo, executa o módulo uma vez e o Client.slash() guarda a definição para deploy e execução.
Variáveis de ambiente#
Comece com o mínimo e adicione integrações somente quando forem usadas.
BOT_TOKEN=seu_token_do_discord# Opcionais: integração com API e HUBAPI_KEY=API_SECRET=# Opcional: banco de dadosDATABASE_URL=- Nunca envie
.envpara o Git; mantenha apenas um.env.examplesem secrets. - Use um token de bot, não o client secret da aplicação.
- A ausência de
API_KEYeAPI_SECRETdesativa a hidratação remota, mas não impede o bot de conectar ao Discord. - Mantenha
srcedistcom a mesma árvore para o auto-loader funcionar após o build.