Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions .eslintignore
Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,7 @@ commands/lockdown.js
commands/manualVerify.js
commands/manualVetVerify.js
commands/memes.js
commands/modmail.js
commands/modmailBlacklist.js
commands/modmailClose.js
commands/modmailRespond.js
commands/mute.js
commands/mutes.js
commands/noNicknames.js
Expand Down
3 changes: 1 addition & 2 deletions botSetup.js
Original file line number Diff line number Diff line change
Expand Up @@ -127,10 +127,9 @@ async function setup(bot) {

// initialize components (eg. modmail, verification)
iterServers(bot, (bot, g) => {
vibotChannels.update(g, bot).catch(er => { });
const db = dbSetup.getDB(g.id);
vibotChannels.update(g, bot, db).catch(er => { });
afkCheck.loadBotAfkChecks(g, bot, db);
// if (bot.settings[g.id].backend.modmail) modmail.init(g, bot, db).catch(er => { ErrorLogger.log(er, bot, g); })
if (bot.settings[g.id].backend.verification) verification.init(g, bot, db).catch(er => { ErrorLogger.log(er, bot, g); });
if (bot.settings[g.id].backend.vetverification) vetVerification.init(g, bot, db).catch(er => { ErrorLogger.log(er, bot, g); });
});
Expand Down
335 changes: 0 additions & 335 deletions commands/modmail.js

This file was deleted.

31 changes: 0 additions & 31 deletions commands/modmailClose.js

This file was deleted.

98 changes: 40 additions & 58 deletions commands/modmailRespond.js
Original file line number Diff line number Diff line change
@@ -1,68 +1,50 @@
const Discord = require('discord.js')
const moment = require('moment')
const { EmbedBuilder, Colors } = require('discord.js');
const { Modmail } = require('../lib/modmail.js');

module.exports = {
name: 'modmailrespond',
alias: ['mmr'],
role: 'security',
args: '<id>',
requiredArgs: 1,
/**
* @param {import('discord.js').Message} message
* @param {string[]} args
* @param {import('discord.js').Client} bot
* @param {import('mysql2').Pool} db
*/
async execute(message, args, bot, db) {
let settings = bot.settings[message.guild.id]
if (!settings.backend.modmail) {
messsage.reply(`Modmail is disabled in this server.`)
return
}
if (message.channel.id !== settings.channels.modmail) return
if (!args[0]) return
let m = await message.channel.messages.fetch(args[0])
if (!m) return message.channel.send(`Could not find message with ID of \`${args[0]}\``)
let embed = new Discord.EmbedBuilder()
embed.data = m.embeds[0].data;
let raider;
if (!raider)
try {
raider = message.guild.members.cache.get(embed.data.footer.text.split(/ +/g)[2]);
if (!raider)
raider = await message.guild.members.fetch({ user: embed.data.footer.text.split(/ +/g)[2], force: true });
} catch (e) { return message.channel.send(`User is not currently in the server.`); }
if (!raider)
return message.channel.send(`User is not currently in the server.`);
let dms = await raider.user.createDM()
const settings = bot.settings[message.guild.id];

function checkInServer() {
const result = message.guild.members.cache.get(dms.recipient.id);
if (!result)
message.channel.send(`User ${dms.recipient} is no longer in the server.`);
return result;
}
const embed = new EmbedBuilder()
.setTitle('Modmail Respond')
.setAuthor({ name: message.member.displayName, iconURL: message.member.displayAvatarURL() })
.setColor(Colors.Red)
.setTimestamp();

let originalMessage = embed.data.description;
// originalMessage = originalMessage.substring(originalMessage.indexOf(':') + 3, originalMessage.length - 1)
let responseEmbed = new Discord.EmbedBuilder()
.setDescription(`__How would you like to respond to ${raider}'s [message](${m.url})__\n${originalMessage}`)
let responseEmbedMessage = await message.channel.send({ embeds: [responseEmbed] })
let responseCollector = new Discord.MessageCollector(message.channel,{filter: m => m.author.id === message.author.id})
responseCollector.on('collect', async function (mes) {
let response = mes.content.trim()
if (response == '') return mes.channel.send(`Invalid response. Please provide text. If you attached an image, please copy the URL and send that`)
responseCollector.stop()
await mes.delete()
if (!checkInServer())
return responseEmbedMessage.delete();
responseEmbed.setDescription(`__Are you sure you want to respond with the following?__\n${response}`)
await responseEmbedMessage.edit({ embeds: [responseEmbed] }).then(async confirmMessage => {
if (await confirmMessage.confirmButton(message.author.id)) {
if (!checkInServer())
return responseEmbedMessage.delete();
await dms.send(response)
responseEmbedMessage.delete()
embed.addFields([{ name: `Response by ${message.member.displayName} <t:${moment().unix()}:R>:`, value: response }])
m.edit({ embeds: [embed] })
} else {
await responseEmbedMessage.delete()
}
})
})
message.delete()
if (!settings.backend.modmail) return await message.reply({ embeds: [embed.setDescription('Modmail is disabled in this server.')] });
if (message.channel.id !== settings.channels.modmail) return await message.reply({ embeds: [embed.setDescription('This is not the modmail channel.')] });
/** @type {Discord.Message} */
const modmailMessage = await message.channel.messages.fetch(args[0]);
if (!modmailMessage) return await message.reply({ embeds: [embed.setDescription(`Could not find message with ID of \`${args[0]}\``)] });
const modmailEmbed = EmbedBuilder.from(modmailMessage.embeds[0]);

const raiderId = modmailEmbed.data.footer.text.split(/ +/g)[2];
const raider = await message.guild.members.fetch({ user: raiderId, force: true });
if (!raider) return await message.reply({ embeds: [embed.setDescription(`User <@!${raiderId}> is no longer in the server.`)] });

const dms = await raider.user.createDM();
if (!dms) return await message.reply({ embeds: [embed.setDescription(`Cannot send messages to ${raider}.`)] });

message.message = message;
const dummyInteraction = {
message: modmailMessage,
member: message.member,
guild: message.guild,
channel: message.channel,
reply: message.reply.bind(message)
};
await Modmail.send({ settings, interaction: dummyInteraction, embed: modmailEmbed, raider, db, bot });
message.delete();
}
}
};
23 changes: 1 addition & 22 deletions commands/vibotChannels.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ const fs = require('fs')
const botSettings = require('../settings.json')
const ErrorLogger = require('../lib/logError')
const vibotChannel = require('./vibotChannels.js')
const modmail = require('./modmail.js')
const modmail = require('../lib/modmail.js')
const roleassignment = require('./roleAssignment.js')
var watchedMessages = []
var watchedButtons = {}; //the keys for this are the id of a VC
Expand All @@ -25,26 +25,7 @@ module.exports = {
},
async update(guild, bot, db) {
let settings = bot.settings[guild.id]
await updateModmailListeners(guild.channels.cache.get(settings.channels.modmail), settings, bot, db)
await updateRoleAssignmentListeners(guild.channels.cache.get(settings.channels.roleassignment), settings, bot, db)
async function updateModmailListeners(modmailChannel, settings, bot, db) {
if (!modmailChannel) { return } // If there is no modmail channel it will not continue
let modmailChannelMessages = await modmailChannel.messages.fetch() // This fetches all the messages in the modmail channel
modmailChannelMessages.each(async modmailMessage => { // This will loop through the modmail channel messages
if (modmailMessage.author.id !== bot.user.id) return; // If the modmail message author is not the same id as ViBot it will not continue with this message
if (modmailMessage.embeds.length == 0) return; // If the message has no embeds it will not continue
let embed = new Discord.EmbedBuilder() // This creates a empty embed, able to be edited later
embed.data = modmailMessage.embeds[0].data // This will change the empty embed to have the modmailMessage embed data

/* We have a message -> check if it has no components
**EXPLANATION** When the modmail is done, its not supposed to have any components.
If it has any components at all, we will revert them to the basic "unlock" modmail
*/
if (modmailMessage.components == 0) { return }
// Anything below this code inside this function is for open modmails, and we need to reset them
module.exports.addModmailUnlockButton(modmailMessage, settings, bot, db) // This will add a modmail "unlock" button to the modmailMessage
})
}
async function updateRoleAssignmentListeners(roleassignmentChannel, settings, bot, db) {
if (!settings.backend.roleassignment) return;
if (!roleassignmentChannel) { return } // If there is no roleassignment channel it will not continue
Expand Down Expand Up @@ -146,8 +127,6 @@ module.exports = {
.setCustomId('modmailUnlock'))
message = await message.edit({ components: [components] })
}
modmailInteractionCollector = new Discord.InteractionCollector(bot, { message: message, interactionType: Discord.InteractionType.MessageComponent, componentType: Discord.ComponentType.Button })
modmailInteractionCollector.on('collect', (interaction) => modmail.interactionHandler(interaction, settings, bot, db))
},

async addCloseChannelButtons(bot, m, rsaMessage) {
Expand Down
11 changes: 9 additions & 2 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const dbSetup = require('./dbSetup.js');
const memberHandler = require('./memberHandler.js');
const { logWrapper } = require('./metrics.js');
const { handleReactionRow } = require('./redis.js');

const Modmail = require('./lib/modmail.js');
// Specific Commands
const verification = require('./commands/verification');

Expand Down Expand Up @@ -51,7 +51,14 @@ bot.on('interactionCreate', logWrapper('message', async (logger, interaction) =>
// Validate the interaction is a command
if (interaction.isChatInputCommand()) return await messageManager.handleCommand(interaction, true);
if (interaction.isUserContextMenuCommand()) return await messageManager.handleCommand(interaction, true);
if (interaction.isButton()) return await handleReactionRow(bot, interaction);
if (interaction.isButton()) {
if (interaction.customId.startsWith('modmail')) {
const settings = bot.settings[interaction.guild.id];
const db = dbSetup.getDB(interaction.guild.id);
return await Modmail.interactionHandler(interaction, settings, bot, db);
}
return await handleReactionRow(bot, interaction);
}
}));

bot.on('ready', async () => {
Expand Down
25 changes: 10 additions & 15 deletions lib/extensions.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,38 +51,33 @@ Promise.wait = Promise.wait || function Wait(time) {
* @param {string?} requirementMessage Message to provide when filter fails
* @param {Discord.Snowflake?} author_id Id of the user to watch for. If not provided, will accept any message that isn't from a bot user.
*/
Discord.BaseChannel.prototype.next = function Next(filter, requirementMessage, author_id) {
Discord.TextChannel.prototype.next = function Next(filter, requirementMessage, author_id) {
return new Promise((resolve, reject) => {
const collector = this.createMessageCollector({ filter: (message) => !message.author.bot && (author_id ? message.author.id == author_id : true), time: MAX_WAIT });
let resolved = false;
let error;
collector.on('collect', async (message) => {
resolved = true;
if (message.deletable) await message.delete();
if (error?.deletable) error.then(err => err.delete());

if (message.content.toLowerCase() === 'cancel') {
collector.stop();
reject('Manually cancelled.');
message.error = 'manually cancelled';
reject(message);
return;
}

if (error)
error.then(err => err.delete());

let result = message;
if (message.deletable)
result = await message.delete();
if (filter && !filter(result)) {
if (filter && !filter(message)) {
resolved = false;
error = message.channel.send(`${result.content} is not a valid input.\r\n${requirementMessage}\r\nType cancel to cancel.`)
error = message.channel.send(`${message.content} is not a valid input.\r\n${requirementMessage}\r\nType cancel to cancel.`)
return;
}
collector.stop();
resolve(result);
resolve(message);
})
collector.on('end', () => {
const err = 'timed out';
err.stack = new Error().stack;
if (!resolved)
reject(err)
if (!resolved) reject({ error: 'timed out' })
});
});
};
Expand Down
14 changes: 7 additions & 7 deletions lib/logCommand.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
const Discord = require('discord.js')
const loggingInfo = require('../data/loggingInfo.json');

const { developerId } = require('../settings.json')
module.exports = {
async log(message, bot) {
if (!bot) return
let guildHub = bot.guilds.cache.get(loggingInfo.info.guildid);
let vi = bot.users.fetch(loggingInfo.info.vi)
const developer = await bot.users.fetch(developerId)
if (!guildHub) {
console.log("ViBot Info not found. ``logCommand.js``")
await vi.send("ViBot Info not found. ``logCommand.js``")
await developer?.send("ViBot Info not found. ``logCommand.js``")
return
}
let channel = guildHub.channels.cache.get(loggingInfo[message.guild.id].channelCommand)
if (!channel) channel = guildHub.channels.cache.get(loggingInfo.info.channelCommand)
if (!channel) {
console.log("ViBot Info Channel not found. ``logCommand.js``")
await vi.send("ViBot Info Channel not found. ``logCommand.js``")
await developer?.send("ViBot Info Channel not found. ``logCommand.js``")
return
}
let embed = new Discord.EmbedBuilder()
Expand All @@ -33,17 +33,17 @@ module.exports = {
async logInteractionCommand(interaction, bot) {
if (!bot) return
let guildHub = bot.guilds.cache.get(loggingInfo.info.guildid);
let vi = bot.users.fetch(loggingInfo.info.vi)
let developer = await bot.users.fetch(developerId)
if (!guildHub) {
console.log("ViBot Info not found. ``logCommand.js``")
await vi.send("ViBot Info not found. ``logCommand.js``")
await developer?.send("ViBot Info not found. ``logCommand.js``")
return
}
let channel = guildHub.channels.cache.get(loggingInfo[interaction.guild.id].channelCommand)
if (!channel) channel = guildHub.channels.cache.get(loggingInfo.info.channelCommand)
if (!channel) {
console.log("ViBot Info Channel not found. ``logCommand.js``")
await vi.send("ViBot Info Channel not found. ``logCommand.js``")
await developer?.send("ViBot Info Channel not found. ``logCommand.js``")
return
}
let embed = new Discord.EmbedBuilder()
Expand Down
Loading