Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Using Enmap for per-server configurations

Enmap Example

COMPATIBLE WITH VERSION 4 ONLY: Please note that the below has been updated to Enmap 4 and will not work in previous versions! Make sure to update Enmap if it's already installed!

This example uses a very, very simple bot made in discord.js to demonstrate how easily Enmap can be used to create a per-server configuration system.


This code requires the following installation on Windows:

NodeJS version 8.4 and higher is a pre-requisite to use all of this, please make sure your node version is up to date.


All support for enmap is offered in the Official Evie.Codes Discord.

Comments below are not monitored.

// start discord.js init
const config = require("./config.json"); // See config.json below for example
const Discord = require("discord.js"); // Code below supports and is tested under "stable" 11.3.x
const client = new Discord.Client();
// end discord.js init
// Initialize **or load** the server configurations
const Enmap = require('enmap');
// I attach settings to client to allow for modular bot setups
// In this example we'll leverage fetchAll:false and autoFetch:true for
// best efficiency in memory usage. We also have to use cloneLevel:'deep'
// to avoid our values to be "reference" to the default settings.
// The explanation for why is complex - just go with it.
client.settings = new Enmap({
name: "settings",
fetchAll: false,
autoFetch: true,
cloneLevel: 'deep'
const defaultSettings = {
prefix: "!",
modLogChannel: "mod-log",
modRole: "Moderator",
adminRole: "Administrator",
welcomeChannel: "welcome",
welcomeMessage: "Say hello to {{user}}, everyone! We all need a warm welcome sometimes :D"
client.on("guildDelete", guild => {
// Removing an element uses `delete(key)`
client.on("guildMemberAdd", member => {
// This executes when a member joins, so let's welcome them!
// First, ensure the settings exist
client.settings.ensure(, defaultSettings);
// First, get the welcome message using get:
let welcomeMessage = client.settings.get(, "welcomeMessage");
// Our welcome message has a bit of a placeholder, let's fix that:
welcomeMessage = welcomeMessage.replace("{{user}}", member.user.tag)
// we'll send to the welcome channel.
.find("name", client.settings.get(, "welcomeChannel"))
// Nowe let's get to the commands!
// This runs on every message we'll use it to demonstrate loading and changing values
client.on("message", async (message) => {
// This stops if it's not a guild (obviously), and we ignore all bots.
if(!message.guild || return;
// We can use ensure() to actually grab the default value for settings,
// if the key doesn't already exist.
const guildConf = client.settings.ensure(, defaultSettings);
// We also stop processing if the message does not start with our prefix.
if(message.content.indexOf(guildConf.prefix) !== 0) return;
//Then we use the config prefix to get our arguments and command:
const args = message.content.split(/\s+/g);
const command = args.shift().slice(guildConf.prefix.length).toLowerCase();
// Alright. Let's make a command! This one changes the value of any key
// in the configuration.
if(command === "setconf") {
// Command is admin only, let's grab the admin value:
const adminRole = message.guild.roles.find("name", guildConf.adminRole);
if(!adminRole) return message.reply("Administrator Role Not Found");
// Then we'll exit if the user is not admin
if(!message.member.roles.has( {
return message.reply("You're not an admin, sorry!");
// Let's get our key and value from the arguments.
// This is array destructuring, by the way.
const [prop, ...value] = args;
// Example:
// prop: "prefix"
// value: ["+"]
// (yes it's an array, we join it further down!)
// We can check that the key exists to avoid having multiple useless,
// unused keys in the config:
if(!client.settings.has(, prop)) {
return message.reply("This key is not in the configuration.");
// Now we can finally change the value. Here we only have strings for values
// so we won't bother trying to make sure it's the right type and such.
client.settings.set(, value.join(" "), prop);
// We can confirm everything's done to the client.`Guild configuration item ${prop} has been changed to:\n\`${value.join(" ")}\``);
// Now let's make another command that shows the configuration items.
if(command === "showconf") {
let configProps = Object.keys(guildConf).map(prop => {
return `${prop} : ${guildConf[prop]}\n`;
});`The following are the server's current configuration:
// Start the bot by logging it in.
"token": "MTg-this-IzNzU3OTA5NjA-is.not-DCeFB-a.real-r4DQlO-t0ken-qerT0"

This comment has been minimized.

Copy link
Owner Author

@eslachance eslachance commented Mar 23, 2018

Hey guys, if you need help, stop commenting on this gist I'm not monitoring and read the last line of the readme:
All support for enmap is offered in the Idiot's Guide Official Server

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.