feat: allow channels from uncached guilds to be returned from fetch (#6034)

Co-authored-by: Antonio Román <kyradiscord@gmail.com>
This commit is contained in:
ckohen
2021-07-06 05:04:26 -07:00
committed by GitHub
parent 2e078e4488
commit 755c180659
9 changed files with 79 additions and 34 deletions

View File

@@ -19,7 +19,7 @@ class ChannelManager extends CachedManager {
* @name ChannelManager#cache
*/
add(data, guild, cache = true) {
add(data, guild, cache = true, allowUnknownGuild = false) {
const existing = this.cache.get(data.id);
if (existing) {
if (cache) existing._patch(data);
@@ -30,14 +30,14 @@ class ChannelManager extends CachedManager {
return existing;
}
const channel = Channel.create(this.client, data, guild);
const channel = Channel.create(this.client, data, guild, allowUnknownGuild);
if (!channel) {
this.client.emit(Events.DEBUG, `Failed to find guild, or unknown type for channel ${data.id} ${data.type}`);
return null;
}
if (cache) this.cache.set(channel.id, channel);
if (cache && !allowUnknownGuild) this.cache.set(channel.id, channel);
return channel;
}
@@ -74,10 +74,17 @@ class ChannelManager extends CachedManager {
* @returns {?Snowflake}
*/
/**
* Options for fetching a channel from discord
* @typedef {BaseFetchOptions} FetchChannelOptions
* @property {boolean} [allowUnknownGuild=false] Allows the channel to be returned even if the guild is not in cache,
* it will not be cached. <warn>Many of the properties and methods on the returned channel will throw errors</warn>
*/
/**
* Obtains a channel from Discord, or the channel cache if it's already available.
* @param {Snowflake} id The channel's id
* @param {BaseFetchOptions} [options] Additional options for this fetch
* @param {FetchChannelOptions} [options] Additional options for this fetch
* @returns {Promise<?Channel>}
* @example
* // Fetch a channel by its id
@@ -85,14 +92,14 @@ class ChannelManager extends CachedManager {
* .then(channel => console.log(channel.name))
* .catch(console.error);
*/
async fetch(id, { cache = true, force = false } = {}) {
async fetch(id, { allowUnknownGuild = false, cache = true, force = false } = {}) {
if (!force) {
const existing = this.cache.get(id);
if (existing && !existing.partial) return existing;
}
const data = await this.client.api.channels(id).get();
return this.add(data, null, cache);
return this.add(data, null, cache, allowUnknownGuild);
}
}

View File

@@ -1,6 +1,7 @@
'use strict';
const CachedManager = require('./CachedManager');
const { Error } = require('../errors');
const GuildChannel = require('../structures/GuildChannel');
const PermissionOverwrites = require('../structures/PermissionOverwrites');
const ThreadChannel = require('../structures/ThreadChannel');
@@ -164,11 +165,17 @@ class GuildChannelManager extends CachedManager {
if (existing) return existing;
}
// We cannot fetch a single guild channel, as of this commit's date, Discord API throws with 404
if (id) {
const data = await this.client.api.channels(id).get();
// Since this is the guild manager, throw if on a different guild
if (this.guild.id !== data.guild_id) throw new Error('GUILD_CHANNEL_UNOWNED');
return this.client.channels.add(data, this.guild, cache);
}
const data = await this.client.api.guilds(this.guild.id).channels.get();
const channels = new Collection();
for (const channel of data) channels.set(channel.id, this.client.channels.add(channel, this.guild, cache));
return id ? channels.get(id) ?? null : channels;
return channels;
}
}