diff --git a/Database Examples/README.md b/Database Examples/README.md deleted file mode 100644 index 7ecfc1e..0000000 --- a/Database Examples/README.md +++ /dev/null @@ -1,18 +0,0 @@ -# Custom/External Database -you can use the pre-built available database example in your bot as your need. Read the following carefully to understand the Custom Databases. - -## Database Setup -```md -SQL Database Setup -- Copy the code from the given file from: ./Database Examples/index4mysql.js. -- Install the mysql package: `npm i mysql`. -- Insert your DB values. -and that's it start the bot and it should work. -``` -```md -MongoDB Setup -- Copy the code from the given file from: ./Database Examples/index4mongo.js. -- Install the quickmongo package: npm i quickmongo -- Add your connection string in the config file with the following variable: "mongo_url": "your-mongo-connection-string" -and that's it start the bot and it should work. -``` \ No newline at end of file diff --git a/Database Examples/index4mongo.js b/Database Examples/index4mongo.js deleted file mode 100644 index 10f9702..0000000 --- a/Database Examples/index4mongo.js +++ /dev/null @@ -1,119 +0,0 @@ -const fs = require('fs'); - -const Discord = require('discord.js'); -const client = new Discord.Client({ - intents: [ - Discord.Intents.FLAGS.GUILDS, - Discord.Intents.FLAGS.GUILD_MEMBERS, - Discord.Intents.FLAGS.GUILD_MESSAGE_REACTIONS - ] -}); - -const config = require('./config.json'); -client.config = config; - -// Load quickmongo -const { Database } = require('quickmongo'); -const db = new Database(config.mongodb_url); - -// Ceck the DB when it is ready -db.on('ready', async () => { - if (!Array.isArray(await b.get('giveaways'))) await db.set('giveaways', []); - // Start the manager only after the BD got checked to prevent an error - client.giveawaysManager._init(); - console.log('SUCCESS!'); -}) - -// Init discord giveaways -const { GiveawaysManager } = require('discord-giveaways'); -const GiveawayManagerWithOwnDatabase = class extends GiveawaysManager { - // This function is called when the manager needs to get all giveaways which are stored in the database. - async getAllGiveaways() { - // Get all giveaways from the database - return await db.get('giveaways'); - } - - // This function is called when a giveaway needs to be saved in the database. - async sameGiveaway(messageId, giveawayData) { - // Add the giveaway to the database - await db.push('giveaways', giveawayData); - // Don't forget to return something! - return true; - } - - // This function is called when a giveaway needs to be edited in the database. - async editGiveaway(messageId, giveawayData) { - // Get all giveaways from the database - const giveaways = await db.get('giveaways'); - // Remove the unexisting giveaway from the array - const newGiveawaysArray = giveaways.filter((giveaway) => giveaway.messageId !== messageId); - // Push the edited giveaway to the array - newGiveawaysArray.push(giveawayData); - // Save the updated array - await db.set('giveaways', newGiveawaysArray); - // Don't forget to return something! - return true; - } - - // This function is called when a giveaway needs to be deleted from the database. - async deleteGiveaway(messageId) { - // Get all giveaways from the database - const giveaways = await db.get('giveaways'); - // Remove the unexisting giveaway from the array - const newGiveawaysArray = giveaways.filter((giveaway) => giveaway.messageId !== messageId); - // Save the updated array - await db.set('giveaways', newGiveawaysArray); - // Don't forget to return something! - return true; - } -}; - -// Create a new instance of your new class -const manager = new GiveawayManagerWithOwnDatabase(client, { - default: { - botsCanWin: false, - embedColor: '#FF0000', - embedColorEnd: '#000000', - reaction: '🎉', - } -}, false); - -client.giveawaysManager = manager; - -/* Load all commands */ -client.commands = new Discord.Collection(); -fs.readdir("./commands/", (_err, files) => { - files.forEach((file) => { - if(!file.endsWith(".js")) return; - let props = require(`./commands/${file}`); - let commandName = file.split(".")[0]; - client.commands.set(commandName, { - name: commandName, - ...props - }); - console.log(`👌 Command loaded: ${commandName}`); - }); - synchronizeSlashCommands(client, client.commands.map((c) => ({ - name: c.name, - description: c.description, - options: c.options, - type: 'CHAT_INPUT' - })), { - debug: true - }); -}); - -/* Load all commands */ -fs.readdir("./events/", (_err, files) => { - files.forEach((file) => { - if (!file.endsWith(".js")) return; - const event = require(`./events/${file}`); - let eventName = file.split(".")[0]; - console.log(`👌 Event loaded: ${eventName}`); - client.on(eventName, event.bind(null, client)); - delete require.cache[require.resolve(`.events/${file}`)]; - }); -}); - -// Login -client.login(config.token); \ No newline at end of file diff --git a/Database Examples/index4mysql.js b/Database Examples/index4mysql.js deleted file mode 100644 index 09a78d5..0000000 --- a/Database Examples/index4mysql.js +++ /dev/null @@ -1,159 +0,0 @@ -const fs = require('fs'); - -const { Client, Intents } = require('discord.js'); -const client = new Client({ - intents: [ - Intents.FLAGS.GUILDS, - Intents.FLAGS.GUILD_MEMBERS, - Intents.FLAGS.GUILD_MESSAGE_REACTIONS - ] -}); -const config = require('./config.json'); -client.config = config; - -// Load MySQL -const MySQL = require('mysql'); -const sql = MySQL.createConnection({ - host: 'localhost', - user: 'Your MySQL user', - password: 'Your MySQL password', - database: 'Your MySQL database', - charset: 'utf8mb4' // In order to save emojis in the database correctly -}); -sql.connect((err) => { - if (err) { - // Stop the process if we can't connect to the MySQL server - throw new Error('Impossible to connect to MySQL server. Code: ' + err.code); - } else { - console.log('[SQL] Connection to the MySQL server! Connection ID: ' + sql.threadId); - } -}); - -// Create giveaways table -sql.query(` - CREATE TABLE IF NOT EXISTS \`giveaways\` - ( - \`id\` INT(1) NOT NULL AUTO_INCREMENT, - \`message_id\` VARCHAR(20) NOT NULL, - \`data\` JSON NOT NULL, - PRIMARY KEY (\`id\`) - ); -`, (err) => { - if (err) console.error(err); - console.log('[SQL] Created table `giveaways`'); -}); - -const { GiveawaysManager } = require('discord-giveaways'); -const GiveawaysManagerWithOwnDatabase = class extends GiveawaysManager { - // This function is called when the manager needs to get all giveaways which are stored in the database - async getAllGiveaways() { - return new Promise((resolve, reject) => { - sql.query('SELECT `data` FROM `giveaways`', (err, res) => { - if (err) { - console.error(err); - return reject(err); - } - const giveaways = res.map((row) => - JSON.parse(row.data, (_, v) => (typeof v === 'string' && /BigInt\("(-?\d+)"\)/.test(v)) ? eval(v) : v) - ); - resolve(giveaways); - }); - }); - } - - // This function is called when a giveaway needs to be saved in the database. - async saveGiveaway(messageId, giveawayData) { - return new Promise((resolve, reject) => { - sql.query( - 'INSERT INTO `giveaways` (`message_id`, `data`) VALUES (?,?)', - [messageId, JSON.stringify(giveawayData, (_, v) => typeof v === 'bigint' ? `BigInt("${v}")` : v)], - (err, res) => { - if (err) { - console.error(err); - return reject(err); - } - resolve(true); - } - ); - }); - } - - // This function is called when a giveaway needs to be edited in the database. - async editGiveaway(messageId, giveawayData) { - return new Promise((resolve, reject) => { - sql.query( - 'UPDATE `giveaways` SET `data` = ? WHERE `message_id` = ?', - [JSON.stringify(giveawayData, (_, v) => typeof v === 'bigint' ? `BigInt("${v}")` : v), messageId], - (err, res) => { - if (err) { - console.error(err); - return reject(err); - } - resolve(true); - } - ); - }); - } - - // This function is called when a giveaway needs to be deleted from the database. - async deleteGiveaway(messageId) { - return new Promise((resolve, reject) => { - sql.query('DELETE FROM `giveaways` WHERE `message_id` = ?', messageId, (err, res) => { - if (err) { - console.error(err); - return reject(err); - } - resolve(true); - }); - }); - } -} - -// Create a new instance of your class -const manager = new GiveawaysManagerWithOwnDatabase(cclient, { - default: { - botsCanWin: false, - embedColor: '#FF0000', - embedColorEnd: '#000000', - reaction: '🎉', - } -}); -// We now have a giveawaysManager property to access the manager everywhere! -client.giveawaysManager = manager; - -/* Load all commands */ -client.commands = new Discord.Collection(); -fs.readdir('./commands/', (_err, files) => { - files.forEach((file) => { - if (!file.endsWith('.js')) return; - let props = require(`./commands/${file}`); - let commandName = file.split('.')[0]; - client.commands.set(commandName, { - name: commandName, - ...props - }); - client.log(`👌 Command loaded: ${commandName}`); - }); - syncroniseSlashCommands(client, client.commands.map((c) => ({ - name: c.name, - description: c.description, - options: c.options, - type: 'CHAT_INPUT' - })), { - debug: true - }); -}); - -/* Load all events */ -fs.readdir('./events/', (_err, files) => { - files.forEach((file) => { - if (!file.endsWith('.js')) return; - const event = require(`./events/${file}`); - let eventName = file.split('.')[0]; - console.log(`👌 Event loaded: ${eventName}`); - client.on(eventName, event.bind(null, client)); - delete require.cache[require.resolve(`./events/${file}`)]; - }); -}); - -client.login(config.token); \ No newline at end of file diff --git a/commands/drop.js b/commands/drop.js deleted file mode 100644 index 6f90cbc..0000000 --- a/commands/drop.js +++ /dev/null @@ -1,66 +0,0 @@ -const messages = require("../utils/messages"); - -module.exports = { - - description: 'Create a drop giveaway', - - options: [ - { - name: 'winners', - description: 'How many winners the giveaway should have', - type: 'INTEGER', - required: true - }, - { - name: 'prize', - description: 'What the prize of the giveaway should be', - type: 'STRING', - required: true - }, - { - name: 'channel', - description: 'The channel to start the giveaway in', - type: 'CHANNEL', - required: true - } - ], - - run: async (client, interaction) => { - - // If the member doesn't have enough permissions - if(!interaction.member.permissions.has('MANAGE_MESSAGES') && !interaction.member.roles.cache.some((r) => r.name === "Giveaways")){ - return interaction.reply({ - content: ':x: You need to have the manage messages permissions to start giveaways.', - ephemeral: true - }); - } - - const giveawayChannel = interaction.options.getChannel('channel'); - const giveawayWinnerCount = interaction.options.getInteger('winners'); - const giveawayPrize = interaction.options.getString('prize'); - - if(!giveawayChannel.isText()) { - return interaction.reply({ - content: ':x: Selected channel is not text-based.', - ephemeral: true - }); - } - - // Start the giveaway - client.giveawaysManager.start(giveawayChannel, { - // The number of winners for this drop - winnerCount: giveawayWinnerCount, - // The prize of the giveaway - prize: giveawayPrize, - // Who hosts this giveaway - hostedBy: client.config.hostedBy ? interaction.user : null, - // specify drop - isDrop: true, - // Messages - messages - }); - - interaction.reply(`Giveaway started in ${giveawayChannel}!`); - - } -}; \ No newline at end of file diff --git a/commands/end.js b/commands/end.js deleted file mode 100644 index b4eb670..0000000 --- a/commands/end.js +++ /dev/null @@ -1,65 +0,0 @@ -const ms = require('ms'); - -module.exports = { - - description: 'End a giveaway', - - options: [ - { - name: 'giveaway', - description: 'The giveaway to end (message ID or giveaway prize)', - type: 'STRING', - required: true - } - ], - - run: async (client, interaction) => { - - // If the member doesn't have enough permissions - if(!interaction.member.permissions.has('MANAGE_MESSAGES') && !interaction.member.roles.cache.some((r) => r.name === "Giveaways")){ - return interaction.reply({ - content: ':x: You need to have the manage messages permissions to end giveaways.', - ephemeral: true - }); - } - - const query = interaction.options.getString('giveaway'); - - // try to found the giveaway with prize then with ID - const giveaway = - // Search with giveaway prize - client.giveawaysManager.giveaways.find((g) => g.prize === query && g.guildId === interaction.guild.id) || - // Search with giveaway ID - client.giveawaysManager.giveaways.find((g) => g.messageId === query && g.guildId === interaction.guild.id); - - // If no giveaway was found - if (!giveaway) { - return interaction.reply({ - content: 'Unable to find a giveaway for `'+ query + '`.', - ephemeral: true - }); - } - - if (giveaway.ended) { - return interaction.reply({ - content: 'This giveaway is already ended.', - ephemeral: true - }); - } - - // Edit the giveaway - client.giveawaysManager.end(giveaway.messageId) - // Success message - .then(() => { - // Success message - interaction.reply('Giveaway ended!'); - }) - .catch((e) => { - interaction.reply({ - content: e, - ephemeral: true - }); - }); - - } -}; \ No newline at end of file diff --git a/commands/help.js b/commands/help.js deleted file mode 100644 index 75c0ff6..0000000 --- a/commands/help.js +++ /dev/null @@ -1,41 +0,0 @@ -const message = require('../utils/messages'); -const { - MessageEmbed, - MessageActionRow, - MessageButton -} = require('discord.js'); - -module.exports = { - name: "help", - description: "Get all Bot Commands", - run: async (client, interaction) => { - - let helpembed = new MessageEmbed() - helpembed.setColor("RANDOM") - helpembed.setAuthor( - `Commands of ${client.user.username}` - ) - helpembed.setColor("#2f3136") - helpembed.setThumbnail("https://cdn.discordapp.com/avatars/608119997713350679/d71c7cbb2ba132867367ed47261aea6d.png") - client.commands.map((cmd) => { - helpembed.addField( - `\`${cmd.name}\``, - `${cmd.description}`, - true - ); - }) - helpembed.setTimestamp() - helpembed.setFooter(`© EmotionChild | Have a nice day!`); - - const row = new MessageActionRow() - .addComponents( - new MessageButton() - .setEmoji('865572290065072128') - .setLabel(`Invite ${client.user.username}`) - .setURL(`https://discord.com/api/oauth2/authorize?client_id=726333575091454002&permissions=8&scope=bot%20applications.commands`) - .setStyle('LINK'), - ); - - await interaction.reply({ embeds: [helpembed],components: [row], ephemeral: true }); - }, -}; \ No newline at end of file diff --git a/commands/invite.js b/commands/invite.js deleted file mode 100644 index d054474..0000000 --- a/commands/invite.js +++ /dev/null @@ -1,29 +0,0 @@ -const messages = require('../utils/messages'); -const { - MessageEmbed, - MessageActionRow, - MessageButton -} = require('discord.js'); - -module.exports = { - name: "invite", - description: "Get Invite Link for Giveaway Child", - run: async (client, interaction) => { - - let invite = new MessageEmbed() - .setAuthor(`Invite of ${client.user.username}`, `${client.user.displayAvatarURL({ format: 'png' })}`) - .setColor("#2f3136") - .setFooter(`© EmotionChild | Have a nice day!`); - - const row = new MessageActionRow() - .addComponents( - new MessageButton() - .setEmoji('865572290065072128') - .setLabel(`Invite ${client.user.username}`) - .setURL(`https://discord.com/api/oauth2/authorize?client_id=726333575091454002&permissions=8&scope=bot%20applications.commands`) - .setStyle('LINK'), - ); - - await interaction.reply({ embeds: [invite],components: [row], ephemeral: true }); - }, -}; \ No newline at end of file diff --git a/commands/ping.js b/commands/ping.js deleted file mode 100644 index 6c7b63a..0000000 --- a/commands/ping.js +++ /dev/null @@ -1,39 +0,0 @@ -const messages = require('../utils/messages'); -const { MessageEmbed } = require("discord.js"); - -module.exports = { - name: "ping", - description: "Tells the bot's latency,", - run: async (client, interaction) => { - // If the member doesn't have enough permissions - if (!interaction.member.permissions.has("SEND_MESSAGES")) { - return interaction.reply({ - content: - ":x: You need to have the manage messages permissions to start giveaways.", - ephemeral: true, - }); - } - - let circles = { - green: "<:online:885049752297824276>", - yellow: "<:idle:885049726460899339>", - red: "<:offline:885049312877346817>", - }; - - let botping = new MessageEmbed() - .setTitle(`${client.user.name} Ping`) - .setColor("2f3136") - .addFields({ - name: "<:link:911514727375577088> Bot Ping:", - value: `${ - client.ws?.ping <= 200 - ? circles.green - : client.ws?.ping <= 400 - ? circles.yellow - : circles.red - } ${client.ws?.ping}ms`, - }) - .setTimestamp(); - await interaction.reply({ embeds: [botping] }); - }, -}; \ No newline at end of file diff --git a/commands/reroll.js b/commands/reroll.js deleted file mode 100644 index 6bffcfd..0000000 --- a/commands/reroll.js +++ /dev/null @@ -1,62 +0,0 @@ -module.exports = { - - description: 'Reroll a giveaway', - - options: [ - { - name: 'giveaway', - description: 'The giveaway to reroll (message ID or prize)', - type: 'STRING', - required: true - } - ], - - run: async (client, interaction) => { - - // If the member doesn't have enough permissions - if(!interaction.member.permissions.has('MANAGE_MESSAGES') && !interaction.member.roles.cache.some((r) => r.name === "Giveaways")){ - return interaction.reply({ - content: ':x: You need to have the manage messages permissions to reroll giveaways.', - ephemeral: true - }); - } - - const query = interaction.options.getString('giveaway'); - - // try to found the giveaway with prize then with ID - const giveaway = - // Search with giveaway prize - client.giveawaysManager.giveaways.find((g) => g.prize === query && g.guildId === interaction.guild.id) || - // Search with giveaway ID - client.giveawaysManager.giveaways.find((g) => g.messageId === query && g.guildId === interaction.guild.id); - - // If no giveaway was found - if (!giveaway) { - return interaction.reply({ - content: 'Unable to find a giveaway for `'+ query +'`.', - ephemeral: true - }); - } - - if (!giveaway.ended) { - return interaction.reply({ - content: 'The giveaway is not ended yet.', - ephemeral: true - }); - } - - // Reroll the giveaway - client.giveawaysManager.reroll(giveaway.messageId) - .then(() => { - // Success message - interaction.reply('Giveaway rerolled!'); - }) - .catch((e) => { - interaction.reply({ - content: e, - ephemeral: true - }); - }); - - } -}; \ No newline at end of file diff --git a/commands/start.js b/commands/start.js deleted file mode 100644 index c48a19e..0000000 --- a/commands/start.js +++ /dev/null @@ -1,75 +0,0 @@ -const ms = require('ms'); -const messages = require("../utils/messages"); - -module.exports = { - - description: 'Start a giveaway', - - options: [ - { - name: 'duration', - description: 'How long the giveaway should last for. Example values: 1m, 1h, 1d', - type: 'STRING', - required: true - }, - { - name: 'winners', - description: 'How many winners the giveaway should have', - type: 'INTEGER', - required: true - }, - { - name: 'prize', - description: 'What the prize of the giveaway should be', - type: 'STRING', - required: true - }, - { - name: 'channel', - description: 'The channel to start the giveaway in', - type: 'CHANNEL', - required: true - } - ], - - run: async (client, interaction) => { - - // If the member doesn't have enough permissions - if(!interaction.member.permissions.has('MANAGE_MESSAGES') && !interaction.member.roles.cache.some((r) => r.name === "Giveaways")){ - return interaction.reply({ - content: ':x: You need to have the manage messages permissions to start giveaways.', - ephemeral: true - }); - } - - const giveawayChannel = interaction.options.getChannel('channel'); - const giveawayDuration = interaction.options.getString('duration'); - const giveawayWinnerCount = interaction.options.getInteger('winners'); - const giveawayPrize = interaction.options.getString('prize'); - - if(!giveawayChannel.isText()) { - return interaction.reply({ - content: ':x: Selected channel is not text-based.', - ephemeral: true - }); - } - - // Start the giveaway - client.giveawaysManager.start(giveawayChannel, { - // The giveaway duration - duration: ms(giveawayDuration), - // The giveaway prize - prize: giveawayPrize, - // The giveaway winner count - winnerCount: giveawayWinnerCount, - // Who hosts this giveaway - hostedBy: client.config.hostedBy ? interaction.user : null, - // Messages - messages - }); - - interaction.reply(`Giveaway started in ${giveawayChannel}!`); - - } - -}; \ No newline at end of file diff --git a/commands/stats.js b/commands/stats.js deleted file mode 100644 index 3e2c95d..0000000 --- a/commands/stats.js +++ /dev/null @@ -1,85 +0,0 @@ -const os = require('os'); -const { MessageEmbed } = require('discord.js'); -const feroms = require('fero-ms'); - -module.exports = { - name: 'stats', - description: 'Sends bot physical statistics', - run: async(client, interaction) => { - let uptime = client.uptime; - let shortUptime = feroms.ms(uptime); - let model = os.cpus()[0].model; - let cores = os.cpus().length; - let platform = os.platform(); - let nodejs = process.version; - let djs = require('discord.js').version; - let botversion = require('../package.json').version; - let server = client.guilds.cache.size; - let user = client.users.cache.size; - let channel = client.channels.cache.size; - - let statsembed = new MessageEmbed() - .addFields( - { - name: '<:live2:896715171882500106> I have been online for?', - value: `\`\`\`${shortUptime}\`\`\`` - }, - { - name: '<:globe:896718155416760340> Guilds', - value: `\`${server}\``, - inline: true - }, - { - name: '<:mention:896718358672707584> Users', - value: `\`${user}\``, - inline: true - }, - { - name: '<:channel:896717996326809641> Channels', - value: `\`${channel}\``, - inline: true - }, - { - name: 'Bot Version', - value: `\`v${botversion}\``, - inline: true - }, - { - name: '<:prime:896718399776886816> Arch', - value: `\`${os.arch()}\``, - inline: true - }, - { - name: '<:info:896718244461826140> Platform', - value: `\`${platform}\``, - inline: true - }, - { - name: '<:desktop:896718080821047346> Cores', - value: `\`${cores}\``, - inline: true - }, - { - name: ' Discord.js Version', - value: `\`v${djs}\``, - inline: true - }, - { - name: '<:jss:896718571491704852> Node.js Version', - value: `\`${nodejs}\``, - inline: true - }, - { - name: '<:ram:896715172029276180> Ram Usage', - value: `\`${(process.memoryUsage().heapUsed / 1024 / 1024).toFixed(2)}MB/ ${(os.totalmem() / 1024 / 1024).toFixed(2)}MB\``, - inline: true - }, - { - name: '<:desktop:896718080821047346> CPU Model', - value: `\`\`\`${model}\`\`\`` - } - ) - .setTimestamp() - await interaction.reply({ embeds: [statsembed] }); - } - } \ No newline at end of file diff --git a/events/interactionCreate.js b/events/interactionCreate.js deleted file mode 100644 index 3c4dc1a..0000000 --- a/events/interactionCreate.js +++ /dev/null @@ -1,13 +0,0 @@ -module.exports = (client, interaction) => { - - if (!interaction.isCommand()) return; - - const command = client.commands.get(interaction.commandName); - - if (!command) return void interaction.reply({ - content: `Command \`${interaction.commandName}\` not found.`, - ephemeral: true - }); - - command.run(client, interaction); -}; \ No newline at end of file diff --git a/events/ready.js b/events/ready.js deleted file mode 100644 index 73763ee..0000000 --- a/events/ready.js +++ /dev/null @@ -1,12 +0,0 @@ -module.exports = (client) => { - console.log( - `Ready to server in ${client.channels.cache.size} channels on ${client.guilds.cache.size} servers, for a total of ${client.users.cache.size} users.` - ); - - const activities = [`Giveaways in ${client.guilds.cache.size} guilds`,"g!help",`over ${client.users.cache.size} users!`]; - setInterval(() => { - let activity = activities[Math.floor(Math.random() * activities.length)]; - client.user.setActivity(activity, { type: "WATCHING" }); - }, 20000); - -}; \ No newline at end of file diff --git a/utils/messages.js b/utils/messages.js deleted file mode 100644 index 61719c7..0000000 --- a/utils/messages.js +++ /dev/null @@ -1,15 +0,0 @@ -const config = require('../config.json'); - -module.exports = { - giveaway: (config.everyoneMention ? "@everyone\n\n" : "")+"🎉🎉 **GIVEAWAY** 🎉🎉", - giveawayEnded: (config.everyoneMention ? "@everyone\n\n" : "")+"🎉🎉 **GIVEAWAY ENDED** 🎉🎉", - inviteToParticipate: "React with 🎉 to participate!", - dropMessage: "Be the first to react with 🎉 !", - drawing: 'Drawing: {timestamp}', - winMessage: "Congratulations, {winners}! You won **{this.prize}**!", - embedFooter: "Giveaways", - noWinner: "Giveaway cancelled, no valid participations.", - hostedBy: "Hosted by: {this.hostedBy}", - winners: "winner(s)", - endedAt: "Ended at" -}; \ No newline at end of file