npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

exsta-giveaways

v1.1.14

Published

🎉 Complete framework to facilitate the creation of giveaways using discord.js v14

Downloads

14

Readme

Exsta Giveaways

discordBadge downloadsBadge versionBadge

Exsta Giveaways is a powerful Node.js module that allows you to easily create giveaways!

Static Badge

Features

  • ⏱️ Easy to use!
  • 🔄 Automatic restart after bot crash!
  • ⚙️ Very customizable! (prize, duration, winners, ignored permissions, bonus entries, etc...)
  • 🚀 Super powerful: start, edit, reroll, end, delete giveaways!
  • 🕸️ Support for shards!

Installation

npm install --save exsta-giveaways

Launch of the module

Required Discord Intents: Guilds and GuildMessageReactions.
Optional Discord Privileged Intent for better performance: GuildMembers.

import { Client } from 'discord.js';

const client = new Client({
    intents: [
        Discord.IntentsBitField.Flags.Guilds,
        Discord.IntentsBitField.Flags.GuildMessageReactions,
        Discord.IntentsBitField.Flags.GuildMembers
    ]
});

// Requires Manager from exsta-giveaways

/*
    For TypeScript
*/

import { GiveawaysManager } from 'exsta-giveaways';

const manager = new GiveawaysManager(client, {
    storage: './giveaways.json',
    config: {
        botsCanWin: false,
        embedColor: '#FF0000',
        embedColorEnd: '#000000',
        reaction: '💫',
        botName: "Giveaway Bot",
        forceUpdateEvery: 3600,
        endedGiveawaysLifetime: 1_600_000,
    }
});

/*
    For JavaScript
*/
const gw = require('exsta-giveaways');

const manager = new gw.GiveawaysManager(client, {
    storage: './giveaways.json',
    config: {
        botsCanWin: false,
        embedColor: '#FF0000',
        embedColorEnd: '#000000',
        reaction: '💫',
        botName: "Giveaway Bot",
        forceUpdateEvery: 3600,
        endedGiveawaysLifetime: 1_600_000,
    }
});

// We now have a giveawaysManager property to access the manager everywhere!
client.giveawaysManager = manager;

client.on('ready', () => {
    console.log('Bot is ready!');
});

client.login("My cool discord bot token !");

After that, giveaways that are not yet completed will start to be updated again and new giveaways can be started. You can pass an options object to customize the giveaways. Here is a list of them:

Start a giveaway

client.on('interactionCreate', (interaction) => {
    const ms = require('ms');

    if (interaction.isChatInputCommand() && interaction.commandName === 'start-giveaway') {
        // /start-giveaway 2d 1 Awesome prize!
        // Will create a giveaway with a duration of two days, with one winner and the prize will be "Awesome prize!"

        await interaction.deferReply();

        let giveawayChannel = interaction.channel;
        var giveawayDuration = interaction.options.getString("time");
        let giveawayNumberWinners = interaction.options.getNumber("winner");

        if (isNaN(giveawayNumberWinners as number) || (parseInt(giveawayNumberWinners as unknown as string) <= 0)) {
            await interaction.editReply({ content: "You must specify a valid number of winners!" });
            return;
        };

        let giveawayPrize = interaction.options.getString("prize");
        let giveawayDurationFormated = ms(giveawayDuration as unknown as number);

        if (Number.isNaN(giveawayDurationFormated)) {
            await interaction.editReply({
                content: `${interaction.user}, the giveaway Duration you specified are invalid, please try again!`
            });
            return;
        };

        client.giveawaysManager.create(giveawayChannel as TextBasedChannel, {
            duration: parseInt(giveawayDurationFormated),
            prize: giveawayPrize,
            winnerCount: giveawayNumberWinners,
            hostedBy: interaction.user.id,
            embedImageURL: interaction.options.getString('imageURL') || undefined
        });
    }
});
  • options.duration: the giveaway duration.
  • options.prize: the giveaway prize.
  • options.winnerCount: the number of giveaway winners.

This allows you to start a new giveaway. Once the create() function is called, the giveaway starts, and you only have to observe the result, the package does the rest!

⚠ ATTENTION!

The command examples below (reroll, edit delete, end) can be executed on any server your bot is a member of if a person has the messageId of a giveaway. To prevent abuse we recommend to check if the messageId that was provided by the command user is for a giveaway on the same server, if it is not, then cancel the command execution.

const query = interaction.options.getString('query');
const giveaway =
    // Search with messageId
    client.giveawaysManager.isValid(query);

// If no giveaway was found
if (!giveaway) return interaction.reply(`Unable to find a giveaway for \`${query}\`.`);

Reroll a giveaway

client.on('interactionCreate', (interaction) => {
    if (interaction.isChatInputCommand() && interaction.commandName === 'reroll') {
        const messageId = interaction.options.getString('message_id');
        
        try {
            await client.giveawaysManager.reroll(client, messageId as string);
            
            interaction.reply('Success! Giveaway rerolled!');

        } catch (error) {
            
            interaction.reply(`An error has occurred, please check and try again\n\`${error}\``);

        };
    }
});

Delete a giveaway

client.on('interactionCreate', (interaction) => {
    if (interaction.isChatInputCommand() && interaction.commandName === 'delete') {
        const messageId = interaction.options.getString('message_id');
        
        client.giveawaysManager.delete(messageId)
            .then(() => {
                interaction.reply('Success! Giveaway deleted!');
            })
            .catch((err) => {
                interaction.reply(`An error has occurred, please check and try again.\n\`${err}\``);
            });
    }
});
  • doNotDeleteMessage: whether the giveaway message shouldn't be deleted.

⚠️ Note: when you use the delete function, the giveaway data and the message of the giveaway are deleted (by default). You cannot restore a giveaway once you have deleted it!

End a giveaway

client.on('interactionCreate', (interaction) => {
    if (interaction.isChatInputCommand() && interaction.commandName === 'end') {
        const messageId = interaction.options.getString('message_id');

        client.giveawaysManager.end(client, inputData as string)
            .then(() => {
                interaction.reply('Success! Giveaway ended!');
            })
            .catch((err) => {
                interaction.reply(`An error has occurred, please check and try again.\n\`${err}\``);
            });
    }
});
  • noWinnerMessage: Sent in the channel if there is no valid winner for the giveaway. Message Options