UNPKG

djs-systems

Version:

The simplest way to build complex Discord bots.

470 lines (469 loc) 24.8 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.giveaway = void 0; const discord_js_1 = require("discord.js"); const giveaway_1 = __importDefault(require("./model/giveaway")); const misc_1 = require("./misc"); const error_1 = require("./error"); // ------------------------------ // ------ F U N C T I O N ------- // ------------------------------ /** * A **Powerful** yet simple giveaway system | *Required: **manageGiveaway() * @param msgOrInt * @param options * @link `Documentation:` https://simplyd.js.org/docs/systems/giveway * @example simplydjs.giveaway(interaction) */ async function giveaway(msgOrInt, options = { strict: false }) { return new Promise(async (resolve) => { try { const { client } = msgOrInt; let interaction; if (msgOrInt.commandId) { interaction = msgOrInt; } const extInteraction = msgOrInt; const extMessage = msgOrInt; const timeStart = Date.now(); let manager; if (options?.manager) manager = options.manager; else if (options?.manager) manager = await msgOrInt.member.roles.cache.find((r) => r.id === options.manager); if (!(manager || msgOrInt?.member?.permissions?.has(discord_js_1.PermissionFlagsBits.ManageEvents) || msgOrInt?.member?.permissions?.has(discord_js_1.PermissionFlagsBits.ManageGuild) || msgOrInt?.member?.permissions?.has(discord_js_1.PermissionFlagsBits.Administrator))) { if (interaction) return extInteraction.reply({ content: 'You must have • `Administrator`/`Manage Guild`/`Manage Events` Permission or • Giveaway Manager Role to perform this action', ephemeral: true }); else return extMessage.reply({ content: 'You must have • `Administrator`/`Manage Guild`/`Manage Events` Permission or • Giveaway Manager Role to perform this action' }); } if (msgOrInt.commandId && !interaction.deferred) await interaction.deferReply({ fetchReply: true }); options.winners ??= 1; const buttonStyles = { enter: { style: options.buttons?.enter?.style || discord_js_1.ButtonStyle.Success, label: options.buttons?.enter?.label || '0', emoji: options.buttons?.enter?.emoji || '🎁' }, end: { style: options.buttons?.end?.style || discord_js_1.ButtonStyle.Danger, label: options.buttons?.end?.label || 'End', emoji: options.buttons?.end?.emoji || '⛔' }, reroll: { style: options.buttons?.reroll?.style || discord_js_1.ButtonStyle.Primary, label: options.buttons?.reroll?.label || 'Reroll', emoji: options.buttons?.reroll?.emoji || '🔁' } }; if (!options.embed) { options.embed = { giveaway: { footer: { text: '©️ Rahuletto. npm i simply-djs', iconURL: 'https://i.imgur.com/XFUIwPh.png' }, color: (0, misc_1.toRgb)('#406DBC'), title: 'Giveaway !' } }; } let channel; let time; let winners; let prize; let requirements = { type: 'None', value: null }; let content = '** **'; if (options?.pingRole) content = options.pingRole.toString(); else if (options?.pingRole) content = (await msgOrInt.member.roles.cache.find((r) => r.id === options.pingRole)).toString(); if (options?.requirements?.type === 'Role') { const role = await msgOrInt.guild.roles.fetch(options.requirements?.id, { force: true }); requirements = { type: 'Role', value: role }; } else if (options?.requirements?.type === 'Guild') { const guild = await client.guilds.cache.get(options.requirements?.id); if (!guild) return extMessage.channel.send({ content: 'Please add me to that server so I can set the requirement.' }); requirements = { type: 'Guild', value: guild }; } if (interaction) { channel = options.channel || extInteraction.options.get('channel')?.channel || interaction.channel; time = options.time || extInteraction.options.get('time')?.value.toString() || '1h'; winners = options.winners || Number(extInteraction.options.get('winners')?.value); prize = options.prize || extInteraction.options.get('prize')?.value?.toString(); } else if (!interaction) { const [...args] = extMessage.content.split(/ +/g); if (!Number(args[2])) return extMessage.reply({ content: 'Please provide a number for winners argument' }); channel = options.channel || extMessage.mentions?.channels?.first() || extMessage.channel; time = options.time || args[1] || '1h'; winners = Number(args[2]) || options.winners; prize = options.prize || args.slice(3)?.join(' '); } if (buttonStyles?.enter?.style) buttonStyles.enter.style = (0, misc_1.toButtonStyle)(buttonStyles?.enter?.style); if (buttonStyles?.end?.style) buttonStyles.end.style = (0, misc_1.toButtonStyle)(buttonStyles?.end?.style); if (buttonStyles?.reroll?.style) buttonStyles.reroll.style = (0, misc_1.toButtonStyle)(buttonStyles?.reroll?.style); const enter = new discord_js_1.ButtonBuilder() .setCustomId('enter_giveaway') .setStyle(buttonStyles?.enter?.style || discord_js_1.ButtonStyle.Success); if (options?.type === 'Emoji') enter.setEmoji(buttonStyles?.enter?.emoji || '🎁'); else if (options?.type === 'Label') enter.setLabel(buttonStyles?.enter?.label || '0'); else { enter .setEmoji(buttonStyles?.enter?.emoji || '🎁') .setLabel(buttonStyles?.enter?.label || '0'); } const end = new discord_js_1.ButtonBuilder() .setCustomId('end_giveaway') .setStyle(buttonStyles?.end?.style || discord_js_1.ButtonStyle.Danger); if (options?.type === 'Emoji') end.setEmoji(buttonStyles?.end?.emoji || '⛔'); else if (options?.type === 'Label') end.setLabel(buttonStyles?.end?.label || 'End'); else { end .setEmoji(buttonStyles?.end?.emoji || '⛔') .setLabel(buttonStyles?.end?.label || 'End'); } const reroll = new discord_js_1.ButtonBuilder() .setCustomId('reroll_giveaway') .setStyle(buttonStyles?.reroll?.style || discord_js_1.ButtonStyle.Primary) .setDisabled(true); if (options?.type === 'Emoji') reroll.setEmoji(buttonStyles?.reroll?.emoji || '🔁'); else if (options?.type === 'Label') reroll.setLabel(buttonStyles?.reroll?.label || 'Reroll'); else { reroll .setEmoji(buttonStyles?.reroll?.emoji || '🔁') .setLabel(buttonStyles?.reroll?.label || 'Reroll'); } const row = new discord_js_1.ActionRowBuilder().addComponents([ enter, reroll, end ]); const timeInMS = (0, misc_1.ms)(time); const endTime = Number((Date.now() + timeInMS).toString().slice(0, -3)); const fields = options?.embed?.giveaway?.fields || [ { name: 'Prize', value: `{prize}` }, { name: 'Hosted By', value: `{hosted}`, inline: true }, { name: 'Ends at', value: `{endsAt}`, inline: true }, { name: 'Winner(s)', value: `{winCount}`, inline: true }, { name: 'Requirements', value: `{requirements}` } ]; let guildInvite; if (requirements.type == 'Guild') { await requirements.value.invites .fetch() .then((a) => { guildInvite = `https://discord.gg/${a.first()}`; }); } function replacer(str) { return str .replaceAll('{hosted}', `<@${msgOrInt.member.user.id}>`) .replaceAll('{endsAt}', `<t:${endTime}:f>`) .replaceAll('{prize}', prize) .replaceAll('{requirements}', requirements.type === 'None' ? 'None' : requirements.type + ' | ' + (requirements.type === 'Guild' ? `${guildInvite}` : `${requirements.value}`)) .replaceAll('{winCount}', winners.toString()) .replaceAll('{entered}', '0'); } fields?.forEach((a) => { a.value = replacer(a?.value); }); const embed = new discord_js_1.EmbedBuilder() .setTitle(replacer(options?.embed?.giveaway?.title || 'Giveaway Time!')) .setColor(options?.embed?.giveaway?.color || (0, misc_1.toRgb)('#406DBC')) .setTimestamp(Number(Date.now() + timeInMS)) .setFooter(options?.embed?.giveaway?.footer ? options?.embed?.giveaway?.footer : { text: '©️ Rahuletto. npm i simply-djs', iconURL: 'https://i.imgur.com/XFUIwPh.png' }) .setDescription(replacer(options?.embed?.giveaway?.description || `Interact with the giveaway using the buttons below.`)) .setFields(options?.embed?.giveaway?.fields); if (options?.embed?.giveaway?.author) embed.setAuthor(options.embed?.giveaway?.author); if (options?.embed?.giveaway?.image) embed.setImage(options.embed?.giveaway?.image); if (options?.embed?.giveaway?.thumbnail) embed.setThumbnail(options.embed?.giveaway?.thumbnail); if (options?.embed?.giveaway?.timestamp) embed.setTimestamp(options.embed?.giveaway?.timestamp); if (options?.embed?.giveaway?.title) embed.setTitle(options.embed?.giveaway?.title); if (options?.embed?.giveaway?.url) embed.setURL(options.embed?.giveaway?.url); await channel .send({ content: content, embeds: [embed], components: [row] }) .then(async (msg) => { const end = Number(Date.now() + timeInMS); resolve({ message: msg, winners: winners, prize: prize, endsAt: end, requirements: requirements }); const link = new discord_js_1.ButtonBuilder() .setLabel('View Giveaway.') .setStyle(discord_js_1.ButtonStyle.Link) .setURL(msg.url); const linkRow = new discord_js_1.ActionRowBuilder().addComponents([ link ]); if (interaction) { await extInteraction.followUp({ content: 'Giveaway has started.', components: [linkRow] }); } else await extMessage.channel.send({ content: 'Giveaway has started.', components: [linkRow] }); options.embed.giveaway.fields = fields; const createDb = new giveaway_1.default({ message: msg.id, entered: 0, winCount: winners, description: options.embed?.giveaway?.description || null, embeds: options.embed, requirements: { type: requirements?.type === 'None' ? 'none' : requirements?.type?.toLowerCase(), id: requirements?.value?.id }, started: timeStart, prize: prize, entry: [], endTime: end, host: msgOrInt.member.user.id }); await createDb.save(); const timer = setInterval(async () => { if (!msg) return; const components = discord_js_1.ActionRowBuilder.from(msg?.components[0]); const data = await giveaway_1.default.findOne({ message: msg.id }); if (data.endTime && Number(data.endTime) < Date.now()) { const loadEmbed = new discord_js_1.EmbedBuilder() .setTitle(data?.embeds?.load?.title || 'Processing Tickets...') .setColor(data?.embeds?.load?.color || (0, misc_1.toRgb)('#cc0000')) .setDescription(data?.embeds?.load?.description || `Please wait.. We are shuffling the members to pick a winner.`) .setFooter(data?.embeds?.load?.footer || { text: 'Ending the Giveaway, Choosing a winner...' }); if (data?.embeds?.load?.fields) loadEmbed.setFields(data?.embeds?.load?.fields); if (data?.embeds?.load?.author) loadEmbed.setAuthor(data?.embeds?.load?.author); if (data?.embeds?.load?.image) loadEmbed.setImage(data?.embeds?.load?.image); if (data?.embeds?.load?.thumbnail) loadEmbed.setThumbnail(data?.embeds?.load?.thumbnail); if (data?.embeds?.load?.timestamp) loadEmbed.setTimestamp(data?.embeds?.load?.timestamp); if (data?.embeds?.load?.title) loadEmbed.setTitle(data?.embeds?.load?.title); if (data?.embeds?.load?.url) loadEmbed.setURL(data?.embeds?.load?.url); clearInterval(timer); await msg .edit({ embeds: [loadEmbed], components: [] }) .catch(() => { }); const displayWinner = []; const winnerArray = []; const winnerCount = data.winCount; const entries = data.entry; for (let i = 0; i < winnerCount; i++) { const win = Math.floor(Math.random() * data.entered); if (entries.length != 0) winnerArray.push(entries[win]); } const oldFields = msg.embeds[0].fields; const resultWinner = []; setTimeout(() => { winnerArray.forEach(async (name) => { await interaction.guild.members .fetch(name?.userId) .then((member) => { resultWinner.push(member); displayWinner.push(`<@${member.user.id}>`); const dmEmbed = new discord_js_1.EmbedBuilder() .setTitle('You, Won the Giveaway!') .setDescription(`You just won \`${data.prize}\` in the Giveaway at \`${member.guild.name}\` Go claim it fast !`) .setColor('DarkGreen') .setFooter(data?.embeds?.result?.footer || { text: 'GG winner.' }); const linkButton = new discord_js_1.ButtonBuilder() .setLabel('View Giveaway') .setStyle(discord_js_1.ButtonStyle.Link) .setURL(msg.url); const linkRow = new discord_js_1.ActionRowBuilder().addComponents([ linkButton ]); return member .send({ embeds: [dmEmbed], components: [linkRow] }) .catch(() => { }); }) .catch(() => { }); }); }, (0, misc_1.ms)('2s')); setTimeout(async () => { if (!data) return await msg.delete(); if (data) { const embed = discord_js_1.EmbedBuilder.from(msg.embeds[0]); const time = Number(data.endTime); const fields = []; data?.embeds?.result?.fields.forEach((a) => { if (a.name === 'Requirements') return; a.value = a.value .replaceAll('{hosted}', `<@${data.host}>`) .replaceAll('{endsAt}', `<t:${time}:f>`) .replaceAll('{prize}', data.prize.toString()) .replaceAll('{winCount}', data.winCount.toString()) .replaceAll('{entered}', data.entered.toString()); fields.push(a); }); if (data.entered <= 0 || entries.length == 0 || !winnerArray[0]) { embed .setTitle('No one entered') .setFields(fields || oldFields) .setColor((0, misc_1.toRgb)('#cc0000')) .setFooter({ text: 'Ohh man, Its ok lets get another giveaway goin.' }); return await msg.edit({ embeds: [embed], components: (0, misc_1.disableButtons)([ components ]) }); } const b1 = discord_js_1.ButtonBuilder.from(components .components[0]).setDisabled(true); const b2 = discord_js_1.ButtonBuilder.from(components .components[1]).setDisabled(false); const b3 = discord_js_1.ButtonBuilder.from(components .components[2]).setDisabled(true); const buttonRow = new discord_js_1.ActionRowBuilder().setComponents([ b1, b2, b3 ]); const resultEmbed = new discord_js_1.EmbedBuilder() .setTitle(data?.embeds?.result?.title || 'And the winner is,') .setColor(data?.embeds?.result?.color || 'DarkGreen') .setDescription(data?.embeds?.result?.description.replaceAll('{winners}', displayWinner.join(', ')) || `${displayWinner.join(', ')} won the prize !\nGet in touch with the staff members to collect your prize.`) .setFooter(data?.embeds?.result?.footer || { text: 'GG winner.' }) .setFields(fields || oldFields); if (data?.embeds?.result?.author) resultEmbed.setAuthor(data?.embeds?.result?.author); if (data?.embeds?.result?.image) resultEmbed.setImage(data?.embeds?.result?.image); if (data?.embeds?.result?.thumbnail) resultEmbed.setThumbnail(data?.embeds?.result?.thumbnail); if (data?.embeds?.result?.timestamp) resultEmbed.setTimestamp(data?.embeds?.result?.timestamp); if (data?.embeds?.result?.title) resultEmbed.setTitle(data?.embeds?.result?.title); if (data?.embeds?.result?.url) resultEmbed.setURL(data?.embeds?.result?.url); await msg.edit({ embeds: [resultEmbed], components: [buttonRow] }); resolve({ type: 'End', url: msg.url, user: resultWinner }); } }, (0, misc_1.ms)('6s')); } }, timeInMS); }); } catch (err) { if (options?.strict) throw new error_1.SimplyError({ function: 'giveaway', title: 'An Error occured when running the function ', tip: err.stack }); else console.log(`SimplyError - giveaway | Error: ${err.stack}`); } }); } exports.giveaway = giveaway;