Channel helpers

This commit is contained in:
TriForMine
2021-10-21 22:10:26 +02:00
parent 4a12b7714b
commit 96b5782bad
20 changed files with 183 additions and 204 deletions
+4 -3
View File
@@ -1,8 +1,9 @@
import { cache } from "../../cache.ts"; import {Bot} from "../../bot.ts";
/** Gets an array of all the channels ids that are the children of this category. /** Gets an array of all the channels ids that are the children of this category.
* ⚠️ This does not work for custom cache users! * ⚠️ This does not work for custom cache users!
*/ */
export function categoryChildren(parentChannelId: bigint) { export function categoryChildren(bot: Bot, parentChannelId: bigint) {
return cache.channels.filter((channel) => channel.parentId === parentChannelId); // TODO: Cache Filter ?
return bot.cache.channels.filter((channel) => channel.parentId === parentChannelId);
} }
+8 -11
View File
@@ -1,18 +1,15 @@
import { cacheHandlers } from "../../cache.ts"; import type { Bot } from "../../bot.ts";
import { DiscordChannelTypes } from "../../types/channels/channel_types.ts"; import { DiscordChannelTypes } from "../../types/channels/channel_types.ts";
import type { CreateGuildChannel } from "../../types/guilds/create_guild_channel.ts"; import type { CreateGuildChannel } from "../../types/guilds/create_guild_channel.ts";
import { Errors } from "../../types/discordeno/errors.ts";
import { calculatePermissions } from "../../util/permissions.ts";
import { helpers } from "../mod.ts";
/** Create a copy of a channel */ /** Create a copy of a channel */
export async function cloneChannel(channelId: bigint, reason?: string) { export async function cloneChannel(bot: Bot, channelId: bigint, reason?: string) {
const channelToClone = await cacheHandlers.get("channels", channelId); const channelToClone = await bot.cache.channels.get(channelId);
if (!channelToClone) throw new Error(Errors.CHANNEL_NOT_FOUND); if (!channelToClone) throw new Error(bot.constants.Errors.CHANNEL_NOT_FOUND);
//Check for DM channel //Check for DM channel
if (channelToClone.type === DiscordChannelTypes.DM || channelToClone.type === DiscordChannelTypes.GroupDm) { if (channelToClone.type === DiscordChannelTypes.DM || channelToClone.type === DiscordChannelTypes.GroupDm) {
throw new Error(Errors.CHANNEL_NOT_IN_GUILD); throw new Error(bot.constants.Errors.CHANNEL_NOT_IN_GUILD);
} }
const createChannelOptions: CreateGuildChannel = { const createChannelOptions: CreateGuildChannel = {
@@ -22,11 +19,11 @@ export async function cloneChannel(channelId: bigint, reason?: string) {
permissionOverwrites: channelToClone.permissionOverwrites.map((overwrite) => ({ permissionOverwrites: channelToClone.permissionOverwrites.map((overwrite) => ({
id: overwrite.id.toString(), id: overwrite.id.toString(),
type: overwrite.type, type: overwrite.type,
allow: calculatePermissions(overwrite.allow), allow: bot.utils.calculatePermissions(overwrite.allow),
deny: calculatePermissions(overwrite.deny), deny: bot.utils.calculatePermissions(overwrite.deny),
})), })),
}; };
//Create the channel (also handles permissions) //Create the channel (also handles permissions)
return await helpers.createChannel(channelToClone.guildId!, createChannelOptions, reason); return await bot.helpers.createChannel(bot, channelToClone.guildId!, createChannelOptions, reason);
} }
+21 -18
View File
@@ -1,39 +1,42 @@
import { cacheHandlers } from "../../cache.ts";
import { rest } from "../../rest/rest.ts";
import { structures } from "../../structures/mod.ts";
import type { Channel } from "../../types/channels/channel.ts"; import type { Channel } from "../../types/channels/channel.ts";
import { DiscordChannelTypes } from "../../types/channels/channel_types.ts"; import { DiscordChannelTypes } from "../../types/channels/channel_types.ts";
import type { CreateGuildChannel, DiscordCreateGuildChannel } from "../../types/guilds/create_guild_channel.ts"; import type { CreateGuildChannel, DiscordCreateGuildChannel } from "../../types/guilds/create_guild_channel.ts";
import { endpoints } from "../../util/constants.ts"; import type { Bot } from "../../bot.ts";
import { calculateBits, requireOverwritePermissions } from "../../util/permissions.ts";
import { snakelize } from "../../util/utils.ts";
/** Create a channel in your server. Bot needs MANAGE_CHANNEL permissions in the server. */ /** Create a channel in your server. Bot needs MANAGE_CHANNEL permissions in the server. */
export async function createChannel(guildId: bigint, options?: CreateGuildChannel, reason?: string) { export async function createChannel(bot: Bot, guildId: bigint, options?: CreateGuildChannel, reason?: string) {
if (options?.permissionOverwrites) { if (options?.permissionOverwrites) {
await requireOverwritePermissions(guildId, options.permissionOverwrites); await bot.utils.requireOverwritePermissions(bot, guildId, options.permissionOverwrites);
} }
// BITRATES ARE IN THOUSANDS SO IF USER PROVIDES 32 WE CONVERT TO 32000 // BITRATES ARE IN THOUSANDS SO IF USER PROVIDES 32 WE CONVERT TO 32000
if (options?.bitrate && options.bitrate < 1000) options.bitrate *= 1000; if (options?.bitrate && options.bitrate < 1000) options.bitrate *= 1000;
const result = await rest.runMethod<Channel>( const result = await bot.rest.runMethod<Channel>(
bot.rest,
"post", "post",
endpoints.GUILD_CHANNELS(guildId), bot.constants.endpoints.GUILD_CHANNELS(guildId),
snakelize<DiscordCreateGuildChannel>({ options ? {
...options, name: options.name,
permissionOverwrites: options?.permissionOverwrites?.map((perm) => ({ topic: options.topic,
bitrate: options.bitrate,
userLimit: options.userLimit,
rateLimitPerUser: options.rateLimitPerUser,
position: options.position,
parentId: options.parentId,
nsfw: options.nsfw,
permission_overwrites: options?.permissionOverwrites?.map((perm) => ({
...perm, ...perm,
allow: calculateBits(perm.allow), allow: bot.utils.calculateBits(perm.allow),
deny: calculateBits(perm.deny), deny: bot.utils.calculateBits(perm.deny),
})), })),
type: options?.type || DiscordChannelTypes.GuildText, type: options?.type || DiscordChannelTypes.GuildText,
reason, reason,
}) } : {}
); );
const discordenoChannel = await structures.createDiscordenoChannel(result); const discordenoChannel = bot.transformers.channel(result);
await cacheHandlers.set("channels", discordenoChannel.id, discordenoChannel); await bot.cache.channels.set(discordenoChannel.id, discordenoChannel);
return discordenoChannel; return discordenoChannel;
} }
+14 -19
View File
@@ -1,37 +1,32 @@
import { validateLength } from "../../util/validate_length.ts";
import { Errors } from "../../types/discordeno/errors.ts";
import { rest } from "../../rest/rest.ts";
import { endpoints } from "../../util/constants.ts";
import type { StageInstance } from "../../types/channels/stage_instance.ts"; import type { StageInstance } from "../../types/channels/stage_instance.ts";
import { cacheHandlers } from "../../cache.ts"; import type { Bot } from "../../bot.ts";
import { ChannelTypes } from "../../types/channels/channel_types.ts"; import { ChannelTypes } from "../../types/channels/channel_types.ts";
import { requireBotChannelPermissions } from "../../util/permissions.ts";
import { PrivacyLevel } from "../../types/channels/privacy_level.ts"; import { PrivacyLevel } from "../../types/channels/privacy_level.ts";
import { snakelize } from "../../util/utils.ts";
/** Creates a new Stage instance associated to a Stage channel. Requires the user to be a moderator of the Stage channel. */ /** Creates a new Stage instance associated to a Stage channel. Requires the user to be a moderator of the Stage channel. */
export async function createStageInstance(channelId: bigint, topic: string, privacyLevel?: PrivacyLevel) { export async function createStageInstance(bot: Bot, channelId: bigint, topic: string, privacyLevel?: PrivacyLevel) {
const channel = await cacheHandlers.get("channels", channelId); const channel = await bot.cache.channels.get(channelId);
if (channel) { if (channel) {
if (channel.type !== ChannelTypes.GuildStageVoice) { if (channel.type !== ChannelTypes.GuildStageVoice) {
throw new Error(Errors.CHANNEL_NOT_STAGE_VOICE); throw new Error(bot.constants.Errors.CHANNEL_NOT_STAGE_VOICE);
} }
await requireBotChannelPermissions(channel, ["MANAGE_CHANNELS", "MUTE_MEMBERS", "MOVE_MEMBERS"]); await bot.utils.requireBotChannelPermissions(bot, channel, ["MANAGE_CHANNELS", "MUTE_MEMBERS", "MOVE_MEMBERS"]);
} }
if (!validateLength(topic, { max: 120, min: 1 })) { if (!bot.utils.validateLength(topic, { max: 120, min: 1 })) {
throw new Error(Errors.INVALID_TOPIC_LENGTH); throw new Error(bot.constants.Errors.INVALID_TOPIC_LENGTH);
} }
return await rest.runMethod<StageInstance>( return await bot.rest.runMethod<StageInstance>(
bot.rest,
"post", "post",
endpoints.STAGE_INSTANCES, bot.constants.endpoints.STAGE_INSTANCES,
snakelize({ {
channelId, channel_id: channelId,
topic, topic,
privacyLevel, privacy_level: privacyLevel,
}) }
); );
} }
+7 -11
View File
@@ -1,27 +1,23 @@
import { cacheHandlers } from "../../cache.ts"; import type { Bot } from "../../bot.ts";
import { rest } from "../../rest/rest.ts";
import { Errors } from "../../types/discordeno/errors.ts";
import { endpoints } from "../../util/constants.ts";
import { requireBotGuildPermissions } from "../../util/permissions.ts";
/** Delete a channel in your server. Bot needs MANAGE_CHANNEL permissions in the server. */ /** Delete a channel in your server. Bot needs MANAGE_CHANNEL permissions in the server. */
export async function deleteChannel(channelId: bigint, reason?: string) { export async function deleteChannel(bot: Bot, channelId: bigint, reason?: string) {
const channel = await cacheHandlers.get("channels", channelId); const channel = await cacheHandlers.get("channels", channelId);
if (channel?.guildId) { if (channel?.guildId) {
const guild = await cacheHandlers.get("guilds", channel.guildId); const guild = await cacheHandlers.get("guilds", channel.guildId);
if (!guild) throw new Error(Errors.GUILD_NOT_FOUND); if (!guild) throw new Error(bot.constants.Errors.GUILD_NOT_FOUND);
if (guild.rulesChannelId === channelId) { if (guild.rulesChannelId === channelId) {
throw new Error(Errors.RULES_CHANNEL_CANNOT_BE_DELETED); throw new Error(bot.constants.Errors.RULES_CHANNEL_CANNOT_BE_DELETED);
} }
if (guild.publicUpdatesChannelId === channelId) { if (guild.publicUpdatesChannelId === channelId) {
throw new Error(Errors.UPDATES_CHANNEL_CANNOT_BE_DELETED); throw new Error(bot.constants.Errors.UPDATES_CHANNEL_CANNOT_BE_DELETED);
} }
await requireBotGuildPermissions(guild, ["MANAGE_CHANNELS"]); await bot.utils.requireBotGuildPermissions(bot, guild, ["MANAGE_CHANNELS"]);
} }
return await rest.runMethod<undefined>("delete", endpoints.CHANNEL_BASE(channelId), { reason }); return await bot.rest.runMethod<undefined>(bot.rest, "delete", bot.constants.endpoints.CHANNEL_BASE(channelId), { reason });
} }
@@ -1,14 +1,13 @@
import { rest } from "../../rest/rest.ts"; import type { Bot } from "../../bot.ts";
import { endpoints } from "../../util/constants.ts";
import { requireBotGuildPermissions } from "../../util/permissions.ts";
/** Delete the channel permission overwrites for a user or role in this channel. Requires `MANAGE_ROLES` permission. */ /** Delete the channel permission overwrites for a user or role in this channel. Requires `MANAGE_ROLES` permission. */
export async function deleteChannelOverwrite( export async function deleteChannelOverwrite(
bot: Bot,
guildId: bigint, guildId: bigint,
channelId: bigint, channelId: bigint,
overwriteId: bigint overwriteId: bigint
): Promise<undefined> { ): Promise<undefined> {
await requireBotGuildPermissions(guildId, ["MANAGE_ROLES"]); await bot.utils.requireBotGuildPermissions(bot, guildId, ["MANAGE_ROLES"]);
return await rest.runMethod<undefined>("delete", endpoints.CHANNEL_OVERWRITE(channelId, overwriteId)); return await bot.rest.runMethod<undefined>(bot.rest,"delete", bot.constants.endpoints.CHANNEL_OVERWRITE(channelId, overwriteId));
} }
+6 -10
View File
@@ -1,21 +1,17 @@
import { cacheHandlers } from "../../cache.ts";
import { rest } from "../../rest/rest.ts";
import { ChannelTypes } from "../../types/channels/channel_types.ts"; import { ChannelTypes } from "../../types/channels/channel_types.ts";
import { Errors } from "../../types/discordeno/errors.ts"; import type { Bot } from "../../bot.ts";
import { endpoints } from "../../util/constants.ts";
import { requireBotChannelPermissions } from "../../util/permissions.ts";
/** Deletes the Stage instance. Requires the user to be a moderator of the Stage channel. */ /** Deletes the Stage instance. Requires the user to be a moderator of the Stage channel. */
export async function deleteStageInstance(channelId: bigint) { export async function deleteStageInstance(bot: Bot, channelId: bigint) {
const channel = await cacheHandlers.get("channels", channelId); const channel = await bot.cache.channels.get(channelId);
if (channel) { if (channel) {
if (channel.type !== ChannelTypes.GuildStageVoice) { if (channel.type !== ChannelTypes.GuildStageVoice) {
throw new Error(Errors.CHANNEL_NOT_STAGE_VOICE); throw new Error(bot.constants.Errors.CHANNEL_NOT_STAGE_VOICE);
} }
await requireBotChannelPermissions(channel, ["MUTE_MEMBERS", "MANAGE_CHANNELS", "MOVE_MEMBERS"]); await bot.utils.requireBotChannelPermissions(bot, channel, ["MUTE_MEMBERS", "MANAGE_CHANNELS", "MOVE_MEMBERS"]);
} }
return await rest.runMethod<undefined>("delete", endpoints.STAGE_INSTANCE(channelId)); return await bot.rest.runMethod<undefined>(bot.rest, "delete", bot.constants.endpoints.STAGE_INSTANCE(channelId));
} }
+25 -21
View File
@@ -1,21 +1,16 @@
import { eventHandlers } from "../../bot.ts";
import { cacheHandlers } from "../../cache.ts";
import { rest } from "../../rest/rest.ts";
import type { DiscordenoChannel } from "../../structures/channel.ts"; import type { DiscordenoChannel } from "../../structures/channel.ts";
import { structures } from "../../structures/mod.ts";
import type { Channel } from "../../types/channels/channel.ts"; import type { Channel } from "../../types/channels/channel.ts";
import type { ModifyChannel } from "../../types/channels/modify_channel.ts"; import type { ModifyChannel } from "../../types/channels/modify_channel.ts";
import { endpoints } from "../../util/constants.ts"; import type { Bot } from "../../bot.ts";
import { calculateBits, requireOverwritePermissions } from "../../util/permissions.ts"; import {SnakeCasedPropertiesDeep} from "../../types/util.ts";
import { snakelize } from "../../util/utils.ts";
/** Update a channel's settings. Requires the `MANAGE_CHANNELS` permission for the guild. */ /** Update a channel's settings. Requires the `MANAGE_CHANNELS` permission for the guild. */
export async function editChannel(channelId: bigint, options: ModifyChannel, reason?: string) { export async function editChannel(bot: Bot, channelId: bigint, options: ModifyChannel, reason?: string) {
const channel = await cacheHandlers.get("channels", channelId); const channel = await bot.cache.channels.get(channelId);
if (channel) { if (channel) {
if (options.permissionOverwrites && Array.isArray(options.permissionOverwrites)) { if (options.permissionOverwrites && Array.isArray(options.permissionOverwrites)) {
await requireOverwritePermissions(channel.guildId, options.permissionOverwrites); await bot.utils.requireOverwritePermissions(bot, channel.guildId, options.permissionOverwrites);
} }
} }
@@ -40,16 +35,25 @@ export async function editChannel(channelId: bigint, options: ModifyChannel, rea
request.items.push({ channelId, options, resolve, reject }); request.items.push({ channelId, options, resolve, reject });
if (editChannelProcessing) return; if (editChannelProcessing) return;
editChannelProcessing = true; editChannelProcessing = true;
processEditChannelQueue(); processEditChannelQueue(bot);
}); });
} }
} }
const result = await rest.runMethod<Channel>( const result = await bot.rest.runMethod<SnakeCasedPropertiesDeep<Channel>>(
bot.rest,
"patch", "patch",
endpoints.CHANNEL_BASE(channelId), bot.constants.endpoints.CHANNEL_BASE(channelId),
snakelize({ {
...options, name: options.name,
topic: options.topic,
bitrate: options.bitrate,
userLimit: options.userLimit,
rateLimitPerUser: options.rateLimitPerUser,
position: options.position,
parentId: options.parentId,
nsfw: options.nsfw,
type: options.type,
permissionOverwrites: options.permissionOverwrites permissionOverwrites: options.permissionOverwrites
? options.permissionOverwrites?.map((overwrite) => { ? options.permissionOverwrites?.map((overwrite) => {
return { return {
@@ -60,10 +64,10 @@ export async function editChannel(channelId: bigint, options: ModifyChannel, rea
}) })
: undefined, : undefined,
reason, reason,
}) }
); );
return await structures.createDiscordenoChannel(result); return bot.transformers.channel(result);
} }
interface EditChannelRequest { interface EditChannelRequest {
@@ -82,7 +86,7 @@ interface EditChannelRequest {
const editChannelNameTopicQueue = new Map<bigint, EditChannelRequest>(); const editChannelNameTopicQueue = new Map<bigint, EditChannelRequest>();
let editChannelProcessing = false; let editChannelProcessing = false;
function processEditChannelQueue() { function processEditChannelQueue(bot: Bot) {
if (!editChannelProcessing) return; if (!editChannelProcessing) return;
const now = Date.now(); const now = Date.now();
@@ -99,13 +103,13 @@ function processEditChannelQueue() {
if (!details) return; if (!details) return;
await editChannel(details.channelId, details.options) await bot.helpers.editChannel(bot, details.channelId, details.options)
.then((result) => details.resolve(result)) .then((result) => details.resolve(result))
.catch(details.reject); .catch(details.reject);
const secondDetails = request.items.shift(); const secondDetails = request.items.shift();
if (!secondDetails) return; if (!secondDetails) return;
await editChannel(secondDetails.channelId, secondDetails.options) await bot.helpers.editChannel(bot, secondDetails.channelId, secondDetails.options)
.then((result) => secondDetails.resolve(result)) .then((result) => secondDetails.resolve(result))
.catch(secondDetails.reject); .catch(secondDetails.reject);
return; return;
@@ -114,7 +118,7 @@ function processEditChannelQueue() {
if (editChannelNameTopicQueue.size) { if (editChannelNameTopicQueue.size) {
setTimeout(() => { setTimeout(() => {
eventHandlers.debug?.("loop", `Running setTimeout in EDIT_CHANNEL file.`); eventHandlers.debug?.("loop", `Running setTimeout in EDIT_CHANNEL file.`);
processEditChannelQueue(); processEditChannelQueue(bot);
}, 60000); }, 60000);
} else { } else {
editChannelProcessing = false; editChannelProcessing = false;
@@ -1,20 +1,19 @@
import { rest } from "../../rest/rest.ts";
import type { Overwrite } from "../../types/channels/overwrite.ts"; import type { Overwrite } from "../../types/channels/overwrite.ts";
import { endpoints } from "../../util/constants.ts"; import type { Bot } from "../../bot.ts";
import { calculateBits, requireBotGuildPermissions } from "../../util/permissions.ts";
/** Edit the channel permission overwrites for a user or role in this channel. Requires `MANAGE_ROLES` permission. */ /** Edit the channel permission overwrites for a user or role in this channel. Requires `MANAGE_ROLES` permission. */
export async function editChannelOverwrite( export async function editChannelOverwrite(
bot: Bot,
guildId: bigint, guildId: bigint,
channelId: bigint, channelId: bigint,
overwriteId: bigint, overwriteId: bigint,
options: Omit<Overwrite, "id"> options: Omit<Overwrite, "id">
): Promise<undefined> { ): Promise<undefined> {
await requireBotGuildPermissions(guildId, ["MANAGE_ROLES"]); await bot.utils.requireBotGuildPermissions(bot, guildId, ["MANAGE_ROLES"]);
return await rest.runMethod<undefined>("put", endpoints.CHANNEL_OVERWRITE(channelId, overwriteId), { return await bot.rest.runMethod<undefined>(bot.rest,"put", bot.constants.endpoints.CHANNEL_OVERWRITE(channelId, overwriteId), {
allow: calculateBits(options.allow), allow: bot.utils.calculateBits(options.allow),
deny: calculateBits(options.deny), deny: bot.utils.calculateBits(options.deny),
type: options.type, type: options.type,
}); });
} }
+4 -6
View File
@@ -1,13 +1,11 @@
import { rest } from "../../rest/rest.ts";
import type { FollowedChannel } from "../../types/channels/followed_channel.ts"; import type { FollowedChannel } from "../../types/channels/followed_channel.ts";
import { endpoints } from "../../util/constants.ts"; import type { Bot } from "../../bot.ts";
import { requireBotChannelPermissions } from "../../util/permissions.ts";
/** Follow a News Channel to send messages to a target channel. Requires the `MANAGE_WEBHOOKS` permission in the target channel. Returns the webhook id. */ /** Follow a News Channel to send messages to a target channel. Requires the `MANAGE_WEBHOOKS` permission in the target channel. Returns the webhook id. */
export async function followChannel(sourceChannelId: bigint, targetChannelId: bigint) { export async function followChannel(bot: Bot, sourceChannelId: bigint, targetChannelId: bigint) {
await requireBotChannelPermissions(targetChannelId, ["MANAGE_WEBHOOKS"]); await bot.utils.requireBotChannelPermissions(bot, targetChannelId, ["MANAGE_WEBHOOKS"]);
const data = await rest.runMethod<FollowedChannel>("post", endpoints.CHANNEL_FOLLOW(sourceChannelId), { const data = await bot.rest.runMethod<FollowedChannel>(bot.rest,"post", bot.constants.endpoints.CHANNEL_FOLLOW(sourceChannelId), {
webhook_channel_id: targetChannelId, webhook_channel_id: targetChannelId,
}); });
+9 -11
View File
@@ -1,23 +1,21 @@
import { cacheHandlers } from "../../cache.ts"; import type { Bot } from "../../bot.ts";
import { rest } from "../../rest/rest.ts";
import { structures } from "../../structures/mod.ts";
import type { Channel } from "../../types/channels/channel.ts"; import type { Channel } from "../../types/channels/channel.ts";
import { snowflakeToBigint } from "../../util/bigint.ts";
import { endpoints } from "../../util/constants.ts";
/** Fetches a single channel object from the api. /** Fetches a single channel object from the api.
* *
* ⚠️ **If you need this, you are probably doing something wrong. This is not intended for use. Your channels will be cached in your guild.** * ⚠️ **If you need this, you are probably doing something wrong. This is not intended for use. Your channels will be cached in your guild.**
*/ */
export async function getChannel(channelId: bigint, addToCache = true) { export async function getChannel(bot: Bot, channelId: bigint, addToCache = true) {
const result = await rest.runMethod<Channel>("get", endpoints.CHANNEL_BASE(channelId)); const result = await bot.rest.runMethod<Channel>(bot.rest,"get", bot.constants.endpoints.CHANNEL_BASE(channelId));
const discordenoChannel = await structures.createDiscordenoChannel( const discordenoChannel = bot.transformers.channel(
result, {
result.guildId ? snowflakeToBigint(result.guildId) : undefined channel: result,
guildId: result.guildId ? bot.transformers.snowflake(result.guildId) : undefined
}
); );
if (addToCache) { if (addToCache) {
await cacheHandlers.set("channels", discordenoChannel.id, discordenoChannel); await bot.cache.channels.set(discordenoChannel.id, discordenoChannel);
} }
return discordenoChannel; return discordenoChannel;
+4 -6
View File
@@ -1,14 +1,12 @@
import { rest } from "../../rest/rest.ts";
import type { Webhook } from "../../types/webhooks/webhook.ts"; import type { Webhook } from "../../types/webhooks/webhook.ts";
import { Collection } from "../../util/collection.ts"; import { Collection } from "../../util/collection.ts";
import { endpoints } from "../../util/constants.ts"; import type { Bot } from "../../bot.ts";
import { requireBotChannelPermissions } from "../../util/permissions.ts";
/** Gets the webhooks for this channel. Requires MANAGE_WEBHOOKS */ /** Gets the webhooks for this channel. Requires MANAGE_WEBHOOKS */
export async function getChannelWebhooks(channelId: bigint) { export async function getChannelWebhooks(bot: Bot, channelId: bigint) {
await requireBotChannelPermissions(channelId, ["MANAGE_WEBHOOKS"]); await bot.utils.requireBotChannelPermissions(bot, channelId, ["MANAGE_WEBHOOKS"]);
const result = await rest.runMethod<Webhook[]>("get", endpoints.CHANNEL_WEBHOOKS(channelId)); const result = await bot.rest.runMethod<Webhook[]>(bot.rest,"get", bot.constants.endpoints.CHANNEL_WEBHOOKS(channelId));
return new Collection(result.map((webhook) => [webhook.id, webhook])); return new Collection(result.map((webhook) => [webhook.id, webhook]));
} }
+5 -8
View File
@@ -1,24 +1,21 @@
import { cacheHandlers } from "../../cache.ts";
import { rest } from "../../rest/rest.ts";
import { structures } from "../../structures/mod.ts";
import type { Channel } from "../../types/channels/channel.ts"; import type { Channel } from "../../types/channels/channel.ts";
import { Collection } from "../../util/collection.ts"; import { Collection } from "../../util/collection.ts";
import { endpoints } from "../../util/constants.ts"; import type { Bot } from "../../bot.ts";
/** Returns a list of guild channel objects. /** Returns a list of guild channel objects.
* *
* ⚠️ **If you need this, you are probably doing something wrong. This is not intended for use. Your channels will be cached in your guild.** * ⚠️ **If you need this, you are probably doing something wrong. This is not intended for use. Your channels will be cached in your guild.**
*/ */
export async function getChannels(guildId: bigint, addToCache = true) { export async function getChannels(bot: Bot, guildId: bigint, addToCache = true) {
const result = await rest.runMethod<Channel[]>("get", endpoints.GUILD_CHANNELS(guildId)); const result = await bot.rest.runMethod<Channel[]>(bot.rest,"get", bot.constants.endpoints.GUILD_CHANNELS(guildId));
return new Collection( return new Collection(
( (
await Promise.all( await Promise.all(
result.map(async (res) => { result.map(async (res) => {
const discordenoChannel = await structures.createDiscordenoChannel(res, guildId); const discordenoChannel = await bot.transformers.channel({channel: res, guildId});
if (addToCache) { if (addToCache) {
await cacheHandlers.set("channels", discordenoChannel.id, discordenoChannel); await bot.cache.channels.set(discordenoChannel.id, discordenoChannel);
} }
return discordenoChannel; return discordenoChannel;
+4 -6
View File
@@ -1,11 +1,9 @@
import { rest } from "../../rest/rest.ts";
import { structures } from "../../structures/mod.ts";
import type { Message } from "../../types/messages/message.ts"; import type { Message } from "../../types/messages/message.ts";
import { endpoints } from "../../util/constants.ts"; import type { Bot } from "../../bot.ts";
/** Get pinned messages in this channel. */ /** Get pinned messages in this channel. */
export async function getPins(channelId: bigint) { export async function getPins(bot: Bot, channelId: bigint) {
const result = await rest.runMethod<Message[]>("get", endpoints.CHANNEL_PINS(channelId)); const result = await bot.rest.runMethod<Message[]>(bot.rest,"get", bot.constants.endpoints.CHANNEL_PINS(channelId));
return Promise.all(result.map((res) => structures.createDiscordenoMessage(res))); return result.map(bot.transformers.message);
} }
+6 -9
View File
@@ -1,19 +1,16 @@
import { cacheHandlers } from "../../cache.ts"; import type { ChannelTypes } from "../../types/channels/channel_types.ts";
import { rest } from "../../rest/rest.ts";
import { ChannelTypes } from "../../types/channels/channel_types.ts";
import type { StageInstance } from "../../types/channels/stage_instance.ts"; import type { StageInstance } from "../../types/channels/stage_instance.ts";
import { Errors } from "../../types/discordeno/errors.ts"; import type { Bot } from "../../bot.ts";
import { endpoints } from "../../util/constants.ts";
/** Gets the stage instance associated with the Stage channel, if it exists. */ /** Gets the stage instance associated with the Stage channel, if it exists. */
export async function getStageInstance(channelId: bigint) { export async function getStageInstance(bot: Bot, channelId: bigint) {
const channel = await cacheHandlers.get("channels", channelId); const channel = await bot.cache.channels.get(channelId);
if (channel) { if (channel) {
if (channel.type !== ChannelTypes.GuildStageVoice) { if (channel.type !== ChannelTypes.GuildStageVoice) {
throw new Error(Errors.CHANNEL_NOT_STAGE_VOICE); throw new Error(bot.constants.Errors.CHANNEL_NOT_STAGE_VOICE);
} }
} }
return await rest.runMethod<StageInstance>("get", endpoints.STAGE_INSTANCE(channelId)); return await bot.rest.runMethod<StageInstance>(bot.rest,"get", bot.constants.endpoints.STAGE_INSTANCE(channelId));
} }
+4 -4
View File
@@ -1,11 +1,11 @@
import { cacheHandlers } from "../../cache.ts"; import type { Bot } from "../../bot.ts";
/** Checks whether a channel is synchronized with its parent/category channel or not. */ /** Checks whether a channel is synchronized with its parent/category channel or not. */
export async function isChannelSynced(channelId: bigint) { export async function isChannelSynced(bot: Bot, channelId: bigint) {
const channel = await cacheHandlers.get("channels", channelId); const channel = await bot.cache.channels.get(channelId);
if (!channel?.parentId) return false; if (!channel?.parentId) return false;
const parentChannel = await cacheHandlers.get("channels", channel.parentId); const parentChannel = await bot.cache.channels.get(channel.parentId);
if (!parentChannel) return false; if (!parentChannel) return false;
return channel.permissionOverwrites?.every((overwrite) => { return channel.permissionOverwrites?.every((overwrite) => {
+7 -11
View File
@@ -1,17 +1,13 @@
import { cacheHandlers } from "../../cache.ts";
import { rest } from "../../rest/rest.ts";
import { DiscordChannelTypes } from "../../types/channels/channel_types.ts"; import { DiscordChannelTypes } from "../../types/channels/channel_types.ts";
import { Errors } from "../../types/discordeno/errors.ts"; import type { Bot } from "../../bot.ts";
import { endpoints } from "../../util/constants.ts";
import { botHasChannelPermissions } from "../../util/permissions.ts";
/** /**
* Trigger a typing indicator for the specified channel. Generally bots should **NOT** implement this route. * Trigger a typing indicator for the specified channel. Generally bots should **NOT** implement this route.
* However, if a bot is responding to a command and expects the computation to take a few seconds, * However, if a bot is responding to a command and expects the computation to take a few seconds,
* this endpoint may be called to let the user know that the bot is processing their message. * this endpoint may be called to let the user know that the bot is processing their message.
*/ */
export async function startTyping(channelId: bigint) { export async function startTyping(bot: Bot, channelId: bigint) {
const channel = await cacheHandlers.get("channels", channelId); const channel = await bot.cache.channels.get(channelId);
// If the channel is cached, we can do extra checks/safety // If the channel is cached, we can do extra checks/safety
if (channel) { if (channel) {
if ( if (
@@ -24,14 +20,14 @@ export async function startTyping(channelId: bigint) {
DiscordChannelTypes.GuildPublicThread, DiscordChannelTypes.GuildPublicThread,
].includes(channel.type) ].includes(channel.type)
) { ) {
throw new Error(Errors.CHANNEL_NOT_TEXT_BASED); throw new Error(bot.constants.Errors.CHANNEL_NOT_TEXT_BASED);
} }
const hasSendMessagesPerm = await botHasChannelPermissions(channelId, ["SEND_MESSAGES"]); const hasSendMessagesPerm = await bot.utils.botHasChannelPermissions(bots, channelId, ["SEND_MESSAGES"]);
if (!hasSendMessagesPerm) { if (!hasSendMessagesPerm) {
throw new Error(Errors.MISSING_SEND_MESSAGES); throw new Error(bot.constants.Errors.MISSING_SEND_MESSAGES);
} }
} }
return await rest.runMethod<undefined>("post", endpoints.CHANNEL_TYPING(channelId)); return await bot.rest.runMethod<undefined>(bot.rest,"post", bot.constants.endpoints.CHANNEL_TYPING(channelId));
} }
+11 -6
View File
@@ -1,13 +1,18 @@
import { rest } from "../../rest/rest.ts";
import type { ModifyGuildChannelPositions } from "../../types/guilds/modify_guild_channel_position.ts"; import type { ModifyGuildChannelPositions } from "../../types/guilds/modify_guild_channel_position.ts";
import { endpoints } from "../../util/constants.ts"; import type { Bot } from "../../bot.ts";
import { snakelize } from "../../util/utils.ts";
/** Modify the positions of channels on the guild. Requires MANAGE_CHANNELS permisison. */ /** Modify the positions of channels on the guild. Requires MANAGE_CHANNELS permission. */
export async function swapChannels(guildId: bigint, channelPositions: ModifyGuildChannelPositions[]) { export async function swapChannels(bot: Bot, guildId: bigint, channelPositions: ModifyGuildChannelPositions[]) {
if (channelPositions.length < 2) { if (channelPositions.length < 2) {
throw "You must provide at least two channels to be swapped."; throw "You must provide at least two channels to be swapped.";
} }
return await rest.runMethod<undefined>("patch", endpoints.GUILD_CHANNELS(guildId), snakelize(channelPositions)); return await bot.rest.runMethod<undefined>(bot.rest,"patch", bot.constants.endpoints.GUILD_CHANNELS(guildId), channelPositions.map((channelPosition) => {
return {
id: channelPosition.id,
position: channelPosition.position,
lock_positions: channelPosition.lockPositions,
parent_id: channelPosition.parentId
}
}));
} }
+12 -14
View File
@@ -1,37 +1,35 @@
import { rest } from "../../rest/rest.ts";
import { Errors } from "../../types/discordeno/errors.ts";
import type { StageInstance } from "../../types/channels/stage_instance.ts"; import type { StageInstance } from "../../types/channels/stage_instance.ts";
import { endpoints } from "../../util/constants.ts"; import type { Bot } from "../../bot.ts";
import { validateLength } from "../../util/validate_length.ts"; import type { ChannelTypes } from "../../types/channels/channel_types.ts";
import { cacheHandlers } from "../../cache.ts";
import { requireBotChannelPermissions } from "../../util/permissions.ts";
import { ChannelTypes } from "../../types/channels/channel_types.ts";
import { snakelize } from "../../util/utils.ts";
/** Updates fields of an existing Stage instance. Requires the user to be a moderator of the Stage channel. */ /** Updates fields of an existing Stage instance. Requires the user to be a moderator of the Stage channel. */
export async function updateStageInstance( export async function updateStageInstance(
bot: Bot,
channelId: bigint, channelId: bigint,
data: Partial<Pick<StageInstance, "topic" | "privacyLevel">> = {} data: Partial<Pick<StageInstance, "topic" | "privacyLevel">> = {}
) { ) {
const channel = await cacheHandlers.get("channels", channelId); const channel = await bot.cache.channels.get(channelId);
if (channel) { if (channel) {
if (channel.type !== ChannelTypes.GuildStageVoice) { if (channel.type !== ChannelTypes.GuildStageVoice) {
throw new Error(Errors.CHANNEL_NOT_STAGE_VOICE); throw new Error(bot.constants.Errors.CHANNEL_NOT_STAGE_VOICE);
} }
await requireBotChannelPermissions(channel, ["MOVE_MEMBERS", "MUTE_MEMBERS", "MANAGE_CHANNELS"]); await bot.utils.requireBotChannelPermissions(channel, ["MOVE_MEMBERS", "MUTE_MEMBERS", "MANAGE_CHANNELS"]);
} }
if ( if (
data?.topic && data?.topic &&
!validateLength(data.topic, { !bot.utils.validateLength(data.topic, {
min: 1, min: 1,
max: 120, max: 120,
}) })
) { ) {
throw new Error(Errors.INVALID_TOPIC_LENGTH); throw new Error(bot.constants.Errors.INVALID_TOPIC_LENGTH);
} }
return await rest.runMethod<StageInstance>("patch", endpoints.STAGE_INSTANCE(channelId), snakelize(data)); return await bot.rest.runMethod<StageInstance>(bot.rest,"patch", bot.constants.endpoints.STAGE_INSTANCE(channelId), {
topic: data.topic,
privacy_level: data.privacyLevel
});
} }
+11 -7
View File
@@ -1,8 +1,6 @@
import { rest } from "../../rest/rest.ts"; import type { UpdateOthersVoiceState } from "../../types/guilds/update_others_voice_state.ts";
import { UpdateOthersVoiceState } from "../../types/guilds/update_others_voice_state.ts";
import type { UpdateSelfVoiceState } from "../../types/guilds/update_self_voice_state.ts"; import type { UpdateSelfVoiceState } from "../../types/guilds/update_self_voice_state.ts";
import { endpoints } from "../../util/constants.ts"; import type { Bot } from "../../bot.ts";
import { hasOwnProperty, snakelize } from "../../util/utils.ts";
/** /**
* Updates the a user's voice state, defaults to the current user * Updates the a user's voice state, defaults to the current user
@@ -19,9 +17,15 @@ export async function updateBotVoiceState(
guildId: bigint, guildId: bigint,
options: UpdateSelfVoiceState | ({ userId: bigint } & UpdateOthersVoiceState) options: UpdateSelfVoiceState | ({ userId: bigint } & UpdateOthersVoiceState)
) { ) {
return await rest.runMethod( return await bot.rest.runMethod(
bot.rest,
"patch", "patch",
endpoints.UPDATE_VOICE_STATE(guildId, hasOwnProperty(options, "userId") ? options.userId : undefined), bot.constants.endpoints.UPDATE_VOICE_STATE(guildId, bot.utils.hasOwnProperty(options, "userId") ? options.userId : undefined),
snakelize(options) {
channel_id: options.channelId,
suppress: options.suppress,
request_to_speak_timestamp: options.requestToSpeakTimestamp,
user_id: options.userId
}
); );
} }