mirror of
https://github.com/ZeppelinBot/Zeppelin.git
synced 2025-05-17 15:15:02 +00:00
feat: handle template errors
Fixes ZDEV-20
This commit is contained in:
parent
2ce5082018
commit
ffa9eeb3f5
14 changed files with 231 additions and 94 deletions
|
@ -1,13 +1,14 @@
|
|||
import { PermissionsBitField, PermissionsString } from "discord.js";
|
||||
import { U } from "ts-toolbelt";
|
||||
import z from "zod";
|
||||
import { TemplateSafeValueContainer, renderTemplate } from "../../../templateFormatter";
|
||||
import { TemplateParseError, TemplateSafeValueContainer, renderTemplate } from "../../../templateFormatter";
|
||||
import { isValidSnowflake, keys, noop, zBoundedCharacters } from "../../../utils";
|
||||
import {
|
||||
guildToTemplateSafeGuild,
|
||||
savedMessageToTemplateSafeSavedMessage,
|
||||
userToTemplateSafeUser,
|
||||
} from "../../../utils/templateSafeObjects";
|
||||
import { LogsPlugin } from "../../Logs/LogsPlugin";
|
||||
import { automodAction } from "../helpers";
|
||||
|
||||
type LegacyPermMap = Record<string, keyof (typeof PermissionsBitField)["Flags"]>;
|
||||
|
@ -71,30 +72,52 @@ export const ChangePermsAction = automodAction({
|
|||
perms: z.record(z.enum(allPermissionNames), z.boolean().nullable()),
|
||||
}),
|
||||
|
||||
async apply({ pluginData, contexts, actionConfig }) {
|
||||
async apply({ pluginData, contexts, actionConfig, ruleName }) {
|
||||
const user = contexts.find((c) => c.user)?.user;
|
||||
const message = contexts.find((c) => c.message)?.message;
|
||||
|
||||
const renderTarget = async (str: string) =>
|
||||
renderTemplate(
|
||||
str,
|
||||
let target: string;
|
||||
try {
|
||||
target = await renderTemplate(
|
||||
actionConfig.target,
|
||||
new TemplateSafeValueContainer({
|
||||
user: user ? userToTemplateSafeUser(user) : null,
|
||||
guild: guildToTemplateSafeGuild(pluginData.guild),
|
||||
message: message ? savedMessageToTemplateSafeSavedMessage(message) : null,
|
||||
}),
|
||||
);
|
||||
const renderChannel = async (str: string) =>
|
||||
renderTemplate(
|
||||
str,
|
||||
new TemplateSafeValueContainer({
|
||||
user: user ? userToTemplateSafeUser(user) : null,
|
||||
guild: guildToTemplateSafeGuild(pluginData.guild),
|
||||
message: message ? savedMessageToTemplateSafeSavedMessage(message) : null,
|
||||
}),
|
||||
);
|
||||
const target = await renderTarget(actionConfig.target);
|
||||
const channelId = actionConfig.channel ? await renderChannel(actionConfig.channel) : null;
|
||||
} catch (err) {
|
||||
if (err instanceof TemplateParseError) {
|
||||
pluginData.getPlugin(LogsPlugin).logBotAlert({
|
||||
body: `Error in target format of automod rule ${ruleName}: ${err.message}`,
|
||||
});
|
||||
return;
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
|
||||
let channelId: string | null = null;
|
||||
if (actionConfig.channel) {
|
||||
try {
|
||||
channelId = await renderTemplate(
|
||||
actionConfig.channel,
|
||||
new TemplateSafeValueContainer({
|
||||
user: user ? userToTemplateSafeUser(user) : null,
|
||||
guild: guildToTemplateSafeGuild(pluginData.guild),
|
||||
message: message ? savedMessageToTemplateSafeSavedMessage(message) : null,
|
||||
}),
|
||||
);
|
||||
} catch (err) {
|
||||
if (err instanceof TemplateParseError) {
|
||||
pluginData.getPlugin(LogsPlugin).logBotAlert({
|
||||
body: `Error in channel format of automod rule ${ruleName}: ${err.message}`,
|
||||
});
|
||||
return;
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
|
||||
const role = pluginData.guild.roles.resolve(target);
|
||||
if (!role) {
|
||||
const member = await pluginData.guild.members.fetch(target).catch(noop);
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
import { GuildTextBasedChannel, MessageCreateOptions, PermissionsBitField, Snowflake, User } from "discord.js";
|
||||
import z from "zod";
|
||||
import { TemplateSafeValueContainer, renderTemplate } from "../../../templateFormatter";
|
||||
import { TemplateParseError, TemplateSafeValueContainer, renderTemplate } from "../../../templateFormatter";
|
||||
import {
|
||||
convertDelayStringToMS,
|
||||
noop,
|
||||
|
@ -58,10 +58,21 @@ export const ReplyAction = automodAction({
|
|||
}),
|
||||
);
|
||||
|
||||
const formatted =
|
||||
typeof actionConfig === "string"
|
||||
? await renderReplyText(actionConfig)
|
||||
: ((await renderRecursively(actionConfig.text, renderReplyText)) as MessageCreateOptions);
|
||||
let formatted: string | MessageCreateOptions;
|
||||
try {
|
||||
formatted =
|
||||
typeof actionConfig === "string"
|
||||
? await renderReplyText(actionConfig)
|
||||
: ((await renderRecursively(actionConfig.text, renderReplyText)) as MessageCreateOptions);
|
||||
} catch (err) {
|
||||
if (err instanceof TemplateParseError) {
|
||||
pluginData.getPlugin(LogsPlugin).logBotAlert({
|
||||
body: `Error in reply format of automod rule \`${ruleName}\`: ${err.message}`,
|
||||
});
|
||||
return;
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
|
||||
if (formatted) {
|
||||
const channel = pluginData.guild.channels.cache.get(channelId as Snowflake) as GuildTextBasedChannel;
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
import { ChannelType, GuildTextThreadCreateOptions, ThreadAutoArchiveDuration, ThreadChannel } from "discord.js";
|
||||
import z from "zod";
|
||||
import { TemplateSafeValueContainer, renderTemplate } from "../../../templateFormatter";
|
||||
import { TemplateParseError, TemplateSafeValueContainer, renderTemplate } from "../../../templateFormatter";
|
||||
import { MINUTES, convertDelayStringToMS, noop, zBoundedCharacters, zDelayString } from "../../../utils";
|
||||
import { savedMessageToTemplateSafeSavedMessage, userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
|
||||
import { LogsPlugin } from "../../Logs/LogsPlugin";
|
||||
import { automodAction } from "../helpers";
|
||||
|
||||
const validThreadAutoArchiveDurations: ThreadAutoArchiveDuration[] = [
|
||||
|
@ -21,7 +22,7 @@ export const StartThreadAction = automodAction({
|
|||
limit_per_channel: z.number().nullable().default(5),
|
||||
}),
|
||||
|
||||
async apply({ pluginData, contexts, actionConfig }) {
|
||||
async apply({ pluginData, contexts, actionConfig, ruleName }) {
|
||||
// check if the message still exists, we don't want to create threads for deleted messages
|
||||
const threads = contexts.filter((c) => {
|
||||
if (!c.message || !c.user) return false;
|
||||
|
@ -48,15 +49,25 @@ export const StartThreadAction = automodAction({
|
|||
const channel = pluginData.guild.channels.cache.get(threadContext.message!.channel_id);
|
||||
if (!channel || !("threads" in channel) || channel.isThreadOnly()) continue;
|
||||
|
||||
const renderThreadName = async (str: string) =>
|
||||
renderTemplate(
|
||||
str,
|
||||
let threadName: string;
|
||||
try {
|
||||
threadName = await renderTemplate(
|
||||
actionConfig.name ?? "{user.renderedUsername}'s thread",
|
||||
new TemplateSafeValueContainer({
|
||||
user: userToTemplateSafeUser(threadContext.user!),
|
||||
msg: savedMessageToTemplateSafeSavedMessage(threadContext.message!),
|
||||
}),
|
||||
);
|
||||
const threadName = await renderThreadName(actionConfig.name ?? "{user.renderedUsername}'s thread");
|
||||
} catch (err) {
|
||||
if (err instanceof TemplateParseError) {
|
||||
pluginData.getPlugin(LogsPlugin).logBotAlert({
|
||||
body: `Error in thread name format of automod rule ${ruleName}: ${err.message}`,
|
||||
});
|
||||
return;
|
||||
}
|
||||
throw err;
|
||||
}
|
||||
|
||||
const threadOptions: GuildTextThreadCreateOptions<unknown> = {
|
||||
name: threadName,
|
||||
autoArchiveDuration: autoArchive,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue