generated from nhcarrigan/template
3f89b7eb4f
- 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
103 lines
3.4 KiB
TypeScript
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)}`,
|
|
});
|
|
}
|
|
};
|