Last active
June 30, 2019 15:45
-
-
Save Ratismal/a99262408922ba2ca2e9ffb367bc80c5 to your computer and use it in GitHub Desktop.
A simple method to handle awaiting messages
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* The premise of a message-awaiter is simple. You need the following: | |
* 1. An object to store messages | |
* 2. A function to populate the object | |
* 3. A hook to check this object | |
* | |
* DISCLAIMER: This gist is untested and should only be looked at for learning purposes. | |
* Please do not directly copy/paste it into your production environment. | |
*/ | |
/** | |
* A container to put await information into. Will have the folloing data structure: | |
* { | |
* channelId: { | |
* userId: { | |
* resolve: Function(), | |
* reject: Function(), | |
* callback: Function() | |
* } | |
* } | |
* } | |
*/ | |
var awaitedMessages = {}; | |
/** | |
* @description This functions takes a message object, and a verification callback. | |
* The callback is used to verify input, rather than return a result. | |
* You may expand this as needed. | |
* @param {Message} msg The message object | |
* @param {Function} callback A verification callback, taking a new Message object and returning a boolean | |
* @param {Number} timeout Amount of time in milliseconds before rejecting the request. Defaults to 300000 (5 minutes). Set to -1 to never expire. | |
* @returns {Promise} | |
*/ | |
function awaitMessage(msg, callback, timeout = 300000) { | |
return new Promise((resolve, reject) => { | |
/* Verify the contents of the object */ | |
if (!awaitedMessages[msg.channel.id]) | |
awaitedMessages[msg.channel.id] = {}; | |
/* Create an optional timeout */ | |
let timer; | |
if (timeout >= 0) { | |
timer = setTimeout(function() { | |
delete awaitedMessages[msg.channel.id][msg.author.id]; | |
reject(new Error(`Request timed out (${timeout}ms)`)); | |
}, timeout); | |
} | |
/* Check for an existing entry, and remove if neccesary */ | |
if (awaitedMessages[msg.channel.id][msg.author.id]) { | |
awaitedMessages[msg.channel.id][msg.author.id].reject(); | |
} | |
/* Create an empty entry for the user, overwriting any old one */ | |
awaitedMessages[msg.channel.id][msg.author.id] = { | |
/* Resolving function */ | |
resolve: function(msg2) { | |
clearTimeout(timer); | |
resolve(msg2); | |
}, | |
/* Rejecting function */ | |
reject: function() { | |
clearTimeout(timer); | |
reject(new Error('Request was overwritten')); | |
}, | |
callback | |
}; | |
}); | |
} | |
/** | |
* Finally, we need to hook into the awaitedMessages object. | |
*/ | |
bot.on('messageCreate', msg => { | |
/* Check if the object has the right channel-author combo */ | |
if (awaitedMessages.hasOwnProperty(msg.channel.id) | |
&& awaitedMessages[msg.channel.id].hasOwnProperty(msg.author.id)) { | |
/* Verify input */ | |
if (awaitedMessages[msg.channel.id][msg.author.id].callback(msg)) { | |
/* Resolve the promise */ | |
awaitedMessages[msg.channel.id][msg.author.id].resolve(msg); | |
} | |
} | |
}); | |
/** | |
* Examples | |
*/ | |
/* eslint-disable no-undef */ | |
// Return a message containing the word "meow", case insensitive | |
awaitMessage(msg, msg2 => msg2.content.toLowerCase().includes('meow')) | |
.then(msg2 => { | |
// Do what you want with msg2 | |
}); | |
// Return a message containing a number | |
awaitMessage(msg, msg2 => !isNaN(parseInt(msg2.content))) | |
.then(msg2 => { | |
// Do what you want with msg2 | |
}); | |
/* eslint-enable no-undef */ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment