From b3eca749aaa952464909619157ad58c6113cd770 Mon Sep 17 00:00:00 2001 From: Jarl Gullberg Date: Sat, 17 Jun 2023 15:38:31 +0200 Subject: [PATCH] Implement support for join raid and mention raid protection. See discord/discord-api-docs#5778. --- .../AutoModeration/IAutoModerationTriggerMetadata.cs | 5 +++++ .../API/Objects/Guilds/GuildFeature.cs | 5 +++++ .../API/Objects/Guilds/IGuild.cs | 8 ++++++++ .../API/Objects/Guilds/IPartialGuild.cs | 3 +++ .../API/Rest/IDiscordRestGuildAPI.cs | 4 ++++ .../API/Gateway/Events/Guilds/GuildCreate.cs | 1 + .../API/Gateway/Events/Guilds/GuildUpdate.cs | 3 ++- .../AutoModeration/AutoModerationTriggerMetadata.cs | 3 ++- Backend/Remora.Discord.API/API/Objects/Guilds/Guild.cs | 3 ++- .../Remora.Discord.API/API/Objects/Guilds/PartialGuild.cs | 3 ++- .../API/CachingDiscordRestGuildAPI.cs | 2 ++ .../Remora.Discord.Rest/API/Guilds/DiscordRestGuildAPI.cs | 2 ++ .../API/Guild/DiscordRestGuildAPITests.cs | 7 ++++++- .../Samples/Gateway/Events/GUILD_CREATE/GUILD_CREATE.json | 1 + .../Gateway/Events/GUILD_CREATE/GUILD_CREATE.nulls.json | 1 + .../Events/GUILD_CREATE/GUILD_CREATE.optionals.json | 1 + .../Samples/Gateway/Events/GUILD_UPDATE/GUILD_UPDATE.json | 3 ++- .../Gateway/Events/GUILD_UPDATE/GUILD_UPDATE.nulls.json | 3 ++- .../Events/GUILD_UPDATE/GUILD_UPDATE.optionals.json | 3 ++- .../AUTO_MODERATION_TRIGGER_METADATA.json | 3 ++- .../Remora.Discord.Tests/Samples/Objects/GUILD/GUILD.json | 3 ++- .../Samples/Objects/GUILD/GUILD.nulls.json | 3 ++- .../Samples/Objects/GUILD/GUILD.optionals.json | 3 ++- 23 files changed, 61 insertions(+), 12 deletions(-) diff --git a/Backend/Remora.Discord.API.Abstractions/API/Objects/AutoModeration/IAutoModerationTriggerMetadata.cs b/Backend/Remora.Discord.API.Abstractions/API/Objects/AutoModeration/IAutoModerationTriggerMetadata.cs index 3ed75e711d..c6edec0011 100644 --- a/Backend/Remora.Discord.API.Abstractions/API/Objects/AutoModeration/IAutoModerationTriggerMetadata.cs +++ b/Backend/Remora.Discord.API.Abstractions/API/Objects/AutoModeration/IAutoModerationTriggerMetadata.cs @@ -78,4 +78,9 @@ public interface IAutoModerationTriggerMetadata /// Max 50. /// Optional MentionTotalLimit { get; } + + /// + /// Gets a value indicating whether to automatically detect mention raids. + /// + Optional MentionRaidProtectionEnabled { get; } } diff --git a/Backend/Remora.Discord.API.Abstractions/API/Objects/Guilds/GuildFeature.cs b/Backend/Remora.Discord.API.Abstractions/API/Objects/Guilds/GuildFeature.cs index e0ba57f934..cb7f00f5b6 100644 --- a/Backend/Remora.Discord.API.Abstractions/API/Objects/Guilds/GuildFeature.cs +++ b/Backend/Remora.Discord.API.Abstractions/API/Objects/Guilds/GuildFeature.cs @@ -125,6 +125,11 @@ public enum GuildFeature /// PreviewEnabled, + /// + /// The guild has disabled alerts for join raids in the configured safety alerts channel. + /// + RaidAlertsDisabled, + /// /// The guild is able to set role icons. /// diff --git a/Backend/Remora.Discord.API.Abstractions/API/Objects/Guilds/IGuild.cs b/Backend/Remora.Discord.API.Abstractions/API/Objects/Guilds/IGuild.cs index 3dd5f1dcb6..e6149f1ef3 100644 --- a/Backend/Remora.Discord.API.Abstractions/API/Objects/Guilds/IGuild.cs +++ b/Backend/Remora.Discord.API.Abstractions/API/Objects/Guilds/IGuild.cs @@ -243,6 +243,11 @@ public interface IGuild : IPartialGuild /// new bool IsPremiumProgressBarEnabled { get; } + /// + /// Gets the ID of the channel where admins and moderators of Community guilds receive safety alerts from Discord. + /// + new Snowflake? SafetyAlertsChannelID { get; } + /// Optional IPartialGuild.ID => this.ID; @@ -365,4 +370,7 @@ public interface IGuild : IPartialGuild /// Optional IPartialGuild.IsPremiumProgressBarEnabled => this.IsPremiumProgressBarEnabled; + + /// + Optional IPartialGuild.SafetyAlertsChannelID => this.SafetyAlertsChannelID; } diff --git a/Backend/Remora.Discord.API.Abstractions/API/Objects/Guilds/IPartialGuild.cs b/Backend/Remora.Discord.API.Abstractions/API/Objects/Guilds/IPartialGuild.cs index d43ce864cb..e96e53b516 100644 --- a/Backend/Remora.Discord.API.Abstractions/API/Objects/Guilds/IPartialGuild.cs +++ b/Backend/Remora.Discord.API.Abstractions/API/Objects/Guilds/IPartialGuild.cs @@ -155,4 +155,7 @@ public interface IPartialGuild /// Optional IsPremiumProgressBarEnabled { get; } + + /// + Optional SafetyAlertsChannelID { get; } } diff --git a/Backend/Remora.Discord.API.Abstractions/API/Rest/IDiscordRestGuildAPI.cs b/Backend/Remora.Discord.API.Abstractions/API/Rest/IDiscordRestGuildAPI.cs index 5ed7624d9e..5e7cf3d231 100644 --- a/Backend/Remora.Discord.API.Abstractions/API/Rest/IDiscordRestGuildAPI.cs +++ b/Backend/Remora.Discord.API.Abstractions/API/Rest/IDiscordRestGuildAPI.cs @@ -131,6 +131,9 @@ Task> GetGuildPreviewAsync /// The new guild features. /// The new description. /// Whether the guild has the boost progress bar enabled. + /// + /// The ID of the channel where admins and moderators of Community guilds receive safety alerts from Discord. + /// /// The reason to mark the action in the audit log with. /// The cancellation token for this operation. /// A modification result which may or may not have succeeded. @@ -156,6 +159,7 @@ Task> ModifyGuildAsync Optional> features = default, Optional description = default, Optional isPremiumProgressBarEnabled = default, + Optional safetyAlertsChannelID = default, Optional reason = default, CancellationToken ct = default ); diff --git a/Backend/Remora.Discord.API/API/Gateway/Events/Guilds/GuildCreate.cs b/Backend/Remora.Discord.API/API/Gateway/Events/Guilds/GuildCreate.cs index c2b544e533..9081b52898 100644 --- a/Backend/Remora.Discord.API/API/Gateway/Events/Guilds/GuildCreate.cs +++ b/Backend/Remora.Discord.API/API/Gateway/Events/Guilds/GuildCreate.cs @@ -79,6 +79,7 @@ public record AvailableGuild GuildNSFWLevel NSFWLevel, Optional> Stickers, bool IsPremiumProgressBarEnabled, + Snowflake? SafetyAlertsChannelID, DateTimeOffset JoinedAt, bool IsLarge, Optional IsUnavailable, diff --git a/Backend/Remora.Discord.API/API/Gateway/Events/Guilds/GuildUpdate.cs b/Backend/Remora.Discord.API/API/Gateway/Events/Guilds/GuildUpdate.cs index 0eb41511eb..16faa27350 100644 --- a/Backend/Remora.Discord.API/API/Gateway/Events/Guilds/GuildUpdate.cs +++ b/Backend/Remora.Discord.API/API/Gateway/Events/Guilds/GuildUpdate.cs @@ -73,5 +73,6 @@ public record GuildUpdate Optional WelcomeScreen, GuildNSFWLevel NSFWLevel, Optional> Stickers, - bool IsPremiumProgressBarEnabled + bool IsPremiumProgressBarEnabled, + Snowflake? SafetyAlertsChannelID ) : IGuildUpdate; diff --git a/Backend/Remora.Discord.API/API/Objects/AutoModeration/AutoModerationTriggerMetadata.cs b/Backend/Remora.Discord.API/API/Objects/AutoModeration/AutoModerationTriggerMetadata.cs index 3fc8f610fd..2f876953e3 100644 --- a/Backend/Remora.Discord.API/API/Objects/AutoModeration/AutoModerationTriggerMetadata.cs +++ b/Backend/Remora.Discord.API/API/Objects/AutoModeration/AutoModerationTriggerMetadata.cs @@ -35,5 +35,6 @@ public record AutoModerationTriggerMetadata Optional> RegexPatterns = default, Optional> Presets = default, Optional> AllowList = default, - Optional MentionTotalLimit = default + Optional MentionTotalLimit = default, + Optional MentionRaidProtectionEnabled = default ) : IAutoModerationTriggerMetadata; diff --git a/Backend/Remora.Discord.API/API/Objects/Guilds/Guild.cs b/Backend/Remora.Discord.API/API/Objects/Guilds/Guild.cs index 3bf7958489..a6fbada17b 100644 --- a/Backend/Remora.Discord.API/API/Objects/Guilds/Guild.cs +++ b/Backend/Remora.Discord.API/API/Objects/Guilds/Guild.cs @@ -74,5 +74,6 @@ public record Guild Optional WelcomeScreen, GuildNSFWLevel NSFWLevel, Optional> Stickers, - bool IsPremiumProgressBarEnabled + bool IsPremiumProgressBarEnabled, + Snowflake? SafetyAlertsChannelID ) : IGuild; diff --git a/Backend/Remora.Discord.API/API/Objects/Guilds/PartialGuild.cs b/Backend/Remora.Discord.API/API/Objects/Guilds/PartialGuild.cs index 0dbef0fc62..b4371a17cc 100644 --- a/Backend/Remora.Discord.API/API/Objects/Guilds/PartialGuild.cs +++ b/Backend/Remora.Discord.API/API/Objects/Guilds/PartialGuild.cs @@ -74,5 +74,6 @@ public record PartialGuild Optional WelcomeScreen = default, Optional NSFWLevel = default, Optional> Stickers = default, - Optional IsPremiumProgressBarEnabled = default + Optional IsPremiumProgressBarEnabled = default, + Optional SafetyAlertsChannelID = default ) : IPartialGuild; diff --git a/Backend/Remora.Discord.Caching/API/CachingDiscordRestGuildAPI.cs b/Backend/Remora.Discord.Caching/API/CachingDiscordRestGuildAPI.cs index b5a6fb05c2..26545c18f0 100644 --- a/Backend/Remora.Discord.Caching/API/CachingDiscordRestGuildAPI.cs +++ b/Backend/Remora.Discord.Caching/API/CachingDiscordRestGuildAPI.cs @@ -183,6 +183,7 @@ public async Task> ModifyGuildAsync Optional> features = default, Optional description = default, Optional isPremiumProgressBarEnabled = default, + Optional safetyAlertsChannelID = default, Optional reason = default, CancellationToken ct = default ) @@ -209,6 +210,7 @@ public async Task> ModifyGuildAsync features, description, isPremiumProgressBarEnabled, + safetyAlertsChannelID, reason, ct ); diff --git a/Backend/Remora.Discord.Rest/API/Guilds/DiscordRestGuildAPI.cs b/Backend/Remora.Discord.Rest/API/Guilds/DiscordRestGuildAPI.cs index ea5ba67003..86a75edd4c 100644 --- a/Backend/Remora.Discord.Rest/API/Guilds/DiscordRestGuildAPI.cs +++ b/Backend/Remora.Discord.Rest/API/Guilds/DiscordRestGuildAPI.cs @@ -191,6 +191,7 @@ public virtual async Task> ModifyGuildAsync Optional> features = default, Optional description = default, Optional isPremiumProgressBarEnabled = default, + Optional safetyAlertsChannelID = default, Optional reason = default, CancellationToken ct = default ) @@ -263,6 +264,7 @@ public virtual async Task> ModifyGuildAsync json.Write("features", features, this.JsonOptions); json.Write("description", description, this.JsonOptions); json.Write("premium_progress_bar_enabled", isPremiumProgressBarEnabled, this.JsonOptions); + json.Write("safety_alerts_channel_id", safetyAlertsChannelID, this.JsonOptions); } ) .WithRateLimitContext(this.RateLimitCache), diff --git a/Tests/Remora.Discord.Rest.Tests/API/Guild/DiscordRestGuildAPITests.cs b/Tests/Remora.Discord.Rest.Tests/API/Guild/DiscordRestGuildAPITests.cs index c506f7ef9f..36759acb86 100644 --- a/Tests/Remora.Discord.Rest.Tests/API/Guild/DiscordRestGuildAPITests.cs +++ b/Tests/Remora.Discord.Rest.Tests/API/Guild/DiscordRestGuildAPITests.cs @@ -346,6 +346,7 @@ public async Task PerformsRequestCorrectly() var features = Array.Empty(); var description = "aaa"; var isPremiumProgressBarEnabled = true; + var safetyAlertsChannel = DiscordSnowflake.New(5); var reason = "test"; var api = CreateAPI @@ -381,6 +382,7 @@ public async Task PerformsRequestCorrectly() .WithProperty("features", p => p.IsArray()) .WithProperty("description", p => p.Is(description)) .WithProperty("premium_progress_bar_enabled", p => p.Is(isPremiumProgressBarEnabled)) + .WithProperty("safety_alerts_channel_id", p => p.Is(safetyAlertsChannel.ToString())) ) ) .Respond("application/json", SampleRepository.Samples[typeof(IGuild)]) @@ -408,6 +410,7 @@ public async Task PerformsRequestCorrectly() features, description, isPremiumProgressBarEnabled, + safetyAlertsChannel, reason ); @@ -436,6 +439,7 @@ public async Task PerformsNullableRequestCorrectly() .WithProperty("icon", p => p.IsNull()) .WithProperty("splash", p => p.IsNull()) .WithProperty("banner", p => p.IsNull()) + .WithProperty("safety_alerts_channel_id", p => p.IsNull()) ) ) .Respond("application/json", SampleRepository.Samples[typeof(IGuild)]) @@ -447,7 +451,8 @@ public async Task PerformsNullableRequestCorrectly() name, icon: null, banner: null, - splash: null + splash: null, + safetyAlertsChannelID: null ); ResultAssert.Successful(result); diff --git a/Tests/Remora.Discord.Tests/Samples/Gateway/Events/GUILD_CREATE/GUILD_CREATE.json b/Tests/Remora.Discord.Tests/Samples/Gateway/Events/GUILD_CREATE/GUILD_CREATE.json index 1bd0c70b5f..0026d2653d 100644 --- a/Tests/Remora.Discord.Tests/Samples/Gateway/Events/GUILD_CREATE/GUILD_CREATE.json +++ b/Tests/Remora.Discord.Tests/Samples/Gateway/Events/GUILD_CREATE/GUILD_CREATE.json @@ -74,6 +74,7 @@ } ], "premium_progress_bar_enabled": true, + "safety_alerts_channel_id": "999999999999999999", "joined_at": "1970-01-01T00:00:00.000000+00:00", "large": true, "unavailable": true, diff --git a/Tests/Remora.Discord.Tests/Samples/Gateway/Events/GUILD_CREATE/GUILD_CREATE.nulls.json b/Tests/Remora.Discord.Tests/Samples/Gateway/Events/GUILD_CREATE/GUILD_CREATE.nulls.json index 840c7a3527..23b35c6d19 100644 --- a/Tests/Remora.Discord.Tests/Samples/Gateway/Events/GUILD_CREATE/GUILD_CREATE.nulls.json +++ b/Tests/Remora.Discord.Tests/Samples/Gateway/Events/GUILD_CREATE/GUILD_CREATE.nulls.json @@ -73,6 +73,7 @@ } ], "premium_progress_bar_enabled": true, + "safety_alerts_channel_id": null, "joined_at": "1970-01-01T00:00:00.000000+00:00", "large": true, "unavailable": true, diff --git a/Tests/Remora.Discord.Tests/Samples/Gateway/Events/GUILD_CREATE/GUILD_CREATE.optionals.json b/Tests/Remora.Discord.Tests/Samples/Gateway/Events/GUILD_CREATE/GUILD_CREATE.optionals.json index e2c667a9c4..f887c71a32 100644 --- a/Tests/Remora.Discord.Tests/Samples/Gateway/Events/GUILD_CREATE/GUILD_CREATE.optionals.json +++ b/Tests/Remora.Discord.Tests/Samples/Gateway/Events/GUILD_CREATE/GUILD_CREATE.optionals.json @@ -49,6 +49,7 @@ "public_updates_channel_id": "999999999999999999", "nsfw_level": 0, "premium_progress_bar_enabled": true, + "safety_alerts_channel_id": "999999999999999999", "joined_at": "1970-01-01T00:00:00.000000+00:00", "large": true, "member_count": 1, diff --git a/Tests/Remora.Discord.Tests/Samples/Gateway/Events/GUILD_UPDATE/GUILD_UPDATE.json b/Tests/Remora.Discord.Tests/Samples/Gateway/Events/GUILD_UPDATE/GUILD_UPDATE.json index 5ec4085381..549a49bcc8 100644 --- a/Tests/Remora.Discord.Tests/Samples/Gateway/Events/GUILD_UPDATE/GUILD_UPDATE.json +++ b/Tests/Remora.Discord.Tests/Samples/Gateway/Events/GUILD_UPDATE/GUILD_UPDATE.json @@ -73,6 +73,7 @@ "format_type": 1 } ], - "premium_progress_bar_enabled": true + "premium_progress_bar_enabled": true, + "safety_alerts_channel_id": "999999999999999999" } } diff --git a/Tests/Remora.Discord.Tests/Samples/Gateway/Events/GUILD_UPDATE/GUILD_UPDATE.nulls.json b/Tests/Remora.Discord.Tests/Samples/Gateway/Events/GUILD_UPDATE/GUILD_UPDATE.nulls.json index 7abcdf9db0..c6c1f82ff3 100644 --- a/Tests/Remora.Discord.Tests/Samples/Gateway/Events/GUILD_UPDATE/GUILD_UPDATE.nulls.json +++ b/Tests/Remora.Discord.Tests/Samples/Gateway/Events/GUILD_UPDATE/GUILD_UPDATE.nulls.json @@ -72,6 +72,7 @@ "format_type": 1 } ], - "premium_progress_bar_enabled": true + "premium_progress_bar_enabled": true, + "safety_alerts_channel_id": null } } diff --git a/Tests/Remora.Discord.Tests/Samples/Gateway/Events/GUILD_UPDATE/GUILD_UPDATE.optionals.json b/Tests/Remora.Discord.Tests/Samples/Gateway/Events/GUILD_UPDATE/GUILD_UPDATE.optionals.json index ddab360cc3..f8ae0933ef 100644 --- a/Tests/Remora.Discord.Tests/Samples/Gateway/Events/GUILD_UPDATE/GUILD_UPDATE.optionals.json +++ b/Tests/Remora.Discord.Tests/Samples/Gateway/Events/GUILD_UPDATE/GUILD_UPDATE.optionals.json @@ -48,6 +48,7 @@ "preferred_locale": "en-US", "public_updates_channel_id": "999999999999999999", "nsfw_level": 0, - "premium_progress_bar_enabled": true + "premium_progress_bar_enabled": true, + "safety_alerts_channel_id": "999999999999999999" } } diff --git a/Tests/Remora.Discord.Tests/Samples/Objects/AUTO_MODERATION_TRIGGER_METADATA/AUTO_MODERATION_TRIGGER_METADATA.json b/Tests/Remora.Discord.Tests/Samples/Objects/AUTO_MODERATION_TRIGGER_METADATA/AUTO_MODERATION_TRIGGER_METADATA.json index 17d47e21db..66c21c1b55 100644 --- a/Tests/Remora.Discord.Tests/Samples/Objects/AUTO_MODERATION_TRIGGER_METADATA/AUTO_MODERATION_TRIGGER_METADATA.json +++ b/Tests/Remora.Discord.Tests/Samples/Objects/AUTO_MODERATION_TRIGGER_METADATA/AUTO_MODERATION_TRIGGER_METADATA.json @@ -11,5 +11,6 @@ "allow_list": [ "none" ], - "mention_total_limit": 1 + "mention_total_limit": 1, + "mention_raid_protection_enabled": true } diff --git a/Tests/Remora.Discord.Tests/Samples/Objects/GUILD/GUILD.json b/Tests/Remora.Discord.Tests/Samples/Objects/GUILD/GUILD.json index b558e93c2f..0b98ebf6ba 100644 --- a/Tests/Remora.Discord.Tests/Samples/Objects/GUILD/GUILD.json +++ b/Tests/Remora.Discord.Tests/Samples/Objects/GUILD/GUILD.json @@ -69,5 +69,6 @@ "format_type": 1 } ], - "premium_progress_bar_enabled": true + "premium_progress_bar_enabled": true, + "safety_alerts_channel_id": "999999999999999999" } diff --git a/Tests/Remora.Discord.Tests/Samples/Objects/GUILD/GUILD.nulls.json b/Tests/Remora.Discord.Tests/Samples/Objects/GUILD/GUILD.nulls.json index d94601c3cb..28cf621b02 100644 --- a/Tests/Remora.Discord.Tests/Samples/Objects/GUILD/GUILD.nulls.json +++ b/Tests/Remora.Discord.Tests/Samples/Objects/GUILD/GUILD.nulls.json @@ -68,5 +68,6 @@ "format_type": 1 } ], - "premium_progress_bar_enabled": true + "premium_progress_bar_enabled": true, + "safety_alerts_channel_id": null } diff --git a/Tests/Remora.Discord.Tests/Samples/Objects/GUILD/GUILD.optionals.json b/Tests/Remora.Discord.Tests/Samples/Objects/GUILD/GUILD.optionals.json index 3e15139706..8d718d5d23 100644 --- a/Tests/Remora.Discord.Tests/Samples/Objects/GUILD/GUILD.optionals.json +++ b/Tests/Remora.Discord.Tests/Samples/Objects/GUILD/GUILD.optionals.json @@ -44,5 +44,6 @@ "preferred_locale": "en-US", "public_updates_channel_id": "999999999999999999", "nsfw_level": 0, - "premium_progress_bar_enabled": true + "premium_progress_bar_enabled": true, + "safety_alerts_channel_id": "999999999999999999" }