Add a generic bot alert log type. Use this in several places.

This commit is contained in:
Dragory 2019-05-04 19:18:16 +03:00
parent e18193c1a2
commit 8a3097f63e
8 changed files with 110 additions and 27 deletions

View file

@ -55,5 +55,7 @@
"MEMBER_MUTE_REJOIN": "⚠ Reapplied active mute for {userMention(member)} on rejoin",
"SCHEDULED_MESSAGE": "⏰ {userMention(author)} scheduled a message to be posted to {channelMention(channel)} on {date} at {time} (UTC)",
"POSTED_SCHEDULED_MESSAGE": "\uD83D\uDCE8 Posted scheduled message (`{messageId}`) to {channelMention(channel)} as scheduled by {userMention(author)}"
"POSTED_SCHEDULED_MESSAGE": "\uD83D\uDCE8 Posted scheduled message (`{messageId}`) to {channelMention(channel)} as scheduled by {userMention(author)}",
"BOT_ALERT": "⚠ {tmplEval(body)}"
}

View file

@ -56,4 +56,6 @@ export enum LogType {
SCHEDULED_MESSAGE,
POSTED_SCHEDULED_MESSAGE,
BOT_ALERT,
}

View file

@ -7,6 +7,8 @@ import { CaseTypeColors } from "../data/CaseTypeColors";
import { ZeppelinPlugin } from "./ZeppelinPlugin";
import { GuildArchives } from "../data/GuildArchives";
import { IPluginOptions } from "knub";
import { GuildLogs } from "../data/GuildLogs";
import { LogType } from "../data/LogType";
interface ICasesPluginConfig {
log_automatic_actions: boolean;
@ -43,6 +45,7 @@ export class CasesPlugin extends ZeppelinPlugin<ICasesPluginConfig> {
protected cases: GuildCases;
protected archives: GuildArchives;
protected logs: GuildLogs;
getDefaultOptions(): IPluginOptions<ICasesPluginConfig> {
return {
@ -56,11 +59,7 @@ export class CasesPlugin extends ZeppelinPlugin<ICasesPluginConfig> {
onLoad() {
this.cases = GuildCases.getInstance(this.guildId);
this.archives = GuildArchives.getInstance(this.guildId);
// this.actions.register("postCase", async args => {
// const embed = await this.getCaseEmbed(args.caseId);
// return (args.channel as TextableChannel).createMessage(embed);
// });
this.logs = new GuildLogs(this.guildId);
}
protected resolveCaseId(caseOrCaseId: Case | number): number {
@ -124,9 +123,7 @@ export class CasesPlugin extends ZeppelinPlugin<ICasesPluginConfig> {
(!args.automatic || config.log_automatic_actions) &&
args.postInCaseLogOverride !== false
) {
try {
await this.postCaseToCaseLogChannel(createdCase);
} catch (e) {} // tslint:disable-line
await this.postCaseToCaseLogChannel(createdCase);
}
return createdCase;
@ -173,9 +170,7 @@ export class CasesPlugin extends ZeppelinPlugin<ICasesPluginConfig> {
}
if ((!args.automatic || this.getConfig().log_automatic_actions) && args.postInCaseLogOverride !== false) {
try {
await this.postCaseToCaseLogChannel(theCase.id);
} catch (e) {} // tslint:disable-line
await this.postCaseToCaseLogChannel(theCase.id);
}
}
@ -256,9 +251,19 @@ export class CasesPlugin extends ZeppelinPlugin<ICasesPluginConfig> {
* A helper to post a case embed to the case log channel
*/
public async postCaseToCaseLogChannel(caseOrCaseId: Case | number): Promise<Message> {
const theCase = await this.cases.find(this.resolveCaseId(caseOrCaseId));
if (!theCase) return;
const caseEmbed = await this.getCaseEmbed(caseOrCaseId);
if (!caseEmbed) return;
return this.postToCaseLogChannel(caseEmbed);
try {
return this.postToCaseLogChannel(caseEmbed);
} catch (e) {
this.logs.log(LogType.BOT_ALERT, {
body: `Failed to post case #${theCase.case_number} to the case log channel`,
});
return null;
}
}
}

View file

@ -169,7 +169,7 @@ export class LogsPlugin extends ZeppelinPlugin<ILogsPluginConfig> {
let formatted;
try {
formatted = await renderTemplate(format, {
const values = {
...data,
userMention: async userOrMember => {
if (!userOrMember) return "";
@ -217,7 +217,16 @@ export class LogsPlugin extends ZeppelinPlugin<ILogsPluginConfig> {
return result;
},
});
};
if (type === LogType.BOT_ALERT) {
const valuesWithoutTmplEval = { ...values };
values.tmplEval = str => {
return renderTemplate(str, valuesWithoutTmplEval);
};
}
formatted = await renderTemplate(format, values);
} catch (e) {
if (e instanceof TemplateParseError) {
logger.error(`Error when parsing template:\nError: ${e.message}\nTemplate: ${format}`);

View file

@ -571,7 +571,12 @@ export class MutesPlugin extends ZeppelinPlugin<IMutesPluginConfig> {
if (member) {
try {
await member.removeRole(this.getConfig().mute_role);
} catch (e) {} // tslint:disable-line
} catch (e) {
this.serverLogs.log(LogType.BOT_ALERT, {
body: `Failed to remove mute role from {userMention(member)}`,
member: stripObjectToScalars(member),
});
}
}
await this.mutes.clear(mute.user_id);

View file

@ -152,16 +152,26 @@ export class PostPlugin extends ZeppelinPlugin<IPostPluginConfig> {
for (const post of duePosts) {
const channel = this.guild.channels.get(post.channel_id);
if (channel instanceof TextChannel) {
const [username, discriminator] = post.author_name.split("#");
const author: Partial<User> = this.bot.users.get(post.author_id) || {
id: post.author_id,
username,
discriminator,
};
try {
const postedMessage = await this.postMessage(channel, post.content, post.attachments, post.enable_mentions);
const [username, discriminator] = post.author_name.split("#");
this.logs.log(LogType.POSTED_SCHEDULED_MESSAGE, {
author: ({ id: post.author_id, username, discriminator } as any) as Partial<User>,
author: stripObjectToScalars(author),
channel: stripObjectToScalars(channel),
messageId: postedMessage.id,
});
} catch (e) {
this.logs.log(LogType.BOT_ALERT, {
body: `Failed to post scheduled message by {userMention(author)} to {channelMention(channel)}`,
channel: stripObjectToScalars(channel),
author: stripObjectToScalars(author),
});
logger.warn(
`Failed to post scheduled message to #${channel.name} (${channel.id}) on ${this.guild.name} (${
this.guildId

View file

@ -1,12 +1,22 @@
import { decorators as d, IPluginOptions, logger } from "knub";
import { GuildChannel, Message, TextChannel, Constants as ErisConstants, User } from "eris";
import { convertDelayStringToMS, createChunkedMessage, errorMessage, noop, successMessage } from "../utils";
import {
convertDelayStringToMS,
createChunkedMessage,
errorMessage,
noop,
stripObjectToScalars,
successMessage,
UnknownUser,
} from "../utils";
import { GuildSlowmodes } from "../data/GuildSlowmodes";
import humanizeDuration from "humanize-duration";
import { ZeppelinPlugin } from "./ZeppelinPlugin";
import { SavedMessage } from "../data/entities/SavedMessage";
import { GuildSavedMessages } from "../data/GuildSavedMessages";
import DiscordRESTError from "eris/lib/errors/DiscordRESTError"; // tslint:disable-line
import { GuildLogs } from "../data/GuildLogs";
import { LogType } from "../data/LogType";
const NATIVE_SLOWMODE_LIMIT = 6 * 60 * 60; // 6 hours
const MAX_SLOWMODE = 60 * 60 * 24 * 365 * 100; // 100 years
@ -24,6 +34,7 @@ export class SlowmodePlugin extends ZeppelinPlugin<ISlowmodePluginConfig> {
protected slowmodes: GuildSlowmodes;
protected savedMessages: GuildSavedMessages;
protected logs: GuildLogs;
protected clearInterval;
private onMessageCreateFn;
@ -52,6 +63,7 @@ export class SlowmodePlugin extends ZeppelinPlugin<ISlowmodePluginConfig> {
onLoad() {
this.slowmodes = GuildSlowmodes.getInstance(this.guildId);
this.savedMessages = GuildSavedMessages.getInstance(this.guildId);
this.logs = new GuildLogs(this.guildId);
this.clearInterval = setInterval(() => this.clearExpiredSlowmodes(), BOT_SLOWMODE_CLEAR_INTERVAL);
this.onMessageCreateFn = this.onMessageCreate.bind(this);
@ -78,13 +90,25 @@ export class SlowmodePlugin extends ZeppelinPlugin<ISlowmodePluginConfig> {
try {
await channel.editPermission(userId, newAllowedPermissions, newDeniedPermissions, "member");
} catch (e) {
const user = this.bot.users.get(userId) || new UnknownUser({ id: userId });
if (e instanceof DiscordRESTError && e.code === 50013) {
logger.warn(
`Missing permissions to apply bot slowmode to user ${userId} on channel ${channel.name} (${
channel.id
}) on server ${this.guild.name} (${this.guildId})`,
);
this.logs.log(LogType.BOT_ALERT, {
body: `Missing permissions to apply bot slowmode to {userMention(user)} in {channelMention(channel)}`,
user: stripObjectToScalars(user),
channel: stripObjectToScalars(channel),
});
} else {
this.logs.log(LogType.BOT_ALERT, {
body: `Failed to apply bot slowmode to {userMention(user)} in {channelMention(channel)}`,
user: stripObjectToScalars(user),
channel: stripObjectToScalars(channel),
});
throw e;
}
}
@ -190,11 +214,18 @@ export class SlowmodePlugin extends ZeppelinPlugin<ISlowmodePluginConfig> {
return;
}
await this.clearBotSlowmodeFromUserId(args.channel, args.user.id);
msg.channel.createMessage(
successMessage(
`Slowmode cleared from **${args.user.username}#${args.user.discriminator}** in <#${args.channel.id}>`,
),
try {
await this.clearBotSlowmodeFromUserId(args.channel, args.user.id);
} catch (e) {
return this.sendErrorMessage(
msg.channel,
`Failed to clear slowmode from **${args.user.username}#${args.user.discriminator}** in <#${args.channel.id}>`,
);
}
this.sendSuccessMessage(
msg.channel,
`Slowmode cleared from **${args.user.username}#${args.user.discriminator}** in <#${args.channel.id}>`,
);
}

View file

@ -3,6 +3,8 @@ import { decorators as d, IPluginOptions } from "knub";
import { Member, TextChannel } from "eris";
import { renderTemplate } from "../templateFormatter";
import { createChunkedMessage, stripObjectToScalars } from "../utils";
import { LogType } from "../data/LogType";
import { GuildLogs } from "../data/GuildLogs";
interface IWelcomeMessageConfig {
send_dm: boolean;
@ -13,6 +15,8 @@ interface IWelcomeMessageConfig {
export class WelcomeMessagePlugin extends ZeppelinPlugin<IWelcomeMessageConfig> {
public static pluginName = "welcome_message";
protected logs: GuildLogs;
protected getDefaultOptions(): IPluginOptions<IWelcomeMessageConfig> {
return {
config: {
@ -23,6 +27,10 @@ export class WelcomeMessagePlugin extends ZeppelinPlugin<IWelcomeMessageConfig>
};
}
protected onLoad() {
this.logs = new GuildLogs(this.guildId);
}
@d.event("guildMemberAdd")
async onGuildMemberAdd(_, member: Member) {
const config = this.getConfig();
@ -39,7 +47,12 @@ export class WelcomeMessagePlugin extends ZeppelinPlugin<IWelcomeMessageConfig>
try {
createChunkedMessage(dmChannel, formatted);
} catch (e) {} // tslint:disable-line
} catch (e) {
this.logs.log(LogType.BOT_ALERT, {
body: `Failed send a welcome DM to {userMention(member)}`,
member: stripObjectToScalars(member),
});
}
}
if (config.send_to_channel) {
@ -48,7 +61,13 @@ export class WelcomeMessagePlugin extends ZeppelinPlugin<IWelcomeMessageConfig>
try {
createChunkedMessage(channel, formatted);
} catch (e) {} // tslint:disable-line
} catch (e) {
this.logs.log(LogType.BOT_ALERT, {
body: `Failed send a welcome message for {userMention(member)} to {channelMention(channel)}`,
member: stripObjectToScalars(member),
channel: stripObjectToScalars(channel),
});
}
}
}
}