362 lines
16 KiB
JavaScript
362 lines
16 KiB
JavaScript
const path = require("path");
|
||
const Embed = require(path.join(__dirname, "../functions/embed"));
|
||
const PollDB = require(path.join(__dirname, "../models/polls"));
|
||
const Giveaways = require(path.join(__dirname, "../models/giveaways"));
|
||
|
||
// Constants
|
||
const EMOJIS = [
|
||
{ name: "1️⃣", id: 0 }, { name: "2️⃣", id: 1 }, { name: "3️⃣", id: 2 },
|
||
{ name: "4️⃣", id: 3 }, { name: "5️⃣", id: 4 }, { name: "6️⃣", id: 5 },
|
||
{ name: "7️⃣", id: 6 }, { name: "8️⃣", id: 7 }, { name: "9️⃣", id: 8 },
|
||
{ name: "🔟", id: 9 }, { name: "🛑", id: "stop" }
|
||
];
|
||
const COLORS_REGEX = /^([A-Z0-9]+)/;
|
||
|
||
/**
|
||
* Handles message collector reactions
|
||
* @param {Object} client - The client instance
|
||
* @param {Object} message - The message object
|
||
* @param {string} userId - The user ID
|
||
* @param {string} emojiId - The emoji ID
|
||
* @param {Object} collector - The message collector
|
||
* @returns {Promise<void>}
|
||
*/
|
||
async function handleMessageCollector(client, message, userId, emojiId, collector) {
|
||
if (emojiId === client.config.emojis.check) {
|
||
if (collector.roles.length === 0) {
|
||
const db = await client.database.getGuild(message.server.id);
|
||
await Promise.all([
|
||
message.delete().catch(() => {}),
|
||
client.messages.get(collector?.oldMessageId)?.delete().catch(() => {})
|
||
]);
|
||
|
||
const reactions = [...collector.rolesDone.map(e => e.emoji)];
|
||
const content = collector.type === "content"
|
||
? { content: `${message.content}\n\n##### ${client.translate.get(db.language, "Events.messageReactionAdd.cooldown")}`, interactions: [reactions] }
|
||
: { embeds: [new Embed().setColor("#A52F05").setDescription(`${client.messages.get(message.id).embeds[0].description}\n\n##### ${client.translate.get(db.language, "Events.messageReactionAdd.cooldown")}`)], interactions: [reactions] };
|
||
|
||
const msg = await message.channel.sendMessage(content);
|
||
db.roles.push({ msgId: msg.id, chanId: msg.channelId, roles: [...collector.rolesDone] });
|
||
await client.database.updateGuild(msg.server.id, { roles: db.roles });
|
||
|
||
clearTimeout(client.messageCollector.get(userId).timeout);
|
||
return client.messageCollector.delete(userId);
|
||
}
|
||
return;
|
||
}
|
||
|
||
if (emojiId === client.config.emojis.cross) {
|
||
const db = await client.database.getGuild(message.server.id);
|
||
client.messageCollector.delete(userId);
|
||
return message.reply({
|
||
embeds: [new Embed().setColor("#A52F05").setDescription(client.translate.get(db.language, "Events.messageReactionAdd.deleteCollector"))]
|
||
});
|
||
}
|
||
|
||
if (collector.roles.length === 0) return;
|
||
|
||
const emote = COLORS_REGEX.test(emojiId) ? `:${emojiId}:` : emojiId;
|
||
const role = collector.roles[0];
|
||
const roleColor = role[1].colour?.includes("linear-gradient") ? '#000000' : role[1].colour;
|
||
|
||
collector.rolesDone.push({
|
||
emoji: emojiId,
|
||
role: role[0],
|
||
name: role[1].name,
|
||
color: roleColor
|
||
});
|
||
|
||
const content = collector.type === "content"
|
||
? { content: message.content.replace(`{role:${collector.regex[0]}}`, `${emote} $\\text{\\textcolor{${roleColor}}{${role[1].name}}}$`) }
|
||
: { embeds: [new Embed().setColor("#A52F05").setDescription(client.messages.get(message.id).embeds[0].description.replace(`{role:${collector.regex[0]}}`, `:${emojiId}: $\\text{\\textcolor{${roleColor}}{${role[1].name}}}$`))] };
|
||
|
||
await message.edit(content);
|
||
collector.roles.shift();
|
||
return collector.regex.shift();
|
||
}
|
||
|
||
/**
|
||
* Handles pagination reactions
|
||
* @param {Object} client - The client instance
|
||
* @param {Object} message - The message object
|
||
* @param {Object} paginateCheck - The pagination check object
|
||
* @param {string} emojiId - The emoji ID
|
||
* @returns {Promise<void>}
|
||
*/
|
||
async function handlePagination(client, message, paginateCheck, emojiId) {
|
||
const { pages, page } = paginateCheck;
|
||
let newPage = page;
|
||
|
||
switch (emojiId) {
|
||
case "⏪":
|
||
if (page !== 0) {
|
||
await message.edit({ embeds: [pages[0]] }).catch(() => {});
|
||
newPage = 0;
|
||
}
|
||
break;
|
||
case "⬅️":
|
||
if (pages[page - 1]) {
|
||
await message.edit({ embeds: [pages[--newPage]] }).catch(() => {});
|
||
}
|
||
break;
|
||
case "➡️":
|
||
if (pages[page + 1]) {
|
||
await message.edit({ embeds: [pages[++newPage]] }).catch(() => {});
|
||
}
|
||
break;
|
||
case "⏩":
|
||
if (page !== pages.length) {
|
||
await message.edit({ embeds: [pages[pages.length - 1]] }).catch(() => {});
|
||
newPage = pages.length - 1;
|
||
}
|
||
break;
|
||
}
|
||
|
||
if (newPage !== page) {
|
||
paginateCheck.page = newPage;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Handles poll reactions
|
||
* @param {Object} client - The client instance
|
||
* @param {Object} message - The message object
|
||
* @param {Object} pollCheck - The poll check object
|
||
* @param {string} userId - The user ID
|
||
* @param {string} emojiId - The emoji ID
|
||
* @returns {Promise<void>}
|
||
*/
|
||
async function handlePoll(client, message, pollCheck, userId, emojiId) {
|
||
const convert = EMOJIS.findIndex(e => e.name === emojiId);
|
||
|
||
if (convert === 10 && pollCheck.owner === userId) {
|
||
await PollDB.findOneAndDelete({ messageId: message.id });
|
||
await pollCheck.poll.update();
|
||
|
||
const tooMuch = [];
|
||
if (pollCheck.poll.options.description.length > 80) {
|
||
tooMuch.push(`**${client.translate.get(pollCheck.lang, "Events.messageReactionAdd.title")}**: ${pollCheck.poll.options.description}`);
|
||
}
|
||
pollCheck.poll.voteOptions.name.filter(e => e).forEach((e, i) => {
|
||
if (e.length > 70) {
|
||
tooMuch.push(`**${i + 1}.** ${e}`);
|
||
}
|
||
});
|
||
|
||
await message.edit({
|
||
content: `${client.translate.get(pollCheck.lang, "Events.messageReactionAdd.owner")} (<@${pollCheck.owner}>) ${client.translate.get(pollCheck.lang, "Events.messageReactionAdd.end")}:`,
|
||
embeds: [new Embed()
|
||
.setDescription(tooMuch.length > 0 ? tooMuch.join("\n") : null)
|
||
.setMedia(await client.Uploader.upload(pollCheck.poll.canvas.toBuffer(), `Poll.png`))
|
||
.setColor("#F24646")]
|
||
}).catch(() => {});
|
||
|
||
return client.polls.delete(message.id);
|
||
}
|
||
|
||
if (convert === 0 || (convert !== -1 && convert !== 10)) {
|
||
if (client.reactions.get(userId)) {
|
||
return client.users.get(userId)?.openDM()
|
||
.then(dm => dm.sendMessage(client.translate.get(pollCheck.lang, "Events.messageReactionAdd.tooFast")))
|
||
.catch(() => {});
|
||
}
|
||
|
||
if (pollCheck.users.includes(userId)) return;
|
||
|
||
pollCheck.users.push(userId);
|
||
const user = client.users.get(userId) || await client.users.fetch(userId);
|
||
await pollCheck.poll.addVote(convert, userId, 'https://chat.f95.io/api/users/01HATCWS7XZ7KEHW64AV20SMKR/default_avatar', message.id);
|
||
|
||
const tooMuch = [];
|
||
if (pollCheck.poll.options.description.length > 80) {
|
||
tooMuch.push(`**${client.translate.get(pollCheck.lang, "Events.messageReactionAdd.title")}**: ${pollCheck.poll.options.description}`);
|
||
}
|
||
pollCheck.poll.voteOptions.name.filter(e => e).forEach((e, i) => {
|
||
if (e.length > 70) {
|
||
tooMuch.push(`**${i + 1}.** ${e}`);
|
||
}
|
||
});
|
||
|
||
await message.edit({
|
||
embeds: [new Embed()
|
||
.setDescription(tooMuch.length > 0 ? tooMuch.join("\n") : null)
|
||
.setMedia(await client.Uploader.upload(pollCheck.poll.canvas.toBuffer(), `Poll.png`))
|
||
.setColor("#A52F05")]
|
||
}).catch(() => {});
|
||
|
||
client.reactions.set(userId, Date.now() + 3000);
|
||
setTimeout(() => client.reactions.delete(userId), 3000);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Handles giveaway reactions
|
||
* @param {Object} client - The client instance
|
||
* @param {Object} message - The message object
|
||
* @param {Object} db - The giveaway database object
|
||
* @param {string} userId - The user ID
|
||
* @param {string} emojiId - The emoji ID
|
||
* @returns {Promise<void>}
|
||
*/
|
||
async function handleGiveaway(client, message, db, userId, emojiId) {
|
||
if (emojiId === client.config.emojis.confetti && !db.ended) {
|
||
if (client.reactions.get(userId) || db.users.find(u => u.userID === userId)) return;
|
||
|
||
db.users.push({ userID: userId });
|
||
db.picking.push({ userID: userId });
|
||
await db.save();
|
||
|
||
client.reactions.set(userId, Date.now() + 3000);
|
||
setTimeout(() => client.reactions.delete(userId), 3000);
|
||
|
||
await client.users.get(userId)?.openDM()
|
||
.then(dm => dm.sendMessage(
|
||
`${client.translate.get(db.lang, "Events.messageReactionAdd.joined")} [${db.prize}](https://chat.f95.io/server/${db.serverId}/channel/${db.channelId}/${db.messageId})!\n` +
|
||
`${client.translate.get(db.lang, "Events.messageReactionAdd.joined2")} **${db.users.length}** ${client.translate.get(db.lang, "Events.messageReactionAdd.joined3")}`
|
||
))
|
||
.catch(() => {});
|
||
} else if (emojiId === client.config.emojis.stop && db.owner === userId && !db.ended) {
|
||
const endDate = Date.now();
|
||
|
||
if (db.users.length === 0) {
|
||
const noUsers = new Embed()
|
||
.setColor("#A52F05")
|
||
.setTitle(client.translate.get(db.lang, "Events.messageReactionAdd.giveaway"))
|
||
.setDescription(
|
||
`${client.translate.get(db.lang, "Events.messageReactionAdd.owner")} (<@${userId}>) ${client.translate.get(db.lang, "Events.messageReactionAdd.early")}\n` +
|
||
`${client.translate.get(db.lang, "Events.messageReactionAdd.endNone")}!\n\n` +
|
||
`${client.translate.get(db.lang, "Events.messageReactionAdd.ended")}: <t:${Math.floor(endDate / 1000)}:R>\n` +
|
||
`${client.translate.get(db.lang, "Events.messageReactionAdd.prize")}: ${db.prize}\n` +
|
||
`${client.translate.get(db.lang, "Events.messageReactionAdd.winnersNone")}` +
|
||
(db.requirement ? `\n${client.translate.get(db.lang, "Events.messageReactionAdd.reqs")}: ${db.requirement}` : ``)
|
||
);
|
||
|
||
await db.updateOne({ ended: true, endDate });
|
||
await db.save();
|
||
return await client.api.patch(`/channels/${db.channelId}/messages/${db.messageId}`, { embeds: [noUsers] });
|
||
}
|
||
|
||
for (let i = 0; i < db.winners; i++) {
|
||
const winner = db.picking[Math.floor(Math.random() * db.picking.length)];
|
||
if (winner) {
|
||
db.picking = db.picking.filter(object => object.userID !== winner.userID);
|
||
db.pickedWinners.push({ id: winner.userID });
|
||
}
|
||
}
|
||
|
||
await db.updateOne({ ended: true, endDate });
|
||
await db.save();
|
||
|
||
const noUsers = new Embed()
|
||
.setColor("#A52F05")
|
||
.setTitle(client.translate.get(db.lang, "Events.messageReactionAdd.giveaway"))
|
||
.setDescription(
|
||
`${client.translate.get(db.lang, "Events.messageReactionAdd.owner")} (<@${userId}>) ${client.translate.get(db.lang, "Events.messageReactionAdd.early")}\n` +
|
||
`${client.translate.get(db.lang, "Events.messageReactionAdd.partici")}: ${db.users.length}\n\n` +
|
||
`${client.translate.get(db.lang, "Events.messageReactionAdd.ended")}: <t:${Math.floor(endDate / 1000)}:R>\n` +
|
||
`${client.translate.get(db.lang, "Events.messageReactionAdd.prize")}: ${db.prize}\n` +
|
||
`${client.translate.get(db.lang, "Events.messageReactionAdd.winners")}: ${db.pickedWinners.length > 0 ? db.pickedWinners.map(w => `<@${w.id}>`).join(", ") : client.translate.get(db.lang, "Events.messageReactionAdd.none")}` +
|
||
(db.requirement ? `\n${client.translate.get(db.lang, "Events.messageReactionAdd.reqs")}: ${db.requirement}` : ``)
|
||
);
|
||
|
||
await message.edit({ embeds: [noUsers] }).catch(() => {});
|
||
await client.api.post(`/channels/${db.channelId}/messages`, {
|
||
content: `${client.translate.get(db.lang, "Events.messageReactionAdd.congrats")} ${db.pickedWinners.map(w => `<@${w.id}>`).join(", ")}! ${client.translate.get(db.lang, "Events.messageReactionAdd.youWon")} **[${db.prize}](https://chat.f95.io/server/${db.serverId}/channel/${db.channelId}/${db.messageId})**!`
|
||
}).catch(() => {});
|
||
|
||
client.reactions.set(userId, Date.now() + 3000);
|
||
setTimeout(() => client.reactions.delete(userId), 3000);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Handles role reactions
|
||
* @param {Object} client - The client instance
|
||
* @param {Object} message - The message object
|
||
* @param {Object} db - The guild database object
|
||
* @param {string} userId - The user ID
|
||
* @param {string} emojiId - The emoji ID
|
||
* @returns {Promise<void>}
|
||
*/
|
||
async function handleRoleReaction(client, message, db, userId, emojiId) {
|
||
if (client.reactions.get(userId)) return;
|
||
|
||
const roles = [];
|
||
db.roles.find(e => e.msgId === message.id).roles.map(e => roles.push(e));
|
||
const role = roles.find(e => e.emoji === emojiId);
|
||
|
||
const member = await (client.servers.get(message.server.id) || await client.servers.fetch(message.server.id))?.fetchMember(userId);
|
||
if (!member) return;
|
||
|
||
let error = false;
|
||
let dataRoles = [];
|
||
if (member.roles) member.roles.map(e => dataRoles.push(e));
|
||
if (dataRoles.includes(role.role)) return;
|
||
|
||
client.reactions.set(userId, Date.now() + 3000);
|
||
setTimeout(() => client.reactions.delete(userId), 3000);
|
||
|
||
dataRoles.push(role.role);
|
||
await member.edit({ roles: dataRoles }).catch(() => { error = true });
|
||
|
||
if (db.dm) {
|
||
const dmMessage = error
|
||
? client.translate.get(db.language, "Events.messageReactionAdd.noPerms").replace("{role}", `**${role.name}**`)
|
||
: client.translate.get(db.language, "Events.messageReactionAdd.success").replace("{role}", `**${role.name}**`);
|
||
|
||
await member?.user?.openDM()
|
||
.then(dm => dm.sendMessage(dmMessage))
|
||
.catch(() => {});
|
||
}
|
||
}
|
||
|
||
/**
|
||
* Main event handler for message reactions
|
||
* @param {Object} client - The client instance
|
||
* @param {Object} message - The message object
|
||
* @param {string} userId - The user ID
|
||
* @param {string} emojiId - The emoji ID
|
||
* @returns {Promise<void>}
|
||
*/
|
||
module.exports = async (client, message, userId, emojiId) => {
|
||
try {
|
||
const paginateCheck = client.paginate.get(userId);
|
||
const pollCheck = client.polls.get(message.id);
|
||
const collector = client.messageCollector.get(userId);
|
||
const editCollector = client.messageEdit.get(userId);
|
||
|
||
// Handle message collector
|
||
if (collector && (collector.messageId === message.id || (collector?.oldMessageId === message.id && collector.channelId === message.channelId))) {
|
||
return await handleMessageCollector(client, message, userId, emojiId, collector);
|
||
}
|
||
|
||
// Handle edit collector
|
||
if (editCollector && (editCollector.messageId === message.id || (editCollector?.botMessage === message.id && editCollector.channelId === message.channelId))) {
|
||
return await handleMessageCollector(client, message, userId, emojiId, editCollector);
|
||
}
|
||
|
||
// Handle pagination
|
||
if (paginateCheck && paginateCheck.message === message.id) {
|
||
return await handlePagination(client, message, paginateCheck, emojiId);
|
||
}
|
||
|
||
// Handle poll
|
||
if (pollCheck) {
|
||
return await handlePoll(client, message, pollCheck, userId, emojiId);
|
||
}
|
||
|
||
// Handle giveaway
|
||
const giveaway = await Giveaways.findOne({ messageId: message.id });
|
||
if (giveaway) {
|
||
return await handleGiveaway(client, message, giveaway, userId, emojiId);
|
||
}
|
||
|
||
// Handle role reaction
|
||
const db = await client.database.getGuild(message.server.id, true);
|
||
if (db?.roles.find(e => e.msgId === message.id)?.roles.find(e => e.emoji === emojiId)) {
|
||
return await handleRoleReaction(client, message, db, userId, emojiId);
|
||
}
|
||
} catch (error) {
|
||
console.error('Error in messageReactionAdd:', error);
|
||
}
|
||
}; |