refactor: initial moves
This commit is contained in:
93
bot/modules/user/enrollment.interaction.ts
Normal file
93
bot/modules/user/enrollment.interaction.ts
Normal file
@@ -0,0 +1,93 @@
|
||||
import { ButtonInteraction, MessageFlags } from "discord.js";
|
||||
import { config } from "@/lib/config";
|
||||
import { getEnrollmentSuccessMessage } from "./enrollment.view";
|
||||
import { classService } from "@shared/modules/class/class.service";
|
||||
import { userService } from "@shared/modules/user/user.service";
|
||||
import { UserError } from "@/lib/errors";
|
||||
import { sendWebhookMessage } from "@/lib/webhookUtils";
|
||||
|
||||
export async function handleEnrollmentInteraction(interaction: ButtonInteraction) {
|
||||
if (!interaction.inCachedGuild()) {
|
||||
throw new UserError("This action can only be performed in a server.");
|
||||
}
|
||||
|
||||
const { studentRole, visitorRole } = config;
|
||||
|
||||
if (!studentRole || !visitorRole) {
|
||||
throw new UserError("No student or visitor role configured for enrollment.");
|
||||
}
|
||||
|
||||
// 1. Ensure user exists in DB and check current enrollment status
|
||||
const user = await userService.getOrCreateUser(interaction.user.id, interaction.user.username);
|
||||
if (!user) {
|
||||
throw new UserError("User profiles could not be loaded. Please try again later.");
|
||||
}
|
||||
|
||||
// Check DB enrollment
|
||||
if (user.class) {
|
||||
throw new UserError("You are already enrolled in a class.");
|
||||
}
|
||||
|
||||
const member = interaction.member;
|
||||
|
||||
// Check Discord role enrollment (Double safety)
|
||||
if (member.roles.cache.has(studentRole)) {
|
||||
throw new UserError("You already have the student role.");
|
||||
}
|
||||
|
||||
// 2. Get available classes
|
||||
const allClasses = await classService.getAllClasses();
|
||||
const validClasses = allClasses.filter((c: any) => c.roleId);
|
||||
|
||||
if (validClasses.length === 0) {
|
||||
throw new UserError("No classes with specified roles found in database.");
|
||||
}
|
||||
|
||||
// 3. Pick random class
|
||||
const selectedClass = validClasses[Math.floor(Math.random() * validClasses.length)]!;
|
||||
const classRoleId = selectedClass.roleId!;
|
||||
|
||||
// Check if the role exists in the guild
|
||||
const classRole = interaction.guild.roles.cache.get(classRoleId);
|
||||
if (!classRole) {
|
||||
throw new UserError(`The configured role ID \`${classRoleId}\` for class **${selectedClass.name}** does not exist in this server.`);
|
||||
}
|
||||
|
||||
// 4. Perform Enrollment Actions
|
||||
await member.roles.remove(visitorRole);
|
||||
await member.roles.add(studentRole);
|
||||
await member.roles.add(classRole);
|
||||
|
||||
// Persist to DB
|
||||
await classService.assignClass(user.id.toString(), selectedClass.id);
|
||||
|
||||
await interaction.reply({
|
||||
...getEnrollmentSuccessMessage(classRole.name),
|
||||
flags: MessageFlags.Ephemeral
|
||||
});
|
||||
|
||||
// 5. Send Welcome Message (if configured)
|
||||
if (config.welcomeChannelId) {
|
||||
const welcomeChannel = interaction.guild.channels.cache.get(config.welcomeChannelId);
|
||||
if (welcomeChannel && welcomeChannel.isTextBased()) {
|
||||
const rawMessage = config.welcomeMessage || "Welcome to Aurora, {user}! You have been enrolled as a **{class}**.";
|
||||
|
||||
const processedMessage = rawMessage
|
||||
.replace(/{user}/g, member.toString())
|
||||
.replace(/{username}/g, member.user.username)
|
||||
.replace(/{class}/g, selectedClass.name)
|
||||
.replace(/{guild}/g, interaction.guild.name);
|
||||
|
||||
let payload;
|
||||
try {
|
||||
payload = JSON.parse(processedMessage);
|
||||
} catch {
|
||||
payload = processedMessage;
|
||||
}
|
||||
|
||||
// Fire and forget webhook
|
||||
sendWebhookMessage(welcomeChannel, payload, interaction.client.user, "New Student Enrollment")
|
||||
.catch((err: any) => console.error("Failed to send welcome message:", err));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user