Fancy Developer Info

Don't bother reading this if you don't code.

How Hoppi Works

It's kind of a long story how Hoppi works, but I'll summarize: Hoppi was the first bot I (p0tato#5991) ever created. Believe it or not, I started completely from scratch. I had no knowledge of Commando or any sort of command handlers. But since I didn't use any kind of fancy framework, Hoppi's programming is actually extremely simple to understand. Below is the framework for Hoppi, but I'll explain. This may seem simple to veteran bot developers, but I'm trying to explain to beginners as well (and help them get started. In fact, this code is fully functional if you have created your bot application and gotten your token).

First, I logged in using Hoppi's token, imported Discord.js, and created a client. Also, I make sure to set disableEveryone to false so that Hoppi can ping @everyone. Then simply have a client.on('message')event. I also have a client.on('ready')event to check then the bot is online. Below is the original, basic framework of Hoppi, I also explain how to create an embed, turn a sentence into an array, send a message, set the bot's status, and find the bot's ping.

Note: Hoppi obviously has a command handler now, Hoppi was gaining too many commands and users that I finally implemented my own command handler.

Hoppi's Original Framework

const Discord = require('discord.js')
const client = new Discord.Client({ disableEveryone: false })
const prefix = ';'

client.on("ready", async () => {
    console.log("Bot online")
    // Console log when the bot is logged in
    client.user.setActivity(prefix + "help", {
			type: "WATCHING",
			name: "online"
		});
		// Set bot status
}

client.on("message", async (message) => {
    // Make sure this function is asynchronous, much of the Discord API is async.

    if (message.author.bot) { return };
    // this checks if the author is a bot
    
    if (message.guild == null) {
        return message.channel.send("If there is no message.guild it means the" +
        " author direct messaged the bot.")
    }
    // this checks if the message is a dm and returns if it is.
    
    if (message.content.indexOf(prefix) !== 0) { return };
    // this checks if the message starts with the prefix, you can also use message.content.startsWith(prefix).
    
    const args = message.content.toLowerCase().slice(prefix.length).trim().split(' ');
    // toLowerCase() makes the string lowercase.
    // slice(prefix.length) slices the prefix off the string so I don't have to deal with it later.
    // trim() trims the spaces off the string at the beginning and end, if it has any.
    // split(' ') splits the string on spaces, so args becomes an array of each word of their message.
    
    const command = args.shift()
    // this makes command become the first value in args, so the first word of their message.
    
    // Now that the checks are done, we can check what command their message is.
    // DISCLAIMER: These are only examples, not the actual code.
    
    if (command === 'hello') {
        // message.channel.send sends a message to the message's channel.
            
        message.channel.send("hello there")
        return;
    } else if (command === 'ping') {
        // EMBED CONSTRUCTION: this function will show how to create an embed.
        // NOTE: the client.ping property was moved to the WebSocketManager
        // during the update to Discord.js V12. Use client.ws.ping instead.
        
        // new Discord.MessageEmbed() creates an embed.
        // '\n' makes a newline in the text.
        // Surrounding text in **four asterisks** bolds the text.
        // Math.round rounds the ping to a whole number, as the ping can be a float.
        
        ping = Math.round(client.ws.ping)
        pingEmbed = new Discord.MessageEmbed()
            .setColor("#0099ff") // the default Hoppi color.
            .setTitle("๐Ÿ“ Pong!")
            .setDescription("Ping:\n**" + ping + "**!" // Don't forget to add two asterisks to bold the text.
            .setTimestamp() // sets the timestamp.
            .setFooter("Powered by Hoppi") // set the footer text.
            
        message.channel.send(pingEmbed) // Finally, send the embed in the channel.
        return;
    } else if (command === 'hello' && args[0] === 'hoppi') {
        // The above if statement means the user has to send in a channel 
        // "hello hoppi", separated by a space.
        
        // message.author.username is the author's username, so the bot's reply
        // would look something like "hello, p0tato!".
        
        message.channel.send("hello, " + message.author.username + "!")
        return;
    } else if (command === <your command>) {
        // Your turn now! create more commands by making more if statements, 
        // and your bot will get even better!
    }
    
    // MORE CODE 
})

client.login('SUPER_SECRET_TOKEN')

Read the official Documentation for more info! The code above is only the framework for creating a bot.

Sources

Suggested sources, most of these are from the Discord.js Guide

Creating a bot/Creating an application Running your bot Adding your bot to servers Command Handling Embeds General commands/functions

Fancy developer info

Programming language: Javascript

Powered by Node.js

Node Modules

All of these can be viewed at npmjs.org.

Discord.js, urban, dateformat, moment, ytdl-core, cheerio, youtube-search, quick.db, jimp, parse-ms, pretty-ms, request, crypto, fs-nextra, random-puppy, superagent, imageapi.js, node-fetch, g-i-s, split-camelcase-to-words

General Node Module Usage

Discord: Discord.js

Database: quick.db

Http Requests: superagent, request, random-puppy, imageapi.js, node-fetch, g-i-s, urban

Time Formatting: moment, dateformat, parse-ms, pretty-ms

Photo Editing: jimp, canvas

Specific Node Module Usage

Urban dictionary: urban

Reddit search: random-puppy, imageapi.js

Wikipedia: split-camelcase-to-words

Google Images: g-i-s

Photo editing/hosting photos: jimp, canvas, crypto, fs-nextra

Last updated