1.4.0 • Published 6 years ago

instacord v1.4.0

Weekly downloads
1
License
GPL-3.0
Repository
github
Last release
6 years ago

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()
1.4.0

6 years ago

1.3.0

6 years ago

1.2.4

6 years ago

1.2.3

6 years ago

1.2.2

6 years ago

1.2.1

6 years ago

1.2.0

6 years ago

1.1.1

6 years ago

1.1.0

6 years ago

1.0.1

6 years ago

1.0.0

6 years ago