Changing the prefix for a guild can be done without needing a complete restart, while adding a new guild to my database inexplicably requires one

I have set up a code that adds guilds to the database with default settings when they join. If the guild decides to change the prefix, it updates successfully and they can immediately start using it. However, there is an issue where I have to restart the bot or use nodemon to auto-restart it upon changes for the new guild before they can use any commands. Is there a difference in how I am adding this information to the database compared to adding the prefix?

Below is the code I use to add the server to the database and below that is the code I use to allow them to change the prefix. I am attempting to make the commands work for the server that just invited the bot without having to restart the bot to prevent bugs down the line when it is interrupted and then restarted due to a new guild invitation.

/// code for adding a guild to the database upon invite
bot.on('guildCreate', async (guild) => {
    // Guild the user needs to have the role in
    let myGuild = await bot.guilds.fetch(process.env.BOT_GUILD);
    console.log(myGuild);

    // Required role for the user
    let requiredRole = process.env.PAID_ROLE;
    console.log(requiredRole);

    // Finding the default channel
    let defaultChannel = "";
    guild.channels.cache.forEach((channel) => {
      if(channel.type == "text" && defaultChannel == "") {
        if(channel.permissionsFor(guild.me).has("SEND_MESSAGES")) {
          defaultChannel = channel;
          console.log(defaultChannel);
        }
      }
    });

    // Member object of the user in guildA
    try{
        let guildOwner = await myGuild.members.fetch(guild.ownerID);
        console.log(guildOwner);

        if (!guildOwner)
        return console.log(`Oops, ${guild.owner} is not a member of your server.`);
    }catch(error) {
        return console.log(`Oops, ${guild.owner} is not a member of your server.`),
        defaultChannel.send('Please kick the bot, have the guild owner join this discord https://discord.gg/tDTjBAaCAn, Then you can reinvite the bot and you will be properly added to the database and can use the bot! dont forget to check out the premium features while your there if you decide you want more features from Gate Bot!');
    }
    // Checking if they have the role 
    let guildOwner = await myGuild.members.fetch(guild.ownerID);
    let ownerHasPaidRole = guildOwner.roles.cache.has(process.env.PAID_ROLE);

    if (ownerHasPaidRole){
      console.log(`Woohoo, ${guildOwner} has the required role`);}
        try {
            /// Insert serverid and serverownerid into servers db
        await connection.query(
            `INSERT INTO Servers (serverId, serverOwnerId, paidRole) VALUES ('${guild.id}', '${guild.ownerID}', 1)`
            );
            /// Insert server id into serverconfig db
        await connection.query(
            `INSERT INTO ServerConfig (serverId) VALUES ('${guild.id}')`
            );
        }catch(err){
            console.log(err);
    }});


Message handler for using the change prefix command

/// Allowing the script to access files from the commands folder
bot.commands = new Discord.Collection();

const commandFiles = fs.readdirSync('./commands/').filter(file => file.endsWith('.js'));
for(const file of commandFiles){
   const command = require(`./commands/${file}`);
   bot.commands.set(command.name, command);
}



/// Message Handler
    bot.on('message', async (message) => {
        const prefix = guildCommandPrefixes.get(message.guild.id);
        console.log('Caught message');
        if(!message.content.startsWith(prefix) || message.author.bot) return;
        const args = message.content.slice(prefix.length).split(/ +/);
        const command = args.shift().toLowerCase();

   /// Basic ping pong test command
    if(command === 'help'){
        bot.commands.get('help').execute(message);
    }
    /// Basic ping pong test command
    else if(command === 'ping'){
        bot.commands.get('ping').execute(message);
    }
    /// Command to change the server's prefix
    else if(command === 'changeprefix'){
        bot.commands.get('changeprefix').execute(message, connection, prefix, guildCommandPrefixes);
    }   
    /// Arguments test
    else if (command === 'argsinfo'){
        bot.commands.get('argsinfo').execute(message, command, args)
    }
    /// Message command list
    else if (command === 'autoungate'){
        bot.commands.get('autoungate').execute(message, args, Discord);
    }});

Code used to change the prefix

module.exports= {
    name: 'changeprefix',
    description: "This will change the prefix in the database for the set guild id",
    execute: async (message, connection, prefix, guildCommandPrefixes) =>{
        setTimeout(() => {message.delete();}, 3000);
        if (message.content.toLowerCase().startsWith(prefix + 'changeprefix')){
            if (message.member.id === message.guild.ownerID) {
                var guild = message.guild
                paidRole = await connection.query(`SELECT paidRole FROM Servers Where '${guild}' === serverId`);
                const [cmdName, newPrefix ] = message.content.split(" ");
                if (paidRole === '1'){
                if (newPrefix) {
                    try {
                        await connection.query(
                        `UPDATE ServerConfig SET cmdPrefix = '${newPrefix}' WHERE serverId= '${message.guild.id}'`
                    );
                    guildCommandPrefixes.set(message.guild.id, newPrefix);
                    message.channel.send(`Updated guild prefix to ${newPrefix}`).then(sentMessage => {sentMessage.delete({ timeout: 3000}); });
                }catch(err) {
                    console.log(err);
                    message.channel.send(`Failed to update guild prefix to ${newPrefix}`).then(sentMessage => {sentMessage.delete({ timeout: 3000}); });
                }}
                else {
                    message.channel.send('You need to input a prefix to change to!').then(sentMessage => {sentMessage.delete({ timeout: 3000}); });
                 }}
                else {
                    message.channel.send('You need to purchase the premium version for prefix customization.').then(sentMessage => {sentMessage.delete({ timeout: 3000}); });
                }}
                else {
                    message.channel.send('You do not have permissions to do this command!').then(sentMessage => {sentMessage.delete({ timeout: 3000}); });
            }
        }
}}

Answer №1

In order to ensure flexibility, I made adjustments to my paidRole variable within my database to allow for a null value.

During the creation of a guild, a brief moment of marking the guild as null occurs to facilitate its database entry. I utilized the UPDATE function to assign either 1 or 0 to the role based on their Discord role.

Utilizing the UPDATE function triggers a bot "refresh" that automatically applies certain changes, avoiding the need for a potential restart that could lead to issues.

Below is the code implementation I utilized:

/// Database entry for newly invited guilds
bot.on('guildCreate', async (guild) => {
    // Retrieving the guild where the user must have the role
    let myGuild = await bot.guilds.fetch(process.env.BOT_GUILD);

    try {
        /// Inserting serverid and serverownerid into servers table
    await connection.query(
        `INSERT INTO Servers (serverId, serverOwnerId, paidRole) VALUES ('${guild.id}', '${guild.ownerID}', NULL)`
        );
        /// Inserting server id into serverconfig table
    await connection.query(
        `INSERT INTO ServerConfig (serverId) VALUES ('${guild.id}')`
        );
    }catch(err){
        console.log(err);

    // Locating the default channel
    let defaultChannel = "";
    guild.channels.cache.forEach((channel) => {
      if(channel.type == "text" && defaultChannel == "") {
        if(channel.permissionsFor(guild.me).has("SEND_MESSAGES")) {
          defaultChannel = channel;
          console.log(defaultChannel);
        }
      }
    });

    // Retrieving the guild owner's member object
    try{
        let guildOwner = await myGuild.members.fetch(guild.ownerID);

        if (!guildOwner)
        return console.log(`Oops, ${guild.owner} is not a member of your server.`);
    }catch(error) {
        return console.log(`Oops, ${guild.owner} is not a member of your server.`),
        defaultChannel.send('Please kick the bot, have the guild owner join this discord https://discord.gg/tDTjBAaCAn, Then you can reinvite the bot and you will be properly added to the database and can use the bot! dont forget to check out the premium features while your there if you decide you want more features from Gate Bot!');
    }
    // Checking for the required role 
    let guildOwner = await myGuild.members.fetch(guild.ownerID);
    let ownerHasPaidRole = guildOwner.roles.cache.has(process.env.PAID_ROLE);

    if (ownerHasPaidRole){
      console.log(`Woohoo, ${guildOwner} has the required role`);
      await connection.query(
          `UPDATE Servers SET paidRole = '1' WHERE serverId = ${guild.id}`
      );
    }
    else {
        await connection.query(
           `UPDATE Servers SET paidRole = '0' WHERE serverId = ${guild.id}`
        );
    }
    }});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Issue with this.setState() not updating value despite not being related to asynchronous updates

Just a quick note, this specific question does not involve any asynchronous update problem (at least, as far as I can tell). I currently have a class component with the following code snippet (simplified for clarity on the main issue): constructor(props ...

Unveiling the Magic: Displaying Quill's raw HTML in Vue.js

Within my Vue.js app, I am utilizing the Quill editor to generate raw HTML content that is saved directly to the database without any cleaning. When fetching this content from the backend, the text and styling are displayed correctly (colors, bolding, etc. ...

Javascript function fails to trigger when clicked

<body ng-app="starter"> <ion-pane> <ion-header-bar class="bar-dark"> <h1 class="title">AppifyLife</h1> </ion-header-bar> <ion-content> <center><div class="card" id="life"><h3>20< ...

Learn the proper way to write onClick in tsx with Vue 2.7.13

current version of vue is 2.7.13 Although it supports jsx, I encounter a type error when using onClick event handling. The type '(event: MouseEvent) => Promise<void>' cannot be assigned to type 'MouseEvent' Is there a correct ...

Incorporating a dropdown menu into an HTML table through jQuery proves to be a

I loaded my tabular data from the server using ajax with json. I aimed to generate HTML table rows dynamically using jQuery, with each row containing elements like input type='text' and select dropdowns. While I could create textboxes in columns ...

Assistance needed for jQuery functions running too early

Within my click function, I am setting certain flags and then calling two functions. However, I want these two functions to execute sequentially in order after the flags have been set. jQuery("#element").click(function(e){ var op = jQuery("#box" ...

What is the best way to input an HTML element into AngularJS code?

I am looking to integrate the html element into my angularjs code. Within my HTML, I have elements such as data-form-selector='#linechart_general_form' and data-url="{% url 'horizon:admin:metering:samples'%}" that I need to access withi ...

Issue with verifying file existence utilizing $.ajax()

I'm currently facing a challenge checking for the existence of a file using $.ajax(). I am cycling through a JSON file with $.each and trying to determine if a specific staff member has an image. If not, I want to default to using the no_photo.jpg ima ...

Checking email existence through remote jQuery validation

Utilizing the jQuery validator plugin, I am implementing an ajax function with a remote method to validate whether an email already exists in my database. However, I am encountering an error when making the ajax call within my validation function. "email ...

Is there a way to verify that a form field has been completed?

Currently, I am grappling with a method to clear a field if a specific field is filled in and vice versa. This form identifies urgent care locations based on the information provided by users. The required entries include the name of the urgent care facil ...

HTML Tutorial: A Beginner's Guide to Invoking REST API

Hi there! I'm new to APIs and struggling to grasp the concept. The tutorials online seem more complex than necessary. Here's what I need help with: I want to create a basic webpage that allows me to search for information using the Pokemon API a ...

Attempting to highlight a specific list item by using the CSS current class to emphasize its active state

I've been experimenting with different solutions I found in previous questions, but unfortunately, none of them have worked for me. I suspect the issue lies in the fact that the element is deeply nested within CSS classes, and my lack of experience is ...

What steps should I take to convert this Mongo schema into a MySQL schema?

Is there a way to convert this MongoDB schema into MySQL format? var userSchema = mongoose.Schema({ socketid: String, username: { type: String, unique: true }, room: String }); ...

Obtain the HTTP response status code within a middleware function

I am currently developing an application where I want to create a custom logging system for every request made. For each request, I want to log the timestamp, method, route, and the response code sent to the client. Here is the code I have at the moment: ...

Displaying an array of JSON objects in ReactJS by parsing them

Recently, I've encountered an odd issue with my React App. I am attempting to parse a JSON object that includes arrays of data. The structure of the data looks something like this: {"Place":"San Francisco","Country":"USA", "Author":{"Name":"xyz", "Ti ...

Load styles in Nuxt asynchronously to improve performance

Is there a way to load styles asynchronously on the website or insert them in the footer? I am currently using Nuxt version 2.0.0 Here's what I have tried so far: Adding a plugin in webpack called async-stylesheet-webpack-plugin. However, this res ...

Region Covered by Mouse Over Does Not Extend Across Whole Div

On my website, there is an arrow located on the middle right side that, when hovered over with the mouse, reveals a sidebar. Clicking on each icon in the sidebar further extends it to reveal more content. However, the issue I am facing is that the sidebar ...

What steps can be taken to avoid special characters in ion-input fields?

When inputting special characters into the field used for storing the alphanumeric serial number, they are accepted. I need to prevent special characters from being entered in the input field. <ion-input [(ngModel)]="serial_number" (ngModelCha ...

Is it possible to utilize X-Y coordinates as repositories for values beyond just X-Y coordinates themselves?

I am in the process of creating a tile-based grid and I need to expand the X-Y coordinates to include additional values for determining characteristics of each tile, such as resources (for example, food, water, stone, lumber) within a game context. Conside ...

Keep deciphering in a loop until the URI string matches

I have a task to decode a string URI until there are no more changes. The string URI I am working with typically has around 53,000 characters, so the comparison needs to be fast. For demonstration purposes, I have used a shortened version of the string. B ...