Haha-Yes/events/client/messageCreate.js

472 lines
15 KiB
JavaScript
Raw Normal View History

2022-08-28 17:04:31 +02:00
/* TODO:
* Make this shit work.
*/
2022-11-24 21:11:53 +01:00
import { ApplicationCommandOptionType, EmbedBuilder, PermissionFlagsBits } from 'discord.js';
2022-08-28 17:04:31 +02:00
import db from '../../models/index.js';
import { rand } from '../../utils/rand.js';
2022-12-18 23:30:25 +01:00
import ratelimiter from '../../utils/ratelimiter.js';
2022-08-28 17:04:31 +02:00
const { ownerId, prefix } = process.env;
const prefixs = prefix.split(',');
export default {
name: 'messageCreate',
async execute(message, client) {
if (message.partials) {
await message.fetch();
}
if (message.author.bot) return;
/* Autoresponse feature & tag
*
* This section contains autoresponse and tag feature
*
*/
// auto responses
if (message.guild) {
const autoresponseStat = await db.autoresponseStat.findOne({ where: { serverID: message.guild.id, stat: 'enable' } });
if (autoresponseStat) {
// Infinite haha very yes
if (message.content.toLowerCase().startsWith('haha very') && message.content.toLowerCase().endsWith('yes')) {
let yes = message.content.toLowerCase().replace('haha', '');
yes = yes.replace('yes', '');
yes += 'very';
return message.channel.send(`haha${yes} yes`);
}
else if (message.content.toLowerCase() == 'haha yes') {
return message.channel.send('haha very yes');
}
// Reply with images as attachement
const autoresponse = await db.autoresponse.findOne({ where: { trigger: message.content.toLowerCase() } });
if (autoresponse) {
db.autoresponse.findOne({ where: { trigger: message.content.toLowerCase() } });
const trigger = autoresponse.get('trigger');
const type = autoresponse.get('type');
const content = autoresponse.get('response');
if (trigger == message.content.toLowerCase() && type == 'text') {
return message.channel.send(content);
}
else if (trigger == message.content.toLowerCase() && type == 'react') {
return message.react(content);
}
else if (trigger == message.content.toLowerCase() && type == 'image') {
return message.channel.send({ files: [content] });
}
}
}
// User autoresponse
const tag = await db.Tag.findOne({ where: { trigger: message.content.toLowerCase(), serverID: message.guild.id } });
if (tag) {
db.Tag.findOne({ where: { trigger: message.content.toLowerCase(), serverID: message.guild.id } });
let text = tag.get('response');
2023-04-04 19:51:36 +02:00
/*
2022-08-28 17:04:31 +02:00
if (text.includes('[ban]')) {
message.member.ban('Tag ban :^)');
}
else if (text.includes('[kick]')) {
message.member.kick('Tag kick :^)');
}
2023-04-04 19:51:36 +02:00
else
*/
if (text.includes('[delete]')) {
2022-08-28 17:04:31 +02:00
message.delete();
}
2022-09-04 02:26:02 +02:00
text = rand(text, message);
2022-08-28 17:04:31 +02:00
let attach = '';
if (text.includes('[attach:')) {
attach = text.split(/(\[attach:.*?])/);
for (let i = 0, l = attach.length; i < l; i++) {
if (attach[i].includes('[attach:')) {
attach = attach[i].replace('[attach:', '').slice(0, -1);
i = attach.length;
}
}
text = text.replace(/(\[attach:.*?])/, '');
}
// THIS SECTION IS VERY VERY BAD MUST CHANGE
if (text.includes('[embed]')) {
text = text.replace(/\[embed\]/, ' ');
let title = '';
let desc = '';
let image;
let thumbnail;
let footer = '';
let color;
if (text.includes('[embedImage:')) {
image = text.split(/(\[embedImage:.*?])/);
for (let i = 0, l = image.length; i < l; i++) {
if (image[i].includes('[embedImage:')) {
image = image[i].replace('[embedImage:', '').slice(0, -1);
text = text.replace(/(\[embedimage:.*?])/g, '');
i = image.length;
}
}
}
if (text.includes('[embedThumbnail:')) {
thumbnail = text.split(/(\[embedThumbnail:.*?])/);
for (let i = 0, l = thumbnail.length; i < l; i++) {
if (thumbnail[i].includes('[embedThumbnail:')) {
thumbnail = thumbnail[i].replace('[embedThumbnail:', '').slice(0, -1);
text = text.replace(/(\[embedThumbnail:.*?])/g, '');
i = thumbnail.length;
}
}
}
if (text.includes('[embedColor:')) {
color = text.split(/(\[embedColor:.*?])/);
for (let i = 0, l = color.length; i < l; i++) {
if (color[i].includes('[embedColor:')) {
color = color[i].replace('[embedColor:', '').slice(0, -1);
text = text.replace(/(\[embedColor:.*?])/g, '');
i = color.length;
}
}
}
if (text.includes('[embedTitle:')) {
title = text.split(/(\[embedTitle:.*?])/);
for (let i = 0, l = title.length; i < l; i++) {
if (title[i].includes('[embedTitle:')) {
title = title[i].replace('[embedTitle:', '').slice(0, -1);
text = text.replace(/(\[embedTitle:.*?])/g, '');
i = title.length;
}
}
}
if (text.includes('[embedFooter:')) {
footer = text.split(/(\[embedFooter:.*?])/);
for (let i = 0, l = footer.length; i < l; i++) {
if (footer[i].includes('[embedFooter:')) {
footer = footer[i].replace('[embedFooter:', '').slice(0, -1);
text = text.replace(/(\[embedFooter:.*?])/g, '');
i = footer.length;
}
}
}
if (text.includes('[embedDesc:')) {
desc = text.split(/(\[embedDesc:.*?])/);
for (let i = 0, l = desc.length; i < l; i++) {
if (desc[i].includes('[embedDesc:')) {
desc = desc[i].replace('[embedDesc:', '').slice(0, -1);
i = desc.length;
}
}
}
const embed = new EmbedBuilder()
.setColor(color)
.setTitle(title)
.setImage(image)
.setThumbnail(thumbnail)
.setDescription(desc)
.setFooter(footer)
.setTimestamp();
if (attach) {
return message.channel.send(embed, { files: [attach] });
}
else {
return message.channel.send(embed);
}
}
if (attach) {
return message.channel.send(text, { files: [attach] });
}
else {
return message.channel.send(text);
}
}
/* Quotation feature
*
* This section will contain the code for the quotation feature, it will detect link for it and send it as embed
*
*/
2022-08-29 20:56:26 +02:00
const isOptOut = await db.optout.findOne({ where: { userID: message.author.id } });
if (!isOptOut) {
const quotationstat = await db.quotationStat.findOne({ where: { serverID: message.guild.id, stat: 'enable' } });
if (quotationstat && (message.content.includes('discordapp.com/channels/') || message.content.includes('discord.com/channels/'))) {
const url = message.content.split('/');
const guildID = url[4];
const channelID = url[5];
const messageID = url[6].split(' ')[0];
// Verify if the guild, channel and message exist
const guild = client.guilds.resolve(guildID);
if (!guild) return;
const channel = client.channels.resolve(channelID);
if (!channel) return;
const quote = await channel.messages.fetch(messageID)
.catch(() => {
return;
});
if (!quote) return;
const Embed = new EmbedBuilder()
.setAuthor({ name: quote.author.username, iconURL: quote.author.displayAvatarURL() })
2022-09-14 14:38:35 +02:00
.setColor(message.member ? message.member.displayHexColor : 'Navy')
2022-08-29 20:56:26 +02:00
.addFields(
{ name: 'Jump to', value: `[message](https://discordapp.com/channels/${message.guild.id}/${channelID}/${messageID})`, inline: true },
{ name: 'In channel', value: quote.channel.name.toString(), inline: true },
{ name: 'Quoted by', value: message.author.toString(), inline: true },
)
.setDescription(quote.content)
.setTimestamp(quote.createdTimestamp);
if (quote.member) Embed.setAuthor({ name: `${quote.author.username}#${quote.author.discriminator}`, iconURL: quote.author.displayAvatarURL() });
if (quote.author.bot) Embed.setAuthor({ name: `${quote.author.username}#${quote.author.discriminator} (BOT)`, iconURL: quote.author.displayAvatarURL() });
if (guild.id != message.guild.id) Embed.addFields({ name: 'In guild', value: guild.name, inline: true });
const Attachment = Array.from(message.attachments.values());
if (Attachment[0]) Embed.setImage(Attachment[0].url);
return message.channel.send({ embeds: [Embed] });
}
2022-08-28 17:04:31 +02:00
}
}
// Command handling from message
2024-01-30 00:25:41 +01:00
// TODO: Moving that to a dedicated function that works for both messages and interactions
2022-08-28 17:04:31 +02:00
let hasPrefix = false;
prefixs.forEach(p => {
if (message.content.toLowerCase().startsWith(p)) {
hasPrefix = true;
}
});
if (!hasPrefix) return;
const messageArray = message.content.match(/"[^"]*"|\S+/g).map(m => m.slice(0, 1) === '"' ? m.slice(1, -1) : m);
2022-08-29 20:37:38 +02:00
let commandName = messageArray[1].toLowerCase();
2022-09-01 01:43:59 +02:00
const messageArgs = messageArray.splice(2, messageArray.length);
2022-08-28 17:04:31 +02:00
2022-08-29 20:37:38 +02:00
// Search for alias
client.commands.find(c => {
if (c.alias) {
if (c.alias.includes(commandName)) {
commandName = c.data.name;
}
}
});
const command = client.commands.get(commandName);
if (!command) return;
2022-08-28 17:04:31 +02:00
const globalBlacklist = await db.Blacklists.findOne({ where: { type:'global', uid:message.author.id } });
const commandBlacklist = await db.Blacklists.findOne({ where: { type:commandName, uid:message.author.id } });
2024-06-30 20:05:09 +02:00
if (message.guild) {
const serverBlacklist = await db.Blacklists.findOne({ where: { type:'guild', uid:message.guild.id } });
if (serverBlacklist) {
message.reply({ content: `This guild has been blacklisted for the following reason: \`${serverBlacklist.reason}\``, ephemeral: true });
return message.guild.leave();
}
}
2022-08-28 17:04:31 +02:00
if (globalBlacklist) {
return message.reply({ content: `You are globally blacklisted for the following reason: \`${globalBlacklist.reason}\``, ephemeral: true });
}
2022-08-28 17:04:31 +02:00
else if (commandBlacklist) {
return message.reply({ content: `You are blacklisted for the following reason: \`${commandBlacklist.reason}\``, ephemeral: true });
}
2023-09-13 20:56:06 +02:00
const userTag = message.author.username;
2022-08-28 17:04:31 +02:00
const userID = message.author.id;
let isOptOut = await db.optout.findOne({ where: { userID: message.author.id } });
if (commandName === 'optout') {
isOptOut = true;
}
2023-12-12 21:45:09 +01:00
const timestamp = new Date();
console.log(`[${timestamp.toISOString()}] \x1b[33m${ isOptOut ? 'A user' : `${userTag} (${userID})`}\x1b[0m launched command \x1b[33m${commandName}\x1b[0m using prefix`);
2023-12-12 21:45:09 +01:00
2022-08-28 17:04:31 +02:00
// Owner only check
if (command.ownerOnly && message.author.id !== ownerId) {
return message.reply({ content: '❌ This command is reserved for the owner!', ephemeral: true });
}
2023-04-14 17:46:12 +02:00
// Guild only check
if (command.guildOnly && !message.guild) {
return message.reply({ content: '❌ This command only work in a server!', ephemeral: true });
}
2022-08-28 17:04:31 +02:00
// Check if the bot has the needed permissions
if (command.clientPermissions) {
const clientMember = await message.guild.members.fetch(client.user.id);
if (!clientMember.permissions.has(command.clientPermissions)) {
return message.reply({ content: `❌ I am missing one of the following permission(s): \`${new PermissionFlagsBits(command.clientPermissions).toArray()}\``, ephemeral: true });
}
}
// Check if the user has the needed permissions
if (command.default_member_permissions) {
if (!message.member.permissions.has(command.default_member_permissions)) {
2022-08-28 17:04:31 +02:00
return message.reply({ content: `❌ You are missing one of the following permission(s): \`${new PermissionFlagsBits(command.userPermissions).toArray()}\``, ephemeral: true });
}
}
// Check if the limit of parallel execution has been reached
if (command.parallelLimit) {
const doParallelLimit = await ratelimiter.checkParallel(message.author, commandName, command);
if (doParallelLimit.limited) {
return await message.reply({ content: doParallelLimit.msg, ephemeral: true });
}
ratelimiter.addParallel(commandName);
}
2022-12-18 23:30:25 +01:00
// Check the ratelimit
const doRateLimit = await ratelimiter.check(message.author, commandName, command);
2022-12-18 23:30:25 +01:00
if (doRateLimit) {
return message.reply({ content: doRateLimit, ephemeral: true });
2022-12-18 22:53:23 +01:00
2022-12-18 23:30:25 +01:00
}
2022-08-28 17:04:31 +02:00
2022-12-18 23:30:25 +01:00
try {
2022-08-28 17:04:31 +02:00
message.user = message.author;
message.isMessage = true;
2022-11-24 21:34:54 +01:00
message.prefix = `${messageArray[0]} `;
2022-08-28 17:04:31 +02:00
let waitingmsg;
const toDelete = [];
message.deferReply = async function() {
waitingmsg = await message.reply('The bot is thinking...');
};
message.followUp = async function(payload) {
if (payload.ephemeral) {
toDelete.push(await message.channel.send(payload));
}
else {
await message.channel.send(payload);
}
};
message.editReply = async function(payload) {
if (waitingmsg) {
await waitingmsg.delete();
}
await message.channel.send(payload);
};
message.deleteReply = async function() {
if (waitingmsg) {
await waitingmsg.delete()
.catch(() => { return; });
}
};
message.cleanUp = async function() {
toDelete.forEach(async msg => {
msg.delete();
});
};
2022-11-24 21:34:54 +01:00
2022-09-01 01:43:59 +02:00
const args = {};
2022-11-24 21:11:53 +01:00
2022-12-21 21:54:23 +01:00
let argsToDelete = 0;
2022-11-24 21:11:53 +01:00
command.data.options.forEach(obj => {
if (obj.type === ApplicationCommandOptionType.Attachment) {
args[obj.name] = message.attachments.first();
2022-12-21 21:54:23 +01:00
delete command.data.options[command.data.options.indexOf(obj)];
argsToDelete++;
2022-11-24 21:11:53 +01:00
}
});
2022-12-21 21:54:23 +01:00
const argsLength = command.data.options.length - argsToDelete;
const missingRequired = [];
2022-12-21 21:54:23 +01:00
for (let i = 0, j = 0; i < argsLength; i++, j++) {
const arg = command.data.options[j];
if (arg.required && !messageArgs[i]) {
missingRequired.push({ name: arg.name, description: arg.description });
}
if (!messageArgs[i]) continue;
2022-11-24 21:11:53 +01:00
if (arg.type === ApplicationCommandOptionType.Attachment) continue;
2022-12-21 21:54:23 +01:00
2022-09-14 11:31:43 +02:00
let payloadName = arg.name;
2022-09-01 01:43:59 +02:00
let payload = messageArgs[i];
2022-11-24 21:11:53 +01:00
if (i >= argsLength - 1) {
payload = messageArgs.slice(i).join(' ');
}
2022-09-12 11:36:51 +02:00
if (arg.type === ApplicationCommandOptionType.Boolean && !messageArgs[i].startsWith('--')) {
continue;
}
else if (messageArgs[i].startsWith('--')) {
2022-09-14 11:31:43 +02:00
payloadName = payload.substring(2);
2022-09-12 11:36:51 +02:00
payload = true;
2022-09-14 11:31:43 +02:00
j--;
2022-09-12 11:36:51 +02:00
}
2022-11-24 21:11:53 +01:00
if (arg.type === ApplicationCommandOptionType.Mentionable || arg.type === ApplicationCommandOptionType.User) {
await message.guild.members.fetch();
payload = message.mentions.members.first() ? message.mentions.members.first() : message.guild.members.cache.find(u => u.user.username.toLowerCase().includes(payload.toLowerCase()));
2022-08-28 17:04:31 +02:00
}
2022-09-02 09:18:52 +02:00
2022-09-14 11:31:43 +02:00
args[payloadName] = payload;
2022-08-28 17:04:31 +02:00
}
2023-04-07 02:25:46 +02:00
if (!isOptOut && argsLength > 0) {
console.log(`[${timestamp.toISOString()}] \x1b[33m⤷\x1b[0m with args ${JSON.stringify(args)}`);
}
if (missingRequired.length > 0) {
let missingMsg = '';
missingRequired.forEach(arg => {
missingMsg += `${arg.name} | ${arg.description}\n`;
});
return message.reply(`You are missing a required argument!\n\`${missingMsg}\``);
}
await command.execute(message, args, client)
.then(async () => {
const hasPrallelLimit = await ratelimiter.checkParallel(message.author, commandName, command);
if (hasPrallelLimit) ratelimiter.removeParallel(commandName);
});
2022-08-28 17:04:31 +02:00
}
catch (error) {
console.error(error);
const hasPrallelLimit = await ratelimiter.checkParallel(message.author, commandName, command);
if (hasPrallelLimit) ratelimiter.removeParallel(commandName);
2024-01-30 00:25:41 +01:00
await message.reply({ content: `There was an error while executing this command!\n\`${error}\`` })
.catch(async () => {
await message.channel.send({ content: `There was an error while executing this command!\n\`${error}\`` });
});
2022-08-28 17:04:31 +02:00
}
},
};