arabs-giveaways
Version:
NPM packages designed to make it easier for arab developers make giveaways.
127 lines (112 loc) • 4.7 kB
JavaScript
const scheduler = require('node-schedule');
const GiveawayModel = require('../models/GiveawayModel');
function getWinner(users, max) {
if (users.length <= max) return users;
const numbers = new Set();
const array = [];
let i = 0;
while(i < max) {
const random = Math.floor(Math.random() * users.length);
const selected = users[random];
if (!numbers.has(random)) {
array.push(selected);
i++
}
}
return array;
}
async function schedule(client, giveawayArray) {
for(let i = 0; i < giveawayArray.length; i++) {
let { messageId, channelId, endsOn, hostedBy, prize, winners } = giveawayArray[i];
scheduler.scheduleJob(`${messageId}`, endsOn, async () => {
const channel = client.channels.cache.get(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, 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 ${winner}, you won the **${prize}**!\n${message.url}`);
endGiveaway(messageId);
}
}
}
});
}
}
async function endGiveaway(messageId) {
let data = await GiveawayModel.findOne({ messageId: messageId });
data.hasEnded = 'True';
await data.save();
}
async function remainingTime() {
return this.endsOn - Date.now();
}
/**
* Gets the content of the giveaway
* @type {string}
* @readonly
*/
async function content() {
let roundTowardsZero = this.remainingTime > 0 ? Math.floor : Math.ceil;
this.messages.units.days = "days"
this.messages.units.hours = "hours"
this.messages.units.minutes = "minutes"
this.messages.units.seconds = "seconds"
// Gets days, hours, minutes and seconds
let days = roundTowardsZero(this.remainingTime / 86400000),
hours = roundTowardsZero(this.remainingTime / 3600000) % 24,
minutes = roundTowardsZero(this.remainingTime / 60000) % 60,
seconds = roundTowardsZero(this.remainingTime / 1000) % 60;
// Increment seconds if equal to zero
if (seconds === 0) seconds++;
// Whether values are inferior to zero
let isDay = days > 0,
isHour = hours > 0,
isMinute = minutes > 0;
let dayUnit =
days < 2 && (false || false)
? this.messages.units.days.substr(0, this.messages.units.days.length - 1)
: this.messages.units.days,
hourUnit =
hours < 2 && (false || false)
? this.messages.units.hours.substr(0, this.messages.units.hours.length - 1)
: this.messages.units.hours,
minuteUnit =
minutes < 2 && (false || false)
? this.messages.units.minutes.substr(0, this.messages.units.minutes.length - 1)
: this.messages.units.minutes,
secondUnit =
seconds < 2 && (false || false)
? this.messages.units.seconds.substr(0, this.messages.units.seconds.length - 1)
: this.messages.units.seconds;
// Generates a first pattern
let pattern =
(!isDay ? '' : `{days} ${dayUnit}, `) +
(!isHour ? '' : `{hours} ${hourUnit}, `) +
(!isMinute ? '' : `{minutes} ${minuteUnit}, `) +
`{seconds} ${secondUnit}`;
// Format the pattern with the right values
let content = remainingTime()
.replace('{duration}', pattern)
.replace('{days}', days.toString())
.replace('{hours}', hours.toString())
.replace('{minutes}', minutes.toString())
.replace('{seconds}', seconds.toString());
return content;
}
module.exports = {
getWinner,
schedule,
endGiveaway,
remainingTime,
content
}