all repos — stealth-developers @ 89e4c7ff2aa4e6d6e161f82ee270a6fb7662c00a

apps/bot/src/feats/tickets/timers.ts (view raw)

 1
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
import { editTicket, getOpenTickets } from "@stealth-developers/db";

import { getTextChannel } from "@/lib";
import { addTimer } from "@/timers";

import { getGuildActor } from "../guild-actor";
import { closeTicket, messageChannel } from "./actions";

// time in minutes before a ticket is considered inactive
const CLAIMANT_INACTIVITY_THRESHOLD = 15;
const SUBJECT_INACTIVITY_THRESHOLD = 15;

addTimer({
	name: "Check if tickets are inactive",
	interval: 1,
	callback: async () => {
		const openTickets = await getOpenTickets();

		for (const ticket of openTickets) {
			const { lastClaimantActivityAt, lastSubjectActivityAt } = ticket;

			if (lastClaimantActivityAt) {
				const now = Date.now();
				const timeSinceLastActivity = now - lastClaimantActivityAt.getTime();
				if (timeSinceLastActivity / 60_000 > CLAIMANT_INACTIVITY_THRESHOLD && ticket.channelId) {
					const channel = await getTextChannel(ticket.channelId);
					editTicket(ticket.id, {
						claimedAt: null,
						claimedBy: null,
						lastClaimantActivityAt: null,
					});

					messageChannel(channel.id, {
						content: `This ticket has been automatically unclaimed due to inactivity, someone else will be with you shortly.`,
					});
				}

				continue;
			}

			if (!lastSubjectActivityAt && ticket.guild) {
				const now = Date.now();
				const timeSinceLastActivity = now - ticket.openedAt.getTime();

				if (timeSinceLastActivity / 60_000 > SUBJECT_INACTIVITY_THRESHOLD) {
					const guildActor = getGuildActor(ticket.guild.discordId);
					if (!guildActor) continue;

					await closeTicket(
						guildActor,
						ticket.id,
						{
							public: `Ticket closed after ${SUBJECT_INACTIVITY_THRESHOLD} minutes of inactivity`,
							private: null,
						},
						true,
					);
				}
			}
		}
	},
});