UNPKG

arabs-giveaways

Version:

NPM packages designed to make it easier for arab developers make giveaways.

212 lines (153 loc) 6.8 kB
const mongoose = require('mongoose'); const Discord = require('discord.js'); const Giveaway = require('./Giveaway'); const moment = require('moment'); const { schedule, getWinner, endGiveaway, remainingTime, content } = require('./functions'); const GiveawayModel = require('../models/GiveawayModel'); const scheduler = require('node-schedule'); class GiveawayCreator { /** * * @param {Discord.Client} client - A discord.js client. * @param {string} url - A MongoDB connection string. */ constructor(client, url = '') { if (!client) throw new Error("A client wasn't provided."); if (!url) throw new Error("A connection string wasn't provided."); this.client = client; this.mongoUrl = url; mongoose.connect(this.mongoUrl, { useNewUrlParser: true, useUnifiedTopology: true }); this.client.on('ready', async () => { const now = new Date(); const giveaways = await GiveawayModel.find({ endsOn: { $gt: now }, hasEnded: 'False' }); await schedule(this.client, giveaways); }); } /** * * @param {GiveawayOptions} options - Options for the giveaway. */ async startGiveaway(options) { if (!options.duration) throw new Error("You didn't provide a duration."); if (!options.channelId) throw new Error("You didn't provide a channel ID."); if (!options.guildId) throw new Error("You didn't provide a guild ID."); if (!options.prize) throw new Error("You didn't provide a prize."); if (!options.winners || isNaN(options.winners)) throw new Error("You didn't provide an amount of winners OR winners is not a number."); if (!options.hostedBy) throw new Error("Please provide a user ID for the person who hosted the giveaway."); const guild = this.client.guilds.cache.get(options.guildId); const channel = guild.channels.cache.get(options.channelId); const giveawayEmbed = new Discord.MessageEmbed() .setAuthor(options.prize) .setColor("#FF0000") .setDescription(`React with 🎉 to participate! Hosted By: ${this.client.users.cache.get(options.hostedBy).toString()}`) .setTimestamp(new Date(Date.now() + options.duration).toISOString()) .setFooter(`${options.winners} winner(s)`) const msg = await channel.send(giveawayEmbed); await msg.react('🎉'); const newGiveaway = new Giveaway({ prize: options.prize, duration: options.duration, channelId: options.channelId, guildId: options.guildId, endsOn: new Date(Date.now() + options.duration), startsOn: new Date(), messageId: msg.id, winners: options.winners, hostedBy: options.hostedBy }); await schedule(this.client, [newGiveaway]); return newGiveaway; } /** * * @param {string} messageId - A discord message ID. */ async endGiveaway(messageId) { let data = await GiveawayModel.findOne({ messageId: messageId }); if (!data) return false; if (data.hasEnded === 'True') return false; const job = scheduler.scheduledJobs[`${messageId}`]; if (!job) return false; job.cancel(); const channel = this.client.channels.cache.get(data.channelId); if (channel) { const message = await channel.messages.fetch(messageId); if (message) { const { embeds, reactions } = message; const reaction = reactions.cache.get('🎉'); const users = await reaction.users.fetch(); const entries = users.filter(user => !user.bot).array(); if (embeds.length === 1) { const embed = embeds[0]; const winner = getWinner(entries, data.winners); const finalWinners = winner.map(user => user.toString()).join(', '); embed.setDescription(`Winner(s): ${finalWinners}`); embed.setFooter("Ended at"); await message.edit(embed); message.channel.send(`Congratulations ${finalWinners}, you won the **${data.prize}**!\n${message.url}`); endGiveaway(messageId); } } } return data; } /** * * @param {string} messageId - A discord message ID. */ async fetchGiveaway(messageId) { const giveaway = await GiveawayModel.findOne({ messageId: messageId }); if (!giveaway) return false; return giveaway; } /** * * @param {string} messageId - A discord message ID. */ async rerollGiveaway(messageId) { const giveaway = await GiveawayModel.findOne({ messageId: messageId }); if (!giveaway) return false; if (giveaway.hasEnded === 'False') return false; const channel = this.client.channels.cache.get(giveaway.channelId); if (channel) { const message = await channel.messages.fetch(messageId); if (message) { const { embeds, reactions } = message; const reaction = reactions.cache.get('🎉'); const users = await reaction.users.fetch(); const entries = users.filter(user => !user.bot).array(); const winner = getWinner(entries, giveaway.winners); const finalWinners = winner.map(user => user.toString()).join(', '); message.channel.send(`Congratulations ${finalWinners}, you won the **${giveaway.prize}**!\n${message.url}`); if (embeds.length === 1) { const embed = embeds[0]; embed.setDescription(`Winner(s): ${finalWinners}`); await message.edit(embed); } } } return giveaway; } /** * * @param {string} guildId - A discord guild ID. */ async listGiveaways(guildId) { if (!guildId) throw new Error("Please provide a guild ID."); const Giveaways = await GiveawayModel.find({ guildId: guildId, hasEnded: 'False' }); if (Giveaways.length < 1) return false; const array = []; Giveaways.map(i => array.push({ hostedBy: this.client.users.cache.get(i.hostedBy).tag ? this.client.users.cache.get(i.hostedBy).tag : "Nobody#0000", timeRemaining: i.endsOn - Date.now(), messageId: i.messageId, prize: i.prize })); return array; } } module.exports = GiveawayCreator;