From 709364aaef84cefad34a509ff961cff92b94ee82 Mon Sep 17 00:00:00 2001
From: Misha133 <61027276+Misha-133@users.noreply.github.com>
Date: Sun, 26 Feb 2023 22:47:13 +0300
Subject: [PATCH] AutoMod custom block message (#2613)
---
.../AutoModeration/AutoModRuleAction.cs | 9 +++++++-
.../AutoModeration/AutoModRuleBuilder.cs | 0
.../AutoModeration/AutoModRuleProperties.cs | 11 ++++++++++
.../API/Common/ActionMetadata.cs | 3 +++
.../Entities/Guilds/GuildHelper.cs | 21 ++++++++++++-------
.../Entities/Guilds/RestAutoModRule.cs | 11 +++++++++-
.../DiscordSocketClient.cs | 12 ++++++++---
.../Entities/Guilds/SocketAutoModRule.cs | 11 +++++++++-
8 files changed, 64 insertions(+), 14 deletions(-)
delete mode 100644 src/Discord.Net.Core/Entities/Guilds/AutoModeration/AutoModRuleBuilder.cs
diff --git a/src/Discord.Net.Core/Entities/Guilds/AutoModeration/AutoModRuleAction.cs b/src/Discord.Net.Core/Entities/Guilds/AutoModeration/AutoModRuleAction.cs
index 531d435a..47f8f075 100644
--- a/src/Discord.Net.Core/Entities/Guilds/AutoModeration/AutoModRuleAction.cs
+++ b/src/Discord.Net.Core/Entities/Guilds/AutoModeration/AutoModRuleAction.cs
@@ -21,16 +21,23 @@ namespace Discord
///
public ulong? ChannelId { get; }
+ ///
+ /// Gets the custom message that will be shown to members whenever their message is blocked.
+ /// if no message has been set.
+ ///
+ public Optional CustomMessage { get; set; }
+
///
/// Gets the duration of which a user will be timed out for breaking this rule. if no timeout duration has been provided.
///
public TimeSpan? TimeoutDuration { get; }
- internal AutoModRuleAction(AutoModActionType type, ulong? channelId, int? duration)
+ internal AutoModRuleAction(AutoModActionType type, ulong? channelId, int? duration, string customMessage)
{
Type = type;
ChannelId = channelId;
TimeoutDuration = duration.HasValue ? TimeSpan.FromSeconds(duration.Value) : null;
+ CustomMessage = customMessage;
}
}
}
diff --git a/src/Discord.Net.Core/Entities/Guilds/AutoModeration/AutoModRuleBuilder.cs b/src/Discord.Net.Core/Entities/Guilds/AutoModeration/AutoModRuleBuilder.cs
deleted file mode 100644
index e69de29b..00000000
diff --git a/src/Discord.Net.Core/Entities/Guilds/AutoModeration/AutoModRuleProperties.cs b/src/Discord.Net.Core/Entities/Guilds/AutoModeration/AutoModRuleProperties.cs
index 9af9832e..d4e86f06 100644
--- a/src/Discord.Net.Core/Entities/Guilds/AutoModeration/AutoModRuleProperties.cs
+++ b/src/Discord.Net.Core/Entities/Guilds/AutoModeration/AutoModRuleProperties.cs
@@ -66,6 +66,12 @@ namespace Discord
///
public const int MaxTimeoutSeconds = 2419200;
+ ///
+ /// Returns the max custom message length AutoMod rule action allowed by Discord.
+ ///
+ public const int MaxCustomBlockMessageLength = 50;
+
+
///
/// Gets or sets the name for the rule.
///
@@ -146,6 +152,11 @@ namespace Discord
/// Gets or sets the duration of which a user will be timed out for breaking this rule.
///
public TimeSpan? TimeoutDuration { get; set; }
+
+ ///
+ /// Gets or sets the custom message that will be shown to members whenever their message is blocked.
+ ///
+ public Optional CustomMessage { get; set; }
}
}
diff --git a/src/Discord.Net.Rest/API/Common/ActionMetadata.cs b/src/Discord.Net.Rest/API/Common/ActionMetadata.cs
index 148c54cd..93b85d0e 100644
--- a/src/Discord.Net.Rest/API/Common/ActionMetadata.cs
+++ b/src/Discord.Net.Rest/API/Common/ActionMetadata.cs
@@ -14,5 +14,8 @@ namespace Discord.API
[JsonProperty("duration_seconds")]
public Optional DurationSeconds { get; set; }
+
+ [JsonProperty("custom_message")]
+ public Optional CustomMessage { get; set; }
}
}
diff --git a/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs b/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs
index 15005f7e..bbcb2bb5 100644
--- a/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs
+++ b/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs
@@ -1071,6 +1071,8 @@ namespace Discord.Rest
var args = new AutoModRuleProperties();
func(args);
+ #region Validations
+
if (!args.TriggerType.IsSpecified)
throw new ArgumentException(message: $"AutoMod rule must have a specified type.", paramName: nameof(args.TriggerType));
@@ -1078,9 +1080,7 @@ namespace Discord.Rest
throw new ArgumentException("Name of the rule must not be empty", paramName: nameof(args.Name));
Preconditions.AtLeast(1, args.Actions.GetValueOrDefault(Array.Empty()).Length, nameof(args.Actions), "Auto moderation rule must have at least 1 action");
-
- #region Keyword Validations
-
+
if (args.RegexPatterns.IsSpecified)
{
if (args.TriggerType.Value is not AutoModTriggerType.Keyword)
@@ -1124,9 +1124,7 @@ namespace Discord.Rest
if (args.TriggerType.Value is not AutoModTriggerType.KeywordPreset && args.Presets.IsSpecified)
throw new ArgumentException(message: $"Keyword presets scan only be used with 'KeywordPreset' trigger type.", paramName: nameof(args.Presets));
-
- #endregion
-
+
if (args.MentionLimit.IsSpecified)
{
if (args.TriggerType.Value is AutoModTriggerType.MentionSpam)
@@ -1154,6 +1152,11 @@ namespace Discord.Rest
if (args.Actions.Value.Any(x => x.TimeoutDuration.GetValueOrDefault().TotalSeconds > AutoModRuleProperties.MaxTimeoutSeconds))
throw new ArgumentException(message: $"Field count must be less than or equal to {AutoModRuleProperties.MaxTimeoutSeconds}.", paramName: nameof(AutoModRuleActionProperties.TimeoutDuration));
+ if (args.Actions.Value.Any(x => x.CustomMessage.IsSpecified && x.CustomMessage.Value.Length > AutoModRuleProperties.MaxCustomBlockMessageLength))
+ throw new ArgumentException(message: $"Custom message length must be less than or equal to {AutoModRuleProperties.MaxCustomBlockMessageLength}.", paramName: nameof(AutoModRuleActionProperties.CustomMessage));
+
+ #endregion
+
var props = new CreateAutoModRuleParams
{
EventType = args.EventType.GetValueOrDefault(AutoModEventType.MessageSend),
@@ -1167,7 +1170,8 @@ namespace Discord.Rest
Metadata = new ActionMetadata
{
ChannelId = x.ChannelId ?? Optional.Unspecified,
- DurationSeconds = (int?)x.TimeoutDuration?.TotalSeconds ?? Optional.Unspecified
+ DurationSeconds = (int?)x.TimeoutDuration?.TotalSeconds ?? Optional.Unspecified,
+ CustomMessage = x.CustomMessage,
},
Type = x.Type
}).ToArray(),
@@ -1203,7 +1207,8 @@ namespace Discord.Rest
Metadata = x.ChannelId.HasValue || x.TimeoutDuration.HasValue ? new API.ActionMetadata
{
ChannelId = x.ChannelId ?? Optional.Unspecified,
- DurationSeconds = x.TimeoutDuration.HasValue ? (int)Math.Floor(x.TimeoutDuration.Value.TotalSeconds) : Optional.Unspecified
+ DurationSeconds = x.TimeoutDuration.HasValue ? (int)Math.Floor(x.TimeoutDuration.Value.TotalSeconds) : Optional.Unspecified,
+ CustomMessage = x.CustomMessage,
} : Optional.Unspecified
}).ToArray() : Optional.Unspecified,
Enabled = args.Enabled,
diff --git a/src/Discord.Net.Rest/Entities/Guilds/RestAutoModRule.cs b/src/Discord.Net.Rest/Entities/Guilds/RestAutoModRule.cs
index f2dc4c9b..2b7b07b7 100644
--- a/src/Discord.Net.Rest/Entities/Guilds/RestAutoModRule.cs
+++ b/src/Discord.Net.Rest/Entities/Guilds/RestAutoModRule.cs
@@ -82,7 +82,16 @@ public class RestAutoModRule : RestEntity, IAutoModRule
MentionTotalLimit = model.TriggerMetadata.MentionLimit.IsSpecified
? model.TriggerMetadata.MentionLimit.Value
: null;
- Actions = model.Actions.Select(x => new AutoModRuleAction(x.Type, x.Metadata.GetValueOrDefault()?.ChannelId.ToNullable(), x.Metadata.GetValueOrDefault()?.DurationSeconds.ToNullable())).ToImmutableArray();
+ Actions = model.Actions.Select(x => new AutoModRuleAction(
+ x.Type,
+ x.Metadata.GetValueOrDefault()?.ChannelId.ToNullable(),
+ x.Metadata.GetValueOrDefault()?.DurationSeconds.ToNullable(),
+ x.Metadata.IsSpecified
+ ? x.Metadata.Value.CustomMessage.IsSpecified
+ ? x.Metadata.Value.CustomMessage.Value
+ : null
+ : null
+ )).ToImmutableArray();
Enabled = model.Enabled;
ExemptRoles = model.ExemptRoles.ToImmutableArray();
ExemptChannels = model.ExemptChannels.ToImmutableArray();
diff --git a/src/Discord.Net.WebSocket/DiscordSocketClient.cs b/src/Discord.Net.WebSocket/DiscordSocketClient.cs
index f2091df9..99c9af97 100644
--- a/src/Discord.Net.WebSocket/DiscordSocketClient.cs
+++ b/src/Discord.Net.WebSocket/DiscordSocketClient.cs
@@ -2895,7 +2895,7 @@ namespace Discord.WebSocket
var rule = guild.AddOrUpdateAutoModRule(data);
- await TimedInvokeAsync(_autoModRuleCreated, nameof(AutoModRuleCreated), rule);
+ await TimedInvokeAsync(_autoModRuleCreated, nameof(AutoModRuleCreated), rule);
}
break;
@@ -2942,8 +2942,14 @@ namespace Discord.WebSocket
? data.Action.Metadata.Value.DurationSeconds.IsSpecified
? data.Action.Metadata.Value.DurationSeconds.Value
: null
+ : null,
+ data.Action.Metadata.IsSpecified
+ ? data.Action.Metadata.Value.CustomMessage.IsSpecified
+ ? data.Action.Metadata.Value.CustomMessage.Value
+ : null
: null);
+
var member = guild.GetUser(data.UserId);
var cacheableUser = new Cacheable(member,
@@ -2965,7 +2971,7 @@ namespace Discord.WebSocket
channel != null,
async () =>
{
- if(data.ChannelId.IsSpecified)
+ if (data.ChannelId.IsSpecified)
return await GetChannelAsync(data.ChannelId.Value).ConfigureAwait(false) as ISocketMessageChannel;
return null;
});
@@ -2980,7 +2986,7 @@ namespace Discord.WebSocket
cachedMsg is not null,
async () =>
{
- if(data.MessageId.IsSpecified)
+ if (data.MessageId.IsSpecified)
return (await channel!.GetMessageAsync(data.MessageId.Value).ConfigureAwait(false)) as IUserMessage;
return null;
});
diff --git a/src/Discord.Net.WebSocket/Entities/Guilds/SocketAutoModRule.cs b/src/Discord.Net.WebSocket/Entities/Guilds/SocketAutoModRule.cs
index d562c5a2..844a6828 100644
--- a/src/Discord.Net.WebSocket/Entities/Guilds/SocketAutoModRule.cs
+++ b/src/Discord.Net.WebSocket/Entities/Guilds/SocketAutoModRule.cs
@@ -93,7 +93,16 @@ namespace Discord.WebSocket
MentionTotalLimit = model.TriggerMetadata.MentionLimit.IsSpecified
? model.TriggerMetadata.MentionLimit.Value
: null;
- Actions = model.Actions.Select(x => new AutoModRuleAction(x.Type, x.Metadata.GetValueOrDefault()?.ChannelId.ToNullable(), x.Metadata.GetValueOrDefault()?.DurationSeconds.ToNullable())).ToImmutableArray();
+ Actions = model.Actions.Select(x => new AutoModRuleAction(
+ x.Type,
+ x.Metadata.GetValueOrDefault()?.ChannelId.ToNullable(),
+ x.Metadata.GetValueOrDefault()?.DurationSeconds.ToNullable(),
+ x.Metadata.IsSpecified
+ ? x.Metadata.Value.CustomMessage.IsSpecified
+ ? x.Metadata.Value.CustomMessage.Value
+ : null
+ : null
+ )).ToImmutableArray();
Enabled = model.Enabled;
ExemptRoles = model.ExemptRoles.Select(x => Guild.GetRole(x)).ToImmutableArray();
ExemptChannels = model.ExemptChannels.Select(x => Guild.GetChannel(x)).ToImmutableArray();