Zonies-Bot/events/messageReactionAdd.js
2025-05-12 15:20:40 -05:00

362 lines
16 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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);
}
};