Skip to content

Commit 457f1a7

Browse files
Add support for incident actions (#3424)
Rebase of #3079 now that this feature is stable and documented. --------- Co-authored-by: jamesbt365 <[email protected]>
1 parent c6eca3a commit 457f1a7

File tree

7 files changed

+150
-0
lines changed

7 files changed

+150
-0
lines changed
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#[cfg(feature = "http")]
2+
use crate::http::Http;
3+
#[cfg(feature = "http")]
4+
use crate::internal::prelude::*;
5+
use crate::model::prelude::*;
6+
7+
/// A builder for editing guild incident actions.
8+
///
9+
/// [Discord's docs]: https://discord.com/developers/docs/resources/guild#modify-guild-incident-actions
10+
#[derive(Clone, Debug, Default, Serialize)]
11+
#[must_use]
12+
pub struct EditGuildIncidentActions {
13+
invites_disabled_until: Option<Timestamp>,
14+
dms_disabled_until: Option<Timestamp>,
15+
}
16+
17+
impl EditGuildIncidentActions {
18+
pub fn new() -> Self {
19+
Self::default()
20+
}
21+
22+
/// Sets the time until which guild invites will remain disabled, which can be at most 24 hours
23+
/// in the future.
24+
pub fn invites_disabled_until(mut self, timestamp: Timestamp) -> Self {
25+
self.invites_disabled_until = Some(timestamp);
26+
self
27+
}
28+
29+
/// Sets the time at which direct messages for users within the guild will remain disabled,
30+
/// which can be at most 24 hours in the future.
31+
pub fn dms_disabled_until(mut self, timestamp: Timestamp) -> Self {
32+
self.dms_disabled_until = Some(timestamp);
33+
self
34+
}
35+
36+
/// Modifies the guild's incident actions.
37+
///
38+
/// # Errors
39+
///
40+
/// Returns [`Error::Http`] if invalid data is given. See [Discord's docs] for more details.
41+
///
42+
/// May also return [`Error::Json`] if there is an error in deserializing the API response.
43+
#[cfg(feature = "http")]
44+
pub async fn execute(self, http: &Http, guild_id: GuildId) -> Result<IncidentsData> {
45+
http.edit_guild_incident_actions(guild_id, &self).await
46+
}
47+
}

src/builder/mod.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ mod create_webhook;
6161
mod edit_automod_rule;
6262
mod edit_channel;
6363
mod edit_guild;
64+
mod edit_guild_incident_actions;
6465
mod edit_guild_welcome_screen;
6566
mod edit_guild_widget;
6667
mod edit_interaction_response;
@@ -105,6 +106,7 @@ pub use create_webhook::*;
105106
pub use edit_automod_rule::*;
106107
pub use edit_channel::*;
107108
pub use edit_guild::*;
109+
pub use edit_guild_incident_actions::*;
108110
pub use edit_guild_welcome_screen::*;
109111
pub use edit_guild_widget::*;
110112
pub use edit_interaction_response::*;

src/http/client.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4871,6 +4871,29 @@ impl Http {
48714871
.await
48724872
}
48734873

4874+
/// Modify the guild's incident actions.
4875+
///
4876+
/// **Note**: Requires the [Manage Guild] permission.
4877+
///
4878+
/// [Manage Guild]: Permissions::MANAGE_GUILD
4879+
pub async fn edit_guild_incident_actions(
4880+
&self,
4881+
guild_id: GuildId,
4882+
map: &impl serde::Serialize,
4883+
) -> Result<IncidentsData> {
4884+
self.fire(Request {
4885+
body: Some(to_vec(map)?),
4886+
multipart: None,
4887+
headers: None,
4888+
method: LightMethod::Put,
4889+
route: Route::GuildIncidentActions {
4890+
guild_id,
4891+
},
4892+
params: None,
4893+
})
4894+
.await
4895+
}
4896+
48744897
/// Starts typing in the specified [`Channel`] for an indefinite period of time.
48754898
///
48764899
/// Returns [`Typing`] that is used to trigger the typing. [`Typing::stop`] must be called on

src/http/routing.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -354,6 +354,10 @@ routes! ('a, {
354354
api!("/guilds/{}/threads/active", guild_id),
355355
Some(RatelimitingKind::PathAndId(guild_id.into()));
356356

357+
GuildIncidentActions { guild_id: GuildId },
358+
api!("/guilds/{}/incident-actions", guild_id),
359+
Some(RatelimitingKind::PathAndId(guild_id.into()));
360+
357361
Guilds,
358362
api!("/guilds"),
359363
Some(RatelimitingKind::Path);

src/model/guild/guild_id.rs

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use crate::builder::{
1515
EditAutoModRule,
1616
EditCommandPermissions,
1717
EditGuild,
18+
EditGuildIncidentActions,
1819
EditGuildWelcomeScreen,
1920
EditGuildWidget,
2021
EditMember,
@@ -1787,6 +1788,28 @@ impl GuildId {
17871788
) -> Result<()> {
17881789
http.as_ref().delete_guild_soundboard(self, sound_id, audit_log_reason).await
17891790
}
1791+
1792+
/// Edits the guild incident actions
1793+
///
1794+
/// **Note**: Requires the [Manage Guild] permission.
1795+
///
1796+
/// [Manage Guild]: Permissions::MANAGE_GUILD
1797+
///
1798+
/// # Errors
1799+
///
1800+
/// Returns [`Error::Http`] if invalid data is given. See [Discord's docs] for more details.
1801+
///
1802+
/// May also return [`Error::Json`] if there is an error in deserializing the API response.
1803+
///
1804+
/// [Discord's docs]: https://discord.com/developers/docs/resources/guild#modify-guild-incident-actions
1805+
pub async fn edit_guild_incident_actions(
1806+
self,
1807+
http: &Http,
1808+
guild_id: GuildId,
1809+
builder: EditGuildIncidentActions,
1810+
) -> Result<IncidentsData> {
1811+
builder.execute(http, guild_id).await
1812+
}
17901813
}
17911814

17921815
impl From<PartialGuild> for GuildId {

src/model/guild/mod.rs

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ use crate::builder::{
4242
EditAutoModRule,
4343
EditCommandPermissions,
4444
EditGuild,
45+
EditGuildIncidentActions,
4546
EditGuildWelcomeScreen,
4647
EditGuildWidget,
4748
EditMember,
@@ -263,6 +264,10 @@ pub struct Guild {
263264
/// The stage instances in this guild.
264265
#[serde(rename = "guild_scheduled_events")]
265266
pub scheduled_events: Vec<ScheduledEvent>,
267+
/// The id of the channel where this guild will recieve safety alerts.
268+
pub safety_alerts_channel_id: Option<ChannelId>,
269+
/// The incidents data for this guild, if any.
270+
pub incidents_data: Option<IncidentsData>,
266271
}
267272

268273
#[cfg(feature = "model")]
@@ -2618,6 +2623,28 @@ impl Guild {
26182623
) -> Result<()> {
26192624
self.id.delete_soundboard(http, sound_id, audit_log_reason).await
26202625
}
2626+
2627+
/// Edits the guild incident actions
2628+
///
2629+
/// **Note**: Requires the [Manage Guild] permission.
2630+
///
2631+
/// [Manage Guild]: Permissions::MANAGE_GUILD
2632+
///
2633+
/// # Errors
2634+
///
2635+
/// Returns [`Error::Http`] if invalid data is given. See [Discord's docs] for more details.
2636+
///
2637+
/// May also return [`Error::Json`] if there is an error in deserializing the API response.
2638+
///
2639+
/// [Discord's docs]: https://discord.com/developers/docs/resources/guild#modify-guild-incident-actions
2640+
pub async fn edit_guild_incident_actions(
2641+
self,
2642+
http: &Http,
2643+
guild_id: GuildId,
2644+
builder: EditGuildIncidentActions,
2645+
) -> Result<IncidentsData> {
2646+
builder.execute(http, guild_id).await
2647+
}
26212648
}
26222649

26232650
#[cfg(feature = "model")]
@@ -2939,6 +2966,23 @@ enum_number! {
29392966
}
29402967
}
29412968

2969+
/// The [`Guild`]'s incident's data.
2970+
///
2971+
/// [Discord docs](https://discord.com/developers/docs/resources/guild#incidents-data-object).
2972+
#[derive(Clone, Copy, Debug, Deserialize, Serialize)]
2973+
#[cfg_attr(feature = "typesize", derive(typesize::derive::TypeSize))]
2974+
#[non_exhaustive]
2975+
pub struct IncidentsData {
2976+
/// The time that invites get enabled again.
2977+
pub invites_disabled_until: Option<Timestamp>,
2978+
/// The time that dms get enabled again.
2979+
pub dms_disabled_until: Option<Timestamp>,
2980+
/// The time when elevated dm activity was triggered.
2981+
pub dm_spam_detected_at: Option<Timestamp>,
2982+
/// The time when raid alerts were triggered.
2983+
pub raid_detected_at: Option<Timestamp>,
2984+
}
2985+
29422986
#[cfg(test)]
29432987
mod test {
29442988
#[cfg(feature = "model")]

src/model/guild/partial_guild.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use serde::Serialize;
22

3+
use super::IncidentsData;
34
#[cfg(feature = "model")]
45
use crate::builder::{
56
CreateChannel,
@@ -176,6 +177,10 @@ pub struct PartialGuild {
176177
pub stickers: HashMap<StickerId, Sticker>,
177178
/// Whether the guild has the boost progress bar enabled
178179
pub premium_progress_bar_enabled: bool,
180+
/// The id of the channel where this guild will recieve safety alerts.
181+
pub safety_alerts_channel_id: Option<ChannelId>,
182+
/// The incidents data for this guild, if any.
183+
pub incidents_data: Option<IncidentsData>,
179184
}
180185

181186
#[cfg(feature = "model")]
@@ -1708,6 +1713,8 @@ impl From<Guild> for PartialGuild {
17081713
preferred_locale: guild.preferred_locale,
17091714
max_stage_video_channel_users: guild.max_stage_video_channel_users,
17101715
premium_progress_bar_enabled: guild.premium_progress_bar_enabled,
1716+
safety_alerts_channel_id: guild.safety_alerts_channel_id,
1717+
incidents_data: guild.incidents_data,
17111718
}
17121719
}
17131720
}

0 commit comments

Comments
 (0)