Auto mod blame wolf (#2267)

* feat(meister): add automod

* fix(test); rest error with code

* fix(rest): log error nicely

* fix(test): disable benchmark test until gateway rewrite

* fix(automod): enum should start with 1

* fix(helper): better undefined handling of metadata

* fix(transfomrers): automod transformers

* fix(tests): add some automod tests

* Update types/shared.ts

Co-authored-by: meister03 <69507874+meister03@users.noreply.github.com>

* fix: changes discord made recently

* fix(fmt): i hate deno fmt but i love itoh

Co-authored-by: meister03 <69507874+meister03@users.noreply.github.com>
Co-authored-by: LTS20050703 <87189679+lts20050703@users.noreply.github.com>
This commit is contained in:
Skillz4Killz
2022-06-15 11:25:53 -04:00
committed by GitHub
co-authored by meister03 LTS20050703
parent 4263b7b787
commit ccd8506c81
22 changed files with 796 additions and 3 deletions
@@ -0,0 +1,75 @@
import { Bot } from "../../../bot.ts";
import {
AutoModerationActionType,
AutoModerationEventTypes,
AutoModerationTriggerTypes,
DiscordAutoModerationRule,
DiscordAutoModerationRuleTriggerMetadataPresets,
} from "../../../types/discord.ts";
/** Get a rule currently configured for guild. */
export async function createAutomodRule(bot: Bot, guildId: bigint, options: CreateAutoModerationRuleOptions) {
const rule = await bot.rest.runMethod<DiscordAutoModerationRule>(
bot.rest,
"POST",
bot.constants.routes.AUTOMOD_RULES(guildId),
{
name: options.name,
event_type: options.eventType,
trigger_type: options.triggerType,
trigger_metadata: {
keyword_filter: options.triggerMetadata.keywordFilter,
presets: options.triggerMetadata.presets,
},
actions: options.actions.map((action) => ({
type: action.type,
metadata: action.metadata
? {
channel_id: action.metadata.channelId?.toString(),
duration_seconds: action.metadata.durationSeconds,
}
: undefined,
})),
enabled: options.enabled ?? true,
exempt_roles: options.exemptRoles?.map((id) => id.toString()),
exempt_channels: options.exemptChannels?.map((id) => id.toString()),
},
);
return bot.transformers.automodRule(bot, rule);
}
export interface CreateAutoModerationRuleOptions {
/** The name of the rule. */
name: string;
/** The type of event to trigger the rule on. */
eventType: AutoModerationEventTypes;
/** The type of trigger to use for the rule. */
triggerType: AutoModerationTriggerTypes;
/** The metadata to use for the trigger. */
triggerMetadata: {
// TODO: discord is considering renaming this before release
/** The keywords needed to match. Only present when TriggerType.Keyword */
keywordFilter?: string[];
/** The pre-defined lists of words to match from. Only present when TriggerType.KeywordPreset */
presets?: DiscordAutoModerationRuleTriggerMetadataPresets[];
};
/** The actions that will trigger for this rule */
actions: {
/** The type of action to take when a rule is triggered */
type: AutoModerationActionType;
/** additional metadata needed during execution for this specific action type */
metadata?: {
/** The id of channel to which user content should be logged. Only in SendAlertMessage */
channelId?: bigint;
/** Timeout duration in seconds. Max is 2419200(4 weeks). Only supported for TriggerType.Keyword */
durationSeconds?: number;
};
}[];
/** Whether the rule should be enabled, true by default. */
enabled?: boolean;
/** The role ids that should not be effected by the rule */
exemptRoles?: bigint[];
/** The channel ids that should not be effected by the rule. */
exemptChannels?: bigint[];
}
@@ -0,0 +1,10 @@
import { Bot } from "../../../bot.ts";
/** Delete a rule currently configured for guild. */
export async function deleteAutomodRule(bot: Bot, guildId: bigint, ruleId: bigint) {
await bot.rest.runMethod<undefined>(
bot.rest,
"DELETE",
bot.constants.routes.AUTOMOD_RULE(guildId, ruleId),
);
}
+73
View File
@@ -0,0 +1,73 @@
import { Bot } from "../../../bot.ts";
import {
AutoModerationActionType,
AutoModerationEventTypes,
DiscordAutoModerationRule,
DiscordAutoModerationRuleTriggerMetadataPresets,
} from "../../../types/discord.ts";
/** Edit a rule currently configured for guild. */
export async function editAutomodRule(bot: Bot, guildId: bigint, options: Partial<EditAutoModerationRuleOptions>) {
const rule = await bot.rest.runMethod<DiscordAutoModerationRule>(
bot.rest,
"PATCH",
bot.constants.routes.AUTOMOD_RULES(guildId),
{
name: options.name,
event_type: options.eventType,
trigger_metadata: options.triggerMetadata
? {
keyword_filter: options.triggerMetadata.keywordFilter,
presets: options.triggerMetadata.presets,
}
: undefined,
actions: options.actions?.map((action) => ({
type: action.type,
metadata: {
channel_id: action.metadata.channelId?.toString(),
duration_seconds: action.metadata.durationSeconds,
},
})),
enabled: options.enabled ?? true,
exempt_roles: options.exemptRoles?.map((id) => id.toString()),
exempt_channels: options.exemptChannels?.map((id) => id.toString()),
},
);
return bot.transformers.automodRule(bot, rule);
}
export interface EditAutoModerationRuleOptions {
/** The name of the rule. */
name: string;
/** The type of event to trigger the rule on. */
eventType: AutoModerationEventTypes;
/** The metadata to use for the trigger. */
triggerMetadata: {
// TODO: discord is considering renaming this before release
/** The keywords needed to match. Only present when TriggerType.Keyword */
keywordFilter?: string[];
// TODO: discord is considering renaming this before release
// TODO: This may need a special type or enum
/** The pre-defined lists of words to match from. Only present when TriggerType.KeywordPreset */
presets?: DiscordAutoModerationRuleTriggerMetadataPresets[];
};
/** The actions that will trigger for this rule */
actions: {
/** The type of action to take when a rule is triggered */
type: AutoModerationActionType;
/** additional metadata needed during execution for this specific action type */
metadata: {
/** The id of channel to which user content should be logged. Only in SendAlertMessage */
channelId?: bigint;
/** Timeout duration in seconds. Only supported for TriggerType.Keyword */
durationSeconds?: number;
};
}[];
/** Whether the rule should be enabled. */
enabled?: boolean;
/** The role ids that should not be effected by the rule */
exemptRoles?: bigint[];
/** The channel ids that should not be effected by the rule. */
exemptChannels?: bigint[];
}
+14
View File
@@ -0,0 +1,14 @@
import { Bot } from "../../../bot.ts";
import { DiscordAutoModerationRule } from "../../../types/discord.ts";
import { Collection } from "../../../util/collection.ts";
/** Get a rule currently configured for guild. */
export async function getAutomodRule(bot: Bot, guildId: bigint, ruleId: bigint) {
const rule = await bot.rest.runMethod<DiscordAutoModerationRule>(
bot.rest,
"GET",
bot.constants.routes.AUTOMOD_RULE(guildId, ruleId),
);
return bot.transformers.automodRule(bot, rule);
}
+17
View File
@@ -0,0 +1,17 @@
import { Bot } from "../../../bot.ts";
import { DiscordAutoModerationRule } from "../../../types/discord.ts";
import { Collection } from "../../../util/collection.ts";
/** Get a list of all rules currently configured for guild. */
export async function getAutomodRules(bot: Bot, guildId: bigint) {
const rules = await bot.rest.runMethod<DiscordAutoModerationRule[]>(
bot.rest,
"GET",
bot.constants.routes.AUTOMOD_RULES(guildId),
);
return new Collection(rules.map((r) => {
const rule = bot.transformers.automodRule(bot, r);
return [rule.id, rule];
}));
}
+5
View File
@@ -0,0 +1,5 @@
export * from "./getAutomodRule.ts";
export * from "./getAutomodRules.ts";
export * from "./createAutomodRule.ts";
export * from "./editAutomodRule.ts";
export * from "./deleteAutomodRule.ts";
+1
View File
@@ -1,4 +1,5 @@
export * from "./scheduledEvents/mod.ts";
export * from "./automod/mod.ts";
export * from "./createGuild.ts";
export * from "./deleteGuild.ts";