logs: add support for embeds in log formats
This commit is contained in:
parent
b6b4154b2d
commit
8b22ce267d
3 changed files with 75 additions and 54 deletions
|
@ -5,6 +5,7 @@ import { GuildLogs } from "src/data/GuildLogs";
|
||||||
import { GuildSavedMessages } from "src/data/GuildSavedMessages";
|
import { GuildSavedMessages } from "src/data/GuildSavedMessages";
|
||||||
import { GuildArchives } from "src/data/GuildArchives";
|
import { GuildArchives } from "src/data/GuildArchives";
|
||||||
import { GuildCases } from "src/data/GuildCases";
|
import { GuildCases } from "src/data/GuildCases";
|
||||||
|
import { tMessageContent } from "../../utils";
|
||||||
|
|
||||||
const LogChannel = t.partial({
|
const LogChannel = t.partial({
|
||||||
include: t.array(t.string),
|
include: t.array(t.string),
|
||||||
|
@ -20,14 +21,16 @@ export type TLogChannel = t.TypeOf<typeof LogChannel>;
|
||||||
const LogChannelMap = t.record(t.string, LogChannel);
|
const LogChannelMap = t.record(t.string, LogChannel);
|
||||||
export type TLogChannelMap = t.TypeOf<typeof LogChannelMap>;
|
export type TLogChannelMap = t.TypeOf<typeof LogChannelMap>;
|
||||||
|
|
||||||
|
const tLogFormats = t.intersection([
|
||||||
|
t.record(t.string, t.union([t.string, tMessageContent])),
|
||||||
|
t.type({
|
||||||
|
timestamp: t.string,
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
|
||||||
export const ConfigSchema = t.type({
|
export const ConfigSchema = t.type({
|
||||||
channels: LogChannelMap,
|
channels: LogChannelMap,
|
||||||
format: t.intersection([
|
format: tLogFormats,
|
||||||
t.record(t.string, t.string),
|
|
||||||
t.type({
|
|
||||||
timestamp: t.string,
|
|
||||||
}),
|
|
||||||
]),
|
|
||||||
ping_user: t.boolean,
|
ping_user: t.boolean,
|
||||||
});
|
});
|
||||||
export type TConfigSchema = t.TypeOf<typeof ConfigSchema>;
|
export type TConfigSchema = t.TypeOf<typeof ConfigSchema>;
|
||||||
|
|
|
@ -1,7 +1,14 @@
|
||||||
import { PluginData } from "knub";
|
import { PluginData } from "knub";
|
||||||
import { LogsPluginType } from "../types";
|
import { LogsPluginType } from "../types";
|
||||||
import { LogType } from "src/data/LogType";
|
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 { SavedMessage } from "src/data/entities/SavedMessage";
|
||||||
import { renderTemplate, TemplateParseError } from "src/templateFormatter";
|
import { renderTemplate, TemplateParseError } from "src/templateFormatter";
|
||||||
import { logger } from "src/logger";
|
import { logger } from "src/logger";
|
||||||
|
@ -12,53 +19,55 @@ export async function getLogMessage(pluginData: PluginData<LogsPluginType>, type
|
||||||
const format = config.format[LogType[type]] || "";
|
const format = config.format[LogType[type]] || "";
|
||||||
if (format === "") return;
|
if (format === "") return;
|
||||||
|
|
||||||
let formatted;
|
const values = {
|
||||||
try {
|
...data,
|
||||||
const values = {
|
userMention: async inputUserOrMember => {
|
||||||
...data,
|
if (!inputUserOrMember) return "";
|
||||||
userMention: async inputUserOrMember => {
|
|
||||||
if (!inputUserOrMember) return "";
|
|
||||||
|
|
||||||
const usersOrMembers = Array.isArray(inputUserOrMember) ? inputUserOrMember : [inputUserOrMember];
|
const usersOrMembers = Array.isArray(inputUserOrMember) ? inputUserOrMember : [inputUserOrMember];
|
||||||
|
|
||||||
const mentions = [];
|
const mentions = [];
|
||||||
for (const userOrMember of usersOrMembers) {
|
for (const userOrMember of usersOrMembers) {
|
||||||
let user;
|
let user;
|
||||||
let member;
|
let member;
|
||||||
|
|
||||||
if (userOrMember.user) {
|
if (userOrMember.user) {
|
||||||
member = userOrMember;
|
member = userOrMember;
|
||||||
user = member.user;
|
user = member.user;
|
||||||
} else {
|
} else {
|
||||||
user = userOrMember;
|
user = userOrMember;
|
||||||
member = await resolveMember(pluginData.client, pluginData.guild, user.id);
|
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return mentions.join(", ");
|
const memberConfig = pluginData.config.getMatchingConfig({ member, userId: user.id }) || ({} as any);
|
||||||
},
|
|
||||||
channelMention: channel => {
|
mentions.push(memberConfig.ping_user ? verboseUserMention(user) : verboseUserName(user));
|
||||||
if (!channel) return "";
|
}
|
||||||
return verboseChannelMention(channel);
|
|
||||||
},
|
return mentions.join(", ");
|
||||||
messageSummary: (msg: SavedMessage) => {
|
},
|
||||||
if (!msg) return "";
|
channelMention: channel => {
|
||||||
return messageSummary(msg);
|
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 renderLogString = str => renderTemplate(str, values);
|
||||||
const valuesWithoutTmplEval = { ...values };
|
|
||||||
values.tmplEval = str => {
|
|
||||||
return renderTemplate(str, valuesWithoutTmplEval);
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
formatted = await renderTemplate(format, values);
|
let formatted;
|
||||||
|
try {
|
||||||
|
formatted = typeof format === "string" ? await renderLogString(format) : renderRecursively(format, renderLogString);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
if (e instanceof TemplateParseError) {
|
if (e instanceof TemplateParseError) {
|
||||||
logger.error(`Error when parsing template:\nError: ${e.message}\nTemplate: ${format}`);
|
logger.error(`Error when parsing template:\nError: ${e.message}\nTemplate: ${format}`);
|
||||||
|
@ -68,13 +77,15 @@ export async function getLogMessage(pluginData: PluginData<LogsPluginType>, type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
formatted = formatted.trim();
|
if (typeof formatted === "string") {
|
||||||
|
formatted = formatted.trim();
|
||||||
|
|
||||||
const timestampFormat = config.format.timestamp;
|
const timestampFormat = config.format.timestamp;
|
||||||
if (timestampFormat) {
|
if (timestampFormat) {
|
||||||
const timestamp = moment().format(timestampFormat);
|
const timestamp = moment().format(timestampFormat);
|
||||||
return `\`[${timestamp}]\` ${formatted}`;
|
formatted = `\`[${timestamp}]\` ${formatted}`;
|
||||||
} else {
|
}
|
||||||
return formatted;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return formatted;
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,14 @@ export async function log(pluginData: PluginData<LogsPluginType>, type: LogType,
|
||||||
|
|
||||||
const message = await getLogMessage(pluginData, type, data);
|
const message = await getLogMessage(pluginData, type, data);
|
||||||
if (message) {
|
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;
|
const batchTime = opts.batch_time ?? 1000;
|
||||||
|
|
||||||
if (batched) {
|
if (batched) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue