Skip to content

braden-reap/clauadette

Repository files navigation

Claude-Bot Gateway

A Telegram bot gateway that connects to local Claude Code sessions via the Agent SDK V2, enabling AI-assisted development through Telegram with multi-project routing.

Features

  • Native Claude Code Integration - Uses the Agent SDK V2 for direct session management
  • Multi-Project Routing - Different Telegram groups/chats map to different project directories
  • Proactive Heartbeat - Scheduled check-ins with configurable intervals per project
  • Tool Approval Workflow - Approve/deny tool calls via Telegram inline buttons
  • Model Provider Abstraction - Support for Claude Code native models and OpenRouter
  • Session Persistence - Conversations persist across bot restarts via PostgreSQL
  • Health Monitoring - Built-in health check endpoints for monitoring

Table of Contents


Quick Start

# 1. Clone and install
git clone https://github.com/your-repo/claude-bot.git
cd claude-bot
pnpm install && pnpm build

# 2. Set up PostgreSQL (Docker)
docker run -d --name claudebot-db \
  -e POSTGRES_USER=claudebot \
  -e POSTGRES_PASSWORD=your-secure-password \
  -e POSTGRES_DB=claudebot \
  -p 5432:5432 postgres:16

# 3. Authenticate Claude Code
claude auth login

# 4. Configure (copy and edit)
cp config.example.json config.json
cp .env.example .env
# Edit config.json with your Telegram bot token, user IDs, and project paths

# 5. Run migrations and start
pnpm --filter @claude-bot/storage db:migrate
pnpm --filter @claude-bot/gateway start

Prerequisites

Requirement Version Purpose
Node.js 20+ Runtime
pnpm 9+ Package manager
PostgreSQL 14+ Session and message storage
Claude Code CLI Latest AI agent backend
Telegram Bot - User interface

Detailed Setup Guides

1. Telegram Bot Setup

Create Your Bot

  1. Open Telegram and search for @BotFather
  2. Start a chat and send /newbot
  3. Choose a name (display name, can have spaces): My Claude Assistant
  4. Choose a username (must end in bot): my_claude_assistant_bot
  5. Copy the token - looks like: 123456789:ABCdefGHIjklMNOpqrsTUVwxyz

Configure Bot Settings (Optional but Recommended)

With BotFather, send these commands:

/setdescription - Add a description for your bot
/setabouttext - Add about text
/setcommands - Set command menu:
  start - Start the bot
  help - Show help
  status - Check connection status

Get Your User ID

  1. Search for @userinfobot on Telegram
  2. Start a chat and send any message
  3. Copy your numeric user ID (e.g., 123456789)

Get Group Chat IDs

For group-based project routing:

  1. Create a Telegram group for your project
  2. Add your bot to the group
  3. Send a message in the group
  4. Get the chat ID using one of these methods:

Method A: Using the API

curl "https://api.telegram.org/bot<YOUR_BOT_TOKEN>/getUpdates" | jq '.result[-1].message.chat.id'

Method B: Using @RawDataBot

  1. Add @RawDataBot to your group temporarily
  2. Send a message - it will reply with the chat ID
  3. Remove the bot after getting the ID

Group IDs are negative numbers (e.g., -1001234567890).


2. PostgreSQL Setup

Option A: Docker (Recommended for Development)

# Create and start container
docker run -d \
  --name claudebot-db \
  -e POSTGRES_USER=claudebot \
  -e POSTGRES_PASSWORD=your-secure-password \
  -e POSTGRES_DB=claudebot \
  -p 5432:5432 \
  -v claudebot-pgdata:/var/lib/postgresql/data \
  postgres:16

# Verify it's running
docker ps | grep claudebot-db

# View logs if needed
docker logs claudebot-db

Option B: Docker Compose

Create docker-compose.yml:

version: '3.8'
services:
  postgres:
    image: postgres:16
    container_name: claudebot-db
    environment:
      POSTGRES_USER: claudebot
      POSTGRES_PASSWORD: your-secure-password
      POSTGRES_DB: claudebot
    ports:
      - "5432:5432"
    volumes:
      - pgdata:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready -U claudebot"]
      interval: 10s
      timeout: 5s
      retries: 5

volumes:
  pgdata:

Run with:

docker-compose up -d

Option C: Native PostgreSQL

# macOS with Homebrew
brew install postgresql@16
brew services start postgresql@16
createdb claudebot

# Ubuntu/Debian
sudo apt install postgresql postgresql-contrib
sudo -u postgres createuser -P claudebot  # Set password when prompted
sudo -u postgres createdb -O claudebot claudebot

Run Database Migrations

After PostgreSQL is running:

pnpm --filter @claude-bot/storage db:migrate

3. Claude Code Authentication

The gateway uses the Claude Code CLI under the hood for AI capabilities.

Install Claude Code

# Install globally
npm install -g @anthropic-ai/claude-code

# Or use with npx (no install)
npx @anthropic-ai/claude-code --version

Authenticate

# Interactive login
claude auth login

# This opens a browser for authentication
# Follow the prompts to authorize

Verify Authentication

# Check auth status
claude auth status

# Test with a simple prompt
claude -p "Say hello"

Troubleshooting Auth

If authentication fails:

# Clear existing auth
claude auth logout

# Re-authenticate
claude auth login

# Check config location
ls -la ~/.claude/

4. OpenRouter Setup (Optional)

OpenRouter provides access to alternative models. This is optional - you can use Claude Code's native models only.

Get an API Key

  1. Go to openrouter.ai
  2. Sign up or log in
  3. Navigate to API Keys
  4. Create a new key and copy it

Configure

Add to your config.json:

{
  "openRouter": {
    "apiKey": "sk-or-YOUR_API_KEY",
    "defaultModel": "anthropic/claude-3.5-sonnet"
  }
}

Or use environment variable:

export OPENROUTER_API_KEY="sk-or-YOUR_API_KEY"

Available Models via OpenRouter

anthropic/claude-3.5-sonnet    # Claude 3.5 Sonnet
anthropic/claude-3-opus        # Claude 3 Opus
google/gemini-pro              # Google Gemini Pro
openai/gpt-4-turbo             # OpenAI GPT-4 Turbo

Configuration

Configuration Files

File Purpose Required
config.json Main configuration Yes
.env Environment variables (secrets) Recommended

Environment Variables

Create .env from the example:

cp .env.example .env
Variable Required Description
TELEGRAM_BOT_TOKEN Yes* Bot token from BotFather
DATABASE_URL Yes* PostgreSQL connection string
OPENROUTER_API_KEY No OpenRouter API key
GATEWAY_PORT No Health server port (default: 3000)
LOG_LEVEL No Logging level (default: info)
NODE_ENV No Environment (development/production)

*Can also be set in config.json

Full Configuration Reference

config.json Structure

{
  "$schema": "./config.schema.json",
  "gateway": { /* Gateway settings */ },
  "database": { /* Database connection */ },
  "telegram": { /* Telegram bot settings */ },
  "openRouter": { /* OpenRouter settings (optional) */ },
  "projects": [ /* Project definitions */ ]
}

Gateway Settings

Option Type Default Description
port number 3000 Health check server port
logLevel string "info" Log level: trace, debug, info, warn, error
prettyLogs boolean true Enable colored, formatted logs

Database Settings

Option Type Default Description
url string - PostgreSQL connection URL
poolSize number 10 Connection pool size
queryTimeout number 30000 Query timeout in ms

Telegram Settings

Option Type Default Description
botToken string - Bot token from BotFather
allowedUsers string[] [] User IDs allowed to use the bot
allowedGroups string[] [] Group IDs allowed to use the bot
usePolling boolean true Use polling (true) or webhooks (false)

Project Settings

Option Type Required Description
id string Yes Unique identifier (alphanumeric + hyphens)
name string Yes Display name
workspacePath string Yes Absolute path to project directory
telegramGroupId string Yes Telegram chat ID for this project
models.default string Yes Default model for conversations
models.heartbeat string No Model for heartbeat (uses default if not set)
permissions object No Tool permission settings
heartbeat object No Heartbeat configuration

Permission Settings

Control which Claude tools are auto-approved, require confirmation, or are denied:

{
  "permissions": {
    "autoApprove": ["Read", "Glob", "Grep", "LS"],
    "requireConfirmation": ["Bash", "Write", "Edit"],
    "deny": ["rm", "sudo"]
  }
}
Permission Level Behavior
autoApprove Tool executes immediately without user input
requireConfirmation User must approve via Telegram button
deny Tool is blocked entirely
(not listed) Defaults to requireConfirmation

Available Tools:

  • Read - Read file contents
  • Write - Write/create files
  • Edit - Edit existing files
  • Bash - Execute shell commands
  • Glob - Find files by pattern
  • Grep - Search file contents
  • LS - List directory contents

Heartbeat Settings

Enable proactive check-ins for a project:

{
  "heartbeat": {
    "enabled": true,
    "intervalMinutes": 30,
    "prompt": "Check for pending tasks, failing tests, or issues that need attention."
  }
}
Option Type Default Description
enabled boolean false Enable heartbeat for this project
intervalMinutes number 30 Check-in interval (1-1440 minutes)
prompt string - Custom prompt for heartbeat checks

Running the Gateway

Development Mode

# With hot reload
pnpm --filter @claude-bot/gateway start:dev

Production Mode

# Build and start
pnpm build
pnpm --filter @claude-bot/gateway start

Using PM2 (Recommended for Production)

# Install PM2
npm install -g pm2

# Start with PM2
pm2 start pnpm --name "claude-bot" -- --filter @claude-bot/gateway start

# View logs
pm2 logs claude-bot

# Monitor
pm2 monit

# Restart on file changes
pm2 start pnpm --name "claude-bot" --watch -- --filter @claude-bot/gateway start

Systemd Service (Linux)

Create /etc/systemd/system/claude-bot.service:

[Unit]
Description=Claude Bot Gateway
After=network.target postgresql.service

[Service]
Type=simple
User=your-username
WorkingDirectory=/path/to/claude-bot
Environment=NODE_ENV=production
ExecStart=/usr/bin/pnpm --filter @claude-bot/gateway start
Restart=on-failure
RestartSec=10

[Install]
WantedBy=multi-user.target

Enable and start:

sudo systemctl enable claude-bot
sudo systemctl start claude-bot
sudo systemctl status claude-bot

Architecture

claude-bot/
├── packages/
│   ├── core/           # Shared types, utilities, errors, logger
│   │   └── src/
│   │       ├── types/      # Common type definitions
│   │       ├── errors/     # Error classes and handling
│   │       ├── logger/     # Pino-based logging
│   │       └── utils/      # Helper functions
│   │
│   ├── config/         # Configuration management
│   │   └── src/
│   │       ├── schema.ts   # Zod schemas for validation
│   │       └── loader.ts   # Config loading and helpers
│   │
│   ├── storage/        # Database layer
│   │   └── src/
│   │       ├── schema.ts   # Drizzle schema definitions
│   │       ├── client.ts   # Database client
│   │       └── repositories/
│   │           ├── sessions.ts
│   │           └── messages.ts
│   │
│   ├── channels/
│   │   └── telegram/   # Telegram integration
│   │       └── src/
│   │           ├── bot.ts      # grammY bot setup
│   │           ├── handlers.ts # Message handlers
│   │           └── formatter.ts # Message formatting
│   │
│   ├── agents/         # Claude Agent SDK wrapper
│   │   └── src/
│   │       ├── agent.ts    # Agent class
│   │       ├── session.ts  # Session management
│   │       └── types.ts    # Agent types
│   │
│   ├── models/         # Model provider abstraction
│   │   └── src/
│   │       ├── providers/
│   │       │   ├── claude-code.ts
│   │       │   └── openrouter.ts
│   │       └── router.ts   # Provider routing
│   │
│   └── scheduler/      # Job scheduling
│       └── src/
│           ├── scheduler.ts # Main scheduler
│           └── jobs/
│               └── heartbeat.ts
│
└── apps/
    └── gateway/        # Main application
        └── src/
            ├── gateway.ts          # Main Gateway class
            ├── conversation.ts     # Message flow handling
            ├── project-manager.ts  # Per-project agent management
            └── health.ts           # Health check endpoints

Data Flow

Telegram User
     │
     ▼
┌─────────────┐
│  grammY Bot │  (packages/channels/telegram)
└─────────────┘
     │
     ▼
┌─────────────┐
│   Gateway   │  (apps/gateway)
│             │
│ ┌─────────┐ │
│ │ Project │ │  Routes messages to correct project
│ │ Manager │ │
│ └─────────┘ │
└─────────────┘
     │
     ▼
┌─────────────┐
│    Agent    │  (packages/agents)
│             │
│  Claude SDK │  Manages AI sessions
│     V2      │
└─────────────┘
     │
     ▼
┌─────────────┐
│   Storage   │  (packages/storage)
│             │
│ PostgreSQL  │  Persists sessions & messages
└─────────────┘

API Reference

Health Check Endpoints

The gateway exposes HTTP endpoints on the configured port (default: 3000).

GET /health

Full health status with component checks.

curl http://localhost:3000/health

Response:

{
  "status": "healthy",
  "timestamp": "2024-01-15T10:30:00Z",
  "components": {
    "telegram": { "status": "up", "lastCheck": "2024-01-15T10:29:55Z" },
    "database": { "status": "up", "lastCheck": "2024-01-15T10:29:58Z" },
    "scheduler": { "status": "up" }
  }
}

GET /live

Simple liveness probe for container orchestration.

curl http://localhost:3000/live

Response: 200 OK with {"status": "ok"}

GET /ready

Readiness probe - checks if the gateway can accept traffic.

curl http://localhost:3000/ready

Response: 200 OK if ready, 503 Service Unavailable if not.

GET /version

Version information.

curl http://localhost:3000/version

Response:

{
  "name": "@claude-bot/gateway",
  "version": "1.0.0",
  "nodeVersion": "v20.10.0"
}

Troubleshooting

Bot Not Responding

  1. Check bot token: Verify token in config matches BotFather
  2. Check allowed users: Ensure your user ID is in allowedUsers
  3. Check logs: pnpm --filter @claude-bot/gateway start shows errors
  4. Test bot directly: Send /start to your bot

Database Connection Failed

# Check PostgreSQL is running
docker ps | grep postgres
# or
systemctl status postgresql

# Test connection
psql postgresql://claudebot:password@localhost:5432/claudebot -c "SELECT 1"

# Check connection string format
# Format: postgresql://USER:PASSWORD@HOST:PORT/DATABASE

Claude Code Auth Issues

# Check auth status
claude auth status

# Re-authenticate if needed
claude auth logout
claude auth login

# Test Claude directly
claude -p "Hello"

Message Not Routed to Project

  1. Check telegramGroupId: Must match the chat ID exactly
  2. Group IDs are negative: e.g., -1001234567890
  3. User chats are positive: e.g., 123456789

Tool Approval Buttons Not Working

  1. Bot needs admin in groups: For inline buttons to work in groups
  2. Check callback handling: View logs for callback errors

Heartbeat Not Running

  1. Check enabled: heartbeat.enabled must be true
  2. Check interval: Must be between 1 and 1440 minutes
  3. Check scheduler logs: Look for heartbeat scheduling messages

High Memory Usage

  1. Reduce pool size: Lower database.poolSize
  2. Check for memory leaks: Monitor with node --inspect
  3. Restart periodically: Use PM2 with --max-memory-restart

Common Error Messages

Error Cause Solution
ECONNREFUSED Database not running Start PostgreSQL
401 Unauthorized Invalid bot token Check token with BotFather
403 Forbidden User not in allowedUsers Add user ID to config
ETIMEDOUT Network issues Check firewall, DNS

Development

Running Tests

# All tests
pnpm test

# Specific package
pnpm --filter @claude-bot/core test

# Watch mode
pnpm test -- --watch

# Coverage
pnpm test -- --coverage

Type Checking

pnpm typecheck

Linting

pnpm lint
pnpm lint:fix

Building

# Build all packages
pnpm build

# Build specific package
pnpm --filter @claude-bot/core build

License

MIT

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors