Skip to content

Instantly share code, notes, and snippets.

@Geczy
Last active December 6, 2022 21:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Geczy/646da1f777056ecd4cf8c6ecf6965592 to your computer and use it in GitHub Desktop.
Save Geczy/646da1f777056ecd4cf8c6ecf6965592 to your computer and use it in GitHub Desktop.
class TwitchCommandHandler {
// Constructor for initializing the command handler
constructor() {
this.commands = new Map(); // Map for storing command information
this.cooldowns = new Map(); // Map for storing command cooldowns
this.bypassCooldownUsers = []; // List of users that are allowed to bypass the cooldown
}
// Function for adding a user to the list of users that are allowed to bypass the cooldown
addUserToBypassList(username) {
this.bypassCooldownUsers.push(username);
}
// Function for registering a new command
registerCommand(commandName, options) {
// Check if the command is already registered
if (this.commands.has(commandName)) {
throw new Error(`Command "${commandName}" is already registered.`);
}
// Store the command information in the commands map
this.commands.set(commandName, options);
}
// Function for handling incoming Twitch chat messages
handleMessage(message) {
// Parse the message to get the command and its arguments
const [command, ...args] = this.parseMessage(message);
// Check if the command is registered
if (!this.commands.has(command)) {
return; // Skip unregistered commands
}
// Get the command options from the commands map
const options = this.commands.get(command);
// Check if the command is on cooldown
if (this.isOnCooldown(command, options.cooldown, message.user)) {
return; // Skip commands that are on cooldown
}
// Update the command cooldown
this.updateCooldown(command, options.cooldown);
// Check if the user has the required permissions
if (!this.hasPermission(message.user, options.permission)) {
return; // Skip commands for which the user lacks permission
}
// Execute the command handler
options.handler(message, args);
}
// Function for parsing a Twitch chat message to extract the command and its arguments
parseMessage(message) {
// Use a regular expression to match the command and its arguments
const match = message.content.match(/^!(\w+)\s*(.*)/);
if (!match) {
return []; // Return an empty array if the message is not a command
}
// Split the arguments on spaces, while taking into account quoted strings
const args = match[2].match(/\S+|"[^"]+"/g);
if (args === null) {
return [match[1]]; // Return the command if there are no arguments
}
// Strip the quotes from the quoted arguments
for (let i = 0; i < args.length; i++) {
if (args[i][0] === '"') {
args[i] = args[i].slice(1, -1);
}
}
// Return the command and its arguments
return [match[1], ...args];
}
// Function for checking if a command is on cooldown
isOnCooldown(command, cooldown, user) {
// Check if the user is on the list of users that are allowed to bypass the cooldown
if (this.bypassCooldownUsers.includes(user.username)) {
return false; // The command is not on cooldown for users that are allowed to bypass the cooldown
}
// Check if the command has a cooldown
if (cooldown === 0) {
return false; // Commands with a cooldown of 0 are not on cooldown
}
// Check if the command has been used recently
if (!this.cooldowns.has(command)) {
this.cooldowns.set(command, Date.now()); // Set the initial cooldown time
return false; // The command is not on cooldown if it has not been used before
}
// Check if the command cooldown has expired
const timeDiff = Date.now() - this.cooldowns.get(command);
if (timeDiff >= cooldown) {
this.cooldowns.set(command, Date.now()); // Update the cooldown time
return false; // The command is not on cooldown if its cooldown has expired
}
return true; // The command is on cooldown if none of the above conditions are met
}
// Function for updating the cooldown time for a command
updateCooldown(command, cooldown) {
// Check if the command has a cooldown
if (cooldown === 0) {
return; // Do not update the cooldown for commands with a cooldown of 0
}
// Update the command cooldown time
this.cooldowns.set(command, Date.now());
}
// Function for checking if a user has the required permission for a command
hasPermission(user, permission) {
// Check if the user has the required permission level
if (user.permission >= permission) {
return true; // The user has the required permission
}
// Send a message to the user indicating that they lack permission
user.send("You do not have permission to use this command.");
return false; // The user lacks the required permission
}
}
const commandHandler = new TwitchCommandHandler();
// Register a "ping" command that sends a "pong" message to the chat
commandHandler.registerCommand("ping", {
permission: 0, // The "ping" command requires no special permission
cooldown: 1000, // The "ping" command has a cooldown of 1 second
handler: (message, args) => {
// Send a "pong" message to the chat
message.channel.send("pong");
},
});
// Add a user to the list of users that are allowed to bypass the cooldown
commandHandler.addUserToBypassList("user1");
client.on("message", (message) => {
// Handle the incoming message using the command handler
commandHandler.handleMessage(message);
});
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment