Coding a discord bot to generate a Pokemon in your discord server

Tarun Kumar
hackgenius
Published in
6 min readOct 9, 2022

When creating a discord server, one of the first things you might think of is how to spice up your server and create a fun place for your friends to hang out. Usually you would add music bots like Rhythm or Octave, some games like MEE6 or auto-moderators like MEE6 or carl-bot.

What is a Discord Bot?

Discord bots are AI-driven pseudo-users which are given the same permissions as an ordinary user and interact with the user. The functionality of the bots can be customized using the discord.js API provided by Discord themselves. It is NodeJS based API that allows you to make your bot respond to Slash-commands and send messages and embeds.

Creating your own bot

Step 1. Head on over to the discord developer page and click on “New Application”.

Step 2. Give your bot a name and copy the token of your bot. The token is to be treated as the password of your bot. The token can be found in the Bot tab.(It should either show you the option directly or offer to Reset Token)

Step 3. Go to Oauth2 -> URL Generator and select the following permissions.

Step 4. Scroll down and open the URL in a new tab. Select the server you want to add it to and solve the captcha to add it.

You should see this message in your server now.

Step 5. Copy your bot’s Client ID from Oauth2 -> General and store it somewhere

Coding the bot

Prerequisites
1. NodeJS
2. VSCode
3. Your Server/Guild Id (How to get?)

Initial Setup

Open up a terminal or powershell window and run the following commands:-

mkdir Pokedexcd Pokedexnpm init -ynpm install discord.js undici nodemoncode .

Discord.js is our main package with which we create our bot.
Undici is a package to send HTTP requests.
Nodemon automatically restarts the app when a change is made to the code.

Create a file named config.json and add the following JSON object in it

config.json

{   
"token": "Your Bot token from before",
"guildId": "Your Server ID",
"clientId": "Your Client ID from your Bot page"
}

DISCLAIMER: Do not share the details of this file to anyone. If you are uploading this bot to github or other cloud repository, make sure to include in your .gitignore file.

Now we need to register the Slash commands your bot will be responding to. To do that, create a file name deploy-commands.js and add the following code

deploy-commands.js

const { REST, SlashCommandBuilder, Routes } = require('discord.js');const { clientId, guildId, token } = require('./config.json');const commands = [new SlashCommandBuilder().setName('pokemon-gen').setDescription('Display basic details of a pokemon!').addStringOption(option =>option.setName('name').setDescription('Display basic details of a pokemon!').setRequired(true))].map(command => command.toJSON());const rest = new REST({ version: '10' }).setToken(token);rest.put(Routes.applicationGuildCommands(clientId, guildId), { body: commands }).then((data) => console.log(`Successfully registered ${data.length} application commands.`)).catch(console.error);

This file needs to be executed every time you add a new command to your bot.

Additional commands can be created using the SlashCommandBuilder() constructor and adding it to the commands array. The command being created here follows the syntax of

/pokemon-gen <name>

Now, to change the how your bot should behave when the command /pokemon-gen <name>,

Create a file called index.js. This file is your “bot” to put it simply and the bot will remain online as long as this file is running.

After creating the file, add the following code,

index.js

const { Client, GatewayIntentBits, EmbedBuilder } = require('discord.js');const { token } = require('./config.json');const { request } = require('undici');async function getJSONResponse(body) {let fullBody = '';for await (const data of body) {fullBody += data.toString();}return JSON.parse(fullBody);}// Create a new client instanceconst client = new Client({ intents: [GatewayIntentBits.Guilds] });client.on('interactionCreate', async interaction => {if (!interaction.isChatInputCommand()) return;const { commandName } = interaction;if (commandName === 'pokemon-gen') {const p_name = interaction.options.getString('name');const pokemon = await request('https://pokeapi.co/api/v2/pokemon/' + p_name);const status_code = pokemon.statusCode;if (status_code > 299) return interaction.channel.send('Pokemon not found!')const data = await getJSONResponse(pokemon.body);const sprite_url = data.sprites.front_default;const official_art = data.sprites.other['official-artwork'].front_default;const name = data.name;const random_move1 = data.moves[Math.floor(Math.random() * data.moves.length)].move.name;const random_move2 = data.moves[Math.floor(Math.random() * data.moves.length)].move.name;const random_move3 = data.moves[Math.floor(Math.random() * data.moves.length)].move.name;const random_move4 = data.moves[Math.floor(Math.random() * data.moves.length)].move.name;const pokemon_type = data.types[0].type.name;const embed = new EmbedBuilder().setTitle(name).setURL('https://bulbapedia.bulbagarden.net/wiki/' + name + '_(Pok%C3%A9mon)').setAuthor({ name: 'Pokedex', iconURL: 'https://scontent.fmaa1-3.fna.fbcdn.net/v/t39.30808-6/305210378_481487853988893_2962652754532608370_n.png?_nc_cat=107&ccb=1-7&_nc_sid=09cbfe&_nc_ohc=kMZhovV5v5EAX9yhXEb&_nc_ht=scontent.fmaa1-3.fna&oh=00_AT-vMD1TdLIzRvrTXfcAXwdey6ANA7CoYBhijZ_vB6ZYqA&oe=633C5FA0', url: 'https://discord.js.org' }).setDescription('A wild ' + name + ' appeared!').setThumbnail(official_art).addFields({ name: 'Type', value: pokemon_type, inline: true },{ name: 'Move 1', value: random_move1, inline: true },{ name: 'Move 2', value: random_move2, inline: true },{ name: 'Move 3', value: random_move3, inline: true },{ name: 'Move 4', value: random_move4, inline: true },).setImage(sprite_url).setTimestamp()return await interaction.channel.send({ embeds: [embed] });}});client.login(token);

The Client() constructor is used to create your bot client. The client responds to slash commands from your server and sends responses back to the server in the form of messages, embeds, files etc.

The client.on() adds an event listener to the client which basically means it is actively looking for a command matching the pattern /pokemon-gen <name> and performs whatever is written in the callback function passed to it.

In this case, when the command /pokemon-gen <name> is typed, the bot uses the undici package and sends an HTTP GET request to pokeapi.co. PokeAPI is a RESTful API that offers all the data you would ever need about every Pokemon in the Pokemon Universe. In this case, the data fields we will be needing are the following:-

  1. Name
  2. Official art
  3. Sprite art
  4. 4 Random moves from a list of 70+ moves
  5. Type

After extracting the above data, it can be embedded into a discord message using the EmbedBuilder() constructor.

After constructing the Embed Message, it can be sent to the server by returning the function interaction.channel.send({ embeds: [embed] });. Since the callback function is asynchronous, the return statement must be awaited while the bot listens to other slash commands.

Finally to get the bot online, it must be logged into using the client.login(token) statement, where your bot token behaves as the password.

Now, to get the commands working, two steps must be followed:

  1. Registering the commands by running the deploy-commands.js, with the command node deploy-commands.js
  2. Running your bot using the command npx nodemon index.js

Now lets see our bot in action

Head on over to your server and try generating your favourite Pokemon using the commands we deployed:

/pokemon-gen yveltal
/pokemon-gen pikachu

And there you have it, your own Pokemon-generator that gives you a Pokemon with random moves, right there in your own discord server. You can find the final code in my GitHub.

Feel free to send me feedback.

--

--