3
0
Fork 0
mirror of https://github.com/ZeppelinBot/Zeppelin.git synced 2025-06-08 08:05:03 +00:00
zeppelin/backend/src/plugins/Automod/functions/createMessageSpamTrigger.ts
Dragory 45e3fe2ef0
chore: esm imports
This will make merging this into 'next' much easier.
2024-08-11 21:58:52 +03:00

95 lines
3.2 KiB
TypeScript

import z from "zod";
import { SavedMessage } from "../../../data/entities/SavedMessage.js";
import { humanizeDurationShort } from "../../../humanizeDurationShort.js";
import { getBaseUrl } from "../../../pluginUtils.js";
import { convertDelayStringToMS, sorter, zDelayString } from "../../../utils.js";
import { RecentActionType } from "../constants.js";
import { automodTrigger } from "../helpers.js";
import { findRecentSpam } from "./findRecentSpam.js";
import { getMatchingMessageRecentActions } from "./getMatchingMessageRecentActions.js";
import { getMessageSpamIdentifier } from "./getSpamIdentifier.js";
interface TMessageSpamMatchResultType {
archiveId: string;
}
const configSchema = z.strictObject({
amount: z.number().int(),
within: zDelayString,
per_channel: z.boolean().nullable().default(false),
});
export function createMessageSpamTrigger(spamType: RecentActionType, prettyName: string) {
return automodTrigger<TMessageSpamMatchResultType>()({
configSchema,
async match({ pluginData, context, triggerConfig }) {
if (!context.message) {
return;
}
const spamIdentifier = getMessageSpamIdentifier(context.message, Boolean(triggerConfig.per_channel));
const recentSpam = findRecentSpam(pluginData, spamType, spamIdentifier);
if (recentSpam) {
if (recentSpam.archiveId) {
await pluginData.state.archives.addSavedMessagesToArchive(
recentSpam.archiveId,
[context.message],
pluginData.guild,
);
}
return {
silentClean: true,
extra: { archiveId: "" }, // FIXME: Fix up automod trigger match() typings so extra is not required when doing a silentClean
};
}
const within = convertDelayStringToMS(triggerConfig.within) ?? 0;
const matchedSpam = getMatchingMessageRecentActions(
pluginData,
context.message,
spamType,
spamIdentifier,
triggerConfig.amount,
within,
);
if (matchedSpam) {
const messages = matchedSpam.recentActions
.map((action) => action.context.message)
.filter(Boolean)
.sort(sorter("posted_at")) as SavedMessage[];
const archiveId = await pluginData.state.archives.createFromSavedMessages(messages, pluginData.guild);
pluginData.state.recentSpam.push({
type: spamType,
identifiers: [spamIdentifier],
archiveId,
timestamp: Date.now(),
});
return {
extraContexts: matchedSpam.recentActions
.map((action) => action.context)
.filter((_context) => _context !== context),
extra: {
archiveId,
},
};
}
},
renderMatchInformation({ pluginData, matchResult, triggerConfig }) {
const baseUrl = getBaseUrl(pluginData);
const archiveUrl = pluginData.state.archives.getUrl(baseUrl, matchResult.extra.archiveId);
const withinMs = convertDelayStringToMS(triggerConfig.within);
const withinStr = humanizeDurationShort(withinMs);
return `Matched ${prettyName} spam (${triggerConfig.amount} in ${withinStr}): ${archiveUrl}`;
},
});
}