From e7b572e5b6755c3be0c120ab5bbcc2d6f2c8534e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20Olausson=20Holten=C3=A4s?= Date: Fri, 4 Mar 2022 20:58:55 +0100 Subject: [PATCH] =?UTF-8?q?=F0=9F=94=96=20Version=202.1.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env.example | 19 ------ config.json.example | 21 +++++++ deploy-commands.js | 11 ++-- package.json | 2 +- src/commands/credits/addons/balance.js | 14 ++--- src/commands/credits/addons/gift.js | 22 +++---- src/commands/credits/addons/give.js | 10 ++-- src/commands/credits/addons/redeem.js | 34 +++++------ src/commands/credits/addons/take.js | 12 ++-- src/commands/credits/addons/top.js | 7 +-- src/events/interactionCreate.js | 51 ++++++++++++++++ src/events/messageCreate.js | 41 +++++++++++++ src/events/ready.js | 9 +++ src/handlers/api.js | 4 +- src/handlers/logger.js | 2 +- src/helpers/database/index.js | 11 ++-- src/index.js | 81 ++++---------------------- 17 files changed, 199 insertions(+), 152 deletions(-) delete mode 100644 .env.example create mode 100644 config.json.example create mode 100644 src/events/interactionCreate.js create mode 100644 src/events/messageCreate.js create mode 100644 src/events/ready.js diff --git a/.env.example b/.env.example deleted file mode 100644 index 78a1595..0000000 --- a/.env.example +++ /dev/null @@ -1,19 +0,0 @@ -BOT_TOKEN=YOUR BOT TOKEN -BOT_CLIENT_ID=YOUR BOT CLIENT ID -BOT_GUILD_ID=THE GUILD ID WHERE THE BOT WILL LIVE - -FOOTER_TEXT=FOOTER_TEXT -FOOTER_ICON=FOOTER_ICON - -API_URL=CONTROLPANEL.GG URL scheme://domain/api/ -API_TOKEN=CONTROLPANEL.GG TOKEN - -DISABLE_REDEEM=FALSE - -MONGODB_URL="CONNECTION STRNIG" - -SUCCESS_COLOR=0xHEX -ERROR_COLOR=0xHEX -WAIT_COLOR=0xHEX - -DEBUG=FALSE diff --git a/config.json.example b/config.json.example new file mode 100644 index 0000000..748cd41 --- /dev/null +++ b/config.json.example @@ -0,0 +1,21 @@ +{ + "bot": { + "token": "required", + "clientId": "required", + "guildId": "required" + }, + "credits": { + "url": "scheme://domain/api/", + "token": "required", + "timeout": "5000", + "rate": "1", + "minimumLength": "5" + }, + "colors": { "success": "0x22bb33", "error": "0xbb2124", "wait": "0xf0ad4e" }, + "mongodb": { + "url": "mongodb+srv://username:password@server/database?retryWrites=true&w=majority" + }, + "footer": { "icon": "https://avatars.githubusercontent.com/u/83163073", "text": "https://github.com/ZynerOrg/xyter" }, + "disable": { "redeem": false }, + "debug": false +} diff --git a/deploy-commands.js b/deploy-commands.js index a052540..19a30b8 100644 --- a/deploy-commands.js +++ b/deploy-commands.js @@ -1,20 +1,21 @@ -require('dotenv').config(); +__basedir = __dirname; +__config = require(`${__basedir}/config.json`); const fs = require('node:fs'); const { REST } = require('@discordjs/rest'); const { Routes } = require('discord-api-types/v9'); const commands = []; -const commandFiles = fs.readdirSync('./src/commands'); +const commandFiles = fs.readdirSync(`${__basedir}/src/commands`); for (const file of commandFiles) { - const command = require(`./src/commands/${file}`); + const command = require(`${__basedir}/src/commands/${file}`); commands.push(command.data.toJSON()); } -const rest = new REST({ version: '9' }).setToken(process.env.BOT_TOKEN); +const rest = new REST({ version: '9' }).setToken(__config.bot.token); rest - .put(Routes.applicationGuildCommands(process.env.BOT_CLIENT_ID, process.env.BOT_GUILD_ID), { + .put(Routes.applicationGuildCommands(__config.bot.clientId, __config.bot.guildId), { body: commands, }) .then(() => console.log('Successfully registered application commands.')) diff --git a/package.json b/package.json index 940c909..ab8d429 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "xyter", - "version": "2.0.0", + "version": "2.1.0", "description": "Earn credits while chatting! And more", "main": "src/index.js", "scripts": { diff --git a/src/commands/credits/addons/balance.js b/src/commands/credits/addons/balance.js index 398a51e..20ca0a0 100644 --- a/src/commands/credits/addons/balance.js +++ b/src/commands/credits/addons/balance.js @@ -1,6 +1,6 @@ -const credits = require('../../../helpers/database/models/creditSchema'); -const logger = require('../../../handlers/logger'); -const creditNoun = require('../../../helpers/creditNoun'); +const credits = require(`${__basedir}/helpers/database/models/creditSchema`); +const logger = require(`${__basedir}/handlers/logger`); +const creditNoun = require(`${__basedir}/helpers/creditNoun`); module.exports = async (interaction) => { try { @@ -13,9 +13,9 @@ module.exports = async (interaction) => { const embed = { title: 'Balance', description: `${user} has no credits.`, - color: process.env.SUCCESS_COLOR, + color: __config.colors.success, timestamp: new Date(), - footer: { iconURL: process.env.FOOTER_ICON, text: process.env.FOOTER_TEXT }, + footer: { iconURL: __config.footer.icon, text: __config.footer.text }, }; return await interaction.editReply({ embeds: [embed], ephemeral: true }); @@ -25,9 +25,9 @@ module.exports = async (interaction) => { const embed = { title: 'Balance', description: `${user ? `${user} has` : 'You have'} ${creditNoun(balance)}.`, - color: process.env.SUCCESS_COLOR, + color: __config.colors.success, timestamp: new Date(), - footer: { iconURL: process.env.FOOTER_ICON, text: process.env.FOOTER_TEXT }, + footer: { iconURL: __config.footer.icon, text: __config.footer.text }, }; return await interaction.editReply({ embeds: [embed], ephemeral: true }); } diff --git a/src/commands/credits/addons/gift.js b/src/commands/credits/addons/gift.js index a9427a4..c9f0bf6 100644 --- a/src/commands/credits/addons/gift.js +++ b/src/commands/credits/addons/gift.js @@ -1,7 +1,7 @@ -const credits = require('../../../helpers/database/models/creditSchema'); -const logger = require('../../../handlers/logger'); -const saveUser = require('../../../helpers/saveUser'); -const creditNoun = require('../../../helpers/creditNoun'); +const credits = require(`${__basedir}/helpers/database/models/creditSchema`); +const logger = require(`${__basedir}/handlers/logger`); +const saveUser = require(`${__basedir}/helpers/saveUser`); +const creditNoun = require(`${__basedir}/helpers/creditNoun`); module.exports = async (interaction) => { try { @@ -15,7 +15,7 @@ module.exports = async (interaction) => { description: "You can't pay yourself.", color: 0xbb2124, timestamp: new Date(), - footer: { iconURL: process.env.FOOTER_ICON, text: process.env.FOOTER_TEXT }, + footer: { iconURL: __config.footer.icon, text: __config.footer.text }, }; return await interaction.editReply({ embeds: [embed], ephemeral: true }); } else if (amount <= 0) { @@ -24,7 +24,7 @@ module.exports = async (interaction) => { description: "You can't pay zero or below.", color: 0xbb2124, timestamp: new Date(), - footer: { iconURL: process.env.FOOTER_ICON, text: process.env.FOOTER_TEXT }, + footer: { iconURL: __config.footer.icon, text: __config.footer.text }, }; return await interaction.editReply({ embeds: [embed], ephemeral: true }); } else { @@ -34,7 +34,7 @@ module.exports = async (interaction) => { description: `You have insufficient credits. Your balance is ${data.balance}`, color: 0xbb2124, timestamp: new Date(), - footer: { iconURL: process.env.FOOTER_ICON, text: process.env.FOOTER_TEXT }, + footer: { iconURL: __config.footer.icon, text: __config.footer.text }, }; return await interaction.editReply({ embeds: [embed], ephemeral: true }); } else { @@ -48,12 +48,12 @@ module.exports = async (interaction) => { const embed = { title: 'Gift', - description: `You sent ${creditNoun( - amount - )} to ${user}. Your new balance is ${creditNoun(fromUser.balance)}.`, + description: `You sent ${creditNoun(amount)} to ${user}. Your new balance is ${creditNoun( + fromUser.balance + )}.`, color: 0x22bb33, timestamp: new Date(), - footer: { iconURL: process.env.FOOTER_ICON, text: process.env.FOOTER_TEXT }, + footer: { iconURL: __config.footer.icon, text: __config.footer.text }, }; await logger.debug(`Gift sent from: ${interaction.user.username} to: ${user.username}`); return await interaction.editReply({ embeds: [embed], ephemeral: true }); diff --git a/src/commands/credits/addons/give.js b/src/commands/credits/addons/give.js index 8ebb9ef..c57f047 100644 --- a/src/commands/credits/addons/give.js +++ b/src/commands/credits/addons/give.js @@ -1,8 +1,8 @@ const { Permissions } = require('discord.js'); -const credits = require('../../../helpers/database/models/creditSchema'); -const logger = require('../../../handlers/logger'); -const creditNoun = require('../../../helpers/creditNoun'); +const credits = require(`${__basedir}/helpers/database/models/creditSchema`); +const logger = require(`${__basedir}/handlers/logger`); +const creditNoun = require(`${__basedir}/helpers/creditNoun`); module.exports = async (interaction) => { try { @@ -22,7 +22,7 @@ module.exports = async (interaction) => { description: "You can't give zero or below.", color: 0xbb2124, timestamp: new Date(), - footer: { iconURL: process.env.FOOTER_ICON, text: process.env.FOOTER_TEXT }, + footer: { iconURL: __config.footer.icon, text: __config.footer.text }, }; return await interaction.editReply({ embeds: [embed], ephemeral: true }); } else { @@ -34,7 +34,7 @@ module.exports = async (interaction) => { description: `Gave ${creditNoun(amount)} to ${user}.`, color: 0x22bb33, timestamp: new Date(), - footer: { iconURL: process.env.FOOTER_ICON, text: process.env.FOOTER_TEXT }, + footer: { iconURL: __config.footer.icon, text: __config.footer.text }, }; await logger.debug( `Administrator: ${interaction.user.username} gave ${ diff --git a/src/commands/credits/addons/redeem.js b/src/commands/credits/addons/redeem.js index 9291ca7..44e7fc9 100644 --- a/src/commands/credits/addons/redeem.js +++ b/src/commands/credits/addons/redeem.js @@ -1,19 +1,19 @@ -const credits = require('../../../helpers/database/models/creditSchema'); -const logger = require('../../../handlers/logger'); -const creditNoun = require('../../../helpers/creditNoun'); +const credits = require(`${__basedir}/helpers/database/models/creditSchema`); +const logger = require(`${__basedir}/handlers/logger`); +const creditNoun = require(`${__basedir}/helpers/creditNoun`); -const api = require('../../../handlers/api.js'); +const api = require(`${__basedir}/handlers/api.js`); const { v4: uuidv4 } = require('uuid'); module.exports = async (interaction) => { try { - if (!process.env.DISABLE_REDEEM) { + if (__config.disable.redeem) { const embed = { title: 'Redeem failed', description: `Redeem is disabled until further.`, - color: 0xbb2124, + color: __config.colors.error, timestamp: new Date(), - footer: { iconURL: process.env.FOOTER_ICON, text: process.env.FOOTER_TEXT }, + footer: { iconURL: __config.footer.icon, text: __config.footer.text }, }; return await interaction.editReply({ embeds: [embed], ephemeral: true }); } @@ -25,27 +25,27 @@ module.exports = async (interaction) => { const embed = { title: 'Redeem', description: `You can't redeem below 100. Your balance is ${user.balance}.`, - color: 0xbb2124, + color: __config.colors.error, timestamp: new Date(), - footer: { iconURL: process.env.FOOTER_ICON, text: process.env.FOOTER_TEXT }, + footer: { iconURL: __config.footer.icon, text: __config.footer.text }, }; return await interaction.editReply({ embeds: [embed], ephemeral: true }); } else if ((amount || user.balance) > 1000000) { const embed = { title: 'Redeem', description: `You can't redeem over 1,000,000. Your balance is ${user.balance}.`, - color: 0xbb2124, + color: __config.colors.error, timestamp: new Date(), - footer: { iconURL: process.env.FOOTER_ICON, text: process.env.FOOTER_TEXT }, + footer: { iconURL: __config.footer.icon, text: __config.footer.text }, }; return await interaction.editReply({ embeds: [embed], ephemeral: true }); } else if (user.balance < amount) { const embed = { title: 'Redeem', description: `You have insufficient credits. Your balance is ${user.balance}.`, - color: 0xbb2124, + color: __config.colors.error, timestamp: new Date(), - footer: { iconURL: process.env.FOOTER_ICON, text: process.env.FOOTER_TEXT }, + footer: { iconURL: __config.footer.icon, text: __config.footer.text }, }; return await interaction.editReply({ embeds: [embed], ephemeral: true }); } else { @@ -70,9 +70,9 @@ module.exports = async (interaction) => { inline: true, }, ], - color: 0x22bb33, + color: __config.colors.success, timestamp: new Date(), - footer: { iconURL: process.env.FOOTER_ICON, text: process.env.FOOTER_TEXT }, + footer: { iconURL: __config.footer.icon, text: __config.footer.text }, }; user.balance -= amount || user.balance; @@ -86,9 +86,9 @@ module.exports = async (interaction) => { const embed = { title: 'Redeem', description: 'Something went wrong.', - color: 0xbb2124, + color: __config.colors.error, timestamp: new Date(), - footer: { iconURL: process.env.FOOTER_ICON, text: process.env.FOOTER_TEXT }, + footer: { iconURL: __config.footer.icon, text: __config.footer.text }, }; return await interaction.editReply({ embeds: [embed], ephemeral: true }); }); diff --git a/src/commands/credits/addons/take.js b/src/commands/credits/addons/take.js index db8d037..fccc0cd 100644 --- a/src/commands/credits/addons/take.js +++ b/src/commands/credits/addons/take.js @@ -1,8 +1,8 @@ const { Permissions } = require('discord.js'); -const credits = require('../../../helpers/database/models/creditSchema'); -const logger = require('../../../handlers/logger'); -const creditNoun = require('../../../helpers/creditNoun'); +const credits = require(`${__basedir}/helpers/database/models/creditScheme`); +const logger = require(`${__basedir}/handlers/logger`); +const creditNoun = require(`${__basedir}/helpers/creditNoun`); module.exports = async (interaction) => { if (!interaction.member.permissions.has(Permissions.FLAGS.MANAGE_GUILD)) { @@ -11,7 +11,7 @@ module.exports = async (interaction) => { description: 'You need to have permission to manage this guild (MANAGE_GUILD)', color: 0xbb2124, timestamp: new Date(), - footer: { iconURL: process.env.FOOTER_ICON, text: process.env.FOOTER_TEXT }, + footer: { iconURL: __config.footer.icon, text: __config.footer.text }, }; return await interaction.editReply({ embeds: [embed], ephemeral: true }); } @@ -24,7 +24,7 @@ module.exports = async (interaction) => { description: "You can't take zero or below.", color: 0xbb2124, timestamp: new Date(), - footer: { iconURL: process.env.FOOTER_ICON, text: process.env.FOOTER_TEXT }, + footer: { iconURL: __config.footer.icon, text: __config.footer.text }, }; return await interaction.editReply({ embeds: [embed], ephemeral: true }); } @@ -37,7 +37,7 @@ module.exports = async (interaction) => { description: `You took ${creditNoun(amount)} to ${user}.`, color: 0x22bb33, timestamp: new Date(), - footer: { iconURL: process.env.FOOTER_ICON, text: process.env.FOOTER_TEXT }, + footer: { iconURL: __config.footer.icon, text: __config.footer.text }, }; await logger.debug( `Administrator: ${interaction.user.username} took ${ diff --git a/src/commands/credits/addons/top.js b/src/commands/credits/addons/top.js index f7e230e..2169bc3 100644 --- a/src/commands/credits/addons/top.js +++ b/src/commands/credits/addons/top.js @@ -1,6 +1,5 @@ -const credits = require('../../../helpers/database/models/creditSchema'); -const logger = require('../../../handlers/logger'); -const creditNoun = require('../../../helpers/creditNoun'); +const credits = require(`${__basedir}/helpers/database/models/creditSchema`); +const creditNoun = require(`${__basedir}/helpers/creditNoun`); module.exports = async (interaction) => { await credits.find().then(async (data) => { @@ -13,7 +12,7 @@ module.exports = async (interaction) => { description: `Below are the top ten.\n${topTen.map((x, index) => item(x, index)).join('\n')}`, color: 0x22bb33, timestamp: new Date(), - footer: { iconURL: process.env.FOOTER_ICON, text: process.env.FOOTER_TEXT }, + footer: { iconURL: __config.footer.icon, text: __config.footer.text }, }; return await interaction.editReply({ embeds: [embed], ephemeral: true }); }); diff --git a/src/events/interactionCreate.js b/src/events/interactionCreate.js new file mode 100644 index 0000000..b20cb76 --- /dev/null +++ b/src/events/interactionCreate.js @@ -0,0 +1,51 @@ +const logger = require(`${__basedir}/handlers/logger`); + +module.exports = { + name: 'interactionCreate', + async execute(interaction) { + if (!interaction.isCommand()) return; + + const command = interaction.client.commands.get(interaction.commandName); + + if (!command) return; + + try { + await interaction.deferReply({ + embeds: [ + { + author: { + name: interaction.client.user.username, + icon_url: interaction.client.user.displayAvatarURL(), + url: 'https://bot.zyner.org/', + }, + title: 'Check', + description: 'Please wait...', + color: __config.colors.wait, + timestamp: new Date(), + }, + ], + ephemeral: true, + }); + await command.execute(interaction); + await logger.debug(`Executing command: ${interaction.commandName}`); + } catch (err) { + await logger.error(err); + await interaction.reply({ + embeds: [ + { + author: { + name: interaction.client.user.username, + icon_url: interaction.client.user.displayAvatarURL(), + url: 'https://bot.zyner.org/', + }, + title: 'Error', + description: 'There was an error while executing this command!', + color: __config.colors.error, + timestamp: new Date(), + }, + ], + ephemeral: true, + }); + } + }, +}; diff --git a/src/events/messageCreate.js b/src/events/messageCreate.js new file mode 100644 index 0000000..a4a5fcf --- /dev/null +++ b/src/events/messageCreate.js @@ -0,0 +1,41 @@ +const logger = require(`${__basedir}/handlers/logger`); + +const credits = require(`${__basedir}/helpers/database/models/creditSchema`); + +const talkedRecently = new Set(); + +module.exports = { + name: 'messageCreate', + async execute(message) { + if (message.author.bot) return; + if (message.content.length < __config.credits.minimumLength) return; + + if (!talkedRecently.has(message.author.id)) { + await credits + .findOneAndUpdate( + { userId: message.author.id }, + { $inc: { balance: __config.credits.rate } }, + { new: true, upsert: true } + ) + .then(async () => await logger.debug(`Credits added to user: ${message.author.id}`)) + .catch(async (err) => { + await logger.error(err); + }); + talkedRecently.add(message.author.id); + setTimeout(() => { + logger.debug( + `User: ${message.author.id} has not talked within last ${ + __config.credits.timeout / 1000 + } seconds, credits can be given` + ); + talkedRecently.delete(message.author.id); + }, __config.credits.timeout); + } else { + logger.debug( + `User: ${message.author.id} has talked within last ${ + __config.credits.timeout / 1000 + } seconds, no credits given` + ); + } + }, +}; diff --git a/src/events/ready.js b/src/events/ready.js new file mode 100644 index 0000000..781fb4f --- /dev/null +++ b/src/events/ready.js @@ -0,0 +1,9 @@ +const logger = require(`${__basedir}/handlers/logger`); + +module.exports = { + name: 'ready', + once: true, + async execute(client) { + await logger.info(`Ready! Logged in as ${client.user.tag}`); + }, +}; diff --git a/src/handlers/api.js b/src/handlers/api.js index 21b9a70..84f4bab 100644 --- a/src/handlers/api.js +++ b/src/handlers/api.js @@ -1,6 +1,6 @@ const axios = require('axios'); module.exports = axios.create({ - baseURL: process.env.API_URL, - headers: { Authorization: `Bearer ${process.env.API_TOKEN}` }, + baseURL: __config.credits.url, + headers: { Authorization: `Bearer ${__config.credits.token}` }, }); diff --git a/src/handlers/logger.js b/src/handlers/logger.js index 1c8e610..99c1469 100644 --- a/src/handlers/logger.js +++ b/src/handlers/logger.js @@ -1,3 +1,3 @@ const pino = require('pino'); -const logger = pino({ level: process.env.DEBUG ? 'debug' : 'info' }); +const logger = pino({ level: __config.debug ? 'debug' : 'info' }); module.exports = logger; diff --git a/src/helpers/database/index.js b/src/helpers/database/index.js index 4ea36a3..96605ea 100644 --- a/src/helpers/database/index.js +++ b/src/helpers/database/index.js @@ -1,11 +1,12 @@ +const logger = require(`${__basedir}/handlers/logger`); + const mongoose = require('mongoose'); module.exports = async () => { try { - await mongoose.connect(process.env.MONGODB_URL); - console.log('Connected to the database'); - } - catch (e) { - console.log(e); + await mongoose.connect(__config.mongodb.url); + await logger.info('Connected to the database'); + } catch (err) { + await logger.error(err); } }; diff --git a/src/index.js b/src/index.js index a53f9d6..3c39a68 100644 --- a/src/index.js +++ b/src/index.js @@ -1,13 +1,14 @@ -require('dotenv').config(); +__basedir = __dirname; +__config = require(`${__basedir}/../config.json`); require('./helpers/database')(); const fs = require('node:fs'); const { Client, Collection, Intents } = require('discord.js'); -const credits = require('./helpers/database/models/creditSchema'); -const logger = require('./handlers/logger'); const client = new Client({ intents: [Intents.FLAGS.GUILDS, Intents.FLAGS.GUILD_MESSAGES] }); +const eventFiles = fs.readdirSync('./src/events').filter((file) => file.endsWith('.js')); + client.commands = new Collection(); const commandFiles = fs.readdirSync('./src/commands'); @@ -16,71 +17,13 @@ for (const file of commandFiles) { client.commands.set(command.data.name, command); } -client.once('ready', async () => { - await logger.info('Ready!'); -}); - -client.on('interactionCreate', async (interaction) => { - if (!interaction.isCommand()) return; - - const command = client.commands.get(interaction.commandName); - - if (!command) return; - - try { - await interaction.deferReply({ - embeds: [ - { - author: { - name: interaction.client.user.username, - icon_url: interaction.client.user.displayAvatarURL(), - url: 'https://bot.zyner.org/', - }, - title: 'Check', - description: 'Please wait...', - color: process.env.WAIT_COLOR, - timestamp: new Date(), - }, - ], - ephemeral: true, - }); - await command.execute(interaction); - await logger.debug(`Executing command: ${interaction.commandName}`); +for (const file of eventFiles) { + const event = require(`./events/${file}`); + if (event.once) { + client.once(event.name, (...args) => event.execute(...args)); + } else { + client.on(event.name, (...args) => event.execute(...args)); } - catch (err) { - await logger.error(err); - await interaction.reply({ - embeds: [ - { - author: { - name: interaction.client.user.username, - icon_url: interaction.client.user.displayAvatarURL(), - url: 'https://bot.zyner.org/', - }, - title: 'Error', - description: 'There was an error while executing this command!', - color: process.env.WAIT_COLOR, - timestamp: new Date(), - }, - ], - ephemeral: true, - }); - } -}); +} -client.on('messageCreate', async (message) => { - if (message.author.bot) return; - - await credits - .findOneAndUpdate( - { userId: message.author.id }, - { $inc: { balance: 1 } }, - { new: true, upsert: true } - ) - .then(async (data) => await logger.debug('Credits added:', message.author.id)) - .catch(async (err) => { - await logger.error(err); - }); -}); - -client.login(process.env.BOT_TOKEN); +client.login(__config.bot.token);