{"id":16621350,"url":"https://github.com/androz2091/discord-giveaways","last_synced_at":"2025-04-19T17:06:05.860Z","repository":{"id":34923687,"uuid":"189822036","full_name":"Androz2091/discord-giveaways","owner":"Androz2091","description":"🎉 Complete framework to facilitate the creation of giveaways using discord.js","archived":false,"fork":false,"pushed_at":"2023-07-23T12:45:54.000Z","size":1345,"stargazers_count":340,"open_issues_count":23,"forks_count":128,"subscribers_count":7,"default_branch":"master","last_synced_at":"2024-05-13T14:36:01.073Z","etag":null,"topics":["customizable","discord","discord-giveaway","discordbot","embeds","framework","multi-language-support"],"latest_commit_sha":null,"homepage":"https://discord-giveaways.js.org","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Androz2091.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"patreon":"androz2091","github":"Androz2091"}},"created_at":"2019-06-02T08:23:58.000Z","updated_at":"2024-06-18T12:31:03.181Z","dependencies_parsed_at":"2024-06-18T12:31:00.643Z","dependency_job_id":"92f30f99-93f8-4c9a-9e3d-c9439f273f37","html_url":"https://github.com/Androz2091/discord-giveaways","commit_stats":{"total_commits":634,"total_committers":28,"mean_commits":"22.642857142857142","dds":0.5078864353312302,"last_synced_commit":"cee7f6b61ba8be3125fdb872013b6dd332606c15"},"previous_names":[],"tags_count":39,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Androz2091%2Fdiscord-giveaways","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Androz2091%2Fdiscord-giveaways/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Androz2091%2Fdiscord-giveaways/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Androz2091%2Fdiscord-giveaways/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Androz2091","download_url":"https://codeload.github.com/Androz2091/discord-giveaways/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246173855,"owners_count":20735405,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["customizable","discord","discord-giveaway","discordbot","embeds","framework","multi-language-support"],"created_at":"2024-10-12T02:47:04.654Z","updated_at":"2025-03-30T23:32:43.628Z","avatar_url":"https://github.com/Androz2091.png","language":"JavaScript","funding_links":["https://patreon.com/androz2091","https://github.com/sponsors/Androz2091"],"categories":[],"sub_categories":[],"readme":"# Discord Giveaways\n\n[![discordBadge](https://img.shields.io/badge/Chat-Click%20here-7289d9?style=for-the-badge\u0026logo=discord)](https://discord.gg/r5mb9r5WXv)\n[![downloadsBadge](https://img.shields.io/npm/dt/discord-giveaways?style=for-the-badge)](https://npmjs.com/discord-giveaways)\n[![versionBadge](https://img.shields.io/npm/v/discord-giveaways?style=for-the-badge)](https://npmjs.com/discord-giveaways)\n[![documentationBadge](https://img.shields.io/badge/Documentation-Click%20here-blue?style=for-the-badge)](https://discord-giveaways.js.org)\n\nDiscord Giveaways is a powerful [Node.js](https://nodejs.org) module that allows you to easily create giveaways!\n\n## Features\n\n-   ⏱️ Easy to use!\n-   🔄 Automatic restart after bot crash!\n-   🇫🇷 Support for translations: adapt the strings for your own language!\n-   📁 Support for all databases! (default is json)\n-   ⚙️ Very customizable! (prize, duration, winners, ignored permissions, bonus entries, etc...)\n-   🚀 Super powerful: start, edit, reroll, end, delete and pause giveaways!\n-   💥 Events: giveawayEnded, giveawayRerolled, giveawayDeleted, giveawayReactionAdded, giveawayReactionRemoved, endedGiveawayReactionAdded\n-   🕸️ Support for shards!\n-   and much more!\n\n## Installation\n\n```bash\nnpm install --save discord-giveaways\n```\n\n## Examples\n\nYou can read this example bot on GitHub: [discord-giveaways-bot](https://github.com/Androz2091/discord-giveaways-bot)\n\n### Launch of the module\n\nRequired Discord Intents: `Guilds` and `GuildMessageReactions`.  \nOptional Discord Privileged Intent for better performance: `GuildMembers`.\n\n```js\nconst Discord = require('discord.js');\nconst client = new Discord.Client({\n    intents: [\n        Discord.IntentsBitField.Flags.Guilds,\n        Discord.IntentsBitField.Flags.GuildMessageReactions,\n        Discord.IntentsBitField.Flags.GuildMembers // Optional, for better performance\n    ]\n});\n\n// Requires Manager from discord-giveaways\nconst { GiveawaysManager } = require('discord-giveaways');\nconst manager = new GiveawaysManager(client, {\n    storage: './giveaways.json',\n    default: {\n        botsCanWin: false,\n        embedColor: '#FF0000',\n        embedColorEnd: '#000000',\n        reaction: '🎉'\n    }\n});\n// We now have a giveawaysManager property to access the manager everywhere!\nclient.giveawaysManager = manager;\n\nclient.on('ready', () =\u003e {\n    console.log('Bot is ready!');\n});\n\nclient.login(process.env.DISCORD_BOT_TOKEN);\n```\n\nAfter that, giveaways that are not yet completed will start to be updated again and new giveaways can be started.\nYou can pass an options object to customize the giveaways. Here is a list of them:\n\n-   **client**: the discord client (your discord bot instance).\n-   **[and many other optional parameters to customize the manager - read documentation](https://discord-giveaways.js.org/global.html#GiveawaysManagerOptions)**\n\n### Start a giveaway\n\n```js\nclient.on('interactionCreate', (interaction) =\u003e {\n    const ms = require('ms');\n\n    if (interaction.isChatInputCommand() \u0026\u0026 interaction.commandName === 'start') {\n        // /start 2d 1 Awesome prize!\n        // Will create a giveaway with a duration of two days, with one winner and the prize will be \"Awesome prize!\"\n\n        const duration = interaction.options.getString('duration');\n        const winnerCount = interaction.options.getInteger('winners');\n        const prize = interaction.options.getString('prize');\n\n        client.giveawaysManager\n            .start(interaction.channel, {\n                duration: ms(duration),\n                winnerCount,\n                prize\n            })\n            .then((data) =\u003e {\n                console.log(data); // {...} (messageId, end date and more)\n            });\n        // And the giveaway has started!\n    }\n});\n```\n\n-   **options.duration**: the giveaway duration.\n-   **options.prize**: the giveaway prize.\n-   **options.winnerCount**: the number of giveaway winners.\n-   **[and many other optional parameters to customize the giveaway - read documentation](https://discord-giveaways.js.org/global.html#GiveawayStartOptions)**\n\nThis 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!\n\n\u003ca href=\"http://zupimages.net/viewer.php?id=19/23/5h0s.png\"\u003e\n    \u003cimg src=\"https://zupimages.net/up/19/23/5h0s.png\"/\u003e\n\u003c/a\u003e\n\n#### ⚠ ATTENTION!\n\nThe 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.\n\n```js\nconst query = interaction.options.getString('query');\nconst giveaway =\n    // Search with giveaway prize\n    client.giveawaysManager.giveaways.find((g) =\u003e g.guildId === interaction.guildId \u0026\u0026 g.prize === query) ||\n    // Search with messageId\n    client.giveawaysManager.giveaways.find((g) =\u003e g.guildId === interaction.guildId \u0026\u0026 g.messageId === query);\n\n// If no giveaway was found\nif (!giveaway) return interaction.reply(`Unable to find a giveaway for \\`${query}\\`.`);\n```\n\n### Reroll a giveaway\n\n```js\nclient.on('interactionCreate', (interaction) =\u003e {\n    if (interaction.isChatInputCommand() \u0026\u0026 interaction.commandName === 'reroll') {\n        const messageId = interaction.options.getString('message_id');\n        client.giveawaysManager\n            .reroll(messageId)\n            .then(() =\u003e {\n                interaction.reply('Success! Giveaway rerolled!');\n            })\n            .catch((err) =\u003e {\n                interaction.reply(`An error has occurred, please check and try again.\\n\\`${err}\\``);\n            });\n    }\n});\n```\n\n-   **options.winnerCount**: the number of winners to pick.\n-   **options.messages**: an object with the \"congrat\" and the \"error\" message. [Usage example](https://github.com/Androz2091/discord-giveaways#-translation).\n-   **options.messages.replyWhenNoWinner**: Whether or not to send the \"error\" message when there is no winner.\n\n\u003ca href=\"http://zupimages.net/viewer.php?id=19/24/mhuo.png\"\u003e\n    \u003cimg src=\"https://zupimages.net/up/19/24/mhuo.png\"/\u003e\n\u003c/a\u003e\n\n### Edit a giveaway\n\n```js\nclient.on('interactionCreate', (interaction) =\u003e {\n    if (interaction.isChatInputCommand() \u0026\u0026 interaction.commandName === 'edit') {\n        const messageId = interaction.options.getString('message_id');\n        client.giveawaysManager\n            .edit(messageId, {\n                addTime: 5000,\n                newWinnerCount: 3,\n                newPrize: 'New Prize!'\n            })\n            .then(() =\u003e {\n                interaction.reply('Success! Giveaway updated!');\n            })\n            .catch((err) =\u003e {\n                interaction.reply(`An error has occurred, please check and try again.\\n\\`${err}\\``);\n            });\n    }\n});\n```\n\n-   **options.newWinnerCount**: the new number of winners.\n-   **options.newPrize**: the new prize. You can [access giveaway properties](https://github.com/Androz2091/discord-giveaways#access-giveaway-properties-in-messages).\n-   **options.addTime**: the number of milliseconds to add to the giveaway duration.\n-   **options.setEndTimestamp**: the timestamp of the new end date (for example, for the giveaway to be ended in 1 hour, set it to `Date.now() + 60000`).\n-   **[and many other optional parameters - read documentation](https://discord-giveaways.js.org/global.html#GiveawayEditOptions)**\n\n**Note**: to reduce giveaway duration, define `addTime` with a negative number! For example `addTime: -5000` will reduce giveaway duration by 5 seconds!\n\n### Delete a giveaway\n\n```js\nclient.on('interactionCreate', (interaction) =\u003e {\n    if (interaction.isChatInputCommand() \u0026\u0026 interaction.commandName === 'delete') {\n        const messageId = interaction.options.getString('message_id');\n        client.giveawaysManager\n            .delete(messageId)\n            .then(() =\u003e {\n                interaction.reply('Success! Giveaway deleted!');\n            })\n            .catch((err) =\u003e {\n                interaction.reply(`An error has occurred, please check and try again.\\n\\`${err}\\``);\n            });\n    }\n});\n```\n\n-   **doNotDeleteMessage**: whether the giveaway message shouldn't be deleted.\n\n⚠️ **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!\n\n### End a giveaway\n\n```js\nclient.on('interactionCreate', (interaction) =\u003e {\n    if (interaction.isChatInputCommand() \u0026\u0026 interaction.commandName === 'end') {\n        const messageId = interaction.options.getString('message_id');\n        client.giveawaysManager\n            .end(messageId)\n            .then(() =\u003e {\n                interaction.reply('Success! Giveaway ended!');\n            })\n            .catch((err) =\u003e {\n                interaction.reply(`An error has occurred, please check and try again.\\n\\`${err}\\``);\n            });\n    }\n});\n```\n\n-   **noWinnerMessage**: Sent in the channel if there is no valid winner for the giveaway. [Message Options](https://github.com/Androz2091/discord-giveaways#message-options)\n\n### Pause a giveaway\n\n```js\nclient.on('interactionCreate', (interaction) =\u003e {\n    if (interaction.isChatInputCommand() \u0026\u0026 interaction.commandName === 'pause') {\n        const messageId = interaction.options.getString('message_id');\n        client.giveawaysManager\n            .pause(messageId)\n            .then(() =\u003e {\n                interaction.reply('Success! Giveaway paused!');\n            })\n            .catch((err) =\u003e {\n                interaction.reply(`An error has occurred, please check and try again.\\n\\`${err}\\``);\n            });\n    }\n});\n```\n\n-   **options.content**: the text of the embed when the giveaway is paused. You can [access giveaway properties](https://github.com/Androz2091/discord-giveaways#access-giveaway-properties-in-messages).\n-   **options.unpauseAfter**: the number of milliseconds, or a timestamp in milliseconds, after which the giveaway will automatically unpause.\n-   **options.embedColor**: the color of the embed when the giveaway is paused.\n-   **options.infiniteDurationText**: The text that gets displayed next to `GiveawayMessages#drawing` in the paused embed, when there is no `unpauseAfter`.  \n    ^^^ You can [access giveaway properties](https://github.com/Androz2091/discord-giveaways#access-giveaway-properties-in-messages).\n\n⚠️ **Note**: the pause function overwrites/edits the [pauseOptions object property](https://github.com/Androz2091/discord-giveaways#pause-options) of a giveaway!\n\n### Unpause a giveaway\n\n```js\nclient.on('interactionCreate', (interaction) =\u003e {\n    if (interaction.isChatInputCommand() \u0026\u0026 interaction.commandName === 'unpause') {\n        const messageId = interaction.options.getString('message_id');\n        client.giveawaysManager\n            .unpause(messageId)\n            .then(() =\u003e {\n                interaction.reply('Success! Giveaway unpaused!');\n            })\n            .catch((err) =\u003e {\n                interaction.reply(`An error has occurred, please check and try again.\\n\\`${err}\\``);\n            });\n    }\n});\n```\n\n### Fetch giveaways\n\n```js\n// A list of all the giveaways\nconst allGiveaways = client.giveawaysManager.giveaways; // [ {Giveaway}, {Giveaway} ]\n\n// A list of all the giveaways on the server with Id \"1909282092\"\nconst onServer = client.giveawaysManager.giveaways.filter((g) =\u003e g.guildId === '1909282092');\n\n// A list of the current active giveaways (not ended)\nconst notEnded = client.giveawaysManager.giveaways.filter((g) =\u003e !g.ended);\n```\n\n### Exempt Members\n\nFunction to filter members. If true is returned, the member will not be able to win the giveaway.\n\n```js\nclient.giveawaysManager.start(interaction.channel, {\n    duration: 60000,\n    winnerCount: 1,\n    prize: 'Free Steam Key',\n    // Only members who have the \"Nitro Boost\" role are able to win\n    exemptMembers: (member, giveaway) =\u003e !member.roles.cache.some((r) =\u003e r.name === 'Nitro Boost')\n});\n```\n\n**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](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function) constructor:\n\n```js\nconst roleName = 'Nitro Boost';\n\nclient.giveawaysManager.start(interaction.channel, {\n    duration: 60000,\n    winnerCount: 1,\n    prize: 'Free Steam Key',\n    // Only members who have the the role which is assigned to \"roleName\" are able to win\n    exemptMembers: new Function(\n        'member',\n        'giveaway',\n        `return !member.roles.cache.some((r) =\u003e r.name === '${roleName}')`\n    )\n});\n```\n\n\u003cu\u003e**⚠ Note**\u003c/u\u003e\n\n-   You can use `this`, instead of the `giveaway` parameter, inside of the function string to access anything of the giveaway instance.  \n    For example: `this.extraData`, or `this.client`.\n-   Strings have to be \"stringified\" (wrapped in quotation marks) again like you can see in the example.  \n    Array brackets also have to be stated again.\n-   Global variables which contain numbers with more than 16 digits cannot be used.  \n    =\u003e Snoflakes have to be \"stringified\" correctly to avoid misbehaviour.\n-   If you want to make an asynchronous function in this format, refer to [this](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/AsyncFunction) article.\n-   \u003cu\u003e**Because of those various complications it is therefore highly suggested to use `giveaway.extraData` for storing variables.**\u003c/u\u003e  \n    But if you really want to do it in this way and need more information/help, please visit the [Discord Server](https://discord.gg/r5mb9r5WXv).\n\n### Last Chance\n\n```js\nclient.giveawaysManager.start(interaction.channel, {\n    duration: 60000,\n    winnerCount: 1,\n    prize: 'Discord Nitro!',\n    lastChance: {\n        enabled: true,\n        content: '⚠️ **LAST CHANCE TO ENTER !** ⚠️',\n        threshold: 10_000,\n        embedColor: '#FF0000'\n    }\n});\n```\n\n-   **lastChance.enabled**: if the last chance system is enabled.\n-   **lastChance.content**: the text of the embed when the last chance system is enabled.  \n    ^^^ You can [access giveaway properties](https://github.com/Androz2091/discord-giveaways#access-giveaway-properties-in-messages).\n-   **lastChance.threshold**: the number of milliseconds before the giveaway ends when the last chance system will be enabled.\n-   **lastChance.embedColor**: the color of the embed when last chance is enabled.\n\n\u003ca href=\"https://zupimages.net/viewer.php?id=21/08/50mx.png\"\u003e\n    \u003cimg src=\"https://zupimages.net/up/21/08/50mx.png\"/\u003e\n\u003c/a\u003e\n\n### Pause Options\n\n```js\nclient.giveawaysManager.start(interaction.channel, {\n    duration: 60000,\n    winnerCount: 1,\n    prize: 'Discord Nitro!',\n    pauseOptions: {\n        isPaused: true,\n        content: '⚠️ **THIS GIVEAWAY IS PAUSED !** ⚠️',\n        unpauseAfter: null,\n        embedColor: '#FFFF00',\n        infiniteDurationText: '`NEVER`'\n    }\n});\n```\n\n-   **pauseOptions.isPaused**: if the giveaway is paused.\n-   **pauseOptions.content**: the text of the embed when the giveaway is paused.  \n    ^^^ You can [access giveaway properties](https://github.com/Androz2091/discord-giveaways#access-giveaway-properties-in-messages).\n-   **pauseOptions.unpauseAfter**: the number of milliseconds, or a timestamp in milliseconds, after which the giveaway will automatically unpause.\n-   **pauseOptions.embedColor**: the color of the embed when the giveaway is paused.\n-   **pauseOptions.infiniteDurationText**: The text that gets displayed next to `GiveawayMessages#drawing` in the paused embed, when there is no `unpauseAfter`.  \n    ^^^ You can [access giveaway properties](https://github.com/Androz2091/discord-giveaways#access-giveaway-properties-in-messages).\n\n\u003ca href=\"https://zupimages.net/viewer.php?id=21/24/dxhk.png\"\u003e\n    \u003cimg src=\"https://zupimages.net/up/21/24/dxhk.png\"/\u003e\n\u003c/a\u003e\n\n### Bonus Entries\n\n```js\nclient.giveawaysManager.start(interaction.channel, {\n    duration: 60000,\n    winnerCount: 1,\n    prize: 'Free Steam Key',\n    bonusEntries: [\n        {\n            // Members who have the \"Nitro Boost\" role get 2 bonus entries\n            bonus: (member, giveaway) =\u003e (member.roles.cache.some((r) =\u003e r.name === 'Nitro Boost') ? 2 : null),\n            cumulative: false\n        }\n    ]\n});\n```\n\n-   **bonusEntries[].bonus**: the filter function that takes two parameters: \"member\" and \"giveaway\", and returns the amount of additional entries.\n-   **bonusEntries[].cumulative**: if the amount of entries from the function can get summed with other amounts of entries.\n\n**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](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Function) constructor.  \nLook at the [exemptMembers](https://github.com/Androz2091/discord-giveaways#exempt-members) section for more information on that.\n\n### Message Options\n\nOptions are available for the following messages:  \n`GiveawayStartOptions#GiveawayMessages#winMessage`, `GiveawayRerollOptions#messages#congrat`, `GiveawayRerollOptions#messages#error` and `client.giveawaysManager.end(messageId, noWinnerMessage)`.\n\nYou can [access giveaway properties](https://github.com/Androz2091/discord-giveaways#access-giveaway-properties-in-messages) in all embed or component properties that are a string.\n\nThe format, including all currently available options, looks like this:\n\n```js\nmessage: {\n    content: '',\n    embed: new Discord.EmbedBuilder(),\n    components: [new Discord.ActionRowBuilder()],\n    replyToGiveaway: true\n}\n```\n\n⚠ **Note**: When sending a component, `content` or `embed` is required.\n\n### Access giveaway properties in messages\n\nYou can access any giveaway property inside of giveaway messages with the format: `{this.\u003cproperty\u003e}`.  \nFor example:\n\n\u003c!-- prettier-ignore --\u003e\n```js\nwinMessage: 'Congratulations, {winners}! You won **{this.prize}**!\\n{this.messageURL}'\n```\n\nAlso, you can write JavaScript code inside of `{}`.  \nFor example:\n\n\u003c!-- prettier-ignore --\u003e\n```js\nwinMessage: 'Congratulations, {winners}! You won **{this.prize.toUpperCase()}**!\\n{this.messageURL}'\n```\n\nIf you want to fill in strings that are not messages of a giveaway, or just custom embeds, then you can use `giveaway.fillInString(string)` for strings, `giveaway.fillInEmbed(embed)` for embeds and `giveaway.fillInComponents(embed)` for components.\n\n## 🇫🇷 Translation\n\nYou can also pass a `messages` parameter for the `start()` function, if you want to translate the giveaway texts:\n\n-   **options.messages.giveaway**: the message that will be displayed above the embeds.\n-   **options.messages.giveawayEnded**: the message that will be displayed above the embeds when the giveaway is ended.\n-   **options.messages.title**: the title of the giveaway embed. Will default to the prize of the giveaway if the value is not a string.\n-   **options.messages.drawing**: the message that displays the drawing timestamp.\n-   **options.messages.dropMessage**: the message that will be displayed for drop giveaways.\n-   **options.messages.inviteToParticipate**: the message that invites users to participate.\n-   **options.messages.winMessage**: the message that will be displayed to congratulate the winner(s) when the giveaway is ended.  \n    ^^^ [Message options](https://github.com/Androz2091/discord-giveaways#message-options) are available in this message.\n-   **options.messages.embedFooter**: the message displayed at the bottom of the main (not ended) embed.  \n    ^^^ An empty string can be used for \"deactivation\", or [`iconURL` can be set](https://discord-giveaways.js.org/global.html#EmbedFooterObject).\n-   **options.messages.noWinner**: the message that is displayed if no winner can be drawn.\n-   **options.messages.hostedBy**: the message to display the host of the giveaway.\n-   **options.messages.winners**: simply the expression \"Winner(s):\" in your language.\n-   **options.messages.endedAt**: simply the words \"Ended at\" in your language.\n\nFor example:\n\n```js\nconst duration = interaction.options.getString('duration');\nconst winnerCount = interaction.options.getInteger('winners');\nconst prize = interaction.options.getString('prize');\n\nclient.giveawaysManager.start(interaction.channel, {\n    duration: ms(duration),\n    winnerCount,\n    prize,\n    messages: {\n        giveaway: '🎉🎉 **GIVEAWAY** 🎉🎉',\n        giveawayEnded: '🎉🎉 **GIVEAWAY ENDED** 🎉🎉',\n        title: '{this.prize}',\n        drawing: 'Drawing: {timestamp}',\n        dropMessage: 'Be the first to react with 🎉 !',\n        inviteToParticipate: 'React with 🎉 to participate!',\n        winMessage: 'Congratulations, {winners}! You won **{this.prize}**!\\n{this.messageURL}',\n        embedFooter: '{this.winnerCount} winner(s)',\n        noWinner: 'Giveaway cancelled, no valid participations.',\n        hostedBy: 'Hosted by: {this.hostedBy}',\n        winners: 'Winner(s):',\n        endedAt: 'Ended at'\n    }\n});\n```\n\nYou can [access giveaway properties](https://github.com/Androz2091/discord-giveaways#access-giveaway-properties-in-messages) in all these messages.\n\nAnd for the `reroll()` function:\n\n```js\nclient.giveawaysManager.reroll(messageId, {\n    messages: {\n        congrat: ':tada: New winner(s): {winners}! Congratulations, you won **{this.prize}**!\\n{this.messageURL}',\n        error: 'No valid participations, no new winner(s) can be chosen!'\n    }\n});\n```\n\n-   **options.messages.congrat**: the congratulatory message.\n-   **options.messages.error**: the error message if there is no valid participant.\n\nYou can [access giveaway properties](https://github.com/Androz2091/discord-giveaways#access-giveaway-properties-in-messages) in these messages.  \n[Message options](https://github.com/Androz2091/discord-giveaways#message-options) are available in these messages.\n\n## Custom Database\n\nYou can use your custom database to save giveaways, instead of the json files (the \"database\" by default for `discord-giveaways`).  \nFor this, you will need to extend the `GiveawaysManager` class, and replace some methods with your custom ones.  \nThere are 4 methods you will need to replace:\n\n-   `getAllGiveaways`: this method returns an array of stored giveaways.\n-   `saveGiveaway`: this method stores a new giveaway in the database.\n-   `editGiveaway`: this method edits a giveaway already stored in the database.\n-   `deleteGiveaway`: this method deletes a giveaway from the database (permanently).\n\n**⚠️ All the methods should be asynchronous to return a promise!**\n\n\u003cu\u003e**SQL examples**\u003c/u\u003e\n\n-   [MySQL](https://github.com/Androz2091/discord-giveaways/blob/master/examples/custom-databases/mysql.js)\n-   SQLite\n    -   [Quick.db](https://github.com/Androz2091/discord-giveaways/blob/master/examples/custom-databases/quick.db.js)\n    -   [Enmap](https://github.com/Androz2091/discord-giveaways/blob/master/examples/custom-databases/enmap.js)\n\n\u003cu\u003e**NoSQL examples**\u003c/u\u003e\n\n-   MongoDB\n    -   [Mongoose](https://github.com/Androz2091/discord-giveaways/blob/master/examples/custom-databases/mongoose.js)\n    -   [QuickMongo](https://github.com/Androz2091/discord-giveaways/blob/master/examples/custom-databases/quickmongo.js) ⚠️ Not recommended for high giveaway usage, use the `mongoose` example instead\n-   [Apache CouchDB - Nano](https://github.com/Androz2091/discord-giveaways/blob/master/examples/custom-databases/nano.js)\n-   Replit Database ⚠️ Only usable if your bot is hosted on [Replit](https://replit.com/)\n    -   [@replit/database](https://github.com/Androz2091/discord-giveaways/blob/master/examples/custom-databases/replit.js)\n    -   [Quick.Replit](https://github.com/Androz2091/discord-giveaways/blob/master/examples/custom-databases/quick.replit.js)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandroz2091%2Fdiscord-giveaways","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fandroz2091%2Fdiscord-giveaways","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fandroz2091%2Fdiscord-giveaways/lists"}