From 0670dd1ef96d7172d4c0e8a79b24999cc762be97 Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Fri, 30 Apr 2021 22:10:24 +0200 Subject: [PATCH 01/72] add: new channel types --- src/types/channels/channel_types.ts | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/types/channels/channel_types.ts b/src/types/channels/channel_types.ts index e7a47deab..e7cf521c6 100644 --- a/src/types/channels/channel_types.ts +++ b/src/types/channels/channel_types.ts @@ -1,19 +1,25 @@ /** https://discord.com/developers/docs/resources/channel#channel-object-channel-types */ export enum DiscordChannelTypes { /** A text channel within a server */ - GUILD_TEXT, + GuildText, /** A direct message between users */ - DM, + Dm, /** A voice channel within a server */ - GUILD_VOICE, + GuildVoice, /** A direct message between multiple users */ - GROUP_DM, + GroupDm, /** An organizational category that contains up to 50 channels */ - GUILD_CATEGORY, + GuildCategory, /** A channel that users can follow and crosspost into their own server */ - GUILD_NEWS, + GuildNews, /** A channel in which game developers can sell their game on Discord */ - GUILD_STORE, + GuildStore, + /** A temporary sub-channel within a GUILD_NEWS channel */ + GuildNewsThread = 10, + /** A temporary sub-channel within a GUILD_TEXT channel */ + GuildPublicThread, + /** A temporary sub-channel within a GUILD_TEXT channel that is only viewable by those invited and those with the MANAGE_THREADS permission */ + GuildPivateThread, /** A voice channel for hosting events with an audience */ GUILD_STAGE_VOICE = 13, } From 84d5f8635fbc094ccb0b64ca455482eefe5b83d1 Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Fri, 30 Apr 2021 22:44:18 +0200 Subject: [PATCH 02/72] new message types --- src/types/messages/message_types.ts | 41 +++++++++++++++-------------- 1 file changed, 21 insertions(+), 20 deletions(-) diff --git a/src/types/messages/message_types.ts b/src/types/messages/message_types.ts index ba4c6a58a..29fc92fb5 100644 --- a/src/types/messages/message_types.ts +++ b/src/types/messages/message_types.ts @@ -1,23 +1,24 @@ /** https://discord.com/developers/docs/resources/channel#message-object-message-types */ export enum DiscordMessageTypes { - DEFAULT, - RECIPIENT_ADD, - RECIPIENT_REMOVE, - CALL, - CHANNEL_NAME_CHANGE, - CHANNEL_ICON_CHANGE, - CHANNEL_PINNED_MESSAGE, - GUILD_MEMBER_JOIN, - USER_PREMIUM_GUILD_SUBSCRIPTION, - USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_1, - USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_2, - USER_PREMIUM_GUILD_SUBSCRIPTION_TIER_3, - CHANNEL_FOLLOW_ADD, - GUILD_DISCOVERY_DISQUALIFIED = 14, - GUILD_DISCOVERY_REQUALIFIED, - GUILD_DISCOVERY_GRACE_PERIOD_INITIAL_WARNING, - GUILD_DISCOVERY_GRACE_PERIOD_FINAL_WARNING, - REPLY = 19, - APPLICATION_COMMAND, - GUILD_INVITE_REMINDER = 22, + Default, + RecipientAdd, + RecipientRemove, + Call, + ChannelNameChange, + ChannelIconChange, + ChannelPinnedMessage, + GuildMemberJoin, + UserPremiumGuildSubscription, + UserPremiumGuildSubscriptionTier1, + UserPremiumGuildSubscriptionTier2, + UserPremiumGuildSubscriptionTier3, + ChannelFollowAdd, + GuildDiscoveryDisqualified = 14, + GuildDiscoveryRequalified, + GuildDiscoveryGracePeriodInitialWarning, + GuildDiscoveryGracePeriodFinalWarning, + ThreadCreated, + Reply = 19, + ApplicationCommand, + GuildInviteReminder = 22, } From 2a31b245e6306f0aae2245c511504b800c57be1b Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Fri, 30 Apr 2021 23:01:08 +0200 Subject: [PATCH 03/72] add: new message flags --- src/types/messages/message_flags.ts | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/types/messages/message_flags.ts b/src/types/messages/message_flags.ts index 4f55463d9..f9c149dbe 100644 --- a/src/types/messages/message_flags.ts +++ b/src/types/messages/message_flags.ts @@ -1,17 +1,19 @@ /** https://discord.com/developers/docs/resources/channel#message-object-message-flags */ export enum DiscordMessageFlags { /** This message has been published to subscribed channels (via Channel Following) */ - CROSSPOSTED = 1 << 0, + Crossposted = 1 << 0, /** This message originated from a message in another channel (via Channel Following) */ - IS_CROSSPOST = 1 << 1, + IsCrosspost = 1 << 1, /** Do not include any embeds when serializing this message */ - SUPPRESS_EMBEDS = 1 << 2, + SuppressEmbeeds = 1 << 2, /** The source message for this crosspost has been deleted (via Channel Following) */ - SOURCE_MESSAGE_DELETED = 1 << 3, + SourceMessageDeleted = 1 << 3, /** This message came from the urgent message system */ - URGENT = 1 << 4, + Urgent = 1 << 4, + /** This message has an associated thread, with the same id as the message */ + HasThread = 1 << 5, /** This message is only visible to the user who invoked the Interaction */ - EMPHERAL = 1 << 6, + Empheral = 1 << 6, /** This message is an Interaction Response and the bot is "thinking" */ - LOADING = 1 << 7, + Loading = 1 << 7, } From 399914826630c78063a745c43b1cf44d0536614d Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Fri, 30 Apr 2021 23:01:17 +0200 Subject: [PATCH 04/72] add: ThreadMember --- src/types/messages/thread_member.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 src/types/messages/thread_member.ts diff --git a/src/types/messages/thread_member.ts b/src/types/messages/thread_member.ts new file mode 100644 index 000000000..2b3d1b54a --- /dev/null +++ b/src/types/messages/thread_member.ts @@ -0,0 +1,10 @@ +export interface ThreadMember { + /** The id of the thread */ + id: string; + /** The id of the user */ + userId: string; + /** The time the current user last joined the thread */ + joinTimestamp: string; + /** Any user-thread settings, currently only used for notifications */ + flags: number; +} From 653ef1faab7588419aab831cff61f57eb4ee90ec Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Fri, 30 Apr 2021 23:01:28 +0200 Subject: [PATCH 05/72] add: ThreadMetadata --- src/types/messages/thread_metadata.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/types/messages/thread_metadata.ts diff --git a/src/types/messages/thread_metadata.ts b/src/types/messages/thread_metadata.ts new file mode 100644 index 000000000..ce8f40e56 --- /dev/null +++ b/src/types/messages/thread_metadata.ts @@ -0,0 +1,12 @@ +export interface ThreadMetadata { + /** Whether the thread is archived */ + archived: boolean; + /** Id of the user that last archived or unarchived the thread */ + archiverId?: string; + /** Duration in minutes to automatically archive the thread after recent activity */ + autoArchiveDuration: 60 | 1440 | 4320 | 10080; + /** Timestamp when the thread's archive status was last changed, used for calculating recent activity */ + archiveTimestamp: string; + /** When a thread is locked, only users with `MANAGE_THREADS` can unarchive it */ + locked?: boolean; +} From bd52c0f571fb1b93b4145fb8dcc22d393a292f5e Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Fri, 30 Apr 2021 23:01:40 +0200 Subject: [PATCH 06/72] add: thread param --- src/types/messages/message.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/types/messages/message.ts b/src/types/messages/message.ts index c00b23d62..f25f257a4 100644 --- a/src/types/messages/message.ts +++ b/src/types/messages/message.ts @@ -1,3 +1,4 @@ +import { Channel } from "../channels/channel.ts"; import { ChannelMention } from "../channels/channel_mention.ts"; import { Embed } from "../embeds/embed.ts"; import { GuildMember } from "../guilds/guild_member.ts"; @@ -11,6 +12,7 @@ import { MessageReference } from "./message_reference.ts"; import { MessageSticker } from "./message_sticker.ts"; import { DiscordMessageTypes } from "./message_types.ts"; import { DiscordReaction } from "./reaction.ts"; +import { ThreadMember } from "./thread_member.ts"; export interface Message { /** id of the message */ @@ -82,6 +84,8 @@ export interface Message { referencedMessage?: Message; /** Sent if the message is a response to an Interaction */ interaction?: MessageInteraction; + /** The thread that was started from this message, includes thread member object */ + thread?: Omit & { member: ThreadMember }; } /** https://discord.com/developers/docs/resources/channel#message-object */ From 111dde1020b4f4c8a1f67d8782240e31aacf00ed Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Fri, 30 Apr 2021 23:01:51 +0200 Subject: [PATCH 07/72] add: thread params --- src/types/channels/channel.ts | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/types/channels/channel.ts b/src/types/channels/channel.ts index 9361bbeb3..a4cffce5d 100644 --- a/src/types/channels/channel.ts +++ b/src/types/channels/channel.ts @@ -1,3 +1,5 @@ +import { ThreadMember } from "../messages/thread_member.ts"; +import { ThreadMetadata } from "../messages/thread_metadata.ts"; import { User } from "../users/user.ts"; import { SnakeCasedPropertiesDeep } from "../util.ts"; import { DiscordChannelTypes } from "./channel_types.ts"; @@ -33,11 +35,11 @@ export interface Channel { recipients?: User[]; /** Icon hash */ icon?: string | null; - /** id of the DM creator */ + /** Id of the creator of the group DM or thread */ ownerId?: string; /** Application id of the group DM creator if it is bot-created */ applicationId?: string; - /** Id of the parent category for a channel (each parent category can contain up to 50 channels) */ + /** For guild channels: Id of the parent category for a channel (each parent category can contain up to 50 channels), for threads: id of the text channel this thread was created */ parentId?: string | null; /** When the last pinned message was pinned. This may be null in events such as GUILD_CREATE when a message is not pinned. */ lastPinTimestamp?: string | null; @@ -45,6 +47,14 @@ export interface Channel { rtcRegion?: string | null; /** The camera video quality mode of the voice channel, 1 when not present */ videoQualityMode?: DiscordVideoQualityModes; + /** An approximate count of messages in a thread, stops counting at 50 */ + messageCount?: number; + /** An approximate count of users in a thread, stops counting at 50 */ + memberCount?: number; + /** Thread-specifig fields not needed by other channels */ + threadMetadata?: ThreadMetadata; + /** Thread member object for the current user, if they have joined the thread, only included on certain API endpoints */ + member?: ThreadMember; } /** https://discord.com/developers/docs/resources/channel#channel-object */ From b2fbfeb08e59e45769b57a02c009f6d69b0dbc0c Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sat, 1 May 2021 11:13:23 +0200 Subject: [PATCH 08/72] add: ListActiveThreads --- src/types/channels/list_active_threads.ts | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 src/types/channels/list_active_threads.ts diff --git a/src/types/channels/list_active_threads.ts b/src/types/channels/list_active_threads.ts new file mode 100644 index 000000000..da542f7f7 --- /dev/null +++ b/src/types/channels/list_active_threads.ts @@ -0,0 +1,11 @@ +import { ThreadMember } from "../messages/thread_member.ts"; +import { Channel } from "./channel.ts"; + +export interface ListActiveThreads { + /** The active threads */ + threads: Channel[]; + /** A thread member object for each returned thread the current user has joined */ + members: ThreadMember[]; + /** Whether there are potentially additional threads that could be returned on subsequent call */ + hasMore: boolean; +} From c5eb08f9af22da24eae10057adaafb0a5e72dfe9 Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sat, 1 May 2021 11:13:31 +0200 Subject: [PATCH 09/72] add: ModifyThread --- src/types/channels/modify_thread.ts | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 src/types/channels/modify_thread.ts diff --git a/src/types/channels/modify_thread.ts b/src/types/channels/modify_thread.ts new file mode 100644 index 000000000..629aea0c7 --- /dev/null +++ b/src/types/channels/modify_thread.ts @@ -0,0 +1,12 @@ +export interface ModifyThread { + /** 2-100 character thread name */ + name?: string; + /** Whether the thread is archived */ + archived?: boolean; + /** Duration in minutes to automatically archive the thread after recent activity */ + autoArchiveDuration?: 60 | 1440 | 4320 | 10080; + /** When a thread is locked, only users with `MANAGE_THREADS` can unarchive it */ + locked?: boolean; + /** Amount of seconds a user has to wait before sending another message (0-21600); bots, as well as users with the permission `MANAGE_MESSAGES`, `MANAGE_THREAD` or `MANAGE_CHANNEL` are unaffected */ + rateLimitPerUser?: number; +} From f9a516d503ac6711d88f1ce74e49d8a318a83de5 Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sat, 1 May 2021 11:13:39 +0200 Subject: [PATCH 10/72] add: StartThread --- src/types/channels/start_thread.ts | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 src/types/channels/start_thread.ts diff --git a/src/types/channels/start_thread.ts b/src/types/channels/start_thread.ts new file mode 100644 index 000000000..a1cf60381 --- /dev/null +++ b/src/types/channels/start_thread.ts @@ -0,0 +1,6 @@ +export interface StartThread { + /** 2-100 character thread name */ + name: string; + /** Duration in minutes to automatically archive the thread after recent activity */ + autoArchiveDuration: 60 | 1440 | 4320 | 10080; +} From dc2a3eb9f00d021b951d2f458d02207026e65309 Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sat, 1 May 2021 11:18:16 +0200 Subject: [PATCH 11/72] add: ListPublicArchivedThreads --- src/types/channels/list_public_archived_threads.ts | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 src/types/channels/list_public_archived_threads.ts diff --git a/src/types/channels/list_public_archived_threads.ts b/src/types/channels/list_public_archived_threads.ts new file mode 100644 index 000000000..fe5eae590 --- /dev/null +++ b/src/types/channels/list_public_archived_threads.ts @@ -0,0 +1,7 @@ +export interface ListPublicArchivedThreads { + // TODO: convert unix to ISO9601 timestamp + /** Returns threads before this timestamp. UNIX or ISO8601 timestamp */ + before?: number | string; + /** Optional maximum number of threads to return */ + limit?: number; +} From 3396f7ddc847f25d5254993054b29986dde47c96 Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sat, 1 May 2021 11:19:55 +0200 Subject: [PATCH 12/72] add: threads prop --- src/types/guilds/guild.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/types/guilds/guild.ts b/src/types/guilds/guild.ts index c346f9f22..e60d96b86 100644 --- a/src/types/guilds/guild.ts +++ b/src/types/guilds/guild.ts @@ -79,6 +79,9 @@ export interface Guild { members?: GuildMember[]; /** Channels in the guild */ channels?: Channel[]; + // TODO: check if need to omit + /** All active threads in the guild that the current user has permission to view */ + threads?: Channel[]; /** Presences of the members in the guild, will only include non-offline members if the size is greater than large threshold */ presences?: Partial[]; /** The maximum number of presences for the guild (the default value, currently 25000, is in effect when null is returned) */ From 0c875f155ebc44a5ffd3d9a31a025a43d495e5b8 Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sat, 1 May 2021 11:20:42 +0200 Subject: [PATCH 13/72] chore: bump API_VERSION to v9 --- src/util/constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/constants.ts b/src/util/constants.ts index eed6df6f1..f0ee88935 100644 --- a/src/util/constants.ts +++ b/src/util/constants.ts @@ -2,7 +2,7 @@ export const BASE_URL = "https://discord.com/api"; /** https://discord.com/developers/docs/reference#api-versioning-api-versions */ -export const API_VERSION = 8; +export const API_VERSION = 9; /** https://discord.com/developers/docs/topics/gateway#gateways-gateway-versions */ export const GATEWAY_VERSION = 8; From f0e9bc86b2da2b068e1ea786df0df74cdcfc523e Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sat, 1 May 2021 11:20:52 +0200 Subject: [PATCH 14/72] full dd version string is better --- src/util/constants.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/util/constants.ts b/src/util/constants.ts index f0ee88935..072e42d4a 100644 --- a/src/util/constants.ts +++ b/src/util/constants.ts @@ -7,8 +7,9 @@ export const API_VERSION = 9; /** https://discord.com/developers/docs/topics/gateway#gateways-gateway-versions */ export const GATEWAY_VERSION = 8; +// TODO: update this version /** https://github.com/discordeno/discordeno/releases */ -export const DISCORDENO_VERSION = 11; +export const DISCORDENO_VERSION = "v11.0.0"; /** https://discord.com/developers/docs/reference#user-agent */ export const USER_AGENT = From 7b1128a010df3eebcd68ebcbca5b93eb55bb1681 Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sat, 1 May 2021 11:44:53 +0200 Subject: [PATCH 15/72] add: docs link todo comment --- src/types/channels/list_active_threads.ts | 1 + src/types/channels/list_public_archived_threads.ts | 1 + src/types/channels/modify_thread.ts | 1 + src/types/channels/start_thread.ts | 1 + 4 files changed, 4 insertions(+) diff --git a/src/types/channels/list_active_threads.ts b/src/types/channels/list_active_threads.ts index da542f7f7..2651360f0 100644 --- a/src/types/channels/list_active_threads.ts +++ b/src/types/channels/list_active_threads.ts @@ -1,6 +1,7 @@ import { ThreadMember } from "../messages/thread_member.ts"; import { Channel } from "./channel.ts"; +// TODO: add docs link export interface ListActiveThreads { /** The active threads */ threads: Channel[]; diff --git a/src/types/channels/list_public_archived_threads.ts b/src/types/channels/list_public_archived_threads.ts index fe5eae590..95a7a2a0a 100644 --- a/src/types/channels/list_public_archived_threads.ts +++ b/src/types/channels/list_public_archived_threads.ts @@ -1,3 +1,4 @@ +// TODO: add docs link export interface ListPublicArchivedThreads { // TODO: convert unix to ISO9601 timestamp /** Returns threads before this timestamp. UNIX or ISO8601 timestamp */ diff --git a/src/types/channels/modify_thread.ts b/src/types/channels/modify_thread.ts index 629aea0c7..d261cab1d 100644 --- a/src/types/channels/modify_thread.ts +++ b/src/types/channels/modify_thread.ts @@ -1,3 +1,4 @@ +// TODO: add docs link export interface ModifyThread { /** 2-100 character thread name */ name?: string; diff --git a/src/types/channels/start_thread.ts b/src/types/channels/start_thread.ts index a1cf60381..10a5c0b02 100644 --- a/src/types/channels/start_thread.ts +++ b/src/types/channels/start_thread.ts @@ -1,3 +1,4 @@ +// TODO: add docs link export interface StartThread { /** 2-100 character thread name */ name: string; From 6cd229dcef92e31b0bd18afb8e2fe131b6f2f0d7 Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sat, 1 May 2021 11:53:18 +0200 Subject: [PATCH 16/72] add: ThreadListSync --- src/types/channels/thread_list_sync.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/types/channels/thread_list_sync.ts diff --git a/src/types/channels/thread_list_sync.ts b/src/types/channels/thread_list_sync.ts new file mode 100644 index 000000000..c5fa334d4 --- /dev/null +++ b/src/types/channels/thread_list_sync.ts @@ -0,0 +1,15 @@ +import { ThreadMember } from "../messages/thread_member.ts"; +import { Channel } from "./channel.ts"; + +// TODO: add docs link +export interface ThreadListSync { + /** The id of the guild */ + guildId: string; + /** The parent channel ids whose threads are being synced. If omitted, then threads were synced for the entire guild. This array may contain channelIds that have no active threads as well, so you know to clear that data */ + channelIds?: string[]; + // TODO: check if need to omit + /** All active threads in the given channels that the current user can access */ + threads: Channel[]; + /** All thread member objects from the synced threads for the current user, indicating which threads the current user has been added to */ + members: ThreadMember[]; +} From 3a5745143793b513ef8887444c40955c367f5e67 Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sat, 1 May 2021 11:53:27 +0200 Subject: [PATCH 17/72] add: new thread error codes --- src/types/codes/json_error_codes.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/types/codes/json_error_codes.ts b/src/types/codes/json_error_codes.ts index 69fb660f9..39c24c1a2 100644 --- a/src/types/codes/json_error_codes.ts +++ b/src/types/codes/json_error_codes.ts @@ -78,6 +78,10 @@ export enum DiscordJsonErrorCodes { InvalidApiVersionProvided = 50041, CannotDeleteAChannelRequiredForCommunityGuilds = 50074, InvalidStickerSent = 50081, + TriedToPerformAnOperationOnAnArchivedThreadSuchAsEditingAMessageOrAddingAUserToTheThread = + 50083, + InvalidThreadNotificationSettings, + BeforeValueIsEarlierThanTheThreadCreationDate, ReqctionWasBlocked = 90001, ApiResourceIsCurrentlyOverloadedTryAgainALittleLater = 130000, } From b889b518adc4554db02b98de46a6d900483837aa Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sat, 1 May 2021 11:53:37 +0200 Subject: [PATCH 18/72] add: missing twofactor error code --- src/types/codes/json_error_codes.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/types/codes/json_error_codes.ts b/src/types/codes/json_error_codes.ts index 39c24c1a2..906828b3d 100644 --- a/src/types/codes/json_error_codes.ts +++ b/src/types/codes/json_error_codes.ts @@ -82,6 +82,7 @@ export enum DiscordJsonErrorCodes { 50083, InvalidThreadNotificationSettings, BeforeValueIsEarlierThanTheThreadCreationDate, + TwoFactorIsRequiredForThisOperation = 60003, ReqctionWasBlocked = 90001, ApiResourceIsCurrentlyOverloadedTryAgainALittleLater = 130000, } From 58edfac3b6851f0dcce9b3364b85ca322bac4160 Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sat, 1 May 2021 16:03:41 +0200 Subject: [PATCH 19/72] add: new thread perms --- src/types/permissions/bitwise_permission_flags.ts | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/types/permissions/bitwise_permission_flags.ts b/src/types/permissions/bitwise_permission_flags.ts index cd539e5d0..c76891e99 100644 --- a/src/types/permissions/bitwise_permission_flags.ts +++ b/src/types/permissions/bitwise_permission_flags.ts @@ -65,7 +65,13 @@ export enum DiscordBitwisePermissionFlags { /** Allows members to use slash commands in text channels */ USE_SLASH_COMMANDS = 0x80000000, /** Allows for requesting to speak in stage channels. */ - REQUEST_TO_SPEAK = 0x100000000, + REQUEST_TO_SPEAK = 0x100000001, + /** Allows for deleting and archiving threads, and viewing all private threads */ + MANAGE_THREADS = 0x0400000000, + /** Allows for creating and participating in threads */ + USE_PUBLIC_THREADS = 0x0800000000, + /** Allows for creating and participating in private threads */ + USE_PRIVATE_THREADS = 0x1000000000, } export type BitwisePermissions = DiscordBitwisePermissionFlags; From bd11f3fcd0b3c10d17769261f1a4b74e81beb6a6 Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sat, 1 May 2021 16:06:55 +0200 Subject: [PATCH 20/72] change: gateway version --- src/util/constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/constants.ts b/src/util/constants.ts index 072e42d4a..9e65c1929 100644 --- a/src/util/constants.ts +++ b/src/util/constants.ts @@ -5,7 +5,7 @@ export const BASE_URL = "https://discord.com/api"; export const API_VERSION = 9; /** https://discord.com/developers/docs/topics/gateway#gateways-gateway-versions */ -export const GATEWAY_VERSION = 8; +export const GATEWAY_VERSION = 9; // TODO: update this version /** https://github.com/discordeno/discordeno/releases */ From c80abf344ba9a53d150a781b11d6a5d6b448b185 Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sat, 1 May 2021 16:07:31 +0200 Subject: [PATCH 21/72] add: ThreadMembersUpdate --- src/types/channels/thread_members_update.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 src/types/channels/thread_members_update.ts diff --git a/src/types/channels/thread_members_update.ts b/src/types/channels/thread_members_update.ts new file mode 100644 index 000000000..8d3331683 --- /dev/null +++ b/src/types/channels/thread_members_update.ts @@ -0,0 +1,15 @@ +import { ThreadMember } from "../messages/thread_member.ts"; + +// TODO: add docs link +export interface ThreadMembersUpdate { + /** The id of the thread */ + id: string; + /** The id of the guild */ + guildId: string; + /** The approximate number of members in the thread, capped at 50 */ + memberCount: number; + /** The users who were added to the thread */ + addedMembers?: ThreadMember[]; + /** The id of the users who were removed from the thread */ + removedMemberIds?: string[]; +} From 642cf58bae72809dbb25fe73b39816e47710e1dc Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sat, 1 May 2021 16:08:07 +0200 Subject: [PATCH 22/72] remove: v for dd version --- src/util/constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/constants.ts b/src/util/constants.ts index 9e65c1929..90bb371ec 100644 --- a/src/util/constants.ts +++ b/src/util/constants.ts @@ -9,7 +9,7 @@ export const GATEWAY_VERSION = 9; // TODO: update this version /** https://github.com/discordeno/discordeno/releases */ -export const DISCORDENO_VERSION = "v11.0.0"; +export const DISCORDENO_VERSION = "11.0.0"; /** https://discord.com/developers/docs/reference#user-agent */ export const USER_AGENT = From cff1b61af5496e877edeb579b59b8b4c968726b9 Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sat, 1 May 2021 18:35:19 +0200 Subject: [PATCH 23/72] fix channel permission thing --- src/helpers/channels/clone_channel.ts | 4 +-- src/helpers/channels/create_channel.ts | 22 +++++---------- src/helpers/channels/edit_channel.ts | 13 +++++++-- src/util/permissions.ts | 38 ++++++++++++++++++-------- 4 files changed, 46 insertions(+), 31 deletions(-) diff --git a/src/helpers/channels/clone_channel.ts b/src/helpers/channels/clone_channel.ts index e84e039e0..d523572cf 100644 --- a/src/helpers/channels/clone_channel.ts +++ b/src/helpers/channels/clone_channel.ts @@ -13,8 +13,8 @@ export async function cloneChannel(channelId: string, reason?: string) { //Check for DM channel if ( - channelToClone.type === DiscordChannelTypes.DM || - channelToClone.type === DiscordChannelTypes.GROUP_DM + channelToClone.type === DiscordChannelTypes.Dm || + channelToClone.type === DiscordChannelTypes.GroupDm ) { throw new Error(Errors.CHANNEL_NOT_IN_GUILD); } diff --git a/src/helpers/channels/create_channel.ts b/src/helpers/channels/create_channel.ts index 9d675ed60..699881c5a 100644 --- a/src/helpers/channels/create_channel.ts +++ b/src/helpers/channels/create_channel.ts @@ -1,4 +1,3 @@ -import { eventHandlers } from "../../bot.ts"; import { cacheHandlers } from "../../cache.ts"; import { rest } from "../../rest/rest.ts"; import { structures } from "../../structures/mod.ts"; @@ -8,11 +7,10 @@ import { CreateGuildChannel, DiscordCreateGuildChannel, } from "../../types/guilds/create_guild_channel.ts"; -import { PermissionStrings } from "../../types/permissions/permission_strings.ts"; import { endpoints } from "../../util/constants.ts"; import { calculateBits, - requireBotGuildPermissions, + requireOverwritePermissions, } from "../../util/permissions.ts"; import { camelKeysToSnakeCase } from "../../util/utils.ts"; @@ -22,18 +20,12 @@ export async function createChannel( options?: CreateGuildChannel, reason?: string, ) { - const requiredPerms: Set = new Set(["MANAGE_CHANNELS"]); - - options?.permissionOverwrites?.forEach((overwrite) => { - eventHandlers.debug?.( - "loop", - `Running forEach loop in create_channel file.`, + if (options?.permissionOverwrites) { + await requireOverwritePermissions( + guildId, + options.permissionOverwrites, ); - overwrite.allow.forEach(requiredPerms.add, requiredPerms); - overwrite.deny.forEach(requiredPerms.add, requiredPerms); - }); - - await requireBotGuildPermissions(guildId, [...requiredPerms]); + } // BITRATES ARE IN THOUSANDS SO IF USER PROVIDES 32 WE CONVERT TO 32000 if (options?.bitrate && options.bitrate < 1000) options.bitrate *= 1000; @@ -48,7 +40,7 @@ export async function createChannel( allow: calculateBits(perm.allow), deny: calculateBits(perm.deny), })), - type: options?.type || DiscordChannelTypes.GUILD_TEXT, + type: options?.type || DiscordChannelTypes.GuildText, reason, }, ); diff --git a/src/helpers/channels/edit_channel.ts b/src/helpers/channels/edit_channel.ts index dfb064c7d..89b95f2ae 100644 --- a/src/helpers/channels/edit_channel.ts +++ b/src/helpers/channels/edit_channel.ts @@ -1,20 +1,27 @@ import { eventHandlers } from "../../bot.ts"; +import { cacheHandlers } from "../../cache.ts"; import { rest } from "../../rest/rest.ts"; import { ModifyChannel } from "../../types/channels/modify_channel.ts"; import { Channel } from "../../types/mod.ts"; import { endpoints } from "../../util/constants.ts"; import { calculateBits, - requireBotChannelPermissions, + requireOverwritePermissions, } from "../../util/permissions.ts"; - +//TODO: implement DM group channel edit /** Update a channel's settings. Requires the `MANAGE_CHANNELS` permission for the guild. */ export async function editChannel( channelId: string, options: ModifyChannel, reason?: string, ) { - await requireBotChannelPermissions(channelId, ["MANAGE_CHANNELS"]); + const channel = await cacheHandlers.get("channels", channelId); + if (channel?.guildId) { + await requireOverwritePermissions( + channel.guildId, + options.permissionOverwrites || [], + ); + } if (options.name || options.topic) { const request = editChannelNameTopicQueue.get(channelId); diff --git a/src/util/permissions.ts b/src/util/permissions.ts index 90e187562..2a2bf61b5 100644 --- a/src/util/permissions.ts +++ b/src/util/permissions.ts @@ -4,6 +4,7 @@ import { DiscordenoChannel } from "../structures/channel.ts"; import { DiscordenoGuild } from "../structures/guild.ts"; import { DiscordenoMember } from "../structures/member.ts"; import { DiscordenoRole } from "../structures/role.ts"; +import { Overwrite } from "../types/channels/overwrite.ts"; import { Errors } from "../types/misc/errors.ts"; import { DiscordBitwisePermissionFlags } from "../types/permissions/bitwise_permission_flags.ts"; import { PermissionStrings } from "../types/permissions/permission_strings.ts"; @@ -28,11 +29,6 @@ async function getCached( ? // @ts-ignore TS is wrong here await cacheHandlers.get(table, key) : key; - if (!cached || typeof cached === "string") { - throw new Error( - Errors[`${table.slice(0, -1).toUpperCase()}_NOT_FOUND` as Errors], - ); - } return typeof cached === "string" ? undefined : cached; } @@ -50,7 +46,7 @@ export async function calculateBasePermissions( let permissions = 0n; // Calculate the role permissions bits, @everyone role is not in memberRoleIds so we need to pass guildId manualy permissions |= [...(member.guilds.get(guild.id)?.roles || []), guild.id] - .map((id) => (guild as DiscordenoGuild).roles.get(id)?.permissions) + .map((id) => guild.roles.get(id)?.permissions) // Removes any edge case undefined .filter((perm) => perm) .reduce((bits, perms) => { @@ -76,7 +72,7 @@ export async function calculateChannelOverwrites( const member = await getCached("members", memberOrId); - if (!member) return "8"; + if (!channel || !member) return "8"; // Get all the role permissions this member already has let permissions = BigInt( @@ -84,7 +80,7 @@ export async function calculateChannelOverwrites( ); // First calculate @everyone overwrites since these have the lowest priority - const overwriteEveryone = channel?.permissionOverwrites?.find( + const overwriteEveryone = channel.permissionOverwrites.find( (overwrite) => overwrite.id === (channel as DiscordenoChannel).guildId, ); if (overwriteEveryone) { @@ -93,7 +89,7 @@ export async function calculateChannelOverwrites( permissions |= BigInt(overwriteEveryone.allow); } - const overwrites = channel?.permissionOverwrites; + const overwrites = channel.permissionOverwrites; // In order to calculate the role permissions correctly we need to temporarily save the allowed and denied permissions let allow = 0n; @@ -111,8 +107,8 @@ export async function calculateChannelOverwrites( permissions |= allow; // Third calculate member specific overwrites since these have the highest priority - const overwriteMember = overwrites?.find( - (overwrite) => overwrite.id === (member as DiscordenoMember).id, + const overwriteMember = overwrites.find( + (overwrite) => overwrite.id === member.id, ); if (overwriteMember) { permissions &= ~BigInt(overwriteMember.deny); @@ -290,6 +286,26 @@ export function calculateBits(permissions: PermissionStrings[]) { .toString(); } +/** Internal function to check if the bot has the permissions to set these overwrites */ +export async function requireOverwritePermissions( + guildOrId: string | DiscordenoGuild, + overwrites: Overwrite[], +) { + let requiredPerms: Set = new Set(["MANAGE_CHANNELS"]); + + overwrites?.forEach((overwrite) => { + overwrite.allow.forEach(requiredPerms.add, requiredPerms); + overwrite.deny.forEach(requiredPerms.add, requiredPerms); + }); + + // MANAGE_ROLES permission can only be set by administrators + if (requiredPerms.has("MANAGE_ROLES")) { + requiredPerms = new Set(["ADMINISTRATOR"]); + } + + await requireGuildPermissions(guildOrId, botId, [...requiredPerms]); +} + /** Gets the highest role from the member in this guild */ export async function highestRole( guildOrId: string | DiscordenoGuild, From 8032133ad44f0b8fa71601d1952a4d7ef104bfec Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sat, 1 May 2021 18:35:27 +0200 Subject: [PATCH 24/72] Update permissions.ts --- src/util/permissions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/permissions.ts b/src/util/permissions.ts index 2a2bf61b5..c7290c0b5 100644 --- a/src/util/permissions.ts +++ b/src/util/permissions.ts @@ -81,7 +81,7 @@ export async function calculateChannelOverwrites( // First calculate @everyone overwrites since these have the lowest priority const overwriteEveryone = channel.permissionOverwrites.find( - (overwrite) => overwrite.id === (channel as DiscordenoChannel).guildId, + (overwrite) => overwrite.id === channel.guildId, ); if (overwriteEveryone) { // First remove denied permissions since denied < allowed From 51095db12fe9180d63ae101ebfab98be9334211d Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sat, 1 May 2021 18:39:20 +0200 Subject: [PATCH 25/72] fix my renaming thing --- src/handlers/channels/CHANNEL_DELETE.ts | 2 +- src/helpers/channels/start_typing.ts | 6 +++--- src/helpers/messages/send_message.ts | 6 +++--- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/handlers/channels/CHANNEL_DELETE.ts b/src/handlers/channels/CHANNEL_DELETE.ts index f4c07229f..8da02b9a0 100644 --- a/src/handlers/channels/CHANNEL_DELETE.ts +++ b/src/handlers/channels/CHANNEL_DELETE.ts @@ -11,7 +11,7 @@ export async function handleChannelDelete(data: DiscordGatewayPayload) { if (!cachedChannel) return; if ( - cachedChannel.type === DiscordChannelTypes.GUILD_VOICE && payload.guildId + cachedChannel.type === DiscordChannelTypes.GuildVoice && payload.guildId ) { const guild = await cacheHandlers.get("guilds", payload.guildId); diff --git a/src/helpers/channels/start_typing.ts b/src/helpers/channels/start_typing.ts index 013ad46e2..4bd2b5163 100644 --- a/src/helpers/channels/start_typing.ts +++ b/src/helpers/channels/start_typing.ts @@ -16,9 +16,9 @@ export async function startTyping(channelId: string) { if (channel) { if ( ![ - DiscordChannelTypes.DM, - DiscordChannelTypes.GUILD_NEWS, - DiscordChannelTypes.GUILD_TEXT, + DiscordChannelTypes.Dm, + DiscordChannelTypes.GuildNews, + DiscordChannelTypes.GuildText, ].includes(channel.type) ) { throw new Error(Errors.CHANNEL_NOT_TEXT_BASED); diff --git a/src/helpers/messages/send_message.ts b/src/helpers/messages/send_message.ts index 87dd3eb20..716d079d5 100644 --- a/src/helpers/messages/send_message.ts +++ b/src/helpers/messages/send_message.ts @@ -26,9 +26,9 @@ export async function sendMessage( if (channel) { if ( ![ - DiscordChannelTypes.DM, - DiscordChannelTypes.GUILD_NEWS, - DiscordChannelTypes.GUILD_TEXT, + DiscordChannelTypes.Dm, + DiscordChannelTypes.GuildNews, + DiscordChannelTypes.GuildText, ].includes(channel.type) ) { throw new Error(Errors.CHANNEL_NOT_TEXT_BASED); From eda4895da32d2d4366b47a4711dd5255dd17e0f4 Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sat, 1 May 2021 18:42:46 +0200 Subject: [PATCH 26/72] more fixxes --- src/types/channels/channel_types.ts | 2 +- tests/channels/category_children.ts | 6 ++--- .../channel_overwrite_has_permission.ts | 2 +- tests/channels/clone_channel.ts | 8 +++--- tests/channels/create_channel.ts | 26 +++++++++---------- tests/channels/delete_channel_overwrite.ts | 2 +- tests/channels/edit_channel_overwrite.ts | 2 +- tests/channels/is_channel_synced.ts | 10 +++---- 8 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/types/channels/channel_types.ts b/src/types/channels/channel_types.ts index 7c0b9247d..26a3ce5e4 100644 --- a/src/types/channels/channel_types.ts +++ b/src/types/channels/channel_types.ts @@ -21,7 +21,7 @@ export enum DiscordChannelTypes { /** A temporary sub-channel within a GUILD_TEXT channel that is only viewable by those invited and those with the MANAGE_THREADS permission */ GuildPivateThread, /** A voice channel for hosting events with an audience */ - GUILD_STAGE_VOICE = 13, + GuildStageVoice = 13, } export type ChannelTypes = DiscordChannelTypes; diff --git a/tests/channels/category_children.ts b/tests/channels/category_children.ts index 1c5b6d555..78901d894 100644 --- a/tests/channels/category_children.ts +++ b/tests/channels/category_children.ts @@ -1,16 +1,16 @@ -import { defaultTestOptions, tempData } from "../ws/start_bot.ts"; -import { assertExists } from "../deps.ts"; import { cache } from "../../src/cache.ts"; import { categoryChildren, createChannel } from "../../src/helpers/mod.ts"; import { DiscordChannelTypes } from "../../src/types/channels/channel_types.ts"; +import { assertExists } from "../deps.ts"; import { delayUntil } from "../util/delay_until.ts"; +import { defaultTestOptions, tempData } from "../ws/start_bot.ts"; Deno.test({ name: "[channel] category channel ids", async fn() { const category = await createChannel(tempData.guildId, { name: "Discordeno-test", - type: DiscordChannelTypes.GUILD_CATEGORY, + type: DiscordChannelTypes.GuildCategory, }); // Assertions diff --git a/tests/channels/channel_overwrite_has_permission.ts b/tests/channels/channel_overwrite_has_permission.ts index 55319ac60..d8d9dd367 100644 --- a/tests/channels/channel_overwrite_has_permission.ts +++ b/tests/channels/channel_overwrite_has_permission.ts @@ -15,7 +15,7 @@ async function ifItFailsBlameWolf(options: CreateGuildChannel, _save = false) { // Assertions assertExists(channel); - assertEquals(channel.type, options.type || DiscordChannelTypes.GUILD_TEXT); + assertEquals(channel.type, options.type || DiscordChannelTypes.GuildText); // Delay the execution by 5 seconds to allow CHANNEL_CREATE event to be processed await delayUntil(10000, () => cache.channels.has(channel.id)); diff --git a/tests/channels/clone_channel.ts b/tests/channels/clone_channel.ts index 4708d6687..ca639abb6 100644 --- a/tests/channels/clone_channel.ts +++ b/tests/channels/clone_channel.ts @@ -61,7 +61,7 @@ Deno.test({ await ifItFailsBlameWolf( { name: "Discordeno-clone-test", - type: DiscordChannelTypes.GUILD_CATEGORY, + type: DiscordChannelTypes.GuildCategory, }, false, ); @@ -75,7 +75,7 @@ Deno.test({ await ifItFailsBlameWolf( { name: "Discordeno-clone-test", - type: DiscordChannelTypes.GUILD_VOICE, + type: DiscordChannelTypes.GuildVoice, }, false, ); @@ -89,7 +89,7 @@ Deno.test({ await ifItFailsBlameWolf( { name: "discordeno-clone-test", - type: DiscordChannelTypes.GUILD_VOICE, + type: DiscordChannelTypes.GuildVoice, bitrate: 32000, }, false, @@ -104,7 +104,7 @@ Deno.test({ await ifItFailsBlameWolf( { name: "Discordeno-clone-test", - type: DiscordChannelTypes.GUILD_VOICE, + type: DiscordChannelTypes.GuildVoice, userLimit: 32, }, false, diff --git a/tests/channels/create_channel.ts b/tests/channels/create_channel.ts index 02c952fb4..f01fd7b31 100644 --- a/tests/channels/create_channel.ts +++ b/tests/channels/create_channel.ts @@ -1,19 +1,19 @@ -import { defaultTestOptions, tempData } from "../ws/start_bot.ts"; -import { assertEquals, assertExists } from "../deps.ts"; -import { cache } from "../../src/cache.ts"; -import { DiscordChannelTypes } from "../../src/types/channels/channel_types.ts"; -import { CreateGuildChannel } from "../../src/types/guilds/create_guild_channel.ts"; -import { createChannel } from "../../src/helpers/channels/create_channel.ts"; -import { delayUntil } from "../util/delay_until.ts"; -import { DiscordOverwriteTypes } from "../../src/types/channels/overwrite_types.ts"; import { botId } from "../../src/bot.ts"; +import { cache } from "../../src/cache.ts"; +import { createChannel } from "../../src/helpers/channels/create_channel.ts"; +import { DiscordChannelTypes } from "../../src/types/channels/channel_types.ts"; +import { DiscordOverwriteTypes } from "../../src/types/channels/overwrite_types.ts"; +import { CreateGuildChannel } from "../../src/types/guilds/create_guild_channel.ts"; +import { assertEquals, assertExists } from "../deps.ts"; +import { delayUntil } from "../util/delay_until.ts"; +import { defaultTestOptions, tempData } from "../ws/start_bot.ts"; async function ifItFailsBlameWolf(options: CreateGuildChannel, save = false) { const channel = await createChannel(tempData.guildId, options); // Assertions assertExists(channel); - assertEquals(channel.type, options.type || DiscordChannelTypes.GUILD_TEXT); + assertEquals(channel.type, options.type || DiscordChannelTypes.GuildText); if (save) tempData.channelId = channel.id; @@ -60,7 +60,7 @@ Deno.test({ await ifItFailsBlameWolf( { name: "Discordeno-test", - type: DiscordChannelTypes.GUILD_CATEGORY, + type: DiscordChannelTypes.GuildCategory, }, true, ); @@ -90,7 +90,7 @@ Deno.test({ await ifItFailsBlameWolf( { name: "Discordeno-test", - type: DiscordChannelTypes.GUILD_VOICE, + type: DiscordChannelTypes.GuildVoice, }, true, ); @@ -104,7 +104,7 @@ Deno.test({ await ifItFailsBlameWolf( { name: "discordeno-test", - type: DiscordChannelTypes.GUILD_VOICE, + type: DiscordChannelTypes.GuildVoice, bitrate: 32000, }, true, @@ -119,7 +119,7 @@ Deno.test({ await ifItFailsBlameWolf( { name: "Discordeno-test", - type: DiscordChannelTypes.GUILD_VOICE, + type: DiscordChannelTypes.GuildVoice, userLimit: 32, }, true, diff --git a/tests/channels/delete_channel_overwrite.ts b/tests/channels/delete_channel_overwrite.ts index acf63c7a9..8b5b4f02a 100644 --- a/tests/channels/delete_channel_overwrite.ts +++ b/tests/channels/delete_channel_overwrite.ts @@ -14,7 +14,7 @@ async function ifItFailsBlameWolf(options: CreateGuildChannel, _save = false) { // Assertions assertExists(channel); - assertEquals(channel.type, options.type || DiscordChannelTypes.GUILD_TEXT); + assertEquals(channel.type, options.type || DiscordChannelTypes.GuildText); // Delay the execution by 5 seconds to allow CHANNEL_CREATE event to be processed await delayUntil(10000, () => cache.channels.has(channel.id)); diff --git a/tests/channels/edit_channel_overwrite.ts b/tests/channels/edit_channel_overwrite.ts index f8a9ad241..1ed56a038 100644 --- a/tests/channels/edit_channel_overwrite.ts +++ b/tests/channels/edit_channel_overwrite.ts @@ -16,7 +16,7 @@ async function ifItFailsBlameWolf(options: CreateGuildChannel, _save = false) { // Assertions assertExists(channel); - assertEquals(channel.type, options.type || DiscordChannelTypes.GUILD_TEXT); + assertEquals(channel.type, options.type || DiscordChannelTypes.GuildText); // Delay the execution by 5 seconds to allow CHANNEL_CREATE event to be processed await delayUntil(10000, () => cache.channels.has(channel.id)); diff --git a/tests/channels/is_channel_synced.ts b/tests/channels/is_channel_synced.ts index eac621f6a..78f9c30a7 100644 --- a/tests/channels/is_channel_synced.ts +++ b/tests/channels/is_channel_synced.ts @@ -1,19 +1,19 @@ +import { botId } from "../../src/bot.ts"; import { cache } from "../../src/cache.ts"; import { createChannel } from "../../src/helpers/channels/create_channel.ts"; -import { defaultTestOptions, tempData } from "../ws/start_bot.ts"; -import { delayUntil } from "../util/delay_until.ts"; -import { assertEquals, assertExists } from "../deps.ts"; import { isChannelSynced } from "../../src/helpers/channels/is_channel_synced.ts"; import { DiscordChannelTypes } from "../../src/types/channels/channel_types.ts"; -import { botId } from "../../src/bot.ts"; import { DiscordOverwriteTypes } from "../../src/types/channels/overwrite_types.ts"; +import { assertEquals, assertExists } from "../deps.ts"; +import { delayUntil } from "../util/delay_until.ts"; +import { defaultTestOptions, tempData } from "../ws/start_bot.ts"; Deno.test({ name: "[channel] is channel synced.", async fn() { const category = await createChannel(tempData.guildId, { name: "synced-category", - type: DiscordChannelTypes.GUILD_CATEGORY, + type: DiscordChannelTypes.GuildCategory, permissionOverwrites: [ { id: botId, From 152654bd448c2b7c9cfd6f729d3982f62bc4333f Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sat, 1 May 2021 18:48:40 +0200 Subject: [PATCH 27/72] only run coverage report for main branch --- .github/workflows/test.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index cfbb40471..ac5e2dbe1 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -23,8 +23,10 @@ jobs: if: ${{ github.event_name == 'pull_request' && github.event.action == 'labeled' && github.event.label.name == 'run-tests' }} run: DISCORD_TOKEN=${{ secrets.DISCORD_TOKEN }} deno test --unstable --coverage=coverage --allow-net tests/mod.ts - name: Create coverage report + if: github.ref == 'refs/heads/main' run: deno --unstable coverage ./coverage --lcov > coverage.lcov - name: Collect and upload the coverage report + if: github.ref == 'refs/heads/main' uses: codecov/codecov-action@v1.0.10 with: file: ./coverage.lcov From b0758e7094671e08e57c473d823f17e073073233 Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sat, 1 May 2021 22:38:41 +0200 Subject: [PATCH 28/72] Update permissions.ts --- src/util/permissions.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/util/permissions.ts b/src/util/permissions.ts index c7290c0b5..44ca9dd7a 100644 --- a/src/util/permissions.ts +++ b/src/util/permissions.ts @@ -80,7 +80,7 @@ export async function calculateChannelOverwrites( ); // First calculate @everyone overwrites since these have the lowest priority - const overwriteEveryone = channel.permissionOverwrites.find( + const overwriteEveryone = channel.permissionOverwrites?.find( (overwrite) => overwrite.id === channel.guildId, ); if (overwriteEveryone) { @@ -107,7 +107,7 @@ export async function calculateChannelOverwrites( permissions |= allow; // Third calculate member specific overwrites since these have the highest priority - const overwriteMember = overwrites.find( + const overwriteMember = overwrites?.find( (overwrite) => overwrite.id === member.id, ); if (overwriteMember) { From 9cd6b963da4f3c1730fe8150a25a7f96f87f5a8b Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sat, 1 May 2021 22:38:49 +0200 Subject: [PATCH 29/72] add: hasOwnProperty --- src/util/utils.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/util/utils.ts b/src/util/utils.ts index 6a2b9a240..0b64e826f 100644 --- a/src/util/utils.ts +++ b/src/util/utils.ts @@ -204,3 +204,13 @@ export function validateSlashCommands( } } } + +// Typescript is not so good as we developers so we need this little utility function to help it out +// Taken from https://fettblog.eu/typescript-hasownproperty/ +/** TS save way to check if a property exists in an object */ +export function hasOwnProperty( + obj: T, + prop: Y, +): obj is T & Record { + return obj.hasOwnProperty(prop); +} From d60ccae805741363c804aa77dfef38b5ecd07cb6 Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sat, 1 May 2021 23:35:43 +0200 Subject: [PATCH 30/72] fix(types): channel.permissionOverwrites can be undefined --- src/helpers/channels/clone_channel.ts | 2 +- src/structures/channel.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/helpers/channels/clone_channel.ts b/src/helpers/channels/clone_channel.ts index d523572cf..d881a5373 100644 --- a/src/helpers/channels/clone_channel.ts +++ b/src/helpers/channels/clone_channel.ts @@ -24,7 +24,7 @@ export async function cloneChannel(channelId: string, reason?: string) { name: channelToClone.name!, topic: channelToClone.topic || undefined, parentId: channelToClone.parentId || undefined, - permissionOverwrites: channelToClone.permissionOverwrites.map(( + permissionOverwrites: channelToClone.permissionOverwrites?.map(( overwrite, ) => ({ id: overwrite.id, diff --git a/src/structures/channel.ts b/src/structures/channel.ts index b71bfc596..b20da7122 100644 --- a/src/structures/channel.ts +++ b/src/structures/channel.ts @@ -109,7 +109,7 @@ export async function createDiscordenoChannel( export interface DiscordenoChannel extends Omit { - permissionOverwrites: DiscordOverwrite[]; + permissionOverwrites?: DiscordOverwrite[]; guildId: string; // GETTERS From 8840ed5662886a8393545096a922017ee4edb2b7 Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sat, 1 May 2021 23:36:17 +0200 Subject: [PATCH 31/72] changed: moved thread types to channel/threads --- .../channels/{ => threads}/list_active_threads.ts | 0 .../{ => threads}/list_public_archived_threads.ts | 0 src/types/channels/{ => threads}/modify_thread.ts | 0 src/types/channels/{ => threads}/start_thread.ts | 0 .../channels/{ => threads}/thread_list_sync.ts | 0 src/types/channels/threads/thread_member.ts | 10 ++++++++++ .../channels/{ => threads}/thread_members_update.ts | 0 src/types/channels/threads/thread_metadata.ts | 13 +++++++++++++ 8 files changed, 23 insertions(+) rename src/types/channels/{ => threads}/list_active_threads.ts (100%) rename src/types/channels/{ => threads}/list_public_archived_threads.ts (100%) rename src/types/channels/{ => threads}/modify_thread.ts (100%) rename src/types/channels/{ => threads}/start_thread.ts (100%) rename src/types/channels/{ => threads}/thread_list_sync.ts (100%) create mode 100644 src/types/channels/threads/thread_member.ts rename src/types/channels/{ => threads}/thread_members_update.ts (100%) create mode 100644 src/types/channels/threads/thread_metadata.ts diff --git a/src/types/channels/list_active_threads.ts b/src/types/channels/threads/list_active_threads.ts similarity index 100% rename from src/types/channels/list_active_threads.ts rename to src/types/channels/threads/list_active_threads.ts diff --git a/src/types/channels/list_public_archived_threads.ts b/src/types/channels/threads/list_public_archived_threads.ts similarity index 100% rename from src/types/channels/list_public_archived_threads.ts rename to src/types/channels/threads/list_public_archived_threads.ts diff --git a/src/types/channels/modify_thread.ts b/src/types/channels/threads/modify_thread.ts similarity index 100% rename from src/types/channels/modify_thread.ts rename to src/types/channels/threads/modify_thread.ts diff --git a/src/types/channels/start_thread.ts b/src/types/channels/threads/start_thread.ts similarity index 100% rename from src/types/channels/start_thread.ts rename to src/types/channels/threads/start_thread.ts diff --git a/src/types/channels/thread_list_sync.ts b/src/types/channels/threads/thread_list_sync.ts similarity index 100% rename from src/types/channels/thread_list_sync.ts rename to src/types/channels/threads/thread_list_sync.ts diff --git a/src/types/channels/threads/thread_member.ts b/src/types/channels/threads/thread_member.ts new file mode 100644 index 000000000..2b3d1b54a --- /dev/null +++ b/src/types/channels/threads/thread_member.ts @@ -0,0 +1,10 @@ +export interface ThreadMember { + /** The id of the thread */ + id: string; + /** The id of the user */ + userId: string; + /** The time the current user last joined the thread */ + joinTimestamp: string; + /** Any user-thread settings, currently only used for notifications */ + flags: number; +} diff --git a/src/types/channels/thread_members_update.ts b/src/types/channels/threads/thread_members_update.ts similarity index 100% rename from src/types/channels/thread_members_update.ts rename to src/types/channels/threads/thread_members_update.ts diff --git a/src/types/channels/threads/thread_metadata.ts b/src/types/channels/threads/thread_metadata.ts new file mode 100644 index 000000000..ea67fd966 --- /dev/null +++ b/src/types/channels/threads/thread_metadata.ts @@ -0,0 +1,13 @@ +export interface ThreadMetadata { + /** Whether the thread is archived */ + archived: boolean; + /** Id of the user that last archived or unarchived the thread */ + archiverId?: string; + /** Duration in minutes to automatically archive the thread after recent activity */ + autoArchiveDuration: 60 | 1440 | 4320 | 10080; + // TODO(threads): channel struct should convert this to a unixx + /** Timestamp when the thread's archive status was last changed, used for calculating recent activity */ + archiveTimestamp: string; + /** When a thread is locked, only users with `MANAGE_THREADS` can unarchive it */ + locked?: boolean; +} From 478952d9ebe4094c7d9dddb726c3b9860c176e77 Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sat, 1 May 2021 23:36:59 +0200 Subject: [PATCH 32/72] fix(helpers/messages): sendMessage add new thread types to channel type check --- src/helpers/messages/send_message.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/helpers/messages/send_message.ts b/src/helpers/messages/send_message.ts index 716d079d5..b05d5d424 100644 --- a/src/helpers/messages/send_message.ts +++ b/src/helpers/messages/send_message.ts @@ -29,6 +29,9 @@ export async function sendMessage( DiscordChannelTypes.Dm, DiscordChannelTypes.GuildNews, DiscordChannelTypes.GuildText, + DiscordChannelTypes.GuildPublicThread, + DiscordChannelTypes.GuildPivateThread, + DiscordChannelTypes.GuildNewsThread, ].includes(channel.type) ) { throw new Error(Errors.CHANNEL_NOT_TEXT_BASED); From 8fa98b49706e7a8e8cc585f391932883b01aaeed Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sat, 1 May 2021 23:37:05 +0200 Subject: [PATCH 33/72] Update channel.ts --- src/types/channels/channel.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/types/channels/channel.ts b/src/types/channels/channel.ts index 15caecb29..9277d7366 100644 --- a/src/types/channels/channel.ts +++ b/src/types/channels/channel.ts @@ -1,8 +1,8 @@ -import { ThreadMember } from "../messages/thread_member.ts"; -import { ThreadMetadata } from "../messages/thread_metadata.ts"; import { User } from "../users/user.ts"; import { DiscordChannelTypes } from "./channel_types.ts"; import { Overwrite } from "./overwrite.ts"; +import { ThreadMember } from "./threads/thread_member.ts"; +import { ThreadMetadata } from "./threads/thread_metadata.ts"; import { DiscordVideoQualityModes } from "./video_quality_modes.ts"; /** https://discord.com/developers/docs/resources/channel#channel-object */ @@ -47,6 +47,7 @@ export interface Channel { rtcRegion?: string | null; /** The camera video quality mode of the voice channel, 1 when not present */ videoQualityMode?: DiscordVideoQualityModes; + // TODO(threads): consider a ThreadChannel object /** An approximate count of messages in a thread, stops counting at 50 */ messageCount?: number; /** An approximate count of users in a thread, stops counting at 50 */ From 8a974511c94c4c6cd3461ed9894c57ca8e5ab7a1 Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sat, 1 May 2021 23:37:10 +0200 Subject: [PATCH 34/72] fmt --- src/types/messages/message.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/types/messages/message.ts b/src/types/messages/message.ts index de3956f0a..1cb9d416a 100644 --- a/src/types/messages/message.ts +++ b/src/types/messages/message.ts @@ -1,5 +1,6 @@ import { Channel } from "../channels/channel.ts"; import { ChannelMention } from "../channels/channel_mention.ts"; +import { ThreadMember } from "../channels/threads/thread_member.ts"; import { Embed } from "../embeds/embed.ts"; import { GuildMember } from "../guilds/guild_member.ts"; import { MessageInteraction } from "../interactions/message_interaction.ts"; @@ -12,7 +13,6 @@ import { MessageReference } from "./message_reference.ts"; import { MessageSticker } from "./message_sticker.ts"; import { DiscordMessageTypes } from "./message_types.ts"; import { Reaction } from "./reaction.ts"; -import { ThreadMember } from "./thread_member.ts"; /** https://discord.com/developers/docs/resources/channel#message-object */ export interface Message { From 95fdb6b064173cda675b9dabcef6b92e2a558677 Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sat, 1 May 2021 23:37:19 +0200 Subject: [PATCH 35/72] idk --- src/types/messages/thread_member.ts | 10 ---------- src/types/messages/thread_metadata.ts | 12 ------------ 2 files changed, 22 deletions(-) delete mode 100644 src/types/messages/thread_member.ts delete mode 100644 src/types/messages/thread_metadata.ts diff --git a/src/types/messages/thread_member.ts b/src/types/messages/thread_member.ts deleted file mode 100644 index 2b3d1b54a..000000000 --- a/src/types/messages/thread_member.ts +++ /dev/null @@ -1,10 +0,0 @@ -export interface ThreadMember { - /** The id of the thread */ - id: string; - /** The id of the user */ - userId: string; - /** The time the current user last joined the thread */ - joinTimestamp: string; - /** Any user-thread settings, currently only used for notifications */ - flags: number; -} diff --git a/src/types/messages/thread_metadata.ts b/src/types/messages/thread_metadata.ts deleted file mode 100644 index ce8f40e56..000000000 --- a/src/types/messages/thread_metadata.ts +++ /dev/null @@ -1,12 +0,0 @@ -export interface ThreadMetadata { - /** Whether the thread is archived */ - archived: boolean; - /** Id of the user that last archived or unarchived the thread */ - archiverId?: string; - /** Duration in minutes to automatically archive the thread after recent activity */ - autoArchiveDuration: 60 | 1440 | 4320 | 10080; - /** Timestamp when the thread's archive status was last changed, used for calculating recent activity */ - archiveTimestamp: string; - /** When a thread is locked, only users with `MANAGE_THREADS` can unarchive it */ - locked?: boolean; -} From 9ff0c2c6933b6a49f0c24b759ad0cfe5d88b4abd Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sat, 1 May 2021 23:37:26 +0200 Subject: [PATCH 36/72] Update utils.ts --- src/util/utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/utils.ts b/src/util/utils.ts index 0b64e826f..d2c0a016d 100644 --- a/src/util/utils.ts +++ b/src/util/utils.ts @@ -208,7 +208,7 @@ export function validateSlashCommands( // Typescript is not so good as we developers so we need this little utility function to help it out // Taken from https://fettblog.eu/typescript-hasownproperty/ /** TS save way to check if a property exists in an object */ -export function hasOwnProperty( +export function hasOwnProperty( obj: T, prop: Y, ): obj is T & Record { From 6f7ade244a16f734b0cfbd2b781048b3011bccbe Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sun, 2 May 2021 12:34:47 +0200 Subject: [PATCH 37/72] add: thread channel support --- src/helpers/channels/edit_channel.ts | 82 ++++++++++++++++++++-------- 1 file changed, 60 insertions(+), 22 deletions(-) diff --git a/src/helpers/channels/edit_channel.ts b/src/helpers/channels/edit_channel.ts index 89b95f2ae..3a6e83be1 100644 --- a/src/helpers/channels/edit_channel.ts +++ b/src/helpers/channels/edit_channel.ts @@ -2,28 +2,68 @@ import { eventHandlers } from "../../bot.ts"; import { cacheHandlers } from "../../cache.ts"; import { rest } from "../../rest/rest.ts"; import { ModifyChannel } from "../../types/channels/modify_channel.ts"; -import { Channel } from "../../types/mod.ts"; +import { ModifyThread } from "../../types/channels/threads/modify_thread.ts"; +import { + Channel, + DiscordChannelTypes, + PermissionStrings, +} from "../../types/mod.ts"; import { endpoints } from "../../util/constants.ts"; import { calculateBits, + requireBotChannelPermissions, requireOverwritePermissions, } from "../../util/permissions.ts"; +import { camelKeysToSnakeCase, hasOwnProperty } from "../../util/utils.ts"; + //TODO: implement DM group channel edit /** Update a channel's settings. Requires the `MANAGE_CHANNELS` permission for the guild. */ export async function editChannel( channelId: string, - options: ModifyChannel, + options: ModifyChannel | ModifyThread, reason?: string, ) { const channel = await cacheHandlers.get("channels", channelId); - if (channel?.guildId) { - await requireOverwritePermissions( - channel.guildId, - options.permissionOverwrites || [], - ); + + if (channel) { + if ( + [ + DiscordChannelTypes.GuildNewsThread, + DiscordChannelTypes.GuildPivateThread, + DiscordChannelTypes.GuildPublicThread, + ].includes(channel.type) + ) { + const permissions = new Set(); + + if (hasOwnProperty(options, "archive") && options.archive === false) { + permissions.add("SEND_MESSAGES"); + } + + // TODO(threads): change this to a better check + // hacky way of checking if more is being modified + if (Object.keys(options).length > 1) { + permissions.add("MANAGE_THREADS"); + } + + await requireBotChannelPermissions(channel.parentId ?? "", [ + ...permissions, + ]); + } + + if ( + hasOwnProperty( + options, + "permissionOverwrites", + ) && Array.isArray(options.permissionOverwrites) + ) { + await requireOverwritePermissions( + channel.guildId, + options.permissionOverwrites, + ); + } } - if (options.name || options.topic) { + if (options.name || (options as ModifyChannel).topic) { const request = editChannelNameTopicQueue.get(channelId); if (!request) { // If this hasnt been done before simply add 1 for it @@ -49,21 +89,18 @@ export async function editChannel( } const payload = { - ...options, + ...camelKeysToSnakeCase<{}>(options), // deno-lint-ignore camelcase - rate_limit_per_user: options.rateLimitPerUser, - // deno-lint-ignore camelcase - parent_id: options.parentId, - // deno-lint-ignore camelcase - user_limit: options.userLimit, - // deno-lint-ignore camelcase - permission_overwrites: options.permissionOverwrites?.map((overwrite) => { - return { - ...overwrite, - allow: calculateBits(overwrite.allow), - deny: calculateBits(overwrite.deny), - }; - }), + permission_overwrites: + hasOwnProperty(options, "permissionOverwrites") + ? options.permissionOverwrites?.map((overwrite) => { + return { + ...overwrite, + allow: calculateBits(overwrite.allow), + deny: calculateBits(overwrite.deny), + }; + }) + : undefined, }; return await rest.runMethod( @@ -87,6 +124,7 @@ interface EditChannelRequest { } const editChannelNameTopicQueue = new Map(); + let editChannelProcessing = false; function processEditChannelQueue() { From 64606025ece6014d2f3cab769c45881a33a25bf0 Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sun, 2 May 2021 13:37:07 +0200 Subject: [PATCH 38/72] add: delete thread functionality --- src/helpers/channels/delete_channel.ts | 33 ++++++++++++++++++-------- 1 file changed, 23 insertions(+), 10 deletions(-) diff --git a/src/helpers/channels/delete_channel.ts b/src/helpers/channels/delete_channel.ts index d934c8944..23441cb1c 100644 --- a/src/helpers/channels/delete_channel.ts +++ b/src/helpers/channels/delete_channel.ts @@ -1,26 +1,39 @@ import { cacheHandlers } from "../../cache.ts"; import { rest } from "../../rest/rest.ts"; import { Errors } from "../../types/misc/errors.ts"; +import { ChannelTypes } from "../../types/mod.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. */ export async function deleteChannel( - guildId: string, channelId: string, reason?: string, -): Promise { - await requireBotGuildPermissions(guildId, ["MANAGE_CHANNELS"]); +) { + const channel = await cacheHandlers.get("channels", channelId); - const guild = await cacheHandlers.get("guilds", guildId); - if (!guild) throw new Error(Errors.GUILD_NOT_FOUND); + if (channel?.guildId) { + const guild = await cacheHandlers.get("guilds", channel.guildId); + if (!guild) throw new Error(Errors.GUILD_NOT_FOUND); - if (guild?.rulesChannelId === channelId) { - throw new Error(Errors.RULES_CHANNEL_CANNOT_BE_DELETED); - } + // TODO(threads): check if this requires guild perms or channel is enough + await requireBotGuildPermissions( + guild, + [ + ChannelTypes.GuildNewsThread, + ChannelTypes.GuildPivateThread, + ChannelTypes.GuildPublicThread, + ].includes(channel.type) + ? ["MANAGE_THREADS"] + : ["MANAGE_CHANNELS"], + ); + if (guild.rulesChannelId === channelId) { + throw new Error(Errors.RULES_CHANNEL_CANNOT_BE_DELETED); + } - if (guild?.publicUpdatesChannelId === channelId) { - throw new Error(Errors.UPDATES_CHANNEL_CANNOT_BE_DELETED); + if (guild.publicUpdatesChannelId === channelId) { + throw new Error(Errors.UPDATES_CHANNEL_CANNOT_BE_DELETED); + } } return await rest.runMethod( From 86af3a089cbd3e73ac74a6e652dc89af6504d9f3 Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sun, 2 May 2021 13:42:15 +0200 Subject: [PATCH 39/72] add: START_THREAD endpoint --- src/util/constants.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/util/constants.ts b/src/util/constants.ts index 90bb371ec..fae7f4e48 100644 --- a/src/util/constants.ts +++ b/src/util/constants.ts @@ -78,6 +78,10 @@ export const endpoints = { // Bots SHALL NOT use this endpoint but they can CHANNEL_TYPING: (channelId: string) => `${CHANNEL_BASE(channelId)}/typing`, + // Thread Endpoints + START_THREAD: (channelId: string, messageId: string) => + `${endpoints.CHANNEL_MESSAGE(channelId, messageId)}/threads`, + // Guild Endpoints GUILDS: `${baseEndpoints.BASE_URL}/guilds`, GUILD_AUDIT_LOGS: (guildId: string) => `${GUILDS_BASE(guildId)}/audit-logs`, From b5f5b0caf6cf21b8ca1fec02ce4f63fbdc2fd7d5 Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sun, 2 May 2021 14:39:27 +0200 Subject: [PATCH 40/72] add: more thread endpoints --- src/util/constants.ts | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/util/constants.ts b/src/util/constants.ts index fae7f4e48..c5a566383 100644 --- a/src/util/constants.ts +++ b/src/util/constants.ts @@ -79,8 +79,26 @@ export const endpoints = { CHANNEL_TYPING: (channelId: string) => `${CHANNEL_BASE(channelId)}/typing`, // Thread Endpoints - START_THREAD: (channelId: string, messageId: string) => + THREAD_START_PUBLIC: (channelId: string, messageId: string) => `${endpoints.CHANNEL_MESSAGE(channelId, messageId)}/threads`, + THREAD_START_PRIVATE: (channelId: string) => + `${CHANNEL_BASE(channelId)}/threads`, + THREAD_ACTIVE: (channelId: string) => + `${CHANNEL_BASE(channelId)}/threads/active`, + THREAD_MEMBERS: (channelId: string) => + `${CHANNEL_BASE(channelId)}/thread-members`, + THREAD_ME: (channelId: string) => + `${endpoints.THREAD_MEMBERS(channelId)}/@me`, + THREAD_USER: (channelId: string, userId: string) => + `${endpoints.THREAD_MEMBERS(channelId)}/${userId}`, + THREAD_ARCHIVED_BASE: (channelId: string) => + `${CHANNEL_BASE(channelId)}/archived`, + THREAD_ARCHIVED_PUBLIC: (channelId: string) => + `${endpoints.THREAD_ARCHIVED_BASE(channelId)}/public`, + THREAD_ARCHIVED_PRIVATE: (channelId: string) => + `${endpoints.THREAD_ARCHIVED_BASE(channelId)}/private`, + THREAD_ARCHIVED_PRIVATE_JOINED: (channelId: string) => + `${CHANNEL_BASE(channelId)}/users/@me/threads/archived/private`, // Guild Endpoints GUILDS: `${baseEndpoints.BASE_URL}/guilds`, From 02b9d7188f98ea81e2a1c841839c291bd1029780 Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sun, 2 May 2021 16:35:11 +0200 Subject: [PATCH 41/72] Update edit_channel.ts --- src/helpers/channels/edit_channel.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/helpers/channels/edit_channel.ts b/src/helpers/channels/edit_channel.ts index 3a6e83be1..cc8119c81 100644 --- a/src/helpers/channels/edit_channel.ts +++ b/src/helpers/channels/edit_channel.ts @@ -17,6 +17,7 @@ import { import { camelKeysToSnakeCase, hasOwnProperty } from "../../util/utils.ts"; //TODO: implement DM group channel edit +//TODO(threads): check thread perms /** Update a channel's settings. Requires the `MANAGE_CHANNELS` permission for the guild. */ export async function editChannel( channelId: string, From 4faeab8bac8145c2b074bc9ee3a9c74b9bd677ea Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sun, 2 May 2021 16:35:26 +0200 Subject: [PATCH 42/72] add: startThread --- src/helpers/channels/threads/start_thread.ts | 38 ++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 src/helpers/channels/threads/start_thread.ts diff --git a/src/helpers/channels/threads/start_thread.ts b/src/helpers/channels/threads/start_thread.ts new file mode 100644 index 000000000..5fe429c22 --- /dev/null +++ b/src/helpers/channels/threads/start_thread.ts @@ -0,0 +1,38 @@ +import { cacheHandlers } from "../../../cache.ts"; +import { rest } from "../../../rest/rest.ts"; +import { ChannelTypes } from "../../../types/channels/channel_types.ts"; +import { StartThread } from "../../../types/channels/threads/start_thread.ts"; +import { Errors } from "../../../types/misc/errors.ts"; +import { endpoints } from "../../../util/constants.ts"; +import { camelKeysToSnakeCase } from "../../../util/utils.ts"; + +/** + * Creates a new public thread from an existing message. Returns a channel on success, and a 400 BAD REQUEST on invalid parameters. Fires a Thread Create Gateway event. + * @param messageId when provided the thread will be public + */ +export async function startThread( + channelId: string, + options: StartThread & { messageId?: string }, +) { + const channel = await cacheHandlers.get("channels", channelId); + if (channel) { + // TODO(threads): perm check + if ( + ![ChannelTypes.GuildText, ChannelTypes.GuildNews].includes(channel.type) + ) { + throw new Error(Errors.INVALID_THREAD_PARENT_CHANNEL_TYPE); + } + + if (!options.messageId && channel.type === ChannelTypes.GuildNews) { + throw new Error(Errors.GUILD_NEWS_CHANNEL_ONLY_SUPPORT_PUBLIC_THREADS); + } + } + + return rest.runMethod( + "post", + options?.messageId + ? endpoints.THREAD_START_PUBLIC(channelId, options.messageId) + : endpoints.THREAD_START_PRIVATE(channelId), + camelKeysToSnakeCase(options), + ); +} From 8c23b88dc51add10b99e34ad6ae5ccbc2b951a84 Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sun, 2 May 2021 17:17:11 +0200 Subject: [PATCH 43/72] add: removeFromThread --- .../channels/threads/remove_from_thread.ts | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/helpers/channels/threads/remove_from_thread.ts diff --git a/src/helpers/channels/threads/remove_from_thread.ts b/src/helpers/channels/threads/remove_from_thread.ts new file mode 100644 index 000000000..7cf250275 --- /dev/null +++ b/src/helpers/channels/threads/remove_from_thread.ts @@ -0,0 +1,29 @@ +import { cacheHandlers } from "../../../cache.ts"; +import { rest } from "../../../rest/rest.ts"; +import { ChannelTypes } from "../../../types/channels/channel_types.ts"; +import { Errors } from "../../../types/misc/errors.ts"; +import { endpoints } from "../../../util/constants.ts"; + +/** Removes another 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. Returns a 204 empty response on success. Fires a Thread Members Update Gateway event. */ +export async function removeFromThread(channelId: string, userId?: string) { + // TODO(threads): perm check + const channel = await cacheHandlers.get("channels", channelId); + if (channel) { + if ( + ![ + ChannelTypes.GuildNewsThread, + ChannelTypes.GuildPivateThread, + ChannelTypes.GuildPublicThread, + ].includes(channel.type) + ) { + throw new Error(Errors.NOT_A_THREAD_CHANNEL); + } + } + + return await rest.runMethod( + "delete", + userId + ? endpoints.THREAD_USER(channelId, userId) + : endpoints.THREAD_ME(channelId), + ); +} From 28e407ca03307e07fc36f345865896c3176ac495 Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sun, 2 May 2021 17:17:17 +0200 Subject: [PATCH 44/72] add: getThreadMembers --- .../channels/threads/get_thread_members.ts | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 src/helpers/channels/threads/get_thread_members.ts diff --git a/src/helpers/channels/threads/get_thread_members.ts b/src/helpers/channels/threads/get_thread_members.ts new file mode 100644 index 000000000..b56b0f576 --- /dev/null +++ b/src/helpers/channels/threads/get_thread_members.ts @@ -0,0 +1,26 @@ +import { cacheHandlers } from "../../../cache.ts"; +import { rest } from "../../../rest/rest.ts"; +import { ChannelTypes } from "../../../types/channels/channel_types.ts"; +import { Errors } from "../../../types/misc/errors.ts"; +import { endpoints } from "../../../util/constants.ts"; + +// TODO(threads): it seems like the documented return type is wrong +/** Returns array of thread members objects that are members of the thread. */ +export async function getThreadMembers(channelId: string) { + // TODO(threads): perm check + // TODO(threads): intents check + const channel = await cacheHandlers.get("channels", channelId); + if (channel) { + if ( + ![ + ChannelTypes.GuildNewsThread, + ChannelTypes.GuildPivateThread, + ChannelTypes.GuildPublicThread, + ].includes(channel.type) + ) { + throw new Error(Errors.NOT_A_THREAD_CHANNEL); + } + } + + return await rest.runMethod("get", endpoints.THREAD_MEMBERS(channelId)); +} From f0ea01b502cf52e7a141914c73571561e915bb21 Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sun, 2 May 2021 18:20:57 +0200 Subject: [PATCH 45/72] add: getArchivedThreads --- .../channels/threads/get_archived_threads.ts | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/helpers/channels/threads/get_archived_threads.ts diff --git a/src/helpers/channels/threads/get_archived_threads.ts b/src/helpers/channels/threads/get_archived_threads.ts new file mode 100644 index 000000000..50229b260 --- /dev/null +++ b/src/helpers/channels/threads/get_archived_threads.ts @@ -0,0 +1,24 @@ +import { rest } from "../../../rest/rest.ts"; +import { ListPublicArchivedThreads } from "../../../types/channels/threads/list_public_archived_threads.ts"; +import { endpoints } from "../../../util/constants.ts"; +import { camelKeysToSnakeCase } from "../../../util/utils.ts"; + +export async function getArchivedThreads( + channelId: string, + options?: ListPublicArchivedThreads & { + type?: "public" | "private" | "privateJoinedThreads"; + }, +) { + // TODO(threads): perm check + // TODO(threads): check if this works + + return await rest.runMethod( + "get", + options?.type === "privateJoinedThreads" + ? endpoints.THREAD_ARCHIVED_PRIVATE_JOINED(channelId) + : options?.type === "private" + ? endpoints.THREAD_ARCHIVED_PRIVATE(channelId) + : endpoints.THREAD_ARCHIVED_PUBLIC(channelId), + camelKeysToSnakeCase(options ?? {}), + ); +} From 1b7c777aa31c5489c1cca76a30c0da17e6df343e Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sun, 2 May 2021 20:50:46 +0200 Subject: [PATCH 46/72] Update CHANNEL_UPDATE.ts --- src/handlers/channels/CHANNEL_UPDATE.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/handlers/channels/CHANNEL_UPDATE.ts b/src/handlers/channels/CHANNEL_UPDATE.ts index 1045545c5..57ff9af3e 100644 --- a/src/handlers/channels/CHANNEL_UPDATE.ts +++ b/src/handlers/channels/CHANNEL_UPDATE.ts @@ -7,11 +7,10 @@ import { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts"; export async function handleChannelUpdate(data: DiscordGatewayPayload) { const payload = data.d as Channel; const cachedChannel = await cacheHandlers.get("channels", payload.id); + if (!cachedChannel) return; const discordenoChannel = await structures.createDiscordenoChannel(payload); await cacheHandlers.set("channels", discordenoChannel.id, discordenoChannel); - if (!cachedChannel) return; - eventHandlers.channelUpdate?.(discordenoChannel, cachedChannel); } From b148c67b6cd299ce2e3fd12cc16561a0e13ce5c1 Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sun, 2 May 2021 20:50:58 +0200 Subject: [PATCH 47/72] add: THREAD_CREATE event handler --- src/handlers/channels/THREAD_CREATE.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 src/handlers/channels/THREAD_CREATE.ts diff --git a/src/handlers/channels/THREAD_CREATE.ts b/src/handlers/channels/THREAD_CREATE.ts new file mode 100644 index 000000000..ac24436b5 --- /dev/null +++ b/src/handlers/channels/THREAD_CREATE.ts @@ -0,0 +1,14 @@ +import { eventHandlers } from "../../bot.ts"; +import { cacheHandlers } from "../../cache.ts"; +import { structures } from "../../structures/mod.ts"; +import { Channel } from "../../types/channels/channel.ts"; +import { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts"; + +export async function handleThreadCreate(data: DiscordGatewayPayload) { + const payload = data.d as Channel; + + const discordenoChannel = await structures.createDiscordenoChannel(payload); + await cacheHandlers.set("channels", discordenoChannel.id, discordenoChannel); + + eventHandlers.threadCreate?.(discordenoChannel); +} From 5e747a8cdf4ddb246696868f2cf2584fc4220c70 Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sun, 2 May 2021 20:51:09 +0200 Subject: [PATCH 48/72] add: THREAD_UPDATE event handler --- src/handlers/channels/THREAD_UPDATE.ts | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 src/handlers/channels/THREAD_UPDATE.ts diff --git a/src/handlers/channels/THREAD_UPDATE.ts b/src/handlers/channels/THREAD_UPDATE.ts new file mode 100644 index 000000000..fac23b833 --- /dev/null +++ b/src/handlers/channels/THREAD_UPDATE.ts @@ -0,0 +1,16 @@ +import { eventHandlers } from "../../bot.ts"; +import { cacheHandlers } from "../../cache.ts"; +import { structures } from "../../structures/mod.ts"; +import { Channel } from "../../types/channels/channel.ts"; +import { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts"; + +export async function handleThreadUpdate(data: DiscordGatewayPayload) { + const payload = data.d as Channel; + const oldChannel = await cacheHandlers.get("channels", payload.id); + if (!oldChannel) return; + + const discordenoChannel = await structures.createDiscordenoChannel(payload); + await cacheHandlers.set("channels", discordenoChannel.id, discordenoChannel); + + eventHandlers.threadUpdate?.(discordenoChannel, oldChannel); +} From efd52e9c9b265adedd2b94910d360403a0e3d1f3 Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sun, 2 May 2021 20:51:39 +0200 Subject: [PATCH 49/72] fix: thread channels have own prop --- src/structures/guild.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/structures/guild.ts b/src/structures/guild.ts index 562440c25..3d36eb213 100644 --- a/src/structures/guild.ts +++ b/src/structures/guild.ts @@ -118,6 +118,7 @@ export async function createDiscordenoGuild( memberCount = 0, voiceStates = [], channels = [], + threads = [], presences = [], joinedAt = "", emojis, @@ -131,7 +132,7 @@ export async function createDiscordenoGuild( ), ); - await Promise.all(channels.map(async (channel) => { + await Promise.all([...channels, ...threads].map(async (channel) => { const discordenoChannel = await structures.createDiscordenoChannel( channel, rest.id, From cd0a86d831a3097768ea69008e2475be2c7b4a1c Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sun, 2 May 2021 20:51:48 +0200 Subject: [PATCH 50/72] add: some thread errors --- src/types/misc/errors.ts | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/types/misc/errors.ts b/src/types/misc/errors.ts index ee55755c0..34c50ccea 100644 --- a/src/types/misc/errors.ts +++ b/src/types/misc/errors.ts @@ -18,6 +18,11 @@ export enum Errors { MEMBER_SEARCH_LIMIT_TOO_LOW = "MEMBER_SEARCH_LIMIT_TOO_LOW", PRUNE_MAX_DAYS = "PRUNE_MAX_DAYS", ROLE_NOT_FOUND = "ROLE_NOT_FOUND", + // Thread errors + INVALID_THREAD_PARENT_CHANNEL_TYPE = "INVALID_THREAD_PARENT_CHANNEL_TYPE", + GUILD_NEWS_CHANNEL_ONLY_SUPPORT_PUBLIC_THREADS = + "GUILD_NEWS_CHANNEL_ONLY_SUPPORT_PUBLIC_THREADS", + NOT_A_THREAD_CHANNEL = "NOT_A_THREAD_CHANNEL", // Message Delete Errors DELETE_MESSAGES_MIN = "DELETE_MESSAGES_MIN", PRUNE_MIN_DAYS = "PRUNE_MIN_DAYS", From 59bc25fd67e2bbbc368b2c3d53c776f7f6734992 Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sun, 2 May 2021 20:52:05 +0200 Subject: [PATCH 51/72] fix: THREAD_ARCHIVED_BASE constant missing threads/ --- src/util/constants.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/constants.ts b/src/util/constants.ts index c5a566383..d8367493c 100644 --- a/src/util/constants.ts +++ b/src/util/constants.ts @@ -92,7 +92,7 @@ export const endpoints = { THREAD_USER: (channelId: string, userId: string) => `${endpoints.THREAD_MEMBERS(channelId)}/${userId}`, THREAD_ARCHIVED_BASE: (channelId: string) => - `${CHANNEL_BASE(channelId)}/archived`, + `${CHANNEL_BASE(channelId)}/threads/archived`, THREAD_ARCHIVED_PUBLIC: (channelId: string) => `${endpoints.THREAD_ARCHIVED_BASE(channelId)}/public`, THREAD_ARCHIVED_PRIVATE: (channelId: string) => From a094a1e7bd04520293f4e3cfbec8683db1ffbfb0 Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sun, 2 May 2021 20:59:16 +0200 Subject: [PATCH 52/72] add: THREAD_DELETE event handler --- src/handlers/channels/THREAD_DELETE.ts | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/handlers/channels/THREAD_DELETE.ts diff --git a/src/handlers/channels/THREAD_DELETE.ts b/src/handlers/channels/THREAD_DELETE.ts new file mode 100644 index 000000000..8452cba2b --- /dev/null +++ b/src/handlers/channels/THREAD_DELETE.ts @@ -0,0 +1,24 @@ +import { eventHandlers } from "../../bot.ts"; +import { cacheHandlers } from "../../cache.ts"; +import { Channel } from "../../types/channels/channel.ts"; +import { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts"; + +export async function handleThreadDelete(data: DiscordGatewayPayload) { + const payload = data.d as Channel; + + const cachedChannel = await cacheHandlers.get("channels", payload.id); + if (!cachedChannel) return; + + await cacheHandlers.delete("channels", payload.id); + cacheHandlers.forEach("messages", (message) => { + eventHandlers.debug?.( + "loop", + `Running forEach messages loop in CHANNEL_DELTE file.`, + ); + if (message.channelId === payload.id) { + cacheHandlers.delete("messages", message.id); + } + }); + + eventHandlers.channelDelete?.(cachedChannel); +} From 3fb9c805000c95feb70209fd1f3b6a5ad5d4875e Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sun, 2 May 2021 20:59:40 +0200 Subject: [PATCH 53/72] fix: unnecessary messages loop for non message channels --- src/handlers/channels/CHANNEL_DELETE.ts | 29 +++++++++++++++++-------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/handlers/channels/CHANNEL_DELETE.ts b/src/handlers/channels/CHANNEL_DELETE.ts index 8da02b9a0..0fc3bdd45 100644 --- a/src/handlers/channels/CHANNEL_DELETE.ts +++ b/src/handlers/channels/CHANNEL_DELETE.ts @@ -30,15 +30,26 @@ export async function handleChannelDelete(data: DiscordGatewayPayload) { } } + if ( + [ + DiscordChannelTypes.GuildText, + DiscordChannelTypes.Dm, + DiscordChannelTypes.GroupDm, + DiscordChannelTypes.GuildNews, + ].includes(payload.type) + ) { + cacheHandlers.forEach("messages", (message) => { + eventHandlers.debug?.( + "loop", + `Running forEach messages loop in CHANNEL_DELTE file.`, + ); + if (message.channelId === payload.id) { + cacheHandlers.delete("messages", message.id); + } + }); + } + await cacheHandlers.delete("channels", payload.id); - cacheHandlers.forEach("messages", (message) => { - eventHandlers.debug?.( - "loop", - `Running forEach messages loop in CHANNEL_DELTE file.`, - ); - if (message.channelId === payload.id) { - cacheHandlers.delete("messages", message.id); - } - }); + eventHandlers.channelDelete?.(cachedChannel); } From df03334464a10e7610ad82b06014c5e3ff6d33e6 Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sun, 2 May 2021 21:06:36 +0200 Subject: [PATCH 54/72] use correct event handler function --- src/handlers/channels/THREAD_DELETE.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/handlers/channels/THREAD_DELETE.ts b/src/handlers/channels/THREAD_DELETE.ts index 8452cba2b..7de3d61ed 100644 --- a/src/handlers/channels/THREAD_DELETE.ts +++ b/src/handlers/channels/THREAD_DELETE.ts @@ -20,5 +20,5 @@ export async function handleThreadDelete(data: DiscordGatewayPayload) { } }); - eventHandlers.channelDelete?.(cachedChannel); + eventHandlers.threadDelete?.(cachedChannel); } From 48606a67c664a2a4b67404c6ee831f62a8f1f633 Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sun, 2 May 2021 21:06:49 +0200 Subject: [PATCH 55/72] fix: file move imports --- src/types/channels/threads/list_active_threads.ts | 4 ++-- src/types/channels/threads/thread_list_sync.ts | 4 ++-- src/types/channels/threads/thread_members_update.ts | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/types/channels/threads/list_active_threads.ts b/src/types/channels/threads/list_active_threads.ts index 2651360f0..55753d444 100644 --- a/src/types/channels/threads/list_active_threads.ts +++ b/src/types/channels/threads/list_active_threads.ts @@ -1,5 +1,5 @@ -import { ThreadMember } from "../messages/thread_member.ts"; -import { Channel } from "./channel.ts"; +import { Channel } from "../channel.ts"; +import { ThreadMember } from "./thread_member.ts"; // TODO: add docs link export interface ListActiveThreads { diff --git a/src/types/channels/threads/thread_list_sync.ts b/src/types/channels/threads/thread_list_sync.ts index c5fa334d4..2c905a907 100644 --- a/src/types/channels/threads/thread_list_sync.ts +++ b/src/types/channels/threads/thread_list_sync.ts @@ -1,5 +1,5 @@ -import { ThreadMember } from "../messages/thread_member.ts"; -import { Channel } from "./channel.ts"; +import { Channel } from "../channel.ts"; +import { ThreadMember } from "./thread_member.ts"; // TODO: add docs link export interface ThreadListSync { diff --git a/src/types/channels/threads/thread_members_update.ts b/src/types/channels/threads/thread_members_update.ts index 8d3331683..2190f6297 100644 --- a/src/types/channels/threads/thread_members_update.ts +++ b/src/types/channels/threads/thread_members_update.ts @@ -1,4 +1,4 @@ -import { ThreadMember } from "../messages/thread_member.ts"; +import { ThreadMember } from "./thread_member.ts"; // TODO: add docs link export interface ThreadMembersUpdate { From 4f591320be466cfe00bf0f6b50ed78e55136cf21 Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sun, 2 May 2021 21:26:08 +0200 Subject: [PATCH 56/72] add: THREAD_LIST_SYNC handlere --- src/handlers/channels/THREAD_LIST_SYNC.ts | 34 +++++++++++++++++++++++ 1 file changed, 34 insertions(+) create mode 100644 src/handlers/channels/THREAD_LIST_SYNC.ts diff --git a/src/handlers/channels/THREAD_LIST_SYNC.ts b/src/handlers/channels/THREAD_LIST_SYNC.ts new file mode 100644 index 000000000..659769d99 --- /dev/null +++ b/src/handlers/channels/THREAD_LIST_SYNC.ts @@ -0,0 +1,34 @@ +import { eventHandlers } from "../../bot.ts"; +import { cacheHandlers } from "../../cache.ts"; +import { DiscordenoChannel } from "../../structures/channel.ts"; +import { structures } from "../../structures/mod.ts"; +import { ThreadListSync } from "../../types/channels/threads/thread_list_sync.ts"; +import { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts"; +import { Collection } from "../../util/collection.ts"; + +export async function handleThreadListSync(data: DiscordGatewayPayload) { + const payload = data.d as ThreadListSync; + + const discordenoChannels = await Promise.all( + payload.threads.map(async (thread) => { + const discordenoChannel = await structures.createDiscordenoChannel( + thread, + payload.guildId, + ); + + await cacheHandlers.set( + "channels", + discordenoChannel.id, + discordenoChannel, + ); + + return discordenoChannel; + }), + ); + + const threads = new Collection( + discordenoChannels.map((t) => [t.id, t]), + ); + + eventHandlers.threadListSync?.(threads, payload.members, payload.guildId); +} From 2396ba2ce437f877f60b73d32859214e27b55e32 Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sun, 2 May 2021 21:30:26 +0200 Subject: [PATCH 57/72] deno lint stupid --- src/helpers/channels/edit_channel.ts | 2 +- src/util/utils.ts | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/helpers/channels/edit_channel.ts b/src/helpers/channels/edit_channel.ts index cc8119c81..5319b171b 100644 --- a/src/helpers/channels/edit_channel.ts +++ b/src/helpers/channels/edit_channel.ts @@ -90,7 +90,7 @@ export async function editChannel( } const payload = { - ...camelKeysToSnakeCase<{}>(options), + ...camelKeysToSnakeCase>(options), // deno-lint-ignore camelcase permission_overwrites: hasOwnProperty(options, "permissionOverwrites") diff --git a/src/util/utils.ts b/src/util/utils.ts index d2c0a016d..af2d605b1 100644 --- a/src/util/utils.ts +++ b/src/util/utils.ts @@ -208,9 +208,11 @@ export function validateSlashCommands( // Typescript is not so good as we developers so we need this little utility function to help it out // Taken from https://fettblog.eu/typescript-hasownproperty/ /** TS save way to check if a property exists in an object */ +// deno-lint-ignore ban-types export function hasOwnProperty( obj: T, prop: Y, ): obj is T & Record { + // deno-lint-ignore no-prototype-builtins return obj.hasOwnProperty(prop); } From 81e70dc4ff5005b73fea14dadd6aa6200e16bf6a Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sun, 2 May 2021 21:34:18 +0200 Subject: [PATCH 58/72] guild id has been removed --- tests/channels/delete_channel.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/channels/delete_channel.ts b/tests/channels/delete_channel.ts index d2b46cb05..41a8a4be3 100644 --- a/tests/channels/delete_channel.ts +++ b/tests/channels/delete_channel.ts @@ -1,8 +1,8 @@ import { cache } from "../../src/cache.ts"; import { createChannel } from "../../src/helpers/channels/create_channel.ts"; import { deleteChannel } from "../../src/helpers/channels/delete_channel.ts"; -import { defaultTestOptions, tempData } from "../ws/start_bot.ts"; import { delayUntil } from "../util/delay_until.ts"; +import { defaultTestOptions, tempData } from "../ws/start_bot.ts"; Deno.test({ name: "[channel] delete a channel without a reason.", @@ -51,7 +51,7 @@ Deno.test({ } // Delete the channel now without a reason - await deleteChannel(tempData.guildId, channel.id, "with a reason"); + await deleteChannel(channel.id, "with a reason"); // wait 5 seconds to give it time for CHANNEL_DELETE event await delayUntil(10000, () => !cache.channels.has(channel.id)); // Make sure it is gone from cache From 5240981d61d36487de4c1d09d033e93f653a4a88 Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Sun, 2 May 2021 21:36:36 +0200 Subject: [PATCH 59/72] this too --- src/structures/channel.ts | 6 +++--- tests/channels/delete_channel.ts | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/structures/channel.ts b/src/structures/channel.ts index b20da7122..56f50dc05 100644 --- a/src/structures/channel.ts +++ b/src/structures/channel.ts @@ -49,8 +49,8 @@ const baseChannel: Partial = { disconnect(memberId) { return disconnectMember(this.guildId!, memberId); }, - delete() { - return deleteChannel(this.guildId!, this.id!); + delete(reason) { + return deleteChannel(this.id!, reason); }, editOverwrite(id, options) { return editChannelOverwrite(this.guildId!, this.id!, id, options); @@ -147,7 +147,7 @@ export interface DiscordenoChannel /** Disconnect a member from a voice channel. Requires MOVE_MEMBERS permission. */ disconnect(memberID: string): ReturnType; /** Delete the channel */ - delete(): ReturnType; + delete(reason?: string): ReturnType; /** Edit a channel Overwrite */ editOverwrite( overwriteID: string, diff --git a/tests/channels/delete_channel.ts b/tests/channels/delete_channel.ts index 41a8a4be3..57cb9c986 100644 --- a/tests/channels/delete_channel.ts +++ b/tests/channels/delete_channel.ts @@ -21,7 +21,7 @@ Deno.test({ } // Delete the channel now without a reason - await deleteChannel(tempData.guildId, channel.id); + await deleteChannel(channel.id); // wait 5 seconds to give it time for CHANNEL_DELETE event await delayUntil(3000, () => !cache.channels.has(channel.id)); // Make sure it is gone from cache From 7f7273ed2e6df635e68f78ab9d37d74aaddd6ed2 Mon Sep 17 00:00:00 2001 From: itohatweb Date: Mon, 3 May 2021 18:51:15 +0000 Subject: [PATCH 60/72] Commit from GitHub Actions (Lint) --- src/util/mod.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/mod.ts b/src/util/mod.ts index fe2efd7b1..9af7e2b53 100644 --- a/src/util/mod.ts +++ b/src/util/mod.ts @@ -4,4 +4,4 @@ export * from "./constants.ts"; export * from "./loop_object.ts"; export * from "./permissions.ts"; export * from "./utils.ts"; -export * from "./validate_length.ts"; \ No newline at end of file +export * from "./validate_length.ts"; From 6afe31ad553de04aa3b0182bbc966ee20f78c261 Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Mon, 3 May 2021 21:19:44 +0200 Subject: [PATCH 61/72] add: handleThreadMemberUpdate --- src/handlers/channels/THREAD_MEMBER_UPDATE.ts | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 src/handlers/channels/THREAD_MEMBER_UPDATE.ts diff --git a/src/handlers/channels/THREAD_MEMBER_UPDATE.ts b/src/handlers/channels/THREAD_MEMBER_UPDATE.ts new file mode 100644 index 000000000..a25490523 --- /dev/null +++ b/src/handlers/channels/THREAD_MEMBER_UPDATE.ts @@ -0,0 +1,20 @@ +import { eventHandlers } from "../../bot.ts"; +import { cacheHandlers } from "../../cache.ts"; +import { ThreadMember } from "../../types/channels/threads/thread_member.ts"; +import { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts"; +import { snowflakeToBigint } from "../../util/bigint.ts"; + +export async function handleThreadMemberUpdate(data: DiscordGatewayPayload) { + const payload = data.d as ThreadMember; + const thread = await cacheHandlers.get( + "channels", + snowflakeToBigint(payload.id), + ); + if (!thread) return; + + thread.member = payload; + + await cacheHandlers.set("channels", thread.id, thread); + + eventHandlers.threadMemberUpdate?.(payload); +} From 09474864110ecd59089852aa5057d7edf1f6480e Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Mon, 3 May 2021 21:19:53 +0200 Subject: [PATCH 62/72] fix: now bigint --- src/util/constants.ts | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/util/constants.ts b/src/util/constants.ts index 90f10e4d3..71e17f1e9 100644 --- a/src/util/constants.ts +++ b/src/util/constants.ts @@ -79,25 +79,25 @@ export const endpoints = { CHANNEL_TYPING: (channelId: bigint) => `${CHANNEL_BASE(channelId)}/typing`, // Thread Endpoints - THREAD_START_PUBLIC: (channelId: string, messageId: string) => + THREAD_START_PUBLIC: (channelId: bigint, messageId: bigint) => `${endpoints.CHANNEL_MESSAGE(channelId, messageId)}/threads`, - THREAD_START_PRIVATE: (channelId: string) => + THREAD_START_PRIVATE: (channelId: bigint) => `${CHANNEL_BASE(channelId)}/threads`, - THREAD_ACTIVE: (channelId: string) => + THREAD_ACTIVE: (channelId: bigint) => `${CHANNEL_BASE(channelId)}/threads/active`, - THREAD_MEMBERS: (channelId: string) => + THREAD_MEMBERS: (channelId: bigint) => `${CHANNEL_BASE(channelId)}/thread-members`, - THREAD_ME: (channelId: string) => + THREAD_ME: (channelId: bigint) => `${endpoints.THREAD_MEMBERS(channelId)}/@me`, - THREAD_USER: (channelId: string, userId: string) => + THREAD_USER: (channelId: bigint, userId: bigint) => `${endpoints.THREAD_MEMBERS(channelId)}/${userId}`, - THREAD_ARCHIVED_BASE: (channelId: string) => + THREAD_ARCHIVED_BASE: (channelId: bigint) => `${CHANNEL_BASE(channelId)}/threads/archived`, - THREAD_ARCHIVED_PUBLIC: (channelId: string) => + THREAD_ARCHIVED_PUBLIC: (channelId: bigint) => `${endpoints.THREAD_ARCHIVED_BASE(channelId)}/public`, - THREAD_ARCHIVED_PRIVATE: (channelId: string) => + THREAD_ARCHIVED_PRIVATE: (channelId: bigint) => `${endpoints.THREAD_ARCHIVED_BASE(channelId)}/private`, - THREAD_ARCHIVED_PRIVATE_JOINED: (channelId: string) => + THREAD_ARCHIVED_PRIVATE_JOINED: (channelId: bigint) => `${CHANNEL_BASE(channelId)}/users/@me/threads/archived/private`, // Guild Endpoints From c0a2c520a5a5d17b4b1febca7cb8e8696ac79b24 Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Mon, 3 May 2021 21:21:51 +0200 Subject: [PATCH 63/72] fix: bigint now --- src/helpers/channels/threads/get_archived_threads.ts | 2 +- src/helpers/channels/threads/get_thread_members.ts | 2 +- src/helpers/channels/threads/remove_from_thread.ts | 2 +- src/helpers/channels/threads/start_thread.ts | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/helpers/channels/threads/get_archived_threads.ts b/src/helpers/channels/threads/get_archived_threads.ts index 50229b260..4a4de2927 100644 --- a/src/helpers/channels/threads/get_archived_threads.ts +++ b/src/helpers/channels/threads/get_archived_threads.ts @@ -4,7 +4,7 @@ import { endpoints } from "../../../util/constants.ts"; import { camelKeysToSnakeCase } from "../../../util/utils.ts"; export async function getArchivedThreads( - channelId: string, + channelId: bigint, options?: ListPublicArchivedThreads & { type?: "public" | "private" | "privateJoinedThreads"; }, diff --git a/src/helpers/channels/threads/get_thread_members.ts b/src/helpers/channels/threads/get_thread_members.ts index b56b0f576..34c1d0e13 100644 --- a/src/helpers/channels/threads/get_thread_members.ts +++ b/src/helpers/channels/threads/get_thread_members.ts @@ -6,7 +6,7 @@ import { endpoints } from "../../../util/constants.ts"; // TODO(threads): it seems like the documented return type is wrong /** Returns array of thread members objects that are members of the thread. */ -export async function getThreadMembers(channelId: string) { +export async function getThreadMembers(channelId: bigint) { // TODO(threads): perm check // TODO(threads): intents check const channel = await cacheHandlers.get("channels", channelId); diff --git a/src/helpers/channels/threads/remove_from_thread.ts b/src/helpers/channels/threads/remove_from_thread.ts index 7cf250275..9e967a843 100644 --- a/src/helpers/channels/threads/remove_from_thread.ts +++ b/src/helpers/channels/threads/remove_from_thread.ts @@ -5,7 +5,7 @@ import { Errors } from "../../../types/misc/errors.ts"; import { endpoints } from "../../../util/constants.ts"; /** Removes another 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. Returns a 204 empty response on success. Fires a Thread Members Update Gateway event. */ -export async function removeFromThread(channelId: string, userId?: string) { +export async function removeFromThread(channelId: bigint, userId?: bigint) { // TODO(threads): perm check const channel = await cacheHandlers.get("channels", channelId); if (channel) { diff --git a/src/helpers/channels/threads/start_thread.ts b/src/helpers/channels/threads/start_thread.ts index 5fe429c22..dc4f8bbde 100644 --- a/src/helpers/channels/threads/start_thread.ts +++ b/src/helpers/channels/threads/start_thread.ts @@ -11,8 +11,8 @@ import { camelKeysToSnakeCase } from "../../../util/utils.ts"; * @param messageId when provided the thread will be public */ export async function startThread( - channelId: string, - options: StartThread & { messageId?: string }, + channelId: bigint, + options: StartThread & { messageId?: bigint }, ) { const channel = await cacheHandlers.get("channels", channelId); if (channel) { From 49eb18d848bc6f4ed7ce41953e46e8e2b363a757 Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Mon, 3 May 2021 21:46:17 +0200 Subject: [PATCH 64/72] Update THREAD_DELETE.ts --- src/handlers/channels/THREAD_DELETE.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/handlers/channels/THREAD_DELETE.ts b/src/handlers/channels/THREAD_DELETE.ts index 7de3d61ed..e4c2b4d87 100644 --- a/src/handlers/channels/THREAD_DELETE.ts +++ b/src/handlers/channels/THREAD_DELETE.ts @@ -2,20 +2,24 @@ import { eventHandlers } from "../../bot.ts"; import { cacheHandlers } from "../../cache.ts"; import { Channel } from "../../types/channels/channel.ts"; import { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts"; +import { snowflakeToBigint } from "../../util/bigint.ts"; export async function handleThreadDelete(data: DiscordGatewayPayload) { const payload = data.d as Channel; - const cachedChannel = await cacheHandlers.get("channels", payload.id); + const cachedChannel = await cacheHandlers.get( + "channels", + snowflakeToBigint(payload.id), + ); if (!cachedChannel) return; - await cacheHandlers.delete("channels", payload.id); + await cacheHandlers.delete("channels", snowflakeToBigint(payload.id)); cacheHandlers.forEach("messages", (message) => { eventHandlers.debug?.( "loop", `Running forEach messages loop in CHANNEL_DELTE file.`, ); - if (message.channelId === payload.id) { + if (message.channelId === snowflakeToBigint(payload.id)) { cacheHandlers.delete("messages", message.id); } }); From fb8e232d2fdae9aaaae0e190556b0582b1f10d42 Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Mon, 3 May 2021 21:46:19 +0200 Subject: [PATCH 65/72] Update THREAD_LIST_SYNC.ts --- src/handlers/channels/THREAD_LIST_SYNC.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/handlers/channels/THREAD_LIST_SYNC.ts b/src/handlers/channels/THREAD_LIST_SYNC.ts index 659769d99..aedcab173 100644 --- a/src/handlers/channels/THREAD_LIST_SYNC.ts +++ b/src/handlers/channels/THREAD_LIST_SYNC.ts @@ -4,6 +4,7 @@ import { DiscordenoChannel } from "../../structures/channel.ts"; import { structures } from "../../structures/mod.ts"; import { ThreadListSync } from "../../types/channels/threads/thread_list_sync.ts"; import { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts"; +import { snowflakeToBigint } from "../../util/bigint.ts"; import { Collection } from "../../util/collection.ts"; export async function handleThreadListSync(data: DiscordGatewayPayload) { @@ -13,7 +14,7 @@ export async function handleThreadListSync(data: DiscordGatewayPayload) { payload.threads.map(async (thread) => { const discordenoChannel = await structures.createDiscordenoChannel( thread, - payload.guildId, + snowflakeToBigint(payload.guildId), ); await cacheHandlers.set( @@ -26,9 +27,13 @@ export async function handleThreadListSync(data: DiscordGatewayPayload) { }), ); - const threads = new Collection( + const threads = new Collection( discordenoChannels.map((t) => [t.id, t]), ); - eventHandlers.threadListSync?.(threads, payload.members, payload.guildId); + eventHandlers.threadListSync?.( + threads, + payload.members, + snowflakeToBigint(payload.guildId), + ); } From c2175cc3396b6f7afece56326a76e1953ad29104 Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Mon, 3 May 2021 21:46:26 +0200 Subject: [PATCH 66/72] add: handleThreadMembersUpdate --- .../channels/THREAD_MEMBERS_UPDATE.ts | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/handlers/channels/THREAD_MEMBERS_UPDATE.ts diff --git a/src/handlers/channels/THREAD_MEMBERS_UPDATE.ts b/src/handlers/channels/THREAD_MEMBERS_UPDATE.ts new file mode 100644 index 000000000..b614f143e --- /dev/null +++ b/src/handlers/channels/THREAD_MEMBERS_UPDATE.ts @@ -0,0 +1,19 @@ +import { eventHandlers } from "../../bot.ts"; +import { cacheHandlers } from "../../cache.ts"; +import { ThreadMembersUpdate } from "../../types/channels/threads/thread_members_update.ts"; +import { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts"; +import { snowflakeToBigint } from "../../util/bigint.ts"; + +export async function handleThreadMembersUpdate(data: DiscordGatewayPayload) { + const payload = data.d as ThreadMembersUpdate; + const thread = await cacheHandlers.get( + "channels", + snowflakeToBigint(payload.id), + ); + if (!thread) return; + + thread.memberCount = payload.memberCount; + await cacheHandlers.set("channels", thread.id, thread); + + eventHandlers.threadMembersUpdate?.(payload); +} From 781a3e71c073ce4c99d1e680443a0e2990f3a974 Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Mon, 3 May 2021 21:46:30 +0200 Subject: [PATCH 67/72] Update THREAD_UPDATE.ts --- src/handlers/channels/THREAD_UPDATE.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/handlers/channels/THREAD_UPDATE.ts b/src/handlers/channels/THREAD_UPDATE.ts index fac23b833..1e3ae12d0 100644 --- a/src/handlers/channels/THREAD_UPDATE.ts +++ b/src/handlers/channels/THREAD_UPDATE.ts @@ -3,10 +3,14 @@ import { cacheHandlers } from "../../cache.ts"; import { structures } from "../../structures/mod.ts"; import { Channel } from "../../types/channels/channel.ts"; import { DiscordGatewayPayload } from "../../types/gateway/gateway_payload.ts"; +import { snowflakeToBigint } from "../../util/bigint.ts"; export async function handleThreadUpdate(data: DiscordGatewayPayload) { const payload = data.d as Channel; - const oldChannel = await cacheHandlers.get("channels", payload.id); + const oldChannel = await cacheHandlers.get( + "channels", + snowflakeToBigint(payload.id), + ); if (!oldChannel) return; const discordenoChannel = await structures.createDiscordenoChannel(payload); From a017a976a96e7dd984aa19f17106c5a686a531cf Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Mon, 3 May 2021 21:46:39 +0200 Subject: [PATCH 68/72] add: new thread events --- src/types/discordeno/eventHandlers.ts | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/src/types/discordeno/eventHandlers.ts b/src/types/discordeno/eventHandlers.ts index 4c97cea77..5386935ab 100644 --- a/src/types/discordeno/eventHandlers.ts +++ b/src/types/discordeno/eventHandlers.ts @@ -4,6 +4,8 @@ import { DiscordenoMember } from "../../structures/member.ts"; import { DiscordenoMessage } from "../../structures/message.ts"; import { DiscordenoRole } from "../../structures/role.ts"; import { Collection } from "../../util/collection.ts"; +import { ThreadMember } from "../channels/threads/thread_member.ts"; +import { ThreadMembersUpdate } from "../channels/threads/thread_members_update.ts"; import { IntegrationCreateUpdate } from "../integration/integration_create_update.ts"; import { ApplicationCommandCreateUpdateDelete } from "../interactions/application_command_create_update_delete.ts"; import { @@ -211,6 +213,25 @@ export interface EventHandlers { shardId: number, unavailableGuildIds: Set, ) => unknown; + /** Sent when a thread is created */ + threadCreate?: (channel: DiscordenoChannel) => unknown; + /** Sent when a thread is updated */ + threadUpdate?: ( + cahnnel: DiscordenoChannel, + oldChannel: DiscordenoChannel, + ) => unknown; + /** Sent when the bot gains access to threads */ + threadListSync?: ( + channels: Collection, + members: ThreadMember[], + guildId: bigint, + ) => unknown; + /** Sent when the current users thread member is updated */ + threadMemberUpdate?: (threadMember: ThreadMember) => unknown; + /** Sent when anyone is added to or removed from a thread */ + threadMembersUpdate?: (update: ThreadMembersUpdate) => unknown; + /** Sent when a thread is deleted */ + threadDelete?: (channel: DiscordenoChannel) => unknown; /** Sent when a user starts typing in a channel. */ typingStart?: (data: TypingStart) => unknown; /** Sent when a user joins a voice channel */ From 9e05a0c4fa0111ecd7e9d3b3b9859658ceaa972b Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Mon, 3 May 2021 21:46:46 +0200 Subject: [PATCH 69/72] add: new thread events --- src/handlers/mod.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/handlers/mod.ts b/src/handlers/mod.ts index 2eda4a9c7..169e79d21 100644 --- a/src/handlers/mod.ts +++ b/src/handlers/mod.ts @@ -2,6 +2,12 @@ import { handleChannelCreate } from "./channels/CHANNEL_CREATE.ts"; import { handleChannelDelete } from "./channels/CHANNEL_DELETE.ts"; import { handleChannelPinsUpdate } from "./channels/CHANNEL_PINS_UPDATE.ts"; import { handleChannelUpdate } from "./channels/CHANNEL_UPDATE.ts"; +import { handleThreadCreate } from "./channels/THREAD_CREATE.ts"; +import { handleThreadDelete } from "./channels/THREAD_DELETE.ts"; +import { handleThreadListSync } from "./channels/THREAD_LIST_SYNC.ts"; +import { handleThreadMembersUpdate } from "./channels/THREAD_MEMBERS_UPDATE.ts"; +import { handleThreadMemberUpdate } from "./channels/THREAD_MEMBER_UPDATE.ts"; +import { handleThreadUpdate } from "./channels/THREAD_UPDATE.ts"; import { handleApplicationCommandCreate } from "./commands/APPLICATION_COMMAND_CREATE.ts"; import { handleApplicationCommandDelete } from "./commands/APPLICATION_COMMAND_DELETE.ts"; import { handleApplicationCommandUpdate } from "./commands/APPLICATION_COMMAND_UPDATE.ts"; @@ -77,6 +83,12 @@ export { handleMessageUpdate, handlePresenceUpdate, handleReady, + handleThreadCreate, + handleThreadDelete, + handleThreadListSync, + handleThreadMembersUpdate, + handleThreadMemberUpdate, + handleThreadUpdate, handleTypingStart, handleUserUpdate, handleVoiceServerUpdate, @@ -92,6 +104,12 @@ export let handlers = { CHANNEL_DELETE: handleChannelDelete, CHANNEL_PINS_UPDATE: handleChannelPinsUpdate, CHANNEL_UPDATE: handleChannelUpdate, + THREAD_CREATE: handleThreadCreate, + THREAD_UPDATE: handleThreadUpdate, + THREAD_DELETE: handleThreadDelete, + THREAD_LIST_SYNC: handleThreadListSync, + THREAD_MEMBER_UPDATE: handleThreadMemberUpdate, + THREAD_MEMBERS_UPDATE: handleThreadMembersUpdate, // commands APPLICATION_COMMAND_CREATE: handleApplicationCommandCreate, APPLICATION_COMMAND_DELETE: handleApplicationCommandDelete, From 304e3a26ac53f3a9a3d4e41e4904fae42faa0891 Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Mon, 3 May 2021 21:47:03 +0200 Subject: [PATCH 70/72] NOT TESTED BECAUSE DISCORD NOT WORKING --- src/helpers/channels/threads/add_to_thread.ts | 35 +++++++++++++++++++ .../channels/threads/get_active_threads.ts | 12 +++++++ 2 files changed, 47 insertions(+) create mode 100644 src/helpers/channels/threads/add_to_thread.ts create mode 100644 src/helpers/channels/threads/get_active_threads.ts diff --git a/src/helpers/channels/threads/add_to_thread.ts b/src/helpers/channels/threads/add_to_thread.ts new file mode 100644 index 000000000..1fd913b5f --- /dev/null +++ b/src/helpers/channels/threads/add_to_thread.ts @@ -0,0 +1,35 @@ +import { cacheHandlers } from "../../../cache.ts"; +import { rest } from "../../../rest/rest.ts"; +import { ChannelTypes, Errors } from "../../../types/mod.ts"; +import { endpoints } from "../../../util/constants.ts"; +//TODO(threads): this does not work rn +/** Adds the current user to a thread. Returns a 204 empty response on success. Also requires the thread is not archived. Fires a Thread Members Update Gateway event.Adds another user to a thread. Requires the ability to send messages in the thread. Also requires the thread is not archived. Returns a 204 empty response on success. Fires a Thread Members Update Gateway event. + * @param userId the user to add to the thread defaults to bot + */ +export async function addToThread(channelId: bigint, userId?: bigint) { + // TODO(threads): perm check + const channel = await cacheHandlers.get("channels", channelId); + if (channel) { + if ( + ![ + ChannelTypes.GuildNewsThread, + ChannelTypes.GuildPivateThread, + ChannelTypes.GuildPublicThread, + ].includes(channel.type) + ) { + throw new Error(Errors.NOT_A_THREAD_CHANNEL); + } + } + console.log( + "put", + userId + ? endpoints.THREAD_USER(channelId, userId) + : endpoints.THREAD_ME(channelId), + ); + return await rest.runMethod( + "put", + userId + ? endpoints.THREAD_USER(channelId, userId) + : endpoints.THREAD_ME(channelId), + ); +} diff --git a/src/helpers/channels/threads/get_active_threads.ts b/src/helpers/channels/threads/get_active_threads.ts new file mode 100644 index 000000000..6fd529bd2 --- /dev/null +++ b/src/helpers/channels/threads/get_active_threads.ts @@ -0,0 +1,12 @@ +import { rest } from "../../../rest/rest.ts"; +import { endpoints } from "../../../util/constants.ts"; + +/** Returns all active threads in the channel, including public and private threads. Threads are ordered by their id, in descending order. Requires the READ_MESSAGE_HISTORY permission. */ +export async function getActiveThreads(channelId: bigint) { + // TODO(threads): perm check + // TODO(threads): test if it works + return rest.runMethod( + "get", + endpoints.THREAD_ACTIVE(channelId), + ); +} From 9c3c8c58acb51d319f34bead8b8ede1d9614e2bc Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Mon, 3 May 2021 21:55:08 +0200 Subject: [PATCH 71/72] forgot that one --- src/helpers/channels/threads/get_active_threads.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/helpers/channels/threads/get_active_threads.ts b/src/helpers/channels/threads/get_active_threads.ts index 6fd529bd2..2ed30691d 100644 --- a/src/helpers/channels/threads/get_active_threads.ts +++ b/src/helpers/channels/threads/get_active_threads.ts @@ -5,7 +5,7 @@ import { endpoints } from "../../../util/constants.ts"; export async function getActiveThreads(channelId: bigint) { // TODO(threads): perm check // TODO(threads): test if it works - return rest.runMethod( + return await rest.runMethod( "get", endpoints.THREAD_ACTIVE(channelId), ); From e942aea490790618ba28b0c081be46488a9b9af2 Mon Sep 17 00:00:00 2001 From: ITOH <72305210+itohatweb@users.noreply.github.com> Date: Tue, 4 May 2021 17:42:31 +0200 Subject: [PATCH 72/72] add threadd types --- src/helpers/channels/start_typing.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/helpers/channels/start_typing.ts b/src/helpers/channels/start_typing.ts index 2a7a09d79..4f65aa771 100644 --- a/src/helpers/channels/start_typing.ts +++ b/src/helpers/channels/start_typing.ts @@ -19,6 +19,9 @@ export async function startTyping(channelId: bigint) { DiscordChannelTypes.Dm, DiscordChannelTypes.GuildNews, DiscordChannelTypes.GuildText, + DiscordChannelTypes.GuildNewsThread, + DiscordChannelTypes.GuildPivateThread, + DiscordChannelTypes.GuildPublicThread, ].includes(channel.type) ) { throw new Error(Errors.CHANNEL_NOT_TEXT_BASED);