MCPcopy Index your code
hub / github.com/Androz2091/discord-giveaways

github.com/Androz2091/discord-giveaways @v6.0.1

Chat with this repo
repository ↗ · DeepWiki ↗ · release v6.0.1 ↗ · + Follow
119 symbols 209 edges 15 files 51 documented · 43%
What it actually does AI analysis from the code graph — generated when you open this
loading…
README

Discord Giveaways

discordBadge downloadsBadge versionBadge documentationBadge

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

Features

  • ⏱️ Easy to use!
  • 🔄 Automatic restart after bot crash!
  • 🇫🇷 Support for translations: adapt the strings for your own language!
  • 📁 Support for all databases! (default is json)
  • ⚙️ Very customizable! (prize, duration, winners, ignored permissions, bonus entries, etc...)
  • 🚀 Super powerful: start, edit, reroll, end, delete and pause giveaways!
  • 💥 Events: giveawayEnded, giveawayRerolled, giveawayDeleted, giveawayReactionAdded, giveawayReactionRemoved, endedGiveawayReactionAdded
  • 🕸️ Support for shards!
  • and much more!

Installation

npm install --save discord-giveaways

Examples

You can read this example bot on GitHub: discord-giveaways-bot

Launch of the module

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

const Discord = require('discord.js');
const client = new Discord.Client({
    intents: [
        Discord.IntentsBitField.Flags.Guilds,
        Discord.IntentsBitField.Flags.GuildMessageReactions,
        Discord.IntentsBitField.Flags.GuildMembers // Optional, for better performance
    ]
});

// Requires Manager from discord-giveaways
const { GiveawaysManager } = require('discord-giveaways');
const manager = new GiveawaysManager(client, {
    storage: './giveaways.json',
    default: {
        botsCanWin: false,
        embedColor: '#FF0000',
        embedColorEnd: '#000000',
        reaction: '🎉'
    }
});
// We now have a giveawaysManager property to access the manager everywhere!
client.giveawaysManager = manager;

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

client.login(process.env.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') {
        // /start 2d 1 Awesome prize!
        // Will create a giveaway with a duration of two days, with one winner and the prize will be "Awesome prize!"

        const duration = interaction.options.getString('duration');
        const winnerCount = interaction.options.getInteger('winners');
        const prize = interaction.options.getString('prize');

        client.giveawaysManager
            .start(interaction.channel, {
                duration: ms(duration),
                winnerCount,
                prize
            })
            .then((data) => {
                console.log(data); // {...} (messageId, end date and more)
            });
        // And the giveaway has started!
    }
});

This allows you to start a new giveaway. Once the start() 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 prize or the messageId of a giveaway. To prevent abuse we recommend to check if the prize or 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 giveaway prize
    client.giveawaysManager.giveaways.find((g) => g.guildId === interaction.guildId && g.prize === query) ||
    // Search with messageId
    client.giveawaysManager.giveaways.find((g) => g.guildId === interaction.guildId && g.messageId === 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');
        client.giveawaysManager
            .reroll(messageId)
            .then(() => {
                interaction.reply('Success! Giveaway rerolled!');
            })
            .catch((err) => {
                interaction.reply(`An error has occurred, please check and try again.\n\`${err}\``);
            });
    }
});
  • options.winnerCount: the number of winners to pick.
  • options.messages: an object with the "congrat" and the "error" message. Usage example.
  • options.messages.replyWhenNoWinner: Whether or not to send the "error" message when there is no winner.

Edit a giveaway

client.on('interactionCreate', (interaction) => {
    if (interaction.isChatInputCommand() && interaction.commandName === 'edit') {
        const messageId = interaction.options.getString('message_id');
        client.giveawaysManager
            .edit(messageId, {
                addTime: 5000,
                newWinnerCount: 3,
                newPrize: 'New Prize!'
            })
            .then(() => {
                interaction.reply('Success! Giveaway updated!');
            })
            .catch((err) => {
                interaction.reply(`An error has occurred, please check and try again.\n\`${err}\``);
            });
    }
});

Note: to reduce giveaway duration, define addTime with a negative number! For example addTime: -5000 will reduce giveaway duration by 5 seconds!

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(messageId)
            .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

Pause a giveaway

client.on('interactionCreate', (interaction) => {
    if (interaction.isChatInputCommand() && interaction.commandName === 'pause') {
        const messageId = interaction.options.getString('message_id');
        client.giveawaysManager
            .pause(messageId)
            .then(() => {
                interaction.reply('Success! Giveaway paused!');
            })
            .catch((err) => {
                interaction.reply(`An error has occurred, please check and try again.\n\`${err}\``);
            });
    }
});
  • options.content: the text of the embed when the giveaway is paused. You can access giveaway properties.
  • options.unpauseAfter: the number of milliseconds, or a timestamp in milliseconds, after which the giveaway will automatically unpause.
  • options.embedColor: the color of the embed when the giveaway is paused.
  • options.infiniteDurationText: The text that gets displayed next to GiveawayMessages#drawing in the paused embed, when there is no unpauseAfter.
    ^^^ You can access giveaway properties.

⚠️ Note: the pause function overwrites/edits the pauseOptions object property of a giveaway!

Unpause a giveaway

client.on('interactionCreate', (interaction) => {
    if (interaction.isChatInputCommand() && interaction.commandName === 'unpause') {
        const messageId = interaction.options.getString('message_id');
        client.giveawaysManager
            .unpause(messageId)
            .then(() => {
                interaction.reply('Success! Giveaway unpaused!');
            })
            .catch((err) => {
                interaction.reply(`An error has occurred, please check and try again.\n\`${err}\``);
            });
    }
});

Fetch giveaways

// A list of all the giveaways
const allGiveaways = client.giveawaysManager.giveaways; // [ {Giveaway}, {Giveaway} ]

// A list of all the giveaways on the server with Id "1909282092"
const onServer = client.giveawaysManager.giveaways.filter((g) => g.guildId === '1909282092');

// A list of the current active giveaways (not ended)
const notEnded = client.giveawaysManager.giveaways.filter((g) => !g.ended);

Exempt Members

Function to filter members. If true is returned, the member will not be able to win the giveaway.

client.giveawaysManager.start(interaction.channel, {
    duration: 60000,
    winnerCount: 1,
    prize: 'Free Steam Key',
    // Only members who have the "Nitro Boost" role are able to win
    exemptMembers: (member, giveaway) => !member.roles.cache.some((r) => r.name === 'Nitro Boost')
});

Note (only for proficients): if you want to use values of global variables inside of the function without using giveaway.extraData, you can use the Function constructor:

const roleName = 'Nitro Boost';

client.giveawaysManager.start(interaction.channel, {
    duration: 60000,
    winnerCount: 1,
    prize: 'Free Steam Key',
    // Only members who have the the role which is assigned to "roleName" are able to win
    exemptMembers: new Function(
        'member',
        'giveaway',
        `return !member.roles.cache.some((r) => r.name === '${roleName}')`
    )
});

⚠ Note

  • You can use this, instead of the giveaway parameter, inside of the function string to access anything of the giveaway instance.
    For example: this.extraData, or this.client.
  • Strings have to be "stringified" (wrapped in quotation marks) again like you can see in the example.
    Array brackets also have to be stated again.
  • Global variables which contain numbers with more than 16 digits cannot be used.
    => Snoflakes have to be "stringified" correctly to avoid misbehaviour.
  • If you want to make an asynchronous function in this format, refer to this article.
  • Because of those various complications it is therefore highly suggested to use giveaway.extraData for storing variables.
    But if you really want to do it in this way and need more information/help, please visit the Discord Server.

Last Chance

```js client.giveawaysManager.start(interaction.channel, { duration: 60000, winnerCount: 1, prize: 'Discord Nitro!', lastChance: { enabled: true

Extension points exported contracts — how you extend this code

Core symbols most depended-on inside this repo

Shape

Method 84
Class 24
Interface 11

Languages

TypeScript100%

Modules by API surface

src/Giveaway.js34 symbols
src/Manager.js21 symbols
typings/index.d.ts16 symbols
examples/custom-databases/replit.js6 symbols
examples/custom-databases/quickmongo.js6 symbols
examples/custom-databases/quick.replit.js6 symbols
examples/custom-databases/quick.db.js6 symbols
examples/custom-databases/nano.js6 symbols
examples/custom-databases/mysql.js6 symbols
examples/custom-databases/mongoose.js6 symbols
examples/custom-databases/enmap.js6 symbols

Datastores touched

giveawaysCollection · 1 repos
(mongodb)Database · 1 repos

For agents

$ claude mcp add discord-giveaways \
  -- python -m otcore.mcp_server <graph>

⬇ download graph artifact

Ask about this repo answers extend the page