Files
docs/src/content/docs/projects/amari.md
T
naomi f587ef2506
Node.js CI / Lint and Test (push) Failing after 1m48s
chore: remove guild wars 2 from staff training and hierarchy
2025-11-15 09:30:07 -08:00

15 KiB

title
title
Amari

Amari (hereinafter the "Application") is Naomi's Virtual Personal Assistant on Discord, designed to automate community management, content aggregation, mentorship programme coordination, and integration with external services such as GitHub, RetroAchievements, and Baserow.

1. User Documentation

This section is for those interacting with a live instance of the Application.

1.1. Interacting with Amari

1.1.1. Direct Messages

When you send a Direct Message to Amari, the bot will automatically forward your message to Naomi and respond with an acknowledgment. This provides a direct communication channel to reach Naomi through the bot.

Implementation: src/modules/respondToDm.ts:19

1.1.2. Mentions

Amari monitors messages in the Discord server for mentions of "Naomi" or "@nhcarrigan" (user or role). When detected, the bot forwards the message to Naomi for review, helping ensure important messages are not missed. To prevent spam, Amari will not forward mentions from channels that have been active in the last 10 minutes.

Implementation: src/modules/respondToMention.ts:20

1.2. Mentorship Program

1.2.1. Joining the Program

When you receive the Mentorship role, Amari will automatically send a welcome message in the mentee chat channel with onboarding instructions, including:

  • Accepting the GitHub repository invitation
  • Reading the mentorship wiki
  • Creating your initial goal post

Implementation: src/modules/processMentorshipRole.ts:20

1.2.2. Forum Thread Management

Amari automatically manages thread tags in mentorship forums (Goals, Projects, Resume Reviews, and Discussions) to track whose turn it is to respond:

  • When Naomi responds to your thread, the tag changes to "Waiting on Member"
  • When you respond, the tag changes to "Waiting on Naomi"

Implementation: src/modules/updateMentorshipThread.ts:43

1.2.3. Progress Reminders

Every weekday (Monday-Friday) at 9:00 AM, Amari posts progress reminders in configured channels. These reminders prompt you to share:

  1. What you accomplished yesterday
  2. What you're working on today
  3. Any blockers or issues you need help with

Implementation: src/modules/postProgressReminders.ts:16

1.3. Content and News

1.3.1. Tech News Feed

Amari automatically posts new articles from two sources every hour:

  • FreeCodeCamp News: Articles are filtered for inappropriate content before posting
  • Hacker News: Latest posts with comment links

Implementation: src/modules/postNews.ts:40 and src/modules/postNews.ts:95

1.3.2. RetroAchievements

If Naomi unlocks any RetroAchievements, Amari posts them to the gaming channel every 10 minutes. These posts include:

  • Achievement title and description
  • Game title and console
  • Point value
  • Badge images

Implementation: src/modules/checkAchievements.ts:87

1.4. Form Submissions

When you submit a form through the Baserow system, Amari posts a notification to the form submissions channel. Supported forms include:

  • Sanction Appeals
  • Commission Requests
  • Contact Requests
  • Event Requests
  • Meeting Requests
  • Mentorship Requests
  • Staff Applications
  • Testimonials
  • ASCII Submissions
  • Contributor Applications
  • Product and Community Feedback
  • Community Nominations

Implementation: src/modules/processFormSubmission.ts:22 and src/config/forms.ts:9

2. Technical Documentation

This section is for those interested in running their own instance of the Application.

2.1. Prerequisites

  • Node.js (compatible with the version specified in package.json)
  • pnpm 10.15.0 or higher
  • A Discord Bot Token
  • GitHub App credentials (Client ID and Private Key)
  • RetroAchievements API Key (optional, for achievements feature)
  • Baserow webhook secret (optional, for form submissions)

2.2. Environment Variables

The following environment variables must be configured:

Variable Required Description
BOT_TOKEN Yes Discord bot token
GH_CLIENT_ID Yes GitHub App client ID
GH_PRIVATE_KEY Yes GitHub App private key (with newlines as \\n)
GH_WEBHOOK_SECRET No Secret for validating GitHub webhook payloads
RA_KEY No RetroAchievements API key
BASEROW_SECRET No Secret for validating Baserow webhook payloads

2.3. Installation

  1. Clone the repository

  2. Install dependencies:

    pnpm install
    
  3. Build the TypeScript code:

    pnpm run build
    
  4. Configure environment variables (see section 2.2)

  5. Start the application:

    pnpm start
    

Implementation: src/index.ts:1

2.4. Configuration

2.4.1. Discord IDs

All Discord-specific IDs (channels, roles, users, guilds, tags) are configured in src/config/ids.ts. You will need to update these IDs to match your Discord server setup:

  • Channels: Form submissions, gaming, general, mentee chat, forums, news
  • Roles: Mentorship, NHCarrigan, representing
  • Users: Amari (bot), Naomi, NHCarrigan
  • Tags: Forum tags for tracking thread status

Implementation: src/config/ids.ts:7

2.4.2. Form IDs

Form submission notifications are configured in src/config/forms.ts. Map Baserow table IDs to human-readable form names.

Implementation: src/config/forms.ts:9

2.4.3. Progress Reminders

Progress reminder channels are configured in src/config/progressReminders.ts. Configure which channels should receive reminders, associated role IDs, and whether to create threads.

Implementation: src/config/progressReminders.ts:1

2.4.4. DM Response

The automatic response sent when users DM the bot is configured in src/config/responses.ts.

Implementation: src/config/responses.ts:1

2.5. Architecture

2.5.1. Core Components

The Application consists of several key components:

  1. Discord Bot (discord.js): Handles all Discord interactions
  2. GitHub Integration (octokit): Manages GitHub webhooks and API interactions
  3. Web Server (fastify): Receives webhooks and serves health monitoring page
  4. Scheduled Jobs (node-schedule): Executes periodic tasks (news, reminders, etc.)
  5. Analytics (@nhcarrigan/discord-analytics): Tracks bot usage metrics

Main entry point: src/index.ts:1

2.5.2. Event Handlers

The bot responds to the following Discord events:

  • ClientReady: Initialize scheduled jobs and cache data (src/index.ts:65)
  • MessageCreate: Handle guild messages and DMs (src/index.ts:89)
  • InteractionCreate: Handle button interactions (src/index.ts:97)
  • UserUpdate: Process guild tag changes (src/index.ts:117)
  • GuildMemberUpdate: Process mentorship role assignments (src/index.ts:121)
  • GuildMemberAdd: Log when mentees join (src/index.ts:125)
  • GuildMemberRemove: Log when mentees leave (src/index.ts:129)

2.5.3. Scheduled Tasks

The following tasks run on a schedule:

  • Hourly (0 * * * *): Post news from FreeCodeCamp and Hacker News
  • Daily at Midnight (0 0 * * *): Audit and cache guild tags
  • Weekdays at 9 AM (0 9 * * 1-5): Post progress reminders
  • Every 10 minutes (interval): Check RetroAchievements and clear recently active channels

Implementation: src/index.ts:70-86

2.5.4. Web Server Endpoints

The Fastify web server provides the following endpoints:

  • GET /: Health monitoring page with bot information
  • POST /github: Webhook endpoint for GitHub events (issues, pull requests)
  • POST /form: Webhook endpoint for Baserow form submissions

The server listens on port 7044.

Implementation: src/server/serve.ts:61

2.6. Content Filtering

FreeCodeCamp News posts are filtered for inappropriate content using a comprehensive regular expression that detects violations of the Code of Conduct. The regex is defined in src/modules/postNews.ts:23 and checks for:

  • Harassment, bullying, and discrimination
  • Hate speech and slurs
  • Explicit, violent, or illegal content
  • Spam, scams, and fraud
  • Drug-related content
  • Violence and illegal activities

Posts matching these patterns are automatically rejected and not posted to Discord.

2.7. GitHub Integration

When GitHub webhooks are received:

  1. New Issues (opened action): Amari automatically assigns Naomi to the issue
  2. New Pull Requests (opened action): Amari automatically requests Naomi as a reviewer

Implementation: src/modules/processGitHubEvent.ts:31

2.8. Development

2.8.1. Available Scripts

  • pnpm run build: Compile TypeScript to JavaScript
  • pnpm start: Start the production server (uses 1Password for environment variables)
  • pnpm run lint: Run ESLint with zero warnings policy
  • pnpm test: Run tests (currently placeholder)

2.8.2. Code Structure

src/
├── config/          # Configuration files (IDs, forms, responses, reminders)
├── events/          # Discord event handlers
├── interfaces/      # TypeScript interfaces
├── modules/         # Core functionality modules
├── server/          # Fastify web server
├── utils/           # Utility functions
└── index.ts         # Application entry point

2.8.3. Dependencies

Key dependencies:

  • discord.js v14.22.0: Discord API wrapper
  • fastify v5.5.0: Web server framework
  • octokit v5.0.3: GitHub API client
  • node-schedule v2.1.1: Cron job scheduler
  • rss-parser v3.13.0: RSS feed parser
  • @retroachievements/api v2.6.0: RetroAchievements API client
  • @nhcarrigan/discord-analytics v0.0.6: Analytics tracking
  • @nhcarrigan/logger v1.1.1: Logging utility

This section is for expansions to our legal policies specific to the Application.

3.1. License

This software is licensed under Naomi's Public Licence. The full licence text is available in the LICENSE.md file in the repository root.

Copyright held by Naomi Carrigan.

3.2. Code of Conduct

All users interacting with the Application, whether through Discord or by contributing to the codebase, must adhere to the Code of Conduct defined in CODE_OF_CONDUCT.md.

3.3. Content Filtering

The Application implements automated content filtering for RSS feeds to ensure posted content complies with the community's Code of Conduct. While this filtering attempts to catch policy violations, it may not be perfect. Users should report any inappropriate content that bypasses the filters.

3.4. Data Collection

The Application collects the following data for operational purposes:

  • Discord user IDs and message content (forwarded to Naomi for mentions/DMs)
  • GitHub usernames (for webhook processing)
  • Form submission data (row IDs and table identifiers)
  • Analytics metrics (event counts and associated metadata)

All data is processed in accordance with Naomi's privacy policies.

3.5. Third-Party Services

The Application integrates with several third-party services:

  • Discord: Communication platform (Terms of Service apply)
  • GitHub: Code hosting and webhook integration (Terms of Service apply)
  • RetroAchievements: Gaming achievement tracking (Terms of Service apply)
  • Baserow: Form submission processing (Terms of Service apply)

Users of the Application are subject to the terms of service of these platforms.

4. Contributing Documentation

This section is for documentation related to contributing to the Application's codebase.

4.1. Getting Started

Before contributing, please:

  1. Read the CONTRIBUTING.md file for contribution guidelines
  2. Review the CODE_OF_CONDUCT.md to understand community standards
  3. Familiarize yourself with the codebase structure (see section 2.8.2)

4.2. Development Setup

  1. Fork the repository
  2. Clone your fork locally
  3. Install dependencies: pnpm install
  4. Create a feature branch: git checkout -b feature/your-feature-name
  5. Make your changes
  6. Run linting: pnpm run lint
  7. Build the project: pnpm run build
  8. Test your changes with a local instance

4.3. Code Standards

The project enforces the following standards:

  • TypeScript: All code must be written in TypeScript
  • ESLint: Code must pass linting with zero warnings (@nhcarrigan/eslint-config)
  • TypeScript Config: Uses @nhcarrigan/typescript-config
  • File Headers: All files must include copyright header with licence and author information

Example header:

/**
 * @copyright NHCarrigan
 * @license Naomi's Public Licence
 * @author Naomi Carrigan
 */

4.4. Module Guidelines

When creating or modifying modules:

  1. Single Responsibility: Each module should handle one specific feature
  2. Error Handling: Use try-catch blocks and log errors with the logger utility
  3. Type Safety: Define interfaces for all data structures
  4. Documentation: Include JSDoc comments for all exported functions
  5. Testing: Consider how your changes can be tested (when tests are implemented)

4.5. Adding New Features

When adding new features:

  1. Configuration: Add any new IDs or configuration to appropriate config files
  2. Interfaces: Define TypeScript interfaces in the src/interfaces/ directory
  3. Modules: Create new modules in src/modules/ for self-contained functionality
  4. Events: Add event handlers in src/events/ if needed
  5. Server Routes: Add new endpoints in src/server/serve.ts if needed
  6. Documentation: Update this documentation file to reflect new features

4.6. Submitting Changes

  1. Commit your changes with descriptive commit messages
  2. Push to your fork
  3. Create a Pull Request to the main repository
  4. Amari will automatically request Naomi as a reviewer
  5. Address any review feedback
  6. Once approved, your changes will be merged

4.7. Key Files for Contributors

  • src/index.ts: Main application entry point
  • src/config/ids.ts: Discord server IDs configuration
  • src/interfaces/amari.ts: Core application state interface
  • src/server/serve.ts: Web server and webhook handlers
  • src/modules/: Individual feature implementations
  • package.json: Dependencies and scripts

4.8. Common Tasks

Adding a New Form Type

  1. Add the table ID and name to src/config/forms.ts
  2. The form notification will automatically work via src/modules/processFormSubmission.ts

Adding a New Scheduled Task

  1. Add the schedule in src/index.ts within the ClientReady event handler
  2. Use node-schedule cron syntax
  3. Create a new module in src/modules/ for the task logic

Adding a New Discord Event Handler

  1. Create a handler module in src/modules/ or src/events/
  2. Register the event listener in src/index.ts
  3. Use the Amari interface for accessing bot state

Modifying Webhook Endpoints

  1. Update the route handler in src/server/serve.ts
  2. Define interfaces for payloads in src/interfaces/
  3. Ensure proper authentication checking with secrets

4.9. Support and Questions

If you have questions about contributing:

4.10. Analytics and Logging

The Application uses custom logging and analytics:

  • Logger: Use logger.log(), logger.error(), logger.metric() from src/utils/logger.ts
  • Metrics: Log user actions with logger.metric() for analytics tracking
  • Error Handling: Always catch and log errors to help with debugging

Example:

await logger.metric("processed_event", 1, { user: userId });
await logger.error("module name", error);