Compare commits

...

5 commits

Author SHA1 Message Date
03b3b9189e rand text thigny 2022-08-28 17:04:51 +02:00
8e9e93ca50 Star/shameboard 2022-08-28 17:04:39 +02:00
d00ddbbbf5 Command from event message 2022-08-28 17:04:31 +02:00
01a2c9bab5 Join/Leave message 2022-08-28 17:04:23 +02:00
7e186a07a9 V14 update 2022-08-28 17:04:11 +02:00
11 changed files with 5712 additions and 467 deletions

View file

@ -1,6 +1,6 @@
import db from '../../models/index.js'; import db from '../../models/index.js';
const guildBlacklist = db.guildBlacklist; const guildBlacklist = db.guildBlacklist;
import { MessageEmbed } from 'discord.js'; import { EmbedBuilder } from 'discord.js';
import dotenv from 'dotenv'; import dotenv from 'dotenv';
dotenv.config(); dotenv.config();
@ -25,16 +25,18 @@ export default {
const channel = client.channels.resolve(statusChannel); const channel = client.channels.resolve(statusChannel);
const botCount = guild.members.cache.filter(member => member.user.bot).size; const botCount = guild.members.cache.filter(member => member.user.bot).size;
console.log(guild.memberCount); console.log(guild.memberCount);
const addEmbed = new MessageEmbed() const addEmbed = new EmbedBuilder()
.setColor('#52e80d') .setColor('#52e80d')
.setTitle('New boiz in town') .setTitle('New boiz in town')
.setURL('https://www.youtube.com/watch?v=6n3pFFPSlW4') .setURL('https://www.youtube.com/watch?v=6n3pFFPSlW4')
.setThumbnail(guild.iconURL()) .setThumbnail(guild.iconURL())
.addField('Guild', `${guild.name} (${guild.id})`) .addFields(
.addField('Total number of members', guild.memberCount.toString(), true) { name: 'Guild', value: `${guild.name} (${guild.id})` },
.addField('Number of users', (guild.memberCount - botCount).toString(), true) { name: 'Total number of members', value: guild.memberCount.toString(), inline: true },
.addField('Number of bots', botCount.toString(), true) { name: 'Number of users', value: (guild.memberCount - botCount).toString(), inline: true },
.addField('Owner', `${guildOwner.username} (${guild.ownerId})`, true) { name: 'Number of bots', value: botCount.toString(), inline: true },
{ name: 'Owner', value: `${guildOwner.username} (${guild.ownerId})`, inline: true },
)
.setFooter({ text: `I'm now in ${client.guilds.cache.size} servers!` }) .setFooter({ text: `I'm now in ${client.guilds.cache.size} servers!` })
.setTimestamp(); .setTimestamp();

View file

@ -1,6 +1,6 @@
import db from '../../models/index.js'; import db from '../../models/index.js';
const guildBlacklist = db.guildBlacklist; const guildBlacklist = db.guildBlacklist;
import { MessageEmbed } from 'discord.js'; import { EmbedBuilder } from 'discord.js';
import dotenv from 'dotenv'; import dotenv from 'dotenv';
dotenv.config(); dotenv.config();
@ -21,16 +21,18 @@ export default {
const channel = client.channels.resolve(statusChannel); const channel = client.channels.resolve(statusChannel);
const botCount = guild.members.cache.filter(member => member.user.bot).size; const botCount = guild.members.cache.filter(member => member.user.bot).size;
console.log(guild.memberCount); console.log(guild.memberCount);
const kickEmbed = new MessageEmbed() const kickEmbed = new EmbedBuilder()
.setColor('#FF0000') .setColor('#FF0000')
.setTitle('Some mofo just removed me from there guild :(') .setTitle('Some mofo just removed me from there guild :(')
.setURL('https://www.youtube.com/watch?v=6n3pFFPSlW4') .setURL('https://www.youtube.com/watch?v=6n3pFFPSlW4')
.setThumbnail(guild.iconURL()) .setThumbnail(guild.iconURL())
.addField('Guild', `${guild.name} (${guild.id})`) .addFields(
.addField('Total number of members', guild.memberCount.toString(), true) { name: 'Guild', value: `${guild.name} (${guild.id})` },
.addField('Number of users', (guild.memberCount - botCount).toString(), true) { name: 'Total number of members', value: guild.memberCount.toString(), inline: true },
.addField('Number of bots', botCount.toString(), true) { name: 'Number of users', value: (guild.memberCount - botCount).toString(), inline: true },
.addField('Owner', `${guildOwner.username} (${guild.ownerId})`, true) { name: 'Number of bots', value: botCount.toString(), inline: true },
{ name: 'Owner', value: `${guildOwner.username} (${guild.ownerId})`, inline: true },
)
.setFooter({ text: `I'm now in ${client.guilds.cache.size} servers!` }) .setFooter({ text: `I'm now in ${client.guilds.cache.size} servers!` })
.setTimestamp(); .setTimestamp();

View file

@ -0,0 +1,52 @@
import db from '../../models/index.js';
import { rand } from '../../utils/rand.js';
export default {
name: 'guildMemberAdd',
async execute(member, client) {
const join = await db.joinChannel.findOne({ where: { guildID: member.guild.id } });
if (join) {
const channel = client.channels.resolve(join.get('channelID'));
let welcomeMessage = join.get('message');
const invite = new RegExp(/(https?:\/\/)?(www\.)?discord(?:app\.com|\.gg)[/invite/]?(?:(?!.*[Ii10OolL]).[a-zA-Z0-9]{5,6}|[a-zA-Z0-9-]{2,32})/g);
let username = member.user.username;
let user = member.user;
if (username.match(invite)) {
username = username.replace(/(https?:\/\/)?(www\.)?discord(?:app\.com|\.gg)[/invite/]?(?:(?!.*[Ii10OolL]).[a-zA-Z0-9]{5,6}|[a-zA-Z0-9-]{2,32})/g, '[REDACTED]');
user = username;
}
welcomeMessage = welcomeMessage.replace(/\[member\]/g, username);
welcomeMessage = welcomeMessage.replace(/\[memberPing\]/g, user);
welcomeMessage = welcomeMessage.replace(/\[server\]/g, member.guild.name);
// add attachment
let attach;
if (welcomeMessage.includes('[attach:')) {
attach = welcomeMessage.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;
}
}
welcomeMessage = welcomeMessage.replace(/(\[attach:.*?])/, '');
}
welcomeMessage = rand(welcomeMessage);
if (attach) {
return channel.send({ content: welcomeMessage, files: [attach] });
}
else {
return channel.send({ content: welcomeMessage });
}
}
},
};

View file

@ -0,0 +1,52 @@
import db from '../../models/index.js';
import { rand } from '../../utils/rand.js';
export default {
name: 'guildMemberRemove',
async execute(member, client) {
const leave = await db.leaveChannel.findOne({ where: { guildID: member.guild.id } });
if (leave) {
const channel = client.channels.resolve(leave.get('channelID'));
let welcomeMessage = leave.get('message');
const invite = new RegExp(/(https?:\/\/)?(www\.)?discord(?:app\.com|\.gg)[/invite/]?(?:(?!.*[Ii10OolL]).[a-zA-Z0-9]{5,6}|[a-zA-Z0-9-]{2,32})/g);
let username = member.user.username;
let user = member.user;
if (username.match(invite)) {
username = username.replace(/(https?:\/\/)?(www\.)?discord(?:app\.com|\.gg)[/invite/]?(?:(?!.*[Ii10OolL]).[a-zA-Z0-9]{5,6}|[a-zA-Z0-9-]{2,32})/g, '[REDACTED]');
user = username;
}
welcomeMessage = welcomeMessage.replace(/\[member\]/g, username);
welcomeMessage = welcomeMessage.replace(/\[memberPing\]/g, user);
welcomeMessage = welcomeMessage.replace(/\[server\]/g, member.guild.name);
// add attachment
let attach;
if (welcomeMessage.includes('[attach:')) {
attach = welcomeMessage.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;
}
}
welcomeMessage = welcomeMessage.replace(/(\[attach:.*?])/, '');
}
welcomeMessage = rand(welcomeMessage);
if (attach) {
return channel.send({ content: welcomeMessage, files: [attach] });
}
else {
return channel.send({ content: welcomeMessage });
}
}
},
};

View file

@ -1,4 +1,4 @@
import { Permissions } from 'discord.js'; import { PermissionFlagsBits, InteractionType } from 'discord.js';
import db from '../../models/index.js'; import db from '../../models/index.js';
const ratelimit = {}; const ratelimit = {};
@ -10,7 +10,7 @@ export default {
name: 'interactionCreate', name: 'interactionCreate',
async execute(interaction) { async execute(interaction) {
const client = interaction.client; const client = interaction.client;
if (!interaction.isCommand()) return; if (interaction.type !== InteractionType.ApplicationCommand) return;
const globalBlacklist = await db.Blacklists.findOne({ where: { type:'global', uid:interaction.user.id } }); const globalBlacklist = await db.Blacklists.findOne({ where: { type:'global', uid:interaction.user.id } });
const commandBlacklist = await db.Blacklists.findOne({ where: { type:interaction.commandName, uid:interaction.user.id } }); const commandBlacklist = await db.Blacklists.findOne({ where: { type:interaction.commandName, uid:interaction.user.id } });
@ -40,14 +40,14 @@ export default {
if (command.clientPermissions) { if (command.clientPermissions) {
const clientMember = await interaction.guild.members.fetch(client.user.id); const clientMember = await interaction.guild.members.fetch(client.user.id);
if (!clientMember.permissions.has(command.clientPermissions)) { if (!clientMember.permissions.has(command.clientPermissions)) {
return interaction.reply({ content: `❌ I am missing one of the following permission(s): \`${new Permissions(command.clientPermissions).toArray()}\``, ephemeral: true }); return interaction.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 // Check if the user has the needed permissions
if (command.userPermissions) { if (command.userPermissions) {
if (!interaction.member.permissions.has(command.userPermissions)) { if (!interaction.member.permissions.has(command.userPermissions)) {
return interaction.reply({ content: `❌ You are missing one of the following permission(s): \`${new Permissions(command.userPermissions).toArray()}\``, ephemeral: true }); return interaction.reply({ content: `❌ You are missing one of the following permission(s): \`${new PermissionFlagsBits(command.userPermissions).toArray()}\``, ephemeral: true });
} }
} }
@ -74,7 +74,20 @@ export default {
ratelimit[userID] = { command: commandName, limit: ratelimit[userID].limit, cooldown: date }; ratelimit[userID] = { command: commandName, limit: ratelimit[userID].limit, cooldown: date };
} }
} }
await command.execute(interaction);
const args = [];
interaction.options.data.forEach(arg => {
console.log(arg);
if (arg.type === 'MENTIONABLE') {
return args.push(arg.member);
}
else if (arg.type === 'ATTACHMENT') {
return args.push(arg.attachment);
}
args.push(arg.value);
});
await command.execute(interaction, args, client);
} }
catch (error) { catch (error) {
console.error(error); console.error(error);

View file

@ -0,0 +1,392 @@
/* TODO:
* Make this shit work.
*/
import { EmbedBuilder, PermissionFlagsBits } from 'discord.js';
import db from '../../models/index.js';
import { rand } from '../../utils/rand.js';
const ratelimit = {};
import dotenv from 'dotenv';
dotenv.config();
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');
if (text.includes('[ban]')) {
message.member.ban('Tag ban :^)');
}
else if (text.includes('[kick]')) {
message.member.kick('Tag kick :^)');
}
else if (text.includes('[delete]')) {
message.delete();
}
text = rand.random(text, message);
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
*
*/
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() })
.setColor(message.member ? message.member.displayHexColor : 'NAVY')
.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] });
}
}
// Command handling from message
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);
const commandName = messageArray[1].toLowerCase();
let messageArgs = messageArray.splice(2, messageArray.length);
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 } });
if (globalBlacklist) {
return message.reply({ content: `You are globally blacklisted for the following reason: \`${globalBlacklist.reason}\``, ephemeral: true });
}
else if (commandBlacklist) {
return message.reply({ content: `You are blacklisted for the following reason: \`${commandBlacklist.reason}\``, ephemeral: true });
}
const userTag = message.author.tag;
const userID = message.author.id;
const command = client.commands.get(commandName);
if (!command) return;
console.log(`\x1b[33m${userTag} (${userID})\x1b[0m launched command \x1b[33m${commandName}\x1b[0m`);
// Owner only check
if (command.ownerOnly && message.author.id !== ownerId) {
return message.reply({ content: '❌ This command is reserved for the owner!', ephemeral: true });
}
// 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.userPermissions) {
if (!message.member.permissions.has(command.userPermissions)) {
return message.reply({ content: `❌ You are missing one of the following permission(s): \`${new PermissionFlagsBits(command.userPermissions).toArray()}\``, ephemeral: true });
}
}
try {
const date = new Date();
if (ratelimit[userID]) {
if (ratelimit[userID].cooldown) {
if (commandName === ratelimit[userID].command && date > ratelimit[userID].cooldown) {
ratelimit[userID].limit = 0;
ratelimit[userID].cooldown = undefined;
}
}
if (commandName === ratelimit[userID].command && command.ratelimit === ratelimit[userID].limit) {
return await message.reply({ content: `You are being rate limited. You can try again in ${Math.floor((ratelimit[userID].cooldown - date) / 1000)} seconds.`, ephemeral: true });
}
}
if (command.ratelimit) {
ratelimit[userID] = { command: commandName, limit: ratelimit[userID] ? ratelimit[userID].limit + 1 : 1 };
if (command.ratelimit === ratelimit[userID].limit) {
date.setSeconds(date.getSeconds() + command.cooldown);
ratelimit[userID] = { command: commandName, limit: ratelimit[userID].limit, cooldown: date };
}
}
message.user = message.author;
message.isMessage = true;
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();
});
};
if (command.data.options.length > 0) {
// if (command.data.options.length === 1 || command.data.options[command.data.options.length - 1].constructor.name.toLowerCase().includes('attachment')) {
if (command.data.options.length === 1) {
const test = messageArgs.join(' ');
messageArgs = [];
messageArgs.push(test);
}
for (let i = 0; i < messageArgs.length; i++) {
const constructorName = command.data.options[i].constructor.name.toLowerCase();
if (constructorName.includes('boolean')) {
messageArgs[i] = (messageArgs[i].toLowerCase() === 'true');
}
if (constructorName.includes('mentionable')) {
messageArgs[i] = message.mentions.members.first();
}
}
if (message.attachments) {
messageArgs.push(Array.from(message.attachments.values())[0]);
}
}
await command.execute(message, messageArgs, client);
}
catch (error) {
console.error(error);
await message.reply({ content: 'There was an error while executing this command!', ephemeral: true });
}
},
};

View file

@ -0,0 +1,170 @@
import { EmbedBuilder } from 'discord.js';
import fs from 'node:fs';
global.boards = {};
export default {
name: 'messageReactionAdd',
async execute(reaction, users, c) {
if (reaction.partial) {
await reaction.fetch()
.catch(err => {
return console.error(err);
});
}
if (reaction.message.partial) {
await reaction.message.fetch()
.catch(err => {
return console.error(err);
});
}
let starboardChannel, shameboardChannel;
let reactionCount = reaction.count;
// If one of the reaction is the author of the message remove 1 to the reaction count
reaction.users.cache.forEach(user => {
if (reaction.message.author == user) reactionCount--;
});
console.log(fs.existsSync(`./json/board/star${reaction.message.guild.id}.json`));
// Starboard
if (fs.existsSync(`./json/board/star${reaction.message.guild.id}.json`)) {
console.log('hi');
starboardChannel = JSON.parse(fs.readFileSync(`./json/board/star${reaction.message.guild.id}.json`));
let staremote = starboardChannel.emote;
const starcount = starboardChannel.count;
// Get name of the custom emoji
if (reaction.message.guild.emojis.resolve(staremote.replace(/\D/g, ''))) {
staremote = reaction.message.guild.emojis.resolve(staremote.replace(/\D/g, ''));
}
if (reaction.emoji == staremote || reaction.emoji.name == staremote) {
console.log('send or edit');
if (global.boards[reaction.message.id] && reactionCount > starcount) {
return editEmbed('starboard', staremote, global.boards[reaction.message.id], c);
}
else if (reactionCount == starcount) {
return sendEmbed('starboard', staremote, c);
}
}
}
// Shameboard
if (fs.existsSync(`./json/board/shame${reaction.message.guild.id}.json`)) {
shameboardChannel = JSON.parse(fs.readFileSync(`./json/board/shame${reaction.message.guild.id}.json`));
let shameemote = shameboardChannel.emote;
const shamecount = shameboardChannel.count;
// Get name of the custom emoji
if (reaction.message.guild.emojis.resolve(shameemote.replace(/\D/g, ''))) {
shameemote = reaction.message.guild.emojis.resolve(shameemote.replace(/\D/g, ''));
}
if (reaction.emoji == shameemote || reaction.emoji.name == shameemote) {
if (global.boards[reaction.message.id] && reactionCount > shamecount) {
return editEmbed('shameboard', shameemote, global.boards[reaction.message.id], c);
}
else if (reactionCount == shamecount) {
return sendEmbed('shameboard', shameemote, c);
}
}
}
async function editEmbed(name, emote, boardID, client) {
let channel;
if (name == 'starboard') {
channel = client.channels.resolve(starboardChannel.starboard);
}
else {
channel = client.channels.resolve(shameboardChannel.shameboard);
}
const message = await channel.messages.resolve(boardID);
// If the message doesn't have embeds assume it got deleted so don't do anything
if (!message) return;
// If the original embed description is empty make this embed empty ( and not undefined )
let description = message.embeds[0].description;
if (!message.embeds[0].description || message.embeds[0].description == undefined) {
description = '';
}
const Embed = new EmbedBuilder()
.setColor(reaction.message.member ? reaction.message.member.displayHexColor : 'NAVY')
.setAuthor({ name: reaction.message.author.username, iconURL: reaction.message.author.displayAvatarURL() })
.addFields(
{ name: 'Jump to', value: `[message](https://discordapp.com/channels/${reaction.message.guild.id}/${reaction.message.channel.id}/${reaction.message.id})`, inline: true },
{ name: 'Channel', value: reaction.message.channel.toString(), inline: true },
)
.setDescription(description)
.setFooter({ text: `${emote} ${reactionCount}` })
.setTimestamp();
if (reaction.message.guild.emojis.resolve(emote)) Embed.setFooter(reactionCount, reaction.message.guild.emojis.resolve(emote).url);
message.edit({ embed: Embed });
}
async function sendEmbed(name, emote, client) {
let messageAttachments = reaction.message.attachments.map(u => u.url)[0];
// Should change this so it automatically pic the channel ( I'm lazy right now )
let channel;
if (name == 'starboard') {
channel = client.channels.resolve(starboardChannel.starboard);
}
else {
channel = client.channels.resolve(shameboardChannel.shameboard);
}
const Embed = new EmbedBuilder()
.setColor(reaction.message.member ? reaction.message.member.displayHexColor : 'NAVY')
.setAuthor({ name: reaction.message.author.username, iconURL: reaction.message.author.displayAvatarURL() })
.addFields(
{ name: 'Jump to', value: `[message](https://discordapp.com/channels/${reaction.message.guild.id}/${reaction.message.channel.id}/${reaction.message.id})`, inline: true },
{ name: 'Channel', value: reaction.message.channel.toString(), inline: true },
)
.setFooter({ text: `${emote} ${reactionCount}` })
.setTimestamp();
if (reaction.message.guild.emojis.resolve(emote)) Embed.setFooter(reactionCount, reaction.message.guild.emojis.resolve(emote).url);
let description = '';
if (reaction.message.embeds[0]) {
if (reaction.message.embeds[0].type == 'image') {
messageAttachments = reaction.message.embeds[0].url;
}
if (reaction.message.embeds[0].description) {
description = reaction.message.embeds[0].description;
}
else if (reaction.message.content) {
description = reaction.message.content;
}
}
else if (reaction.message.content) {
description = reaction.message.content;
}
// if message come from nsfw channel and the star/shameboard channel isn't nsfw put it in spoiler
if (reaction.message.channel.nsfw && !channel.nsfw) {
Embed.setDescription(`||${description}||`);
if (messageAttachments != '') {
const message = await channel.send({ content: `||${messageAttachments}||`, embeds: [Embed] });
global.boards[reaction.message.id] = message.id;
}
else {
const message = await channel.send({ embeds: [Embed] });
global.boards[reaction.message.id] = message.id;
}
}
else {
Embed.setDescription(description);
const message = await channel.send({ files: [messageAttachments], embeds: [Embed] })
.catch(async () => channel.send({ content: messageAttachments, embeds: [Embed] }));
global.boards[reaction.message.id] = message.id;
}
}
},
};

View file

@ -0,0 +1,116 @@
import { EmbedBuilder } from 'discord.js';
import fs from 'node:fs';
global.boards = {};
export default {
name: 'messageReactionRemove',
async execute(reaction, users, c) {
if (reaction.partial) {
await reaction.fetch()
.catch(err => {
return console.error(err);
});
}
if (reaction.message.partial) {
await reaction.message.fetch()
.catch(err => {
return console.error(err);
});
}
let starboardChannel, shameboardChannel;
let reactionCount = reaction.count;
// If one of the reaction is the author of the message remove 1 to the reaction count
reaction.users.cache.forEach(user => {
if (reaction.message.author == user) reactionCount--;
});
console.log(fs.existsSync(`./json/board/star${reaction.message.guild.id}.json`));
// Starboard
if (fs.existsSync(`./json/board/star${reaction.message.guild.id}.json`)) {
console.log('hi');
starboardChannel = JSON.parse(fs.readFileSync(`./json/board/star${reaction.message.guild.id}.json`));
let staremote = starboardChannel.emote;
const starcount = starboardChannel.count;
// Get name of the custom emoji
if (reaction.message.guild.emojis.resolve(staremote.replace(/\D/g, ''))) {
staremote = reaction.message.guild.emojis.resolve(staremote.replace(/\D/g, ''));
}
if (global.boards[reaction.message.id] && (reaction.emoji == staremote || reaction.emoji.name == staremote) && reactionCount < starcount) {
const channel = c.channels.resolve(starboardChannel.starboard);
const message = await channel.messages.resolve(global.boards[reaction.message.id]);
delete global.boards[reaction.message.id];
// If it didn't find any message don't do anything
if (!message) return;
message.delete();
}
else if ((reaction.emoji == staremote || reaction.emoji.name == staremote) && reactionCount >= starcount) {
return editEmbed('starboard', staremote, global.boards[reaction.message.id], this.client);
}
}
// Shameboard
if (fs.existsSync(`./json/board/shame${reaction.message.guild.id}.json`)) {
shameboardChannel = JSON.parse(fs.readFileSync(`./json/board/shame${reaction.message.guild.id}.json`));
let shameemote = shameboardChannel.emote;
const shamecount = shameboardChannel.count;
// Get name of the custom emoji
if (reaction.message.guild.emojis.resolve(shameemote.replace(/\D/g, ''))) {
shameemote = reaction.message.guild.emojis.resolve(shameemote.replace(/\D/g, ''));
}
if (global.boards[reaction.message.id] && (reaction.emoji == shameemote || reaction.emoji.name == shameemote) && reactionCount < shamecount) {
const channel = c.channels.resolve(starboardChannel.starboard);
const message = await channel.messages.resolve(global.boards[reaction.message.id]);
delete global.boards[reaction.message.id];
// If it didn't find any message don't do anything
if (!message) return;
message.delete();
}
else if ((reaction.emoji == shameemote || reaction.emoji.name == shameemote) && reactionCount >= shamecount) {
return editEmbed('shameboard', shameemote, global.boards[reaction.message.id], this.client);
}
}
async function editEmbed(name, emote, boardID, client) {
let channel;
if (name == 'starboard') {
channel = client.channels.resolve(starboardChannel.starboard);
}
else {
channel = client.channels.resolve(shameboardChannel.shameboard);
}
const message = await channel.messages.resolve(boardID);
// If the message doesn't have embeds assume it got deleted so don't do anything
if (!message) return;
// If the original embed description is empty make this embed empty ( and not undefined )
let description = message.embeds[0].description;
if (!message.embeds[0].description || message.embeds[0].description == undefined) {
description = '';
}
const Embed = new EmbedBuilder()
.setColor(reaction.message.member ? reaction.message.member.displayHexColor : 'NAVY')
.setAuthor({ name: reaction.message.author.username, iconURL: reaction.message.author.displayAvatarURL() })
.addFields(
{ name: 'Jump to', value: `[message](https://discordapp.com/channels/${reaction.message.guild.id}/${reaction.message.channel.id}/${reaction.message.id})`, inline: true },
{ name: 'Channel', value: reaction.message.channel.toString(), inline: true },
)
.setDescription(description)
.setFooter({ text: `${emote} ${reactionCount}` })
.setTimestamp();
if (reaction.message.guild.emojis.resolve(emote)) Embed.setFooter(reactionCount, reaction.message.guild.emojis.resolve(emote).url);
message.edit({ embed: Embed });
}
},
};

5267
package-lock.json generated

File diff suppressed because it is too large Load diff

View file

@ -17,14 +17,14 @@
"homepage": "https://libtar.de", "homepage": "https://libtar.de",
"license": "AGPL", "license": "AGPL",
"dependencies": { "dependencies": {
"@discordjs/builders": "^0.13.0",
"@discordjs/rest": "^0.4.1", "@discordjs/rest": "^0.4.1",
"discord-api-types": "^0.33.1", "discord-api-types": "^0.33.5",
"discord.js": "^13.7.0", "discord.js": "^14.3.0",
"dotenv": "^16.0.1", "dotenv": "^16.0.1",
"mariadb": "^3.0.1", "mariadb": "^3.0.1",
"mysql2": "^2.3.3", "mysql2": "^2.3.3",
"node-fetch": "^3.2.6", "node-fetch": "^3.2.6",
"safe-regex": "github:davisjam/safe-regex",
"sequelize": "^6.21.3", "sequelize": "^6.21.3",
"turndown": "^7.1.1", "turndown": "^7.1.1",
"twit": "^2.2.11" "twit": "^2.2.11"

69
utils/rand.js Normal file
View file

@ -0,0 +1,69 @@
import fs from 'node:fs';
export function rand(text, message) {
// Find a value in an array of objects in Javascript - https://stackoverflow.com/a/12462387
function search(nameKey, myArray) {
for (let i = 0; i < myArray.length; i++) {
if (new RegExp(myArray[i].name).test(nameKey)) {
return myArray[i];
}
}
}
fs.readdirSync('./json/dictionary/').forEach(file => {
file = file.slice(0, -5);
const dictionary = JSON.parse(fs.readFileSync(`./json/dictionary/${file}.json`));
const re = new RegExp('\\[' + file + '\\]');
do {
text = text.replace(re, dictionary[Math.floor((Math.random() * dictionary.length))]);
} while (text.includes(`[${file}]`));
return text;
});
const variables = [
{
name: /\[author\]/,
value: message ? message.author.username : '',
},
{
name: /\[member\]/,
value: message ? message.guild ? message.guild.members.cache.random().user.username : '' : '',
},
{
name: /\[memberRand\]/,
value: (() => message.guild ? message.guild.members.cache.random().user.username : ''),
},
{
name: /\[dice\d*\]/,
value: (() => Math.floor((Math.random() * text.match(/\[dice\d*\]/g)[0].replace(/\D/g, '')) + 1)),
},
{
name: /\[number\]/,
value: (() => Math.floor((Math.random() * 9) + 1)),
},
{
name: /\[kick\]/,
value: '',
},
{
name: /\[ban\]/,
value: '',
},
{
name: /\[delete\]/,
value: '',
},
{
name: /\[n\]/,
value: '\n',
},
];
const matches = text.matchAll(/\[.*?\]\s?/g);
for (const match of matches) {
if (search(match[0].trim(), variables)) { text = text.replace(match[0].trim(), search(match[0].trim(), variables).value); }
}
return text;
}