84 lines
2.9 KiB
TypeScript
84 lines
2.9 KiB
TypeScript
import { Snowflake, TextChannel, User } from "discord.js";
|
|
import { GuildPluginData } from "knub";
|
|
import moment from "moment-timezone";
|
|
import { channelToTemplateSafeChannel, userToTemplateSafeUser } from "../../../utils/templateSafeObjects";
|
|
import { LogType } from "../../../data/LogType";
|
|
import { logger } from "../../../logger";
|
|
import { DBDateFormat, SECONDS, verboseChannelMention, verboseUserMention } from "../../../utils";
|
|
import { PostPluginType } from "../types";
|
|
import { postMessage } from "./postMessage";
|
|
import { LogsPlugin } from "../../Logs/LogsPlugin";
|
|
|
|
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 as Snowflake);
|
|
if (channel instanceof TextChannel) {
|
|
const [username, discriminator] = post.author_name.split("#");
|
|
const author: User = (await pluginData.client.users.fetch(post.author_id as Snowflake)) || {
|
|
id: post.author_id,
|
|
username,
|
|
discriminator,
|
|
};
|
|
|
|
try {
|
|
const postedMessage = await postMessage(
|
|
pluginData,
|
|
channel,
|
|
post.content,
|
|
post.attachments,
|
|
post.enable_mentions,
|
|
);
|
|
pluginData.getPlugin(LogsPlugin).logPostedScheduledMessage({
|
|
author,
|
|
channel,
|
|
messageId: postedMessage.id,
|
|
});
|
|
} catch {
|
|
pluginData.getPlugin(LogsPlugin).logBotAlert({
|
|
body: `Failed to post scheduled message by ${verboseUserMention(author)} to ${verboseChannelMention(
|
|
channel,
|
|
)}`,
|
|
});
|
|
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,
|
|
);
|
|
}
|