zappyzep/backend/src/plugins/Post/util/scheduledPostLoop.ts

82 lines
2.8 KiB
TypeScript

import { TextChannel, User } from "discord.js";
import { GuildPluginData } from "knub";
import moment from "moment-timezone";
import { LogType } from "../../../data/LogType";
import { logger } from "../../../logger";
import { DBDateFormat, SECONDS, stripObjectToScalars } from "../../../utils";
import { PostPluginType } from "../types";
import { postMessage } from "./postMessage";
const SCHEDULED_POST_CHECK_INTERVAL = 5 * SECONDS;
export async function scheduledPostLoop(pluginData: GuildPluginData<PostPluginType>) {
const duePosts = await pluginData.state.scheduledPosts.getDueScheduledPosts();
for (const post of duePosts) {
const channel = pluginData.guild.channels.cache.get(post.channel_id);
if (channel instanceof TextChannel) {
const [username, discriminator] = post.author_name.split("#");
const author: User = (await pluginData.client.users.fetch(post.author_id)) || {
id: post.author_id,
username,
discriminator,
};
try {
const postedMessage = await postMessage(
pluginData,
channel,
post.content,
post.attachments,
post.enable_mentions,
);
pluginData.state.logs.log(LogType.POSTED_SCHEDULED_MESSAGE, {
author: stripObjectToScalars(author),
channel: stripObjectToScalars(channel),
messageId: postedMessage.id,
});
} catch {
pluginData.state.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 ${pluginData.guild.name} (${pluginData.guild.id})`,
);
}
}
let shouldClear = true;
if (post.repeat_interval) {
const nextPostAt = moment.utc().add(post.repeat_interval, "ms");
if (post.repeat_until) {
const repeatUntil = moment.utc(post.repeat_until, DBDateFormat);
if (nextPostAt.isSameOrBefore(repeatUntil)) {
await pluginData.state.scheduledPosts.update(post.id, {
post_at: nextPostAt.format(DBDateFormat),
});
shouldClear = false;
}
} else if (post.repeat_times) {
if (post.repeat_times > 1) {
await pluginData.state.scheduledPosts.update(post.id, {
post_at: nextPostAt.format(DBDateFormat),
repeat_times: post.repeat_times - 1,
});
shouldClear = false;
}
}
}
if (shouldClear) {
await pluginData.state.scheduledPosts.delete(post.id);
}
}
pluginData.state.scheduledPostLoopTimeout = setTimeout(
() => scheduledPostLoop(pluginData),
SCHEDULED_POST_CHECK_INTERVAL,
);
}