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:
- What you accomplished yesterday
- What you're working on today
- 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
-
Clone the repository
-
Install dependencies:
pnpm install -
Build the TypeScript code:
pnpm run build -
Configure environment variables (see section 2.2)
-
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:
- Discord Bot (
discord.js): Handles all Discord interactions - GitHub Integration (
octokit): Manages GitHub webhooks and API interactions - Web Server (
fastify): Receives webhooks and serves health monitoring page - Scheduled Jobs (
node-schedule): Executes periodic tasks (news, reminders, etc.) - 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 informationPOST /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:
- New Issues (
openedaction): Amari automatically assigns Naomi to the issue - New Pull Requests (
openedaction): 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 JavaScriptpnpm start: Start the production server (uses 1Password for environment variables)pnpm run lint: Run ESLint with zero warnings policypnpm 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.jsv14.22.0: Discord API wrapperfastifyv5.5.0: Web server frameworkoctokitv5.0.3: GitHub API clientnode-schedulev2.1.1: Cron job schedulerrss-parserv3.13.0: RSS feed parser@retroachievements/apiv2.6.0: RetroAchievements API client@nhcarrigan/discord-analyticsv0.0.6: Analytics tracking@nhcarrigan/loggerv1.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:
- Read the
CONTRIBUTING.mdfile for contribution guidelines - Review the
CODE_OF_CONDUCT.mdto understand community standards - Familiarize yourself with the codebase structure (see section 2.8.2)
4.2. Development Setup
- Fork the repository
- Clone your fork locally
- Install dependencies:
pnpm install - Create a feature branch:
git checkout -b feature/your-feature-name - Make your changes
- Run linting:
pnpm run lint - Build the project:
pnpm run build - 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:
- Single Responsibility: Each module should handle one specific feature
- Error Handling: Use try-catch blocks and log errors with the logger utility
- Type Safety: Define interfaces for all data structures
- Documentation: Include JSDoc comments for all exported functions
- Testing: Consider how your changes can be tested (when tests are implemented)
4.5. Adding New Features
When adding new features:
- Configuration: Add any new IDs or configuration to appropriate config files
- Interfaces: Define TypeScript interfaces in the
src/interfaces/directory - Modules: Create new modules in
src/modules/for self-contained functionality - Events: Add event handlers in
src/events/if needed - Server Routes: Add new endpoints in
src/server/serve.tsif needed - Documentation: Update this documentation file to reflect new features
4.6. Submitting Changes
- Commit your changes with descriptive commit messages
- Push to your fork
- Create a Pull Request to the main repository
- Amari will automatically request Naomi as a reviewer
- Address any review feedback
- Once approved, your changes will be merged
4.7. Key Files for Contributors
src/index.ts: Main application entry pointsrc/config/ids.ts: Discord server IDs configurationsrc/interfaces/amari.ts: Core application state interfacesrc/server/serve.ts: Web server and webhook handlerssrc/modules/: Individual feature implementationspackage.json: Dependencies and scripts
4.8. Common Tasks
Adding a New Form Type
- Add the table ID and name to
src/config/forms.ts - The form notification will automatically work via
src/modules/processFormSubmission.ts
Adding a New Scheduled Task
- Add the schedule in
src/index.tswithin theClientReadyevent handler - Use
node-schedulecron syntax - Create a new module in
src/modules/for the task logic
Adding a New Discord Event Handler
- Create a handler module in
src/modules/orsrc/events/ - Register the event listener in
src/index.ts - Use the
Amariinterface for accessing bot state
Modifying Webhook Endpoints
- Update the route handler in
src/server/serve.ts - Define interfaces for payloads in
src/interfaces/ - 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()fromsrc/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);