---
title: Saisoku
---

Saisoku (hereinafter the "Application") is a Discord bot designed to help users maintain productivity through hourly task reminders. The bot allows users to create reminders with either encouraging or bullying messages, providing customisable motivation styles to suit different preferences.

## 1. User Documentation

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

### Adding the Bot to Discord

To use Saisoku, add it to Discord using the [official invite link](https://discord.com/oauth2/authorise?client_id=1438325099345346723).

### Subscription Requirements

Saisoku is a premium Discord bot that requires an active subscription to use. When your subscription lapses, you will stop receiving reminders until you restore it.

### Creating a Reminder

To create a reminder, use the `/reminder` slash command with the following options:

- **task** (required): The task you want to be reminded about (maximum 50 characters)
- **bully** (required): Choose your motivation style:
  - `true` - Receive bullying/harsh reminders
  - `false` - Receive encouraging/supportive reminders

**Example:**
```
/reminder task:"Drink water" bully:false
```

### Reminder Limitations

- You can have a maximum of **5 active reminders** at any time
- Reminders are sent **every hour at the top of the hour**
- Reminders are sent via **Discord Direct Messages**

### Completing a Task

When you receive a reminder, it will include a "Complete" button. Clicking this button will:
- Remove the reminder from your active list
- Send you a completion message (encouraging or bullying, matching your reminder style)
- Free up a slot for new reminders

### Motivation Styles

#### Encouraging Mode
When `bully` is set to `false`, you'll receive gentle, supportive reminders like:
- "Just a gentle reminder to start [task name]."
- "You've got this! Time for [task name]."
- "Be kind to your future self and handle [task name] now."

#### Bullying Mode
When `bully` is set to `true`, you'll receive harsh, motivating reminders like:
- "Stop procrastinating and do [task name]."
- "Are you waiting for a written invitation to do [task name]?"
- "JUST DO [task name]!"

#### Completion Messages

The mode you set for a specific task will also determine the style of confirmation message you see when you complete said task.

### Getting Help

If you need assistance or have questions about the bot, you can:
- Visit the [support chat server](https://chat.nhcarrigan.com)
- Check the [documentation site](https://docs.nhcarrigan.com/)

## 2. Technical Documentation

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

### Prerequisites

- Node.js (version compatible with the project)
- pnpm 10.20.0 or higher
- MongoDB database
- Discord Bot Token
- Discord Application with User Install capabilities

### Technology Stack

- **Language**: TypeScript
- **Runtime**: Node.js
- **Package Manager**: pnpm
- **Discord Library**: discord.js 14.24.2
- **Web Server**: Fastify 5.6.2
- **Database ORM**: Prisma 6.19.0
- **Database**: MongoDB
- **Scheduler**: node-schedule 2.1.1
- **Analytics**: @nhcarrigan/discord-analytics 0.0.6

### Project Structure

```
src/
├── commands/
│   └── reminder.ts           # Discord slash command definition
├── config/
│   ├── entitlements.ts       # Entitled user IDs configuration
│   └── phrases.ts            # Encouraging and bullying message phrases
├── modules/
│   ├── completeTask.ts       # Handles task completion interactions
│   ├── createReminder.ts     # Handles reminder creation
│   ├── isEntitled.ts         # Checks user subscription status
│   └── sendReminders.ts      # Sends hourly reminders to users
├── server/
│   └── serve.ts              # Fastify web server for health/info page
├── utils/
│   ├── getRandomValue.ts     # Utility for selecting random phrases
│   └── logger.ts             # Logging utility
└── index.ts                  # Application entry point
```

### Database Schema

The application uses a single MongoDB collection:

**Reminders**
- `id`: String (ObjectId) - Primary key
- `userId`: String - Discord user ID
- `reminder`: String - The task description
- `isHarsh`: Boolean - Whether to use bullying messages

### Installation

1. Clone the repository:
```bash
git clone https://git.nhcarrigan.com/NHCarrigan/saisoku.git
cd saisoku
```

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

3. Set up your environment variables (create a `prod.env` file):
```
BOT_TOKEN=your_discord_bot_token
MONGO_URI=your_mongodb_connection_string
```

4. Set up the database:
```bash
pnpm exec prisma generate
```

5. Build the application:
```bash
pnpm run build
```

6. Start the application:
```bash
pnpm start
```

### Development

For development, you can build the TypeScript code using:
```bash
pnpm run build
```

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

### Discord Bot Configuration

The bot requires the following Discord configurations:

1. **Integration Types**: User Install (`ApplicationIntegrationType.UserInstall`)
2. **Interaction Contexts**:
   - Bot DMs
   - Guild channels
   - Private channels
3. **Required Intents**: None (the bot uses minimal intents)
4. **Commands**: Register the `/reminder` command using `src/commands/reminder.ts`

### Entitlement System

The bot implements Discord's subscription system. Users must have an active subscription to use the bot. The subscription is checked:
- When creating a reminder (in `src/modules/createReminder.ts:29`)
- When completing a task (in `src/modules/completeTask.ts:34`)
- Before sending reminders (in `src/modules/sendReminders.ts:43`)

The SKU ID for the subscription is: `1438369555956105382`

Additionally, specific user IDs can be hardcoded in `src/config/entitlements.ts` to grant free access.

### Scheduling

The bot uses `node-schedule` to send reminders at the top of every hour. The cron expression used is `"0 * * * *"` as defined in `src/index.ts:28`.

### Web Server

A Fastify web server runs on port 9100, serving:
- A landing page at `/` with information about the bot
- Health monitoring endpoint

### Logging

The application uses `@nhcarrigan/logger` for consistent logging throughout the codebase. Logs are output for:
- Client ready status
- Server startup
- Errors during server instantiation

### Analytics

The bot includes Discord analytics tracking via `@nhcarrigan/discord-analytics`, which starts a cron job when the client is ready (in `src/index.ts:26`).

### Key Files Reference

- **Entry Point**: `src/index.ts:1` - Main application bootstrapping
- **Reminder Creation**: `src/modules/createReminder.ts:23` - Handles `/reminder` command
- **Reminder Sending**: `src/modules/sendReminders.ts:23` - Hourly reminder dispatch
- **Task Completion**: `src/modules/completeTask.ts:28` - Processes completion buttons
- **Entitlement Check**: `src/modules/isEntitled.ts:16` - Validates subscriptions
- **Web Server**: `src/server/serve.ts:54` - HTTP server initialization
- **Phrases**: `src/config/phrases.ts:7` - All reminder and completion messages

### Environment Variables

Required environment variables:
- `BOT_TOKEN`: Discord bot token for authentication
- `MONGO_URI`: MongoDB connection string

Note: The application uses `op run --env-file=prod.env` in the start script, indicating it uses 1Password CLI for secure environment variable management in production.

## 3. Legal Documentation

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

### Privacy Policy

The Application collects and stores the following data:
- Discord user IDs
- Task descriptions (reminder text)
- User preference for message style (encouraging vs. bullying)

For the complete privacy policy applicable to this application, please visit: https://docs.nhcarrigan.com/#/privacy

### Terms of Service

By using Saisoku, you agree to:
- Maintain an active subscription to continue receiving reminders
- The hourly reminder schedule (reminders sent at the top of each hour)
- A maximum of 5 concurrent reminders per user
- Receive reminders via Discord Direct Messages

For the complete Terms of Service, please visit: https://docs.nhcarrigan.com/#/terms

### Data Retention

- Active reminders are stored in the database until marked as complete
- If a user cannot be found when sending a reminder, their reminder data is automatically deleted (as implemented in `src/modules/sendReminders.ts:36`)
- Users who let their subscription lapse will not receive reminders but their data is retained

### License

This software is licensed under Naomi's Public Licence. Copyright is held by Naomi Carrigan.

For more information, see the LICENSE.md file in the repository.

## 4. Contributing Documentation

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

### Getting Started

For comprehensive contributing guidelines, please visit: https://docs.nhcarrigan.com/#/contributing

### Code of Conduct

Before interacting with the community or contributing, please read the Code of Conduct available in the repository at `CODE_OF_CONDUCT.md`.

### Development Setup

1. Fork the repository
2. Clone your fork locally
3. Install dependencies with `pnpm install`
4. Create a `.env` file with required environment variables
5. Run `pnpm run build` to compile TypeScript
6. Make your changes
7. Run `pnpm run lint` to check code style
8. Test your changes thoroughly
9. Submit a pull request

### Code Style

The project uses:
- `@nhcarrigan/eslint-config` version 5.2.0 for linting
- `@nhcarrigan/typescript-config` version 4.0.0 for TypeScript configuration
- Maximum 0 warnings policy (enforced in lint script)

### Project Conventions

- All source files include copyright headers
- Functions are documented with JSDoc comments
- Type safety is enforced throughout the codebase
- Error handling uses try-catch blocks with proper logging

### Key Areas for Contribution

1. **Phrase Library** (`src/config/phrases.ts`): Add new encouraging or bullying phrases
2. **Features**: Propose new reminder features or customisation options
3. **Documentation**: Improve user or technical documentation
4. **Bug Fixes**: Address issues reported in the issue tracker
5. **Testing**: Add test coverage (currently minimal)

### Submitting Changes

When submitting a pull request:
1. Ensure all lint checks pass
2. Provide a clear description of changes
3. Reference any related issues
4. Test your changes with a live Discord bot instance if possible

### Getting Help

If you need help contributing:
- Visit the [support chat](https://chat.nhcarrigan.com)
- Check the [documentation](https://docs.nhcarrigan.com/)
- Review existing issues and pull requests for examples

### Security

If you discover a security vulnerability, please refer to `SECURITY.md` in the repository for responsible disclosure procedures.
