New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

discordbot-framework

Package Overview
Dependencies
Maintainers
1
Versions
9
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

discordbot-framework

A simple framework for creating Discord bots

  • 1.4.0
  • latest
  • Source
  • npm
  • Socket score

Version published
Maintainers
1
Created
Source

Introduction

Welcome to the wonderful world of Discord bots. Through creating my own Discord bot, I have put together this basic framework to enable the process.

The purpose of this project is to make it so that anyone can spin up their own simple Discord bot fairly easily. Simply follow the below instructions and you'll be on the way to your own Discord bot in no time.

This project provides a basic wrapper around functionality presented by discord.js project.

Setup

Load the Module

The first step to get started is to load the scaffolding.

const DiscordBot = require('discordbot-framework');
let bot = new DiscordBot();

Add the configuration

Configuration for the bot is provided in the form of a basic object.

How you decide to get the object is at your discretion.

const config = {
    'secret_key' : 'my_discord_provided_secret_key'
};
bot.configure(config);

The only option that is required for configuration is secret_key but the full list of possible options is as follows:

Configuration KeyData TypeDefault ValueNote
secret_keyinteger(none)The client secret key/token provided on the Discord Developer page. The bot will fail to boot without this.
command_prefixstring'!'The prefix used for commands, e.g. !syn
allowed_channelsarray[ ]The channels that the bot is allowed to respond in; an empty array means all channels.
respond_to_botsbooleanfalseWhether or not the bot is allowed to respond to other bots.
playing_msgstringfalseThe "Playing" message for the bot, if false will skip this feature.
boot_msgstring"Connected!"This is just the message that shows up on the command line when you boot the bot up, only really shown to the person starting the bot.
enable_cmdsbooleantrueSetting this to false will tell the bot to skip adding the commands handler; useful if you want to have a non-command based bot.

Note: If there is no default value, the framework will throw an Error if one isn't specified

Configure the Event Listeners

We can add event listeners to the bot.

bot.observe('message', (msg) => console.log(`${msg.author.username} sent a message in #${msg.channel.name}`));

The observe function takes a string for the first parameter, where the string is one of the events defined by the discordjs Client. The second parameter is the callback to fire when the event is triggered.

Note: You can refer to discord.js's Client API documentation here for the supported events

Two event listeners are added automatically as part of the framework; one for 'ready' as it's required for discord.js to start, and the other for message which runs all of the message handlers (including commands, provided you don't disable them). As event listeners can be added multiple times for the same event, these two event listeners should not affect the code you write for the bot.

Add commands

We can also add commands to the bot.

bot.bind('syn', { 
    'callback'      : (msg) => msg.channel.sendMessage('Ack!'),
    'help_message'  : 'Is the bot listening? \n\tUsage: `!syn`',
    'allow_dm'      : true 
});

The bind function takes in two parameters.

  • The first argument is the name of the command (e.g., syn => !syn).
  • The second argument is an object with the required parameters for the command.
ParameterData TypeDefault ValueNote
callbackfunction(none)The function to call when the command is called.
rate_limitinteger3The number of times per minute the command can be called by a user.
allow_dmbooleanfalseWhether or not the bot will respond to this command if it's in a direct message
help_messagestring"[undocumented]"The help message for this command.

Note: If there is no default value, the system will Error if one isn't specified

Command Callbacks

The callback registered for a command is passed two parameters. The first parameter is a reference to the Message object generated by the DiscordJS message event. The second parameter is a reference to the framework instance itself which allows your command to interact with data stored as part of the instance (such as the task scheduler or Client).

I've found convenience in writing my callbacks into their own module and then importing from there. This gives the callback a complete closure to work with.

const {isup} = require('./commands/status.js');
bot.bind('isup', {
    'callback'      : isup,
    'help_message'  : "Check if a server is online.\n\tUsage: `!isup <webpage>`"
});

Command Help Messages

The system makes no implications for what you can do with the help message parameter, which is why it's optional. There is a command on the bot framework getCmdHelp() that will return an array that used in an Embed message

Here is an example implementation:

bot.bind('help', {
    'help_message'  : 'This message.\n\tUsage: `!help`',
    'callback'      : (msg, bot) => {
        let help = bot.getCmdHelp();
         msg.author.sendEmbed({
            'color'       : 0x229922,
            'title'       : "My Bot's Help",
            'fields'      : help,
            'timestamp'   : new Date()
        });
    },
    'allow_dm'      : true
});

Custom Message Handlers

We can write custom handlers for messages to perform actions that aren't related to commands.

There are two methods related to this.

  • addHandler will create a new one and expects a name for the handler as well as the handler itself. It also supports passing in a DI object/context parameter.
  • removeHandler can be used to delete a handler for a given name.

The first parameter of a handler will always be a Message object from the Discordjs message Client event. The second parameter will be the DI object/context.

Here's a basic example...

let counter = 0;
bot.addHandler('counter', (msg) => {
    counter += 1;
    console.log(`I have received ${counter} messages so far!`);
});

bot.removeHandler('counter');

And here's an example where we use the context object. Instead of passing in a function directly, we want to pass an object with two keys, callback and context. The callback defined will receive too parameters. The first parameter is the message object itself, the second parameter is the context provided.

const customHandler = require('./my-handler.js');
const DB = require('./my-db.js');

bot.addHandler('myCustomHandler', {
    'callback': customHandler,
    'context' : DB
});

In the above example, my-handler.js exports a function that starts like...

module.exports = (msg, context) => {
    // ...

And here's one more example that is a modification of the counter example from earlier to use the context parameter. I create a simple object to store my simple counter in and pass that as my context, rather than relying on the function closure.

let counter = 0;
bot.addHandler('counter', {
    'callback' : (msg, ctx) => {
        ctx.counter += 1;
        console.log(`I have seen ${ctx.counter} messages so far!`);
    },
    'context' : { counter }
});

Schedule Events

We can schedule functions to run at specific times.

This is convenient if we want something to happen on a specific schedule.

bot.schedule({
    'name'      : 'server-list', 
    'frequency' : 'hourly',
    'callback'  : (instance) => {
        let servers = instance.getGuilds().reduce((list, guild) => { list.push(guild.name + "|" + guild.id); return list; }, []);
        console.log('I am connected to the following servers: ' + servers.join(', '));
    }
});

By default, the parameter sent in to the callback is a reference to the framework itself, but this can be specified as one of the parameters as seen in the below (fairly useless) example.

// Create some data we want to send in
let days = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday'];

bot.schedule({
    'name'      : 'hourly-notice', 
    'frequency' : 'hourly',
    'start_of'  : 'hour',
    'context'   : {bot, days}, // Short hand object notation, we still want to send the bot instance, but we want to also send in the data we created
    'callback'  : (context) => {
        context.bot.getGuilds().first().defaultChannel.sendMessage(`Hello! I am only available on the following days: ${context.days.join(', ')}`);
    }
});
ParameterData TypeDefault ValueNote
nameString(none)(Required) The name of the task for scheduling purposes. Names must be unique.
frequencyString(none)(Required) The timeframe for which to fire the event; see the supported schedules table below.
callbackfunction(none)(Required) The callback to trigger on the schedule.
begin_atString/momentjs TimestampnowA timestamp at which point to start this task; can be string or momentjs instance.
start_ofString(none)This is used to jump your task the start of the next schedule. e.g., hour means start of next hour, start at 3:44 -> 4:00 -> 5:00. If omitted, it will just schedule for the next increment. e.g., 3:44 -> 4:44 -> 5:44.
contextAnyFrameworkThis is the value that will be passed into the callback parameter, the default is the instance of the framework but this would allow you to pass in anything.
immediateBooleanfalseThis will fire the function once before scheduling it
onceBooleanfalseWhether or not to reschedule the task after it has run the first time (not including the immediate run, so once + immediate = two executions)

The following frequencies are defined as within the limitations of NodeJS's setTimeout / setInterval maximum supported delay.

FrequencyDefinition
deciminuteEvery ten seconds*
minuteEvery minute
hourlyEvery hour
dailyEvery day
weeklyEvery 7 days
biweeklyEvery 14 days

* deciminute was created for testing, but the option was left because there's probably a use case for it. Highly, highly, highly recommend AGAINST hitting the Discord API every ten seconds.

The following start_of options are supported.

start_of Options
year
month
quarter
week
isoweek
day
date
hour
minute
second

This is handled using the momentjs startOf function. For examples of what specifically these options mean, see the MomentJS documentation regarding the function.

Connect!

Now that our bot is configured, has it's listeners, and commands added, we can start up the bot.

bot.connect();

And if everything went according to plan, your bot should log in to Discord successfully.

Full Example

Here is a working example bot that was set up using the framework.

// Load the module
const DiscordBot = require('discordbot-framework');
let bot = new DiscordBot();

// Get the configuration
// Please never ever commit your secret key to a git repository
// See DotEnv in the references
const configData = {
    'secret_key'        : 'thisisreallynotasecrettoken',
    'command_prefix'    : '@',
    'respond_to_bots'   : true,
    'boot_msg'          : 'I have connected!',
    'playing_msg'       : 'I am a bot!'
};

// Load the configuration into the bot
bot.configure(configData);

// Add a command
bot.bind('syn', {
    'callback'  : msg => msg.channel.sendMessage('Ack!'),
    'rate_limit': 1,
    'allow_dm'  : true
});

// Add a listener
bot.observe('guildMemberAdd', (guildMember) => {
    const nickname = guildMember.nickname || guildMember.user.username;
    guildMember.guild.defaultChannel.sendMessage(`Welcome to the ${guildMember.guild.name} party, ${nickname}!`);
});

// Add an event to the schedule
bot.schedule({
    'name'      : 'server-list', 
    'frequency' : 'hourly',
    'callback'  : (instance) => {
        let servers = instance.getGuilds().reduce((list, guild) => { list.push(guild.name + "|" + guild.id); return list; }, []);
        console.log('I am connected to the following servers: ' + servers.join(', '));
    }
});

bot.bind('help', {
    'help_message'  : 'This message.\n\tUsage: `!help`',
    'callback'      : (msg, bot) => {
        let help = bot.getCmdHelp();
         msg.author.sendEmbed({
            'color'       : 0x229922,
            'title'       : "My Bot's Help",
            'fields'      : help,
            'timestamp'   : new Date()
        });
    },
    'allow_dm'      : true
});

let counter = 0;
bot.addHandler('counter', (msg) => {
    counter += 1;
    console.log(`I have seen ${counter} messages so far!`);
});

// Tell the bot to connect to Discord
bot.connect();

References

LinkDescription
Discord.js DocumentationMain repository for documentation on the Discord.js API
momentJSThe library used in the task scheduler
NodeJS DotEnvProject designed for the purpose of loading configurations into projects

Change Log

v1.4.0

  • Added new functionality to write custom message handlers/processors
  • Refactored how commands are processed using the custom handlers (command support can now be turned off if desired)
  • Updated discord.js to 11.2.1
  • Added uws@0.14.5 (optional requirement for discord.js@11.2.1), this should solve issues related to the bot randomly disconnecting.

v1.3.1

  • Updated the dependencies to account for an issue with NPM loading uws.
  • Fixed a small typo in the README, oops!

v1.3.0

  • Added new configuration options playing_msg and boot_msg

v1.2.1

  • Fixed an issue where the allow_dm setting wasn't respected

v1.2.0

  • Added support for storing and retrieving help messages for commands
  • Added support for configuring commands to work in DMs
  • Command callbacks now receive a second parameter with a reference to the framework instance

v1.1.1

  • Fix an issue in which the bot would crash if someone used a command that didn't exist

v1.1.0

  • Support for scheduling tasks to run on rotations!

v1.0.1

  • Fixed some derps in the README file

v1.0.0

  • Initial Release!
  • Support for:
    • Adding commands
    • Listening for events

Keywords

FAQs

Package last updated on 27 Oct 2017

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc