diff --git a/src/Discord.Net.Core/Entities/Guilds/AutoModeration/AutoModActionType.cs b/src/Discord.Net.Core/Entities/Guilds/AutoModeration/AutoModActionType.cs
new file mode 100644
index 000000000..29e95d918
--- /dev/null
+++ b/src/Discord.Net.Core/Entities/Guilds/AutoModeration/AutoModActionType.cs
@@ -0,0 +1,26 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Discord
+{
+ public enum AutoModActionType
+ {
+ ///
+ /// Blocks the content of a message according to the rule.
+ ///
+ BlockMessage = 1,
+
+ ///
+ /// Logs user content to a specified channel.
+ ///
+ SendAlertMessage = 2,
+
+ ///
+ /// Timeout user for a specified duration.
+ ///
+ Timeout = 3,
+ }
+}
diff --git a/src/Discord.Net.Core/Entities/Guilds/AutoModeration/AutoModEventType.cs b/src/Discord.Net.Core/Entities/Guilds/AutoModeration/AutoModEventType.cs
new file mode 100644
index 000000000..3585dece1
--- /dev/null
+++ b/src/Discord.Net.Core/Entities/Guilds/AutoModeration/AutoModEventType.cs
@@ -0,0 +1,19 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Discord
+{
+ ///
+ /// An enum indecating in what event context a rule should be checked.
+ ///
+ public enum AutoModEventType
+ {
+ ///
+ /// When a member sends or edits a message in the guild
+ ///
+ MessageSend = 1
+ }
+}
diff --git a/src/Discord.Net.Core/Entities/Guilds/AutoModeration/AutoModRuleAction.cs b/src/Discord.Net.Core/Entities/Guilds/AutoModeration/AutoModRuleAction.cs
new file mode 100644
index 000000000..7d7f3622a
--- /dev/null
+++ b/src/Discord.Net.Core/Entities/Guilds/AutoModeration/AutoModRuleAction.cs
@@ -0,0 +1,36 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Discord
+{
+ ///
+ /// Represents an action that will be preformed if a user breaks an .
+ ///
+ public class AutoModRuleAction
+ {
+ ///
+ /// Gets the type for this action.
+ ///
+ public AutoModActionType Type { get; }
+
+ ///
+ /// Get the channel id on which to post alerts.
+ ///
+ public ulong? ChannelId { get; }
+
+ ///
+ /// Gets the duration of which a user will be timed out for breaking this rule.
+ ///
+ public TimeSpan? TimeoutDuration { get; }
+
+ internal AutoModRuleAction(AutoModActionType type, ulong? channelId, int? duration)
+ {
+ Type = type;
+ ChannelId = channelId;
+ TimeoutDuration = duration.HasValue ? TimeSpan.FromSeconds(duration.Value) : null;
+ }
+ }
+}
diff --git a/src/Discord.Net.Core/Entities/Guilds/AutoModeration/AutoModRuleProperties.cs b/src/Discord.Net.Core/Entities/Guilds/AutoModeration/AutoModRuleProperties.cs
new file mode 100644
index 000000000..e91276947
--- /dev/null
+++ b/src/Discord.Net.Core/Entities/Guilds/AutoModeration/AutoModRuleProperties.cs
@@ -0,0 +1,78 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Discord
+{
+ ///
+ /// Provides properties used to modify a .
+ ///
+ public class AutoModRuleProperties
+ {
+ ///
+ /// Gets or sets the name for the rule.
+ ///
+ public Optional Name { get; set; }
+
+ ///
+ /// Gets or sets the event type for the rule.
+ ///
+ public Optional EventType { get; set; }
+
+ ///
+ /// Gets or sets the trigger type for the rule.
+ ///
+ public Optional TriggerType { get; set; }
+
+ ///
+ /// Gets or sets the keyword filter for the rule.
+ ///
+ public Optional KeywordFilter { get; set; }
+
+ ///
+ /// Gets or sets the presets for the rule.
+ ///
+ public Optional Presets { get; set; }
+
+ ///
+ /// Gets or sets the actions for the rule.
+ ///
+ public Optional Actions { get; set; }
+
+ ///
+ /// Gets or sets whether or not the rule is enabled.
+ ///
+ public Optional Enabled { get; set; }
+
+ ///
+ /// Gets or sets the exempt roles for the rule.
+ ///
+ public Optional ExemptRoles { get; set; }
+
+ ///
+ /// Gets or sets the exempt channels for the rule.
+ ///
+ public Optional ExemptChannels { get; set; }
+ }
+
+ public class AutoModRuleActionProperties
+ {
+ ///
+ /// Gets or sets the type for this action.
+ ///
+ public AutoModActionType Type { get; set; }
+
+ ///
+ /// Get or sets the channel id on which to post alerts.
+ ///
+ public ulong? ChannelId { get; set; }
+
+ ///
+ /// Gets or sets the duration of which a user will be timed out for breaking this rule.
+ ///
+ public TimeSpan? TimeoutDuration { get; set; }
+ }
+
+}
diff --git a/src/Discord.Net.Core/Entities/Guilds/AutoModeration/AutoModTriggerType.cs b/src/Discord.Net.Core/Entities/Guilds/AutoModeration/AutoModTriggerType.cs
new file mode 100644
index 000000000..8922d697a
--- /dev/null
+++ b/src/Discord.Net.Core/Entities/Guilds/AutoModeration/AutoModTriggerType.cs
@@ -0,0 +1,34 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Discord
+{
+ ///
+ /// An enum representing the type of content which can trigger the rule.
+ ///
+ public enum AutoModTriggerType
+ {
+ ///
+ /// Check if content contains words from a user defined list of keywords
+ ///
+ Keyword = 1,
+
+ ///
+ /// Check if content contains any harmful links
+ ///
+ HarmfulLink = 2,
+
+ ///
+ /// Check if content represents generic spam
+ ///
+ Spam = 3,
+
+ ///
+ /// Check if content contains words from internal pre-defined wordsets
+ ///
+ KeywordPreset = 4,
+ }
+}
diff --git a/src/Discord.Net.Core/Entities/Guilds/AutoModeration/IAutoModRule.cs b/src/Discord.Net.Core/Entities/Guilds/AutoModeration/IAutoModRule.cs
new file mode 100644
index 000000000..b28cc7c05
--- /dev/null
+++ b/src/Discord.Net.Core/Entities/Guilds/AutoModeration/IAutoModRule.cs
@@ -0,0 +1,84 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Discord
+{
+ ///
+ /// Represents a auto mod rule within a guild.
+ ///
+ public interface IAutoModRule : ISnowflakeEntity, IDeletable
+ {
+ ///
+ /// Gets the guild id on which this rule exists.
+ ///
+ ulong GuildId { get; }
+
+ ///
+ /// Get the name of this rule.
+ ///
+ string Name { get; }
+
+ ///
+ /// Gets the id of the user who created this use.
+ ///
+ ulong CreatorId { get; }
+
+ ///
+ /// Gets the event type on which this rule is triggered.
+ ///
+ AutoModEventType EventType { get; }
+
+ ///
+ /// Gets the trigger type on which this rule executes.
+ ///
+ AutoModTriggerType TriggerType { get; }
+
+ ///
+ /// Gets the keyword filter for this rule.
+ ///
+ ///
+ /// This collection will be empty if is not
+ /// .
+ ///
+ public IReadOnlyCollection KeywordFilter { get; }
+
+ ///
+ /// Gets the preset keyword types for this rule.
+ ///
+ ///
+ /// This collection will be empty if is not
+ /// .
+ ///
+ public IReadOnlyCollection Presets { get; }
+
+ ///
+ /// Gets a collection of actions that will be preformed if a user breaks this rule.
+ ///
+ IReadOnlyCollection Actions { get; }
+
+ ///
+ /// Gets whether or not this rule is enabled.
+ ///
+ bool Enabled { get; }
+
+ ///
+ /// Gets a collection of role ids that are exempt from this rule.
+ ///
+ IReadOnlyCollection ExemptRoles { get; }
+
+ ///
+ /// Gets a collection of channel ids that are exempt from this rule.
+ ///
+ IReadOnlyCollection ExemptChannels { get; }
+
+ ///
+ /// Modifies this rule.
+ ///
+ /// The delegate containing the properties to modify the rule with.
+ /// The options to be used when sending the request.
+ Task ModifyAsync(Action func, RequestOptions options = null);
+ }
+}
diff --git a/src/Discord.Net.Core/Entities/Guilds/AutoModeration/KeywordPresetTypes.cs b/src/Discord.Net.Core/Entities/Guilds/AutoModeration/KeywordPresetTypes.cs
new file mode 100644
index 000000000..a399cdc6f
--- /dev/null
+++ b/src/Discord.Net.Core/Entities/Guilds/AutoModeration/KeywordPresetTypes.cs
@@ -0,0 +1,29 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Discord
+{
+ ///
+ /// An enum representing preset filter types.
+ ///
+ public enum KeywordPresetTypes
+ {
+ ///
+ /// Words that may be considered forms of swearing or cursing.
+ ///
+ Profanity = 1,
+
+ ///
+ /// Words that refer to sexually explicit behavior or activity.
+ ///
+ SexualContent = 2,
+
+ ///
+ /// Personal insults or words that may be considered hate speech.
+ ///
+ Slurs = 3,
+ }
+}
diff --git a/src/Discord.Net.Rest/API/Common/ActionMetadata.cs b/src/Discord.Net.Rest/API/Common/ActionMetadata.cs
new file mode 100644
index 000000000..148c54cdd
--- /dev/null
+++ b/src/Discord.Net.Rest/API/Common/ActionMetadata.cs
@@ -0,0 +1,18 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Discord.API
+{
+ internal class ActionMetadata
+ {
+ [JsonProperty("channel_id")]
+ public Optional ChannelId { get; set; }
+
+ [JsonProperty("duration_seconds")]
+ public Optional DurationSeconds { get; set; }
+ }
+}
diff --git a/src/Discord.Net.Rest/API/Common/AutoModAction.cs b/src/Discord.Net.Rest/API/Common/AutoModAction.cs
new file mode 100644
index 000000000..a6fec3c01
--- /dev/null
+++ b/src/Discord.Net.Rest/API/Common/AutoModAction.cs
@@ -0,0 +1,18 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Discord.API
+{
+ internal class AutoModAction
+ {
+ [JsonProperty("type")]
+ public AutoModActionType Type { get; set; }
+
+ [JsonProperty("metadata")]
+ public Optional Metadata { get; set; }
+ }
+}
diff --git a/src/Discord.Net.Rest/API/Common/AutoModerationRule.cs b/src/Discord.Net.Rest/API/Common/AutoModerationRule.cs
new file mode 100644
index 000000000..f30af5bee
--- /dev/null
+++ b/src/Discord.Net.Rest/API/Common/AutoModerationRule.cs
@@ -0,0 +1,45 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Discord.API
+{
+ internal class AutoModerationRule
+ {
+ [JsonProperty("id")]
+ public ulong Id { get; set; }
+
+ [JsonProperty("guild_id")]
+ public ulong GuildId { get; set; }
+
+ [JsonProperty("name")]
+ public string Name { get; set; }
+
+ [JsonProperty("creator_id")]
+ public ulong CreatorId { get; set; }
+
+ [JsonProperty("event_type")]
+ public AutoModEventType EventType { get; set; }
+
+ [JsonProperty("trigger_type")]
+ public AutoModTriggerType TriggerType { get; set; }
+
+ [JsonProperty("trigger_metadata")]
+ public TriggerMetadata TriggerMetadata { get; set; }
+
+ [JsonProperty("actions")]
+ public AutoModAction[] Actions { get; set; }
+
+ [JsonProperty("enabled")]
+ public bool Enabled { get; set; }
+
+ [JsonProperty("exempt_roles")]
+ public ulong[] ExemptRoles { get; set; }
+
+ [JsonProperty("exempt_channels")]
+ public ulong[] ExemptChannels { get; set; }
+ }
+}
diff --git a/src/Discord.Net.Rest/API/Common/TriggerMetadata.cs b/src/Discord.Net.Rest/API/Common/TriggerMetadata.cs
new file mode 100644
index 000000000..c10108459
--- /dev/null
+++ b/src/Discord.Net.Rest/API/Common/TriggerMetadata.cs
@@ -0,0 +1,18 @@
+using Newtonsoft.Json;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Discord.API
+{
+ internal class TriggerMetadata
+ {
+ [JsonProperty("keyword_filter")]
+ public string[] KeywordFilter { get; set; }
+
+ [JsonProperty("presets")]
+ public KeywordPresetTypes[] Presets { get; set; }
+ }
+}
diff --git a/src/Discord.Net.Rest/API/Rest/CreateAutoModRuleParams.cs b/src/Discord.Net.Rest/API/Rest/CreateAutoModRuleParams.cs
new file mode 100644
index 000000000..d126d4078
--- /dev/null
+++ b/src/Discord.Net.Rest/API/Rest/CreateAutoModRuleParams.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Discord.API.Rest
+{
+ internal class CreateAutoModRuleParams
+ {
+ public string Name { get; set; }
+ public AutoModEventType EventType { get; set; }
+ public AutoModTriggerType TriggerType { get; set; }
+ public Optional TriggerMetadata { get; set; }
+ public AutoModAction[] Actions { get; set; }
+ public Optional Enabled { get; set; }
+ public Optional ExemptRoles { get; set; }
+ public Optional ExemptChannels { get; set; }
+ }
+}
diff --git a/src/Discord.Net.Rest/API/Rest/ModifyAutoModRuleParams.cs b/src/Discord.Net.Rest/API/Rest/ModifyAutoModRuleParams.cs
new file mode 100644
index 000000000..3cdb4eac5
--- /dev/null
+++ b/src/Discord.Net.Rest/API/Rest/ModifyAutoModRuleParams.cs
@@ -0,0 +1,20 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Discord.API.Rest
+{
+ internal class ModifyAutoModRuleParams
+ {
+ public Optional Name { get; set; }
+ public Optional EventType { get; set; }
+ public Optional TriggerType { get; set; }
+ public Optional TriggerMetadata { get; set; }
+ public Optional Actions { get; set; }
+ public Optional Enabled { get; set; }
+ public Optional ExemptRoles { get; set; }
+ public Optional ExemptChannels { get; set; }
+ }
+}
diff --git a/src/Discord.Net.Rest/DiscordRestApiClient.cs b/src/Discord.Net.Rest/DiscordRestApiClient.cs
index e179675ba..08adbc509 100644
--- a/src/Discord.Net.Rest/DiscordRestApiClient.cs
+++ b/src/Discord.Net.Rest/DiscordRestApiClient.cs
@@ -2074,6 +2074,58 @@ namespace Discord.API
#endregion
+ #region Guild AutoMod
+
+ public async Task GetGuildAutoModRulesAsync(ulong guildId, RequestOptions options)
+ {
+ Preconditions.NotEqual(guildId, 0, nameof(guildId));
+
+ options = RequestOptions.CreateOrClone(options);
+
+ return await SendAsync("GET", () => $"guilds/{guildId}/auto-moderation/rules", new BucketIds(guildId), options: options);
+ }
+
+ public async Task GetGuildAutoModRuleAsync(ulong guildId, ulong ruleId, RequestOptions options)
+ {
+ Preconditions.NotEqual(guildId, 0, nameof(guildId));
+ Preconditions.NotEqual(ruleId, 0, nameof(ruleId));
+
+ options = RequestOptions.CreateOrClone(options);
+
+ return await SendAsync("GET", () => $"guilds/{guildId}/auto-moderation/rules/{ruleId}", new BucketIds(guildId), options: options);
+ }
+
+ public async Task CreateGuildAutoModRuleAsync(ulong guildId, CreateAutoModRuleParams args, RequestOptions options)
+ {
+ Preconditions.NotEqual(guildId, 0, nameof(guildId));
+
+ options = RequestOptions.CreateOrClone(options);
+
+ return await SendJsonAsync("POST", () => $"guilds/{guildId}/auto-moderation", args, new BucketIds(guildId), options: options);
+ }
+
+ public async Task ModifyGuildAutoModRuleAsync(ulong guildId, ulong ruleId, ModifyAutoModRuleParams args, RequestOptions options)
+ {
+ Preconditions.NotEqual(guildId, 0, nameof(guildId));
+ Preconditions.NotEqual(ruleId, 0, nameof(ruleId));
+
+ options = RequestOptions.CreateOrClone(options);
+
+ return await SendJsonAsync("PATCH", () => $"guilds/{guildId}/auto-moderation/{ruleId}", args, new BucketIds(guildId), options: options);
+ }
+
+ public async Task DeleteGuildAutoModRuleAsync(ulong guildId, ulong ruleId, RequestOptions options)
+ {
+ Preconditions.NotEqual(guildId, 0, nameof(guildId));
+ Preconditions.NotEqual(ruleId, 0, nameof(ruleId));
+
+ options = RequestOptions.CreateOrClone(options);
+
+ await SendAsync("DELETE", () => $"guilds/{guildId}/auto-moderation/rules/{ruleId}", new BucketIds(guildId), options: options);
+ }
+
+ #endregion
+
#region Users
public async Task GetUserAsync(ulong userId, RequestOptions options = null)
{
diff --git a/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs b/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs
index 8bab35937..943f83b75 100644
--- a/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs
+++ b/src/Discord.Net.Rest/Entities/Guilds/GuildHelper.cs
@@ -943,5 +943,42 @@ namespace Discord.Rest
}
#endregion
+
+ #region Auto Mod
+ public static Task ModifyRuleAsync(BaseDiscordClient client, IAutoModRule rule, Action func, RequestOptions options)
+ {
+ var args = new AutoModRuleProperties();
+ func(args);
+
+ var apiArgs = new API.Rest.ModifyAutoModRuleParams
+ {
+ Actions = args.Actions.IsSpecified ? args.Actions.Value.Select(x => new API.AutoModAction()
+ {
+ Type = x.Type,
+ 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
+ } : Optional.Unspecified
+ }).ToArray() : Optional.Unspecified,
+ Enabled = args.Enabled,
+ EventType = args.EventType,
+ ExemptChannels = args.ExemptChannels,
+ ExemptRoles = args.ExemptRoles,
+ Name = args.Name,
+ TriggerType = args.TriggerType,
+ TriggerMetadata = args.KeywordFilter.IsSpecified || args.Presets.IsSpecified ? new API.TriggerMetadata
+ {
+ KeywordFilter = args.KeywordFilter.GetValueOrDefault(Array.Empty()),
+ Presets = args.Presets.GetValueOrDefault(Array.Empty())
+ } : Optional.Unspecified
+ };
+
+ return client.ApiClient.ModifyGuildAutoModRuleAsync(rule.GuildId, rule.Id, apiArgs, options);
+ }
+
+ public static Task DeleteRuleAsync(BaseDiscordClient client, IAutoModRule rule, RequestOptions options)
+ => client.ApiClient.DeleteGuildAutoModRuleAsync(rule.GuildId, rule.Id, options);
+ #endregion
}
}
diff --git a/src/Discord.Net.WebSocket/BaseSocketClient.Events.cs b/src/Discord.Net.WebSocket/BaseSocketClient.Events.cs
index c47591418..fca975629 100644
--- a/src/Discord.Net.WebSocket/BaseSocketClient.Events.cs
+++ b/src/Discord.Net.WebSocket/BaseSocketClient.Events.cs
@@ -877,5 +877,24 @@ namespace Discord.WebSocket
}
internal readonly AsyncEvent> _guildStickerDeleted = new AsyncEvent>();
#endregion
+
+ #region AutoModeration
+
+ public event Func AutoModRuleCreated
+ {
+ add => _autoModRuleCreated.Add(value);
+ remove => _autoModRuleCreated.Remove(value);
+ }
+ internal readonly AsyncEvent> _autoModRuleCreated = new AsyncEvent>();
+
+ public event Func AutoModRuleDelted
+ {
+ add => _autoModRuleDeleted.Add(value);
+ remove => _autoModRuleDeleted.Remove(value);
+ }
+ internal readonly AsyncEvent> _autoModRuleDeleted = new AsyncEvent>();
+
+ //public event Func
+ #endregion
}
}
diff --git a/src/Discord.Net.WebSocket/DiscordSocketClient.cs b/src/Discord.Net.WebSocket/DiscordSocketClient.cs
index 5743d9abd..99f51b8f4 100644
--- a/src/Discord.Net.WebSocket/DiscordSocketClient.cs
+++ b/src/Discord.Net.WebSocket/DiscordSocketClient.cs
@@ -2839,6 +2839,34 @@ namespace Discord.WebSocket
#endregion
+ #region Auto Moderation
+
+ case "AUTO_MODERATION_RULE_CREATE":
+ {
+
+ }
+ break;
+
+ case "AUTO_MODERATION_RULE_UPDATE":
+ {
+
+ }
+ break;
+
+ case "AUTO_MODERATION_RULE_DELETE":
+ {
+
+ }
+ break;
+
+ case "AUTO_MODERATION_RULE_EXECUTE":
+ {
+
+ }
+ break;
+
+ #endregion
+
#region Ignored (User only)
case "CHANNEL_PINS_ACK":
await _gatewayLogger.DebugAsync("Ignored Dispatch (CHANNEL_PINS_ACK)").ConfigureAwait(false);
diff --git a/src/Discord.Net.WebSocket/Entities/Guilds/SocketAutoModRule.cs b/src/Discord.Net.WebSocket/Entities/Guilds/SocketAutoModRule.cs
new file mode 100644
index 000000000..5dab651f8
--- /dev/null
+++ b/src/Discord.Net.WebSocket/Entities/Guilds/SocketAutoModRule.cs
@@ -0,0 +1,104 @@
+using Discord.Rest;
+using System;
+using System.Collections.Generic;
+using System.Collections.Immutable;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Model = Discord.API.AutoModerationRule;
+
+namespace Discord.WebSocket
+{
+ public class SocketAutoModRule : SocketEntity, IAutoModRule
+ {
+ ///
+ /// Gets the guild that this rule is in.
+ ///
+ public SocketGuild Guild { get; }
+
+ ///
+ public string Name { get; private set; }
+
+ ///
+ /// Gets the creator of this rule.
+ ///
+ public SocketGuildUser Creator { get; private set; }
+
+ ///
+ public AutoModEventType EventType { get; private set; }
+
+ ///
+ public AutoModTriggerType TriggerType { get; private set; }
+
+ ///
+ public IReadOnlyCollection KeywordFilter { get; private set; }
+
+ ///
+ public IReadOnlyCollection Presets { get; private set; }
+
+ ///
+ public IReadOnlyCollection Actions { get; private set; }
+
+ ///
+ public bool Enabled { get; private set; }
+
+ ///
+ /// Gets the roles that are exempt from this rule.
+ ///
+ public IReadOnlyCollection ExemptRoles { get; private set; }
+
+ ///
+ /// Gets the channels that are exempt from this rule.
+ ///
+ public IReadOnlyCollection ExemptChannels { get; private set; }
+
+ ///
+ public DateTimeOffset CreatedAt
+ => SnowflakeUtils.FromSnowflake(Id);
+
+ private ulong _creatorId;
+
+ internal SocketAutoModRule(DiscordSocketClient discord, ulong id, SocketGuild guild)
+ : base(discord, id)
+ {
+ Guild = guild;
+ }
+
+ internal static SocketAutoModRule Create(DiscordSocketClient discord, SocketGuild guild, Model model)
+ {
+ var entity = new SocketAutoModRule(discord, model.Id, guild);
+ entity.Update(model);
+ return entity;
+ }
+
+ internal void Update(Model model)
+ {
+ Name = model.Name;
+ _creatorId = model.CreatorId;
+ Creator ??= Guild.GetUser(_creatorId);
+ EventType = model.EventType;
+ TriggerType = model.TriggerType;
+ KeywordFilter = model.TriggerMetadata.KeywordFilter.ToImmutableArray();
+ Presets = model.TriggerMetadata.Presets.ToImmutableArray();
+ Actions = model.Actions.Select(x => new AutoModRuleAction(x.Type, x.Metadata.GetValueOrDefault()?.ChannelId.ToNullable(), x.Metadata.GetValueOrDefault()?.DurationSeconds.ToNullable())).ToImmutableArray();
+ Enabled = model.Enabled;
+ ExemptRoles = model.ExemptRoles.Select(x => Guild.GetRole(x)).ToImmutableArray();
+ ExemptChannels = model.ExemptChannels.Select(x => Guild.GetChannel(x)).ToImmutableArray();
+ }
+
+ ///
+ public Task ModifyAsync(Action func, RequestOptions options = null)
+ => GuildHelper.ModifyRuleAsync(Discord, this, func, options);
+
+ ///
+ public Task DeleteAsync(RequestOptions options = null)
+ => GuildHelper.DeleteRuleAsync(Discord, this, options);
+
+ #region IAutoModRule
+ IReadOnlyCollection IAutoModRule.ExemptRoles => ExemptRoles.Select(x => x.Id).ToImmutableArray();
+ IReadOnlyCollection IAutoModRule.ExemptChannels => ExemptChannels.Select(x => x.Id).ToImmutableArray();
+ ulong IAutoModRule.GuildId => Guild.Id;
+ ulong IAutoModRule.CreatorId => _creatorId;
+ #endregion
+ }
+}
diff --git a/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs b/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs
index 9ce2f507a..811dd8b1c 100644
--- a/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs
+++ b/src/Discord.Net.WebSocket/Entities/Guilds/SocketGuild.cs
@@ -43,6 +43,7 @@ namespace Discord.WebSocket
private ConcurrentDictionary _voiceStates;
private ConcurrentDictionary _stickers;
private ConcurrentDictionary _events;
+ //private ConcurrentDictionary _automodRules;
private ImmutableArray _emotes;
private AudioClient _audioClient;