zappyzep/backend/src/plugins/Automod/actions/reply.ts

63 lines
2 KiB
TypeScript

import * as t from "io-ts";
import { automodAction } from "../helpers";
import {
convertDelayStringToMS,
noop,
renderRecursively,
stripObjectToScalars,
tDelayString,
tMessageContent,
tNullable,
} from "../../../utils";
import { TextChannel } from "eris";
import { AutomodContext } from "../types";
import { renderTemplate } from "../../../templateFormatter";
export const ReplyAction = automodAction({
configType: t.union([
t.string,
t.type({
text: tMessageContent,
auto_delete: tNullable(t.union([tDelayString, t.number])),
}),
]),
async apply({ pluginData, contexts, actionConfig }) {
const contextsWithTextChannels = contexts
.filter(c => c.message?.channel_id)
.filter(c => pluginData.guild.channels.get(c.message.channel_id) instanceof TextChannel);
const contextsByChannelId = contextsWithTextChannels.reduce((map: Map<string, AutomodContext[]>, context) => {
if (!map.has(context.message.channel_id)) {
map.set(context.message.channel_id, []);
}
map.get(context.message.channel_id).push(context);
return map;
}, new Map());
for (const [channelId, _contexts] of contextsByChannelId.entries()) {
const users = Array.from(new Set(_contexts.map(c => c.user).filter(Boolean)));
const user = users[0];
const renderReplyText = async str =>
renderTemplate(str, {
user: stripObjectToScalars(user),
});
const formatted =
typeof actionConfig === "string"
? await renderReplyText(actionConfig)
: await renderRecursively(actionConfig.text, renderReplyText);
if (formatted) {
const channel = pluginData.guild.channels.get(channelId) as TextChannel;
const replyMsg = await channel.createMessage(formatted);
if (typeof actionConfig === "object" && actionConfig.auto_delete) {
const delay = convertDelayStringToMS(String(actionConfig.auto_delete));
setTimeout(() => replyMsg.delete().catch(noop), delay);
}
}
}
},
});