Skip to content

Commit

Permalink
add match_mentions automod trigger
Browse files Browse the repository at this point in the history
  • Loading branch information
almeidx committed Mar 15, 2022
1 parent feeb048 commit 18b0948
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 0 deletions.
10 changes: 10 additions & 0 deletions backend/src/data/GuildSavedMessages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,16 @@ export class GuildSavedMessages extends BaseGuildRepository<SavedMessage> {
}));
}

if (msg.mentions) {
data.mentions = {
channels: Array.from(msg.mentions.channels.keys()),
everyone: msg.mentions.everyone,
roles: Array.from(msg.mentions.roles.keys()),
repliedUser: msg.mentions.repliedUser?.id ?? null,
users: Array.from(msg.mentions.users.keys()),
};
}

return data;
}

Expand Down
9 changes: 9 additions & 0 deletions backend/src/data/entities/SavedMessage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,14 @@ export interface ISavedMessageStickerData {
type: string | null;
}

export interface ISavedMessageMentionsData {
channels: Snowflake[];
everyone: boolean;
roles: Snowflake[];
users: Snowflake[];
repliedUser: Snowflake | null;
}

export interface ISavedMessageData {
attachments?: ISavedMessageAttachmentData[];
author: {
Expand All @@ -74,6 +82,7 @@ export interface ISavedMessageData {
embeds?: ISavedMessageEmbedData[];
stickers?: ISavedMessageStickerData[];
timestamp: number;
mentions?: ISavedMessageMentionsData;
}

@Entity("messages")
Expand Down
3 changes: 3 additions & 0 deletions backend/src/plugins/Automod/triggers/availableTriggers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import { UnmuteTrigger } from "./unmute";
import { WarnTrigger } from "./warn";
import { ThreadArchiveTrigger } from "./threadArchive";
import { ThreadUnarchiveTrigger } from "./threadUnarchive";
import { MatchMentionsTrigger } from "./matchMentions";

export const availableTriggers: Record<string, AutomodTriggerBlueprint<any, any>> = {
any_message: AnyMessageTrigger,
Expand All @@ -44,6 +45,7 @@ export const availableTriggers: Record<string, AutomodTriggerBlueprint<any, any>
match_links: MatchLinksTrigger,
match_attachment_type: MatchAttachmentTypeTrigger,
match_mime_type: MatchMimeTypeTrigger,
match_mentions: MatchMentionsTrigger,
member_join: MemberJoinTrigger,
role_added: RoleAddedTrigger,
role_removed: RoleRemovedTrigger,
Expand Down Expand Up @@ -86,6 +88,7 @@ export const AvailableTriggers = t.type({
match_links: MatchLinksTrigger.configType,
match_attachment_type: MatchAttachmentTypeTrigger.configType,
match_mime_type: MatchMimeTypeTrigger.configType,
match_mentions: MatchMentionsTrigger.configType,
member_join: MemberJoinTrigger.configType,
member_leave: MemberLeaveTrigger.configType,
role_added: RoleAddedTrigger.configType,
Expand Down
60 changes: 60 additions & 0 deletions backend/src/plugins/Automod/triggers/matchMentions.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import { Snowflake } from "discord.js";
import * as t from "io-ts";
import { tNullable } from "../../../utils";
import { getTextMatchPartialSummary } from "../functions/getTextMatchPartialSummary";
import { automodTrigger } from "../helpers";

// I couldn't figure out how to get the type of the keys of the 'configType' dynamically
type ConfigTypeKeys = "channels" | "everyone" | "users" | "roles";

const summaryType: Record<ConfigTypeKeys, string> = {
channels: "channel",
everyone: "everyone",
users: "user",
roles: "role",
};

interface MatchResultType {
reason: typeof summaryType[ConfigTypeKeys];
}

const predicate = (items: Snowflake[], configIds?: Snowflake[] | null): boolean =>
!!configIds?.length && items.some((item) => configIds.includes(item));

export const MatchMentionsTrigger = automodTrigger<MatchResultType>()({
configType: t.type({
channels: tNullable(t.array(t.string)),
everyone: tNullable(t.boolean),
roles: tNullable(t.array(t.string)),
users: tNullable(t.array(t.string)),
}),

defaultConfig: {
channels: [],
everyone: false,
roles: [],
users: [],
},

async match({ context, triggerConfig }) {
if (!context.message?.data.mentions) return;

for (const key of Object.keys(summaryType) as Array<keyof typeof summaryType>) {
if (key === "everyone") {
if (triggerConfig.everyone) return { extra: { reason: summaryType.everyone } };
continue;
}

if (predicate(context.message.data.mentions[key], triggerConfig[key])) {
return { extra: { reason: summaryType[key] } };
}
}

return null;
},

renderMatchInformation({ pluginData, contexts, matchResult }) {
const partialSummary = getTextMatchPartialSummary(pluginData, "message", contexts[0]);
return `Matched ${matchResult.extra.reason} mention in ${partialSummary}`;
},
});

0 comments on commit 18b0948

Please sign in to comment.