| @@ -1267,5 +1267,29 @@ namespace Discord | |||||
| /// A task that represents the asynchronous creation operation. The task result contains a <see cref="WelcomeScreen"/>. | /// A task that represents the asynchronous creation operation. The task result contains a <see cref="WelcomeScreen"/>. | ||||
| /// </returns> | /// </returns> | ||||
| Task<WelcomeScreen> ModifyWelcomeScreenAsync(bool enabled, WelcomeScreenChannelProperties[] channels, string description = null, RequestOptions options = null); | Task<WelcomeScreen> ModifyWelcomeScreenAsync(bool enabled, WelcomeScreenChannelProperties[] channels, string description = null, RequestOptions options = null); | ||||
| /// <summary> | |||||
| /// Get a list of all rules currently configured for the guild. | |||||
| /// </summary> | |||||
| /// <returns> | |||||
| /// A task that represents the asynchronous creation operation. The task result contains a collection of <see cref="IAutoModRule"/>. | |||||
| /// </returns> | |||||
| Task<IAutoModRule[]> GetAutoModRulesAsync(RequestOptions options = null); | |||||
| /// <summary> | |||||
| /// Gets a single rule configured in a guild. Returns <see langword="null"/> if the rule was not found. | |||||
| /// </summary> | |||||
| /// <returns> | |||||
| /// A task that represents the asynchronous creation operation. The task result contains a <see cref="IAutoModRule"/>. | |||||
| /// </returns> | |||||
| Task<IAutoModRule> GetAutoModRuleAsync(RequestOptions options = null); | |||||
| /// <summary> | |||||
| /// Creates a new auto moderation rule. | |||||
| /// </summary> | |||||
| /// <returns> | |||||
| /// A task that represents the asynchronous creation operation. The task result contains the created <see cref="WelcomeScreen"/>. | |||||
| /// </returns> | |||||
| Task<IAutoModRule> CreateAutoModRuleAsync(RequestOptions options = null); | |||||
| } | } | ||||
| } | } | ||||
| @@ -0,0 +1,96 @@ | |||||
| using System; | |||||
| using System.Collections.Generic; | |||||
| using System.Collections.Immutable; | |||||
| using System.Linq; | |||||
| using System.Threading.Tasks; | |||||
| using Model = Discord.API.AutoModerationRule; | |||||
| namespace Discord.Rest; | |||||
| public class RestAutoModRule : RestEntity<ulong>, IAutoModRule | |||||
| { | |||||
| /// <inheritdoc /> | |||||
| public DateTimeOffset CreatedAt { get; private set; } | |||||
| /// <inheritdoc /> | |||||
| public ulong GuildId { get; private set; } | |||||
| /// <inheritdoc /> | |||||
| public string Name { get; private set; } | |||||
| /// <inheritdoc /> | |||||
| public ulong CreatorId { get; private set; } | |||||
| /// <inheritdoc /> | |||||
| public AutoModEventType EventType { get; private set; } | |||||
| /// <inheritdoc /> | |||||
| public AutoModTriggerType TriggerType { get; private set; } | |||||
| /// <inheritdoc /> | |||||
| public IReadOnlyCollection<string> KeywordFilter { get; private set; } | |||||
| /// <inheritdoc /> | |||||
| public IReadOnlyCollection<string> RegexPatterns { get; private set; } | |||||
| /// <inheritdoc /> | |||||
| public IReadOnlyCollection<string> AllowList { get; private set; } | |||||
| /// <inheritdoc /> | |||||
| public IReadOnlyCollection<KeywordPresetTypes> Presets { get; private set; } | |||||
| /// <inheritdoc /> | |||||
| public int? MentionTotalLimit { get; private set; } | |||||
| /// <inheritdoc /> | |||||
| public IReadOnlyCollection<AutoModRuleAction> Actions { get; private set; } | |||||
| /// <inheritdoc /> | |||||
| public bool Enabled { get; private set; } | |||||
| /// <inheritdoc /> | |||||
| public IReadOnlyCollection<ulong> ExemptRoles { get; private set; } | |||||
| /// <inheritdoc /> | |||||
| public IReadOnlyCollection<ulong> ExemptChannels { get; private set; } | |||||
| internal RestAutoModRule(BaseDiscordClient discord, ulong id) : base(discord, id) | |||||
| { | |||||
| } | |||||
| internal static RestAutoModRule Create(BaseDiscordClient discord, Model model) | |||||
| { | |||||
| var entity = new RestAutoModRule(discord, model.Id); | |||||
| entity.Update(model); | |||||
| return entity; | |||||
| } | |||||
| internal void Update(Model model) | |||||
| { | |||||
| Name = model.Name; | |||||
| CreatorId = model.CreatorId; | |||||
| GuildId = model.GuildId; | |||||
| EventType = model.EventType; | |||||
| TriggerType = model.TriggerType; | |||||
| KeywordFilter = model.TriggerMetadata.KeywordFilter.GetValueOrDefault(Array.Empty<string>()).ToImmutableArray(); | |||||
| Presets = model.TriggerMetadata.Presets.GetValueOrDefault(Array.Empty<KeywordPresetTypes>()).ToImmutableArray(); | |||||
| RegexPatterns = model.TriggerMetadata.RegexPatterns.GetValueOrDefault(Array.Empty<string>()).ToImmutableArray(); | |||||
| AllowList = model.TriggerMetadata.AllowList.GetValueOrDefault(Array.Empty<string>()).ToImmutableArray(); | |||||
| 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(); | |||||
| Enabled = model.Enabled; | |||||
| ExemptRoles = model.ExemptRoles.ToImmutableArray(); | |||||
| ExemptChannels = model.ExemptChannels.ToImmutableArray(); | |||||
| } | |||||
| /// <inheritdoc /> | |||||
| public Task ModifyAsync(Action<AutoModRuleProperties> func, RequestOptions options = null) => throw new NotImplementedException(); | |||||
| /// <inheritdoc /> | |||||
| public Task DeleteAsync(RequestOptions options = null) => throw new NotImplementedException(); | |||||
| } | |||||
| @@ -1199,6 +1199,22 @@ namespace Discord.Rest | |||||
| #endregion | #endregion | ||||
| #region AutoMod | |||||
| /// <inheritdoc cref="IGuild.GetAutoModRuleAsync"/> | |||||
| public Task<RestAutoModRule> GetAutoModRuleAsync(RequestOptions options = null) | |||||
| => GuildHelper.GetAutoModRuleAsync(this, Discord, options); | |||||
| /// <inheritdoc cref="IGuild.GetAutoModRulesAsync"/> | |||||
| public Task<RestAutoModRule[]> GetAutoModRulesAsync(RequestOptions options = null) | |||||
| => GuildHelper.GetAutoModRulesAsync(this, Discord, options); | |||||
| /// <inheritdoc cref="IGuild.CreateAutoModRuleAsync"/> | |||||
| public Task<RestAutoModRule> CreateAutoModRuleAsync(RequestOptions options = null) | |||||
| => GuildHelper.CreateAutoModRuleAsync(this, Discord, options); | |||||
| #endregion | |||||
| #region IGuild | #region IGuild | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| bool IGuild.Available => Available; | bool IGuild.Available => Available; | ||||
| @@ -1543,6 +1559,19 @@ namespace Discord.Rest | |||||
| public Task<WelcomeScreen> ModifyWelcomeScreenAsync(bool enabled, WelcomeScreenChannelProperties[] channels, string description = null, RequestOptions options = null) | public Task<WelcomeScreen> ModifyWelcomeScreenAsync(bool enabled, WelcomeScreenChannelProperties[] channels, string description = null, RequestOptions options = null) | ||||
| => GuildHelper.ModifyWelcomeScreenAsync(enabled, description, channels, this, Discord, options); | => GuildHelper.ModifyWelcomeScreenAsync(enabled, description, channels, this, Discord, options); | ||||
| /// <inheritdoc/> | |||||
| async Task<IAutoModRule> IGuild.GetAutoModRuleAsync(RequestOptions options) | |||||
| => await GetAutoModRuleAsync(options).ConfigureAwait(false); | |||||
| /// <inheritdoc/> | |||||
| async Task<IAutoModRule[]> IGuild.GetAutoModRulesAsync(RequestOptions options) | |||||
| => await GetAutoModRulesAsync(options).ConfigureAwait(false); | |||||
| /// <inheritdoc/> | |||||
| async Task<IAutoModRule> IGuild.CreateAutoModRuleAsync(RequestOptions options) | |||||
| => await CreateAutoModRuleAsync(options).ConfigureAwait(false); | |||||
| #endregion | #endregion | ||||
| } | } | ||||
| } | } | ||||
| @@ -4,22 +4,62 @@ namespace Discord.WebSocket; | |||||
| public class AutoModActionExecutedData | public class AutoModActionExecutedData | ||||
| { | { | ||||
| /// <summary> | |||||
| /// Gets the id of the rule which action belongs to. | |||||
| /// </summary> | |||||
| public Cacheable<IAutoModRule, ulong> Rule { get; } | public Cacheable<IAutoModRule, ulong> Rule { get; } | ||||
| /// <summary> | |||||
| /// Gets the trigger type of rule which was triggered. | |||||
| /// </summary> | |||||
| public AutoModTriggerType TriggerType { get; } | public AutoModTriggerType TriggerType { get; } | ||||
| /// <summary> | |||||
| /// Gets the user which generated the content which triggered the rule. | |||||
| /// </summary> | |||||
| public Cacheable<SocketGuildUser, ulong> User { get; } | public Cacheable<SocketGuildUser, ulong> User { get; } | ||||
| /// <summary> | |||||
| /// Gets the channel in which user content was posted. | |||||
| /// </summary> | |||||
| public Cacheable<ISocketMessageChannel, ulong> Channel { get; } | public Cacheable<ISocketMessageChannel, ulong> Channel { get; } | ||||
| /// <summary> | |||||
| /// Gets the message that triggered the action. | |||||
| /// </summary> | |||||
| /// <remarks> | |||||
| /// This property will be <see langword="null"/> if the message was blocked byt automod. | |||||
| /// </remarks> | |||||
| public Cacheable<IUserMessage, ulong> Message { get; } | public Cacheable<IUserMessage, ulong> Message { get; } | ||||
| /// <summary> | |||||
| /// Gets the id of the system auto moderation messages posted as a result of this action. | |||||
| /// </summary> | |||||
| /// <remarks> | |||||
| /// This property will be <see langword="null"/> if this event does not correspond to an action | |||||
| /// with type <see cref="AutoModActionType.SendAlertMessage"/>. | |||||
| /// </remarks> | |||||
| public ulong AlertMessageId { get; } | public ulong AlertMessageId { get; } | ||||
| /// <summary> | |||||
| /// Gets the user-generated text content. | |||||
| /// </summary> | |||||
| /// <remarks> | |||||
| /// This property will be empty if <see cref="GatewayIntents.MessageContent"/> is disabled. | |||||
| /// </remarks> | |||||
| public string Content { get; } | public string Content { get; } | ||||
| /// <summary> | |||||
| /// Gets the substring in content that triggered the rule. | |||||
| /// </summary> | |||||
| /// <remarks> | |||||
| /// This property will be empty if <see cref="GatewayIntents.MessageContent"/> is disabled. | |||||
| /// </remarks> | |||||
| public string MatchedContent { get; } | public string MatchedContent { get; } | ||||
| /// <summary> | |||||
| /// Gets the word or phrase configured in the rule that triggered the rule. | |||||
| /// </summary> | |||||
| public string MatchedKeyword { get; } | public string MatchedKeyword { get; } | ||||
| internal AutoModActionExecutedData(Cacheable<IAutoModRule, ulong> rule, | internal AutoModActionExecutedData(Cacheable<IAutoModRule, ulong> rule, | ||||
| @@ -1810,6 +1810,22 @@ namespace Discord.WebSocket | |||||
| internal SocketGuild Clone() => MemberwiseClone() as SocketGuild; | internal SocketGuild Clone() => MemberwiseClone() as SocketGuild; | ||||
| #endregion | #endregion | ||||
| #region AutoMod | |||||
| /// <inheritdoc cref="IGuild.GetAutoModRuleAsync"/> | |||||
| public Task<RestAutoModRule> GetAutoModRuleAsync(RequestOptions options = null) | |||||
| => GuildHelper.GetAutoModRuleAsync(this, Discord, options); | |||||
| /// <inheritdoc cref="IGuild.GetAutoModRulesAsync"/> | |||||
| public Task<RestAutoModRule[]> GetAutoModRulesAsync(RequestOptions options = null) | |||||
| => GuildHelper.GetAutoModRulesAsync(this, Discord, options); | |||||
| /// <inheritdoc cref="IGuild.CreateAutoModRuleAsync"/> | |||||
| public Task<RestAutoModRule> CreateAutoModRuleAsync(RequestOptions options = null) | |||||
| => GuildHelper.CreateAutoModRuleAsync(this, Discord, options); | |||||
| #endregion | |||||
| #region IGuild | #region IGuild | ||||
| /// <inheritdoc /> | /// <inheritdoc /> | ||||
| ulong? IGuild.AFKChannelId => AFKChannelId; | ulong? IGuild.AFKChannelId => AFKChannelId; | ||||
| @@ -2054,6 +2070,19 @@ namespace Discord.WebSocket | |||||
| _audioLock?.Dispose(); | _audioLock?.Dispose(); | ||||
| _audioClient?.Dispose(); | _audioClient?.Dispose(); | ||||
| } | } | ||||
| /// <inheritdoc/> | |||||
| async Task<IAutoModRule> IGuild.GetAutoModRuleAsync(RequestOptions options) | |||||
| => await GetAutoModRuleAsync(options).ConfigureAwait(false); | |||||
| /// <inheritdoc/> | |||||
| async Task<IAutoModRule[]> IGuild.GetAutoModRulesAsync(RequestOptions options) | |||||
| => await GetAutoModRulesAsync(options).ConfigureAwait(false); | |||||
| /// <inheritdoc/> | |||||
| async Task<IAutoModRule> IGuild.CreateAutoModRuleAsync(RequestOptions options) | |||||
| => await CreateAutoModRuleAsync(options).ConfigureAwait(false); | |||||
| #endregion | #endregion | ||||
| } | } | ||||
| } | } | ||||