Tutorial

Como criar um bot no Discord com o Node.js

Node.jsDevelopmentJavaScriptProgramming Project

O autor selecionou o Free and Open Source Fund para receber uma doação como parte do programa Write for DOnations.

Introdução

O Discord é um aplicativo de chat que permite a milhões de usuários em todo o mundo enviar mensagens e bate-papo de voz online em comunidades chamadas guilds ou servidores. O Discord também fornece uma extensa API que os desenvolvedores podem usar para criar poderosos bots no Discord. Os bots podem realizar várias ações, como enviar mensagens para servidores, enviar mensagens diretas a usuários, moderar servidores e reproduzir áudio em conversas de voz. Isso permite que desenvolvedores criem robôs poderosos que incluem recursos avançados e complexos, como ferramentas de moderação ou até mesmo jogos. Por exemplo, o bot utilitário Dyno serve milhões de guilds e contém recursos úteis, como proteção contra spam, um reprodutor de música e outras funções utilitárias. Aprender como criar bots no Discord lhe permite implementar muitas possibilidades, com as quais milhares de pessoas poderiam interagir todos os dias.

Neste tutorial, você irá criar um bot Discord a partir do zero, usando o Node.js e a biblioteca Discord.js, que permite aos usuários interagir diretamente com a API do Discord. Você irá configurar um perfil para um bot do Discord, obter tokens de autenticação para o bot, e programá-lo com a capacidade de processar comandos, com argumentos, dos usuários.

Pré-requisitos

Antes de começar, você precisará do seguinte:

Passo 1 — Configurando um bot Discord

Neste passo você usará a GUI de desenvolvedores do Discord para configurar um bot Discord e obter o token do bot, que você passará para o seu programa.

Para registrar um bot na plataforma Discord, use o painel da aplicação Discord. Aqui os desenvolvedores podem criar aplicações Discord, incluindo bots Discord.

Image of the Discord application dashboard after first visiting https://discord.com/developers/applications

Para começar, clique em New Application. O Discord vai lhe pedir que digite um nome para a sua nova aplicação. Em seguida, clique em Create para criar a aplicação.

Image of the prompt to create an application, with "Test Node.js Bot" entered as the name of the application

Nota: o nome para sua aplicação é independente do nome do bot, e o bot não precisa ter o mesmo nome que a aplicação.

Agora, abra seu painel de aplicação. Para adicionar um bot à aplicação, navegue até a guia Bot na barra de navegação à esquerda.

Image of the bot tab of the application dashboard

Clique no botão Add Bot para adicionar um bot à aplicação. Clique no botão Yes, do it! quando ele lhe pedir confirmação. Você estará então em um painel contendo detalhes do nome do seu bot, token de autenticação e foto do perfil.

Dashboard containing details of your bot

Você pode modificar o nome do seu bot ou a imagem do perfil aqui no painel. Você também precisa copiar o token de autenticação do bot, clicando em Click to Reveal Token e copiando o token que aparece.

Atenção: nunca compartilhe ou faça o upload do seu token do bot, pois ele permite que alguém faça login no seu bot.

Agora, você precisa criar um convite que lhe permita adicionar as guilds do bot Discord onde você pode testar o bot. Primeiro, navegue até a guia OAuth2 do painel da aplicação. Para criar um convite, desça e selecione bot abaixo de scopes Você também deve definir permissões para controlar quais ações o seu bot pode realizar nas guilds. Para os propósitos deste tutorial, selecione Administrator, que dará ao seu bot permissão para realizar quase todas as ações nas guilds. Copie o link com o botão Copy.

OAuth2 tab, with scope set to "bot" and permissions set to "administator"

Em seguida, adicione o bot a um servidor. Siga o link do convite que você acabou de criar. Você pode adicionar o bot a qualquer servidor que você possua, ou que tenha permissões de administrador, a partir do menu suspenso.

Page from following the invite link, allowing users to add the bot to servers

Agora, clique em Continue. Certifique-se de que a caixa de seleção ao lado de Administrator esteja assinalada — isso concederá ao bot permissões de administrador. Em seguida, clique em Authorize. O Discord irá lhe pedir que resolva um CAPTCHA antes que o bot se junte ao servidor. Agora, você terá o bot Discord na lista de membros no servidor que você adicionou o bot, abaixo de offline.

Members list of a Discord server with the newly created bot under the "offline" section of the members list

Você criou com sucesso um bot Discord e o adicionou a um servidor. Em seguida, você irá escrever um programa para fazer login no bot.

Passo 2 — Criando o seu projeto

Neste passo, você irá configurar o ambiente de codificação básico onde você irá criar seu bot e fazer login nele programaticamente.

Primeiro, você precisa configurar uma pasta de projeto e os arquivos de projeto necessários para o bot.

Crie sua pasta de projeto:

  • mkdir discord-bot

Vá para a pasta do projeto que você acabou de criar:

  • cd discord-bot

Em seguida, use seu editor de texto para criar um arquivo chamado config.json para armazenar o token de autenticação do seu bot:

  • nano config.json

Em seguida, adicione o seguinte código ao arquivo de configuração, substituindo o texto destacado pelo token de autenticação do seu bot:

config.json
{
    "BOT_TOKEN": "YOUR BOT TOKEN"
}

Salve e saia do arquivo.

Em seguida, você irá criar um arquivo package.json, que irá armazenar detalhes do seu projeto e informações sobre as dependências que você usará para o projeto. Você irá criar um arquivo package.json executando o seguinte comando npm:

  • npm init

O npm irá lhe perguntar vários detalhes sobre seu projeto. Se você quiser orientação sobre como preencher esses prompts, pode ler sobre eles em How To Use Node.js Modules with npm and package.json.

Agora, você irá instalar o pacote discord.js que você usará para interagir com a API do Discord. Você pode instalar discord.js através do npm com o seguinte comando:

  • npm install discord.js

Agora que você definiu o arquivo de configuração e instalou a dependência necessária, você está pronto para começar a criar seu bot. Em uma aplicação no mundo real, um bot grande seria dividido em muitos arquivos, mas para os fins deste tutorial, o código para o bot estará em um único arquivo.

Primeiro, crie um arquivo chamado index.js na pasta discord-bot para o código:

  • nano index.js

Comece a codificação do bot exigindo a dependência discord.js e o arquivo de configuração com o token do bot:

index.js
const Discord = require("discord.js");
const config = require("./config.json");

Após isso, adicione as duas linhas de código seguintes:

index.js
...
const client = new Discord.Client();

client.login(config.BOT_TOKEN);

Salve e saia do seu arquivo.

A primeira linha de código cria um novo Discord.Client e o atribui à constante client. Este cliente, em parte, é como você irá interagir com a API do Discord e como o Discord irá notificá-lo de eventos como novas mensagens. O client e, na verdade, representa o bot Discord.

A segunda linha de código usa o método login no client para fazer login no bot Discord que você criou, usando o token no arquivo config.json como uma senha. O token permite que a API do Discord saiba a qual bot o programa se destina e que você está autenticado para usar o bot.

Agora, execute o arquivo index.js usando o Node:

  • node index.js

O status do seu bot irá se alterar para online no servidor Discord ao qual você o adicionou.

Image of the bot online

Você criou com sucesso um ambiente de codificação e criou o código básico para fazer login em um bot Discord. No próximo passo, você irá lidar com comandos de usuário e fazer com que seu bot execute ações, como o envio de mensagens.

Passo 3 — Lidando com seu primeiro comando de usuário

Neste passo, você irá criar um bot que possa lidar com comandos de usuário. Você irá implementar seu primeiro comando ping, que irá responder com "pong" e o tempo necessário para responder ao comando.

Primeiro, você precisa detectar e receber quaisquer mensagens que os usuários enviam para que você possa processar quaisquer comandos. Usando o método on no cliente Discord, o Discord irá lhe enviar uma notificação sobre novos eventos. O método on leva dois argumentos: o nome de um evento para esperar e uma função a executar cada vez que esse evento ocorre. Com este método, você pode esperar pelo evento message — isso ocorrerá cada vez que uma mensagem for enviada a uma guild onde o bot tiver a permissão para visualizar mensagens. Portanto, vamos criar uma função que será executada cada vez que uma mensagem for enviada, para processar comandos.

Primeiro abra seu arquivo:

  • nano index.js

Adicione o código a seguir ao seu arquivo:

index.js
...
const client = new Discord.Client();


client.on("message", function(message) { 
                                         
});                                      

client.login(config.BOT_TOKEN);

Essa função, que executa no evento message, toma message como um parâmetro. message terá o valor de uma instância Discord.js message, que contém informações sobre a mensagem enviada e os métodos para ajudar o bot a responder.

Agora, adicione a seguinte linha de código à sua função de tratamento de comandos:

index.js
...
client.on("message", function(message) {
  if (message.author.bot) return;
});
...

Essa linha verifica se o autor da mensagem é um bot e, se assim for, para de processar o comando. Isso é importante, pois geralmente você não quer processar ou responder a mensagens de bots. Os bots geralmente não precisam ou não querem usar nosso bot, portanto, ignorar suas mensagens economiza energia de processamento e ajuda a evitar respostas acidentais.

Agora, você irá escrever um handler de comando. Para realizar isso, é bom entender o formato usual de um comando Discord. Normalmente, a estrutura de um comando Discord contém três partes na seguinte ordem: um prefixo, um nome de comando e, às vezes, argumentos de comando.

An image of a typical Discord command reading "! add 1 2"

  • Prefix: o prefixo pode ser qualquer coisa, mas normalmente é um pedaço de pontuação ou frase abstrata que normalmente não estaria no início de uma mensagem. Isso significa que quando você incluir o prefixo no início da mensagem, o bot irá saber que a intenção para este comando é para um bot processá-lo.

  • Command name: o nome do comando que o usuário quer usar. Isso significa que o bot pode suportar vários comandos com diferentes funcionalidades e permitir aos usuários escolher entre eles fornecendo um nome de comando diferente.

  • Arguments: às vezes, se o comando exigir ou usar informações extras do usuário, o usuário pode fornecer argumentos após o nome do comando, com cada argumento separado por um espaço.

Nota: não há nenhuma estrutura de comando obrigatória, e os bots podem processar comandos como eles quiserem, mas a estrutura aqui apresentada é uma estrutura eficiente que a grande maioria dos bots usam.

Para começar a criar um parser de comando que lida com este formato, adicione as seguintes linhas de código à função de tratamento de mensagens:

index.js
...
const prefix = "!";

client.on("message", function(message) {
  if (message.author.bot) return;
  if (!message.content.startsWith(prefix)) return;
});
...

Você adiciona a primeira linha de código para atribuir o valor "!" à constante prefix, que você usará como o prefixo do bot.

A segunda linha de código que você adiciona , verifica se o conteúdo da mensagem que o bot está processando começa com o prefixo que você definiu e, se não começar, interrompe o processamento da mensagem.

Agora, converta o resto da mensagem em um nome de comando e todos os argumentos da mensagem. Adicione as linhas destacadas a seguir:

index.js
...
client.on("message", function(message) {
  if (message.author.bot) return;
  if (!message.content.startsWith(prefix)) return;

  const commandBody = message.content.slice(prefix.length);
  const args = commandBody.split(' ');
  const command = args.shift().toLowerCase();
});
...

Você usa a primeira linha aqui para remover o prefixo do conteúdo da mensagem e atribuir o resultado à constante commandBody. Isso é necessário, uma vez que você não quer incluir o prefixo no nome de comando no qual você fez a varredura.

A segunda linha pega a mensagem com o prefixo removido e usa o método split nela, com um espaço como separador. Isso a divide em um array de sub-strings, fazendo uma divisão onde quer que haja um espaço. Isso resulta em um array contendo o nome do comando e, se incluído na mensagem, quaisquer argumentos. Você atribui este array à constante args.

A terceira linha remove o primeiro elemento do array args (que será o nome de comando fornecido), o converte em minúsculas e, em seguida, o atribui à constante command. Isso lhe permite isolar o nome do comando e deixar apenas argumentos no array. Você também usa o método toLowerCase, pois os comandos normalmente não diferenciam maiúsculas de minúsculas em bots do Discord.

Você concluiu a construção de um parser de comando, implementando um prefixo necessário e obtendo o nome do comando e quaisquer argumentos das mensagens. Agora, você irá implementar e criar o código para os comandos específicos.

Adicione o código a seguir para iniciar a implementação do comando ping:

index.js
...
  const args = commandBody.split(' ');
  const command = args.shift().toLowerCase();

  if (command === "ping") {
                           
  }                        
});
...

Esta declaração if verifica se o nome de comando que você analisou (atribuído à constante command) corresponde ao "ping". Se sim, isso indica que o usuário quer usar o comando "ping". Você irá aninhar o código para o comando específico dentro do bloco da declaração if. Você irá repetir este padrão para outros comandos que você deseja implementar.

Agora, você pode implementar o código para o comando "ping":

index.js
...
  if (command === "ping") {
    const timeTaken = Date.now() - message.createdTimestamp;
    message.reply(`Pong! This message had a latency of ${timeTaken}ms.`);
  }
...

Salve e saia do seu arquivo.

Você adiciona o bloco do comando "ping" que calcula a diferença entre o tempo atual — encontrado usando o método now no objeto Date — e o timestamp de quando a mensagem foi criada em milisegundos. Isso calcula quanto tempo a mensagem levou para processar o "ping" do bot.

A segunda linha responde ao comando do usuário usando o método reply na constante message. O método reply faz um ping (que notifica o usuário e destaca a mensagem para o usuário especificado) no usuário que invocou o comando, seguido pelo conteúdo fornecido como o primeiro argumento para o método. Você fornece um modelo literal contendo uma mensagem e o ping calculado como a resposta que o método reply usará.

Isso conclui a implementação do comando "ping".

Execute seu bot usando o comando a seguir (na mesma pasta que index.js):

  • node index.js

Agora, use o comando "! ping"“ em qualquer canal onde o bot possa visualizar e enviar mensagens, resultando em uma resposta.

Image of bot replying in Discord to "! ping" with "@T0M, Pong! This message had a latency of 1128ms."

Você criou com sucesso um bot que pode lidar com comandos de usuário e implementou seu primeiro comando. No próximo passo, você irá continuar desenvolvendo seu bot implementando um comando sum.

Passo 4 — Implementando o comando Sum

Agora, você irá estender seu programa implementando o comando "! sum". O comando irá tomar qualquer número de argumentos e adicioná-los juntos, antes de retornar a soma de todos os argumentos ao usuário.

Se seu bot Discord ainda estiver em execução, você pode parar seu processo com CTRL + C.

Abra seu arquivo index.js novamente:

  • nano index.js

Para começar a implementar o comando "! sum", você usará um bloco else-if. Depois de verificar o nome do comando ping, ele irá verificar se o nome do comando é igual a "sum". Usamos um bloco else-if já que apenas um comando irá processar de cada vez, então se o programa corresponder ao nome de comando "ping", ele não precisa verificar o comando "sum". Adicione as seguintes linhas destacadas ao seu arquivo:

index.js
...
  if (command === "ping") {
    const timeTaken = Date.now() - message.createdTimestamp;
    message.reply(`Ping! This message had a latency of ${timeTaken}ms.`);
  }

  else if (command === "sum") {
                               
  }                            
});
...

Você pode começar a implementar o código para o comando "sum". O código para o comando "sum" irá entrar dentro do bloco else-if que você acabou de criar. Agora, adicione o código a seguir:

index.js
...
  else if (command === "sum") {
    const numArgs = args.map(x => parseFloat(x));
    const sum = numArgs.reduce((counter, x) => counter += x);
    message.reply(`The sum of all the arguments you provided is ${sum}!`);
  }
...

Você usa o método map na lista argumentos para criar uma nova lista usando a função parseFloat em cada item no array args. Isso cria um novo array (atribuído à constante numArgs) no qual todos os itens são números em vez de strings. Isso significa que mais tarde você pode encontrar com sucesso a soma dos números adicionando-os.

A segunda linha usa o método reduce na constante numArgs, fornecendo uma função que totaliza todos os elementos na lista. Você atribui a soma de todos os elementos em numArgs à constante. sum.

Em seguida, você usa o método reply no objeto message para responder ao comando do usuário com modelo literal, que contém a soma de todos os argumentos que o usuário envia para o bot.

Isso conclui a implementação do comando "sum". Agora, execute o bot usando o comando a seguir (na mesma pasta que index.js):

  • node index.js

Agora, você pode usar o comando "! sum"” em qualquer canal em que o bot possa visualizar e enviar mensagem.

Image of bot replying "The sum of all the arguments you provided is 6!" to "! sum 1 2 3", then replying "The sum of all the arguments you provided is 13! to "! sum 1.5 1.5 10"

A seguir está uma versão finalizada do script index.js do bot:

index.js
const Discord = require("discord.js");
const config = require("./config.json");

const client = new Discord.Client();

const prefix = "!";

client.on("message", function(message) {
  if (message.author.bot) return;
  if (!message.content.startsWith(prefix)) return;

  const commandBody = message.content.slice(prefix.length);
  const args = commandBody.split(' ');
  const command = args.shift().toLowerCase();

  if (command === "ping") {
    const timeTaken = Date.now() - message.createdTimestamp;
    message.reply(`Pong! This message had a latency of ${timeTaken}ms.`);
  }

  else if (command === "sum") {
    const numArgs = args.map(x => parseFloat(x));
    const sum = numArgs.reduce((counter, x) => counter += x);
    message.reply(`The sum of all the arguments you provided is ${sum}!`);
  }
});

client.login(config.BOT_TOKEN);

Neste passo, você melhorou ainda mais seu bot Discord implementando o comando sum.

Conclusão

Você implementou com sucesso um bot Discord que pode lidar com vários comandos de usuário e argumentos de comando diferentes. Se você quiser expandir seu bot, você pode possivelmente implementar mais comandos ou experimentar mais partes da API do Discord para criar um bot Discord poderoso. Você pode revisar a documentação do Discord.js ou a documentação da API do Discord para expandir seu conhecimento da API Discord.

Ao criar bots no Discord, você deve sempre ter em mente os termos de serviço da API do Discord, que descreve como os desenvolvedores devem utilizar a API. Você também pode ler este conjunto de diretrizes sobre como implementar melhor um bot Discord, e fornece dicas sobre como projetar bots no Discord. Se você quiser aprender mais sobre o Node.js confira nossa série How To Code in Node.js.

Creative Commons License