Threads helpers

This commit is contained in:
TriForMine
2021-10-21 21:41:51 +02:00
parent 3a08aa15f4
commit 4a12b7714b
15 changed files with 124 additions and 150 deletions
+7 -11
View File
@@ -1,22 +1,18 @@
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 { requireBotChannelPermissions } from "../../../util/permissions.ts";
/** Adds a user to a thread. Requires the ability to send messages in the thread. Requires the thread is not archived. */ /** Adds a user to a thread. Requires the ability to send messages in the thread. Requires the thread is not archived. */
export async function addToThread(threadId: bigint, userId: bigint) { export async function addToThread(bot: Bot, threadId: bigint, userId: bigint) {
const thread = await cacheHandlers.get("threads", threadId); const thread = await bot.cache.threads.get(threadId);
if (thread) { if (thread) {
if (thread.archived) { if (thread.archived) {
throw new Error(Errors.CANNOT_ADD_USER_TO_ARCHIVED_THREADS); throw new Error(bot.constants.Errors.CANNOT_ADD_USER_TO_ARCHIVED_THREADS);
} }
// If a user id is provided SEND_MESSAGES is required. // If a user id is provided SEND_MESSAGES is required.
const channel = await cacheHandlers.get("channels", thread.parentId); const channel = await bot.cache.channels.get(thread.parentId);
// TODO: does MANAGE_THREADS override this???? // TODO: does MANAGE_THREADS override this????
if (channel) await requireBotChannelPermissions(channel, ["SEND_MESSAGES"]); if (channel) await bot.utils.requireBotChannelPermissions(bot, channel, ["SEND_MESSAGES"]);
} }
return await rest.runMethod<undefined>("put", endpoints.THREAD_USER(threadId, userId)); return await bot.rest.runMethod<undefined>(bot.rest, "put", bot.constants.endpoints.THREAD_USER(threadId, userId));
} }
@@ -1,6 +1,6 @@
import { editThread } from "./edit_thread.ts"; import type { Bot } from "../../../bot.ts";
/** Sets a thread channel to be archived. */ /** Sets a thread channel to be archived. */
export async function archiveThread(threadId: bigint) { export async function archiveThread(bot: Bot, threadId: bigint) {
return await editThread(threadId, { archived: true }); return await bot.helpers.editThread(bot, threadId, { archived: true });
} }
@@ -1,15 +1,12 @@
import { cacheHandlers } from "../../../cache.ts"; import type { Bot } from "../../../bot.ts";
import { rest } from "../../../rest/rest.ts";
import { endpoints } from "../../../util/constants.ts";
import { requireBotGuildPermissions } from "../../../util/permissions.ts";
/** Delete a thread in your server. Bot needs MANAGE_THREADS permissions in the server. */ /** Delete a thread in your server. Bot needs MANAGE_THREADS permissions in the server. */
export async function deleteThread(threadId: bigint, reason?: string) { export async function deleteThread(bot: Bot, threadId: bigint, reason?: string) {
const thread = await cacheHandlers.get("threads", threadId); const thread = await bot.cache.threads.get(threadId);
if (thread) { if (thread) {
const channel = await cacheHandlers.get("channels", thread?.parentId); const channel = await bot.cache.channels.get(thread?.parentId);
if (channel?.guildId) await requireBotGuildPermissions(channel.guildId, ["MANAGE_THREADS"]); if (channel?.guildId) await bot.utils.requireBotGuildPermissions(bot, channel.guildId, ["MANAGE_THREADS"]);
} }
return await rest.runMethod<undefined>("delete", endpoints.CHANNEL_BASE(threadId), { reason }); return await bot.rest.runMethod<undefined>(bot.rest,"delete", bot.constants.endpoints.CHANNEL_BASE(threadId), { reason });
} }
+20 -17
View File
@@ -1,23 +1,26 @@
import { rest } from "../../../rest/rest.ts"; import type { ModifyThread } from "../../../types/channels/threads/modify_thread.ts";
import { ModifyThread } from "../../../types/channels/threads/modify_thread.ts"; import type { Bot } from "../../../bot.ts";
import { endpoints } from "../../../util/constants.ts"; import {channelToThread} from "../../../util/transformers/channel_to_thread.ts";
import { channelToThread } from "../../../util/transformers/channel_to_thread.ts";
import { snakelize } from "../../../util/utils.ts";
/** Update a thread's settings. Requires the `MANAGE_CHANNELS` permission for the guild. */ /** Update a thread's settings. Requires the `MANAGE_CHANNELS` permission for the guild. */
export async function editThread(threadId: bigint, options: ModifyThread, reason?: string) { export async function editThread(bot: Bot, threadId: bigint, options: ModifyThread, reason?: string) {
// const thread = await cacheHandlers.get("threads", threadId); // const thread = await cacheHandlers.get("threads", threadId);
// TODO: permission checking // TODO: permission checking
const result = await rest.runMethod( const result = await bot.rest.runMethod(
"patch", bot.rest,
endpoints.CHANNEL_BASE(threadId), "patch",
snakelize({ bot.constants.endpoints.CHANNEL_BASE(threadId),
...options, {
reason, name: options.name,
}) archived: options.archived,
); auto_archive_duration: options.autoArchiveDuration,
locked: options.locked,
rate_limit_per_user: options.rateLimitPerUser,
reason,
}
);
return channelToThread(result); return channelToThread(result);
} }
@@ -1,17 +1,14 @@
import { rest } from "../../../rest/rest.ts"; import type { Bot } from "../../../bot.ts";
import { ListActiveThreads } from "../../../types/channels/threads/list_active_threads.ts"; import type { ListActiveThreads } from "../../../types/channels/threads/list_active_threads.ts";
import { snowflakeToBigint } from "../../../util/bigint.ts";
import { Collection } from "../../../util/collection.ts"; import { Collection } from "../../../util/collection.ts";
import { endpoints } from "../../../util/constants.ts"; import {channelToThread} from "../../../util/transformers/channel_to_thread.ts";
import { requireBotChannelPermissions } from "../../../util/permissions.ts";
import { channelToThread } from "../../../util/transformers/channel_to_thread.ts";
/** Returns all active threads in the channel, including public and private threads. Threads are ordered by their id, in descending order. Requires the VIEW_CHANNEL permission. */ /** Returns all active threads in the channel, including public and private threads. Threads are ordered by their id, in descending order. Requires the VIEW_CHANNEL permission. */
export async function getActiveThreads(channelId: bigint) { export async function getActiveThreads(bot: Bot, channelId: bigint) {
await requireBotChannelPermissions(channelId, ["VIEW_CHANNEL"]); await bot.utils.requireBotChannelPermissions(bot, channelId, ["VIEW_CHANNEL"]);
// TODO: pagination // TODO: pagination
const result = (await rest.runMethod("get", endpoints.THREAD_ACTIVE(channelId))) as ListActiveThreads; const result = (await bot.rest.runMethod(bot.rest,"get", bot.constants.endpoints.THREAD_ACTIVE(channelId))) as ListActiveThreads;
const threads = new Collection( const threads = new Collection(
result.threads.map((t) => { result.threads.map((t) => {
@@ -21,9 +18,9 @@ export async function getActiveThreads(channelId: bigint) {
); );
for (const member of result.members) { for (const member of result.members) {
const thread = threads.get(snowflakeToBigint(member.id!)); const thread = threads.get(bot.transformers.snowflake(member.id!));
thread?.members.set(snowflakeToBigint(member.userId!), { thread?.members.set(bot.transformers.snowflake(member.userId!), {
userId: snowflakeToBigint(member.userId!), userId: bot.transformers.snowflake(member.userId!),
flags: member.flags, flags: member.flags,
joinTimestamp: Date.parse(member.joinTimestamp), joinTimestamp: Date.parse(member.joinTimestamp),
}); });
@@ -1,16 +1,13 @@
import { rest } from "../../../rest/rest.ts";
import { ListActiveThreads } from "../../../types/channels/threads/list_active_threads.ts"; import { ListActiveThreads } from "../../../types/channels/threads/list_active_threads.ts";
import { ListPublicArchivedThreads } from "../../../types/channels/threads/list_public_archived_threads.ts"; import { ListPublicArchivedThreads } from "../../../types/channels/threads/list_public_archived_threads.ts";
import { PermissionStrings } from "../../../types/permissions/permission_strings.ts"; import { PermissionStrings } from "../../../types/permissions/permission_strings.ts";
import { snowflakeToBigint } from "../../../util/bigint.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"; import {channelToThread} from "../../../util/transformers/channel_to_thread.ts";
import { channelToThread } from "../../../util/transformers/channel_to_thread.ts";
import { snakelize } from "../../../util/utils.ts";
/** Get the archived threads for this channel, defaults to public */ /** Get the archived threads for this channel, defaults to public */
export async function getArchivedThreads( export async function getArchivedThreads(
bot: Bot,
channelId: bigint, channelId: bigint,
options?: ListPublicArchivedThreads & { options?: ListPublicArchivedThreads & {
type?: "public" | "private" | "privateJoinedThreads"; type?: "public" | "private" | "privateJoinedThreads";
@@ -19,18 +16,23 @@ export async function getArchivedThreads(
const permissions = new Set<PermissionStrings>(["READ_MESSAGE_HISTORY"]); const permissions = new Set<PermissionStrings>(["READ_MESSAGE_HISTORY"]);
if (options?.type === "private") permissions.add("MANAGE_THREADS"); if (options?.type === "private") permissions.add("MANAGE_THREADS");
await requireBotChannelPermissions(channelId, [...permissions]); await bot.utils.requireBotChannelPermissions(bot, channelId, [...permissions]);
// TODO: pagination // TODO: pagination
const result = (await rest.runMethod( const result = (await bot.rest.runMethod(
bot.rest,
"get", "get",
options?.type === "privateJoinedThreads" options?.type === "privateJoinedThreads"
? endpoints.THREAD_ARCHIVED_PRIVATE_JOINED(channelId) ? bot.constants.endpoints.THREAD_ARCHIVED_PRIVATE_JOINED(channelId)
: options?.type === "private" : options?.type === "private"
? endpoints.THREAD_ARCHIVED_PRIVATE(channelId) ? bot.constants.endpoints.THREAD_ARCHIVED_PRIVATE(channelId)
: endpoints.THREAD_ARCHIVED_PUBLIC(channelId), : bot.constants.endpoints.THREAD_ARCHIVED_PUBLIC(channelId),
snakelize(options ?? {}) options ? {
before: options.before,
limit: options.limit,
type: options.type
} : {}
)) as ListActiveThreads; )) as ListActiveThreads;
const threads = new Collection( const threads = new Collection(
@@ -41,9 +43,9 @@ export async function getArchivedThreads(
); );
for (const member of result.members) { for (const member of result.members) {
const thread = threads.get(snowflakeToBigint(member.id!)); const thread = threads.get(bot.transformers.snowflake(member.id!));
thread?.members.set(snowflakeToBigint(member.userId!), { thread?.members.set(bot.transformers.snowflake(member.userId!), {
userId: snowflakeToBigint(member.userId!), userId: bot.transformers.snowflake(member.userId!),
flags: member.flags, flags: member.flags,
joinTimestamp: Date.parse(member.joinTimestamp), joinTimestamp: Date.parse(member.joinTimestamp),
}); });
@@ -1,29 +1,23 @@
import { cacheHandlers } from "../../../cache.ts"; import type { Bot } from "../../../bot.ts";
import { rest } from "../../../rest/rest.ts";
import { ThreadMember } from "../../../types/channels/threads/thread_member.ts"; import { ThreadMember } from "../../../types/channels/threads/thread_member.ts";
import { Errors } from "../../../types/discordeno/errors.ts";
import { DiscordGatewayIntents } from "../../../types/gateway/gateway_intents.ts"; import { DiscordGatewayIntents } from "../../../types/gateway/gateway_intents.ts";
import { Collection } from "../../../util/collection.ts"; import { Collection } from "../../../util/collection.ts";
import { endpoints } from "../../../util/constants.ts"; import {threadMemberModified} from "../../../util/transformers/thread_member_modified.ts";
import { botHasChannelPermissions } from "../../../util/permissions.ts";
import { threadMemberModified } from "../../../util/transformers/thread_member_modified.ts";
import { ws } from "../../../ws/ws.ts";
/** Returns thread members objects that are members of the thread. */ /** Returns thread members objects that are members of the thread. */
export async function getThreadMembers(threadId: bigint) { export async function getThreadMembers(bot: Bot, threadId: bigint) {
// Check if intents is not 0 as proxy ws won't set intents in other instances // Check if intents is not 0 as proxy ws won't set intents in other instances
if (ws.identifyPayload.intents && !(ws.identifyPayload.intents & DiscordGatewayIntents.GuildMembers)) { if (bot.gateway.identifyPayload.intents && !(bot.gateway.identifyPayload.intents & DiscordGatewayIntents.GuildMembers)) {
throw new Error(Errors.MISSING_INTENT_GUILD_MEMBERS); throw new Error(bot.constants.Errors.MISSING_INTENT_GUILD_MEMBERS);
} }
const thread = await cacheHandlers.get("threads", threadId); const thread = await bot.cache.threads.get(threadId);
if (thread?.isPrivate) { if (thread?.isPrivate) {
const channel = await cacheHandlers.get("channels", thread.parentId); const channel = await bot.cache.channels.get(thread.parentId);
if (channel && !(await botHasChannelPermissions(channel, ["MANAGE_THREADS"])) && !thread.botIsMember) if (channel && !(await bot.utils.botHasChannelPermissions(bot, channel, ["MANAGE_THREADS"])) && !thread.botIsMember)
throw new Error(Errors.CANNOT_GET_MEMBERS_OF_AN_UNJOINED_PRIVATE_THREAD); throw new Error(bot.constants.Errors.CANNOT_GET_MEMBERS_OF_AN_UNJOINED_PRIVATE_THREAD);
} }
const result = await rest.runMethod<ThreadMember[]>("get", endpoints.THREAD_MEMBERS(threadId)); const result = await bot.rest.runMethod<ThreadMember[]>(bot.rest,"get", bot.constants.endpoints.THREAD_MEMBERS(threadId));
const members = result.map((member) => threadMemberModified(member)); const members = result.map((member) => threadMemberModified(member));
+5 -8
View File
@@ -1,14 +1,11 @@
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";
/** Adds the bot to the thread. Cannot join an archived thread. */ /** Adds the bot to the thread. Cannot join an archived thread. */
export async function joinThread(threadId: bigint) { export async function joinThread(bot: Bot, threadId: bigint) {
const thread = await cacheHandlers.get("threads", threadId); const thread = await bot.cache.threads.get(threadId);
if (thread?.archived) { if (thread?.archived) {
throw new Error(Errors.CANNOT_ADD_USER_TO_ARCHIVED_THREADS); throw new Error(bot.contants.Errors.CANNOT_ADD_USER_TO_ARCHIVED_THREADS);
} }
return await rest.runMethod<undefined>("put", endpoints.THREAD_ME(threadId)); return await bot.rest.runMethod<undefined>(bot.rest,"put", bot.constants.endpoints.THREAD_ME(threadId));
} }
+5 -8
View File
@@ -1,12 +1,9 @@
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";
/** Removes the bot from a thread. Requires the thread is not archived. */ /** Removes the bot from a thread. Requires the thread is not archived. */
export async function leaveThread(threadId: bigint) { export async function leaveThread(bot: Bot, threadId: bigint) {
const thread = await cacheHandlers.get("threads", threadId); const thread = await bot.cache.threads.get(threadId);
if (thread?.archived) throw new Error(Errors.CANNOT_LEAVE_ARCHIVED_THREAD); if (thread?.archived) throw new Error(bot.constants.Errors.CANNOT_LEAVE_ARCHIVED_THREAD);
return await rest.runMethod<undefined>("delete", endpoints.THREAD_ME(threadId)); return await bot.rest.runMethod<undefined>(bot.rest,"delete", bot.constants.endpoints.THREAD_ME(threadId));
} }
+3 -3
View File
@@ -1,6 +1,6 @@
import { editThread } from "./edit_thread.ts"; import type { Bot } from "../../../bot.ts";
/** Sets a thread channel to be locked. */ /** Sets a thread channel to be locked. */
export async function lockThread(threadId: bigint) { export async function lockThread(bot: Bot, threadId: bigint) {
return await editThread(threadId, { locked: true }); return await bot.utils.editThread(bot, threadId, { locked: true });
} }
@@ -1,21 +1,16 @@
import { botId } from "../../../bot.ts"; import type { Bot } from "../../../bot.ts";
import { cacheHandlers } from "../../../cache.ts";
import { rest } from "../../../rest/rest.ts";
import { Errors } from "../../../types/discordeno/errors.ts";
import { endpoints } from "../../../util/constants.ts";
import { requireBotChannelPermissions } from "../../../util/permissions.ts";
/** Removes a user from a thread. Requires the MANAGE_THREADS permission or that you are the creator of the thread. Also requires the thread is not archived. */ /** Removes a user from a thread. Requires the MANAGE_THREADS permission or that you are the creator of the thread. Also requires the thread is not archived. */
export async function removeThreadMember(threadId: bigint, userId: bigint) { export async function removeThreadMember(bot: Bot, threadId: bigint, userId: bigint) {
const thread = await cacheHandlers.get("threads", threadId); const thread = await bot.cache.threads.get(threadId);
if (thread) { if (thread) {
if (thread.archived) throw new Error(Errors.CANNOT_REMOVE_FROM_ARCHIVED_THREAD); if (thread.archived) throw new Error(bot.constants.Errors.CANNOT_REMOVE_FROM_ARCHIVED_THREAD);
if (thread.ownerId !== botId) { if (thread.ownerId !== bot.id) {
const channel = await cacheHandlers.get("channels", thread.parentId); const channel = await bot.cache.channels.get(thread.parentId);
if (channel) await requireBotChannelPermissions(channel, ["MANAGE_THREADS"]); if (channel) await bot.utils.requireBotChannelPermissions(bot, channel, ["MANAGE_THREADS"]);
} }
} }
return await rest.runMethod<undefined>("delete", endpoints.THREAD_USER(threadId, userId)); return await bot.rest.runMethod<undefined>(bot.rest,"delete", bot.constants.endpoints.THREAD_USER(threadId, userId));
} }
@@ -1,25 +1,23 @@
import { cacheHandlers } from "../../../cache.ts"; import type { Channel } from "../../../types/channels/channel.ts";
import { rest } from "../../../rest/rest.ts"; import type { StartThread } from "../../../types/channels/threads/start_thread.ts";
import { Channel } from "../../../types/channels/channel.ts"; import type { Bot } from "../../../bot.ts";
import { StartThread } from "../../../types/channels/threads/start_thread.ts"; import {channelToThread} from "../../../util/transformers/channel_to_thread.ts";
import { Errors } from "../../../types/discordeno/errors.ts";
import { endpoints } from "../../../util/constants.ts";
import { requireBotChannelPermissions } from "../../../util/permissions.ts";
import { channelToThread } from "../../../util/transformers/channel_to_thread.ts";
import { snakelize } from "../../../util/utils.ts";
/** Creates a new private thread. Returns a thread channel. */ /** Creates a new private thread. Returns a thread channel. */
export async function startPrivateThread(channelId: bigint, options: StartThread) { export async function startPrivateThread(bot: Bot, channelId: bigint, options: StartThread) {
const channel = await cacheHandlers.get("channels", channelId); const channel = await bot.cache.channels.get(channelId);
if (channel) { if (channel) {
if (!channel.isGuildTextBasedChannel) throw new Error(Errors.INVALID_THREAD_PARENT_CHANNEL_TYPE); if (!channel.isGuildTextBasedChannel) throw new Error(bot.constants.Errors.INVALID_THREAD_PARENT_CHANNEL_TYPE);
if (channel.isNewsChannel) throw new Error(Errors.GUILD_NEWS_CHANNEL_ONLY_SUPPORT_PUBLIC_THREADS); if (channel.isNewsChannel) throw new Error(bot.constants.Errors.GUILD_NEWS_CHANNEL_ONLY_SUPPORT_PUBLIC_THREADS);
await requireBotChannelPermissions(channel, ["SEND_MESSAGES", "USE_PRIVATE_THREADS"]); await bot.utils.requireBotChannelPermissions(bot, channel, ["SEND_MESSAGES", "USE_PRIVATE_THREADS"]);
} }
return channelToThread( return channelToThread(
await rest.runMethod<Channel>("post", endpoints.THREAD_START_PRIVATE(channelId), snakelize(options)) await bot.rest.runMethod<Channel>(bot.rest,"post", bot.constants.endpoints.THREAD_START_PRIVATE(channelId), {
name: options.name,
auto_archive_duration: options.autoArchiveDuration
})
); );
} }
+12 -14
View File
@@ -1,25 +1,23 @@
import { cacheHandlers } from "../../../cache.ts"; import type { Channel } from "../../../types/channels/channel.ts";
import { rest } from "../../../rest/rest.ts"; import type { StartThread } from "../../../types/channels/threads/start_thread.ts";
import { Channel } from "../../../types/channels/channel.ts"; import type { Bot } from "../../../bot.ts";
import { StartThread } from "../../../types/channels/threads/start_thread.ts"; import {channelToThread} from "../../../util/transformers/channel_to_thread.ts";
import { Errors } from "../../../types/discordeno/errors.ts";
import { endpoints } from "../../../util/constants.ts";
import { requireBotChannelPermissions } from "../../../util/permissions.ts";
import { channelToThread } from "../../../util/transformers/channel_to_thread.ts";
import { snakelize } from "../../../util/utils.ts";
/** Creates a new public thread from an existing message. Returns a thread channel. */ /** Creates a new public thread from an existing message. Returns a thread channel. */
export async function startThread(channelId: bigint, messageId: bigint, options: StartThread) { export async function startThread(bot: Bot, channelId: bigint, messageId: bigint, options: StartThread) {
const channel = await cacheHandlers.get("channels", channelId); const channel = await bot.cache.channels.get(channelId);
if (channel) { if (channel) {
if (!channel.isGuildTextBasedChannel) { if (!channel.isGuildTextBasedChannel) {
throw new Error(Errors.INVALID_THREAD_PARENT_CHANNEL_TYPE); throw new Error(bot.constants.Errors.INVALID_THREAD_PARENT_CHANNEL_TYPE);
} }
await requireBotChannelPermissions(channel, ["SEND_MESSAGES", "USE_PUBLIC_THREADS"]); await bot.utils.requireBotChannelPermissions(bot, channel, ["SEND_MESSAGES", "USE_PUBLIC_THREADS"]);
} }
return channelToThread( return channelToThread(
await rest.runMethod<Channel>("post", endpoints.THREAD_START_PUBLIC(channelId, messageId), snakelize(options)) await bot.rest.runMethod<Channel>(bot.rest,"post", bot.constants.endpoints.THREAD_START_PUBLIC(channelId, messageId), {
name: options.name,
auto_archive_duration: options.autoArchiveDuration
})
); );
} }
@@ -1,6 +1,6 @@
import { editThread } from "./edit_thread.ts"; import type { Bot } from "../../../bot.ts";
/** Sets a thread channel to be unarchived. */ /** Sets a thread channel to be unarchived. */
export async function unarchiveThread(threadId: bigint) { export async function unarchiveThread(bot: Bot, threadId: bigint) {
return await editThread(threadId, { archived: false }); return await bot.helpers.editThread(bot, threadId, { archived: false });
} }
@@ -1,6 +1,6 @@
import { editThread } from "./edit_thread.ts"; import type { Bot } from "../../../bot.ts";
/** Sets a thread channel to be unlocked. */ /** Sets a thread channel to be unlocked. */
export async function unlockThread(threadId: bigint) { export async function unlockThread(bot: Bot, threadId: bigint) {
return await editThread(threadId, { locked: false }); return await bot.helpers.editThread(bot, threadId, { locked: false });
} }