486 lines
14 KiB
Markdown
486 lines
14 KiB
Markdown
# Configuration Guide
|
|
|
|
Complete reference for configuring RedditBot.
|
|
|
|
---
|
|
|
|
## Table of Contents
|
|
|
|
1. [Configuration Overview](#configuration-overview)
|
|
2. [Configuration Storage](#configuration-storage)
|
|
3. [Environment Variables](#environment-variables)
|
|
4. [Application Settings](#application-settings)
|
|
5. [Runtime Configuration](#runtime-configuration)
|
|
6. [Configuration Validation](#configuration-validation)
|
|
7. [Troubleshooting](#troubleshooting)
|
|
|
|
---
|
|
|
|
## Configuration Overview
|
|
|
|
RedditBot uses a layered configuration approach:
|
|
|
|
```
|
|
┌──────────────────────────────────────────────────────────────┐
|
|
│ Priority Order (High → Low) │
|
|
├──────────────────────────────────────────────────────────────┤
|
|
│ 1. Environment Variables │
|
|
│ (OPENROUTER_API_KEY, WEB_DASHBOARD_TOKEN) │
|
|
│ │
|
|
│ 2. config.yaml │
|
|
│ (Primary configuration file) │
|
|
│ │
|
|
│ 3. Defaults │
|
|
│ (Hardcoded defaults in code) │
|
|
└──────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
Configuration is loaded at startup by `loadConfig()` in `src/config/index.ts`, which:
|
|
|
|
1. Reads the singleton `app_config` record from SQLite
|
|
2. Imports `config.yaml` only when upgrading an existing database that has no settings record
|
|
3. Validates the entire configuration tree using Zod
|
|
4. Returns a strongly-typed `Config` object
|
|
|
|
Application-owned settings are edited from the dashboard and saved to SQLite. `OPENROUTER_API_KEY`, `WEB_DASHBOARD_TOKEN`, and `DATABASE_PATH` remain environment-owned bootstrap values and are never stored in `app_config`.
|
|
|
|
---
|
|
|
|
## Configuration Storage
|
|
|
|
### Legacy config.yaml
|
|
|
|
`config.yaml` is retained temporarily as a one-time migration source for existing installations. Once every deployed database contains an `app_config` row, it can be removed in a follow-up release.
|
|
|
|
```
|
|
RedditBot/
|
|
├── config.yaml # ← Main configuration
|
|
├── package.json
|
|
├── tsconfig.json
|
|
└── src/
|
|
```
|
|
|
|
### Data Directory
|
|
|
|
Runtime data is stored in `data/` (created automatically):
|
|
|
|
```
|
|
data/
|
|
├── reddit-bot.db # SQLite database
|
|
├── browser/ # Browser session data (cookies, storage)
|
|
├── media/ # Downloaded media files
|
|
│ ├── index.json # Media index (SHA-1 → filename)
|
|
│ ├── abc123.jpg # Media file 1
|
|
│ └── def456.png # Media file 2
|
|
└── chats/ # Cached conversation JSON files
|
|
├── chat_abc123.json
|
|
└── chat_def456.json
|
|
```
|
|
|
|
---
|
|
|
|
## Environment Variables
|
|
|
|
Environment variables provide secrets and bootstrap settings that are intentionally excluded from SQLite.
|
|
|
|
| Variable | Required | Type | Description | Example |
|
|
|---|---|---|---|---|
|
|
| `OPENROUTER_API_KEY` | Yes | string | OpenRouter API key for AI services | `sk-or-v1-abc123...` |
|
|
| `WEB_DASHBOARD_TOKEN` | Yes when dashboard enabled | string | Dashboard access token | `long-random-secret` |
|
|
| `DATABASE_PATH` | No | string | SQLite database location | `./data/reddit-bot.db` |
|
|
|
|
### Setting Environment Variables
|
|
|
|
**Option 1: `.env` file** (recommended for development)
|
|
|
|
Create a `.env` file in the project root:
|
|
|
|
```env
|
|
OPENROUTER_API_KEY=sk-or-v1-abc123...
|
|
WEB_DASHBOARD_TOKEN=long-random-secret
|
|
```
|
|
|
|
> **Note**: Add `.env` to `.gitignore` - never commit credentials.
|
|
|
|
**Option 2: Shell export**
|
|
|
|
```bash
|
|
export OPENROUTER_API_KEY=sk-or-v1-abc123...
|
|
export WEB_DASHBOARD_TOKEN=long-random-secret
|
|
```
|
|
|
|
**Option 3: Docker**
|
|
|
|
Pass via `docker-compose.yml` or Docker CLI:
|
|
|
|
```yaml
|
|
environment:
|
|
- OPENROUTER_API_KEY=sk-or-v1-abc123...
|
|
- WEB_DASHBOARD_TOKEN=long-random-secret
|
|
```
|
|
|
|
---
|
|
|
|
## Application Settings
|
|
|
|
Use **Settings** in the dashboard for monitoring, rate limits, dry-run behaviour, subreddits, models, prompts, filtering, media sync, and strategy configuration. The advanced JSON editor exposes settings that do not yet have dedicated controls; its payload is validated by the server before it is saved.
|
|
|
|
The YAML examples below document the legacy field layout used during one-time migration.
|
|
|
|
Complete reference for every configuration option.
|
|
|
|
### Reddit Settings
|
|
|
|
```yaml
|
|
reddit:
|
|
# Subreddits to monitor for new posts
|
|
subreddits:
|
|
- gonewild
|
|
- ratemyboobs
|
|
- HomemadeNsfw
|
|
- realgirls
|
|
- plussize_gonewild
|
|
# ... add or remove subreddits
|
|
|
|
# Minutes between polling cycles
|
|
pollInterval: 15
|
|
|
|
# Target gender for image analysis filtering
|
|
# Options: "F" (female), "M" (male)
|
|
targetGender: "F"
|
|
|
|
# Keywords used to detect sellers/spam profiles
|
|
# Posts from users matching these keywords are skipped
|
|
sellerKeywords:
|
|
- seller
|
|
- onlyfans
|
|
- link in bio
|
|
- check my profile
|
|
- promo
|
|
- discount
|
|
- affiliate
|
|
```
|
|
|
|
### OpenRouter AI Settings
|
|
|
|
```yaml
|
|
openrouter:
|
|
# OpenRouter API key (can also be set via OPENROUTER_API_KEY env var)
|
|
apiKey: "sk-or-v1-abc123..."
|
|
|
|
# Primary AI model for image analysis
|
|
# Models must be available on OpenRouter
|
|
model: "meta-llama/llama-3.2-90b-vision-preview"
|
|
|
|
# Fallback models tried if the primary model refuses or fails
|
|
fallbackModels:
|
|
- "google/gemini-2.0-flash-001"
|
|
- "meta-llama/llama-3.2-11b-vision-instruct"
|
|
|
|
# Quick detection model (cheaper/faster, used for gender pre-filter)
|
|
quickModel: "google/gemini-2.0-flash-lite-001"
|
|
|
|
# System prompt for image analysis
|
|
# The AI will describe the image and detect gender
|
|
systemPrompt: |
|
|
Analyze this image and provide:
|
|
1. Gender detected (F or M)
|
|
2. Detailed description of the image content
|
|
3. Notable features (hair color, clothing, setting, etc.)
|
|
|
|
Return as JSON: {"gender": "F", "description": "...", "features": [...]}
|
|
|
|
# System prompt for message generation
|
|
# Used when crafting DMs to post authors
|
|
messagePrompt: |
|
|
Generate a natural, friendly DM for this Reddit post.
|
|
|
|
Image analysis: {description}
|
|
Post title: {title}
|
|
Strategy: {strategy}
|
|
|
|
Guidelines:
|
|
- Be complimentary but not creepy
|
|
- Reference something specific from the image
|
|
- Keep it under 2 sentences
|
|
- Sound like a genuine person, not a bot
|
|
- Do NOT ask for anything in return
|
|
```
|
|
|
|
### Rate Limiting
|
|
|
|
```yaml
|
|
rateLimit:
|
|
# Minimum delay between messages (milliseconds)
|
|
# Higher values reduce detection risk
|
|
minDelayMs: 30000
|
|
|
|
# Maximum messages per hour
|
|
# Bot will pause when this limit is reached
|
|
maxMessagesPerHour: 20
|
|
|
|
# Random jitter added to delay (milliseconds)
|
|
# Adds unpredictability to timing
|
|
jitterMs: 15000
|
|
```
|
|
|
|
**Timing example with defaults:**
|
|
```
|
|
Minimum delay: 30,000ms (30 seconds)
|
|
Jitter: 0 to 15,000ms (0-15 seconds)
|
|
Effective delay: 30-45 seconds between messages
|
|
Max messages: 20 per hour
|
|
```
|
|
|
|
### Browser Settings
|
|
|
|
```yaml
|
|
browser:
|
|
# Persistent managed-browser data populated only by verified imports
|
|
sessionDir: "./data/browser-session"
|
|
dryRun: false
|
|
```
|
|
|
|
**Browser session persistence:**
|
|
|
|
```
|
|
data/browser/
|
|
├── Default/
|
|
│ ├── Cookies # Reddit session cookies
|
|
│ ├── Local Storage # Local storage data
|
|
│ └── Preferences # Browser preferences
|
|
├── Login Data # Saved login info
|
|
└── Preferences # Browser state
|
|
```
|
|
|
|
> **Important**: Keep this directory intact. Deleting it requires re-login.
|
|
|
|
### Database Settings
|
|
|
|
```yaml
|
|
database:
|
|
# Path to SQLite database file
|
|
path: "./data/reddit-bot.db"
|
|
```
|
|
|
|
The database is auto-created on first run. Migrations run automatically on startup.
|
|
|
|
### Media Sync Settings
|
|
|
|
```yaml
|
|
mediaSync:
|
|
# Enable periodic media synchronization
|
|
enabled: true
|
|
|
|
# Interval between sync cycles (minutes)
|
|
intervalMinutes: 30
|
|
```
|
|
|
|
**Sync behavior:**
|
|
- **Incremental sync** (automatic): Downloads media from top 10 conversations
|
|
- **Full sync** (manual via dashboard): Downloads media from all conversations
|
|
|
|
### Auto-Reply Settings
|
|
|
|
```yaml
|
|
autoReply:
|
|
# Enable automatic chat replies
|
|
enabled: true
|
|
|
|
# Auto-send replies (true) or mark as pending for approval (false)
|
|
autoSend: false
|
|
|
|
# Minutes between checking for new messages
|
|
checkInterval: 10
|
|
```
|
|
|
|
**Reply modes:**
|
|
|
|
| autoSend | Behavior |
|
|
|---|---|
|
|
| `true` | Bot sends AI-generated replies automatically |
|
|
| `false` | Bot suggests replies, user approves via dashboard |
|
|
|
|
### Strategy Variants (A/B Testing)
|
|
|
|
```yaml
|
|
strategyVariants:
|
|
# Variant 1: Compliment-based
|
|
- name: "compliment"
|
|
prompt: |
|
|
Write a friendly compliment about the person's appearance.
|
|
Be genuine and specific. Keep it short and natural.
|
|
enabled: true
|
|
|
|
# Variant 2: Question-based
|
|
- name: "question"
|
|
prompt: |
|
|
Write a friendly message that includes a question.
|
|
Engage them in conversation naturally.
|
|
enabled: true
|
|
|
|
# Variant 3: Casual observation
|
|
- name: "observation"
|
|
prompt: |
|
|
Write a casual observation about the photo or setting.
|
|
Sound like you're commenting to a friend.
|
|
enabled: true
|
|
```
|
|
|
|
### Web Dashboard Settings
|
|
|
|
```yaml
|
|
web:
|
|
# Port for the web dashboard
|
|
port: 3000
|
|
```
|
|
|
|
### Global Settings
|
|
|
|
```yaml
|
|
# Global dry run mode
|
|
# When true, all actions are logged but not actually performed
|
|
dryRun: false
|
|
|
|
# Number of successful message examples to include in prompts
|
|
fewShotExamples: 3
|
|
|
|
# Minimum responses needed before trusting strategy stats
|
|
minStrategySamples: 10
|
|
|
|
# Exploration rate for A/B testing (0.0 to 1.0)
|
|
# 0.15 = 15% of messages use random variants (exploration)
|
|
explorationRate: 0.15
|
|
```
|
|
|
|
---
|
|
|
|
## Runtime Configuration
|
|
|
|
The following settings can be modified via the web dashboard without restarting the bot:
|
|
|
|
| Setting | Endpoint | Type | Description |
|
|
|---|---|---|---|
|
|
| `rateLimit.minDelayMs` | `PUT /api/config` | number | Message delay |
|
|
| `rateLimit.maxMessagesPerHour` | `PUT /api/config` | number | Hourly cap |
|
|
| `rateLimit.jitterMs` | `PUT /api/config` | number | Jitter range |
|
|
| `reddit.pollInterval` | `PUT /api/config` | number | Poll frequency |
|
|
| `dryRun` | `PUT /api/config` | boolean | Dry run mode |
|
|
|
|
### Updating Runtime Config
|
|
|
|
Via dashboard:
|
|
1. Open the settings modal
|
|
2. Modify desired values
|
|
3. Click "Save"
|
|
|
|
Via API:
|
|
```bash
|
|
curl -X PUT http://localhost:3000/api/config \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"rateLimit": {
|
|
"minDelayMs": 45000,
|
|
"maxMessagesPerHour": 15,
|
|
"jitterMs": 20000
|
|
},
|
|
"dryRun": true
|
|
}'
|
|
```
|
|
|
|
> **Note**: Runtime changes are in-memory only. They are lost when the bot restarts. To make changes persistent, update `config.yaml`.
|
|
|
|
---
|
|
|
|
## Configuration Validation
|
|
|
|
All configuration is validated using Zod at startup. Invalid configuration will cause the bot to exit with a descriptive error.
|
|
|
|
### Validation Rules
|
|
|
|
| Field | Validation |
|
|
|---|---|
|
|
| `reddit.subreddits` | Must be non-empty array of strings |
|
|
| `reddit.pollInterval` | Must be positive integer |
|
|
| `reddit.targetGender` | Must be "F" or "M" |
|
|
| `openrouter.apiKey` | Must be non-empty string |
|
|
| `openrouter.model` | Must be non-empty string |
|
|
| `openrouter.fallbackModels` | Must be non-empty array |
|
|
| `rateLimit.minDelayMs` | Must be positive integer |
|
|
| `rateLimit.maxMessagesPerHour` | Must be positive integer |
|
|
| `rateLimit.jitterMs` | Must be non-negative integer |
|
|
| `browser.sessionDir` | Must be non-empty string |
|
|
| `browser.dryRun` | Must be boolean |
|
|
| `database.path` | Must be non-empty string |
|
|
| `mediaSync.enabled` | Must be boolean |
|
|
| `mediaSync.intervalMinutes` | Must be positive integer (if enabled) |
|
|
| `autoReply.enabled` | Must be boolean |
|
|
| `autoReply.autoSend` | Must be boolean |
|
|
| `autoReply.checkInterval` | Must be positive integer (if enabled) |
|
|
| `strategyVariants` | Must be array with name + prompt |
|
|
| `web.port` | Must be integer 1-65535 |
|
|
| `dryRun` | Must be boolean |
|
|
|
|
### Common Validation Errors
|
|
|
|
**Error**: `Invalid config: openrouter.apiKey must be a string`
|
|
**Fix**: Set `OPENROUTER_API_KEY` environment variable or add `apiKey` to `config.yaml`
|
|
|
|
**Error**: `Invalid config: reddit.subreddits must be a non-empty array`
|
|
**Fix**: Add at least one subreddit to `reddit.subreddits` in `config.yaml`
|
|
|
|
**Error**: `Invalid config: browser.sessionDir must be a string`
|
|
**Fix**: Ensure `browser.sessionDir` is set in `config.yaml`
|
|
|
|
---
|
|
|
|
## Troubleshooting
|
|
|
|
### Configuration Not Loading
|
|
|
|
**Symptom**: Bot fails to start with validation errors.
|
|
|
|
**Steps**:
|
|
1. Verify `config.yaml` is in the project root
|
|
2. Check YAML syntax (use a YAML linter)
|
|
3. Verify environment variables are set correctly
|
|
4. Check bot logs for specific validation errors
|
|
|
|
### Account Authentication Not Working
|
|
|
|
**Symptom**: Account work remains paused.
|
|
|
|
**Steps**:
|
|
1. Sign in to Reddit in local Chrome
|
|
2. Open Reddit Chat and wait for the extension badge to show `OK`
|
|
3. Export and upload a fresh combined session dump
|
|
4. Check dashboard logs for Reddit or Matrix identity verification errors
|
|
|
|
### AI Not Working
|
|
|
|
**Symptom**: Image analysis fails or returns errors.
|
|
|
|
**Steps**:
|
|
1. Verify `OPENROUTER_API_KEY` is valid
|
|
2. Check API key has sufficient balance
|
|
3. Verify `openrouter.model` is available on OpenRouter
|
|
4. Check fallback models are set correctly
|
|
5. Review logs for specific AI errors
|
|
|
|
### Browser Session Expired
|
|
|
|
**Symptom**: Bot stops with "Browser session expired" error.
|
|
|
|
**Steps**:
|
|
1. Open Reddit Chat in the local Chrome profile containing the extension
|
|
2. Export and upload a fresh session dump
|
|
3. Delete the downloaded dump after verification
|
|
|
|
### Port Already in Use
|
|
|
|
**Symptom**: Dashboard fails to start with "Port already in use".
|
|
|
|
**Steps**:
|
|
1. Change `web.port` in `config.yaml`
|
|
2. Or kill the process using the port: `lsof -i :3000`
|