Como criar um bot de Discord com comandos customizados para seu servidor de MU Online
Construa um bot de Discord em Node.js para o seu servidor de MU Online, com comandos de ranking, status do servidor, consulta de personagem e vinculação de conta, consultando o banco MS SQL do MuServer em tempo real.
Um bot de Discord bem construído é hoje um dos pilares de retenção de qualquer servidor de MU Online: ele é o primeiro contato do jogador com a comunidade, o canal onde rankings, eventos e status do servidor aparecem em tempo real, e a ponte entre o jogo e o suporte. Diferente de bots genéricos "pro
Um bot de Discord bem construído é hoje um dos pilares de retenção de qualquer servidor de MU Online: ele é o primeiro contato do jogador com a comunidade, o canal onde rankings, eventos e status do servidor aparecem em tempo real, e a ponte entre o jogo e o suporte. Diferente de bots genéricos "prontos", um bot customizado consulta diretamente o banco de dados do seu MuServer, permitindo comandos como /ranking, /personagem e /status com dados reais, atualizados a cada segundo. Este tutorial monta um bot em Node.js com discord.js, do zero até o deploy, incluindo a conexão segura ao MS SQL Server e os comandos mais pedidos pela comunidade brasileira de MU.
Por que um bot próprio em vez de bots genéricos
Bots de propósito geral (moderação, música, memes) não sabem nada sobre o seu servidor de MU. Um bot próprio lê diretamente as tabelas do MuServer — Character, AccountCharacter, MEMB_STAT — e transforma esses dados em comandos úteis dentro do Discord, sem o jogador precisar abrir o site ou logar no jogo para saber sua posição no ranking. Isso também abre espaço para automações exclusivas: anúncio automático de boss spawnado, alerta de queda de servidor, e notificação de eventos, tudo dentro do canal onde a comunidade já está.
Pré-requisitos
- Node.js 18 ou superior instalado na máquina que vai rodar o bot.
- Uma aplicação registrada no Discord Developer Portal, com o token do bot gerado.
- Acesso de rede ao MS SQL Server do seu MuServer (host, porta, usuário e senha com permissão de leitura).
- Permissão para adicionar bots ao servidor Discord da comunidade (cargo de administrador ou dono do servidor).
- Um editor de código (VS Code é o mais comum) e git instalado, opcional mas recomendado.
Estrutura do projeto
Organize o bot em pastas separadas por responsabilidade, facilitando manutenção conforme os comandos crescem:
mu-discord-bot/
├── index.js
├── deploy-commands.js
├── config.json
├── commands/
│ ├── ranking.js
│ ├── status.js
│ ├── personagem.js
│ └── vincular.js
├── db/
│ └── connection.js
└── package.json
Passo 1 — Criar a aplicação e o token do bot
No Discord Developer Portal, crie uma nova aplicação, vá em "Bot" e clique em "Add Bot". Copie o token gerado — ele nunca deve ser commitado no git nem compartilhado. Em "OAuth2 > URL Generator", marque os escopos bot e applications.commands, selecione as permissões Send Messages, Use Slash Commands e Embed Links, e use a URL gerada para convidar o bot ao seu servidor Discord.
Passo 2 — Instalar dependências e configurar a base
mkdir mu-discord-bot && cd mu-discord-bot
npm init -y
npm install discord.js mssql dotenv
Crie um arquivo .env (nunca versionado) com as credenciais:
DISCORD_TOKEN=seu_token_aqui
CLIENT_ID=id_da_aplicacao
GUILD_ID=id_do_servidor_discord
DB_HOST=127.0.0.1
DB_USER=mu_bot_readonly
DB_PASS=senha_forte_aqui
DB_NAME=MuOnline
Passo 3 — Conectar ao banco MS SQL com uma conta restrita
Crie a conta de banco mu_bot_readonly com permissão apenas de SELECT nas tabelas Character, AccountCharacter e MEMB_STAT. Isso é a diferença entre um vazamento de token virar um incidente de segurança grave ou apenas uma exposição de dados públicos de ranking.
// db/connection.js
const sql = require('mssql');
const config = {
user: process.env.DB_USER,
password: process.env.DB_PASS,
server: process.env.DB_HOST,
database: process.env.DB_NAME,
options: { encrypt: false, trustServerCertificate: true }
};
async function getPool() {
return sql.connect(config);
}
module.exports = { getPool, sql };
Passo 4 — Comando de ranking
// commands/ranking.js
const { SlashCommandBuilder, EmbedBuilder } = require('discord.js');
const { getPool, sql } = require('../db/connection');
module.exports = {
data: new SlashCommandBuilder()
.setName('ranking')
.setDescription('Mostra o top 10 de resets do servidor'),
async execute(interaction) {
await interaction.deferReply();
const pool = await getPool();
const result = await pool.request().query(`
SELECT TOP 10 Name, cLevel, Resets
FROM Character
ORDER BY Resets DESC, cLevel DESC
`);
const embed = new EmbedBuilder()
.setTitle('🏆 Top 10 Resets')
.setColor(0xffcc00)
.setDescription(
result.recordset
.map((r, i) => `**${i + 1}.** ${r.Name} — Lvl ${r.cLevel} — ${r.Resets} resets`)
.join('\n')
);
await interaction.editReply({ embeds: [embed] });
}
};
Passo 5 — Comando de consulta de personagem
O comando /personagem <nome> deve buscar apenas dados públicos (nível, classe, resets, guilda), nunca informações sensíveis de conta como e-mail ou senha. Valide o parâmetro de entrada com sql.VarChar para evitar SQL injection — nunca concatene strings diretamente na query.
// commands/personagem.js (trecho da query segura)
const request = pool.request();
request.input('nome', sql.VarChar, nomePersonagem);
const result = await request.query(
'SELECT Name, cLevel, Class, Resets FROM Character WHERE Name = @nome'
);
Passo 6 — Comando de status do servidor
Um comando /status que verifica se o GameServer e o ConnectServer estão de pé é um dos mais usados pela comunidade, pois evita o jogador tentar logar em um servidor fora do ar sem saber. A checagem mais simples é abrir um socket TCP na porta do ConnectServer (geralmente 44405) com timeout curto e reportar sucesso ou falha.
Passo 7 — Vinculação de conta Discord ↔ jogo
| Etapa | Onde acontece | Descrição |
|---|---|---|
| Gerar código | Painel web ou comando in-game | Sistema gera código de 6 dígitos válido por 10 minutos |
| Informar código | Discord (DM ao bot) | Jogador envia /vincular 123456 |
| Validar e gravar | Bot + banco próprio do bot | Bot confere o código e grava o vínculo discord_id ↔ account_id |
| Usar vínculo | Comandos futuros | /meupersonagem já sabe qual conta buscar sem o jogador digitar o nome |
Nunca implemente vinculação pedindo a senha da conta pelo Discord — isso normaliza um vetor clássico de phishing dentro da própria comunidade.
Passo 8 — Registrar os comandos slash e subir o bot
// deploy-commands.js
const { REST, Routes } = require('discord.js');
const fs = require('fs');
require('dotenv').config();
const commands = fs.readdirSync('./commands')
.map(file => require(`./commands/${file}`).data.toJSON());
const rest = new REST().setToken(process.env.DISCORD_TOKEN);
(async () => {
await rest.put(
Routes.applicationGuildCommands(process.env.CLIENT_ID, process.env.GUILD_ID),
{ body: commands }
);
console.log('Comandos registrados com sucesso.');
})();
Rode node deploy-commands.js uma vez para registrar os comandos, depois inicie o bot com node index.js. Para produção, use um gerenciador de processos como PM2 (pm2 start index.js --name mu-bot) para reiniciar automaticamente em caso de queda.
Passo 9 — Hospedagem e monitoramento contínuo
Uma VPS pequena (1 vCPU, 1 GB RAM) já roda um bot de porte médio sem problemas, desde que o banco de dados não esteja na mesma instância sobrecarregada do GameServer. Configure logs em arquivo (não apenas console) e um alerta simples — mesmo que seja um webhook próprio no Discord — para saber quando o bot cair, evitando descobrir a falha só quando um jogador reclamar.
Erros comuns e soluções
| Sintoma | Causa provável | Solução |
|---|---|---|
| Bot não responde a comandos | deploy-commands.js não executado após alteração | Rode o deploy novamente e aguarde propagação (até 1h em comandos globais) |
| Erro de conexão com o banco | Firewall bloqueando porta 1433 | Libere a porta apenas para o IP da máquina do bot |
| Comando de ranking lento | Query sem índice na coluna Resets | Crie índice na coluna usada no ORDER BY |
| Token exposto no GitHub | .env commitado por engano | Revogue o token imediatamente e gere um novo |
| Bot cai sozinho após horas no ar | Processo sem gerenciador de restart | Use PM2 ou systemd com restart automático |
Checklist de lançamento
- Aplicação e token criados no Discord Developer Portal.
- Conta de banco restrita a SELECT criada e testada.
.envfora do controle de versão (.gitignoreconfigurado).- Comandos de ranking, status e personagem testados em produção.
- Fluxo de vinculação de conta validado sem exposição de senha.
- Processo do bot rodando sob PM2 ou equivalente com restart automático.
- Logs e alerta de queda configurados.
Com o bot no ar respondendo comandos em tempo real, o passo natural seguinte é integrá-lo aos eventos automáticos do seu servidor — por exemplo, anunciando o spawn de bosses ou o início de invasões diretamente no Discord, fechando o ciclo entre o servidor de MU Online e a comunidade que joga nele.
Perguntas frequentes
Preciso saber programar para ter um bot assim?
É recomendável ter noção básica de JavaScript, mas este tutorial fornece o código-base completo. Copiando os arquivos e ajustando a string de conexão do banco, um administrador com conhecimento intermediário consegue colocar o bot no ar sem escrever lógica do zero.
O bot precisa ficar rodando no mesmo servidor do jogo?
Não. É recomendado até rodar em máquina separada, contanto que ela tenha acesso de rede ao MS SQL Server do MuServer (porta 1433 liberada) ou a uma réplica somente leitura do banco, o que é mais seguro.
É seguro dar ao bot acesso direto ao banco de dados do jogo?
Só com uma conta de banco restrita a SELECT nas tabelas necessárias (ranking, personagens, contas). Nunca use a conta de administrador do SQL Server no bot — se o token do bot vazar, um acesso de leitura limitado reduz drasticamente o dano possível.
Como faço o comando de vincular conta (Discord ↔ jogo) com segurança?
Gere um código temporário de 6 dígitos dentro do painel web ou por um comando in-game, e peça ao jogador para digitar esse código no bot via mensagem direta. O bot grava a vinculação em uma tabela própria — nunca peça a senha da conta do jogo pelo Discord.
Dá para hospedar esse bot de graça?
Para testes, sim, em uma VPS pequena ou em um plano gratuito de hospedagem Node.js. Para produção, com centenas de usuários simultâneos, recomenda-se uma VPS paga com pelo menos 1 vCPU e 1 GB de RAM dedicados ao bot, separada do GameServer.