Add pollreaction system to automatically add reactions to polls

This commit is contained in:
Ean Milligan (Bastion) 2022-09-03 03:46:51 -04:00
parent 39567accfa
commit b2b6af90ce
9 changed files with 90 additions and 3 deletions

View File

@ -1,6 +1,6 @@
export const config = {
'name': 'Sweeper Bot', // Name of the bot
'version': '0.1.0', // Version of the bot
'version': '0.2.0', // Version of the bot
'token': 'the_bot_token', // Discord API Token for this bot
'localtoken': 'local_testing_token', // Discord API Token for a secondary OPTIONAL testing bot, THIS MUST BE DIFFERENT FROM "token"
'prefix': 's!', // Prefix for all commands
@ -16,6 +16,7 @@ export const config = {
'reportChannel': 0n, // Discord channel ID where reports will be sent when using the built-in report command
'devServer': 0n, // Discord guild ID where testing of indev features/commands will be handled, used in conjuction with the DEVMODE bool in mod.ts
'ownerId': 0n, // Discord user ID of the bot owner
'pollChannels': [], // List of Discord channel IDs that are to be managed by the pollReaction system
};
export default config;

View File

@ -3,4 +3,4 @@ export const DEVMODE = false;
// DEBUG is used to toggle the cmdPrompt
export const DEBUG = false;
// LOCALMODE is used to run a differnt bot token for local testing
export const LOCALMODE = true;
export const LOCALMODE = false;

View File

@ -11,6 +11,7 @@ events.ready = eventHandlers.ready;
events.guildCreate = eventHandlers.guildCreate;
events.guildDelete = eventHandlers.guildDelete;
events.messageCreate = eventHandlers.messageCreate;
events.messageUpdate = eventHandlers.messageUpdate;
if (DEVMODE) {
events.debug = eventHandlers.debug;

View File

@ -3,6 +3,7 @@ import { guildCreate } from './guildCreate.ts';
import { guildDelete } from './guildDelete.ts';
import { debug } from './debug.ts';
import { messageCreate } from './messageCreate.ts';
import { messageUpdate } from './messageUpdate.ts';
export default {
ready,
@ -10,4 +11,5 @@ export default {
guildDelete,
debug,
messageCreate,
messageUpdate,
};

View File

@ -10,6 +10,7 @@ import {
Message,
} from '../../deps.ts';
import commands from '../commands/_index.ts';
import functions from '../functions/_index.ts';
import utils from '../utils.ts';
export const messageCreate = (bot: Bot, message: Message) => {
@ -23,6 +24,10 @@ export const messageCreate = (bot: Bot, message: Message) => {
commands.handleMentions(bot, message);
}
if (config.pollChannels.includes(message.channelId)) {
functions.pollReactions(bot, message);
}
// return as we are done handling this command
return;
}

View File

@ -0,0 +1,23 @@
import config from '../../config.ts';
import {
// Discordeno deps
Bot,
// Discordeno deps
Message,
} from '../../deps.ts';
import functions from '../functions/_index.ts';
export const messageUpdate = (bot: Bot, message: Message) => {
// Ignore all other bots
if (message.isFromBot) return;
// Ignore all messages that are not commands
if (message.content.indexOf(config.prefix) !== 0) {
if (config.pollChannels.includes(message.channelId)) {
functions.pollReactions(bot, message, true);
}
// return as we are done handling this command
return;
}
};

View File

@ -1 +1,5 @@
export default {};
import { pollReactions } from "./pollReactions.ts";
export default {
pollReactions,
};

View File

@ -0,0 +1,42 @@
import {
// Discordeno deps
Bot,
// Discordeno deps
Message,
} from '../../deps.ts';
import utils from '../utils.ts';
export const pollReactions = async (bot: Bot, message: Message, update = false) => {
if (message.content.toLowerCase().includes('clan poll')) {
// Emoji RegExp
const unicodeEmojis = '(\\p{Emoji_Presentation}|\\p{Extended_Pictographic})';
const unicodeEmojiRX = `(${unicodeEmojis}(\u200d${unicodeEmojis})*)`;
const discordEmojiRX = '(:[a-zA-Z\\d_]+:\\d+)';
const allEmojiRX = new RegExp(`${unicodeEmojiRX}|${discordEmojiRX}`, 'gu');
// Get list of emojis in message
const allEmojis = message.content.match(allEmojiRX) || [];
// If message was edited
if (update) {
// Get message to get reactions from it
const pollMsg = await bot.helpers.getMessage(message.channelId, message.id).catch((e: Error) => utils.commonLoggers.messageGetError('pollReactions.ts:23', message, e));
// If there are reactions, determine if we need to remove any
if (pollMsg?.reactions?.length) {
for (const reaction of pollMsg.reactions) {
if (reaction.emoji.name) {
// Make emoji name that matches our allEmojis array format
const emojiName = reaction.emoji.id ? `:${reaction.emoji.name}:${reaction.emoji.id}` : reaction.emoji.name;
if (!allEmojis.includes(emojiName)) {
bot.helpers.deleteReaction(message.channelId, message.id, emojiName).catch((e: Error) => utils.commonLoggers.reactionDeleteError('pollReactions.ts:32', message, e, emojiName));
}
}
}
}
}
// Finally, add all reactions to the message
bot.helpers.addReactions(message.channelId, message.id, allEmojis, true).catch((e: Error) => utils.commonLoggers.reactionAddError('pollReactions.ts:40', message, e, allEmojis.toString()));
}
};

View File

@ -19,18 +19,27 @@ const jsonStringifyBig = (input: any) => {
const genericLogger = (level: LT, message: string) => log(level, message);
const messageEditError = (location: string, message: Message | string, err: Error) =>
genericLogger(LT.ERROR, `${location} | Failed to edit message: ${jsonStringifyBig(message)} | Error: ${err.name} - ${err.message}`);
const messageGetError = (location: string, message: Message | string, err: Error) =>
genericLogger(LT.ERROR, `${location} | Failed to get message: ${jsonStringifyBig(message)} | Error: ${err.name} - ${err.message}`);
const messageSendError = (location: string, message: Message | string, err: Error) =>
genericLogger(LT.ERROR, `${location} | Failed to send message: ${jsonStringifyBig(message)} | Error: ${err.name} - ${err.message}`);
const messageDeleteError = (location: string, message: Message | string, err: Error) =>
genericLogger(LT.ERROR, `${location} | Failed to delete message: ${jsonStringifyBig(message)} | Error: ${err.name} - ${err.message}`);
const reactionAddError = (location: string, message: Message | string, err: Error, emoji: string) =>
genericLogger(LT.ERROR, `${location} | Failed to add emoji (${emoji}) to message: ${jsonStringifyBig(message)} | Error: ${err.name} - ${err.message}`);
const reactionDeleteError = (location: string, message: Message | string, err: Error, emoji: string) =>
genericLogger(LT.ERROR, `${location} | Failed to delete emoji (${emoji}) from message: ${jsonStringifyBig(message)} | Error: ${err.name} - ${err.message}`);
const dbError = (location: string, type: string, err: Error) => genericLogger(LT.ERROR, `${location} | Failed to ${type} database | Error: ${err.name} - ${err.message}`);
export default {
commonLoggers: {
dbError,
messageGetError,
messageEditError,
messageSendError,
messageDeleteError,
reactionAddError,
reactionDeleteError,
},
jsonStringifyBig,
};