From b2eba13a9a6cab6831c35d164f196800e4ca2b02 Mon Sep 17 00:00:00 2001 From: Valithor Obsidion Date: Wed, 22 Oct 2025 11:51:35 -0400 Subject: [PATCH 01/16] Channel Subtypes --- .../Parts/Channel/AnnouncementThread.php | 18 +++++++++++++++++ src/Discord/Parts/Channel/DM.php | 18 +++++++++++++++++ src/Discord/Parts/Channel/GroupDM.php | 18 +++++++++++++++++ .../Parts/Channel/GuildAnnouncement.php | 18 +++++++++++++++++ src/Discord/Parts/Channel/GuildCategory.php | 18 +++++++++++++++++ src/Discord/Parts/Channel/GuildDirectory.php | 18 +++++++++++++++++ src/Discord/Parts/Channel/GuildForum.php | 18 +++++++++++++++++ src/Discord/Parts/Channel/GuildMedia.php | 18 +++++++++++++++++ src/Discord/Parts/Channel/GuildStageVoice.php | 18 +++++++++++++++++ src/Discord/Parts/Channel/GuildText.php | 18 +++++++++++++++++ src/Discord/Parts/Channel/GuildVoice.php | 18 +++++++++++++++++ src/Discord/Parts/Channel/PrivateThread.php | 20 +++++++++++++++++++ src/Discord/Parts/Channel/PublicThread.php | 20 +++++++++++++++++++ src/Discord/Parts/Guild/Guild.php | 1 + src/Discord/Parts/PartTrait.php | 2 +- 15 files changed, 240 insertions(+), 1 deletion(-) create mode 100644 src/Discord/Parts/Channel/AnnouncementThread.php create mode 100644 src/Discord/Parts/Channel/DM.php create mode 100644 src/Discord/Parts/Channel/GroupDM.php create mode 100644 src/Discord/Parts/Channel/GuildAnnouncement.php create mode 100644 src/Discord/Parts/Channel/GuildCategory.php create mode 100644 src/Discord/Parts/Channel/GuildDirectory.php create mode 100644 src/Discord/Parts/Channel/GuildForum.php create mode 100644 src/Discord/Parts/Channel/GuildMedia.php create mode 100644 src/Discord/Parts/Channel/GuildStageVoice.php create mode 100644 src/Discord/Parts/Channel/GuildText.php create mode 100644 src/Discord/Parts/Channel/GuildVoice.php create mode 100644 src/Discord/Parts/Channel/PrivateThread.php create mode 100644 src/Discord/Parts/Channel/PublicThread.php diff --git a/src/Discord/Parts/Channel/AnnouncementThread.php b/src/Discord/Parts/Channel/AnnouncementThread.php new file mode 100644 index 000000000..e9f3f4c27 --- /dev/null +++ b/src/Discord/Parts/Channel/AnnouncementThread.php @@ -0,0 +1,18 @@ + + * + * This file is subject to the MIT license that is bundled + * with this source code in the LICENSE.md file. + */ + +namespace Discord\Parts\Channel; + +class AnnouncementThread extends Channel +{ +} diff --git a/src/Discord/Parts/Channel/DM.php b/src/Discord/Parts/Channel/DM.php new file mode 100644 index 000000000..04105bfe7 --- /dev/null +++ b/src/Discord/Parts/Channel/DM.php @@ -0,0 +1,18 @@ + + * + * This file is subject to the MIT license that is bundled + * with this source code in the LICENSE.md file. + */ + +namespace Discord\Parts\Channel; + +class DM extends Channel +{ +} diff --git a/src/Discord/Parts/Channel/GroupDM.php b/src/Discord/Parts/Channel/GroupDM.php new file mode 100644 index 000000000..30cb962a1 --- /dev/null +++ b/src/Discord/Parts/Channel/GroupDM.php @@ -0,0 +1,18 @@ + + * + * This file is subject to the MIT license that is bundled + * with this source code in the LICENSE.md file. + */ + +namespace Discord\Parts\Channel; + +class GroupDM extends Channel +{ +} diff --git a/src/Discord/Parts/Channel/GuildAnnouncement.php b/src/Discord/Parts/Channel/GuildAnnouncement.php new file mode 100644 index 000000000..602e00571 --- /dev/null +++ b/src/Discord/Parts/Channel/GuildAnnouncement.php @@ -0,0 +1,18 @@ + + * + * This file is subject to the MIT license that is bundled + * with this source code in the LICENSE.md file. + */ + +namespace Discord\Parts\Channel; + +class GuildAnnouncement extends Channel +{ +} diff --git a/src/Discord/Parts/Channel/GuildCategory.php b/src/Discord/Parts/Channel/GuildCategory.php new file mode 100644 index 000000000..997b65030 --- /dev/null +++ b/src/Discord/Parts/Channel/GuildCategory.php @@ -0,0 +1,18 @@ + + * + * This file is subject to the MIT license that is bundled + * with this source code in the LICENSE.md file. + */ + +namespace Discord\Parts\Channel; + +class GuildCategory extends Channel +{ +} diff --git a/src/Discord/Parts/Channel/GuildDirectory.php b/src/Discord/Parts/Channel/GuildDirectory.php new file mode 100644 index 000000000..f6560f2fa --- /dev/null +++ b/src/Discord/Parts/Channel/GuildDirectory.php @@ -0,0 +1,18 @@ + + * + * This file is subject to the MIT license that is bundled + * with this source code in the LICENSE.md file. + */ + +namespace Discord\Parts\Channel; + +class GuildDirectory extends Channel +{ +} diff --git a/src/Discord/Parts/Channel/GuildForum.php b/src/Discord/Parts/Channel/GuildForum.php new file mode 100644 index 000000000..a0c4444ba --- /dev/null +++ b/src/Discord/Parts/Channel/GuildForum.php @@ -0,0 +1,18 @@ + + * + * This file is subject to the MIT license that is bundled + * with this source code in the LICENSE.md file. + */ + +namespace Discord\Parts\Channel; + +class GuildForum extends Channel +{ +} diff --git a/src/Discord/Parts/Channel/GuildMedia.php b/src/Discord/Parts/Channel/GuildMedia.php new file mode 100644 index 000000000..13201ec37 --- /dev/null +++ b/src/Discord/Parts/Channel/GuildMedia.php @@ -0,0 +1,18 @@ + + * + * This file is subject to the MIT license that is bundled + * with this source code in the LICENSE.md file. + */ + +namespace Discord\Parts\Channel; + +class GuildMedia extends Channel +{ +} diff --git a/src/Discord/Parts/Channel/GuildStageVoice.php b/src/Discord/Parts/Channel/GuildStageVoice.php new file mode 100644 index 000000000..33e30ac59 --- /dev/null +++ b/src/Discord/Parts/Channel/GuildStageVoice.php @@ -0,0 +1,18 @@ + + * + * This file is subject to the MIT license that is bundled + * with this source code in the LICENSE.md file. + */ + +namespace Discord\Parts\Channel; + +class GuildStageVoice extends Channel +{ +} diff --git a/src/Discord/Parts/Channel/GuildText.php b/src/Discord/Parts/Channel/GuildText.php new file mode 100644 index 000000000..03d1c3cb8 --- /dev/null +++ b/src/Discord/Parts/Channel/GuildText.php @@ -0,0 +1,18 @@ + + * + * This file is subject to the MIT license that is bundled + * with this source code in the LICENSE.md file. + */ + +namespace Discord\Parts\Channel; + +class GuildText extends Channel +{ +} diff --git a/src/Discord/Parts/Channel/GuildVoice.php b/src/Discord/Parts/Channel/GuildVoice.php new file mode 100644 index 000000000..d63c608c4 --- /dev/null +++ b/src/Discord/Parts/Channel/GuildVoice.php @@ -0,0 +1,18 @@ + + * + * This file is subject to the MIT license that is bundled + * with this source code in the LICENSE.md file. + */ + +namespace Discord\Parts\Channel; + +class GuildVoice extends Channel +{ +} diff --git a/src/Discord/Parts/Channel/PrivateThread.php b/src/Discord/Parts/Channel/PrivateThread.php new file mode 100644 index 000000000..186f30f0c --- /dev/null +++ b/src/Discord/Parts/Channel/PrivateThread.php @@ -0,0 +1,20 @@ + + * + * This file is subject to the MIT license that is bundled + * with this source code in the LICENSE.md file. + */ + +namespace Discord\Parts\Channel; + +use Discord\Parts\Thread\Thread; + +class PrivateThread extends Thread +{ +} diff --git a/src/Discord/Parts/Channel/PublicThread.php b/src/Discord/Parts/Channel/PublicThread.php new file mode 100644 index 000000000..9caca6542 --- /dev/null +++ b/src/Discord/Parts/Channel/PublicThread.php @@ -0,0 +1,20 @@ + + * + * This file is subject to the MIT license that is bundled + * with this source code in the LICENSE.md file. + */ + +namespace Discord\Parts\Channel; + +use Discord\Parts\Thread\Thread; + +class PublicThread extends Thread +{ +} diff --git a/src/Discord/Parts/Guild/Guild.php b/src/Discord/Parts/Guild/Guild.php index 93af26978..25f6a7177 100644 --- a/src/Discord/Parts/Guild/Guild.php +++ b/src/Discord/Parts/Guild/Guild.php @@ -1631,6 +1631,7 @@ public function save(?string $reason = null): PromiseInterface return reject(new NoPermissionsException("You do not have permission to save changes to the guild {$this->id}.")); } } + return $this->discord->guilds->save($this, $reason); } diff --git a/src/Discord/Parts/PartTrait.php b/src/Discord/Parts/PartTrait.php index 7feada1ee..f7f2991b5 100644 --- a/src/Discord/Parts/PartTrait.php +++ b/src/Discord/Parts/PartTrait.php @@ -50,7 +50,7 @@ protected function afterConstruct(): void * * @param string|null $reason The reason for the audit log, if supported. * - * @throws \Exception If the part does not support saving. + * @throws \Exception If the part does not support saving. * @throws NoPermissionsException Missing permission. * * @return PromiseInterface Resolves with the saved part. From 016296e6708f1ee09adc03c74287d5a889fcd4ab Mon Sep 17 00:00:00 2001 From: Valithor Obsidion Date: Wed, 22 Oct 2025 11:53:25 -0400 Subject: [PATCH 02/16] Update AnnouncementThread.php --- src/Discord/Parts/Channel/AnnouncementThread.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Discord/Parts/Channel/AnnouncementThread.php b/src/Discord/Parts/Channel/AnnouncementThread.php index e9f3f4c27..b905a40af 100644 --- a/src/Discord/Parts/Channel/AnnouncementThread.php +++ b/src/Discord/Parts/Channel/AnnouncementThread.php @@ -13,6 +13,8 @@ namespace Discord\Parts\Channel; -class AnnouncementThread extends Channel +use Discord\Parts\Thread\Thread; + +class AnnouncementThread extends Thread { } From f01ce8ed386091224510773222c30190e4a60476 Mon Sep 17 00:00:00 2001 From: Valithor Obsidion Date: Wed, 22 Oct 2025 11:54:03 -0400 Subject: [PATCH 03/16] ChannelBuilder::TYPES array --- src/Discord/Builders/ChannelBuilder.php | 29 +++++++++++++++++++++++++ 1 file changed, 29 insertions(+) diff --git a/src/Discord/Builders/ChannelBuilder.php b/src/Discord/Builders/ChannelBuilder.php index 40438a2e8..da4a68aa1 100644 --- a/src/Discord/Builders/ChannelBuilder.php +++ b/src/Discord/Builders/ChannelBuilder.php @@ -14,8 +14,21 @@ namespace Discord\Builders; use Discord\Http\Exceptions\RequestFailedException; +use Discord\Parts\Channel\AnnouncementThread; use Discord\Parts\Channel\Channel; +use Discord\Parts\Channel\DM; +use Discord\Parts\Channel\GroupDM; +use Discord\Parts\Channel\GuildAnnouncement; +use Discord\Parts\Channel\GuildCategory; +use Discord\Parts\Channel\GuildDirectory; +use Discord\Parts\Channel\GuildForum; +use Discord\Parts\Channel\GuildMedia; +use Discord\Parts\Channel\GuildStageVoice; +use Discord\Parts\Channel\GuildText; +use Discord\Parts\Channel\GuildVoice; use Discord\Parts\Channel\Overwrite; +use Discord\Parts\Channel\PrivateThread; +use Discord\Parts\Channel\PublicThread; use Discord\Parts\Guild\Emoji; use Discord\Voice\Region; use JsonSerializable; @@ -31,6 +44,22 @@ */ class ChannelBuilder extends Builder implements JsonSerializable { + public const TYPES = [ + 0 => GuildText::class, // A text channel within a server + 1 => DM::class, // A direct message between users + 2 => GuildVoice::class, // A voice channel within a server + 3 => GroupDM::class, // A direct message between multiple users + 4 => GuildCategory::class, // An organizational category that contains up to 50 channels + 5 => GuildAnnouncement::class, // A channel that users can follow and crosspost into their own server (formerly news channels) + 10 => AnnouncementThread::class, // A temporary sub-channel within a GUILD_ANNOUNCEMENT channel + 11 => PublicThread::class, // A temporary sub-channel within a GUILD_TEXT or GUILD_FORUM channel + 12 => PrivateThread::class, // A temporary sub-channel within a GUILD_TEXT channel that is only viewable by those invited and those with the MANAGE_THREADS permission + 13 => GuildStageVoice::class, // A voice channel for hosting events with an audience + 14 => GuildDirectory::class, // The channel in a hub containing the listed servers + 15 => GuildForum::class, // Channel that can only contain threads + 16 => GuildMedia::class, // Channel that can only contain threads, similar to GUILD_FORUM channels + ]; + protected string $name; protected ?int $type; protected ?string $topic; // Text, Announcement, Forum, Media From 7623b0b6235c8e57868d17e0ab13c1d4a686b75a Mon Sep 17 00:00:00 2001 From: Valithor Obsidion Date: Wed, 22 Oct 2025 13:19:22 -0400 Subject: [PATCH 04/16] Update websocket events --- src/Discord/WebSockets/Events/ChannelCreate.php | 3 ++- src/Discord/WebSockets/Events/ChannelDelete.php | 3 ++- src/Discord/WebSockets/Events/ChannelUpdate.php | 4 +++- src/Discord/WebSockets/Events/ThreadCreate.php | 3 ++- src/Discord/WebSockets/Events/ThreadDelete.php | 4 +++- src/Discord/WebSockets/Events/ThreadListSync.php | 3 ++- src/Discord/WebSockets/Events/ThreadUpdate.php | 3 ++- 7 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/Discord/WebSockets/Events/ChannelCreate.php b/src/Discord/WebSockets/Events/ChannelCreate.php index a704fb53f..3505898ca 100644 --- a/src/Discord/WebSockets/Events/ChannelCreate.php +++ b/src/Discord/WebSockets/Events/ChannelCreate.php @@ -13,6 +13,7 @@ namespace Discord\WebSockets\Events; +use Discord\Builders\ChannelBuilder; use Discord\Parts\Channel\Channel; use Discord\WebSockets\Event; use Discord\Parts\Guild\Guild; @@ -30,7 +31,7 @@ class ChannelCreate extends Event public function handle($data) { /** @var Channel */ - $channelPart = $this->factory->part(Channel::class, (array) $data, true); + $channelPart = $this->factory->part(ChannelBuilder::TYPES[$data->type ?? Channel::class], (array) $data, true); if ($channelPart->is_private) { $this->discord->private_channels->set($data->id, $channelPart); diff --git a/src/Discord/WebSockets/Events/ChannelDelete.php b/src/Discord/WebSockets/Events/ChannelDelete.php index a86aa208d..68bd2b774 100644 --- a/src/Discord/WebSockets/Events/ChannelDelete.php +++ b/src/Discord/WebSockets/Events/ChannelDelete.php @@ -13,6 +13,7 @@ namespace Discord\WebSockets\Events; +use Discord\Builders\ChannelBuilder; use Discord\Parts\Channel\Channel; use Discord\WebSockets\Event; @@ -39,6 +40,6 @@ public function handle($data) } } - return $channelPart ?? $this->factory->part(Channel::class, (array) $data); + return $channelPart ?? $this->factory->part(ChannelBuilder::TYPES[$data->type ?? Channel::class], (array) $data); } } diff --git a/src/Discord/WebSockets/Events/ChannelUpdate.php b/src/Discord/WebSockets/Events/ChannelUpdate.php index d38cfb9b2..2f63409c5 100644 --- a/src/Discord/WebSockets/Events/ChannelUpdate.php +++ b/src/Discord/WebSockets/Events/ChannelUpdate.php @@ -13,6 +13,7 @@ namespace Discord\WebSockets\Events; +use Discord\Builders\ChannelBuilder; use Discord\Parts\Channel\Channel; use Discord\WebSockets\Event; @@ -31,7 +32,8 @@ public function handle($data) $oldChannel = $repository = null; /** @var Channel */ - $channelPart = $this->factory->part(Channel::class, (array) $data, true); + $channelPart = $this->factory->part(ChannelBuilder::TYPES[$data->type ?? Channel::class], (array) $data, true); + if ($channelPart->is_private) { /** @var ?Channel */ diff --git a/src/Discord/WebSockets/Events/ThreadCreate.php b/src/Discord/WebSockets/Events/ThreadCreate.php index e34e04cea..ef0b9de66 100644 --- a/src/Discord/WebSockets/Events/ThreadCreate.php +++ b/src/Discord/WebSockets/Events/ThreadCreate.php @@ -13,6 +13,7 @@ namespace Discord\WebSockets\Events; +use Discord\Builders\ChannelBuilder; use Discord\Parts\Channel\Channel; use Discord\Parts\Channel\Message; use Discord\Parts\Guild\Guild; @@ -32,7 +33,7 @@ class ThreadCreate extends Event public function handle($data) { /** @var Thread */ - $threadPart = $this->factory->part(Thread::class, (array) $data, true); + $threadPart = $this->factory->part(ChannelBuilder::TYPES[$data->type ?? Thread::class], (array) $data, true); /** @var ?Guild */ if ($guild = yield $this->discord->guilds->cacheGet($data->guild_id)) { diff --git a/src/Discord/WebSockets/Events/ThreadDelete.php b/src/Discord/WebSockets/Events/ThreadDelete.php index d156cbea1..f4640bd27 100644 --- a/src/Discord/WebSockets/Events/ThreadDelete.php +++ b/src/Discord/WebSockets/Events/ThreadDelete.php @@ -13,8 +13,10 @@ namespace Discord\WebSockets\Events; +use Discord\Builders\ChannelBuilder; use Discord\Parts\Channel\Channel; use Discord\Parts\Guild\Guild; +use Discord\Parts\Thread\Thread; use Discord\WebSockets\Event; /** @@ -36,6 +38,6 @@ public function handle($data) } } - return $threadPart ?? $data; + return $threadPart ?? $threadPart = $this->factory->part(ChannelBuilder::TYPES[$data->type ?? Thread::class], (array) $data, true);; } } diff --git a/src/Discord/WebSockets/Events/ThreadListSync.php b/src/Discord/WebSockets/Events/ThreadListSync.php index 92594f841..bca9b1ad1 100644 --- a/src/Discord/WebSockets/Events/ThreadListSync.php +++ b/src/Discord/WebSockets/Events/ThreadListSync.php @@ -13,6 +13,7 @@ namespace Discord\WebSockets\Events; +use Discord\Builders\ChannelBuilder; use Discord\Helpers\Collection; use Discord\Parts\Channel\Channel; use Discord\Parts\Guild\Guild; @@ -39,7 +40,7 @@ public function handle($data) foreach ($data->threads as $thread) { /** @var Thread */ - $threadPart = $this->factory->part(Thread::class, (array) $thread, true); + $threadPart = $this->factory->part(ChannelBuilder::TYPES[$data->type ?? Thread::class], (array) $thread, true); /** @var ?Channel */ if ($channel = $channels[$thread->parent_id] ?? null) { /** @var ?Thread */ diff --git a/src/Discord/WebSockets/Events/ThreadUpdate.php b/src/Discord/WebSockets/Events/ThreadUpdate.php index 25780e117..0584c027e 100644 --- a/src/Discord/WebSockets/Events/ThreadUpdate.php +++ b/src/Discord/WebSockets/Events/ThreadUpdate.php @@ -13,6 +13,7 @@ namespace Discord\WebSockets\Events; +use Discord\Builders\ChannelBuilder; use Discord\Parts\Channel\Channel; use Discord\Parts\Guild\Guild; use Discord\Parts\Thread\Thread; @@ -46,7 +47,7 @@ public function handle($data) if ($threadPart === null) { /** @var Thread */ - $threadPart = $this->factory->part(Thread::class, (array) $data, true); + $threadPart = $this->factory->part(ChannelBuilder::TYPES[$data->type ?? Thread::class], (array) $data, true); } if (isset($parent)) { From b6f22fee992d600495a155ffe18304b041fa5b0e Mon Sep 17 00:00:00 2001 From: Valithor Obsidion Date: Wed, 22 Oct 2025 13:41:22 -0400 Subject: [PATCH 05/16] Fix MessageCreate for private messages --- src/Discord/WebSockets/Events/MessageCreate.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Discord/WebSockets/Events/MessageCreate.php b/src/Discord/WebSockets/Events/MessageCreate.php index dd668b0b0..1721cd83d 100644 --- a/src/Discord/WebSockets/Events/MessageCreate.php +++ b/src/Discord/WebSockets/Events/MessageCreate.php @@ -16,6 +16,7 @@ use Discord\Parts\Channel\Message; use Discord\WebSockets\Event; use Discord\Parts\Channel\Channel; +use Discord\Parts\Channel\DM; use Discord\Parts\Guild\Guild; use Discord\Parts\Thread\Thread; use Discord\WebSockets\Intents; @@ -37,9 +38,9 @@ public function handle($data) /** @var Message */ $messagePart = $this->factory->part(Message::class, (array) $data, true); - if ($messagePart->is_private) { + if (! $messagePart->member) { /** @var Channel */ - $channel = $this->factory->part(Channel::class, [ + $channel = $this->factory->part(DM::class, [ 'id' => $data->channel_id, 'type' => Channel::TYPE_DM, 'last_message_id' => $data->id, From 7c1cdba0cca660435cd5ada911d99a306261bff6 Mon Sep 17 00:00:00 2001 From: Valithor Obsidion Date: Wed, 22 Oct 2025 13:41:32 -0400 Subject: [PATCH 06/16] Update websocket events --- src/Discord/WebSockets/Events/ChannelCreate.php | 2 +- src/Discord/WebSockets/Events/ChannelDelete.php | 2 +- src/Discord/WebSockets/Events/ChannelUpdate.php | 2 +- src/Discord/WebSockets/Events/ThreadCreate.php | 2 +- src/Discord/WebSockets/Events/ThreadDelete.php | 2 +- src/Discord/WebSockets/Events/ThreadListSync.php | 3 ++- src/Discord/WebSockets/Events/ThreadUpdate.php | 2 +- 7 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/Discord/WebSockets/Events/ChannelCreate.php b/src/Discord/WebSockets/Events/ChannelCreate.php index 3505898ca..6c07de0ba 100644 --- a/src/Discord/WebSockets/Events/ChannelCreate.php +++ b/src/Discord/WebSockets/Events/ChannelCreate.php @@ -31,7 +31,7 @@ class ChannelCreate extends Event public function handle($data) { /** @var Channel */ - $channelPart = $this->factory->part(ChannelBuilder::TYPES[$data->type ?? Channel::class], (array) $data, true); + $channelPart = $this->factory->part(ChannelBuilder::TYPES[$data->type] ?? Channel::class, (array) $data, true); if ($channelPart->is_private) { $this->discord->private_channels->set($data->id, $channelPart); diff --git a/src/Discord/WebSockets/Events/ChannelDelete.php b/src/Discord/WebSockets/Events/ChannelDelete.php index 68bd2b774..6bd7d3ccd 100644 --- a/src/Discord/WebSockets/Events/ChannelDelete.php +++ b/src/Discord/WebSockets/Events/ChannelDelete.php @@ -40,6 +40,6 @@ public function handle($data) } } - return $channelPart ?? $this->factory->part(ChannelBuilder::TYPES[$data->type ?? Channel::class], (array) $data); + return $channelPart ?? $this->factory->part(ChannelBuilder::TYPES[$data->type] ?? Channel::class, (array) $data); } } diff --git a/src/Discord/WebSockets/Events/ChannelUpdate.php b/src/Discord/WebSockets/Events/ChannelUpdate.php index 2f63409c5..7a39bbb20 100644 --- a/src/Discord/WebSockets/Events/ChannelUpdate.php +++ b/src/Discord/WebSockets/Events/ChannelUpdate.php @@ -32,7 +32,7 @@ public function handle($data) $oldChannel = $repository = null; /** @var Channel */ - $channelPart = $this->factory->part(ChannelBuilder::TYPES[$data->type ?? Channel::class], (array) $data, true); + $channelPart = $this->factory->part(ChannelBuilder::TYPES[$data->type] ?? Channel::class, (array) $data, true); if ($channelPart->is_private) { diff --git a/src/Discord/WebSockets/Events/ThreadCreate.php b/src/Discord/WebSockets/Events/ThreadCreate.php index ef0b9de66..1ec463ec3 100644 --- a/src/Discord/WebSockets/Events/ThreadCreate.php +++ b/src/Discord/WebSockets/Events/ThreadCreate.php @@ -33,7 +33,7 @@ class ThreadCreate extends Event public function handle($data) { /** @var Thread */ - $threadPart = $this->factory->part(ChannelBuilder::TYPES[$data->type ?? Thread::class], (array) $data, true); + $threadPart = $this->factory->part(ChannelBuilder::TYPES[$data->type] ?? Thread::class, (array) $data, true); /** @var ?Guild */ if ($guild = yield $this->discord->guilds->cacheGet($data->guild_id)) { diff --git a/src/Discord/WebSockets/Events/ThreadDelete.php b/src/Discord/WebSockets/Events/ThreadDelete.php index f4640bd27..76f24b8d5 100644 --- a/src/Discord/WebSockets/Events/ThreadDelete.php +++ b/src/Discord/WebSockets/Events/ThreadDelete.php @@ -38,6 +38,6 @@ public function handle($data) } } - return $threadPart ?? $threadPart = $this->factory->part(ChannelBuilder::TYPES[$data->type ?? Thread::class], (array) $data, true);; + return $threadPart ?? $threadPart = $this->factory->part(ChannelBuilder::TYPES[$data->type] ?? Thread::class, (array) $data, true);; } } diff --git a/src/Discord/WebSockets/Events/ThreadListSync.php b/src/Discord/WebSockets/Events/ThreadListSync.php index bca9b1ad1..7d9344313 100644 --- a/src/Discord/WebSockets/Events/ThreadListSync.php +++ b/src/Discord/WebSockets/Events/ThreadListSync.php @@ -39,8 +39,9 @@ public function handle($data) } foreach ($data->threads as $thread) { + /** @var Thread $thread */ /** @var Thread */ - $threadPart = $this->factory->part(ChannelBuilder::TYPES[$data->type ?? Thread::class], (array) $thread, true); + $threadPart = $this->factory->part(ChannelBuilder::TYPES[$thread->type ?? Thread::class], (array) $thread, true); /** @var ?Channel */ if ($channel = $channels[$thread->parent_id] ?? null) { /** @var ?Thread */ diff --git a/src/Discord/WebSockets/Events/ThreadUpdate.php b/src/Discord/WebSockets/Events/ThreadUpdate.php index 0584c027e..462f8ccf9 100644 --- a/src/Discord/WebSockets/Events/ThreadUpdate.php +++ b/src/Discord/WebSockets/Events/ThreadUpdate.php @@ -47,7 +47,7 @@ public function handle($data) if ($threadPart === null) { /** @var Thread */ - $threadPart = $this->factory->part(ChannelBuilder::TYPES[$data->type ?? Thread::class], (array) $data, true); + $threadPart = $this->factory->part(ChannelBuilder::TYPES[$data->type] ?? Thread::class, (array) $data, true); } if (isset($parent)) { From 72fa75aaff6f359192150555db331918f3fe444c Mon Sep 17 00:00:00 2001 From: Valithor Obsidion Date: Wed, 22 Oct 2025 13:43:31 -0400 Subject: [PATCH 07/16] Update Resolved.php --- src/Discord/Parts/Interactions/Request/Resolved.php | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/src/Discord/Parts/Interactions/Request/Resolved.php b/src/Discord/Parts/Interactions/Request/Resolved.php index c0833364b..d7965b3c8 100644 --- a/src/Discord/Parts/Interactions/Request/Resolved.php +++ b/src/Discord/Parts/Interactions/Request/Resolved.php @@ -13,6 +13,7 @@ namespace Discord\Parts\Interactions\Request; +use Discord\Builders\ChannelBuilder; use Discord\Helpers\Collection; use Discord\Helpers\ExCollectionInterface; use Discord\Parts\Channel\Attachment; @@ -186,11 +187,7 @@ protected function getChannelsAttribute(): ExCollectionInterface } if (! isset($channelPart)) { - if (in_array($channel->type, [Channel::TYPE_ANNOUNCEMENT_THREAD, Channel::TYPE_PRIVATE_THREAD, Channel::TYPE_PUBLIC_THREAD])) { - $channelPart = $this->factory->part(Thread::class, (array) $channel + ['guild_id' => $this->guild_id], true); - } else { - $channelPart = $this->factory->part(Channel::class, (array) $channel + ['guild_id' => $this->guild_id], true); - } + $channelPart = $this->factory->part(ChannelBuilder::TYPES[$channel->type] ?? Channel::class, (array) $channel + ['guild_id' => $this->guild_id], true); } $collection->pushItem($channelPart); From fff333f0a1e90a9154c47346a8c969c0fb54d73a Mon Sep 17 00:00:00 2001 From: Valithor Obsidion Date: Wed, 22 Oct 2025 13:49:23 -0400 Subject: [PATCH 08/16] Update MessageCreate.php --- src/Discord/WebSockets/Events/MessageCreate.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Discord/WebSockets/Events/MessageCreate.php b/src/Discord/WebSockets/Events/MessageCreate.php index 1721cd83d..cd1bac027 100644 --- a/src/Discord/WebSockets/Events/MessageCreate.php +++ b/src/Discord/WebSockets/Events/MessageCreate.php @@ -38,7 +38,8 @@ public function handle($data) /** @var Message */ $messagePart = $this->factory->part(Message::class, (array) $data, true); - if (! $messagePart->member) { + /** @todo Fix this */ + if (! $messagePart->is_private) { /** @var Channel */ $channel = $this->factory->part(DM::class, [ 'id' => $data->channel_id, From d41e3233be837f4ab24906e9540830796695074a Mon Sep 17 00:00:00 2001 From: Valithor Obsidion Date: Wed, 22 Oct 2025 13:52:31 -0400 Subject: [PATCH 09/16] Update Message.php --- src/Discord/Parts/Channel/Message.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Discord/Parts/Channel/Message.php b/src/Discord/Parts/Channel/Message.php index 223455e0f..3edd36cf5 100644 --- a/src/Discord/Parts/Channel/Message.php +++ b/src/Discord/Parts/Channel/Message.php @@ -471,7 +471,7 @@ protected function getChannelAttribute(): Part return $channel; } - return $this->factory->part(Channel::class, [ + return $this->factory->part(DM::class, [ 'id' => $this->channel_id, 'type' => Channel::TYPE_DM, ], true); From be88af9269dfe35d676a01f5d4077ef9a923ab85 Mon Sep 17 00:00:00 2001 From: Valithor Obsidion Date: Wed, 22 Oct 2025 13:56:34 -0400 Subject: [PATCH 10/16] Fix private messages not being cached --- src/Discord/WebSockets/Events/MessageCreate.php | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/src/Discord/WebSockets/Events/MessageCreate.php b/src/Discord/WebSockets/Events/MessageCreate.php index cd1bac027..e8bc444fc 100644 --- a/src/Discord/WebSockets/Events/MessageCreate.php +++ b/src/Discord/WebSockets/Events/MessageCreate.php @@ -38,17 +38,10 @@ public function handle($data) /** @var Message */ $messagePart = $this->factory->part(Message::class, (array) $data, true); - /** @todo Fix this */ - if (! $messagePart->is_private) { - /** @var Channel */ - $channel = $this->factory->part(DM::class, [ - 'id' => $data->channel_id, - 'type' => Channel::TYPE_DM, - 'last_message_id' => $data->id, - 'recipients' => [$data->author], - ], true); - - $this->discord->private_channels->set($data->channel_id, $channel); + if ($channel = $messagePart->channel) { + if ($channel->type === Channel::TYPE_DM || $channel->type === Channel::TYPE_GROUP_DM) { + $this->discord->private_channels->set($channel->id, $channel); + } } /** @var ?Guild */ From d934f9aa11fc0d8a44e2c3a7c10f4d1c659e8817 Mon Sep 17 00:00:00 2001 From: Valithor Obsidion Date: Wed, 22 Oct 2025 14:12:19 -0400 Subject: [PATCH 11/16] Update MessageCreate.php --- src/Discord/WebSockets/Events/MessageCreate.php | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Discord/WebSockets/Events/MessageCreate.php b/src/Discord/WebSockets/Events/MessageCreate.php index e8bc444fc..0aebac366 100644 --- a/src/Discord/WebSockets/Events/MessageCreate.php +++ b/src/Discord/WebSockets/Events/MessageCreate.php @@ -38,10 +38,9 @@ public function handle($data) /** @var Message */ $messagePart = $this->factory->part(Message::class, (array) $data, true); - if ($channel = $messagePart->channel) { - if ($channel->type === Channel::TYPE_DM || $channel->type === Channel::TYPE_GROUP_DM) { - $this->discord->private_channels->set($channel->id, $channel); - } + $channel = $messagePart->channel; + if ($channel->type === Channel::TYPE_DM || $channel->type === Channel::TYPE_GROUP_DM) { + $this->discord->private_channels->set($channel->id, $channel); } /** @var ?Guild */ From cbbf703e1512b4c50e235b0ba0bc8b541dcbffb1 Mon Sep 17 00:00:00 2001 From: Valithor Obsidion Date: Wed, 22 Oct 2025 14:14:25 -0400 Subject: [PATCH 12/16] Update MessageCreate.php --- src/Discord/WebSockets/Events/MessageCreate.php | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/Discord/WebSockets/Events/MessageCreate.php b/src/Discord/WebSockets/Events/MessageCreate.php index 0aebac366..f2dcbb133 100644 --- a/src/Discord/WebSockets/Events/MessageCreate.php +++ b/src/Discord/WebSockets/Events/MessageCreate.php @@ -41,6 +41,8 @@ public function handle($data) $channel = $messagePart->channel; if ($channel->type === Channel::TYPE_DM || $channel->type === Channel::TYPE_GROUP_DM) { $this->discord->private_channels->set($channel->id, $channel); + } else { + unset($channel); // Force reload below } /** @var ?Guild */ From 5ef857637e5550731d02e4a4335dc8ce876efd37 Mon Sep 17 00:00:00 2001 From: Valithor Obsidion Date: Wed, 22 Oct 2025 14:22:15 -0400 Subject: [PATCH 13/16] Update Message.php --- src/Discord/Parts/Channel/Message.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Discord/Parts/Channel/Message.php b/src/Discord/Parts/Channel/Message.php index 3edd36cf5..d61324717 100644 --- a/src/Discord/Parts/Channel/Message.php +++ b/src/Discord/Parts/Channel/Message.php @@ -474,6 +474,7 @@ protected function getChannelAttribute(): Part return $this->factory->part(DM::class, [ 'id' => $this->channel_id, 'type' => Channel::TYPE_DM, + 'recipients' => [$this->author], ], true); } From 065dae1386e6198cb1f5eaca960212dc63e7ae17 Mon Sep 17 00:00:00 2001 From: Valithor Obsidion Date: Wed, 22 Oct 2025 14:22:23 -0400 Subject: [PATCH 14/16] Update MessageCreate.php --- src/Discord/WebSockets/Events/MessageCreate.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Discord/WebSockets/Events/MessageCreate.php b/src/Discord/WebSockets/Events/MessageCreate.php index f2dcbb133..490bec8e9 100644 --- a/src/Discord/WebSockets/Events/MessageCreate.php +++ b/src/Discord/WebSockets/Events/MessageCreate.php @@ -16,7 +16,6 @@ use Discord\Parts\Channel\Message; use Discord\WebSockets\Event; use Discord\Parts\Channel\Channel; -use Discord\Parts\Channel\DM; use Discord\Parts\Guild\Guild; use Discord\Parts\Thread\Thread; use Discord\WebSockets\Intents; @@ -40,6 +39,7 @@ public function handle($data) $channel = $messagePart->channel; if ($channel->type === Channel::TYPE_DM || $channel->type === Channel::TYPE_GROUP_DM) { + $channel->last_message_id = $data->id; $this->discord->private_channels->set($channel->id, $channel); } else { unset($channel); // Force reload below From 45c5ce025ccd721d9932aaafd6e1a6bb99be6fc2 Mon Sep 17 00:00:00 2001 From: Valithor Obsidion Date: Wed, 22 Oct 2025 14:28:43 -0400 Subject: [PATCH 15/16] cs-fixer --- src/Discord/WebSockets/Events/ChannelUpdate.php | 1 - src/Discord/WebSockets/Events/ThreadDelete.php | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Discord/WebSockets/Events/ChannelUpdate.php b/src/Discord/WebSockets/Events/ChannelUpdate.php index 7a39bbb20..af7c08c1b 100644 --- a/src/Discord/WebSockets/Events/ChannelUpdate.php +++ b/src/Discord/WebSockets/Events/ChannelUpdate.php @@ -34,7 +34,6 @@ public function handle($data) /** @var Channel */ $channelPart = $this->factory->part(ChannelBuilder::TYPES[$data->type] ?? Channel::class, (array) $data, true); - if ($channelPart->is_private) { /** @var ?Channel */ if (! $oldChannel = yield $this->discord->private_channels->cacheGet($data->id)) { diff --git a/src/Discord/WebSockets/Events/ThreadDelete.php b/src/Discord/WebSockets/Events/ThreadDelete.php index 76f24b8d5..9d8464b61 100644 --- a/src/Discord/WebSockets/Events/ThreadDelete.php +++ b/src/Discord/WebSockets/Events/ThreadDelete.php @@ -38,6 +38,6 @@ public function handle($data) } } - return $threadPart ?? $threadPart = $this->factory->part(ChannelBuilder::TYPES[$data->type] ?? Thread::class, (array) $data, true);; + return $threadPart ?? $threadPart = $this->factory->part(ChannelBuilder::TYPES[$data->type] ?? Thread::class, (array) $data, true); } } From 49b464faa0db088d32d09d23d1bbdb6c621dccab Mon Sep 17 00:00:00 2001 From: Valithor Obsidion Date: Wed, 22 Oct 2025 14:54:01 -0400 Subject: [PATCH 16/16] Update ChannelBuilder.php --- src/Discord/Builders/ChannelBuilder.php | 26 ++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/src/Discord/Builders/ChannelBuilder.php b/src/Discord/Builders/ChannelBuilder.php index da4a68aa1..fb5fcadfb 100644 --- a/src/Discord/Builders/ChannelBuilder.php +++ b/src/Discord/Builders/ChannelBuilder.php @@ -45,19 +45,19 @@ class ChannelBuilder extends Builder implements JsonSerializable { public const TYPES = [ - 0 => GuildText::class, // A text channel within a server - 1 => DM::class, // A direct message between users - 2 => GuildVoice::class, // A voice channel within a server - 3 => GroupDM::class, // A direct message between multiple users - 4 => GuildCategory::class, // An organizational category that contains up to 50 channels - 5 => GuildAnnouncement::class, // A channel that users can follow and crosspost into their own server (formerly news channels) - 10 => AnnouncementThread::class, // A temporary sub-channel within a GUILD_ANNOUNCEMENT channel - 11 => PublicThread::class, // A temporary sub-channel within a GUILD_TEXT or GUILD_FORUM channel - 12 => PrivateThread::class, // A temporary sub-channel within a GUILD_TEXT channel that is only viewable by those invited and those with the MANAGE_THREADS permission - 13 => GuildStageVoice::class, // A voice channel for hosting events with an audience - 14 => GuildDirectory::class, // The channel in a hub containing the listed servers - 15 => GuildForum::class, // Channel that can only contain threads - 16 => GuildMedia::class, // Channel that can only contain threads, similar to GUILD_FORUM channels + Channel::TYPE_GUILD_TEXT => GuildText::class, // A text channel within a server + Channel::TYPE_DM => DM::class, // A direct message between users + Channel::TYPE_GUILD_VOICE => GuildVoice::class, // A voice channel within a server + Channel::TYPE_GROUP_DM => GroupDM::class, // A direct message between multiple users + Channel::TYPE_GUILD_CATEGORY => GuildCategory::class, // An organizational category that contains up to 50 channels + Channel::TYPE_GUILD_ANNOUNCEMENT => GuildAnnouncement::class, // A channel that users can follow and crosspost into their own server (formerly news channels) + Channel::TYPE_ANNOUNCEMENT_THREAD => AnnouncementThread::class, // A temporary sub-channel within a GUILD_ANNOUNCEMENT channel + Channel::TYPE_PUBLIC_THREAD => PublicThread::class, // A temporary sub-channel within a GUILD_TEXT or GUILD_FORUM channel + Channel::TYPE_PRIVATE_THREAD => PrivateThread::class, // A temporary sub-channel within a GUILD_TEXT channel that is only viewable by those invited and those with the MANAGE_THREADS permission + Channel::TYPE_GUILD_STAGE_VOICE => GuildStageVoice::class, // A voice channel for hosting events with an audience + Channel::TYPE_GUILD_DIRECTORY => GuildDirectory::class, // The channel in a hub containing the listed servers + Channel::TYPE_GUILD_FORUM => GuildForum::class, // Channel that can only contain threads + Channel::TYPE_GUILD_MEDIA => GuildMedia::class, // Channel that can only contain threads, similar to GUILD_FORUM channels ]; protected string $name;