diff --git a/lib/nyxx.dart b/lib/nyxx.dart index 71d89e402..825cf8eb8 100644 --- a/lib/nyxx.dart +++ b/lib/nyxx.dart @@ -54,7 +54,8 @@ export 'src/builders/guild/welcome_screen.dart' show WelcomeScreenUpdateBuilder; export 'src/builders/guild/widget.dart' show WidgetSettingsUpdateBuilder; export 'src/builders/guild/scheduled_event.dart' show ScheduledEventBuilder, ScheduledEventUpdateBuilder; export 'src/builders/guild/template.dart' show GuildTemplateBuilder, GuildTemplateUpdateBuilder; -export 'src/builders/guild/auto_moderation.dart' show AutoModerationRuleBuilder, AutoModerationRuleUpdateBuilder; +export 'src/builders/guild/auto_moderation.dart' + show AutoModerationRuleBuilder, AutoModerationRuleUpdateBuilder, ActionMetadataBuilder, AutoModerationActionBuilder; export 'src/builders/role.dart' show RoleBuilder, RoleUpdateBuilder; export 'src/builders/voice.dart' show CurrentUserVoiceStateUpdateBuilder, VoiceStateUpdateBuilder, GatewayVoiceStateBuilder; export 'src/builders/presence.dart' show PresenceBuilder, CurrentUserStatus, ActivityBuilder; diff --git a/lib/src/builders/guild/auto_moderation.dart b/lib/src/builders/guild/auto_moderation.dart index 43eee516b..a393753a3 100644 --- a/lib/src/builders/guild/auto_moderation.dart +++ b/lib/src/builders/guild/auto_moderation.dart @@ -9,9 +9,9 @@ class AutoModerationRuleBuilder extends CreateBuilder { TriggerType triggerType; - TriggerMetadata? metadata; + TriggerMetadataBuilder? metadata; - List actions; + List actions; bool? isEnabled; @@ -30,32 +30,70 @@ class AutoModerationRuleBuilder extends CreateBuilder { this.exemptChannelIds, }); + AutoModerationRuleBuilder.keyword({ + required this.name, + required this.eventType, + required this.actions, + this.isEnabled, + this.exemptRoleIds, + this.exemptChannelIds, + List? keywordFilter, + List? regexPatterns, + List? allowList, + }) : triggerType = TriggerType.keyword, + metadata = TriggerMetadataBuilder( + keywordFilter: keywordFilter, + regexPatterns: regexPatterns, + allowList: allowList, + ); + + AutoModerationRuleBuilder.spam({ + required this.name, + required this.eventType, + required this.actions, + this.isEnabled, + this.exemptRoleIds, + this.exemptChannelIds, + }) : triggerType = TriggerType.spam, + metadata = null; + + AutoModerationRuleBuilder.keywordPreset({ + required this.name, + required this.eventType, + required this.actions, + this.isEnabled, + this.exemptRoleIds, + this.exemptChannelIds, + required List? presets, + List? allowList, + }) : triggerType = TriggerType.keywordPreset, + metadata = TriggerMetadataBuilder( + presets: presets, + allowList: allowList, + ); + + AutoModerationRuleBuilder.mentionSpam({ + required this.name, + required this.eventType, + required this.actions, + this.isEnabled, + this.exemptRoleIds, + this.exemptChannelIds, + required int mentionTotalLimit, + bool? isMentionRaidProtectionEnabled, + }) : triggerType = TriggerType.mentionSpam, + metadata = TriggerMetadataBuilder( + mentionTotalLimit: mentionTotalLimit, + isMentionRaidProtectionEnabled: isMentionRaidProtectionEnabled, + ); + @override Map build() => { 'name': name, 'event_type': eventType.value, 'trigger_type': triggerType.value, - if (metadata != null) - 'trigger_metadata': { - 'keyword_filter': metadata!.keywordFilter, - 'regex_patterns': metadata!.regexPatterns, - 'presets': metadata!.presets?.map((type) => type.value).toList(), - 'allow_list': metadata!.allowList, - 'mention_total_limit': metadata!.mentionTotalLimit, - 'mention_raid_protection_enabled': metadata!.isMentionRaidProtectionEnabled, - }, - 'actions': [ - for (final action in actions) - { - 'type': action.type.value, - if (action.metadata != null) - 'metadata': { - 'channel_id': action.metadata!.channelId?.toString(), - 'duration_seconds': action.metadata!.duration?.inSeconds, - 'custom_message': action.metadata!.customMessage, - } - } - ], + if (metadata != null) 'trigger_metadata': metadata!.build(), + 'actions': actions.map((a) => a.build()).toList(), if (isEnabled != null) 'enabled': isEnabled, if (exemptRoleIds != null) 'exempt_roles': exemptRoleIds!.map((id) => id.toString()).toList(), if (exemptChannelIds != null) 'exempt_channels': exemptChannelIds!.map((id) => id.toString()).toList(), @@ -67,9 +105,9 @@ class AutoModerationRuleUpdateBuilder extends UpdateBuilder AutoModerationEventType? eventType; - TriggerMetadata? metadata; + TriggerMetadataBuilder? metadata; - List? actions; + List? actions; bool? isEnabled; @@ -91,30 +129,101 @@ class AutoModerationRuleUpdateBuilder extends UpdateBuilder Map build() => { if (name != null) 'name': name, if (eventType != null) 'event_type': eventType!.value, - if (metadata != null) - 'trigger_metadata': { - 'keyword_filter': metadata!.keywordFilter, - 'regex_patterns': metadata!.regexPatterns, - 'presets': metadata!.presets?.map((type) => type.value).toList(), - 'allow_list': metadata!.allowList, - 'mention_total_limit': metadata!.mentionTotalLimit, - 'mention_raid_protection_enabled': metadata!.isMentionRaidProtectionEnabled, - }, - if (actions != null) - 'actions': [ - for (final action in actions!) - { - 'type': action.type.value, - if (action.metadata != null) - 'metadata': { - 'channel_id': action.metadata!.channelId?.toString(), - 'duration_seconds': action.metadata!.duration?.inSeconds, - 'custom_message': action.metadata!.customMessage, - } - } - ], + if (metadata != null) 'trigger_metadata': metadata!.build(), + if (actions != null) 'actions': actions!.map((a) => a.build()).toList(), if (isEnabled != null) 'enabled': isEnabled, if (exemptRoleIds != null) 'exempt_roles': exemptRoleIds!.map((id) => id.toString()).toList(), if (exemptChannelIds != null) 'exempt_channels': exemptChannelIds!.map((id) => id.toString()).toList(), }; } + +class TriggerMetadataBuilder extends CreateBuilder { + /// A list of words that trigger the rule. + final List? keywordFilter; + + /// A list of regex patterns that trigger the rule. + final List? regexPatterns; + + /// A list of preset keyword types that trigger the rule. + final List? presets; + + /// A list of words allowed to bypass the rule. + final List? allowList; + + /// The maximum number of mentions in a message. + final int? mentionTotalLimit; + + /// Whether mention raid protection is enabled. + final bool? isMentionRaidProtectionEnabled; + + TriggerMetadataBuilder({ + this.keywordFilter, + this.regexPatterns, + this.presets, + this.allowList, + this.mentionTotalLimit, + this.isMentionRaidProtectionEnabled, + }); + + @override + Map build() => { + 'keyword_filter': keywordFilter, + 'regex_patterns': regexPatterns, + 'presets': presets?.map((type) => type.value).toList(), + 'allow_list': allowList, + 'mention_total_limit': mentionTotalLimit, + 'mention_raid_protection_enabled': isMentionRaidProtectionEnabled, + }; +} + +class AutoModerationActionBuilder extends CreateBuilder { + /// The type of action to perform. + final ActionType type; + + /// Metadata needed to perform the action. + final ActionMetadataBuilder? metadata; + + AutoModerationActionBuilder({required this.type, this.metadata}); + + AutoModerationActionBuilder.blockMessage({String? customMessage}) + : type = ActionType.blockMessage, + metadata = customMessage == null ? null : ActionMetadataBuilder(customMessage: customMessage); + + AutoModerationActionBuilder.sendAlertMessage({required Snowflake channelId}) + : type = ActionType.sendAlertMessage, + metadata = ActionMetadataBuilder(channelId: channelId); + + AutoModerationActionBuilder.timeout({required Duration duration}) + : type = ActionType.timeout, + metadata = ActionMetadataBuilder(duration: duration); + + @override + Map build() => { + 'type': type.value, + if (metadata != null) 'metadata': metadata!.build(), + }; +} + +class ActionMetadataBuilder extends CreateBuilder { + /// The ID of the channel to send the alert message to. + final Snowflake? channelId; + + /// The duration of time to time the user out for. + final Duration? duration; + + /// A custom message to send to the user. + final String? customMessage; + + ActionMetadataBuilder({ + this.channelId, + this.duration, + this.customMessage, + }); + + @override + Map build() => { + if (channelId != null) 'channel_id': channelId!.toString(), + if (duration != null) 'duration_seconds': duration!.inSeconds, + if (customMessage != null) 'custom_message': customMessage, + }; +} diff --git a/lib/src/models/guild/auto_moderation.dart b/lib/src/models/guild/auto_moderation.dart index 734cb6a56..8589057d9 100644 --- a/lib/src/models/guild/auto_moderation.dart +++ b/lib/src/models/guild/auto_moderation.dart @@ -1,3 +1,4 @@ +import 'package:nyxx/src/builders/guild/auto_moderation.dart'; import 'package:nyxx/src/http/managers/auto_moderation_manager.dart'; import 'package:nyxx/src/models/channel/channel.dart'; import 'package:nyxx/src/models/channel/text_channel.dart'; @@ -129,24 +130,25 @@ enum TriggerType { /// {@template trigger_metadata} /// Additional metadata associated with the trigger for an [AutoModerationRule]. /// {@endtemplate} -class TriggerMetadata with ToStringHelper { - /// A list of words that trigger the rule. +// TODO(abitofevrything): Remove `implements TriggerMetadataBuilder` +class TriggerMetadata with ToStringHelper implements TriggerMetadataBuilder { + @override final List? keywordFilter; - /// A list of regex patterns that trigger the rule. // TODO: Do we want to parse these as RegExp objects? + @override final List? regexPatterns; - /// A list of preset keyword types that trigger the rule. + @override final List? presets; - /// A list of words allowed to bypass the rule. + @override final List? allowList; - /// The maximum number of mentions in a message. + @override final int? mentionTotalLimit; - /// Whether mention raid protection is enabled. + @override final bool? isMentionRaidProtectionEnabled; /// {@macro trigger_metadata} @@ -159,6 +161,17 @@ class TriggerMetadata with ToStringHelper { required this.mentionTotalLimit, required this.isMentionRaidProtectionEnabled, }); + + @override + @Deprecated('Use TriggerMetadataBuilder instead') + Map build() => { + 'keyword_filter': keywordFilter, + 'regex_patterns': regexPatterns, + 'presets': presets?.map((type) => type.value).toList(), + 'allow_list': allowList, + 'mention_total_limit': mentionTotalLimit, + 'mention_raid_protection_enabled': isMentionRaidProtectionEnabled, + }; } /// A preset list of trigger keywords for an [AutoModerationRule]. @@ -187,11 +200,12 @@ enum KeywordPresetType { /// {@template auto_moderation_action} /// Describes an action to take when an [AutoModerationRule] is triggered. /// {@endtemplate} -class AutoModerationAction with ToStringHelper { - /// The type of action to perform. +// TODO(abitofevrything): Remove `implements AutoModerationActionBuilder` +class AutoModerationAction with ToStringHelper implements AutoModerationActionBuilder { + @override final ActionType type; - /// Metadata needed to perform the action. + @override final ActionMetadata? metadata; /// {@macro auto_moderation_action} @@ -200,6 +214,13 @@ class AutoModerationAction with ToStringHelper { required this.type, required this.metadata, }); + + @override + @Deprecated('Use AutoModerationActionBuilder instead') + Map build() => { + 'type': type.value, + if (metadata != null) 'metadata': metadata!.build(), + }; } /// The type of action for an [AutoModerationAction]. @@ -228,16 +249,17 @@ enum ActionType { /// {@template action_metadata} /// Additional metadata associated with an [AutoModerationAction]. /// {@endtemplate} -class ActionMetadata with ToStringHelper { +// TODO(abitofevrything): Remove `implements ActionMetadataBuilder` +class ActionMetadata with ToStringHelper implements ActionMetadataBuilder { final AutoModerationManager manager; - /// The ID of the channel to send the alert message to. + @override final Snowflake? channelId; - /// The duration of time to time the user out for. + @override final Duration? duration; - /// A custom message to send to the user. + @override final String? customMessage; /// {@macro action_metadata} @@ -251,4 +273,12 @@ class ActionMetadata with ToStringHelper { /// The channel to send the alert message to. PartialTextChannel? get channel => channelId == null ? null : manager.client.channels[channelId!] as PartialTextChannel?; + + @override + @Deprecated('Use ActionMetadataBuilder instead') + Map build() => { + 'channel_id': channelId?.toString(), + 'duration_seconds': duration?.inSeconds, + 'custom_message': customMessage, + }; }