instacord
v1.4.0
Published
super speedy discord bot framework
Downloads
3
Readme
InstaCord
Heavily opinionated discord bot framework built on discord.js for super fast bot development. InstaCord is an all-utilities-included discord bot development framework. It offers a recursive-descent parser for interpreting bot commands with a chainable API and support for waiting for returned ES6 promises to resolve. There's also a built-in database server that offers multiple RocksDB key-value stores with a very simple, well-integrated API.
Instacord is still under early development but it should be more or less stable for use in production.
Instacord has one goal in mind: Strip out the boilerplate and make things dead-simple while retaining full support for the underlying API.
If you're kaydax and/or you want this built with Eris, then sorry mate but it isn't going to happen unless you do it yourself.
Installation
npm install instacord
Bots using InstaCord
- DubsBot-dev
Want your bot on this list? send me a note on github or discord (discord server link).
Example code which should explain the basic usage of the framework:
const Discord = require('instacord');
// Create a new instacord instance.
const discord = new Discord();
// The underlying client is exposed in discord.client
var client = discord.client;
discord
// Pass your bot key here to login. You don't have to login to test commands
// using discord.test, but discord.client.user will be null.
.login(require('./secret.js'))
// 'ready' is called once the bot has logged in, or immediately if already ready.
// discord.test allows you to test a command with an emulated message. This message
// only contains a small subset of the overall discordjs message object and so may not work with all commands.
.ready(() => discord.test(discord.client.user.toString()))
/* Begin a command chain with a prefix */
.prefix("-")
// Sets the current chain and it's children's database. This is used by db
// middleware and can also be used directly (see examples further below).
// RocksDB is used as the underlying data store. RocksDB is a high-throughput
// key-value pair-based database that's meant for use on high-performance disks.
.database("instacord-example-bot")
// If the database server cannot be contacted (runs on port 13570), it will
// be automatically started in-process. Databases are automatically created
// upon request, and are stored in the 'db' folder.
// You can run the db server manually from .\node_modules\instacord\lib\util\db.js
// The database DOES NOT HAVE ANY FORM OF AUTHENTICATION! Keep port 13570 blocked.
/* the db.configdata middleware loads per-user, per-guild, and per-channel keys from the db */
.middleware(discord.mw('db.configdata')())
/* the db.loadKey middleware loads a single key from the database */
.middleware(discord.mw('db.loadKey')('count'))
.on("help", discord.mw('common.help')()) // Still a stub at the moment
.on("info", discord.mw('common.info')()) // Still a stub at the moment
/**
* Example of a simple command
* 'actions' is an object containing a lot of useful commands.
* See /lib/instacord.js CommandChain#on for a complete list
* Usage: '-echo hello'
*/
.on("hello", (actions) => actions.reply("Hello, world!"))
/**
* The second argument is the remaining unparsed command.
* You're free to do whatever you want with it
* Usage: '-echo <some other stuff>'
*/
.on("echo", (actions, substr) => actions.reply(substr))
/* Grouping starts a new CommandChain and returns it. */
.group("fun")
/* Usage: '-fun roll' */
.on("roll", (actions) => {
var msg = actions.getMessage(); // Returns the underlying discord.js message
actions.reply("Roll! Your message ID is " + msg.id);
})
.on("count", (actions, substr, storage) => {
// Remember that loadKey middleware from earlier? It puts the value into
// 'storage', which is an empty object shared with the currently
// executing command. The value is automatically saved by the middleware
// to the database after command execution is done.
storage.count = (storage.count || 0) + 1;
actions.reply("One, two, skip a few... " + storage.count + "!");
// Logs to console at the default logging level. More levels are
// availible at actions.logger[redundant, info, log, warn, error]
actions.log(actions.getMessage().author.username + " counted to " + storage.count);
})
.on("countme", (actions, substr, storage) => {
// The other db middleware we loaded was 'configdata', which loads an
// object unique to each user, channel, and guild. These are also
// saved afterwards, and offer an extremely easy way to store
// small amounts of data efficiently per-user. Be careful - these
// are always saved and loaded for each command run which means that
// if you put in a lot of data it could take a while to load.
storage.user.count = (storage.user.count || 0) + 1;
storage.channel.count = (storage.channel.count || 0) + 1;
storage.guild.count = (storage.guild.count || 0) + 1;
actions.reply("Your count: " + storage.user.count + "!");
actions.reply("Channel-wide count: " + storage.channel.count + "!");
actions.reply("Server-wide count: " + storage.guild.count + "!");
// If you're looking for an in-memory cache which performs the same
// service, try the discord.mw('memorystore')() middleware instead
// It exposes storage.mem.user, storage.mem.channel, and storage.mem.guild,
// as well as storage.mem.general. You can safely store live function data
// inside this store because it's kept in memory, but it will disappear
// when the bot is shut down.
})
.middleware((actions, substr, storage) => {
// If you want to store a key manually, or write your own db middleware,
// then you can use actions.db.get, actions.db.put, and actions.after
actions.db.get("funCmdsRun").then((value) => {
value = (value || 0) + 1;
return actions.db.put("funCmdsRun");
});
// If you didn't want to store the value right away, or perhaps expose
// it via 'storage' to other commands, you can use command.after to save
// the value after all command processing is done.
var promise = actions.db.get("funCmdsRun").then((value) => {
storage.value = value || 0;
// You don't have to worry about this not getting called in time because
// the message execution will be paused while the outer promise
// is running (see next paragraph)
actions.after(() => {
actions.db.put("funCmdsRun", storage.value);
})
});
// IMPORTANT NOTE: the default actions.db.get will LOCK the db value
// until actions.db.put is called! Call it with 'true' as it's second
// argument to disable locking. When a key is locked it cannot be
// retrieved until unlocked by writing.
// Non-locking example: actions.db.get('key', true);
// These locks are anonymous and can be unlocked by anybody calling
// actions.db.put, and are only intended to prevent unintentional
// interleaving issues where a key is written after it is retrieved.
// If you return a promise, further command execution will wait until
// that promise is resolved. If the promise fails, the current chain
// will be aborted similar to calling actions.abort();
return promise;
})
/* Usage: '-fun error <error text>' */
.on("error", (actions, substr) => {
// 'abort' prevents the current chain from going any further
// the chain can still be backtracked to run other commands
actions.abort(substr);
// if you want to immediately quit all processing for a command,
// you can use fullAbort. When you use full abort, the command
// will go straight to jail and will not pass 'go'.
// (ignore the last sentence it's a monopoly joke)
actions.fullAbort(substr);
})
/* 'end' returns to the parent command chain*/
.end()
/* this is the topmost chain, so 'end' will now return the discord instance */
.end()
discord // For clarity, but continuing the other chain would put you here.
/* mention is an alternative prefix which is called when your bot is mentioned */
.mention()
/**
* Middleware is just like 'on', but without a command.
* actions.reroute allows you to restart the entire command chain with
* a different command, allowing you to easy add aliases for commands.
*/
.middleware((actions) => actions.reroute("dub!help"))
/* Return goes all the way back to the instacord instance */
.return()