Androz2091 / discord-giveaways

🎉 Complete framework to facilitate the creation of giveaways using discord.js
https://discord-giveaways.js.org
MIT License
339 stars 128 forks source link

🐛 Giveaway Freeze After Restart #210

Closed MaximKing1 closed 3 years ago

MaximKing1 commented 3 years ago

After I restart the bot it will freeze the giveaway I’m using the MongoDB example not QuickMongo I tried to play around with some of the delete after finish options didn’t work either any idea...

MaximKing1 commented 3 years ago

I’m trying to upgrade my NodeJS version aswell to see if this fixes error also the Database is hosted locally on the server using the example exactly, Bot is using the CustomDB + ShardingManager + Custom Embed for the manager.

MaximKing1 commented 3 years ago

Maybe an idea would to be after the ready event it Refresh's all the giveaways in the database or fetches them however you say it haha..

MaximKing1 commented 3 years ago

I’m now on the latest LTS Version of NodeJS but still didn’t work after restart also what’s strange is that I have the manager send a message when they react it says when they reacted to the giveaway after the restart when reacting to it it don’t fire the event like the giveaway don’t exists...

MaximKing1 commented 3 years ago

@Nico105 is there Gunna be a fix for this soon?

Nico105 commented 3 years ago

Could you maybe try debugging the _checkGiveaway function inside the Manager.js file of the package with breakpoints to find out where it stops. If the _checkGiveaway function does not even get called then debug the _init function in the same file.

You read my msg on the other issue right? I would not have asked if I would have been aware of it/knew why it happens. I cannot even start coming up with a fix if I don't even know exactly why it happens. Unfortunately I couldn't reproduce the problem myself and the other 3 guys who have this issue didn't respond back to my debugging request, so someone has to give me a exact cause so I can start thinking about a fix.

MaximKing1 commented 3 years ago

I will try and debug later Im out atm, but like I’m using Docker-Compose and on a Sharding Manager with these options could you try and reproduce with these please?

MaximKing1 commented 3 years ago

const mongoose = require("mongoose");
const discord = require("discord.js");

module.exports = async (client) => {

// Connect to database
const db = mongoose.connection;

// Check the connection
db.on('error', console.error.bind(console, 'Connection error:'));
db.once('open', () => {
    console.log('Connected to MongoDB.');
});

// Create the schema for giveaways
const giveawaySchema = new mongoose.Schema({
    messageID: String,
    channelID: String,
    guildID: String,
    startAt: Number,
    endAt: Number,
    ended: Boolean,
    winnerCount: Number,
    prize: String,
    messages: {
        giveaway: String,
        giveawayEnded: String,
        inviteToParticipate: String,
        timeRemaining: String,
        winMessage: String,
        embedFooter: String,
        noWinner: String,
        winners: String,
        endedAt: String,
        hostedBy: String,
        units: {
            seconds: String,
            minutes: String,
            hours: String,
            days: String,
            pluralS: Boolean,
        },
    },
    hostedBy: String,
    winnerIDs: [],
    reaction: String,
    botsCanWin: Boolean,
    embedColor: String,
    embedColorEnd: String,
    exemptPermissions: [],
    extraData: {}
});

// Create the model
const giveawayModel = mongoose.model('giveaways', giveawaySchema);

      const { GiveawaysManager } = require("discord-giveaways");
      const GiveawayManagerWithOwnDatabase = class extends GiveawaysManager { 
       async refreshStorage() {
        // This should make all shard refreshing their cache with the updated database
        return client.shard.broadcastEval(() => this.giveawaysManager.getAllGiveaways());
}

async getAllGiveaways() {
    return await giveawayModel.find({});
}

// This function is called when a giveaway needs to be saved in the database (when a giveaway is created or when a giveaway is edited).
async saveGiveaway(messageID, giveawayData) {
    await giveawayModel.create(giveawayData);
    return true;
}

// This function is called when a giveaway needs to be edited in the database.
async editGiveaway(messageID, giveawayData) {
    await giveawayModel
        .findOneAndUpdate({ messageID: messageID }, giveawayData)
        .exec();
    return true;
}

// This function is called when a giveaway needs to be deleted from the database.
async deleteGiveaway(messageID) {
    await giveawayModel
        .findOneAndDelete({ messageID: messageID })
        .exec();
    return true;
}
      };

    const manager = new GiveawayManagerWithOwnDatabase(client, {
        storage: false,
        updateCountdownEvery: 15000,
        hasGuildMembersIntent: true,
        endedGiveawaysLifetime: 500000,
        default: {
          botsCanWin: false,
          embedColor: "#002df7",
          embedColorEnd: "#FF0000",
          exemptPermissions: [ 'ADMINISTRATOR' ],
          reaction: '🎉'
    }});

client.giveawaysManager = manager;

manager.on('giveawayEnded', (giveaway, winners) => {
        winners.forEach((member) => {
            const embed = new discord.MessageEmbed().setTitle(`<:pin:785224364785139722> YOU WON`).setDescription(`<a:gif:785224385811185744> Congratulations, ${member.user.username}, You Won: ${giveaway.prize}`).setColor('#3EB489').setFooter("Strider Givaways", "https://striderbot.net/StriderLogo.jpeg");
            member.send(embed);
    }); 
});

manager.on('giveawayRerolled', (giveaway, winners) => {
    winners.forEach((member) => {
        const embed1 = new discord.MessageEmbed().setTitle(`<:pin:785224364785139722> YOU WON`).setDescription(`<a:gif:785224385811185744> Congratulations, ${member.user.username}, You Won: ${giveaway.prize}`).setColor('#3EB489').setFooter("Strider Givaways", "https://striderbot.net/StriderLogo.jpeg");
        member.send(embed1);
    }); 
});

manager.on('giveawayReactionAdded', (giveaway, member, reaction) => {
    const embed2 = new discord.MessageEmbed().setTitle(`ENTRY ACCEPTED <:Giveaway_Approved:800461412739710976>`).setDescription(`Your entry into [this giveaway](${giveaway.messageURL}) has been approved!`).setColor('#3EB489').setFooter("Strider Givaways", "https://striderbot.net/StriderLogo.jpeg");
    member.send(embed2);
});

manager.on('endedGiveawayReactionAdded', (giveaway, member, reaction) => {
    const embed3 = new discord.MessageEmbed().setTitle(`GIVEAWAY ENDED <a:Strider_offline:785224620751978506>`).setDescription(`Your entry to this giveaway has been denied. \n**Reason:** Already Ended`).setColor('#C40234').setFooter("Strider Givaways", "https://striderbot.net/StriderLogo.jpeg");
    member.send(embed3);
    return reaction.users.remove(member.user);
});
}; `
MaximKing1 commented 3 years ago

@Nico105 if the above stuff works tell me and I know it’s a issue my side if not then we know what the issue is...

Nico105 commented 3 years ago

As said other people have the problem too, one even with the most basic configuration and without sharding. And for one guy it worked fine for weeks until it suddenly started. An your config works for me yeah, but that does not say anything.

MaximKing1 commented 3 years ago

Okay I was just trying to tick every box you know if we’re gunna fix this we have to try eveything 👍 sorry I haven’t debugged yet I’ve been spending time with the family I’ll do it tonight nothink like a late code. @Nico105

Nico105 commented 3 years ago

Yeah, np. I won't force or stress you, take your time, this is open source after all :D

MaximKing1 commented 3 years ago

Morning, I will take a look in a minute and debug it

MaximKing1 commented 3 years ago

Yeah same here @TakeFy

MaximKing1 commented 3 years ago

Umm same here, I have done the different steps but nothink is working for me maybe a case of after the restart we need to add something to the ready event to fetch all giveaways etc?

Sent from Mail for Windows 10

From: TakeFy Sent: 07 February 2021 10:23 To: Androz2091/discord-giveaways Cc: Mental; Author Subject: Re: [Androz2091/discord-giveaways] 🐛 Giveaway Freeze After Restart (#210)

So yeah we don't know what is issues i try to clear the db same issue though — You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or unsubscribe.

Nico105 commented 3 years ago

It fetches all giveaways automatically on manager initialization https://github.com/Androz2091/discord-giveaways/blob/df6f48020def85ec675c25a89b5729e4eddf5c36/src/Manager.js#L447

Nico105 commented 3 years ago
const manager = new GiveawayManagerWithOwnDatabase(client, {
    default: {
    }
}, false); // Set auto initalization to false

Bot Ready Event

client.giveawaysManager._init();

Could you maybe try this to see if a delay helps.

Nico105 commented 3 years ago

? You add the false thing and put client.giveawaysManager._init(); into your own ready event (= that is the delay) and then try it on your not-correctly-functioning bot if possible.

MaximKing1 commented 3 years ago

I'm gunna do that now thanks 👍

MaximKing1 commented 3 years ago

@Nico105 umm where are you getting the extra }; from looks like there is too many? Sorry if I'm wrong...

MaximKing1 commented 3 years ago

Oh I see sorry bout that I'm trying it now..

Nico105 commented 3 years ago

@Nico105 umm where are you getting the extra }; from looks like there is too many? Sorry if I'm wrong...

My bad sry

MaximKing1 commented 3 years ago

omg thanks so much your a life savour it's all working fine now maybe need to fix the auto fetch thingy as that worked for me @TakeFy need any help feel free to ask and I'll share mine..

Nico105 commented 3 years ago

maybe need to fix the auto fetch thingy as that worked for me Hdym?

MaximKing1 commented 3 years ago

Well when adding the thingy to the giveaway manager and ready event it worked so maybe you should get people to do that anyway... or make it have a delay or so people can set a delay?

Nico105 commented 3 years ago

After Line 451 in Manager.js console.log(this.client.readyAt) could you maybe add that and remove the delay temporarily? Because if it is null then we know why nothing updates.

MaximKing1 commented 3 years ago

Okay sure thing let me get back onto my pc and do some testing!!

MaximKing1 commented 3 years ago

Do remember when Sharding it takes longer to get ready, wait gives me an idea for a feature. Have a option called isSharded: Boolean, which adds a delay to the startup etc

MaximKing1 commented 3 years ago

Okay I found another strange issue when not restarting I cannot win as I have admins perms but look after I restarted and done the test it made me win? When admins can't in the giveaway manager... image

Nico105 commented 3 years ago

Do remember when Sharding it takes longer to get ready, wait gives me an idea for a feature. Have a option called isSharded: Boolean, which adds a delay to the startup etc

Yeah, but some had the problem and don't shard @TakeFy do you shard?

MaximKing1 commented 3 years ago

Do remember when Sharding it takes longer to get ready, wait gives me an idea for a feature. Have a option called isSharded: Boolean, which adds a delay to the startup etc

Yeah, but some had the problem and don't shard @TakeFy do you shard?

This is very strange aswell maybe if a bot has more guilds etc could be the reason or due to client options. Also @TakeFy what are your Client options please and discord.js version

Nico105 commented 3 years ago

Okay I found another strange issue when not restarting I cannot win as I have admins perms but look after I restarted and done the test it made me win? When admins can't in the giveaway manager... image

Will look into that, I have some reason in mind.

MaximKing1 commented 3 years ago

Okay I found another strange issue when not restarting I cannot win as I have admins perms but look after I restarted and done the test it made me win? When admins can't in the giveaway manager...

image

Will look into that, I have some reason in mind.

Thanks

Nico105 commented 3 years ago

After Line 451 in Manager.js console.log(this.client.readyAt) could you maybe add that and remove the delay temporarily? Because if it is false then we know why nothing updates.

And also check rawGiveaways.length

MaximKing1 commented 3 years ago

Give me a second and I'll do thoses both also what is your theory why after restarted the except perms don't work?

Nico105 commented 3 years ago

I checked and it wasn't exactly what I though but that doesn't matter. It's because of mongoose, in the schema we said exemptPermissions: [] which means that if exemptPermissions of the giveaway obejct has no value then per default it will save exemptPermissions as an empty array in the DB. Note: defaults can be changed And so after a restart the manager will pull the data from the DB.

get exemptPermissions() {
    return this.options.exemptPermissions || this.manager.options.default.exemptPermissions;
}

But because this.options.exemptPermissions is a empty array, because of mongoose schema config, || will accept [] as valid and returns it instead of this.manager.options.default.exemptPermissions // ADMINISTRATOR.

211 has the fix included (coincidence 😆)

And you can do (in mongoose schema config)

exemptPermissions: {
    type: [],
    default: undefined
}

For now to fix it

Nico105 commented 3 years ago

Below Line 451 Manager.js console.log(this.client.readyAt) is it null?

Nico105 commented 3 years ago

That's normal because it's inside of a setInterval

Nico105 commented 3 years ago

But so I guess I can only ask you to look into the checkGiveaway function which is above the init function and see if it does not get to the .edit part and if probably yes, then debug to see why.

Nico105 commented 3 years ago

you just put some console.log('test') into it or you use a debugger (vscode has one built in) and breakpoints.

Nico105 commented 3 years ago

then if you use vscode as said you can use the built in debugger and just add breakpoints, google it if you don't know how.

Nico105 commented 3 years ago

giveaway.message.edit(giveaway.messages.giveaway, { embed }); So that console.log was after this? But it did not update the embed?

Nico105 commented 3 years ago

image Or as said you can do this to make the process easier

Nico105 commented 3 years ago

check console.log(this.giveaways.length) at the beggining, if it is not 0, then go through each line and find out where exactly it stops

Nico105 commented 3 years ago

Seems so, some other person also had that but that's weird. pls try console.log(giveaway.channel) and console.log(giveaway.channelID) and if possible then check if the logged channelID is really a existing channelID. If the first one is undefined and the second one is a real ID, then try console.log(await this.client.channels.fetch('TheChannelID'))

Nico105 commented 3 years ago

i made a typo giveaway.channeldID did you copy it? this: giveaway.channelID is without the typo

Nico105 commented 3 years ago

console.log(await this.client.channels.fetch(giveaway.channelID)) does this work after a restart?

Nico105 commented 3 years ago

does "id" have a value before you restart? Should have right? could you try and look into your mysql DB to see if it has a value there after a restart?

Nico105 commented 3 years ago
const manager = new GiveawayManagerWithOwnDatabase(client, {
    default: {
    }
}, false); // Set auto initalization to false

Bot Ready Event

client.giveawaysManager._init();

Could you maybe try this to see if a delay helps.

also i have this config though

doesn't matter

Nico105 commented 3 years ago

console.log(await this.client.channels.fetch(giveaway.channelID)) does this work after a restart?

And as said try this after a restart

Nico105 commented 3 years ago

K then remove that. After line 448 console.log(giveaway.channelID), after a restart, does that work? Because that is raw from the DB