---
title: Callista
---

Callista (hereinafter the "Application") is a Discord bot that allows users to bookmark messages so they can find them later. The Application provides a simple interface for saving message links via DM, with optional note-taking capabilities to help organise and remember why messages were bookmarked.

## 1. User Documentation

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

### 1.1. Adding the Bot

Callista is available as a Discord user-installable application. You can add Callista to your Discord account by visiting:
https://discord.com/oauth2/authorise?client_id=1391494389477412906

### 1.2. Bookmarking Messages

To bookmark a message:

1. Right-click (or long-press on mobile) any message in a guild or private channel
2. Navigate to Apps → Bookmark
3. Callista will send you a DM containing the message link

**Note:** You must have Direct Messages enabled to receive bookmarks. If you receive an error, check your Discord privacy settings.

### 1.3. Adding Notes to Bookmarks

Each bookmark can have an associated note to help you remember context:

1. When you receive a bookmark DM, click the **Add Note** button
2. A modal will appear asking "What would you like to note down?"
3. Enter your note (1-1000 characters)
4. Your note will be appended to the bookmark message

### 1.4. Editing Notes

To edit an existing note on a bookmark:

1. Click the **Edit Note** button on the bookmark message
2. Update the note text in the modal
3. The bookmark message will be updated with your new note

### 1.5. Deleting Bookmarks

To delete a bookmark from your DMs:

1. Right-click the bookmark message in your DM with Callista
2. Navigate to Apps → Delete
3. The bookmark message will be deleted

**Note:** The Delete command only works in DMs with Callista (bot DM context).

### 1.6. Additional Features

Each bookmark message includes convenient buttons:
- **Add Note/Edit Note**: Add or modify notes on your bookmarks
- **Join our Discord**: Link to the support server (https://chat.nhcarrigan.com)
- **Donate**: Premium button for supporting the bot developer

### 1.7. Command Reference

| Command | Type | Context | Description |
|---------|------|---------|-------------|
| Bookmark | Message Context Menu | Guilds, Private Channels | Sends you a DM with the message link |
| Delete | Message Context Menu | Bot DMs | Deletes the bookmark message |

## 2. Technical Documentation

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

### 2.1. Prerequisites

- Node.js (compatible with version specified in package.json)
- pnpm 10.17.1 or higher (specified in packageManager field)
- A Discord Bot Token
- 1Password CLI (op) for production environment variables (or modify start script)

### 2.2. Dependencies

**Runtime Dependencies:**
- `discord.js` (14.22.1): Discord API wrapper
- `@nhcarrigan/logger` (1.0.0): Logging utility
- `fastify` (5.6.1): Web server for health monitoring

**Development Dependencies:**
- TypeScript (5.9.2)
- ESLint with @nhcarrigan configuration
- tsx for development execution

### 2.3. Installation

1. Clone the repository:
   ```bash
   git clone <repository-url>
   cd callista
   ```

2. Install dependencies:
   ```bash
   pnpm install
   ```

3. Create a production environment file (`prod.env`) with the following:
   ```
   BOT_TOKEN=your_discord_bot_token
   ```

4. Register Discord commands by running:
   ```bash
   node commandData.js
   ```
   Copy the output JSON and register it via the Discord Developer Portal or API.

### 2.4. Building

Compile TypeScript to JavaScript:
```bash
pnpm run build
```

Output is generated in the `prod/` directory.

### 2.5. Running

**Production:**
```bash
pnpm start
```

This uses 1Password CLI to inject environment variables. Modify the start script in `package.json` if using a different secrets management solution.

**Development:**
```bash
tsx src/index.ts
```

### 2.6. Architecture Overview

**Project Structure:**
```
src/
├── index.ts              # Main entry point, Discord client setup
├── server/
│   └── serve.ts         # Fastify web server for health checks (port 6111)
├── interactions/
│   ├── bookmark.ts      # Bookmark command handler
│   └── deleteCmd.ts     # Delete command handler
├── buttons/
│   ├── addNote.ts       # Add note button definition
│   ├── editNote.ts      # Edit note button definition
│   ├── discord.ts       # Discord invite button
│   └── donate.ts        # Premium donation button
├── modals/
│   └── note.ts          # Note input modal definition
└── utils/
    └── logger.ts        # Logger configuration
```

**Component Interactions:**

1. **Discord Client** (`index.ts:22-24`): Initialized with no intents (interaction-only bot)
2. **Interaction Handler** (`index.ts:27-81`): Routes interactions to appropriate handlers
3. **Web Server** (`server/serve.ts:54-79`): Runs on port 6111 for health monitoring
4. **Message Context Commands**: Registered via `commandData.js` with user-install integration

### 2.7. Bot Configuration

The bot requires the following Discord application settings:

**Intents:** None (the bot uses no gateway intents)

**Integration Types:**
- User Install (ApplicationIntegrationType.UserInstall)

**Interaction Contexts:**
- Bookmark: Guilds and Private Channels
- Delete: Bot DMs only

**Commands to Register:**
```json
[
  {
    "type": 3,
    "name": "Bookmark",
    "contexts": [0, 2],
    "integration_types": [1]
  },
  {
    "type": 3,
    "name": "Delete",
    "contexts": [1],
    "integration_types": [1]
  }
]
```

### 2.8. Environment Variables

| Variable | Required | Description |
|----------|----------|-------------|
| BOT_TOKEN | Yes | Discord bot token for authentication |

### 2.9. Monitoring and Health Checks

The Application exposes a web server on port 6111:
- **Endpoint:** `GET /`
- **Response:** HTML page with bot information
- **Purpose:** Health monitoring and bot information display

### 2.10. Logging

Logging is handled via `@nhcarrigan/logger` with the following log levels:
- `debug`: Informational messages (bot online, server started)
- `error`: Error conditions (server failures, etc.)

Logs are written from `utils/logger.ts:1`.

### 2.11. Error Handling

The Application implements error handling for:
- Failed DM delivery (user has DMs disabled) - `interactions/bookmark.ts:43-46`
- Missing message context for modals - `index.ts:46-52`
- Server startup failures - `server/serve.ts:66-77`

### 2.12. Deployment Considerations

1. **Port Configuration:** The web server runs on port 6111 by default
2. **Secrets Management:** The default start script uses 1Password CLI
3. **Build Output:** Compiled JavaScript is output to `prod/` directory
4. **Process Management:** Consider using PM2, systemd, or Docker for production

## 3. Legal Documentation

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

### 3.1. License

This Application is licensed under **Naomi's Public Licence** as indicated in the source file headers.

Copyright held by **NHCarrigan / Naomi Carrigan**.

Full licence text available at: https://docs.nhcarrigan.com/#/license

### 3.2. Privacy

Privacy policy document: `PRIVACY.md` in the repository root.

**Data Collection:** The Application processes the following user data:
- Discord User IDs (for DM delivery)
- Message URLs (bookmarked messages)
- User-provided notes (stored in Discord messages)

**Data Storage:** All data is stored within Discord's infrastructure via message content. The Application does not maintain a separate database.

**Data Retention:** Data persists as long as users keep their DM messages. Users can delete bookmarks at any time using the Delete command.

### 3.3. Terms of Service

Terms of service document: `TERMS.md` in the repository root.

### 3.4. Security

Security policy document: `SECURITY.md` in the repository root.

For security concerns, please follow the reporting procedures outlined in the security policy.

### 3.5. Code of Conduct

Code of conduct document: `CODE_OF_CONDUCT.md` in the repository root.

## 4. Contributing Documentation

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

### 4.1. Contributing Guidelines

Contributing guidelines document: `CONTRIBUTING.md` in the repository root.

Before contributing, please review:
1. The Code of Conduct (`CODE_OF_CONDUCT.md`)
2. The Contributing Guidelines (`CONTRIBUTING.md`)
3. The License terms (`LICENSE.md`)

### 4.2. Development Setup

1. Fork the repository
2. Clone your fork
3. Install dependencies: `pnpm install`
4. Create a Discord application and bot at https://discord.com/developers/applications
5. Copy your bot token to a `prod.env` file (or use environment variables directly)
6. Run the development server: `tsx src/index.ts`

### 4.3. Code Standards

The project uses:
- **TypeScript** (5.9.2) with strict type checking
- **ESLint** with `@nhcarrigan/eslint-config` (5.2.0)
- **TypeScript Config** from `@nhcarrigan/typescript-config` (4.0.0)

Run linting with:
```bash
pnpm run lint
```

**Note:** The lint script uses `--max-warnings 0`, so warnings are treated as errors.

### 4.4. Code Style Notes

- All source files include copyright headers with `@copyright`, `@license`, and `@author` tags
- Some ESLint rules are selectively disabled with comments (e.g., `index.ts:26`)
- The project uses ESM (module) syntax (`"type": "module"` in package.json)

### 4.5. Testing

Currently, the project has a placeholder test script:
```bash
pnpm test
```

This exits with code 0 (no tests configured yet).

### 4.6. Pull Request Process

1. Create a feature branch from `main`
2. Make your changes following the code standards
3. Run `pnpm run lint` to ensure code quality
4. Run `pnpm run build` to verify the build succeeds
5. Submit a pull request with a clear description of changes
6. Address any review feedback

### 4.7. Adding New Features

**Adding a new button:**
1. Create a new file in `src/buttons/` exporting a `ButtonBuilder`
2. Import and add the button to the relevant `ActionRowBuilder` in `index.ts`
3. Add handler logic in `handleInteraction` if the button requires custom behaviour

**Adding a new command:**
1. Create a handler in `src/interactions/`
2. Add the command definition to `commandData.js`
3. Run `node commandData.js` and register the output with Discord
4. Add the command routing logic to `handleInteraction` in `index.ts`

**Adding a new modal:**
1. Create modal definition in `src/modals/`
2. Add modal handling logic in the `isModalSubmit` section of `handleInteraction`
3. Link the modal to a button or command that calls `showModal()`

### 4.8. Repository Information

- **Main Branch:** `main`
- **Package Manager:** pnpm (lockfile version: 10.17.1)
- **CI/CD:** Configuration available in `.gitea/` directory
- **Editor Configuration:** VSCode settings in `.vscode/`

### 4.9. Contact

For questions or support:
- **Support Server:** https://chat.nhcarrigan.com
- **Email:** contact@nhcarrigan.com
- **Documentation:** https://docs.nhcarrigan.com/
- **Source Code:** https://git.nhcarrigan.com/NHCarrigan/callista

### 4.10. Issue Reporting

Please report bugs in the [Bug Reports](https://support.nhcarrigan.com/c/bug-reports/6) category and feature requests in the [Feature Requests](https://support.nhcarrigan.com/c/feature-requests/7) category on our support forum.

Include:
- Clear description of the issue or feature
- Steps to reproduce (for bugs)
- Expected vs actual behaviour
- Environment details (Discord client version, etc.)
