Configuration - gabrielg2020/10000-beers GitHub Wiki
Configuration
This guide covers all configuration options for the 10,000 Beers bot. Configuration is managed through environment variables loaded from a .env file.
Quick Reference
| Variable | Required | Default | Type |
|---|---|---|---|
DATABASE_URL |
✅ | - | string |
WHATSAPP_GROUP_ID |
✅ | - | string |
NODE_ENV |
❌ | development |
string |
LOG_LEVEL |
❌ | debug (dev) / info (prod) |
string |
ADMIN_IDS |
❌ | - | CSV string |
IMAGE_STORAGE_PATH |
❌ | /data/images |
string |
MAX_IMAGE_SIZE_MB |
❌ | 10 |
number |
SUBMISSION_COOLDOWN_MINUTES |
❌ | 0 |
number |
REPLY_ON_SUBMISSION |
❌ | true |
boolean |
AI_ENABLED |
❌ | false |
boolean |
AI_CONFIDENCE_THRESHOLD |
❌ | 0.9 |
number |
GEMINI_API_KEY |
⚠️ | - | string |
GEMINI_MODEL |
❌ | gemini-1.5-flash |
string |
GITHUB_REPO_OWNER |
❌ | gabrielg2020 |
string |
GITHUB_REPO_NAME |
❌ | 10000-beers |
string |
STARTUP_WAIT |
❌ | 0 |
number |
PUPPETEER_EXECUTABLE_PATH |
❌ | auto-detected | string |
POSTGRES_PASSWORD |
🐳 | beers_dev_password |
string |
PGADMIN_EMAIL |
🐳 | [email protected] |
string |
PGADMIN_PASSWORD |
🐳 | admin |
string |
Legend:
- ✅ = Required
- ❌ = Optional
- ⚠️ = Required when
AI_ENABLED=true - 🐳 = Docker only
Database Configuration
DATABASE_URL
Required: Yes
Type: String
Format: postgresql://username:password@host:port/database
PostgreSQL connection string for the database.
Examples:
# Docker
DATABASE_URL=postgresql://beers:password@postgres:5432/beers
# Local development
DATABASE_URL=postgresql://username:password@localhost:5432/beers
# External database
DATABASE_URL=postgresql://user:[email protected]:5432/beers_production
Validation:
- Must start with
postgresql://orpostgres:// - Host, port, and database name are required
Notes:
- In Docker, use hostname
postgres(the service name) - For production, use strong passwords and consider SSL parameters:
?sslmode=require
POSTGRES_PASSWORD
Required: Docker only
Type: String
Default: beers_dev_password
Password for the PostgreSQL database user in Docker.
Example:
POSTGRES_PASSWORD=your_secure_password_here
Important:
- Change this from the default in production
- Must match the password in
DATABASE_URL - Only used when running PostgreSQL via Docker Compose
WhatsApp Configuration
WHATSAPP_GROUP_ID
Required: Yes
Type: String
Format: [email protected] or 1234567890@lid
The WhatsApp group ID to monitor for beer submissions.
Examples:
# Regular group
[email protected]
# Large group/community
WHATSAPP_GROUP_ID=1234567890@lid
How to get your group ID: See Getting Started - Getting Your WhatsApp Group ID
Validation:
- Must match pattern:
\d+@(g\.us|lid|c\.us) - The bot will ignore messages from all other chats
ADMIN_IDS
Required: No Type: Comma-separated string Default: Empty (no admins)
WhatsApp IDs of users who can run admin commands.
Format: [email protected]
Examples:
# Single admin
[email protected]
# Multiple admins
[email protected],[email protected],[email protected]
Format guide:
- UK:
+44 7123 456789→[email protected] - US:
+1 555 123 4567→[email protected] - Remove
+, spaces, and hyphens - Append
@c.us
Admin commands:
!leaderboard- Display beer leaderboard!removeLast @user- Remove a user's last beer submission!release- Fetch and display latest GitHub release
Notes:
- If not set, admin commands are disabled for all users
- No spaces between IDs in the comma-separated list
Storage Configuration
IMAGE_STORAGE_PATH
Required: No
Type: String
Default: /data/images
Directory path where beer images are stored.
Examples:
# Docker (recommended)
IMAGE_STORAGE_PATH=/data/images
# Local development
IMAGE_STORAGE_PATH=./data/images
# Absolute path
IMAGE_STORAGE_PATH=/var/lib/10000-beers/images
Important:
- Directory must exist and be writable
- For Docker, ensure volume is mounted correctly
- Images are stored with timestamped filenames:
beer_1234567890_abc123.jpg
Storage structure:
/data/images/
├── beer_1711234567_a1b2c3.jpg
├── beer_1711234890_d4e5f6.jpg
└── beer_1711235123_g7h8i9.jpg
MAX_IMAGE_SIZE_MB
Required: No
Type: Number
Default: 10
Maximum allowed image size in megabytes.
Examples:
# Default (10 MB)
MAX_IMAGE_SIZE_MB=10
# Smaller limit for bandwidth constraints
MAX_IMAGE_SIZE_MB=5
# Larger limit for high-quality images
MAX_IMAGE_SIZE_MB=20
Notes:
- Images larger than this limit are rejected
- Consider your storage capacity and network bandwidth
- WhatsApp typically compresses images, so large limits may not be necessary
Bot Behaviour Configuration
SUBMISSION_COOLDOWN_MINUTES
Required: No
Type: Number
Default: 0 (no cooldown)
Minimum minutes between beer submissions for a single user.
Examples:
# No cooldown (default)
SUBMISSION_COOLDOWN_MINUTES=0
# 5-minute cooldown
SUBMISSION_COOLDOWN_MINUTES=5
# 1-hour cooldown
SUBMISSION_COOLDOWN_MINUTES=60
Use cases:
- Prevent spam submissions
- Enforce realistic drinking pace
- Reduce database load
Notes:
- Set to
0to disable cooldown checking - Cooldown is per-user, not global
- Admin commands bypass cooldown
REPLY_ON_SUBMISSION
Required: No
Type: Boolean
Default: true
Whether the bot sends a WhatsApp reply message when a beer is successfully submitted.
Examples:
# Send replies (default)
REPLY_ON_SUBMISSION=true
# Silent mode (no replies)
REPLY_ON_SUBMISSION=false
Reply message format:
🍺 Beer logged! Total: 42 beers
Use cases:
- Disable for less intrusive operation
- Enable for user feedback and confirmation
Application Configuration
NODE_ENV
Required: No
Type: String
Default: development
Values: development, production, test
Execution environment for the application.
Examples:
# Development
NODE_ENV=development
# Production
NODE_ENV=production
# Testing
NODE_ENV=test
Effects:
- Development: Pretty logging, verbose output, hot reload
- Production: JSON logging, optimised performance, error handling
- Test: Minimal logging, test database, mocked dependencies
Notes:
- Automatically set by npm scripts (
npm run dev→ development,npm start→ production) - Changes default
LOG_LEVEL
LOG_LEVEL
Required: No
Type: String
Default: debug (development) / info (production)
Values: debug, info, warn, error
Logging verbosity level.
Examples:
# Verbose logging (development)
LOG_LEVEL=debug
# Standard logging (production)
LOG_LEVEL=info
# Warnings and errors only
LOG_LEVEL=warn
# Errors only
LOG_LEVEL=error
Log level hierarchy:
debug- All logs including detailed debugging informationinfo- Informational messages, warnings, and errorswarn- Warnings and errors onlyerror- Errors only
Notes:
- Use
debugfor development and troubleshooting - Use
infofor production - Use
errorto minimise log volume
STARTUP_WAIT
Required: No
Type: Number
Default: 0
Seconds to wait before initialising the WhatsApp client.
Examples:
# No wait (default)
STARTUP_WAIT=0
# Wait 10 seconds
STARTUP_WAIT=10
Use cases:
- Ensure database is ready before connecting
- Synchronise startup with other services
- Debug startup issues
PUPPETEER_EXECUTABLE_PATH
Required: No Type: String Default: Auto-detected
Path to the Chromium executable for Puppeteer.
Examples:
# Docker (automatically set)
PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium
# macOS
PUPPETEER_EXECUTABLE_PATH=/Applications/Chromium.app/Contents/MacOS/Chromium
# Linux
PUPPETEER_EXECUTABLE_PATH=/usr/bin/chromium-browser
Notes:
- Usually auto-detected and doesn't need to be set
- Required if Chromium is installed in a non-standard location
- Docker image includes Chromium at
/usr/bin/chromium
AI Configuration
AI_ENABLED
Required: No
Type: Boolean
Default: false
Enable AI-powered beer classification using Google Gemini.
Examples:
# Disabled (default)
AI_ENABLED=false
# Enabled
AI_ENABLED=true
When enabled:
- Images are sent to Google Gemini for classification
- Beer type is detected:
can,bottle, ordraught - Confidence score is stored in the database
Notes:
- Requires
GEMINI_API_KEYwhen enabled - Adds latency to submissions (~1-3 seconds)
- See AI Classification below
AI_CONFIDENCE_THRESHOLD
Required: No
Type: Number
Default: 0.9
Range: 0.0 to 1.0
Minimum confidence score required for AI classification to be considered valid.
Examples:
# High confidence required (default)
AI_CONFIDENCE_THRESHOLD=0.9
# Medium confidence
AI_CONFIDENCE_THRESHOLD=0.7
# Low confidence (more permissive)
AI_CONFIDENCE_THRESHOLD=0.5
How it works:
- Gemini returns a confidence score (0.0 to 1.0)
- If score ≥ threshold, classification is accepted
- If score < threshold, beer type is set to
null
Recommended values:
0.9- High accuracy, some beers may not be classified0.7- Balanced accuracy and coverage0.5- More classifications, lower accuracy
GEMINI_API_KEY
Required: When AI_ENABLED=true
Type: String
Default: None
Google Gemini API key for AI classification.
Example:
GEMINI_API_KEY=AIzaSyABC123def456GHI789jkl012MNO345pqr
How to get an API key:
- Visit Google AI Studio
- Create a new API key
- Copy it to your
.envfile
Notes:
- Keep this secret and never commit to version control
- API usage may incur costs (check Google's pricing)
- Free tier available for testing
GEMINI_MODEL
Required: No
Type: String
Default: gemini-1.5-flash
Google Gemini model to use for classification.
Examples:
# Fast and efficient (default)
GEMINI_MODEL=gemini-1.5-flash
# More accurate but slower
GEMINI_MODEL=gemini-1.5-pro
# Latest model
GEMINI_MODEL=gemini-2.0-flash-exp
Model comparison:
gemini-1.5-flash- Fast, low-cost, good accuracygemini-1.5-pro- Slower, higher cost, better accuracygemini-2.0-flash-exp- Experimental, performance varies
Notes:
- See Google's model documentation for details
- Consider cost and latency trade-offs
GitHub Configuration
GITHUB_REPO_OWNER
Required: No
Type: String
Default: gabrielg2020
GitHub repository owner (username or organisation) for the !release command.
Examples:
# Default (this project)
GITHUB_REPO_OWNER=gabrielg2020
# Custom repository
GITHUB_REPO_OWNER=your-username
Notes:
- Used by the
!releaseadmin command to fetch release information - Must be a valid GitHub username or organisation
- Repository must be public (or provide authentication)
GITHUB_REPO_NAME
Required: No
Type: String
Default: 10000-beers
GitHub repository name for the !release command.
Examples:
# Default (this project)
GITHUB_REPO_NAME=10000-beers
# Custom repository
GITHUB_REPO_NAME=your-repo-name
Notes:
- Used by the
!releaseadmin command to fetch release information - Must match the actual repository name on GitHub
- Combined with
GITHUB_REPO_OWNERto form:https://github.com/{owner}/{name}
Usage:
The !release command fetches release information from:
https://api.github.com/repos/{GITHUB_REPO_OWNER}/{GITHUB_REPO_NAME}/releases/latest
See Commands - !release for command usage.
Docker-Only Configuration
PGADMIN_EMAIL
Required: No (Docker only)
Type: String
Default: [email protected]
Login email for pgAdmin web interface.
Example:
[email protected]
PGADMIN_PASSWORD
Required: No (Docker only)
Type: String
Default: admin
Login password for pgAdmin web interface.
Example:
PGADMIN_PASSWORD=secure_pgadmin_password
Access pgAdmin: Navigate to http://localhost:5050 and use these credentials.
Configuration Examples
Development (Docker)
# Database
POSTGRES_PASSWORD=dev_password
DATABASE_URL=postgresql://beers:dev_password@postgres:5432/beers
# WhatsApp
[email protected]
[email protected]
# Storage
IMAGE_STORAGE_PATH=/data/images
MAX_IMAGE_SIZE_MB=10
# Bot
SUBMISSION_COOLDOWN_MINUTES=0
REPLY_ON_SUBMISSION=true
# Application
NODE_ENV=development
LOG_LEVEL=debug
# AI (disabled for development)
AI_ENABLED=false
# GitHub
GITHUB_REPO_OWNER=gabrielg2020
GITHUB_REPO_NAME=10000-beers
# pgAdmin
[email protected]
PGADMIN_PASSWORD=admin
Production (Docker)
# Database (use strong password!)
POSTGRES_PASSWORD=your_strong_secure_password_here
DATABASE_URL=postgresql://beers:your_strong_secure_password_here@postgres:5432/beers
# WhatsApp
[email protected]
[email protected],[email protected]
# Storage
IMAGE_STORAGE_PATH=/data/images
MAX_IMAGE_SIZE_MB=10
# Bot
SUBMISSION_COOLDOWN_MINUTES=5
REPLY_ON_SUBMISSION=true
# Application
NODE_ENV=production
LOG_LEVEL=info
# AI
AI_ENABLED=true
AI_CONFIDENCE_THRESHOLD=0.9
GEMINI_API_KEY=AIzaSyABC123def456GHI789jkl012MNO345pqr
GEMINI_MODEL=gemini-1.5-flash
# GitHub
GITHUB_REPO_OWNER=gabrielg2020
GITHUB_REPO_NAME=10000-beers
Local Development (Non-Docker)
# Database
DATABASE_URL=postgresql://username:password@localhost:5432/beers
# WhatsApp
[email protected]
[email protected]
# Storage
IMAGE_STORAGE_PATH=./data/images
MAX_IMAGE_SIZE_MB=10
# Bot
SUBMISSION_COOLDOWN_MINUTES=0
REPLY_ON_SUBMISSION=true
# Application
NODE_ENV=development
LOG_LEVEL=debug
# AI (disabled for development)
AI_ENABLED=false
# GitHub
GITHUB_REPO_OWNER=gabrielg2020
GITHUB_REPO_NAME=10000-beers
Configuration Validation
The bot validates all configuration on startup. If validation fails, it will log the errors and exit.
Common validation errors:
Invalid DATABASE_URL
ConfigValidationError: Invalid configuration
Invalid fields: database.url (must start with postgresql:// or postgres://)
Fix: Ensure your database URL starts with postgresql://
Invalid WHATSAPP_GROUP_ID
ConfigValidationError: Invalid configuration
Invalid fields: whatsapp.groupId (must be in format: [email protected] or 1234567890@lid)
Fix: Check your group ID format (see Getting Started)
Missing GEMINI_API_KEY with AI enabled
ConfigValidationError: Invalid configuration
Invalid fields: ai.geminiApiKey (required when AI is enabled)
Fix: Add GEMINI_API_KEY to your .env file or set AI_ENABLED=false
AI Classification Flow
When AI_ENABLED=true, the submission flow includes AI classification:
- User sends image to WhatsApp group
- Bot downloads and validates image
- Image is sent to Gemini API with classification prompt
- Gemini returns:
isValid,beerType,confidence - If
confidence >= AI_CONFIDENCE_THRESHOLD:- Beer type is saved (
can,bottle, ordraught) - Confidence score is stored
- Beer type is saved (
- If
confidence < AI_CONFIDENCE_THRESHOLD:- Beer type is saved as
null - Submission is still accepted
- Beer type is saved as
Classification prompt:
See src/system_instruction.md for the full AI prompt.
Security Best Practices
Protect Sensitive Data
Never commit these to version control:
GEMINI_API_KEYPOSTGRES_PASSWORDDATABASE_URL(if it contains passwords)
Use .env files:
# Add to .gitignore
echo ".env" >> .gitignore
Use Strong Passwords
For production:
POSTGRES_PASSWORD- Use 20+ character random stringPGADMIN_PASSWORD- Use strong password if exposing pgAdmin
Restrict Admin Access
Only add trusted users to ADMIN_IDS:
# Good: Only trusted admins
[email protected]
# Bad: Too many admins
[email protected],[email protected],[email protected],[email protected]
Use Environment-Specific Files
Create separate .env files for each environment:
.env.development.env.production.env.test
Load the appropriate file based on NODE_ENV.
Troubleshooting Configuration Issues
Bot doesn't respond to messages
Check:
WHATSAPP_GROUP_IDmatches your group's ID- Bot is connected (check logs for "Client is ready!")
- Session is authenticated
Images not saving
Check:
IMAGE_STORAGE_PATHdirectory exists- Directory is writable
MAX_IMAGE_SIZE_MBis not too small
AI classification not working
Check:
AI_ENABLED=trueGEMINI_API_KEYis set and valid- API quota is not exceeded
- Check logs for AI service errors
Database connection failed
Check:
DATABASE_URLformat is correct- PostgreSQL is running
- Database credentials are correct
- Network connectivity (for remote databases)
Next Steps
- Commands - Learn about available bot commands
- Development Guide - Understand configuration in code