From 8e90be50a05ec265391036b83dd427be40c1285b Mon Sep 17 00:00:00 2001
From: Patric Plattner <patric@patricplattner.de>
Date: Tue, 31 Aug 2021 15:57:01 +0200
Subject: [PATCH] Adding per server locale support and adding German locale.

---
 commands/AddRoleMenu.js        |  51 ++++++-----
 commands/AddRoleToMenu.js      |  37 ++++----
 commands/AssignPermission.js   |  32 ++++---
 commands/ChangeLocale.js       |  24 +++++
 commands/DeleteRoleFromMenu.js |  37 ++++----
 commands/DeleteRoleMenu.js     |  29 +++---
 commands/EditRoleMenu.js       |  53 ++++++-----
 commands/ListPermissions.js    |  13 ++-
 commands/RevokePermission.js   |  29 +++---
 components/locale.js           |  55 ++++++++++++
 components/permConfig.js       |  50 +++++++++--
 components/roles.js            | 160 +++++++++++++++++++--------------
 index.js                       |  28 +++---
 locales/de.json                | 116 ++++++++++++++++++++++++
 locales/en.json                | 116 ++++++++++++++++++++++++
 models/RoleMenu.js             |  18 +---
 models/ServerConfig.js         |  15 +++-
 registerCommands.js            |  33 +++----
 util/locale.js                 |  21 +++++
 util/perm.js                   |   5 +-
 util/registerCommands.js       |  30 +++++++
 21 files changed, 707 insertions(+), 245 deletions(-)
 create mode 100644 commands/ChangeLocale.js
 create mode 100644 components/locale.js
 create mode 100644 locales/de.json
 create mode 100644 locales/en.json
 create mode 100644 util/locale.js
 create mode 100644 util/registerCommands.js

diff --git a/commands/AddRoleMenu.js b/commands/AddRoleMenu.js
index 3459176..a0e6acb 100644
--- a/commands/AddRoleMenu.js
+++ b/commands/AddRoleMenu.js
@@ -1,24 +1,29 @@
-const { SlashCommandBuilder } = require('@discordjs/builders');
+const {SlashCommandBuilder} = require('@discordjs/builders');
 
-module.exports = new SlashCommandBuilder()
-    .setName('add_role_menu')
-    .setDescription('Create a new role menu')
-    .addChannelOption( option =>
-        option.setName('channel')
-            .setDescription('Channel the menu will be put inside.')
-            .setRequired(true))
-    .addStringOption( option =>
-        option.setName('message')
-            .setDescription('Message content.')
-            .setRequired(true))
-    .addStringOption( option =>
-        option.setName('type')
-            .setDescription('NOT YET IMPLEMENTED Sets type of role menu.')
-            .setRequired(true)
-            .addChoice('One of N', 'one')
-            .addChoice('M of N', 'm')
-            .addChoice('Any of N', 'any'))
-    .addBooleanOption( option =>
-	    option.setName('verification')
-            .setDescription('NOT YET IMPLEMENTED Sets verification state of role menu.')
-            .setRequired(true))
\ No newline at end of file
+const locale = require('../util/locale');
+
+module.exports = (loc) => {
+    const commandLocale = locale.get(loc).slashCommands.add_role_menu;
+    return new SlashCommandBuilder()
+        .setName('add_role_menu')
+        .setDescription(commandLocale.description)
+        .addChannelOption(option =>
+            option.setName('channel')
+                .setDescription(commandLocale.channelDescription)
+                .setRequired(true))
+        .addStringOption(option =>
+            option.setName('message')
+                .setDescription(commandLocale.messageDescription)
+                .setRequired(true))
+        .addStringOption(option =>
+            option.setName('type')
+                .setDescription(commandLocale.typeDescription)
+                .setRequired(true)
+                .addChoice(commandLocale.typeChoices.oneOfN, 'one')
+                .addChoice(commandLocale.typeChoices.mOfN, 'm')
+                .addChoice(commandLocale.typeChoices.anyOfN, 'any'))
+        .addBooleanOption(option =>
+            option.setName('verification')
+                .setDescription(commandLocale.verificationDescription)
+                .setRequired(true));
+}
\ No newline at end of file
diff --git a/commands/AddRoleToMenu.js b/commands/AddRoleToMenu.js
index f43dd27..238b5ca 100644
--- a/commands/AddRoleToMenu.js
+++ b/commands/AddRoleToMenu.js
@@ -1,17 +1,22 @@
-const { SlashCommandBuilder } = require('@discordjs/builders');
+const {SlashCommandBuilder} = require('@discordjs/builders');
 
-module.exports = new SlashCommandBuilder()
-    .setName('add_role_to_menu')
-    .setDescription('Add role to a menu.')
-    .addChannelOption( option =>
-	    option.setName('channel')
-            .setDescription('Channel of the menu.')
-            .setRequired(true))
-    .addStringOption( option =>
-        option.setName('message_id')
-            .setDescription('Message ID of the menu.')
-            .setRequired(true))
-    .addRoleOption(option =>
-        option.setName('role')
-            .setDescription('Role to add to the menu.')
-            .setRequired(true))
\ No newline at end of file
+const locale = require('../util/locale');
+
+module.exports = (loc) => {
+    const commandLocale = locale.get(loc).slashCommands.add_role_to_menu;
+    return new SlashCommandBuilder()
+        .setName('add_role_to_menu')
+        .setDescription(commandLocale.description)
+        .addChannelOption(option =>
+            option.setName('channel')
+                .setDescription(commandLocale.channelDescription)
+                .setRequired(true))
+        .addStringOption(option =>
+            option.setName('message_id')
+                .setDescription(commandLocale.messageIDDescription)
+                .setRequired(true))
+        .addRoleOption(option =>
+            option.setName('role')
+                .setDescription(commandLocale.roleDescription)
+                .setRequired(true));
+}
\ No newline at end of file
diff --git a/commands/AssignPermission.js b/commands/AssignPermission.js
index b2009c4..e591f9a 100644
--- a/commands/AssignPermission.js
+++ b/commands/AssignPermission.js
@@ -1,14 +1,20 @@
-const { SlashCommandBuilder } = require('@discordjs/builders');
+const {SlashCommandBuilder} = require('@discordjs/builders');
 
-module.exports = new SlashCommandBuilder()
-    .setName('assign_permission')
-    .setDescription('Assign a permission to a role')
-    .addStringOption(option =>
-        option.setName('permission')
-            .setDescription('Permission to assign.')
-            .setRequired(true)
-            .addChoice("Role Menus", 'role_menu'))
-    .addRoleOption(option =>
-        option.setName('role')
-	        .setDescription('Role to assign permission to.')
-            .setRequired(true))
\ No newline at end of file
+const locale = require('../util/locale');
+
+module.exports = (loc) => {
+    const commandLocale = locale.get(loc).slashCommands.assign_permission;
+    return new SlashCommandBuilder()
+        .setName('assign_permission')
+        .setDescription(commandLocale.description)
+        .addStringOption(option =>
+            option.setName('permission')
+                .setDescription(commandLocale.permissionDescription)
+                .setRequired(true)
+                .addChoice(commandLocale.permissionChoices.roleMenus, 'role_menu')
+                .addChoice(commandLocale.permissionChoices.locale, 'locale'))
+        .addRoleOption(option =>
+            option.setName('role')
+                .setDescription(commandLocale.roleDescription)
+                .setRequired(true));
+}
\ No newline at end of file
diff --git a/commands/ChangeLocale.js b/commands/ChangeLocale.js
new file mode 100644
index 0000000..c93669a
--- /dev/null
+++ b/commands/ChangeLocale.js
@@ -0,0 +1,24 @@
+const {SlashCommandBuilder} = require('@discordjs/builders');
+const fs = require('fs');
+locale = require('../util/locale');
+
+module.exports = (loc, pathToLocales) => {
+    const commandLocale = locale.get(loc).slashCommands.change_locale;
+    return new SlashCommandBuilder()
+        .setName('change_locale')
+        .setDescription(commandLocale.description)
+        .addStringOption((option) => {
+            option.setName('locale')
+                .setDescription(commandLocale.localeDescription)
+                .setRequired(true)
+            const localeFiles = fs.readdirSync('./locales').filter(file => file.endsWith('.json'));
+            for (const localeFile of localeFiles) {
+                const locale1 = JSON.parse(fs.readFileSync(`./locales/${localeFile}`));
+                option.addChoice(locale1.commonName, locale1.locale);
+            }
+            return option
+        });
+
+}
+
+
diff --git a/commands/DeleteRoleFromMenu.js b/commands/DeleteRoleFromMenu.js
index b0c6004..d927919 100644
--- a/commands/DeleteRoleFromMenu.js
+++ b/commands/DeleteRoleFromMenu.js
@@ -1,17 +1,22 @@
-const { SlashCommandBuilder } = require('@discordjs/builders');
+const {SlashCommandBuilder} = require('@discordjs/builders');
 
-module.exports = new SlashCommandBuilder()
-    .setName('delete_role_from_menu')
-    .setDescription('Delete role from menu.')
-    .addChannelOption( option =>
-        option.setName('channel')
-            .setDescription('Channel of the menu.')
-            .setRequired(true))
-    .addStringOption( option =>
-        option.setName('message_id')
-            .setDescription('Message ID of the menu.')
-            .setRequired(true))
-    .addRoleOption(option =>
-        option.setName('role')
-            .setDescription('Role to remove from the menu.')
-            .setRequired(true))
\ No newline at end of file
+const locale = require('../util/locale');
+
+module.exports = (loc) => {
+    const commandLocale = locale.get(loc).slashCommands.delete_role_from_menu;
+    return new SlashCommandBuilder()
+        .setName('delete_role_from_menu')
+        .setDescription(commandLocale.description)
+        .addChannelOption(option =>
+            option.setName('channel')
+                .setDescription(commandLocale.channelDescription)
+                .setRequired(true))
+        .addStringOption(option =>
+            option.setName('message_id')
+                .setDescription(commandLocale.messageIDDescription)
+                .setRequired(true))
+        .addRoleOption(option =>
+            option.setName('role')
+                .setDescription(commandLocale.roleDescription)
+                .setRequired(true));
+}
\ No newline at end of file
diff --git a/commands/DeleteRoleMenu.js b/commands/DeleteRoleMenu.js
index 779a25f..a09c786 100644
--- a/commands/DeleteRoleMenu.js
+++ b/commands/DeleteRoleMenu.js
@@ -1,13 +1,18 @@
-const { SlashCommandBuilder } = require('@discordjs/builders');
+const {SlashCommandBuilder} = require('@discordjs/builders');
 
-module.exports = new SlashCommandBuilder()
-    .setName('delete_role_menu')
-    .setDescription('Delete a role menu')
-    .addChannelOption( option =>
-        option.setName('channel')
-            .setDescription('Select channel of to be deleted menu')
-            .setRequired(true))
-    .addStringOption( option =>
-        option.setName('message_id')
-            .setDescription('Message ID of to be deleted menu')
-            .setRequired(true))
\ No newline at end of file
+const locale = require('../util/locale');
+
+module.exports = (loc) => {
+    const commandLocale = locale.get(loc).slashCommands.delete_role_menu;
+    return new SlashCommandBuilder()
+        .setName('delete_role_menu')
+        .setDescription(commandLocale.description)
+        .addChannelOption(option =>
+            option.setName('channel')
+                .setDescription(commandLocale.channelDescription)
+                .setRequired(true))
+        .addStringOption(option =>
+            option.setName('message_id')
+                .setDescription(commandLocale.messageIDDescription)
+                .setRequired(true));
+}
\ No newline at end of file
diff --git a/commands/EditRoleMenu.js b/commands/EditRoleMenu.js
index 4bc2093..19f766d 100644
--- a/commands/EditRoleMenu.js
+++ b/commands/EditRoleMenu.js
@@ -1,25 +1,30 @@
-const { SlashCommandBuilder } = require('@discordjs/builders');
+const {SlashCommandBuilder} = require('@discordjs/builders');
 
-module.exports = new SlashCommandBuilder()
-    .setName('edit_role_menu')
-    .setDescription('Edit an existing role menu.')
-    .addChannelOption( option =>
-        option.setName('channel')
-            .setDescription('Channel of the menu.')
-            .setRequired(true))
-    .addStringOption( option =>
-        option.setName('message_id')
-            .setDescription('Message ID of the menu.')
-            .setRequired(true))
-    .addStringOption( option =>
-        option.setName('message')
-            .setDescription('Message content.'))
-    .addStringOption( option =>
-        option.setName('type')
-            .setDescription('NOT YET IMPLEMENTED')
-            .addChoice('One of N', 'one')
-            .addChoice('M of N', 'm')
-            .addChoice('Any of N', 'any'))
-    .addBooleanOption( option =>
-        option.setName('verification')
-            .setDescription('NOT YET IMPLEMENTED Sets verification state of role menu.'))
\ No newline at end of file
+const locale = require('../util/locale');
+
+module.exports = (loc) => {
+    const commandLocale = locale.get(loc).slashCommands.edit_role_menu;
+    return new SlashCommandBuilder()
+        .setName('edit_role_menu')
+        .setDescription(commandLocale.description)
+        .addChannelOption(option =>
+            option.setName('channel')
+                .setDescription(commandLocale.channelDescription)
+                .setRequired(true))
+        .addStringOption(option =>
+            option.setName('message_id')
+                .setDescription(commandLocale.messageIDDescription)
+                .setRequired(true))
+        .addStringOption(option =>
+            option.setName('message')
+                .setDescription(commandLocale.messageDescription))
+        .addStringOption(option =>
+            option.setName('type')
+                .setDescription(commandLocale.typeDescription)
+                .addChoice(commandLocale.typeChoices.oneOfN, 'one')
+                .addChoice(commandLocale.typeChoices.mOfN, 'm')
+                .addChoice(commandLocale.typeChoices.anyOfN, 'any'))
+        .addBooleanOption(option =>
+            option.setName('verification')
+                .setDescription(commandLocale.verificationDescription));
+}
\ No newline at end of file
diff --git a/commands/ListPermissions.js b/commands/ListPermissions.js
index b6d35be..c8f7af8 100644
--- a/commands/ListPermissions.js
+++ b/commands/ListPermissions.js
@@ -1,5 +1,10 @@
-const { SlashCommandBuilder } = require('@discordjs/builders');
+const {SlashCommandBuilder} = require('@discordjs/builders');
 
-module.exports = new SlashCommandBuilder()
-    .setName('list_permissions')
-    .setDescription('List all Permissions for this Server.');
\ No newline at end of file
+const locale = require('../util/locale');
+
+module.exports = (loc) => {
+    const commandLocale = locale.get(loc).slashCommands.list_permissions;
+    return new SlashCommandBuilder()
+        .setName('list_permissions')
+        .setDescription(commandLocale.description);
+}
\ No newline at end of file
diff --git a/commands/RevokePermission.js b/commands/RevokePermission.js
index 45b18c4..855bcd9 100644
--- a/commands/RevokePermission.js
+++ b/commands/RevokePermission.js
@@ -1,14 +1,19 @@
 const { SlashCommandBuilder } = require('@discordjs/builders');
 
-module.exports = new SlashCommandBuilder()
-    .setName('revoke_permission')
-    .setDescription('Revoke a permission from a role')
-    .addStringOption(option =>
-        option.setName('permission')
-            .setDescription('Permission to revoke.')
-            .setRequired(true)
-            .addChoice("Role Menus", 'role_menu'))
-    .addRoleOption(option =>
-        option.setName('role')
-            .setDescription('Role to revoke permission from.')
-            .setRequired(true))
\ No newline at end of file
+const locale = require('../util/locale');
+
+module.exports = (loc) => {
+    const commandLocale = locale.get(loc).slashCommands.revoke_permission;
+    return new SlashCommandBuilder()
+        .setName('revoke_permission')
+        .setDescription(commandLocale.description)
+        .addStringOption(option =>
+            option.setName('permission')
+                .setDescription(commandLocale.permissionDescription)
+                .setRequired(true)
+                .addChoice(commandLocale.permissionChoices.roleMenus, 'role_menu'))
+        .addRoleOption(option =>
+            option.setName('role')
+                .setDescription(commandLocale.roleDescription)
+                .setRequired(true));
+}
\ No newline at end of file
diff --git a/components/locale.js b/components/locale.js
new file mode 100644
index 0000000..b4d8424
--- /dev/null
+++ b/components/locale.js
@@ -0,0 +1,55 @@
+const ServerConfig = require('../models/ServerConfig');
+const RoleMenu = require('../models/RoleMenu');
+const checkPerm = require("../util/perm");
+const locales = require('../util/locale');
+const registerCommands = require('../util/registerCommands');
+
+async function changeLocale(interaction) {
+    let config = await ServerConfig.findOne({guildID: interaction.guild.id.toString()});
+    let locale = 'en';
+    if (config != null) {
+        locale = config.locale;
+    }
+    const functionLocale = locales.get(locale).components.locale;
+    if (!(await checkPerm(interaction.member, 'locale'))) {
+        await interaction.reply({content: functionLocale.authDenied, ephemeral: true})
+        return;
+    }
+    const newLocale = interaction.options.getString('locale');
+    if (newLocale !== config.locale) {
+        if (config == null) {
+            config = new ServerConfig()
+            config.guildID = interaction.guild.id.toString();
+            config.permissions = {
+                roleMenu: [], locale: []
+            }
+        }
+        config.locale = newLocale;
+        const messageLocale = locales.get(newLocale).misc.messageTemplates.roleDropdown
+        const menus = await RoleMenu.find({guildID: interaction.guild.id.toString()});
+        await Promise.all(menus.map(async (menu) => {
+            console.log(menu);
+            const message = await (await interaction.guild.channels.fetch(menu.channelID)).messages.fetch(menu.messageID);
+            let components = message.components;
+            components[0].components[0].options[components[0].components[0].options.map((option) => option.value).indexOf('select_reset')].label = messageLocale.selectResetText;
+            components[0].components[0].placeholder = messageLocale.placeholder;
+            await message.edit({content: message.content, components});
+            return true;
+        }));
+        await config.save();
+        await interaction.reply({content: locales.get(newLocale).components.locale.localeApplied, ephemeral: true});
+        await registerCommands(interaction.guild.id.toString(), './commands');
+    } else {
+        await interaction.reply({content: functionLocale.sameLocale, ephemeral: true});
+    }
+}
+
+const slashCommandHandler = async (interaction) => {
+    if (interaction.commandName === 'change_locale') {
+        await changeLocale(interaction);
+    }
+}
+
+module.exports = {
+    slashCommandHandler
+}
diff --git a/components/permConfig.js b/components/permConfig.js
index 4235839..85c1524 100644
--- a/components/permConfig.js
+++ b/components/permConfig.js
@@ -1,11 +1,17 @@
 const ServerConfig = require('../models/ServerConfig');
 const {Permissions} = require('discord.js');
+const locales = require("../util/locale");
 
 async function assignPermission(interaction) {
+    let config = await ServerConfig.findOne({guildID: interaction.guild.id.toString()});
+    let locale = 'en';
+    if (config != null) {
+        locale = config.locale;
+    }
+    const functionLocale = locales.get(locale).components.permConfig;
     if (interaction.member.permissions.has(Permissions.FLAGS.ADMINISTRATOR)) {
         const role = interaction.options.getRole('role');
         const perm = interaction.options.getString('permission');
-        let config = await ServerConfig.findOne({guildID: interaction.guild.id.toString()});
         if (config == null) {
             config = new ServerConfig();
             config.guildID = interaction.guild.id.toString();
@@ -15,15 +21,30 @@ async function assignPermission(interaction) {
             if (!config.permissions.roleMenu.includes(role.id.toString())) {
                 config.permissions.roleMenu.push(role.id.toString());
             }
+        } else if (perm === 'locale') {
+            if (!config.permissions.locale.includes(role.id.toString())) {
+                config.permissions.locale.push(role.id.toString());
+            }
         }
         await config.save();
-        await interaction.reply({content: `Role ${role.name} has been added to ${perm} permission.`, ephemeral: true});
+        await interaction.reply({
+            content: functionLocale.replyAssign
+                .replaceAll("$$ROLE$$", `${role.name}`)
+                .replaceAll('$$PERM$$', `${perm}`),
+            ephemeral: true
+        });
     } else {
-        await interaction.reply({content: 'Only administrators can access this command.', ephemeral: true});
+        await interaction.reply({content: functionLocale.accessDenied, ephemeral: true});
     }
 }
 
 async function revokePermission(interaction) {
+    let config = await ServerConfig.findOne({guildID: interaction.guild.id.toString()});
+    let locale = 'en';
+    if (config != null) {
+        locale = config.locale;
+    }
+    const functionLocale = locales.get(locale).components.permConfig;
     if (interaction.member.permissions.has(Permissions.FLAGS.ADMINISTRATOR)) {
         const role = interaction.options.getRole('role');
         const perm = interaction.options.getString('permission');
@@ -37,18 +58,30 @@ async function revokePermission(interaction) {
             if (config.permissions.roleMenu.includes(role.id.toString())) {
                 config.permissions.roleMenu.splice(config.permissions.roleMenu.indexOf(role.id.toString()), 1);
             }
+        } else if (perm === 'locale') {
+            if (config.permissions.locale.includes(role.id.toString())) {
+                config.permissions.locale.splice(config.permissions.locale.indexOf(role.id.toString()), 1);
+            }
         }
         await config.save();
         await interaction.reply({
-            content: `Role ${role.name} has been removed from ${perm} permission.`,
+            content: functionLocale.replyRevoke
+                .replaceAll("$$ROLE$$", `${role.name}`)
+                .replaceAll('$$PERM$$', `${perm}`),
             ephemeral: true
         });
     } else {
-        await interaction.reply({content: 'Only administrators can access this command.', ephemeral: true});
+        await interaction.reply({content: functionLocale.accessDenied, ephemeral: true});
     }
 }
 
 async function listPermissions(interaction) {
+    let config = await ServerConfig.findOne({guildID: interaction.guild.id.toString()});
+    let locale = 'en';
+    if (config != null) {
+        locale = config.locale;
+    }
+    const functionLocale = locales.get(locale).components.permConfig;
     if (interaction.member.permissions.has(Permissions.FLAGS.ADMINISTRATOR)) {
         let config = await ServerConfig.findOne({guildID: interaction.guild.id.toString()});
         if (config == null) {
@@ -58,7 +91,12 @@ async function listPermissions(interaction) {
         }
         const roles = await Promise.all(config.permissions.roleMenu.map(async (roleID) => (await interaction.guild.roles.fetch(roleID)).name));
 
-        await interaction.reply({content: `List of Permissions:\n\nRole Menu: ${roles.join(',')}`, ephemeral: true});
+        await interaction.reply({
+            content: functionLocale.replyList.replaceAll('$$ROLEMENU$$', `${roles.join(',')}`),
+            ephemeral: true
+        });
+    } else {
+        await interaction.reply({content: functionLocale.accessDenied, ephemeral: true});
     }
 }
 
diff --git a/components/roles.js b/components/roles.js
index 43985bd..ce1b8fb 100644
--- a/components/roles.js
+++ b/components/roles.js
@@ -1,11 +1,20 @@
 const RoleMenu = require('../models/RoleMenu');
+const ServerConfig = require('../models/ServerConfig');
 const {MessageActionRow, MessageSelectMenu} = require("discord.js");
 const checkPerm = require('../util/perm');
+const locales = require("../util/locale");
 
 // slashcommand handler
 async function addRoleMenu(interaction) {
+    const config = await ServerConfig.findOne({guildID: interaction.guild.id.toString()});
+    let locale = 'en';
+    if (config != null) {
+        locale = config.locale;
+    }
+    const functionLocale = locales.get(locale).components.roleMenu;
+    const messageLocale = locales.get(locale).misc.messageTemplates.roleDropdown;
     if (!(await checkPerm(interaction.member, 'role_menu'))) {
-        await interaction.reply({content: 'You are not authorized to do this.', ephemeral: true})
+        await interaction.reply({content: functionLocale.accessDenied, ephemeral: true});
         return;
     }
     const channel = interaction.options.getChannel('channel');
@@ -16,10 +25,10 @@ async function addRoleMenu(interaction) {
         .addComponents(
             new MessageSelectMenu()
                 .setCustomId('selectRole')
-                .setPlaceholder("Select a role.")
+                .setPlaceholder(messageLocale.placeholder)
                 .addOptions([
                     {
-                        label: 'Reset Selection',
+                        label: messageLocale.selectResetText,
                         value: 'select_reset'
                     }
                 ])
@@ -33,42 +42,64 @@ async function addRoleMenu(interaction) {
     menu.type = type;
     menu.roles = [];
     await menu.save();
-    await interaction.reply({content: 'Role Menu has been created.', ephemeral: true});
+    await interaction.reply({content: functionLocale.roleMenuCreated, ephemeral: true});
 }
 
 async function deleteRoleMenu(interaction) {
+    const config = await ServerConfig.findOne({guildID: interaction.guild.id.toString()});
+    let locale = 'en';
+    if (config != null) {
+        locale = config.locale;
+    }
+    const functionLocale = locales.get(locale).components.roleMenu;
     if (!(await checkPerm(interaction.member, 'role_menu'))) {
-        await interaction.reply({content: 'You are not authorized to do this.', ephemeral: true})
+        await interaction.reply({content: functionLocale.accessDenied, ephemeral: true})
         return;
     }
     const channel = interaction.options.getChannel('channel');
     const messageID = interaction.options.getString('message_id');
     let menu = await RoleMenu.findOne({guildID: channel.guild.id, channelID: channel.id, messageID});
     if (channel.isText()) {
-        const message = await channel.messages.fetch(messageID);
-        if (message != null) {
-            if (menu != null) {
-                try {
-                    await RoleMenu.deleteOne({_id: menu._id});
-                    await message.delete();
-                    await interaction.reply({content: 'Menu has been deleted.', ephemeral: true});
-                } catch (e) {
-                    await interaction.reply({content: 'Deleting the Menu has failed.', ephemeral: true});
+        var message = null;
+        var messageSuccess = true;
+        try {
+            message = await channel.messages.fetch(messageID);
+        } catch (e) {
+            messageSuccess = false;
+        }
+        if (messageSuccess) {
+            if (message != null) {
+                if (menu != null) {
+                    try {
+                        await RoleMenu.deleteOne({_id: menu._id});
+                        await message.delete();
+                        await interaction.reply({content: functionLocale.roleMenuDeleted, ephemeral: true});
+                    } catch (e) {
+                        await interaction.reply({content: functionLocale.roleMenuDeletedFailed, ephemeral: true});
+                    }
+                } else {
+                    await interaction.reply({content: functionLocale.notMenuMessage, ephemeral: true});
                 }
             } else {
-                await interaction.reply({content: 'Please select a menu message.', ephemeral: true});
+                await interaction.reply({content: functionLocale.messageIdNotFound, ephemeral: true});
             }
         } else {
-            await interaction.reply({content: 'The message ID does not exist in this channel.', ephemeral: true});
+            await interaction.reply({content: functionLocale.invalidMessageId, ephemeral: true})
         }
     } else {
-        await interaction.reply({content: 'Please select a text channel.', ephemeral: true});
+        await interaction.reply({content: functionLocale.channelNotText, ephemeral: true});
     }
 }
 
 async function addRoleToMenu(interaction) {
+    const config = await ServerConfig.findOne({guildID: interaction.guild.id.toString()});
+    let locale = 'en';
+    if (config != null) {
+        locale = config.locale;
+    }
+    const functionLocale = locales.get(locale).components.roleMenu;
     if (!(await checkPerm(interaction.member, 'role_menu'))) {
-        await interaction.reply({content: 'You are not authorized to do this.', ephemeral: true})
+        await interaction.reply({content: functionLocale.accessDenied, ephemeral: true})
         return;
     }
     const channel = interaction.options.getChannel('channel');
@@ -104,37 +135,38 @@ async function addRoleToMenu(interaction) {
                         await menu.save();
                         await message.edit({content: message.content, components});
                         await interaction.reply({
-                            content: `Role ${role.name} has been added to the message.`,
+                            content: functionLocale.roleAdded.replaceAll("$$ROLE$$", `${role.name}`),
                             ephemeral: true
                         });
                     } else {
                         await interaction.reply({
-                            content: `Role ${role.name} is already added to the message.`,
+                            content: functionLocale.roleAlreadyAdded.replaceAll('$$ROLE$$', `${role.name}`),
                             ephemeral: true
                         });
                     }
                 } else {
-                    await interaction.reply({content: 'Please select a menu message.', ephemeral: true});
+                    await interaction.reply({content: functionLocale.notMenuMessage, ephemeral: true});
                 }
             } else {
-                await interaction.reply({
-                    content: 'The message ID does not exist in this channel.',
-                    ephemeral: true
-                });
+                await interaction.reply({content: functionLocale.messageIdNotFound, ephemeral: true});
             }
         } else {
-            await interaction.reply({
-                content: 'The message ID was invalid.', ephemeral: true
-            })
+            await interaction.reply({content: functionLocale.invalidMessageId, ephemeral: true})
         }
     } else {
-        await interaction.reply({content: 'Please select a text channel.', ephemeral: true});
+        await interaction.reply({content: functionLocale.channelNotText, ephemeral: true});
     }
 }
 
 async function deleteRoleFromMenu(interaction) {
+    const config = await ServerConfig.findOne({guildID: interaction.guild.id.toString()});
+    let locale = 'en';
+    if (config != null) {
+        locale = config.locale;
+    }
+    const functionLocale = locales.get(locale).components.roleMenu;
     if (!(await checkPerm(interaction.member, 'role_menu'))) {
-        await interaction.reply({content: 'You are not authorized to do this.', ephemeral: true})
+        await interaction.reply({content: functionLocale.accessDenied, ephemeral: true})
         return;
     }
     const channel = interaction.options.getChannel('channel');
@@ -166,33 +198,39 @@ async function deleteRoleFromMenu(interaction) {
                             .splice(index2, 1);
                         await message.edit({content: message.content, components: message.components});
                         await menu.save();
-                        await interaction.reply({content: 'Role has been removed from menu.', ephemeral: true});
+                        await interaction.reply({
+                            content: functionLocale.roleRemoved.replaceAll('$$ROLE$$', `${role.name}`),
+                            ephemeral: true
+                        });
                     } else {
                         await interaction.reply({
-                            content: 'This role has not been added to the menu.',
+                            content: functionLocale.roleNotRemoved.replaceAll('$$ROLE$$', `${role.name}`),
                             ephemeral: true
                         });
                     }
                 } else {
-                    await interaction.reply({content: 'Please select a menu message.', ephemeral: true});
+                    await interaction.reply({content: functionLocale.notMenuMessage, ephemeral: true});
                 }
             } else {
-                await interaction.reply({
-                    content: 'The message ID does not exist in this channel.',
-                    ephemeral: true
-                });
+                await interaction.reply({content: functionLocale.messageIdNotFound, ephemeral: true});
             }
         } else {
-            await interaction.reply({
-                content: 'The message ID was invalid.', ephemeral: true
-            })
+            await interaction.reply({content: functionLocale.invalidMessageId, ephemeral: true})
         }
+    } else {
+        await interaction.reply({content: functionLocale.channelNotText, ephemeral: true});
     }
 }
 
 async function editRoleMenu(interaction) {
+    const config = await ServerConfig.findOne({guildID: interaction.guild.id.toString()});
+    let locale = 'en';
+    if (config != null) {
+        locale = config.locale;
+    }
+    const functionLocale = locales.get(locale).components.roleMenu;
     if (!(await checkPerm(interaction.member, 'role_menu'))) {
-        await interaction.reply({content: 'You are not authorized to do this.', ephemeral: true})
+        await interaction.reply({content: functionLocale.accessDenied, ephemeral: true})
         return;
     }
     const channel = interaction.options.getChannel('channel');
@@ -226,21 +264,19 @@ async function editRoleMenu(interaction) {
                         menu.verification = verification;
                     }
                     await menu.save();
-                    await interaction.reply({content: 'Menu has been updated.', ephemeral: true});
+                    await interaction.reply({content: functionLocale.menuUpdated, ephemeral: true});
+
                 } else {
-                    await interaction.reply({content: 'Please select a menu message.', ephemeral: true});
+                    await interaction.reply({content: functionLocale.notMenuMessage, ephemeral: true});
                 }
             } else {
-                await interaction.reply({
-                    content: 'The message ID does not exist in this channel.',
-                    ephemeral: true
-                });
+                await interaction.reply({content: functionLocale.messageIdNotFound, ephemeral: true});
             }
         } else {
-            await interaction.reply({
-                content: 'The message ID was invalid.', ephemeral: true
-            })
+            await interaction.reply({content: functionLocale.invalidMessageId, ephemeral: true})
         }
+    } else {
+        await interaction.reply({content: functionLocale.channelNotText, ephemeral: true});
     }
 }
 
@@ -264,6 +300,12 @@ const slashCommandHandler = async (interaction) => {
 
 const selectMenuHandler = async (interaction) => {
     if (interaction.customId === 'selectRole') {
+        const config = await ServerConfig.findOne({guildID: interaction.guild.id.toString()});
+        let locale = 'en';
+        if (config != null) {
+            locale = config.locale;
+        }
+        const functionLocale = locales.get(locale).components.roleMenu;
         const guild = interaction.guild;
         const channel = interaction.channel;
         const message = interaction.message;
@@ -272,32 +314,20 @@ const selectMenuHandler = async (interaction) => {
             channelID: channel.id,
             messageID: message.id
         });
-        console.log("1");
-        if (interaction.values[0] != 'placeholder') {
-            console.log("2");
             if (menu != null) {
-                console.log("3");
                 if (interaction.values[0] === 'select_reset') {
-                    console.log("4");
                     const roleIDs = menu.roles.map(role => role.roleID);
                     roleIDs.forEach(roleID => interaction.member.roles.remove(roleID));
-                    await interaction.reply({content: 'Your role has been removed.', ephemeral: true});
+                    await interaction.reply({content: functionLocale.interactionMessage.roleRemoved, ephemeral: true});
                 } else {
-                    console.log("5");
                     const roleIDs = menu.roles.map(role => role.roleID);
                     roleIDs.forEach(roleID => interaction.member.roles.remove(roleID));
                     interaction.member.roles.add(roleIDs[menu.roles.map(role => role.value).indexOf(interaction.values[0])]);
-                    await interaction.reply({content: 'You have received your role.', ephemeral: true});
+                    await interaction.reply({content: functionLocale.interactionMessage.roleAdded, ephemeral: true});
                 }
             } else {
-                await interaction.reply({content: 'Internal Error. Please contact admins.', ephemeral: true});
+                await interaction.reply({content: functionLocale.internalError, ephemeral: true});
             }
-        } else {
-            await interaction.reply({
-                content: 'This message does not have any roles yet. Please contact your administrator.',
-                ephemeral: true
-            });
-        }
     }
 }
 module.exports = {
diff --git a/index.js b/index.js
index 65968dd..61c457e 100644
--- a/index.js
+++ b/index.js
@@ -5,10 +5,16 @@ const botConfig = {
     token: process.env.DISCORD_API_TOKEN,
 };
 
+const locale = require('./util/locale')
+
 // Connecting Database.
 
 connectDB();
 
+// Initializing localizations
+
+locale.init()
+
 // Collecting all bot components.
 
 const components = [];
@@ -19,6 +25,8 @@ for (const file of componentFiles) {
     components.push(component);
 }
 
+// Creating the discord client.
+
 const client = new Client({intents: [Intents.FLAGS.GUILDS]});
 
 client.on('ready', () => {
@@ -27,26 +35,20 @@ client.on('ready', () => {
 
 client.on('interactionCreate', async (interaction) => {
     if (interaction.isCommand()) {
-        components.forEach( component => {
-           if (component.slashCommandHandler != null) {
-               component.slashCommandHandler(interaction);
-           }
-        });
-    } else if (interaction.isButton()) {
-        components.forEach( component => {
-            if (component.buttonHandler != null) {
-                component.buttonHandler(interaction);
+        components.forEach(component => {
+            if (component.slashCommandHandler !== undefined) {
+                component.slashCommandHandler(interaction);
             }
         });
     } else if (interaction.isButton()) {
-        components.forEach( component => {
-            if (component.buttonHandler != null) {
+        components.forEach(component => {
+            if (component.buttonHandler !== undefined) {
                 component.buttonHandler(interaction);
             }
         });
     } else if (interaction.isSelectMenu()) {
-        components.forEach( component => {
-            if (component.selectMenuHandler != null) {
+        components.forEach(component => {
+            if (component.selectMenuHandler !== undefined) {
                 component.selectMenuHandler(interaction);
             }
         });
diff --git a/locales/de.json b/locales/de.json
new file mode 100644
index 0000000..09f7abc
--- /dev/null
+++ b/locales/de.json
@@ -0,0 +1,116 @@
+{
+  "locale": "de",
+  "commonName": "Deutsch",
+  "translations": {
+    "slashCommands": {
+      "assign_permission": {
+        "description": "Eine Berechtigung einer Rolle hinzufügen.",
+        "permissionDescription": "Berechtigung, die hinzugefügt werden soll.",
+        "permissionChoices": {
+          "roleMenus": "Rollenmenüs",
+          "locale": "Sprache wechseln"
+        },
+        "roleDescription": "Rolle, der die Berechtigung hinzugefügt werden soll."
+      },
+      "revoke_permission": {
+        "description": "Einer Rolle eine Berechtigung entziehen.",
+        "permissionDescription": "Berechtigung, die entzogen werden soll.",
+        "permissionChoices": {
+          "roleMenus": "Rollenmenüs",
+          "locale": "Sprache wechseln"
+        },
+        "roleDescription": "Rolle, der die Berechtigung entzogen werden soll."
+      },
+      "add_role_menu": {
+        "description": "Ein neues Rollenmenü erstellen.",
+        "channelDescription": "Kanal, in den das Rollenmenü gelegt werden soll",
+        "messageDescription": "Nachricht des Rollenmenüs.",
+        "typeDescription": "NOT YET IMPLEMENTED Typ des Rollenmenüs.",
+        "typeChoices": {
+          "oneOfN": "Bis zu eine Rolle aus N",
+          "mOfN": "Bis zu M Rollen aus N",
+          "anyOfN": "Bis zu N Rollen aus N"
+        },
+        "verificationDescription": "NOT YET IMPLEMENTED Ist Fllaami Verifikation für dieses Rollenmenü notwendig?"
+      },
+      "delete_role_menu": {
+        "description": "Ein Rollenmenü löschen.",
+        "channelDescription": "Kanal des zu löschenden Menüs.",
+        "messageIDDescription": "Nachrichten ID des zu löschenden Menüs."
+      },
+      "edit_role_menu": {
+        "description": "Ein Rollenmenü bearbeiten.",
+        "channelDescription": "Kanal des zu bearbeitenden Menüs.",
+        "messageIDDescription": "Nachrichten ID des zu bearbeitenden Menüs.",
+        "messageDescription": "Message content.",
+        "typeDescription": "NOT YET IMPLEMENTED Typ des Rollenmenüs.",
+        "typeChoices": {
+          "oneOfN": "Bis zu eine Rolle aus N",
+          "mOfN": "Bis zu M Rollen aus N",
+          "anyOfN": "Bis zu N Rollen aus N"
+        },
+        "verificationDescription": "NOT YET IMPLEMENTED Ist Fllaami Verifikation für dieses Rollenmenü notwendig?."
+      },
+      "delete_role_from_menu": {
+        "description": "Rolle aus Rollenmenü löschen.",
+        "channelDescription": "Kanal des zu bearbeitenden Menüs.",
+        "messageIDDescription": "Nachrichten ID des zu bearbeitenden Menüs.",
+        "roleDescription": "Zu entfernende Rolle."
+      },
+      "add_role_to_menu": {
+        "description": "Einem Rollenmenü eine Rolle hinzufügen.",
+        "channelDescription": "Kanal des zu bearbeitenden Menüs.",
+        "messageIDDescription": "Nachrichten ID des zu bearbeitenden Menüs.",
+        "roleDescription": "Hinzuzufügende Rolle."
+      },
+      "list_permissions": {
+        "description": "Alle Berechtigungen des Servers auflisten."
+      },
+      "change_locale": {
+        "description": "Die Sprache des Servers wechseln.",
+        "localeDescription": "Sprache, zu der gewechselt werden soll."
+      }
+    },
+    "components": {
+      "locale": {
+        "authDenied": "Du darfst die Sprache des Bots auf diesem Server nicht ändern.",
+        "localeApplied": "Du hast die Sprache des Bots auf Deutsch gestellt.",
+        "sameLocale": "Die Sprache des Servers ist bereits Deutsch."
+      },
+      "permConfig": {
+        "replyAssign": "Der Rolle $$ROLE$$ wurde die $$PERM$$ Berechtigung hinzugefügt.",
+        "replyRevoke": "Der Rolle $ROLE$$ wurde die $$PERM$$ Berechtigung entzogen.",
+        "replyList": "Liste der Berechtigungen:\n\nRollenmenüs: $$ROLEMENU$$\nSprache ändern $$LOCALE$$",
+        "accessDenied": "Nur administratoren dürfen diesen Command nutzen."
+      },
+      "roleMenu": {
+        "accessDenied": "Du darfst diesen Command nicht nutzen.",
+        "channelNotText": "Bitte wähle einen Textkanal aus.",
+        "invalidMessageId": "Die Nachrichten ID war nicht gültig (falsches Format).'",
+        "messageIdNotFound": "Die Nachrichten ID gehört nicht zu einer Nachricht in diesem Kanal.",
+        "notMenuMessage": "Bitte wähle eine Nachricht, die zu einem Rollenmenü gehört, aus.",
+        "roleMenuCreated": "Das Rollenmenü wurde erstellt.",
+        "roleMenuDeleted": "Das Rollenmenü wurde gelöscht.",
+        "roleMenuDeletedFailed": "Das Rollenmenü konnte nicht gelöscht werden.",
+        "roleAdded": "Die Rolle $$ROLE$$ wurde dem Menü hinzugefügt.",
+        "roleAlreadyAdded": "Die Rolle $$ROLE$$ ist bereits in der Nachricht.",
+        "roleRemoved": "Die Rolle $$ROLE$$ Wurde aus dem Menü entfernt.",
+        "roleNotRemoved": "Die Rolle $$ROLE$$ wurde dem Menü noch nicht hinzugefügt.",
+        "menuUpdated": "Das Menü wurde aktualisiert.",
+        "interactionMessage": {
+          "roleAdded": "Du hast deine Rolle erhalten.",
+          "roleRemoved": "Deine Rolle wurde entfernt."
+        },
+        "internalError": "Interner Fehler. Bitte kontaktier einen Admin."
+      }
+    },
+    "misc": {
+      "messageTemplates": {
+        "roleDropdown": {
+          "placeholder": "Wähle eine Rolle aus.",
+          "selectResetText": "Auswahl zurücksetzen."
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/locales/en.json b/locales/en.json
new file mode 100644
index 0000000..56b4f76
--- /dev/null
+++ b/locales/en.json
@@ -0,0 +1,116 @@
+{
+  "locale": "en",
+  "commonName": "English",
+  "translations": {
+    "slashCommands": {
+      "assign_permission": {
+        "description": "Assign a permission to a role.",
+        "permissionDescription": "Permission to assign.",
+        "permissionChoices": {
+          "roleMenus": "Role Menus",
+          "locale": "Change Locales"
+        },
+        "roleDescription": "Role to assign permission to."
+      },
+      "revoke_permission": {
+        "description": "Revoke a permission from a role.",
+        "permissionDescription": "Permission to revoke.",
+        "permissionChoices": {
+          "roleMenus": "Role Menus",
+          "locale": "Change Locales"
+        },
+        "roleDescription": "Role to revoke permission from."
+      },
+      "add_role_menu": {
+        "description": "Create a new role menu.",
+        "channelDescription": "Channel the menu will be put inside.",
+        "messageDescription": "Message content.",
+        "typeDescription": "NOT YET IMPLEMENTED Sets type of role menu.",
+        "typeChoices": {
+          "oneOfN": "One of N",
+          "mOfN": "M of N",
+          "anyOfN": "Any of N"
+        },
+        "verificationDescription": "NOT YET IMPLEMENTED Sets verification state of role menu."
+      },
+      "delete_role_menu": {
+        "description": "Delete a role menu.",
+        "channelDescription": "Select channel of to be deleted menu.",
+        "messageIDDescription": "Message ID of to be deleted menu."
+      },
+      "edit_role_menu": {
+        "description": "Edit an existing role menu.",
+        "channelDescription": "Channel of the menu.",
+        "messageIDDescription": "Message ID of the menu.",
+        "messageDescription": "Message content.",
+        "typeDescription": "NOT YET IMPLEMENTED Sets type of role menu.",
+        "typeChoices": {
+          "oneOfN": "One of N",
+          "mOfN": "M of N",
+          "anyOfN": "Any of N"
+        },
+        "verificationDescription": "NOT YET IMPLEMENTED Sets verification state of role menu."
+      },
+      "delete_role_from_menu": {
+        "description": "Delete role from menu.",
+        "channelDescription": "Channel of the menu.",
+        "messageIDDescription": "Message ID of the menu.",
+        "roleDescription": "Role to remove from the menu."
+      },
+      "add_role_to_menu": {
+        "description": "Add role to a menu.",
+        "channelDescription": "Channel of the menu.",
+        "messageIDDescription": "Message ID of the menu.",
+        "roleDescription": "Role to add to the menu."
+      },
+      "list_permissions": {
+        "description": "List all permissions for this Server."
+      },
+      "change_locale": {
+        "description": "Change locale of the bot on this server.",
+        "localeDescription": "Locale you want to change to bot to."
+      }
+    },
+    "components": {
+      "locale": {
+        "authDenied": "You are not authorized to change the locale of the server.",
+        "localeApplied": "You changed the locale of the bot to English.",
+        "sameLocale": "The locale of the server is already english."
+      },
+      "permConfig": {
+        "replyAssign": "Role $$ROLE$$ has been aded to $$PERM$$ permission.",
+        "replyRevoke": "Role $$ROLE$$ has been removed from $$PERM$$ permission.",
+        "replyList": "List of Permissions:\n\nRole Menu: $$ROLEMENU$$\nLocale: $$LOCALE$$",
+        "accessDenied": "Only administrators can access this command."
+      },
+      "roleMenu": {
+        "accessDenied": "You are not authorized to do this.",
+        "channelNotText": "Please select a text channel.",
+        "invalidMessageId": "The message ID was invalid.'",
+        "messageIdNotFound": "The message ID does not exist in this channel.",
+        "notMenuMessage": "Please select a menu message.",
+        "roleMenuCreated": "Role Menu has been created.",
+        "roleMenuDeleted": "Role Menu has been deleted.",
+        "roleMenuDeletedFailed": "Deleting the Menu has failed.",
+        "roleAdded": "Role $$ROLE$$ has been added to the message.",
+        "roleAlreadyAdded": "Role $$ROLE$$ is already added to the message.",
+        "roleRemoved": "Role $$ROLE$$ has been removed from menu.",
+        "roleNotRemoved": "Role $$ROLE$$ has not yet been added to the menu.",
+        "menuUpdated": "Menu has been updated",
+        "interactionMessage": {
+          "roleAdded": "You have received your role.",
+          "roleRemoved": "Your role has been removed."
+        },
+        "internalError": "Internal Error. Please contact admins."
+      }
+    },
+    "misc": {
+      "messageTemplates": {
+        "roleDropdown": {
+          "placeholder": "Select a role.",
+          "selectResetText": "Reset selection."
+        }
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/models/RoleMenu.js b/models/RoleMenu.js
index 380fac5..d0932c4 100644
--- a/models/RoleMenu.js
+++ b/models/RoleMenu.js
@@ -2,28 +2,16 @@ const {Schema, model} = require('mongoose');
 
 const RoleMenuSchema = new Schema({
     guildID: {
-        type: Number,
+        type: String,
         required: true,
-        validate: {
-            validator: Number.isInteger,
-            message: '{VALUE} is not an integer value'
-        }
     },
     channelID: {
-        type: Number,
+        type: String,
         required: true,
-        validate: {
-            validator: Number.isInteger,
-            message: '{VALUE} is not an integer value'
-        }
     },
     messageID: {
-        type: Number,
+        type: String,
         required: true,
-        validate: {
-            validator: Number.isInteger,
-            message: '{VALUE} is not an integer value'
-        }
     },
     verification: {
         type: Boolean,
diff --git a/models/ServerConfig.js b/models/ServerConfig.js
index 1428e8a..39aad0d 100644
--- a/models/ServerConfig.js
+++ b/models/ServerConfig.js
@@ -6,10 +6,19 @@ const ServerConfigSchema = new Schema({
         unique: true,
         required: true
     },
+    locale: {
+        type: String,
+        required: true,
+        default: 'en'
+    },
     permissions: {
-    roleMenu: [{
-        type: String
-    }]}
+        roleMenu: [{
+            type: String
+        }],
+        locale: [{
+            type: String
+        }]
+    }
 });
 
 
diff --git a/registerCommands.js b/registerCommands.js
index 4ab8b75..49ed341 100644
--- a/registerCommands.js
+++ b/registerCommands.js
@@ -1,26 +1,24 @@
-const {REST} = require('@discordjs/rest');
-const {Routes} = require('discord-api-types/v9');
 const {Client, Intents} = require('discord.js');
-const fs = require('fs');
+const connectDB = require('./util/db');
 const botConfig = {
     token: process.env.DISCORD_API_TOKEN,
     applicationID: process.env.DISCORD_APP_ID
 };
+const locale = require('./util/locale');
+const registerCommands = require('./util/registerCommands');
+
+// Initializing Database
+
+connectDB()
+
+// Initializing locales
+
+locale.init();
 
 // Loading discord client to get all guild IDs
 const client = new Client({intents: [Intents.FLAGS.GUILDS]});
 
 client.on('ready', () => {
-    // Getting all command Javascript files from the commands folder
-    commands = []
-    const commandFiles = fs.readdirSync('./commands').filter(file => file.endsWith('.js'));
-
-    for (const file of commandFiles) {
-        const command = require(`./commands/${file}`);
-        commands.push(command);
-    }
-
-    const rest = new REST({version: '9'}).setToken(botConfig.token);
 
     (async () => {
         try {
@@ -29,15 +27,10 @@ client.on('ready', () => {
             const guildIDs = await client.guilds.cache.map(guild => guild.id);
             console.log(guildIDs)
             //Going through all guildIDs and registering the commands with each one.
-            await Promise.all(guildIDs.map(async (guildID) => {
-                console.log(guildID);
-                await rest.put(
-                    Routes.applicationGuildCommands(botConfig.applicationID, guildID),
-                    {body: commands},
-                );
-            }));
+            await Promise.all(guildIDs.map(async (guildID) => registerCommands(guildID, './commands')));
 
             console.log('Successfully reloaded application (/) commands.');
+            process.exit(0);
         } catch (error) {
             console.error(error);
         }
diff --git a/util/locale.js b/util/locale.js
new file mode 100644
index 0000000..bff1db0
--- /dev/null
+++ b/util/locale.js
@@ -0,0 +1,21 @@
+const fs = require('fs');
+
+let locales = null;
+
+module.exports = {
+    get: (locale) => {
+        if (locales[locale] !== undefined) {
+            return locales[locale];
+        } else {
+            return locales["en"];
+        }
+    },
+    init: () => {
+        locales = new Object();
+        const localeFiles = fs.readdirSync('./locales').filter(file => file.endsWith('.json'));
+        localeFiles.forEach((localeFile) => {
+            const locale = JSON.parse(fs.readFileSync(`./locales/${localeFile}`));
+            locales[locale.locale] = locale.translations;
+        });
+    }
+}
\ No newline at end of file
diff --git a/util/perm.js b/util/perm.js
index 4fe3a40..1c27730 100644
--- a/util/perm.js
+++ b/util/perm.js
@@ -8,10 +8,9 @@ module.exports = async (member, permission) => {
         return false;
     }
     if (permission === 'role_menu') {
-        //console.log(member.roles.cache);
-        //console.log(config.permissions.roleMenu);
-        console.log("ASD");
         return member.roles.cache.some((role) => config.permissions.roleMenu.some((prole) => prole == role.id.toString())) || member.permissions.has(Permissions.FLAGS.ADMINISTRATOR);
+    } else if (permission === 'locale') {
+        return member.roles.cache.some((role) => config.permissions.locale.some((prole) => prole == role.id.toString())) || member.permissions.has(Permissions.FLAGS.ADMINISTRATOR);
     }
     return false;
 }
\ No newline at end of file
diff --git a/util/registerCommands.js b/util/registerCommands.js
new file mode 100644
index 0000000..dadc378
--- /dev/null
+++ b/util/registerCommands.js
@@ -0,0 +1,30 @@
+const ServerConfig = require("../models/ServerConfig");
+const fs = require("fs");
+const {Routes} = require("discord-api-types/v9");
+const {REST} = require("@discordjs/rest");
+const botConfig = {
+    token: process.env.DISCORD_API_TOKEN,
+    applicationID: process.env.DISCORD_APP_ID
+};
+
+module.exports = async (guildID, pathToCommands) => {
+
+
+    const rest = new REST({version: '9'}).setToken(botConfig.token);
+    const config = await ServerConfig.findOne({guildID});
+    var serverLocale = 'en';
+    if (config != null) {
+        serverLocale = config.locale;
+    }
+    // Getting all command Javascript files from the commands folder
+    let commands = []
+    const commandFiles = fs.readdirSync(pathToCommands).filter(file => file.endsWith('.js'));
+    for (const file of commandFiles) {
+        const command = require(`../commands/${file}`);
+        commands.push(command(serverLocale));
+    }
+    await rest.put(
+        Routes.applicationGuildCommands(botConfig.applicationID, guildID),
+        {body: commands},
+    );
+}
\ No newline at end of file
-- 
GitLab