Skip to content

Commit

Permalink
Switch to API v9 and add support for threads (#1319)
Browse files Browse the repository at this point in the history
This commit adds support to guild threads channels, see discord/discord-api-docs#2855. It also bumps the Discord API version and gateway to v9.
  • Loading branch information
HarmoGlace committed Jul 4, 2021
1 parent 13cf056 commit 4c53b48
Show file tree
Hide file tree
Showing 20 changed files with 1,043 additions and 9 deletions.
41 changes: 41 additions & 0 deletions src/builder/create_thread.rs
@@ -0,0 +1,41 @@
use std::collections::HashMap;

use crate::internal::prelude::*;
use crate::model::channel::ChannelType;

#[derive(Debug, Clone, Default)]
pub struct CreateThread(pub HashMap<&'static str, Value>);

impl CreateThread {
/// The name of the thread.
///
/// **Note**: Must be between 2 and 100 characters long.
pub fn name<D: ToString>(&mut self, name: D) -> &mut Self {
self.0.insert("name", Value::String(name.to_string()));

self
}

/// Duration in minutes to automatically archive the thread after recent activity.
///
/// **Note**: Can only be set to 60, 1440, 4320, 10080 currently.
pub fn auto_archive_duration(&mut self, duration: u16) -> &mut Self {
self.0.insert("auto_archive_duration", Value::Number(Number::from(duration)));

self
}

/// The thread type, which can be [`ChannelType::PublicThread`] or [`ChannelType::PrivateThread`].
///
/// **Note**: It defaults to [`ChannelType::PrivateThread`] in order to match the behavior when thread documentation was first published.
/// This is a bit of a weird default though, and thus is highly likely to change in the future,
/// so it is recommended to always explicitly setting it to avoid any breaking change.
///
/// [`ChannelType::PublicThread`]: crate::model::channel::ChannelType::PublicThread
/// [`ChannelType::PrivateThread`]: crate::model::channel::ChannelType::PrivateThread
pub fn kind(&mut self, kind: ChannelType) -> &mut Self {
self.0.insert("type", Value::Number(Number::from(kind as u8)));

self
}
}
2 changes: 2 additions & 0 deletions src/builder/mod.rs
Expand Up @@ -28,6 +28,7 @@ mod create_interaction_response_followup;
mod create_invite;
mod create_message;
mod create_stage_instance;
mod create_thread;
mod edit_channel;
mod edit_guild;
mod edit_guild_welcome_screen;
Expand All @@ -53,6 +54,7 @@ pub use self::{
create_invite::CreateInvite,
create_message::CreateMessage,
create_stage_instance::CreateStageInstance,
create_thread::CreateThread,
edit_channel::EditChannel,
edit_guild::EditGuild,
edit_guild_welcome_screen::EditGuildWelcomeScreen,
Expand Down
6 changes: 6 additions & 0 deletions src/cache/mod.rs
Expand Up @@ -1074,6 +1074,11 @@ mod test {
slow_mode_rate: Some(0),
rtc_region: None,
video_quality_mode: None,
message_count: None,
member_count: None,
thread_metadata: None,
member: None,
default_auto_archive_duration: None,
};

// Add a channel delete event to the cache, the cached messages for that
Expand Down Expand Up @@ -1138,6 +1143,7 @@ mod test {
widget_enabled: Some(false),
widget_channel_id: None,
stage_instances: vec![],
threads: vec![],
},
}
};
Expand Down
15 changes: 14 additions & 1 deletion src/client/bridge/gateway/intents.rs
Expand Up @@ -54,12 +54,22 @@ __impl_bitflags! {
/// - CHANNEL_UPDATE
/// - CHANNEL_DELETE
/// - CHANNEL_PINS_UPDATE
/// - THREAD_CREATE
/// - THREAD_UPDATE
/// - THREAD_DELETE
/// - THREAD_LIST_SYNC
/// - THREAD_MEMBER_UPDATE
/// - THREAD_MEMBERS_UPDATE
/// - STAGE_INSTANCE_CREATE
/// - STAGE_INSTANCE_UPDATE
/// - STAGE_INSTANCE_DELETE
GUILDS = 1;
/// Enables following gateway events:
///
/// - GUILD_MEMBER_ADD
/// - GUILD_MEMBER_UPDATE
/// - GUILD_MEMBER_REMOVE
/// - THREAD_MEMBERS_UPDATE
///
/// **Info**:
/// This intent is *privileged*.
Expand All @@ -80,6 +90,9 @@ __impl_bitflags! {
/// Enables following gateway event:
///
/// - GUILD_INTEGRATIONS_UPDATE
/// - INTEGRATION_CREATE
/// - INTEGRATION_UPDATE
/// - INTEGRATION_DELETE
GUILD_INTEGRATIONS = 1 << 4;
/// Enables following gateway event:
///
Expand Down Expand Up @@ -110,6 +123,7 @@ __impl_bitflags! {
/// - MESSAGE_CREATE
/// - MESSAGE_UPDATE
/// - MESSAGE_DELETE
/// - MESSAGE_DELETE_BULK
GUILD_MESSAGES = 1 << 9;
/// Enables following gateway events:
///
Expand All @@ -124,7 +138,6 @@ __impl_bitflags! {
GUILD_MESSAGE_TYPING = 1 << 11;
/// Enable following gateway events:
///
/// - CHANNEL_CREATE
/// - MESSAGE_CREATE
/// - MESSAGE_UPDATE
/// - MESSAGE_DELETE
Expand Down
42 changes: 42 additions & 0 deletions src/client/dispatch.rs
Expand Up @@ -831,5 +831,47 @@ async fn handle_event(
event_handler.stage_instance_delete(context, event.stage_instance).await;
});
},
DispatchEvent::Model(Event::ThreadCreate(event)) => {
let event_handler = Arc::clone(event_handler);

tokio::spawn(async move {
event_handler.thread_create(context, event.thread).await;
});
},
DispatchEvent::Model(Event::ThreadUpdate(event)) => {
let event_handler = Arc::clone(event_handler);

tokio::spawn(async move {
event_handler.thread_update(context, event.thread).await;
});
},
DispatchEvent::Model(Event::ThreadDelete(event)) => {
let event_handler = Arc::clone(event_handler);

tokio::spawn(async move {
event_handler.thread_delete(context, event.thread).await;
});
},
DispatchEvent::Model(Event::ThreadListSync(event)) => {
let event_handler = Arc::clone(event_handler);

tokio::spawn(async move {
event_handler.thread_list_sync(context, event).await;
});
},
DispatchEvent::Model(Event::ThreadMemberUpdate(event)) => {
let event_handler = Arc::clone(event_handler);

tokio::spawn(async move {
event_handler.thread_member_update(context, event.member).await;
});
},
DispatchEvent::Model(Event::ThreadMembersUpdate(event)) => {
let event_handler = Arc::clone(event_handler);

tokio::spawn(async move {
event_handler.thread_members_update(context, event).await;
});
},
}
}
45 changes: 43 additions & 2 deletions src/client/event_handler.rs
Expand Up @@ -501,13 +501,54 @@ pub trait EventHandler: Send + Sync {

/// Dispatched when a stage instance is updated.
///
/// Provides the created stage instance.
/// Provides the updated stage instance.
async fn stage_instance_update(&self, _ctx: Context, _stage_instance: StageInstance) {}

/// Dispatched when a stage instance is deleted.
///
/// Provides the created stage instance.
/// Provides the deleted stage instance.
async fn stage_instance_delete(&self, _ctx: Context, _stage_instance: StageInstance) {}

/// Dispatched when a thread is created or the current user is added
/// to a private thread.
///
/// Provides the thread.
async fn thread_create(&self, _ctx: Context, _thread: GuildChannel) {}

/// Dispatched when a thread is updated.
///
/// Provides the updated thread.
async fn thread_update(&self, _ctx: Context, _thread: GuildChannel) {}

/// Dispatched when a thread is deleted.
///
/// Provides the partial deleted thread.
async fn thread_delete(&self, _ctx: Context, _thread: PartialGuildChannel) {}

/// Dispatched when the current user gains access to a channel
///
/// Provides the threads the current user can access, the thread members,
/// the guild Id, and the channel Ids of the parent channels being synced.
async fn thread_list_sync(&self, _ctx: Context, _thread_list_sync: ThreadListSyncEvent) {}

/// Dispatched when the [`ThreadMember`] for the current user is updated.
///
/// Provides the updated thread member.
async fn thread_member_update(&self, _ctx: Context, _thread_member: ThreadMember) {}

/// Dispatched when anyone is added to or removed from a thread. If the current user does not have the [`GatewayIntents::GUILDS`],
/// then this event will only be sent if the current user was added to or removed from the thread.
///
/// Provides the added/removed members, the approximate member count of members in the thread,
/// the thread Id and its guild Id.
///
/// [`GatewayIntents::GUILDS`]: crate::client::bridge::gateway::GatewayIntents::GUILDS
async fn thread_members_update(
&self,
_ctx: Context,
_thread_members_update: ThreadMembersUpdateEvent,
) {
}
}

/// This core trait for handling raw events
Expand Down
2 changes: 1 addition & 1 deletion src/constants.rs
Expand Up @@ -8,7 +8,7 @@ pub const EMBED_MAX_COUNT: usize = 10;

/// The gateway version used by the library. The gateway URI is retrieved via
/// the REST API.
pub const GATEWAY_VERSION: u8 = 8;
pub const GATEWAY_VERSION: u8 = 9;

/// The large threshold to send on identify.
pub const LARGE_THRESHOLD: u8 = 250;
Expand Down

0 comments on commit 4c53b48

Please sign in to comment.