Merge pull request #87 from DarkView/k30_autoDelete
[K30] Migrated AutoDelete
This commit is contained in:
commit
8c7cd245f6
9 changed files with 194 additions and 0 deletions
48
backend/src/plugins/AutoDelete/AutoDeletePlugin.ts
Normal file
48
backend/src/plugins/AutoDelete/AutoDeletePlugin.ts
Normal file
|
@ -0,0 +1,48 @@
|
|||
import { PluginOptions } from "knub";
|
||||
import { AutoDeletePluginType, ConfigSchema } from "./types";
|
||||
import { zeppelinPlugin } from "../ZeppelinPluginBlueprint";
|
||||
import { GuildSavedMessages } from "src/data/GuildSavedMessages";
|
||||
import { GuildLogs } from "src/data/GuildLogs";
|
||||
import { onMessageCreate } from "./util/onMessageCreate";
|
||||
import { onMessageDelete } from "./util/onMessageDelete";
|
||||
import { onMessageDeleteBulk } from "./util/onMessageDeleteBulk";
|
||||
|
||||
const defaultOptions: PluginOptions<AutoDeletePluginType> = {
|
||||
config: {
|
||||
enabled: false,
|
||||
delay: "5s",
|
||||
},
|
||||
};
|
||||
|
||||
export const AutoDeletePlugin = zeppelinPlugin<AutoDeletePluginType>()("auto_delete", {
|
||||
configSchema: ConfigSchema,
|
||||
defaultOptions,
|
||||
|
||||
onLoad(pluginData) {
|
||||
const { state, guild } = pluginData;
|
||||
|
||||
state.guildSavedMessages = GuildSavedMessages.getGuildInstance(guild.id);
|
||||
state.guildLogs = new GuildLogs(guild.id);
|
||||
|
||||
state.deletionQueue = [];
|
||||
state.nextDeletion = null;
|
||||
state.nextDeletionTimeout = null;
|
||||
|
||||
state.maxDelayWarningSent = false;
|
||||
|
||||
state.onMessageCreateFn = msg => onMessageCreate(pluginData, msg);
|
||||
state.guildSavedMessages.events.on("create", state.onMessageCreateFn);
|
||||
|
||||
state.onMessageDeleteFn = msg => onMessageDelete(pluginData, msg);
|
||||
state.guildSavedMessages.events.on("delete", state.onMessageDeleteFn);
|
||||
|
||||
state.onMessageDeleteBulkFn = msgs => onMessageDeleteBulk(pluginData, msgs);
|
||||
state.guildSavedMessages.events.on("deleteBulk", state.onMessageDeleteBulkFn);
|
||||
},
|
||||
|
||||
onUnload(pluginData) {
|
||||
pluginData.state.guildSavedMessages.events.off("create", pluginData.state.onMessageCreateFn);
|
||||
pluginData.state.guildSavedMessages.events.off("delete", pluginData.state.onMessageDeleteFn);
|
||||
pluginData.state.guildSavedMessages.events.off("deleteBulk", pluginData.state.onMessageDeleteBulkFn);
|
||||
},
|
||||
});
|
37
backend/src/plugins/AutoDelete/types.ts
Normal file
37
backend/src/plugins/AutoDelete/types.ts
Normal file
|
@ -0,0 +1,37 @@
|
|||
import * as t from "io-ts";
|
||||
import { BasePluginType } from "knub";
|
||||
import { tDelayString, MINUTES } from "src/utils";
|
||||
import { GuildLogs } from "src/data/GuildLogs";
|
||||
import { GuildSavedMessages } from "src/data/GuildSavedMessages";
|
||||
import { SavedMessage } from "src/data/entities/SavedMessage";
|
||||
|
||||
export const MAX_DELAY = 5 * MINUTES;
|
||||
|
||||
export interface IDeletionQueueItem {
|
||||
deleteAt: number;
|
||||
message: SavedMessage;
|
||||
}
|
||||
|
||||
export const ConfigSchema = t.type({
|
||||
enabled: t.boolean,
|
||||
delay: tDelayString,
|
||||
});
|
||||
export type TConfigSchema = t.TypeOf<typeof ConfigSchema>;
|
||||
|
||||
export interface AutoDeletePluginType extends BasePluginType {
|
||||
config: TConfigSchema;
|
||||
state: {
|
||||
guildSavedMessages: GuildSavedMessages;
|
||||
guildLogs: GuildLogs;
|
||||
|
||||
deletionQueue: IDeletionQueueItem[];
|
||||
nextDeletion: number;
|
||||
nextDeletionTimeout;
|
||||
|
||||
maxDelayWarningSent: boolean;
|
||||
|
||||
onMessageCreateFn;
|
||||
onMessageDeleteFn;
|
||||
onMessageDeleteBulkFn;
|
||||
};
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
import { PluginData } from "knub";
|
||||
import { AutoDeletePluginType } from "../types";
|
||||
import { SavedMessage } from "src/data/entities/SavedMessage";
|
||||
import { scheduleNextDeletion } from "./scheduleNextDeletion";
|
||||
import { sorter } from "src/utils";
|
||||
|
||||
export function addMessageToDeletionQueue(
|
||||
pluginData: PluginData<AutoDeletePluginType>,
|
||||
msg: SavedMessage,
|
||||
delay: number,
|
||||
) {
|
||||
const deleteAt = Date.now() + delay;
|
||||
pluginData.state.deletionQueue.push({ deleteAt, message: msg });
|
||||
pluginData.state.deletionQueue.sort(sorter("deleteAt"));
|
||||
|
||||
scheduleNextDeletion(pluginData);
|
||||
}
|
28
backend/src/plugins/AutoDelete/util/deleteNextItem.ts
Normal file
28
backend/src/plugins/AutoDelete/util/deleteNextItem.ts
Normal file
|
@ -0,0 +1,28 @@
|
|||
import { PluginData } from "knub";
|
||||
import { AutoDeletePluginType } from "../types";
|
||||
import moment from "moment-timezone";
|
||||
import { LogType } from "src/data/LogType";
|
||||
import { stripObjectToScalars, resolveUser } from "src/utils";
|
||||
import { logger } from "src/logger";
|
||||
import { scheduleNextDeletion } from "./scheduleNextDeletion";
|
||||
|
||||
export async function deleteNextItem(pluginData: PluginData<AutoDeletePluginType>) {
|
||||
const [itemToDelete] = pluginData.state.deletionQueue.splice(0, 1);
|
||||
if (!itemToDelete) return;
|
||||
|
||||
pluginData.state.guildLogs.ignoreLog(LogType.MESSAGE_DELETE, itemToDelete.message.id);
|
||||
pluginData.client.deleteMessage(itemToDelete.message.channel_id, itemToDelete.message.id).catch(logger.warn);
|
||||
|
||||
scheduleNextDeletion(pluginData);
|
||||
|
||||
const user = await resolveUser(pluginData.client, itemToDelete.message.user_id);
|
||||
const channel = pluginData.guild.channels.get(itemToDelete.message.channel_id);
|
||||
const messageDate = moment(itemToDelete.message.data.timestamp, "x").format("YYYY-MM-DD HH:mm:ss");
|
||||
|
||||
pluginData.state.guildLogs.log(LogType.MESSAGE_DELETE_AUTO, {
|
||||
message: itemToDelete.message,
|
||||
user: stripObjectToScalars(user),
|
||||
channel: stripObjectToScalars(channel),
|
||||
messageDate,
|
||||
});
|
||||
}
|
26
backend/src/plugins/AutoDelete/util/onMessageCreate.ts
Normal file
26
backend/src/plugins/AutoDelete/util/onMessageCreate.ts
Normal file
|
@ -0,0 +1,26 @@
|
|||
import { AutoDeletePluginType, MAX_DELAY } from "../types";
|
||||
import { PluginData } from "knub";
|
||||
import { SavedMessage } from "src/data/entities/SavedMessage";
|
||||
import { convertDelayStringToMS, resolveMember } from "src/utils";
|
||||
import { LogType } from "src/data/LogType";
|
||||
import { addMessageToDeletionQueue } from "./addMessageToDeletionQueue";
|
||||
|
||||
export async function onMessageCreate(pluginData: PluginData<AutoDeletePluginType>, msg: SavedMessage) {
|
||||
const member = await resolveMember(pluginData.client, pluginData.guild, msg.user_id);
|
||||
const config = pluginData.config.getMatchingConfig({ member, channelId: msg.channel_id });
|
||||
if (config.enabled) {
|
||||
let delay = convertDelayStringToMS(config.delay);
|
||||
|
||||
if (delay > MAX_DELAY) {
|
||||
delay = MAX_DELAY;
|
||||
if (!pluginData.state.maxDelayWarningSent) {
|
||||
pluginData.state.guildLogs.log(LogType.BOT_ALERT, {
|
||||
body: `Clamped auto-deletion delay in <#${msg.channel_id}> to 5 minutes`,
|
||||
});
|
||||
pluginData.state.maxDelayWarningSent = true;
|
||||
}
|
||||
}
|
||||
|
||||
addMessageToDeletionQueue(pluginData, msg, delay);
|
||||
}
|
||||
}
|
12
backend/src/plugins/AutoDelete/util/onMessageDelete.ts
Normal file
12
backend/src/plugins/AutoDelete/util/onMessageDelete.ts
Normal file
|
@ -0,0 +1,12 @@
|
|||
import { PluginData } from "knub";
|
||||
import { AutoDeletePluginType } from "../types";
|
||||
import { SavedMessage } from "src/data/entities/SavedMessage";
|
||||
import { scheduleNextDeletion } from "./scheduleNextDeletion";
|
||||
|
||||
export function onMessageDelete(pluginData: PluginData<AutoDeletePluginType>, msg: SavedMessage) {
|
||||
const indexToDelete = pluginData.state.deletionQueue.findIndex(item => item.message.id === msg.id);
|
||||
if (indexToDelete > -1) {
|
||||
pluginData.state.deletionQueue.splice(indexToDelete, 1);
|
||||
scheduleNextDeletion(pluginData);
|
||||
}
|
||||
}
|
10
backend/src/plugins/AutoDelete/util/onMessageDeleteBulk.ts
Normal file
10
backend/src/plugins/AutoDelete/util/onMessageDeleteBulk.ts
Normal file
|
@ -0,0 +1,10 @@
|
|||
import { AutoDeletePluginType } from "../types";
|
||||
import { PluginData } from "knub";
|
||||
import { SavedMessage } from "src/data/entities/SavedMessage";
|
||||
import { onMessageDelete } from "./onMessageDelete";
|
||||
|
||||
export function onMessageDeleteBulk(pluginData: PluginData<AutoDeletePluginType>, messages: SavedMessage[]) {
|
||||
for (const msg of messages) {
|
||||
onMessageDelete(pluginData, msg);
|
||||
}
|
||||
}
|
14
backend/src/plugins/AutoDelete/util/scheduleNextDeletion.ts
Normal file
14
backend/src/plugins/AutoDelete/util/scheduleNextDeletion.ts
Normal file
|
@ -0,0 +1,14 @@
|
|||
import { PluginData } from "knub";
|
||||
import { AutoDeletePluginType } from "../types";
|
||||
import { deleteNextItem } from "./deleteNextItem";
|
||||
|
||||
export function scheduleNextDeletion(pluginData: PluginData<AutoDeletePluginType>) {
|
||||
if (pluginData.state.deletionQueue.length === 0) {
|
||||
clearTimeout(pluginData.state.nextDeletionTimeout);
|
||||
return;
|
||||
}
|
||||
|
||||
const firstDeleteAt = pluginData.state.deletionQueue[0].deleteAt;
|
||||
clearTimeout(pluginData.state.nextDeletionTimeout);
|
||||
pluginData.state.nextDeletionTimeout = setTimeout(() => deleteNextItem(pluginData), firstDeleteAt - Date.now());
|
||||
}
|
|
@ -13,6 +13,7 @@ import { GuildConfigReloaderPlugin } from "./GuildConfigReloader/GuildConfigRelo
|
|||
import { CasesPlugin } from "./Cases/CasesPlugin";
|
||||
import { MutesPlugin } from "./Mutes/MutesPlugin";
|
||||
import { TagsPlugin } from "./Tags/TagsPlugin";
|
||||
import { AutoDeletePlugin } from "./AutoDelete/AutoDeletePlugin";
|
||||
import { GuildInfoSaverPlugin } from "./GuildInfoSaver/GuildInfoSaverPlugin";
|
||||
import { CensorPlugin } from "./Censor/CensorPlugin";
|
||||
import { RolesPlugin } from "./Roles/RolesPlugin";
|
||||
|
@ -22,6 +23,7 @@ import { ChannelArchiverPlugin } from "./ChannelArchiver/ChannelArchiverPlugin";
|
|||
|
||||
// prettier-ignore
|
||||
export const guildPlugins: Array<ZeppelinPluginBlueprint<any>> = [
|
||||
AutoDeletePlugin,
|
||||
AutoReactionsPlugin,
|
||||
GuildInfoSaverPlugin,
|
||||
CensorPlugin,
|
||||
|
|
Loading…
Add table
Reference in a new issue