Multi-Bot Server

Execute múltiplos bots Discord em um único servidor HTTP

Por que usar?

  • Uma porta - Mais fácil de configurar ngrok/proxy
  • Menos recursos - Um único processo Node.js
  • API limpa - Adicione e remova bots dinamicamente

Instalação

bash
npm install @discord-flow/multibots

Como Funciona

O Discord envia o application_id em toda interação. O servidor identifica automaticamente qual bot deve processar a requisição.

Exemplo Básico

typescript
1import { FlowRegistry, FlowEngine, MemoryStore } from 'discord-flow';
2import { createMultiBotServer } from '@discord-flow/multibots';
3
4// Bot 1
5const registry1 = new FlowRegistry();
6const engine1 = new FlowEngine(registry1, new MemoryStore());
7
8registry1.define('bot1', (flow) => {
9 flow.start('idle');
10 flow.state('idle')
11 .on.command({ name: 'ping1', description: 'Ping Bot 1' }, () => ({
12 response: { content: 'Pong from Bot 1!' }
13 }));
14});
15
16// Bot 2
17const registry2 = new FlowRegistry();
18const engine2 = new FlowEngine(registry2, new MemoryStore());
19
20registry2.define('bot2', (flow) => {
21 flow.start('idle');
22 flow.state('idle')
23 .on.command({ name: 'ping2', description: 'Ping Bot 2' }, () => ({
24 response: { content: 'Pong from Bot 2!' }
25 }));
26});
27
28// Servidor único para ambos os bots
29createMultiBotServer({
30 port: 3000,
31 bots: [
32 {
33 applicationId: process.env.BOT1_APP_ID,
34 publicKey: process.env.BOT1_PUBLIC_KEY,
35 token: process.env.BOT1_TOKEN,
36 engine: engine1
37 },
38 {
39 applicationId: process.env.BOT2_APP_ID,
40 publicKey: process.env.BOT2_PUBLIC_KEY,
41 token: process.env.BOT2_TOKEN,
42 engine: engine2
43 }
44 ]
45}).start();

Configuração Discord

Ambos os bots devem apontar para o mesmo endpoint:

bash
1# No Discord Developer Portal, configure:
2# Bot 1 → Interactions Endpoint URL: https://seu-dominio.com/interactions
3# Bot 2 → Interactions Endpoint URL: https://seu-dominio.com/interactions

API

createMultiBotServer(options)

Cria o servidor multi-bot.

typescript
1interface MultiBotServerOptions {
2 port?: number; // Porta(padrão: 3000)
3 bots: BotConfig[]; // Lista de bots
4 autoRegisterCommands?: boolean; // Auto-registrar comandos(padrão: true)
5}
6
7interface BotConfig {
8 applicationId: string; // ID da aplicação Discord
9 publicKey: string; // Public Key para verificação
10 token: string; // Token do bot
11 engine: FlowEngine; // Engine com os flows do bot
12 guildId?: string; // Guild ID para comandos de teste
13}

Métodos do Servidor

typescript
1const server = createMultiBotServer({ ... });
2
3// Iniciar o servidor
4await server.start();
5
6// Adicionar bot dinamicamente(registra comandos automaticamente!)
7const bot = await server.addBot({
8 publicKey: '...',
9 token: '...',
10 engine: newEngine,
11 guildId: '123456789' // opcional
12});
13console.log(`Bot adicionado: ${bot.applicationId}`);
14
15// Remover bot
16server.removeBot('APP_ID_TO_REMOVE');
17
18// Listar bots registrados
19const bots = server.getBots();

Adicionando Bots em Tempo de Execução

Você pode adicionar novos bots enquanto o servidor está rodando. Os comandos serão registrados automaticamente no Discord.

typescript
1import { FlowRegistry, FlowEngine, MemoryStore } from 'discord-flow';
2import { createMultiBotServer } from '@discord-flow/multibots';
3
4// Servidor começa sem bots
5const server = createMultiBotServer({
6 port: 3000,
7 bots: [],
8 autoRegisterCommands: true
9});
10
11await server.start();
12
13// Mais tarde, adicione bots dinamicamente:
14async function registerNewBot(token: string, publicKey: string) {
15 const registry = new FlowRegistry();
16 const engine = new FlowEngine(registry, new MemoryStore());
17
18 registry.define('dynamic-bot', (flow) => {
19 flow.start('idle');
20 flow.state('idle')
21 .on.command({ name: 'hello', description: 'Say hello' }, () => ({
22 response: { content: 'Hello from dynamic bot!' }
23 }));
24 });
25
26 // Adiciona o bot e registra comandos automaticamente
27 const bot = await server.addBot({
28 token,
29 publicKey,
30 engine,
31 guildId: '123456789' // opcional - para comandos de guild
32 });
33
34 return bot.applicationId;
35}

O que acontece ao adicionar um bot?

  • • O applicationId é obtido automaticamente do token
  • • Os comandos são registrados no Discord (guild ou global)
  • • O bot começa a responder interações imediatamente
  • • Retorna o config resolvido com o applicationId

Integração com API (Express/Fastify)

O servidor multibots pode ser integrado Facilmente com frameworks web para adicionar rotas personalizadas (como um dashboard admin). Use os adapters incluídos:

Express

typescript
1import express from 'express';
2import { createMultiBotServer, expressAdapter } from '@discord-flow/multibots';
3import { authMiddleware } from './auth';
4
5const server = createMultiBotServer({ bots: [] });
6
7const app = express();
8app.use(express.json());
9
10// Rota de interações do Discord(Webhooks)
11app.use(expressAdapter(server));
12
13// Suas rotas de API protegidas
14app.post('/api/bots', authMiddleware, async (req, res) => {
15 try {
16 const bot = await server.addBot(req.body);
17 res.json(bot);
18 } catch(err) {
19 res.status(400).json({ error: err.message });
20 }
21});
22
23app.get('/api/bots/:id', authMiddleware, (req, res) => {
24 const bot = server.getBot(req.params.id);
25 if (!bot) return res.status(404).json({ error: 'Bot not found' });
26 res.json(bot);
27});
28
29// Endpoint para recarregar comandos(Hot Reload)
30app.post('/api/bots/:id/reload', authMiddleware, async (req, res) => {
31 await server.reloadBot(req.params.id);
32 res.json({ success: true });
33});
34
35await server.start(); // Inicia o servidor interno
36app.listen(3000); // Inicia o Express

Fastify

typescript
1import Fastify from 'fastify';
2import { createMultiBotServer, fastifyAdapter } from '@discord-flow/multibots';
3
4const server = createMultiBotServer({ bots: [] });
5const fastify = Fastify();
6
7// Rota de interações
8fastify.register(fastifyAdapter(server));
9
10fastify.post('/api/bots', async (req, reply) => {
11 const bot = await server.addBot(req.body);
12 return bot;
13});
14
15await server.start();
16fastify.listen({ port: 3000 });

Referência de API

Métodos de Gerenciamento

typescript
1interface MultiBotServer {
2 // Adiciona um bot e registra comandos
3 addBot(config: BotConfig): Promise;
4
5 // Remove um bot imediatamente
6 removeBot(applicationId: string): boolean;
7
8 // Busca informações de um bot específico
9 getBot(applicationId: string): BotInfo | undefined;
10
11 // Lista todos os bots ativos
12 getBots(): Map;
13
14 // Recarrega os comandos do bot(Hot Reload)
15 reloadBot(applicationId: string): Promise;
16
17 // Obtém o handler para integração manual
18 getHandler(): (request: Request) => Promise;
19}
20
21interface BotInfo {
22 applicationId: string;
23 commands: number;
24 guildId?: string;
25 addedAt: Date;
26}

Variáveis de Ambiente

bash
1# Bot 1
2BOT1_APP_ID=123456789012345678
3BOT1_PUBLIC_KEY=abc123...
4BOT1_TOKEN=MTIz...
5
6# Bot 2
7BOT2_APP_ID=987654321098765432
8BOT2_PUBLIC_KEY=def456...
9BOT2_TOKEN=OTg3...
10
11# Opcional: Guild para testes
12GUILD_ID=111222333444555666