Files
amari/src/commands/onboardMentee.ts
T
hikari 3f89b7eb4f fix: replace deprecated ephemeral flag and add error handling across modules
- Replace `ephemeral: true` with `flags: [ MessageFlags.Ephemeral ]` in all command files
- Add try/catch with logger.error to logMenteeJoin, checkAchievements, processMentorshipRole
- Extract handleIssueOpened and handlePrOpened helpers in processGitHubEvent to reduce complexity
- Add logger.error calls in all newly introduced catch blocks
2026-03-03 12:04:20 -08:00

103 lines
3.4 KiB
TypeScript

/**
* @copyright NHCarrigan
* @license Naomi's Public License
* @author Naomi Carrigan
*/
import { MessageFlags, type ChatInputCommandInteraction } from "discord.js";
import { ids } from "../config/ids.js";
import { logger } from "../utils/logger.js";
import type { Amari } from "../interfaces/amari.js";
/**
* Creates a mentee repository and configures collaborator access.
* @param amari - The Amari instance.
* @param githubUsername - The mentee's GitHub username.
* @returns The URL of the created or existing repository.
*/
const setupMenteeRepository = async(
amari: Amari,
githubUsername: string,
): Promise<string> => {
const orgApps = amari.githubApp.octokit.rest.apps;
const { data: installation } = await orgApps.getOrgInstallation({
org: "nhcarrigan-mentorship",
});
const mentorshipOctokit
= await amari.githubApp.getInstallationOctokit(installation.id);
let repoUrl = `https://github.com/nhcarrigan-mentorship/${githubUsername}`;
try {
const { data: repoData } = await mentorshipOctokit.rest.repos.createInOrg({
// eslint-disable-next-line @typescript-eslint/naming-convention -- Octokit API field.
auto_init: true,
name: githubUsername,
org: "nhcarrigan-mentorship",
});
repoUrl = repoData.html_url;
} catch {
// Repo likely already exists - use the default URL.
}
await mentorshipOctokit.rest.repos.addCollaborator({
owner: "nhcarrigan-mentorship",
permission: "maintain",
repo: githubUsername,
username: githubUsername,
});
return repoUrl;
};
/**
* Onboards a new mentee by creating their GitHub repository and notifying them.
* @param amari - The Amari instance.
* @param interaction - The Discord slash command interaction.
*/
export const onboardMentee = async(
amari: Amari,
interaction: ChatInputCommandInteraction,
): Promise<void> => {
if (interaction.user.id !== ids.users.naomi) {
await interaction.reply({
content: "This command is restricted to Naomi.",
flags: [ MessageFlags.Ephemeral ],
});
return;
}
const menteeName = interaction.options.getString("mentee_name", true);
const githubUsername = interaction.options.getString("github_username", true);
const menteeUser = interaction.options.getUser("mentee", true);
await interaction.deferReply({ flags: [ MessageFlags.Ephemeral ] });
try {
const repoUrl = await setupMenteeRepository(amari, githubUsername);
const channel
= amari.discord.channels.cache.get(ids.channels.menteeChat)
?? await amari.discord.channels.fetch(ids.channels.menteeChat);
if (channel?.isSendable() !== true) {
await interaction.editReply({
content: "Repo created but could not send Discord notification.",
});
return;
}
await channel.send({
content: `Hey <@${menteeUser.id}>! I've created your mentorship repository: ${repoUrl}\n\nYou should have received an invitation to collaborate - please accept it to get started!`,
});
await logger.metric("onboarded_mentee", 1, { mentee: menteeName });
await interaction.editReply({
content: `✅ Successfully onboarded **${menteeName}**!\nRepository: ${repoUrl}`,
});
} catch (error) {
await logger.error("onboardmentee command", error instanceof Error
? error
: new Error(String(error)));
await interaction.editReply({
content: `❌ Failed to onboard mentee: ${String(error)}`,
});
}
};