diff --git a/api/automoderation.go b/api/automoderation.go new file mode 100644 index 00000000..9ef477ef --- /dev/null +++ b/api/automoderation.go @@ -0,0 +1,87 @@ +package api + +import ( + "github.com/diamondburned/arikawa/v3/discord" + "github.com/diamondburned/arikawa/v3/utils/httputil" + "github.com/diamondburned/arikawa/v3/utils/json/option" +) + +// ListAutoModerationRules gets a list of all rules currently configured for the guild. Returns a list of auto moderation rule objects for the given guild. +// +// This endpoint requires the MANAGE_GUILD permission. +func (c *Client) ListAutoModerationRules(guildID discord.GuildID) ([]discord.AutoModerationRule, error) { + var rules []discord.AutoModerationRule + return rules, c.RequestJSON( + &rules, "GET", + EndpointGuilds+guildID.String()+"/auto-moderation/rules", + ) +} + +// GetAutoModerationRule gets a single rule. Returns an auto moderation rule object. +// +// This endpoint requires the MANAGE_GUILD permission. +func (c *Client) GetAutoModerationRule(guildID discord.GuildID, ruleID discord.AutoModerationRuleID) (discord.AutoModerationRule, error) { + var rule discord.AutoModerationRule + return rule, c.RequestJSON( + &rule, "GET", + EndpointGuilds+guildID.String()+"/auto-moderation/rules/"+ruleID.String(), + ) +} + +// CreateAutoModerationRule creates a new rule. Returns an auto moderation rule on success. Fires an Auto Moderation Rule Create Gateway event. +// +// This endpoint requires the MANAGE_GUILD permission. +// +// This endpoint supports the X-Audit-Log-Reason header. +func (c *Client) CreateAutoModerationRule(guildID discord.GuildID, rule discord.AutoModerationRule) (*discord.AutoModerationRule, error) { + var ret *discord.AutoModerationRule + return ret, c.RequestJSON(&ret, "POST", EndpointGuilds+guildID.String()+"/auto-moderation/rules", + httputil.WithJSONBody(rule), + ) +} + +type ModifyAutoModerationRuleData struct { + // the rule name + Name option.String `json:"name,omitempty"` + // the event type + EventType option.Optional[discord.AutoModerationEventType] `json:"event_type,omitempty"` + // the trigger metadata + TriggerMetadata option.Optional[discord.AutoModerationTriggerMetadata] `json:"triggr_metadata,omitempty"` + // the actions which will execute when the rule is triggered + Actions option.Optional[[]discord.AutoModerationAction] `json:"actions,omitempty"` + // whether the rule is enabled + Enabled option.Bool `json:"enabled,omitempty"` + // the role ids that should not be affected by the rule (Maximum of 20) + ExemptRules option.Optional[[]discord.RoleID] `json:"exempt_roles,omitempty"` + // the channel ids that should not be affected by the rule (Maximum of 50) + ExemptChannels option.Optional[[]discord.ChannelID] `json:"exempt_channels,omitempty"` + AuditLogReason +} + +// ModifyAutoModerationRule modifies an existing rule. Returns an auto moderation rule on success. Fires an Auto Moderation Rule Update Gateway event. +// +// Requires MANAGE_GUILD permissions. +// +// All parameters for this endpoint are optional. +// +// This endpoint supports the X-Audit-Log-Reason header. +func (c *Client) ModifyAutoModerationRule(GuildID discord.GuildID, RuleID discord.AutoModerationRuleID, data ModifyAutoModerationRuleData) (*discord.AutoModerationRule, error) { + var ret *discord.AutoModerationRule + return ret, c.RequestJSON(&ret, "PATCH", EndpointGuilds+GuildID.String()+"/auto-moderation/rules/"+RuleID.String(), + httputil.WithJSONBody(data), + httputil.WithHeaders(data.Header()), + ) +} + +type DeleteAutoModerationRuleData struct { + AuditLogReason `json:"-"` +} + +// DeleteAutoModerationRule deletes a rule. Returns a 204 on success. Fires an Auto Moderation Rule Delete Gateway event. +// +// This endpoint requires the MANAGE_GUILD permission. +// +// This endpoint supports the X-Audit-Log-Reason header. +func (c *Client) DeleteAutoModerationRule(GuildID discord.GuildID, RuleID discord.AutoModerationRuleID, data DeleteAutoModerationRuleData) error { + return c.FastRequest("DELETE", EndpointGuilds+GuildID.String()+"/auto-moderation/rules/"+RuleID.String(), httputil.WithHeaders(data.Header())) +} diff --git a/discord/automoderation.go b/discord/automoderation.go new file mode 100644 index 00000000..478fc22e --- /dev/null +++ b/discord/automoderation.go @@ -0,0 +1,93 @@ +package discord + +type AutoModerationEventType uint32 + +const ( + AutoModerationMessageSend AutoModerationEventType = 1 + iota + AutoModerationMemberUpdate +) + +type AutoModerationTriggerType uint32 + +const ( + AutoModerationKeyword AutoModerationTriggerType = 1 + iota + AutoModerationSpam + AutoModerationKeywordPreset + AutoModerationMentionSpam + AutoModerationMemberProfile +) + +type AutoModerationKeywordPresetType uint32 + +const ( + AutoModeratorProfanity AutoModerationKeywordPresetType = 1 + iota + AutoModeratorSexualContent + AutoModeratorSlurs +) + +type AutoModerationTriggerMetadata struct { + // substrings which will be searched for in content (Maximum of 1000) + KeywordFilter []string `json:"keyword_filter"` + // regular expression patterns which will be matched against content (Maximum of 10) + RegexPatterns []string `json:"regex_patterns"` + // the internally pre-defined wordsets which will be searched for in content + Presets []AutoModerationKeywordPresetType `json:"presets"` + // substrings which should not trigger the rule (Maximum of 100 or 1000) + AllowList []string `json:"allow_list"` + // total number of unique role and user mentions allowed per message (Maximum of 50) + MentionTotalLimit int `json:"mention_total_limit"` + // whether to automatically detect mention raids + MentionRaidProtectionEnabled bool `json:"mention_raid_protection_enabled"` +} + +type AutoModerationActionMetadata struct { + // channel to which user content should be logged + ChannelID ChannelID `json:"channel_id"` + // timeout duration in seconds + // maximum of 2419200 seconds (4 weeks) + DurationSeconds int `json:"duration_seconds"` + // additional explanation that will be shown to members whenever their message is blocked + // maximum of 150 characters + CustomMessage string `json:"custom_message,omitempty"` +} + +type AutoModerationActionType uint32 + +const ( + AutoModerationBlockMessage AutoModerationActionType = 1 + iota + AutoModerationSendAlertMessage + AutoModerationTimeout + AutoModerationBlockMemberInteraction +) + +type AutoModerationAction struct { + // the type of action + Type AutoModerationActionType `json:"type"` + // additional metadata needed during execution for this specific action type + Metadata AutoModerationActionMetadata `json:"metadata,omitempty"` +} + +type AutoModerationRule struct { + // the id of this rule + ID AutoModerationRuleID `json:"id"` + // the id of the guild which this rule belongs to + GuildID GuildID `json:"guild_id"` + // the rule name + Name string `json:"name"` + // the user which first created this rule + CreatorID UserID `json:"creator_id,omitempty"` + // the rule event type + EventType AutoModerationEventType `json:"event_type"` + // the rule trigger type + TriggerType AutoModerationTriggerType + // the rule trigger metadata + TriggerMetadata AutoModerationTriggerMetadata `json:"trigger_metadata,omitempty"` + // the actions which will execute when the rule is triggered + Actions []AutoModerationAction `json:"actions"` + // whether the rule is enabled + Enabled bool `json:"enabled,omitempty"` + // the role ids that should not be affected by the rule (Maximum of 20) + ExemptRoles []RoleID `json:"exempt_roles,omitempty"` + // the channel ids that should not be affected by the rule (Maximum of 50) + ExemptChannels []ChannelID `json:"exempt_channels,omitempty"` +} diff --git a/discord/snowflake.go b/discord/snowflake.go index 2d8ed505..aa4d9a6c 100644 --- a/discord/snowflake.go +++ b/discord/snowflake.go @@ -15,7 +15,7 @@ func DurationSinceEpoch(t time.Time) time.Duration { return time.Duration(t.UnixNano()) - Epoch } -//go:generate go run ../utils/cmd/gensnowflake -o snowflake_types.go AppID AttachmentID AuditLogEntryID ChannelID CommandID EmojiID GuildID IntegrationID InteractionID MessageID RoleID StageID StickerID StickerPackID TagID TeamID UserID WebhookID EventID EntityID +//go:generate go run ../utils/cmd/gensnowflake -o snowflake_types.go AppID AttachmentID AuditLogEntryID ChannelID CommandID EmojiID GuildID IntegrationID InteractionID MessageID RoleID StageID StickerID StickerPackID TagID TeamID UserID WebhookID EventID EntityID AutoModerationRuleID // Mention generates the mention syntax for this channel ID. func (s ChannelID) Mention() string { return "<#" + s.String() + ">" } diff --git a/discord/snowflake_types.go b/discord/snowflake_types.go index 62080fa5..dbf7c3dc 100644 --- a/discord/snowflake_types.go +++ b/discord/snowflake_types.go @@ -483,3 +483,27 @@ func (s EntityID) Time() time.Time { return Snowflake(s).Time() } func (s EntityID) Worker() uint8 { return Snowflake(s).Worker() } func (s EntityID) PID() uint8 { return Snowflake(s).PID() } func (s EntityID) Increment() uint16 { return Snowflake(s).Increment() } + +// AutoModerationRuleID is the snowflake type for a AutoModerationRuleID. +type AutoModerationRuleID Snowflake + +// NullAutoModerationRuleID gets encoded into a null. This is used for optional and nullable snowflake fields. +const NullAutoModerationRuleID = AutoModerationRuleID(NullSnowflake) + +func (s AutoModerationRuleID) MarshalJSON() ([]byte, error) { return Snowflake(s).MarshalJSON() } +func (s *AutoModerationRuleID) UnmarshalJSON(v []byte) error { return (*Snowflake)(s).UnmarshalJSON(v) } + +// String returns the ID, or nothing if the snowflake isn't valid. +func (s AutoModerationRuleID) String() string { return Snowflake(s).String() } + +// IsValid returns whether or not the snowflake is valid. +func (s AutoModerationRuleID) IsValid() bool { return Snowflake(s).IsValid() } + +// IsNull returns whether or not the snowflake is null. This method is rarely +// ever useful; most people should use IsValid instead. +func (s AutoModerationRuleID) IsNull() bool { return Snowflake(s).IsNull() } + +func (s AutoModerationRuleID) Time() time.Time { return Snowflake(s).Time() } +func (s AutoModerationRuleID) Worker() uint8 { return Snowflake(s).Worker() } +func (s AutoModerationRuleID) PID() uint8 { return Snowflake(s).PID() } +func (s AutoModerationRuleID) Increment() uint16 { return Snowflake(s).Increment() }