3
0
Fork 0
mirror of https://github.com/ZeppelinBot/Zeppelin.git synced 2025-05-10 12:25:02 +00:00

Type fixes + use template safe values for renderTemplate() everywhere

This commit is contained in:
Dragory 2021-08-18 20:32:45 +03:00
parent e16eb8c8d1
commit d109a58cb7
No known key found for this signature in database
GPG key ID: 5F387BA66DF8AAC1
21 changed files with 190 additions and 98 deletions

View file

@ -2,7 +2,7 @@ import { MessageOptions, Permissions, Snowflake, TextChannel, User } from "disco
import * as t from "io-ts";
import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
import { LogType } from "../../../data/LogType";
import { renderTemplate } from "../../../templateFormatter";
import { renderTemplate, TemplateSafeValueContainer } from "../../../templateFormatter";
import {
convertDelayStringToMS,
noop,
@ -48,9 +48,12 @@ export const ReplyAction = automodAction({
const user = users[0];
const renderReplyText = async str =>
renderTemplate(str, {
user: userToTemplateSafeUser(user),
});
renderTemplate(
str,
new TemplateSafeValueContainer({
user: userToTemplateSafeUser(user),
}),
);
const formatted =
typeof actionConfig === "string"
? await renderReplyText(actionConfig)

View file

@ -1,9 +1,18 @@
import { parseSignature, typedGuildCommand } from "knub";
import { commandTypes } from "../../commandTypes";
import { stripObjectToScalars } from "../../utils";
import { stripObjectToScalars, UnknownUser } from "../../utils";
import { zeppelinGuildPlugin } from "../ZeppelinPluginBlueprint";
import { runEvent } from "./functions/runEvent";
import { ConfigSchema, CustomEventsPluginType } from "./types";
import { createTypedTemplateSafeValueContainer, TemplateSafeValueContainer } from "../../templateFormatter";
import { Channel, GuildChannel, GuildMember, ThreadChannel, User } from "discord.js";
import {
channelToTemplateSafeChannel,
memberToTemplateSafeMember,
messageToTemplateSafeMessage,
userToTemplateSafeUser,
} from "../../utils/templateSafeObjects";
import { isScalar } from "../../utils/isScalar";
const defaultOptions = {
config: {
@ -28,8 +37,25 @@ export const CustomEventsPlugin = zeppelinGuildPlugin<CustomEventsPluginType>()(
permission: `events.${key}.trigger.can_use`,
signature,
run({ message, args }) {
const strippedMsg = stripObjectToScalars(message, ["channel", "author"]);
runEvent(pluginData, event, { msg: message, args }, { args, msg: strippedMsg });
const safeArgs = new TemplateSafeValueContainer();
for (const [argKey, argValue] of Object.entries(args as Record<string, unknown>)) {
if (argValue instanceof User || argValue instanceof UnknownUser) {
safeArgs[argKey] = userToTemplateSafeUser(argValue);
} else if (argValue instanceof GuildMember) {
safeArgs[argKey] = memberToTemplateSafeMember(argValue);
} else if (argValue instanceof GuildChannel || argValue instanceof ThreadChannel) {
safeArgs[argKey] = channelToTemplateSafeChannel(argValue);
} else if (isScalar(argValue)) {
safeArgs[argKey] = argValue;
}
}
const values = createTypedTemplateSafeValueContainer({
...args,
msg: messageToTemplateSafeMessage(message),
});
runEvent(pluginData, event, { msg: message, args }, values);
},
});
pluginData.commands.add(eventCommand);

View file

@ -2,7 +2,7 @@ import { Snowflake } from "discord.js";
import * as t from "io-ts";
import { GuildPluginData } from "knub";
import { canActOn } from "../../../pluginUtils";
import { renderTemplate } from "../../../templateFormatter";
import { renderTemplate, TemplateSafeValueContainer } from "../../../templateFormatter";
import { resolveMember } from "../../../utils";
import { ActionError } from "../ActionError";
import { CustomEventsPluginType, TCustomEvent } from "../types";
@ -17,7 +17,7 @@ export type TAddRoleAction = t.TypeOf<typeof AddRoleAction>;
export async function addRoleAction(
pluginData: GuildPluginData<CustomEventsPluginType>,
action: TAddRoleAction,
values: any,
values: TemplateSafeValueContainer,
event: TCustomEvent,
eventData: any,
) {

View file

@ -1,7 +1,7 @@
import * as t from "io-ts";
import { GuildPluginData } from "knub";
import { CaseTypes } from "../../../data/CaseTypes";
import { renderTemplate } from "../../../templateFormatter";
import { renderTemplate, TemplateSafeValueContainer } from "../../../templateFormatter";
import { CasesPlugin } from "../../Cases/CasesPlugin";
import { ActionError } from "../ActionError";
import { CustomEventsPluginType, TCustomEvent } from "../types";
@ -18,7 +18,7 @@ export type TCreateCaseAction = t.TypeOf<typeof CreateCaseAction>;
export async function createCaseAction(
pluginData: GuildPluginData<CustomEventsPluginType>,
action: TCreateCaseAction,
values: any,
values: TemplateSafeValueContainer,
event: TCustomEvent,
eventData: any,
) {

View file

@ -4,6 +4,7 @@ import { GuildPluginData } from "knub";
import { convertDelayStringToMS, noop, tDelayString } from "../../../utils";
import { ActionError } from "../ActionError";
import { CustomEventsPluginType, TCustomEvent } from "../types";
import { TemplateSafeValueContainer } from "../../../templateFormatter";
export const MakeRoleMentionableAction = t.type({
type: t.literal("make_role_mentionable"),
@ -15,7 +16,7 @@ export type TMakeRoleMentionableAction = t.TypeOf<typeof MakeRoleMentionableActi
export async function makeRoleMentionableAction(
pluginData: GuildPluginData<CustomEventsPluginType>,
action: TMakeRoleMentionableAction,
values: any,
values: TemplateSafeValueContainer,
event: TCustomEvent,
eventData: any,
) {

View file

@ -3,6 +3,7 @@ import * as t from "io-ts";
import { GuildPluginData } from "knub";
import { ActionError } from "../ActionError";
import { CustomEventsPluginType, TCustomEvent } from "../types";
import { TemplateSafeValueContainer } from "../../../templateFormatter";
export const MakeRoleUnmentionableAction = t.type({
type: t.literal("make_role_unmentionable"),
@ -13,7 +14,7 @@ export type TMakeRoleUnmentionableAction = t.TypeOf<typeof MakeRoleUnmentionable
export async function makeRoleUnmentionableAction(
pluginData: GuildPluginData<CustomEventsPluginType>,
action: TMakeRoleUnmentionableAction,
values: any,
values: TemplateSafeValueContainer,
event: TCustomEvent,
eventData: any,
) {

View file

@ -1,7 +1,7 @@
import { Snowflake, TextChannel } from "discord.js";
import * as t from "io-ts";
import { GuildPluginData } from "knub";
import { renderTemplate } from "../../../templateFormatter";
import { renderTemplate, TemplateSafeValueContainer } from "../../../templateFormatter";
import { ActionError } from "../ActionError";
import { CustomEventsPluginType } from "../types";
@ -15,7 +15,7 @@ export type TMessageAction = t.TypeOf<typeof MessageAction>;
export async function messageAction(
pluginData: GuildPluginData<CustomEventsPluginType>,
action: TMessageAction,
values: any,
values: TemplateSafeValueContainer,
) {
const targetChannelId = await renderTemplate(action.channel, values, false);
const targetChannel = pluginData.guild.channels.cache.get(targetChannelId as Snowflake);

View file

@ -2,7 +2,7 @@ import { Snowflake, VoiceChannel } from "discord.js";
import * as t from "io-ts";
import { GuildPluginData } from "knub";
import { canActOn } from "../../../pluginUtils";
import { renderTemplate } from "../../../templateFormatter";
import { renderTemplate, TemplateSafeValueContainer } from "../../../templateFormatter";
import { resolveMember } from "../../../utils";
import { ActionError } from "../ActionError";
import { CustomEventsPluginType, TCustomEvent } from "../types";
@ -17,7 +17,7 @@ export type TMoveToVoiceChannelAction = t.TypeOf<typeof MoveToVoiceChannelAction
export async function moveToVoiceChannelAction(
pluginData: GuildPluginData<CustomEventsPluginType>,
action: TMoveToVoiceChannelAction,
values: any,
values: TemplateSafeValueContainer,
event: TCustomEvent,
eventData: any,
) {

View file

@ -3,6 +3,7 @@ import * as t from "io-ts";
import { GuildPluginData } from "knub";
import { ActionError } from "../ActionError";
import { CustomEventsPluginType, TCustomEvent } from "../types";
import { TemplateSafeValueContainer } from "../../../templateFormatter";
export const SetChannelPermissionOverridesAction = t.type({
type: t.literal("set_channel_permission_overrides"),
@ -21,7 +22,7 @@ export type TSetChannelPermissionOverridesAction = t.TypeOf<typeof SetChannelPer
export async function setChannelPermissionOverridesAction(
pluginData: GuildPluginData<CustomEventsPluginType>,
action: TSetChannelPermissionOverridesAction,
values: any,
values: TemplateSafeValueContainer,
event: TCustomEvent,
eventData: any,
) {

View file

@ -10,12 +10,13 @@ import { messageAction } from "../actions/messageAction";
import { moveToVoiceChannelAction } from "../actions/moveToVoiceChannelAction";
import { setChannelPermissionOverridesAction } from "../actions/setChannelPermissionOverrides";
import { CustomEventsPluginType, TCustomEvent } from "../types";
import { TemplateSafeValueContainer } from "../../../templateFormatter";
export async function runEvent(
pluginData: GuildPluginData<CustomEventsPluginType>,
event: TCustomEvent,
eventData: any,
values: any,
values: TemplateSafeValueContainer,
) {
try {
for (const action of event.actions) {

View file

@ -36,7 +36,11 @@ import { onMessageDelete } from "./util/onMessageDelete";
import { onMessageDeleteBulk } from "./util/onMessageDeleteBulk";
import { onMessageUpdate } from "./util/onMessageUpdate";
import { Util } from "discord.js";
import { TemplateSafeValueContainer, TypedTemplateSafeValueContainer } from "../../templateFormatter";
import {
createTypedTemplateSafeValueContainer,
TemplateSafeValueContainer,
TypedTemplateSafeValueContainer,
} from "../../templateFormatter";
import { mapToPublicFn } from "../../pluginUtils";
import { logAutomodAction } from "./logFunctions/logAutomodAction";
@ -284,15 +288,19 @@ export const LogsPlugin = zeppelinGuildPlugin<LogsPluginType>()({
state.regexRunnerRepeatedTimeoutListener = (regexSource, timeoutMs, failedTimes) => {
logger.warn(`Disabled heavy regex temporarily: ${regexSource}`);
log(pluginData, LogType.BOT_ALERT, {
body:
`
log(
pluginData,
LogType.BOT_ALERT,
createTypedTemplateSafeValueContainer({
body:
`
The following regex has taken longer than ${timeoutMs}ms for ${failedTimes} times and has been temporarily disabled:
`.trim() +
"\n```" +
Util.escapeCodeBlock(regexSource) +
"```",
});
"\n```" +
Util.escapeCodeBlock(regexSource) +
"```",
}),
);
};
state.regexRunner.on("repeatedTimeout", state.regexRunnerRepeatedTimeoutListener);
},

View file

@ -19,7 +19,10 @@ export function logMemberMuteExpired(pluginData: GuildPluginData<LogsPluginType>
const member =
data.member instanceof GuildMember
? memberToTemplateSafeMember(data.member)
: new TemplateSafeUnknownMember({ ...data.member, user: new TemplateSafeUnknownUser({ ...data.member }) });
: new TemplateSafeUnknownMember({
...data.member,
user: new TemplateSafeUnknownUser({ ...data.member }),
});
const roles = data.member instanceof GuildMember ? Array.from(data.member.roles.cache.keys()) : [];

View file

@ -5,7 +5,7 @@ import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
import { CaseTypes } from "../../../data/CaseTypes";
import { LogType } from "../../../data/LogType";
import { logger } from "../../../logger";
import { renderTemplate } from "../../../templateFormatter";
import { renderTemplate, TemplateSafeValueContainer } from "../../../templateFormatter";
import {
createUserNotificationError,
notifyUser,
@ -48,24 +48,30 @@ export async function banUserId(
if (contactMethods.length) {
if (!banTime && config.ban_message) {
const banMessage = await renderTemplate(config.ban_message, {
guildName: pluginData.guild.name,
reason,
moderator: banOptions.caseArgs?.modId
? stripObjectToScalars(await resolveUser(pluginData.client, banOptions.caseArgs.modId))
: {},
});
const banMessage = await renderTemplate(
config.ban_message,
new TemplateSafeValueContainer({
guildName: pluginData.guild.name,
reason,
moderator: banOptions.caseArgs?.modId
? userToTemplateSafeUser(await resolveUser(pluginData.client, banOptions.caseArgs.modId))
: null,
}),
);
notifyResult = await notifyUser(user, banMessage, contactMethods);
} else if (banTime && config.tempban_message) {
const banMessage = await renderTemplate(config.tempban_message, {
guildName: pluginData.guild.name,
reason,
moderator: banOptions.caseArgs?.modId
? stripObjectToScalars(await resolveUser(pluginData.client, banOptions.caseArgs.modId))
: {},
banTime: humanizeDuration(banTime),
});
const banMessage = await renderTemplate(
config.tempban_message,
new TemplateSafeValueContainer({
guildName: pluginData.guild.name,
reason,
moderator: banOptions.caseArgs?.modId
? userToTemplateSafeUser(await resolveUser(pluginData.client, banOptions.caseArgs.modId))
: null,
banTime: humanizeDuration(banTime),
}),
);
notifyResult = await notifyUser(user, banMessage, contactMethods);
} else {

View file

@ -3,7 +3,7 @@ import { GuildPluginData } from "knub";
import { userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
import { CaseTypes } from "../../../data/CaseTypes";
import { LogType } from "../../../data/LogType";
import { renderTemplate } from "../../../templateFormatter";
import { renderTemplate, TemplateSafeValueContainer } from "../../../templateFormatter";
import { createUserNotificationError, notifyUser, resolveUser, ucfirst, UserNotificationResult } from "../../../utils";
import { CasesPlugin } from "../../Cases/CasesPlugin";
import { IgnoredEventType, KickOptions, KickResult, ModActionsPluginType } from "../types";
@ -31,13 +31,16 @@ export async function kickMember(
if (contactMethods.length) {
if (config.kick_message) {
const kickMessage = await renderTemplate(config.kick_message, {
guildName: pluginData.guild.name,
reason,
moderator: kickOptions.caseArgs?.modId
? userToTemplateSafeUser(await resolveUser(pluginData.client, kickOptions.caseArgs.modId))
: {},
});
const kickMessage = await renderTemplate(
config.kick_message,
new TemplateSafeValueContainer({
guildName: pluginData.guild.name,
reason,
moderator: kickOptions.caseArgs?.modId
? userToTemplateSafeUser(await resolveUser(pluginData.client, kickOptions.caseArgs.modId))
: null,
}),
);
notifyResult = await notifyUser(member.user, kickMessage, contactMethods);
} else {

View file

@ -3,7 +3,7 @@ import { GuildPluginData } from "knub";
import { memberToTemplateSafeMember, userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
import { CaseTypes } from "../../../data/CaseTypes";
import { LogType } from "../../../data/LogType";
import { renderTemplate } from "../../../templateFormatter";
import { renderTemplate, TemplateSafeValueContainer } from "../../../templateFormatter";
import { createUserNotificationError, notifyUser, resolveUser, ucfirst, UserNotificationResult } from "../../../utils";
import { waitForButtonConfirm } from "../../../utils/waitForInteraction";
import { CasesPlugin } from "../../Cases/CasesPlugin";
@ -21,13 +21,16 @@ export async function warnMember(
let notifyResult: UserNotificationResult;
if (config.warn_message) {
const warnMessage = await renderTemplate(config.warn_message, {
guildName: pluginData.guild.name,
reason,
moderator: warnOptions.caseArgs?.modId
? userToTemplateSafeUser(await resolveUser(pluginData.client, warnOptions.caseArgs.modId))
: {},
});
const warnMessage = await renderTemplate(
config.warn_message,
new TemplateSafeValueContainer({
guildName: pluginData.guild.name,
reason,
moderator: warnOptions.caseArgs?.modId
? userToTemplateSafeUser(await resolveUser(pluginData.client, warnOptions.caseArgs.modId))
: null,
}),
);
const contactMethods = warnOptions?.contactMethods
? warnOptions.contactMethods
: getDefaultContactMethods(pluginData, "warn");

View file

@ -7,7 +7,7 @@ import { Case } from "../../../data/entities/Case";
import { LogType } from "../../../data/LogType";
import { LogsPlugin } from "../../../plugins/Logs/LogsPlugin";
import { ERRORS, RecoverablePluginError } from "../../../RecoverablePluginError";
import { renderTemplate } from "../../../templateFormatter";
import { renderTemplate, TemplateSafeValueContainer } from "../../../templateFormatter";
import {
notifyUser,
resolveMember,
@ -151,14 +151,17 @@ export async function muteUser(
const muteMessage =
template &&
(await renderTemplate(template, {
guildName: pluginData.guild.name,
reason: reason || "None",
time: timeUntilUnmute,
moderator: muteOptions.caseArgs?.modId
? userToTemplateSafeUser(await resolveUser(pluginData.client, muteOptions.caseArgs.modId))
: "",
}));
(await renderTemplate(
template,
new TemplateSafeValueContainer({
guildName: pluginData.guild.name,
reason: reason || "None",
time: timeUntilUnmute,
moderator: muteOptions.caseArgs?.modId
? userToTemplateSafeUser(await resolveUser(pluginData.client, muteOptions.caseArgs.modId))
: null,
}),
));
if (muteMessage && user instanceof User) {
let contactMethods: UserNotificationMethod[] = [];

View file

@ -1,11 +1,12 @@
import { Snowflake, TextChannel } from "discord.js";
import {
channelToTemplateSafeChannel,
guildToTemplateSafeGuild,
memberToTemplateSafeMember,
userToTemplateSafeUser,
} from "../../../utils/templateSafeObjects";
import { LogType } from "../../../data/LogType";
import { renderTemplate, TemplateParseError } from "../../../templateFormatter";
import { renderTemplate, TemplateParseError, TemplateSafeValueContainer } from "../../../templateFormatter";
import { createChunkedMessage, stripObjectToScalars, verboseChannelMention, verboseUserMention } from "../../../utils";
import { sendDM } from "../../../utils/sendDM";
import { welcomeMessageEvt } from "../types";
@ -32,12 +33,14 @@ export const SendWelcomeMessageEvt = welcomeMessageEvt({
let formatted;
try {
const strippedMember = stripObjectToScalars(member, ["user", "guild"]);
formatted = await renderTemplate(config.message, {
member: strippedMember,
user: strippedMember["user"],
guild: strippedMember["guild"],
});
formatted = await renderTemplate(
config.message,
new TemplateSafeValueContainer({
member: memberToTemplateSafeMember(member),
user: userToTemplateSafeUser(member.user),
guild: guildToTemplateSafeGuild(member.guild),
}),
);
} catch (e) {
if (e instanceof TemplateParseError) {
pluginData.getPlugin(LogsPlugin).logBotAlert({