68 lines
2.5 KiB
TypeScript
68 lines
2.5 KiB
TypeScript
import { userTimers } from "@db/schema";
|
|
import { eq, and, lt } from "drizzle-orm";
|
|
import { DrizzleClient } from "@shared/db/DrizzleClient";
|
|
import { AuroraClient } from "@/lib/BotClient";
|
|
import { env } from "@shared/lib/env";
|
|
import { TimerType } from "@shared/lib/constants";
|
|
|
|
export const temporaryRoleService = {
|
|
/**
|
|
* Checks for and revokes expired temporary roles.
|
|
* This is intended to run as a high-frequency maintenance task.
|
|
*/
|
|
processExpiredRoles: async (): Promise<number> => {
|
|
const now = new Date();
|
|
let revokedCount = 0;
|
|
|
|
// Find all expired ACCESS (temporary role) timers
|
|
const expiredTimers = await DrizzleClient.query.userTimers.findMany({
|
|
where: and(
|
|
eq(userTimers.type, TimerType.ACCESS),
|
|
lt(userTimers.expiresAt, now)
|
|
)
|
|
});
|
|
|
|
if (expiredTimers.length === 0) return 0;
|
|
|
|
for (const timer of expiredTimers) {
|
|
const userIdStr = timer.userId.toString();
|
|
const meta = timer.metadata as any;
|
|
|
|
// We only handle keys that indicate role management
|
|
if (timer.key.startsWith('role_')) {
|
|
try {
|
|
const roleId = meta?.roleId || timer.key.replace('role_', '');
|
|
const guildId = env.DISCORD_GUILD_ID;
|
|
|
|
if (guildId) {
|
|
const guild = await AuroraClient.guilds.fetch(guildId);
|
|
const member = await guild.members.fetch(userIdStr).catch(() => null);
|
|
|
|
if (member) {
|
|
await member.roles.remove(roleId);
|
|
console.log(`👋 Temporary role ${roleId} revoked from ${member.user.tag} (Expired)`);
|
|
} else {
|
|
console.log(`⚠️ Could not find member ${userIdStr} to revoke role ${roleId}.`);
|
|
}
|
|
}
|
|
} catch (err) {
|
|
console.error(`❌ Failed to revoke role for user ${userIdStr}:`, err);
|
|
}
|
|
}
|
|
|
|
// Always delete the timer record after trying to revoke (or if it's not a role key)
|
|
// to prevent repeated failed attempts.
|
|
await DrizzleClient.delete(userTimers)
|
|
.where(and(
|
|
eq(userTimers.userId, timer.userId),
|
|
eq(userTimers.type, timer.type),
|
|
eq(userTimers.key, timer.key)
|
|
));
|
|
|
|
revokedCount++;
|
|
}
|
|
|
|
return revokedCount;
|
|
}
|
|
};
|