3
0
Fork 0
mirror of https://github.com/ZeppelinBot/Zeppelin.git synced 2025-03-15 05:41:51 +00:00

Add auto-delete plugin

This commit is contained in:
Dragory 2020-01-23 01:31:23 +02:00
parent c0b12254b1
commit dc27821a63
No known key found for this signature in database
GPG key ID: 5F387BA66DF8AAC1
4 changed files with 157 additions and 0 deletions

View file

@ -31,6 +31,7 @@
"MESSAGE_DELETE": "🗑 Message (`{message.id}`) from {userMention(user)} deleted in {channelMention(channel)} (originally posted at **{messageDate}**):{messageSummary(message)}",
"MESSAGE_DELETE_BULK": "🗑 **{count}** messages deleted in {channelMention(channel)} ({archiveUrl})",
"MESSAGE_DELETE_BARE": "🗑 Message (`{messageId}`) deleted in {channelMention(channel)} (no more info available)",
"MESSAGE_DELETE_AUTO": "🗑 Auto-deleted message (`{message.id}`) from {userMention(user)} in {channelMention(channel)} (originally posted at **{messageDate}**):{messageSummary(message)}",
"VOICE_CHANNEL_JOIN": "🎙 🔵 {userMention(member)} joined **{channel.name}**",
"VOICE_CHANNEL_MOVE": "🎙 ↔ {userMention(member)} moved from **{oldChannel.name}** to **{newChannel.name}**",

View file

@ -62,4 +62,6 @@ export enum LogType {
SCHEDULED_REPEATED_MESSAGE,
REPEATED_MESSAGE,
MESSAGE_DELETE_AUTO,
}

View file

@ -0,0 +1,152 @@
import { IPluginOptions, logger } from "knub";
import * as t from "io-ts";
import { ZeppelinPlugin } from "./ZeppelinPlugin";
import { GuildSavedMessages } from "../data/GuildSavedMessages";
import { SavedMessage } from "../data/entities/SavedMessage";
import { convertDelayStringToMS, MINUTES, sorter, stripObjectToScalars, tDelayString } from "../utils";
import { GuildLogs } from "../data/GuildLogs";
import { LogType } from "../data/LogType";
import moment from "moment-timezone";
const ConfigSchema = t.type({
enabled: t.boolean,
delay: tDelayString,
});
type TConfigSchema = t.TypeOf<typeof ConfigSchema>;
interface IDeletionQueueItem {
deleteAt: number;
message: SavedMessage;
}
const MAX_DELAY = 5 * MINUTES;
export class AutoDeletePlugin extends ZeppelinPlugin<TConfigSchema> {
public static pluginName = "auto_delete";
public static showInDocs = true;
public static configSchema = ConfigSchema;
public static pluginInfo = {
prettyName: "Auto-delete",
description: "Allows Zeppelin to auto-delete messages from a channel after a delay",
configurationGuide: "Maximum deletion delay is currently 5 minutes",
};
protected guildSavedMessages: GuildSavedMessages;
protected guildLogs: GuildLogs;
protected onMessageCreateFn;
protected onMessageDeleteFn;
protected onMessageDeleteBulkFn;
protected deletionQueue: IDeletionQueueItem[];
protected nextDeletion: number;
protected nextDeletionTimeout;
protected maxDelayWarningSent = false;
public static getStaticDefaultOptions(): IPluginOptions<TConfigSchema> {
return {
config: {
enabled: false,
delay: "5s",
},
};
}
protected onLoad() {
this.guildSavedMessages = GuildSavedMessages.getGuildInstance(this.guildId);
this.guildLogs = new GuildLogs(this.guildId);
this.deletionQueue = [];
this.onMessageCreateFn = this.onMessageCreate.bind(this);
this.onMessageDeleteFn = this.onMessageDelete.bind(this);
this.onMessageDeleteBulkFn = this.onMessageDeleteBulk.bind(this);
this.guildSavedMessages.events.on("create", this.onMessageCreateFn);
this.guildSavedMessages.events.on("delete", this.onMessageDeleteFn);
this.guildSavedMessages.events.on("deleteBulk", this.onMessageDeleteBulkFn);
}
protected onUnload() {
this.guildSavedMessages.events.off("create", this.onMessageCreateFn);
this.guildSavedMessages.events.off("delete", this.onMessageDeleteFn);
this.guildSavedMessages.events.off("deleteBulk", this.onMessageDeleteFn);
clearTimeout(this.nextDeletionTimeout);
}
protected addMessageToDeletionQueue(msg: SavedMessage, delay: number) {
const deleteAt = Date.now() + delay;
this.deletionQueue.push({ deleteAt, message: msg });
this.deletionQueue.sort(sorter("deleteAt"));
this.scheduleNextDeletion();
}
protected scheduleNextDeletion() {
if (this.deletionQueue.length === 0) {
clearTimeout(this.nextDeletionTimeout);
return;
}
const firstDeleteAt = this.deletionQueue[0].deleteAt;
clearTimeout(this.nextDeletionTimeout);
this.nextDeletionTimeout = setTimeout(() => this.deleteNextItem(), firstDeleteAt - Date.now());
}
protected async deleteNextItem() {
const [itemToDelete] = this.deletionQueue.splice(0, 1);
if (!itemToDelete) return;
this.guildLogs.ignoreLog(LogType.MESSAGE_DELETE, itemToDelete.message.id);
this.bot.deleteMessage(itemToDelete.message.channel_id, itemToDelete.message.id).catch(logger.warn);
this.scheduleNextDeletion();
const user = await this.resolveUser(itemToDelete.message.user_id);
const channel = this.guild.channels.get(itemToDelete.message.channel_id);
const messageDate = moment(itemToDelete.message.data.timestamp, "x").format("YYYY-MM-DD HH:mm:ss");
this.guildLogs.log(LogType.MESSAGE_DELETE_AUTO, {
message: itemToDelete.message,
user: stripObjectToScalars(user),
channel: stripObjectToScalars(channel),
messageDate,
});
}
protected onMessageCreate(msg: SavedMessage) {
const config = this.getConfigForMemberIdAndChannelId(msg.user_id, msg.channel_id);
if (config.enabled) {
let delay = convertDelayStringToMS(config.delay);
if (delay > MAX_DELAY) {
delay = MAX_DELAY;
if (!this.maxDelayWarningSent) {
this.guildLogs.log(LogType.BOT_ALERT, {
body: `Clamped auto-deletion delay in <#${msg.channel_id}> to 5 minutes`,
});
this.maxDelayWarningSent = true;
}
}
this.addMessageToDeletionQueue(msg, delay);
}
}
protected onMessageDelete(msg: SavedMessage) {
const indexToDelete = this.deletionQueue.findIndex(item => item.message.id === msg.id);
if (indexToDelete > -1) {
this.deletionQueue.splice(indexToDelete, 1);
this.scheduleNextDeletion();
}
}
protected onMessageDeleteBulk(messages: SavedMessage[]) {
for (const msg of messages) {
this.onMessageDelete(msg);
}
}
}

View file

@ -28,6 +28,7 @@ import { GuildConfigReloader } from "./GuildConfigReloader";
import { ChannelArchiverPlugin } from "./ChannelArchiver";
import { AutomodPlugin } from "./Automod";
import { RolesPlugin } from "./Roles";
import { AutoDeletePlugin } from "./AutoDelete";
/**
* Plugins available to be loaded for individual guilds
@ -60,6 +61,7 @@ export const availablePlugins = [
LocatePlugin,
ChannelArchiverPlugin,
RolesPlugin,
AutoDeletePlugin,
];
/**