---
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:
   ```bash
   pnpm install
   ```

3. Build the TypeScript code:
   ```bash
   pnpm run build
   ```

4. Configure environment variables (see section 2.2)

5. Start the application:
   ```bash
   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

## 3. Legal Documentation

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:
```typescript
/**
 * @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:

- Post in the #bug-reports or #feature-requests forum channels on our Discord community
- Join the Discord server at https://chat.nhcarrigan.com for discussions
- Email contact@nhcarrigan.com for private inquiries

### 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:
```typescript
await logger.metric("processed_event", 1, { user: userId });
await logger.error("module name", error);
```
