diff --git a/backend/src/plugins/Logs/types.ts b/backend/src/plugins/Logs/types.ts index 2a13e334..fd51da08 100644 --- a/backend/src/plugins/Logs/types.ts +++ b/backend/src/plugins/Logs/types.ts @@ -5,6 +5,7 @@ import { GuildLogs } from "src/data/GuildLogs"; import { GuildSavedMessages } from "src/data/GuildSavedMessages"; import { GuildArchives } from "src/data/GuildArchives"; import { GuildCases } from "src/data/GuildCases"; +import { tMessageContent } from "../../utils"; const LogChannel = t.partial({ include: t.array(t.string), @@ -20,14 +21,16 @@ export type TLogChannel = t.TypeOf; const LogChannelMap = t.record(t.string, LogChannel); export type TLogChannelMap = t.TypeOf; +const tLogFormats = t.intersection([ + t.record(t.string, t.union([t.string, tMessageContent])), + t.type({ + timestamp: t.string, + }), +]); + export const ConfigSchema = t.type({ channels: LogChannelMap, - format: t.intersection([ - t.record(t.string, t.string), - t.type({ - timestamp: t.string, - }), - ]), + format: tLogFormats, ping_user: t.boolean, }); export type TConfigSchema = t.TypeOf; diff --git a/backend/src/plugins/Logs/util/getLogMessage.ts b/backend/src/plugins/Logs/util/getLogMessage.ts index 854f7259..b84b9df7 100644 --- a/backend/src/plugins/Logs/util/getLogMessage.ts +++ b/backend/src/plugins/Logs/util/getLogMessage.ts @@ -1,7 +1,14 @@ import { PluginData } from "knub"; import { LogsPluginType } from "../types"; import { LogType } from "src/data/LogType"; -import { verboseUserMention, verboseUserName, verboseChannelMention, messageSummary, resolveMember } from "src/utils"; +import { + verboseUserMention, + verboseUserName, + verboseChannelMention, + messageSummary, + resolveMember, + renderRecursively, +} from "src/utils"; import { SavedMessage } from "src/data/entities/SavedMessage"; import { renderTemplate, TemplateParseError } from "src/templateFormatter"; import { logger } from "src/logger"; @@ -12,53 +19,55 @@ export async function getLogMessage(pluginData: PluginData, type const format = config.format[LogType[type]] || ""; if (format === "") return; - let formatted; - try { - const values = { - ...data, - userMention: async inputUserOrMember => { - if (!inputUserOrMember) return ""; + const values = { + ...data, + userMention: async inputUserOrMember => { + if (!inputUserOrMember) return ""; - const usersOrMembers = Array.isArray(inputUserOrMember) ? inputUserOrMember : [inputUserOrMember]; + const usersOrMembers = Array.isArray(inputUserOrMember) ? inputUserOrMember : [inputUserOrMember]; - const mentions = []; - for (const userOrMember of usersOrMembers) { - let user; - let member; + const mentions = []; + for (const userOrMember of usersOrMembers) { + let user; + let member; - if (userOrMember.user) { - member = userOrMember; - user = member.user; - } else { - user = userOrMember; - member = await resolveMember(pluginData.client, pluginData.guild, user.id); - } - - const memberConfig = pluginData.config.getMatchingConfig({ member, userId: user.id }) || ({} as any); - - mentions.push(memberConfig.ping_user ? verboseUserMention(user) : verboseUserName(user)); + if (userOrMember.user) { + member = userOrMember; + user = member.user; + } else { + user = userOrMember; + member = await resolveMember(pluginData.client, pluginData.guild, user.id); } - return mentions.join(", "); - }, - channelMention: channel => { - if (!channel) return ""; - return verboseChannelMention(channel); - }, - messageSummary: (msg: SavedMessage) => { - if (!msg) return ""; - return messageSummary(msg); - }, + const memberConfig = pluginData.config.getMatchingConfig({ member, userId: user.id }) || ({} as any); + + mentions.push(memberConfig.ping_user ? verboseUserMention(user) : verboseUserName(user)); + } + + return mentions.join(", "); + }, + channelMention: channel => { + if (!channel) return ""; + return verboseChannelMention(channel); + }, + messageSummary: (msg: SavedMessage) => { + if (!msg) return ""; + return messageSummary(msg); + }, + }; + + if (type === LogType.BOT_ALERT) { + const valuesWithoutTmplEval = { ...values }; + values.tmplEval = str => { + return renderTemplate(str, valuesWithoutTmplEval); }; + } - if (type === LogType.BOT_ALERT) { - const valuesWithoutTmplEval = { ...values }; - values.tmplEval = str => { - return renderTemplate(str, valuesWithoutTmplEval); - }; - } + const renderLogString = str => renderTemplate(str, values); - formatted = await renderTemplate(format, values); + let formatted; + try { + formatted = typeof format === "string" ? await renderLogString(format) : renderRecursively(format, renderLogString); } catch (e) { if (e instanceof TemplateParseError) { logger.error(`Error when parsing template:\nError: ${e.message}\nTemplate: ${format}`); @@ -68,13 +77,15 @@ export async function getLogMessage(pluginData: PluginData, type } } - formatted = formatted.trim(); + if (typeof formatted === "string") { + formatted = formatted.trim(); - const timestampFormat = config.format.timestamp; - if (timestampFormat) { - const timestamp = moment().format(timestampFormat); - return `\`[${timestamp}]\` ${formatted}`; - } else { - return formatted; + const timestampFormat = config.format.timestamp; + if (timestampFormat) { + const timestamp = moment().format(timestampFormat); + formatted = `\`[${timestamp}]\` ${formatted}`; + } } + + return formatted; } diff --git a/backend/src/plugins/Logs/util/log.ts b/backend/src/plugins/Logs/util/log.ts index 59fa2a64..169c4ad6 100644 --- a/backend/src/plugins/Logs/util/log.ts +++ b/backend/src/plugins/Logs/util/log.ts @@ -59,7 +59,14 @@ export async function log(pluginData: PluginData, type: LogType, const message = await getLogMessage(pluginData, type, data); if (message) { - const batched = opts.batched ?? true; // Default to batched unless explicitly disabled + // For non-string log messages (i.e. embeds) batching or chunking is not possible, so send them immediately + if (typeof message !== "string") { + await channel.createMessage(message).catch(noop); + return; + } + + // Default to batched unless explicitly disabled + const batched = opts.batched ?? true; const batchTime = opts.batch_time ?? 1000; if (batched) {