My bot doesn't get the full list of channels on a server

Hi there! I'm working on a bot that posts messages in a channel and I've just noticed that this functionality no longer works. I did some digging and it seems that not all channels are listed when using client.channels.cache. I checked all permissions, and viewed the server by using the bot's role and everything looks fine, my bot is supposed to see the relevant channels, but when I do this:
const channel = client.channels.cache.get(myChannelId);
const channel = client.channels.cache.get(myChannelId);
only a subset of all visible channels is returned. I double checked and the channel id I'm using (myChannelId) is good, but it is not in the list. Am I supposed to invalidate the cache somehow? What am I missing?
16 Replies
d.js toolkit
d.js toolkit8mo ago
- What's your exact discord.js npm list discord.js and node node -v version? - Not a discord.js issue? Check out #other-js-ts. - Consider reading #how-to-get-help to improve your question! - Explain what exactly your issue is. - Post the full error stack trace, not just the top part! - Show your code! - Issue solved? Press the button!
chewie
chewie8mo ago
As long as you have the Guilds intent and you didn't fuck around with a custom channel cache, all normal channels should be cached
addamsson
addamssonOP8mo ago
someone suggested a while ago that I shouldn't do anything so I didn't ... but now I tried this
await client.channels.fetch(providerId, {
cache: true,
});
await client.channels.fetch(providerId, {
cache: true,
});
and the channel suddenly appeared what am I doing wrong? or when am I supposed to fetch stuff? this is how I initialize my client
client = new Client({ intents: [GatewayIntentBits.Guilds] });
await client.login(process.env.DISCORD_BOT_TOKEN);
client = new Client({ intents: [GatewayIntentBits.Guilds] });
await client.login(process.env.DISCORD_BOT_TOKEN);
I don't have any custom caches this worked a few weeks ago and I didn't change the code and it suddenly stopped working, but if I do the fetch before touching the cache it works again
chewie
chewie8mo ago
what type of channel is it
addamsson
addamssonOP8mo ago
Channel is: <ref *2> TextChannel {
type: 0,
guild: <ref *1> Guild {
id: '1141819348672073848',
name: 'Async Assistant Demo',
icon: 'b83d242243fc07b4fcfd3f117e3c751c',
features: [],
commands: GuildApplicationCommandManager {
permissions: [ApplicationCommandPermissionsManager],
guild: [Circular *1]
},
members: GuildMemberManager { guild: [Circular *1] },
channels: GuildChannelManager { guild: [Circular *1] },
bans: GuildBanManager { guild: [Circular *1] },
roles: RoleManager { guild: [Circular *1] },
presences: PresenceManager {},
voiceStates: VoiceStateManager { guild: [Circular *1] },
stageInstances: StageInstanceManager { guild: [Circular *1] },
invites: GuildInviteManager { guild: [Circular *1] },
scheduledEvents: GuildScheduledEventManager { guild: [Circular *1] },
autoModerationRules: AutoModerationRuleManager { guild: [Circular *1] },
available: true,
shardId: 0,
splash: null,
banner: null,
description: null,
verificationLevel: 0,
vanityURLCode: null,
nsfwLevel: 0,
premiumSubscriptionCount: 0,
discoverySplash: null,
memberCount: 6,
large: false,
premiumProgressBarEnabled: false,
applicationId: null,
afkTimeout: 300,
afkChannelId: null,
systemChannelId: '1141819350538522706',
premiumTier: 0,
widgetEnabled: null,
widgetChannelId: null,
explicitContentFilter: 0,
mfaLevel: 0,
joinedTimestamp: 1693058270061,
defaultMessageNotifications: 0,
systemChannelFlags: SystemChannelFlagsBitField { bitfield: 0 },
maximumMembers: 500000,
maximumPresences: null,
maxVideoChannelUsers: 25,
maxStageVideoChannelUsers: 50,
approximateMemberCount: null,
approximatePresenceCount: null,
vanityURLUses: null,
rulesChannelId: null,
publicUpdatesChannelId: null,
preferredLocale: 'en-US',
safetyAlertsChannelId: null,
ownerId: '501071155889700876',
emojis: GuildEmojiManager { guild: [Circular *1] },
stickers: GuildStickerManager { guild: [Circular *1] }
},
guildId: '1141819348672073848',
permissionOverwrites: PermissionOverwriteManager { channel: [Circular *2] },
messages: GuildMessageManager { channel: [Circular *2] },
threads: GuildTextThreadManager { channel: [Circular *2] },
nsfw: false,
flags: ChannelFlagsBitField { bitfield: 0 },
id: '1159578209726238761',
name: 'integration-test',
rawPosition: 4,
parentId: '1161286366676648007',
topic: "This is where we'll send test messages when the Discord Agent tests are executed. You might see occasional gibberish here.",
lastMessageId: '1237393853280026624',
defaultThreadRateLimitPerUser: null,
rateLimitPerUser: 0
}
Channel is: <ref *2> TextChannel {
type: 0,
guild: <ref *1> Guild {
id: '1141819348672073848',
name: 'Async Assistant Demo',
icon: 'b83d242243fc07b4fcfd3f117e3c751c',
features: [],
commands: GuildApplicationCommandManager {
permissions: [ApplicationCommandPermissionsManager],
guild: [Circular *1]
},
members: GuildMemberManager { guild: [Circular *1] },
channels: GuildChannelManager { guild: [Circular *1] },
bans: GuildBanManager { guild: [Circular *1] },
roles: RoleManager { guild: [Circular *1] },
presences: PresenceManager {},
voiceStates: VoiceStateManager { guild: [Circular *1] },
stageInstances: StageInstanceManager { guild: [Circular *1] },
invites: GuildInviteManager { guild: [Circular *1] },
scheduledEvents: GuildScheduledEventManager { guild: [Circular *1] },
autoModerationRules: AutoModerationRuleManager { guild: [Circular *1] },
available: true,
shardId: 0,
splash: null,
banner: null,
description: null,
verificationLevel: 0,
vanityURLCode: null,
nsfwLevel: 0,
premiumSubscriptionCount: 0,
discoverySplash: null,
memberCount: 6,
large: false,
premiumProgressBarEnabled: false,
applicationId: null,
afkTimeout: 300,
afkChannelId: null,
systemChannelId: '1141819350538522706',
premiumTier: 0,
widgetEnabled: null,
widgetChannelId: null,
explicitContentFilter: 0,
mfaLevel: 0,
joinedTimestamp: 1693058270061,
defaultMessageNotifications: 0,
systemChannelFlags: SystemChannelFlagsBitField { bitfield: 0 },
maximumMembers: 500000,
maximumPresences: null,
maxVideoChannelUsers: 25,
maxStageVideoChannelUsers: 50,
approximateMemberCount: null,
approximatePresenceCount: null,
vanityURLUses: null,
rulesChannelId: null,
publicUpdatesChannelId: null,
preferredLocale: 'en-US',
safetyAlertsChannelId: null,
ownerId: '501071155889700876',
emojis: GuildEmojiManager { guild: [Circular *1] },
stickers: GuildStickerManager { guild: [Circular *1] }
},
guildId: '1141819348672073848',
permissionOverwrites: PermissionOverwriteManager { channel: [Circular *2] },
messages: GuildMessageManager { channel: [Circular *2] },
threads: GuildTextThreadManager { channel: [Circular *2] },
nsfw: false,
flags: ChannelFlagsBitField { bitfield: 0 },
id: '1159578209726238761',
name: 'integration-test',
rawPosition: 4,
parentId: '1161286366676648007',
topic: "This is where we'll send test messages when the Discord Agent tests are executed. You might see occasional gibberish here.",
lastMessageId: '1237393853280026624',
defaultThreadRateLimitPerUser: null,
rateLimitPerUser: 0
}
regular text channel
chewie
chewie8mo ago
can you log guild.channels.cache.map(c => c.name + ' - ' + c.id) for me and show the output? Before fetching anything, preferrably in the ready event
addamsson
addamssonOP8mo ago
sure
[
'Text Channels - 1141819350538522704',
'general - 1141819350538522706',
'General - 1141819350538522707',
'daily-sync - 1151433325630717952',
'nova - 1151433342365990913',
'starburst - 1151433357675216946',
'integration-test - 1159578209726238761',
'testing - 1161286366676648007',
'hexworks - 1174813748653998173',
'memes - 1174813774880980992',
'schemes - 1174813792547377152',
'prod_demo - 1196755952741908520',
'dev - 1214616732681900053',
'staging_demo - 1220161494600388678'
]
[
'Text Channels - 1141819350538522704',
'general - 1141819350538522706',
'General - 1141819350538522707',
'daily-sync - 1151433325630717952',
'nova - 1151433342365990913',
'starburst - 1151433357675216946',
'integration-test - 1159578209726238761',
'testing - 1161286366676648007',
'hexworks - 1174813748653998173',
'memes - 1174813774880980992',
'schemes - 1174813792547377152',
'prod_demo - 1196755952741908520',
'dev - 1214616732681900053',
'staging_demo - 1220161494600388678'
]
integration-test is the one we're looking for hm this is in a test, so i have no client ready this is what I have in my test
beforeEach(async () => {
client = new Client({ intents: [GatewayIntentBits.Guilds] });
await client.login(process.env.DISCORD_BOT_TOKEN);
target = DiscordAgent(client);
});
beforeEach(async () => {
client = new Client({ intents: [GatewayIntentBits.Guilds] });
await client.login(process.env.DISCORD_BOT_TOKEN);
target = DiscordAgent(client);
});
so await-ing client.login doesn't await the ready event?
chewie
chewie8mo ago
the ready event is emitted after the client received all guilds, not after the method login completes
addamsson
addamssonOP8mo ago
can i await client ready (without the callback)? as this is not compatible with how tests work i mean after beforeEach returns the client should be ready so preferably tehre should be something like client.awaitReady() or something similar
beforeEach(async () => {
client = new Client({ intents: [GatewayIntentBits.Guilds] });
await client.login(process.env.DISCORD_BOT_TOKEN);
await new Promise((resolve) => {
client.once(Events.ClientReady, () => {
resolve(undefined);
});
});
target = DiscordAgent(client);
});
beforeEach(async () => {
client = new Client({ intents: [GatewayIntentBits.Guilds] });
await client.login(process.env.DISCORD_BOT_TOKEN);
await new Promise((resolve) => {
client.once(Events.ClientReady, () => {
resolve(undefined);
});
});
target = DiscordAgent(client);
});
?
d.js docs
d.js docs8mo ago
:node: nodeEventTarget.once(type, listener) Node.js-specific extension to the EventTarget class that adds a once listener for the given event type. This is equivalent to calling on with the once option set to true.
addamsson
addamssonOP8mo ago
😅 huh where do I import this from? oh got it
await once(client, Events.ClientReady);
await once(client, Events.ClientReady);
let's see I didn't try that so far an abstraction that I use to hide the actual implementation I have SlackAgent, TestAgent and so on I .skip these tests by default I only use it when I need to check the actual result in the channel all the utility functions are tested separately, and the actual discord interaction is not run by default I also have a TestAgent that's effectively a mock for all my agents I added await once(client, Events.ClientReady); and now I dont' need fetch anymore, thanks there is one thing though sending messages is extremely slow i have some logic that chunks up my messages so that I can send embeds without reaching the limit but sometimes sending only a few messages to a channel takes 10+ seconds i realized this when I had a db transaction open accidentally and my code failed because the transaction manager have already closed the transaction by the time discord.js finished what could be the reason for this slowness? rate limiting? to give you some context: this bot sends daily reports to a channel (and also in dms), so a report usually consists of some headers (2-3 embeds), and 5-20 reports (1 embed each) depending on the team size also i think i found the real issue. one of my test users probably closed dms and i get a promise rejection so the rest of the list doesn't get the dms hm what are the rate limits? I'm gonna chunk everything so that I can minimize the amount of messages sent
d.js docs
d.js docs8mo ago
Ratelimits are dynamically assigned by the API based on current load and may change at any point. - The scale from okay to API-spam is sliding and depends heavily on the action you are taking - Rainbow roles, clock and counter channels, and DM'ing advertisements to all members are all examples of things that are not okay
addamsson
addamssonOP8mo ago
how do you test whether the call actually works then?
addamsson
addamssonOP8mo ago
this is all I have though
No description
addamsson
addamssonOP8mo ago
and i only un-skip them when i actually want to see the results i could have put them in a main file or something, but this was more convenient
Want results from more Discord servers?
Add your server