diff --git a/.gitignore b/.gitignore index 622a87b..b4e6f9f 100644 --- a/.gitignore +++ b/.gitignore @@ -62,3 +62,5 @@ typings/ # next.js build output .next + +.gitignore diff --git a/README.md b/README.md index 8735be9..ec2eb19 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ Supports message delete, update, lock command... - lock all - Lock all channels in the network: `c!lock all` - unlock - Unlock the current channel: `c!unlock` - unlock all - Unlock all channels: `c!unlock all` - - commands are usable by poeple with roles in managerRoles only. + - commands are usable by poeple that have one of the roles in the `managerRoles` field in the config. ## Setup @@ -28,7 +28,7 @@ Clone this repository. Run `npm install` or `yarn`. Copy and paste `config.template.json` as `config.json`. -Enter your bot token and all correct informations: +Enter your bot token and all correct information: ```js { @@ -41,8 +41,8 @@ Enter your bot token and all correct informations: }, "messageDelete": true, "deleteOnUpdate": true, - "guilds": { - "youGuildName": { + "guilds": [ + { "name": "name", "identifier": "", "guildID": "111111", @@ -53,7 +53,7 @@ Enter your bot token and all correct informations: "ignoreBots": true, "managerRoles": [] }, - "otherGuildName": { + { "name": "name", "identifier": "", "guildID": "444444", @@ -64,7 +64,7 @@ Enter your bot token and all correct informations: "ignoreBots": true, "managerRoles": [] } - } + ] } ``` diff --git a/config.template.json b/config.template.json index e6c0fec..1f632c6 100644 --- a/config.template.json +++ b/config.template.json @@ -5,9 +5,7 @@ "role": false, "channel": false }, - "prefix": "c!", - "messageDelete": true, - "deleteOnUpdate": true, + "guilds": [ { "name": "name", @@ -18,7 +16,6 @@ "whToken": "", "ignoreAll": false, "ignoreBots": true, - "managerRoles": [] }, { "name": "name2", @@ -29,7 +26,6 @@ "whToken": "", "ignoreAll": false, "ignoreBots": true, - "managerRoles": [] } ] } diff --git a/index.js b/index.js index 02d1e34..4277373 100644 --- a/index.js +++ b/index.js @@ -4,15 +4,9 @@ const config = require('./config.json'); const { bot } = require('./src/bot'); const { setup } = require('./src/index'); -function formatDate() { - const date = new Date(); - - return `${date.getFullYear()}/${date.getMonth() + 1}/${date.getDate()} - ${date.getHours()}:${date.getMinutes()}`; -} - setup(bot, config); bot.connect(); -bot.on('error', (err) => console.log(`${formatDate()} : ${err.stack || err.message}`) ); -bot.on('warn', (msg) => console.log(`${formatDate()} : ${msg}`) ); +bot.on('error', (err) => console.log(`${err.stack || err.message}`)); +bot.on('warn', (msg) => console.log(`${msg}`)); \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index a5cc53b..8d2bb0f 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "cross-server-bot", - "version": "1.0.0", + "version": "3.0.0", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -936,9 +936,9 @@ }, "dependencies": { "ws": { - "version": "7.2.5", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.2.5.tgz", - "integrity": "sha512-C34cIU4+DB2vMyAbmEKossWq2ZQDr6QEyuuCzWrM9zfw1sGc0mYiJ0UnG9zzNykt49C2Fi34hvr2vssFQRS6EA==" + "version": "7.3.1", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.3.1.tgz", + "integrity": "sha512-D3RuNkynyHmEJIpD2qrgVkc9DQ23OrN/moAwZX4L8DfvszsJxpjQuUq3LMx6HoYji9fbIOBY18XWBsAux1ZZUA==" } } }, @@ -2539,9 +2539,9 @@ } }, "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + "version": "4.17.19", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.19.tgz", + "integrity": "sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ==" }, "lodash.findindex": { "version": "4.6.0", diff --git a/src/Resolver.js b/src/Resolver.js index b236443..3c8850f 100644 --- a/src/Resolver.js +++ b/src/Resolver.js @@ -29,7 +29,7 @@ class Resolver { throw new Error('RESOLVER [user]: All the arguments are either not given or false.'); } // Checking if args is an array, if it is not, converting it to an array. - if (!Array.isArray(args) ) { + if (!Array.isArray(args)) { args = `${args}`.split(' '); } @@ -37,15 +37,15 @@ class Resolver { args.lower = args.all.toLowerCase(); const { users } = client; - const mention = REGEXES.userMention.exec(args[0] ); + const mention = REGEXES.userMention.exec(args[0]); - const user = ( (mention && mention[1] ) && users.get(mention[1] ) ) // User mention - || (REGEXES.id.test(args[0] ) && users.get(args[0] ) ) // User ID - || (args.all.indexOf('#') > -1 && users.find(u => `${u.username}#${u.discriminator}` === args.all) ) // Username + discrim + const user = ((mention && mention[1] ) && users.get(mention[1])) // User mention + || (REGEXES.id.test(args[0]) && users.get(args[0])) // User ID + || (args.all.indexOf('#') > -1 && users.find(u => `${u.username}#${u.discriminator}` === args.all)) // Username + discrim || users.find(u => u.username === args.all) // Username || users.find(u => u.username.toLowerCase() === args.lower) // Username lowercase - || users.find(u => u.username.includes(args.all) ) // Username includes - || users.find(u => u.username.toLowerCase().includes(args.lower) ) // Username lowercase includes + || users.find(u => u.username.includes(args.all)) // Username includes + || users.find(u => u.username.toLowerCase().includes(args.lower)) // Username lowercase includes || null;// No users found return user; // Return the user object. @@ -63,7 +63,7 @@ class Resolver { throw new Error('RESOLVER [member]: All the arguments are either not given or false.'); } // Checking if args is an array, if it is not, converting it to an array. - if (!Array.isArray(args) ) { + if (!Array.isArray(args)) { args = `${args}`.split(' '); } @@ -73,17 +73,17 @@ class Resolver { const mention = REGEXES.userMention.exec(args[0] ); - const member = ( (mention && mention[1] ) && members.get(mention[1] ) ) // User mention - || (REGEXES.id.test(args[0] ) && members.get(args[0] ) ) // User ID - || (args.all.indexOf('#') > -1 && members.find(m => `${m.username}#${m.discriminator}` === args.all) ) // Username + discrim + const member = ((mention && mention[1]) && members.get(mention[1])) // User mention + || (REGEXES.id.test(args[0]) && members.get(args[0])) // User ID + || (args.all.indexOf('#') > -1 && members.find(m => `${m.username}#${m.discriminator}` === args.all)) // Username + discrim || members.find(m => m.username === args.all) // Username || members.find(m => m.nick === args.all) // nickname || members.find(m => m.username.toLowerCase() === args.lower) // Username lowercase || members.find(m => m.nick && m.nick.toLowerCase() === args.lower) // nickname lowercase // members.find(m => m.username.includes(args.all) ) || // Username includes // members.find(m => m.nick && m.nick.includes(args.all) ) || // nickname includes - || members.find(m => m.username.toLowerCase().includes(args.lower) ) // username lowercase includes - || members.find(m => m.nick && m.nick.toLowerCase().includes(args.lower) ) // nickname lowercase includes + || members.find(m => m.username.toLowerCase().includes(args.lower)) // username lowercase includes + || members.find(m => m.nick && m.nick.toLowerCase().includes(args.lower)) // nickname lowercase includes || null; // No member found return member; // Return the member object. @@ -103,7 +103,7 @@ class Resolver { } // Checking if args is an array, if it is not, converting it to an array. - if (!Array.isArray(args) ) { + if (!Array.isArray(args)) { args = `${args}`.split(' '); } @@ -111,14 +111,14 @@ class Resolver { args.lower = args.all.toLowerCase(); const { roles } = guild; - const mention = REGEXES.roleMention.exec(args[0] ); + const mention = REGEXES.roleMention.exec(args[0]); - const role = ( (mention && mention[1] ) && roles.get(mention[1] ) ) // mention - || (REGEXES.id.test(args[0] ) && roles.get(args[0] ) ) // id + const role = ((mention && mention[1]) && roles.get(mention[1])) // mention + || (REGEXES.id.test(args[0]) && roles.get(args[0])) // id || roles.find(m => m.name === args.all) // name || roles.find(m => m.name.toLowerCase() === args.lower) // name lower - || roles.find(m => m.name.includes(args.all) ) // name includes - || roles.find(m => m.name.toLowerCase().includes(args.lower) ) // name loxer includes + || roles.find(m => m.name.includes(args.all)) // name includes + || roles.find(m => m.name.toLowerCase().includes(args.lower)) // name loxer includes || null; // no role found return role; @@ -138,7 +138,7 @@ class Resolver { } // Checking if args is an array, if it is not, converting it to an array. - if (!Array.isArray(args) ) { + if (!Array.isArray(args)) { args = `${args}`.split(' '); } @@ -146,14 +146,14 @@ class Resolver { args.lower = args.all.toLowerCase(); const { channels } = guild; - const mention = REGEXES.channelMention.exec(args[0] ); + const mention = REGEXES.channelMention.exec(args[0]); - const channel = ( (mention && mention[1] ) && channels.get(mention[1] ) ) - || (REGEXES.id.test(args[0] ) && channels.get(args[0] ) ) + const channel = ((mention && mention[1]) && channels.get(mention[1])) + || (REGEXES.id.test(args[0]) && channels.get(args[0])) || channels.find(c => c.name === args.all) // name || channels.find(c => c.name.toLowerCase() === args.lower) // name lower - || channels.find(c => c.name.includes(args.all) ) // name includes - || channels.find(c => c.name.toLowerCase().includes(args.lower) ) // name lower includes + || channels.find(c => c.name.includes(args.all)) // name includes + || channels.find(c => c.name.toLowerCase().includes(args.lower)) // name lower includes || null; // no channel found return channel; @@ -176,11 +176,11 @@ class Resolver { args.all = args.join(' '); args.lower = args.all.toLowerCase(); - const guild = (REGEXES.id.test(args[0] ) && guilds.find(g => g.id === args[0] ) ) // ID + const guild = (REGEXES.id.test(args[0]) && guilds.find(g => g.id === args[0])) // ID || guilds.find(g => g.name === args.all) // Name || guilds.find(g => g.name.toLowerCase() === args.lower) // Lowercase name - || guilds.find(g => g.name.includes(args.all) ) // Includes name - || guilds.find(g => g.name.toLowerCase().includes(args.lower) ) // Includes lowercase name + || guilds.find(g => g.name.includes(args.all)) // Includes name + || guilds.find(g => g.name.toLowerCase().includes(args.lower)) // Includes lowercase name || null; return guild; diff --git a/src/bot.js b/src/bot.js index 547f6a2..085796c 100644 --- a/src/bot.js +++ b/src/bot.js @@ -7,6 +7,12 @@ exports.bot = new Client(config.token, { defaultImageFormat: 'png', defaultImageSize: 1024, autoreconnect: true, - messageLimit: 25, + messageLimit: 1000, + getAllUsers: true, + intents: [ + "guilds", + "guildMessages", + "guildMembers", + ], } ); diff --git a/src/commands/index.js b/src/commands/index.js deleted file mode 100644 index e16d5e3..0000000 --- a/src/commands/index.js +++ /dev/null @@ -1,7 +0,0 @@ -'use strict'; - -module.exports = { - purge: require('./purge'), - lock: require('./lock'), - unlock: require('./unlock'), -}; diff --git a/src/commands/lock.js b/src/commands/lock.js deleted file mode 100644 index 46f445e..0000000 --- a/src/commands/lock.js +++ /dev/null @@ -1,29 +0,0 @@ -'use strict'; - -const SEND_PERM = 2048; - -async function lock(bot, channel, roleID) { - try { - const perms = channel.permissionOverwrites.get(roleID); - await bot.editChannelPermission(channel.id, roleID, perms.allow, perms.deny | SEND_PERM); - - bot.createMessage(channel.id, 'Channel locked!').catch(); - } catch (err) { - bot.createMessage(channel.id, 'Permission Error').catch(); - - console.log(`Permission error in ${channel.guild.name}`); - } -} - -module.exports = async(botClient, network, channelsCache, msg, args) => { - if (args[0] === 'all') { - for (const channelID in network) { - const channelConfig = network[channelID]; - const channel = botClient.guilds.get(channelConfig.guildID).channels.get(channelConfig.channelID); - await lock(botClient, channel, channelConfig.guildID); - } - } else { - lock(botClient, msg.channel, msg.channel.guild.id); - } -}; - diff --git a/src/commands/purge.js b/src/commands/purge.js deleted file mode 100644 index 25eff0a..0000000 --- a/src/commands/purge.js +++ /dev/null @@ -1,5 +0,0 @@ -'use strict'; - -module.exports = async(botClient, network, channelsCache, msg, args) => { - -}; diff --git a/src/commands/unlock.js b/src/commands/unlock.js deleted file mode 100644 index 1c0941b..0000000 --- a/src/commands/unlock.js +++ /dev/null @@ -1,29 +0,0 @@ -'use strict'; - -const SEND_PERM = 2048; - -async function unlock(bot, channel, roleID) { - try { - const perms = channel.permissionOverwrites.get(roleID); - await bot.editChannelPermission(channel.id, roleID, perms.allow, perms.deny & ~SEND_PERM); - - bot.createMessage(channel.id, 'Channel locked!').catch(); - } catch (err) { - bot.createMessage(channel.id, 'Permission Error').catch(); - - console.log(`Permission error in ${channel.guild.name}`); - } -} - -module.exports = async(botClient, network, channelsCache, msg, args) => { - if (args[0] === 'all') { - for (const channelID in network) { - const channelConfig = network[channelID]; - const channel = botClient.guilds.get(channelConfig.guildID).channels.get(channelConfig.channelID); - await unlock(botClient, channel, channelConfig.guildID); - } - } else { - unlock(botClient, msg.channel, msg.channel.guild.id); - } -}; - diff --git a/src/enhancedMention.js b/src/enhancedMention.js index fa0d6e3..46b966d 100644 --- a/src/enhancedMention.js +++ b/src/enhancedMention.js @@ -95,14 +95,14 @@ function parse(content, guild) { let resolved = null; if (res[1] === '@') { resolved = ENHANCED_MENTION_CONFIG.role - ? Resolver.role(guild, res[2] ) + ? Resolver.role(guild, res[2]) : null; if (resolved) { return resolved.mention; } resolved = ENHANCED_MENTION_CONFIG.user - ? Resolver.member(guild, res[2] ) + ? Resolver.member(guild, res[2]) : null; if (resolved) { return resolved.mention; @@ -110,7 +110,7 @@ function parse(content, guild) { return content; } if (ENHANCED_MENTION_CONFIG.channel && res[1] === '#') { - resolved = Resolver.channel(guild, res[2] ); + resolved = Resolver.channel(guild, res[2]); return resolved ? resolved.mention : content; @@ -130,7 +130,7 @@ exports.deconstructMention = function (content, guild) { for (const e of contentArr) { const res = e.match(MENTION_REGEX); res - ? final.push(extractMention(res, guild) ) + ? final.push(extractMention(res, guild)) : final.push(e); } return final; diff --git a/src/events/onMessageCreate.js b/src/events/onMessageCreate.js index 4bf302e..a9be86f 100644 --- a/src/events/onMessageCreate.js +++ b/src/events/onMessageCreate.js @@ -3,8 +3,6 @@ const { deconstructMention } = require('../enhancedMention'); const { triggerWH, setInMap, MESSAGE_LIMIT } = require('../utils'); -const commands = require('../commands'); - exports.onMessageCreate = async(botClient, network, channelsCache, msg) => { if (!msg.author || msg.author.discriminator === '0000' || !msg.channel.guild) { return; @@ -19,18 +17,11 @@ exports.onMessageCreate = async(botClient, network, channelsCache, msg) => { return; } - if (msg.content.startsWith(botClient.prefix) && msg.member.roles.some(r => cur.managerRoles.includes(r) ) ) { - const args = msg.content.split(' '); - const label = args[0].slice(botClient.prefix.length, args[0].length); - const command = commands[label]; - command(botClient, network, channelsCache, msg, args.slice(1, args.length) ) - .then( () => console.log(`EXEC: ${label} in ${cur.name} by ${msg.author.username}`) ) - .catch(console.log); - + if (cur.ignore) { // ignore channels if needed return; } - if (cur.ignore) { // ignore channels if needed + if (msg.content.includes("pinned a message to this channel. See all the pins.")) { return; } @@ -41,6 +32,7 @@ exports.onMessageCreate = async(botClient, network, channelsCache, msg) => { const fullLength = `${attachments.join('\n')}\n${msg.content}`.length; const fullMsg = [...attachments, ...deconstructMention(msg.content, msg.channel.guild)]; + if (fullLength > MESSAGE_LIMIT) { msg.channel.createMessage(`${msg.author.mention}: Message too long!`); return; @@ -52,7 +44,7 @@ exports.onMessageCreate = async(botClient, network, channelsCache, msg) => { if (channelConfig.channelID === msg.channel.id) { continue; } - messages.push(await triggerWH(botClient, network, channelConfig, cur, msg.author, fullMsg) ); + messages.push(await triggerWH(botClient, network, channelConfig, cur, msg.author, msg.member, fullMsg)); } setInMap(channelsCache[msg.channel.id], msg.id, messages); }; diff --git a/src/events/onMessageDelete.js b/src/events/onMessageDelete.js index e315b44..7b3fd24 100644 --- a/src/events/onMessageDelete.js +++ b/src/events/onMessageDelete.js @@ -1,5 +1,7 @@ 'use strict'; +const { triggerWHDelete } = require('../utils'); + exports.onMessageDelete = async(botClient, network, channelsCache, msg) => { if (!msg.author || msg.author.discriminator === '0000' || !msg.channel.guild) { return; @@ -19,8 +21,9 @@ exports.onMessageDelete = async(botClient, network, channelsCache, msg) => { } const messages = channelsCache[msg.channel.id].get(msg.id); - for (const m of messages) { - m.delete().catch(); + for (const [i, message] of messages.entries()) { + const channelConfig = network[message.channel.id]; + messages[i] = await triggerWHDelete(botClient, network, channelConfig, message.id); } channelsCache[msg.channel.id].delete(msg.id); }; diff --git a/src/events/onMessageUpdate.js b/src/events/onMessageUpdate.js index a8d2f41..3fced7c 100644 --- a/src/events/onMessageUpdate.js +++ b/src/events/onMessageUpdate.js @@ -1,9 +1,9 @@ 'use strict'; const { deconstructMention } = require('../enhancedMention'); -const { triggerWH, setInMap, MESSAGE_LIMIT } = require('../utils'); +const { triggerWHEdit, setInMap, MESSAGE_LIMIT } = require('../utils'); -exports.onMessageUpdate = async(botClient, network, channelsCache, deleteOnUpdate, msg, oldMsg) => { +exports.onMessageUpdate = async(botClient, network, channelsCache, msg, oldMsg) => { // !oldMsg = message not cached = don't log the update if (!msg.author || msg.author.bot || !msg.channel.guild || !oldMsg) { return; @@ -21,29 +21,20 @@ exports.onMessageUpdate = async(botClient, network, channelsCache, deleteOnUpdat const attachments = msg.attachments.length > 0 ? msg.attachments.map(a => a.url) : []; - - msg.content += ' *(edited)*'; - + const fullLength = `${attachments.join('\n')}\n${msg.content}`.length; const fullMsg = [...attachments, ...deconstructMention(msg.content, msg.channel.guild)]; + if (fullLength > MESSAGE_LIMIT) { msg.channel.createMessage(`${msg.author.mention}: Message too long!`); return; } - const messages = []; - for (const channelID in network) { - const channelConfig = network[channelID]; - if (channelConfig.channelID === msg.channel.id) { - continue; - } - messages.push(await triggerWH(botClient, network, channelConfig, cur, msg.author, fullMsg) ); - } - if (deleteOnUpdate) { - const toDelete = channelsCache[msg.channel.id].get(msg.id); - for (const m of toDelete) { - m.delete().catch(); - } + + const messages = channelsCache[msg.channel.id].get(msg.id); + for (const [i, message] of messages.entries()) { + const channelConfig = network[message.channel.id]; + messages[i] = await triggerWHEdit(botClient, network, channelConfig, cur, msg.author, msg.member, fullMsg, message.id); } setInMap(channelsCache[msg.channel.id], msg.id, messages); }; diff --git a/src/index.js b/src/index.js index 011b28c..61f9b09 100644 --- a/src/index.js +++ b/src/index.js @@ -20,20 +20,21 @@ exports.setup = function (bot, config) { } else { network[val.channelID] = val; channelsCache[val.channelID] = new Map(); - + + /* + var date = new Date(); + bot.executeWebhook(val.whID, val.whToken, { username: bot.user.username, avatarURL: bot.user.avatarURL, - content: 'Bot Ready - Cross Server system operational!', + content: 'Bot started. It is: ' + date.toISOString(), } ); + */ } } } ); - bot.on('messageCreate', (msg) => onMessageCreate(bot, network, channelsCache, msg) ); - bot.on('messageUpdate', (msg, oldMsg) => onMessageUpdate(bot, network, channelsCache, config.deleteOnUpdate, msg, oldMsg) ); - - if (config.messageDelete) { - bot.on('messageDelete', (msg) => onMessageDelete(bot, network, channelsCache, msg) ); - } + bot.on('messageCreate', (msg) => onMessageCreate(bot, network, channelsCache, msg)); + bot.on('messageUpdate', (msg, oldMsg) => onMessageUpdate(bot, network, channelsCache, msg, oldMsg)); + bot.on('messageDelete', (msg) => onMessageDelete(bot, network, channelsCache, msg)); }; diff --git a/src/utils.js b/src/utils.js index f624ba7..cc3fc03 100644 --- a/src/utils.js +++ b/src/utils.js @@ -2,43 +2,16 @@ const { enhanceMention } = require('./enhancedMention'); - -// const FILTER_USERNAME_REGEX = /[A-Za-z0-9_!? -,.éè]*/g; -// const AUTHOR_MAX = 32; - exports.MESSAGE_LIMIT = 2000; -const LIMIT = 30; - - -/** - * Sanitize username in order to have discord supported webhook username. - * Discord now should allow any username to be usable in webhooks. - * - * @param {*} username - * @returns - */ -function filterUsername(username) { - return username; - // let usr = username.match(FILTER_USERNAME_REGEX).join(''); - // if (usr.length < 2) { - // for (let i = 0; i < 2 - usr.length; i++) { - // usr = `${usr}a`; - // } - // return usr; - // } - // if (usr.length > AUTHOR_MAX) { - // return usr.slice(0, AUTHOR_MAX); - // } - // return usr; -} +const CACHELIMIT = 1000; -exports.triggerWH = async function (bot, network, channelConfig, originConfig, user, content) { +exports.triggerWH = async function (bot, network, channelConfig, originConfig, user, member, content) { const guildObj = bot.guilds.get(channelConfig.guildID); let message = null; try { - const username = filterUsername(user.username); + const authorName = member.nick ? member.nick : user.username; message = await bot.executeWebhook(channelConfig.whID, channelConfig.whToken, { - username: `${originConfig.identifier}${username}#${user.discriminator}`, + username: `${authorName} from ${originConfig.name}`, avatarURL: user.avatarURL, content: enhanceMention(content, guildObj), wait: true, @@ -46,7 +19,7 @@ exports.triggerWH = async function (bot, network, channelConfig, originConfig, u } ); } catch (err) { const errMsg = guildObj - ? `WebHook unavailable in ${guildObj.name}.` + ? `\`The last message failed to go through to ${guildObj.name}. It might be the bot's fault, or Discord being buggy.\`` : `Guild unavailable: ${channelConfig.guildID}.`; console.log(errMsg); @@ -61,7 +34,7 @@ exports.triggerWH = async function (bot, network, channelConfig, originConfig, u username: bot.user.username, avatarURL: bot.user.avatarURL, content: errMsg, - } ); + }); } catch (_) { // Do nothing since it would already be handled by another triggerWH } @@ -70,12 +43,81 @@ exports.triggerWH = async function (bot, network, channelConfig, originConfig, u return message; }; +exports.triggerWHEdit = async function (bot, network, channelConfig, originConfig, user, member, content, messageID) { + const guildObj = bot.guilds.get(channelConfig.guildID); + let message = null; + try { + const authorName = member.nick ? member.nick : user.username; + message = await bot.webhookEditMessage(channelConfig.whID, channelConfig.whToken, messageID, { + username: `${authorName} from ${originConfig.name}`, + avatarURL: user.avatarURL, + content: enhanceMention(content, guildObj), + wait: true, + auth: true, + } ); + } catch (err) { + const errMsg = guildObj + ? `\`The last edit failed to go through to ${guildObj.name}. It might be the bot's fault, or Discord being buggy.\`` + : `Guild unavailable: ${channelConfig.guildID}.`; + + console.log(errMsg); + console.log(err); + + for (const c in network) { + if (network[c].guildID === channelConfig.guildID) { + continue; + } + try { + await bot.executeWebhook(network[c].whID, network[c].whToken, { + username: bot.user.username, + avatarURL: bot.user.avatarURL, + content: errMsg, + }); + } catch (_) { + // Do nothing since it would already be handled by another triggerWH + } + } + } + return message; +}; + +exports.triggerWHDelete = async function (bot, network, channelConfig, messageID) { + const guildObj = bot.guilds.get(channelConfig.guildID); + let result = null; + try { + result = await bot.webhookDeleteMessage(channelConfig.whID, channelConfig.whToken, messageID); + } catch (err) { + const errMsg = guildObj + ? `\`The last delete failed to go through to ${guildObj.name}. It might be the bot's fault, or Discord being buggy.\`` + : `Guild unavailable: ${channelConfig.guildID}.`; + + console.log(errMsg); + console.log(err); + + for (const c in network) { + if (network[c].guildID === channelConfig.guildID) { + continue; + } + try { + await bot.executeWebhook(network[c].whID, network[c].whToken, { + username: bot.user.username, + avatarURL: bot.user.avatarURL, + content: errMsg, + }); + } catch (_) { + // Do nothing since it would already be handled by another triggerWH + } + } + } + return result; +}; + exports.setInMap = function (map, key, value) { map.set(key, value); - if (map.size > LIMIT) { + if (map.size > CACHELIMIT) { const iter = map.keys(); - while (map.size > LIMIT) { + while (map.size > CACHELIMIT) { map.delete(iter.next().value); } }