Chunk text-only log messages. Use a cooldown if running into Missing Access / Missing Permissions error during logging.

This commit is contained in:
Dragory 2021-09-11 19:20:31 +03:00
parent ac79eb09f5
commit e6694f3751
No known key found for this signature in database
GPG key ID: 5F387BA66DF8AAC1
3 changed files with 26 additions and 13 deletions

View file

@ -1,4 +1,4 @@
import { PluginOptions } from "knub"; import { CooldownManager, PluginOptions } from "knub";
import DefaultLogMessages from "../../data/DefaultLogMessages.json"; import DefaultLogMessages from "../../data/DefaultLogMessages.json";
import { GuildArchives } from "../../data/GuildArchives"; import { GuildArchives } from "../../data/GuildArchives";
import { GuildCases } from "../../data/GuildCases"; import { GuildCases } from "../../data/GuildCases";
@ -267,6 +267,7 @@ export const LogsPlugin = zeppelinGuildPlugin<LogsPluginType>()({
state.cases = GuildCases.getGuildInstance(guild.id); state.cases = GuildCases.getGuildInstance(guild.id);
state.buffers = new Map(); state.buffers = new Map();
state.channelCooldowns = new CooldownManager();
state.regexRunner = getRegExpRunner(`guild-${pluginData.guild.id}`); state.regexRunner = getRegExpRunner(`guild-${pluginData.guild.id}`);
}, },

View file

@ -1,6 +1,6 @@
import * as t from "io-ts"; import * as t from "io-ts";
import { z } from "zod"; import { z } from "zod";
import { BasePluginType, typedGuildEventListener } from "knub"; import { BasePluginType, CooldownManager, typedGuildEventListener } from "knub";
import { GuildArchives } from "../../data/GuildArchives"; import { GuildArchives } from "../../data/GuildArchives";
import { GuildCases } from "../../data/GuildCases"; import { GuildCases } from "../../data/GuildCases";
import { GuildLogs } from "../../data/GuildLogs"; import { GuildLogs } from "../../data/GuildLogs";
@ -87,6 +87,7 @@ export interface LogsPluginType extends BasePluginType {
logListener; logListener;
buffers: Map<string, MessageBuffer>; buffers: Map<string, MessageBuffer>;
channelCooldowns: CooldownManager;
onMessageDeleteFn; onMessageDeleteFn;
onMessageDeleteBulkFn; onMessageDeleteBulkFn;

View file

@ -6,6 +6,7 @@ import { getLogMessage } from "./getLogMessage";
import { TypedTemplateSafeValueContainer } from "../../../templateFormatter"; import { TypedTemplateSafeValueContainer } from "../../../templateFormatter";
import { LogType } from "../../../data/LogType"; import { LogType } from "../../../data/LogType";
import { MessageBuffer } from "../../../utils/MessageBuffer"; import { MessageBuffer } from "../../../utils/MessageBuffer";
import { createChunkedMessage, isDiscordAPIError, MINUTES } from "../../../utils";
const excludedUserProps = ["user", "member", "mod"]; const excludedUserProps = ["user", "member", "mod"];
const excludedRoleProps = ["message.member.roles", "member.roles"]; const excludedRoleProps = ["message.member.roles", "member.roles"];
@ -82,6 +83,7 @@ export async function log<TLogType extends keyof ILogTypeData>(
logChannelLoop: for (const [channelId, opts] of Object.entries(logChannels)) { logChannelLoop: for (const [channelId, opts] of Object.entries(logChannels)) {
const channel = pluginData.guild.channels.cache.get(channelId as Snowflake); const channel = pluginData.guild.channels.cache.get(channelId as Snowflake);
if (!channel || !(channel instanceof TextChannel)) continue; if (!channel || !(channel instanceof TextChannel)) continue;
if (pluginData.state.channelCooldowns.isOnCooldown(channelId)) continue;
if (opts.include?.length && !opts.include.includes(typeStr)) continue; if (opts.include?.length && !opts.include.includes(typeStr)) continue;
if (opts.exclude && opts.exclude.includes(typeStr)) continue; if (opts.exclude && opts.exclude.includes(typeStr)) continue;
if (await shouldExclude(pluginData, opts, exclusionData)) continue; if (await shouldExclude(pluginData, opts, exclusionData)) continue;
@ -102,17 +104,26 @@ export async function log<TLogType extends keyof ILogTypeData>(
timeout: batchTime, timeout: batchTime,
consume: (part) => { consume: (part) => {
const parse: MessageMentionTypes[] = pluginData.config.get().allow_user_mentions ? ["users"] : []; const parse: MessageMentionTypes[] = pluginData.config.get().allow_user_mentions ? ["users"] : [];
channel const promise =
.send({ part.content && !part.embeds?.length
...part, ? createChunkedMessage(channel, part.content, { parse })
allowedMentions: { parse }, : channel.send({
}) ...part,
.catch((err) => { allowedMentions: { parse },
// tslint:disable-next-line:no-console });
console.warn( promise.catch((err) => {
`Error while sending ${typeStr} log to ${pluginData.guild.id}/${channelId}: ${err.message}`, if (isDiscordAPIError(err)) {
); // Missing Access / Missing Permissions
}); // TODO: Show/log this somewhere
if (err.code === 50001 || err.code === 50013) {
pluginData.state.channelCooldowns.setCooldown(channelId, 2 * MINUTES);
return;
}
}
// tslint:disable-next-line:no-console
console.warn(`Error while sending ${typeStr} log to ${pluginData.guild.id}/${channelId}: ${err.message}`);
});
}, },
}), }),
); );