generated from nhcarrigan/template
feat: add slash commands and context menu command (#16)
## Summary This PR adds a suite of slash commands and a context menu command to Amari, along with shared utilities and quality improvements across the board. ### New Commands - **`/create-issue`** — generates a GitHub issue on a specified repo using AI-drafted content (title, description, acceptance criteria) - **`/create-task`** — creates a task in Naomi's Leantime instance with an AI-drafted description and configurable priority - **`/onboard-mentee`** — automates the mentorship onboarding flow (GitHub invite, forum thread, role assignment) - **Forward to Owner** (context menu, message command) — forwards any message to Naomi with action buttons (contributed by @teklu) ### Shared Utilities - **`src/utils/makeAiRequest.ts`** — a single wrapper around the Anthropic SDK for all AI calls, with Amari's personality prompt baked in and full error handling - **`src/events/handleInteractionCreate.ts`** — extracted interaction handler (was inline in `index.ts`) to keep complexity under control ### Quality Improvements - `ephemeral: true` → `flags: [ MessageFlags.Ephemeral ]` (deprecated API removed) - Full `try/catch` + `logger.error` audit across all modules (`logMenteeJoin`, `checkAchievements`, `processMentorshipRole`, `processGitHubEvent`) - `deployGlobal.ts` replaced with a static `commands.json` payload for manual registration - Amari's personality prompt updated to reflect her actual character — warm, observant, and relentlessly caring ### Notes - `CLIENT_ID` is needed in 1Password at `op://Environment Variables - Naomi/Amari/client id` for the `commands.json` registration call - The forward-to-owner command (PR #13, contributed by @teklu) is fully preserved with original commit authorship ✨ This PR was created with help from Hikari~ 🌸 Co-authored-by: Naomi Carrigan <commits@nhcarrigan.com> Co-authored-by: Teklu <tekluabayneh@gmail.com> Reviewed-on: #16 Co-authored-by: Hikari <hikari@nhcarrigan.com> Co-committed-by: Hikari <hikari@nhcarrigan.com>
This commit was merged in pull request #16.
This commit is contained in:
+16
-23
@@ -10,11 +10,11 @@ import {
|
||||
GatewayIntentBits,
|
||||
Events,
|
||||
Partials,
|
||||
MessageFlags,
|
||||
} from "discord.js";
|
||||
import { scheduleJob } from "node-schedule";
|
||||
import { App } from "octokit";
|
||||
import { ids } from "./config/ids.js";
|
||||
import { handleInteractionCreate } from "./events/handleInteractionCreate.js";
|
||||
import { handleMessageCreate } from "./events/handleMessageCreate.js";
|
||||
import { cacheData } from "./modules/cacheData.js";
|
||||
import { checkRetroAchievements } from "./modules/checkAchievements.js";
|
||||
@@ -41,6 +41,7 @@ const githubApp = new App({
|
||||
appId: process.env.GH_CLIENT_ID,
|
||||
privateKey: process.env.GH_PRIVATE_KEY.replaceAll("\\n", "\n"),
|
||||
});
|
||||
|
||||
const octokit = await githubApp.getInstallationOctokit(83_119_105);
|
||||
const { data } = await octokit.rest.apps.getAuthenticated();
|
||||
await logger.log(
|
||||
@@ -60,6 +61,7 @@ const amari: Amari = {
|
||||
partials: [ Partials.Channel ],
|
||||
}),
|
||||
github: octokit,
|
||||
githubApp: githubApp,
|
||||
lastRssItems: {
|
||||
freeCodeCamp: null,
|
||||
hackerNews: null,
|
||||
@@ -87,12 +89,18 @@ amari.discord.once(Events.ClientReady, () => {
|
||||
scheduleJob("post progress reminders", "0 9 * * 1-5", async() => {
|
||||
await postProgressReminders(amari);
|
||||
});
|
||||
setInterval(() => {
|
||||
amari.recentlyActiveChannels = new Set<string>();
|
||||
}, 10 * 60 * 1000);
|
||||
setInterval(() => {
|
||||
void checkRetroAchievements(amari);
|
||||
}, 10 * 60 * 1000);
|
||||
setInterval(
|
||||
() => {
|
||||
amari.recentlyActiveChannels = new Set<string>();
|
||||
},
|
||||
10 * 60 * 1000,
|
||||
);
|
||||
setInterval(
|
||||
() => {
|
||||
void checkRetroAchievements(amari);
|
||||
},
|
||||
10 * 60 * 1000,
|
||||
);
|
||||
});
|
||||
|
||||
amari.discord.on(Events.MessageCreate, (message) => {
|
||||
@@ -105,22 +113,7 @@ amari.discord.on(Events.MessageCreate, (message) => {
|
||||
|
||||
amari.discord.on(Events.InteractionCreate, (interaction) => {
|
||||
void analytics.logGatewayEvent(Events.InteractionCreate, { ...interaction });
|
||||
if (interaction.isButton() && interaction.customId === "resolve") {
|
||||
if (interaction.user.id !== ids.users.naomi) {
|
||||
return void interaction.reply({
|
||||
content: "Who are you????",
|
||||
flags: [ MessageFlags.Ephemeral ],
|
||||
});
|
||||
}
|
||||
return void interaction.message.delete();
|
||||
}
|
||||
if (interaction.isAutocomplete()) {
|
||||
return void interaction;
|
||||
}
|
||||
return void interaction.reply({
|
||||
content: "What?",
|
||||
flags: [ MessageFlags.Ephemeral ],
|
||||
});
|
||||
handleInteractionCreate(amari, interaction);
|
||||
});
|
||||
|
||||
amari.discord.on(Events.ThreadCreate, (thread) => {
|
||||
|
||||
Reference in New Issue
Block a user