const { parseDuration } = require('/parseDuration.js');
const { addGiveaway, addUserToGiveawayDB, fetchParticipantsFromDB, deleteGiveaway, getGiveawayDetails, removeWinnersFromDB, getAllGiveawaysInfo, fetchParticipantsAll, getActiveGiveaways, getEndedGiveaways, deletePermanentDB } = require('/giveawayDB.js');
const { EmbedBuilder } = require('discord.js');
async function startGiveaway(prize, duration, message, winnersCount, host) {
const em = new EmbedBuilder()
.setDescription(`**Giveaway Prize:** ${prize}\n**Winner(s):** ${winnersCount}\n**Host:** <@${host}>\n**Ends on:** <t:${Math.floor((Date.now() + parseDuration(duration))/1000)}:f> (<t:${Math.floor((Date.now() + parseDuration(duration))/1000)}:R>)\n\nReact 🎉 to join!`)
const giveawayMessage = await message.channel.send({ embeds: [em] });
giveawayMessage.react('🎉');
const endTime = Date.now() + parseDuration(duration);
const guildId = message.guild.id;
const channelId = message.channel.id;
addGiveaway(giveawayMessage.id, guildId, channelId, prize, endTime, winnersCount, hoster)
// Create a reaction collector for the giveaway message
const filter = (reaction, user) => reaction.emoji.name === '🎉' && !user.bot;
const collector = giveawayMessage.createReactionCollector({ filter, time: parseDuration(duration) });
collector.on('collect', (reaction, user) => {
addUserToGiveawayDB(giveawayMessage.id, user.id)
collector.on('end', async (collected, reason) => {
const details = await getGiveawayDetails(giveawayMessage.id);
return message.channel.send('Giveaway Message not found!')
const participantsArray = await fetchParticipantsFromDB(giveawayMessage.id);
const embed = new EmbedBuilder()
.setTitle('Giveaway Ended!')
.setDescription(`**Giveaway Prize:** ${prize}\n**Winner(s):** No eligible participants.`)
if (participantsArray.length === 0) {
await giveawayMessage.edit({ embeds: [embed] });
await deleteGiveaway(giveawayMessage.id);
const winnersCount = details.winnerCount;
const e = new EmbedBuilder()
.setTitle('Congratulations!')
.setDescription(`You have won the giveaway for **${details.prize}!**\nThis needs your immediate attention as **a rerolled prize will never come back!** | [Giveaway Link](https://discord.com/channels/${details.guildId}/${details.channelId}/${giveawayMessage.id})`)
for (let i = 0; i < winnersCount; i++) {
if (participantsArray.length === 0) {
break; // No more participants to select as winners
const randomIndex = Math.floor(Math.random() * participantsArray.length);
const winner = participantsArray.splice(randomIndex, 1)[0];
winners.push(`<@${winner}>`);
const embedWin = new EmbedBuilder()
.setTitle('Giveaway Ended!')
.setDescription(`**Giveaway Prize:** ${prize}\n**Winner(s):** ${winners.join(', ')}`)
if (winners.length > 0) {
await removeWinnersFromDB(giveawayMessage.id, win);
await giveawayMessage.edit({ embeds: [embedWin] });
await giveawayMessage.reply(`**Congratulations to ${winners.join(', ')} for winning!**`);
const user = message.guild.members.cache.get(u);
user.send({ embeds: [e] });
await giveawayMessage.edit({ embeds: [embed] });
await deleteGiveaway(giveawayMessage.id);
console.error("Error handling giveaway", error);
return message.channel.send('An error occurred while handling the giveaway.');
//timeout to end giveaway
}, parseDuration(duration));
async function stopGiveaway(giveawayId, message) {
const details = await getGiveawayDetails(giveawayId);
return message.channel.send('Giveaway already ended / not found!');
const guild = message.guild;
const giveawayChannel = guild.channels.cache.get(details.channelId);
const giveawayMessage = await giveawayChannel.messages.fetch(giveawayId);
return message.channel.send('Giveaway Message not found!')
const participantsArray = await fetchParticipantsFromDB(giveawayId);
const embed = new EmbedBuilder()
.setTitle('Giveaway Ended!')
.setDescription(`**Giveaway Prize:** ${details.prize}\n**Winner(s):** No eligible participants.`)
if (participantsArray.length === 0) {
await giveawayMessage.edit({ embeds: [embed] });
await deleteGiveaway(giveawayId);
return message.channel.send('Giveaway manually ended.');
const winnersCount = details.winnerCount;
const e = new EmbedBuilder()
.setTitle('Congratulations!')
.setDescription(`You have won the giveaway for **${details.prize}!**\nThis needs your immediate attention as **a rerolled prize will never come back!** | [Giveaway Link](https://discord.com/channels/${details.guildId}/${details.channelId}/${giveawayId})`)
for (let i = 0; i < winnersCount; i++) {
if (participantsArray.length === 0) {
const randomIndex = Math.floor(Math.random() * participantsArray.length);
const winner = participantsArray.splice(randomIndex, 1)[0];
winners.push(`<@${winner}>`);
const embedWin = new EmbedBuilder()
.setTitle('Giveaway Ended!')
.setDescription(`**Giveaway Prize:** ${details.prize}\n**Winner(s):** ${winners.join(', ')}`)
if (winners.length > 0) {
await removeWinnersFromDB(giveawayMessage.id, win);
await giveawayMessage.edit({ embeds: [embedWin] });
await giveawayMessage.reply(`**Congratulations to ${winners.join(', ')} for winning!**`);
const user = guild.members.cache.get(u);
user.send({ embeds: [e] });
await giveawayMessage.edit({ embeds: [embed] });
await deleteGiveaway(giveawayId);
return message.channel.send('Giveaway manually ended.');
console.error("Error handling giveaway", error);
return message.channel.send('An error occurred while handling the giveaway.');
async function rerollGiveaway(giveawayId, winnersCount, message) {
const details = await getAllGiveawaysInfo(giveawayId);
return message.channel.send('Giveaway not found!');
const guild = message.guild;
const giveawayChannel = guild.channels.cache.get(details.channelId);
const giveawayMessage = await giveawayChannel.messages.fetch(giveawayId);
if (Date.now() < details.endTime) {
return message.channel.send('Giveaway not ended!')
return message.channel.send('Giveaway Message not found!')
if (winnersCount > details.winnerCount) {
.send('You cannot reroll a giveaway to have more winners than specified in the original!')
const participantsArray = await fetchParticipantsAll(giveawayId);
const embed = new EmbedBuilder()
.setTitle('Giveaway Ended!')
.setDescription(`**Giveaway Prize:** ${details.prize}\n**Winner(s):** No eligible participants.`)
if (participantsArray.length === 0) {
return message.channel.send('No more participants to reroll.');
const e = new EmbedBuilder()
.setTitle('Congratulations!')
.setDescription(`You have won the giveaway for **${details.prize}!**\nThis needs your immediate attention as **a rerolled prize will never come back!** | [Giveaway Link](https://discord.com/channels/${details.guildId}/${details.channelId}/${giveawayId})`)
for (let i = 0; i < winnersCount; i++) {
if (participantsArray.length === 0) {
const randomIndex = Math.floor(Math.random() * participantsArray.length);
const winner = participantsArray.splice(randomIndex, 1)[0];
winners.push(`<@${winner}>`);
const embedWin = new EmbedBuilder()
.setTitle('Giveaway Ended!')
.setDescription(`**Giveaway Prize:** ${details.prize}\n**Winner(s):** ${winners.join(', ')}`)
if (winners.length > 0) {
await removeWinnersFromDB(giveawayMessage.id, win);
await giveawayMessage.edit({ embeds: [embedWin] });
await giveawayMessage.reply(`**Congratulations to ${winners.join(', ')} for winning!**`);
const user = guild.members.cache.get(u);
user.send({ embeds: [e] });
await giveawayMessage.edit({ embeds: [embed] });
return message.channel.send('Giveaway rerolled.');
console.error("Error handling giveaway", error);
return message.channel.send('An error occurred while handling the giveaway.');
async function createGiveawayEmbed(giveaways, title) {
for (const giveaway of giveaways) {
const endTime = new Date(giveaway.endTime);
w.push(`\n\n${i} | ${giveaway.id} | ${giveaway.prize} | <t:${Math.floor(endTime/1000)}:f>`)
const em = new EmbedBuilder()
.setDescription(`** S No. | ID | Prize | End Time |**${w}`)
async function giveawaysList(message) {
const guildId = message.guild.id;
const currentTime = Date.now();
const activeGiveaways = await getActiveGiveaways(guildId);
const endedGiveaways = await getEndedGiveaways(guildId, currentTime);
if (activeGiveaways.length > 0) {
const em = await createGiveawayEmbed(activeGiveaways, 'Active Giveaways');
message.channel.send({ embeds: [em] });
message.channel.send('No active giveaways!');
if (endedGiveaways.length > 0) {
const emb = await createGiveawayEmbed(endedGiveaways, 'Ended Giveaways');
message.channel.send({ embeds: [emb] });
message.channel.send('No ended giveaways');
// function to cancel an ongoing giveaway
async function cancelGiveaway(giveawayId, reason, message) {
const details = await getGiveawayDetails(giveawayId);
return message.channel.send('Giveaway already ended / not found')
const guild = message.guild;
const giveawayChannel = guild.channels.cache.get(details.channelId);
const giveawayMessage = await giveawayChannel.messages.fetch(giveawayId);
return message.channel.send('Giveaway message not found!')
const embed = new EmbedBuilder()
.setTitle('Giveaway Cancelled!')
.setDescription(`This giveaway has unfortunately been called off.\n\n**Reason:** ${reason}`)
await deletePermanentDB(giveawayId);
await deleteGiveaway(giveawayId);
giveawayMessage.edit({ embeds: [embed] });
message.channel.send('Giveaway cancelled!');
// function to get giveaway status
async function giveawayStatus(giveawayId) {
const details = await getAllGiveawaysInfo(giveawayId);
return "Giveaway not found or cancelled!";
if (Date.now() < details.endTime) {
// function to get info of a giveaway.
async function giveawayInfo(giveawayId, message) {
const details = await getAllGiveawaysInfo(giveawayId);
return message.channel.send("Invalid / cancelled giveaway!");
const endTime = new Date(details.endTime);
const status = await giveawayStatus(giveawayId);
const embed = new EmbedBuilder()
.setTitle('Giveaway Info')
.setDescription('Here are some insights of the giveaway:')
{name: 'ID', value: `${giveawayId}`},
{name: 'Prize', value: `${details.prize}`},
{name: 'Status', value: `${status}`},
{name: 'Host', value: `<@${details.hoster}>`},
{name: 'Channel', value: `<#${details.channelId}>`},
{name: 'End Time', value: `<t:${Math.floor(endTime/1000)}:f>`},
await message.channel.send({ embeds: [embed] });