I wrote a Discord.js bot in NodeJS that uses discord-hybrid-sharding to spawn my bot.js
.
In the bot.js
code below, you can see that I have an initial status of "Starting..." and then in ClientReady
I set the actual status.
However, seemingly at random, my bot just goes back to the initial "Starting..." status. It operates completely normally though. I assumed it could be that a shard died or something, but why would that kill my interval? The check I tried to do in the Interval sadly doesn't work.
When I restart my pm2 process for the bot, the status gets correctly set for a while again, but then randomly goes back to "Starting...".
Sharding Manager (app.js
) that starts bot.js
:
import { ClusterManager } from "discord-hybrid-sharding";
import { config } from "../config/config.js";
const manager = new ClusterManager("./src/bot.js", {
totalShards: "auto",
shardsPerClusters: 2,
token: config.discord.bot_token,
});
manager.on("clusterCreate", shard => console.log(`Launched shard ${shard.id}`));
manager.spawn({ timeout: -1 });
bot.js
that sets the status:
import { ClusterClient, getInfo } from "discord-hybrid-sharding";
import DiscordClient from "discord.js";
const client = new DiscordClient({
presence: {
status: "dnd",
activities: [{ name: "Starting...", type: ActivityType.Playing }],
},
shards: getInfo().SHARD_LIST,
shardCount: getInfo().TOTAL_SHARDS,
});
client.cluster = new ClusterClient(client);
client.on(Events.ClientReady, async() => {
const guildCount = await client.guilds.fetch().then(guilds => guilds.size);
client.user?.setActivity({ name: `Counting on ${guildCount} servers!`, type: ActivityType.Playing });
let lastGuildCount = guildCount;
setInterval(async() => {
const newGuildCount = await client.guilds.fetch().then(guilds => guilds.size);
const statusHasReset = client.user?.presence.activities[0].name === "Starting...";
if (newGuildCount !== lastGuildCount || statusHasReset){
lastGuildCount = newGuildCount;
client.user?.setActivity({ name: `Counting on ${newGuildCount} servers!`, type: ActivityType.Playing });
}
}, 45 * 60 * 1000);
client.user?.setStatus("online");
});
(unrelated parts of the code have been omitted. Full code, if required, is at https://github.com/NullDev/Arithmetica-Bot)
Why is this happening and how can I fix it?
Someone on the Discord.js Discord helped me:
Moving my setInterval
logic to the shardReady
event did the trick.
This event is called once the bot starts, and also every time a shard restarts.
Unlike ClientReady
which is only called a single time on bot start.
const setStatus = async function(client, count){
client.user?.setActivity({ name: `Counting on ${count} servers!`, type: ActivityType.Playing });
client.user?.setStatus("online");
};
client.on(Events.ClientReady, async() => {
const guildCount = await client.guilds.fetch().then(guilds => guilds.size);
await setStatus(client, guildCount);
});
client.on(Events.ShardReady, async shard => {
const guildCount = await client.guilds.fetch().then(guilds => guilds.size);
await setStatus(client, guildCount);
let lastGuildCount = guildCount;
setInterval(async() => {
const newGuildCount = await client.guilds.fetch().then(guilds => guilds.size);
if (newGuildCount !== lastGuildCount){
lastGuildCount = newGuildCount;
await setStatus(client, newGuildCount);
Log.info("Guild count changed to " + newGuildCount + ". Updated activity.");
}
}, 10 * 60 * 1000);
});