ctb 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +76 -0
- package/CLAUDE.md +116 -0
- package/LICENSE +21 -0
- package/Makefile +142 -0
- package/README.md +268 -0
- package/SECURITY.md +177 -0
- package/ask_user_mcp/server.ts +115 -0
- package/assets/demo-research.gif +0 -0
- package/assets/demo-video-summary.gif +0 -0
- package/assets/demo-workout.gif +0 -0
- package/assets/demo.gif +0 -0
- package/bun.lock +266 -0
- package/bunfig.toml +2 -0
- package/docs/personal-assistant-guide.md +549 -0
- package/launchagent/com.claude-telegram-ts.plist.template +76 -0
- package/launchagent/start.sh +14 -0
- package/mcp-config.example.ts +42 -0
- package/package.json +46 -0
- package/src/__tests__/formatting.test.ts +118 -0
- package/src/__tests__/security.test.ts +124 -0
- package/src/__tests__/setup.ts +8 -0
- package/src/bookmarks.ts +106 -0
- package/src/bot.ts +151 -0
- package/src/cli.ts +278 -0
- package/src/config.ts +254 -0
- package/src/formatting.ts +309 -0
- package/src/handlers/callback.ts +248 -0
- package/src/handlers/commands.ts +392 -0
- package/src/handlers/document.ts +585 -0
- package/src/handlers/index.ts +21 -0
- package/src/handlers/media-group.ts +205 -0
- package/src/handlers/photo.ts +215 -0
- package/src/handlers/streaming.ts +231 -0
- package/src/handlers/text.ts +128 -0
- package/src/handlers/voice.ts +138 -0
- package/src/index.ts +150 -0
- package/src/security.ts +209 -0
- package/src/session.ts +565 -0
- package/src/types.ts +77 -0
- package/src/utils.ts +246 -0
- package/tsconfig.json +29 -0
package/.env.example
ADDED
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
# Claude Telegram Bot - Environment Configuration
|
|
2
|
+
|
|
3
|
+
# ==============================================================================
|
|
4
|
+
# REQUIRED
|
|
5
|
+
# ==============================================================================
|
|
6
|
+
|
|
7
|
+
# Telegram bot token from @BotFather
|
|
8
|
+
TELEGRAM_BOT_TOKEN=1234567890:ABC-DEF1234ghIkl-zyx57W2v1u123ew11
|
|
9
|
+
|
|
10
|
+
# Comma-separated Telegram user IDs allowed to use the bot
|
|
11
|
+
# Find your ID: message @userinfobot on Telegram
|
|
12
|
+
TELEGRAM_ALLOWED_USERS=123456789
|
|
13
|
+
|
|
14
|
+
# ==============================================================================
|
|
15
|
+
# RECOMMENDED
|
|
16
|
+
# ==============================================================================
|
|
17
|
+
|
|
18
|
+
# Working directory where Claude runs (loads CLAUDE.md, skills, MCP config)
|
|
19
|
+
CLAUDE_WORKING_DIR=/Users/yourname/personal
|
|
20
|
+
|
|
21
|
+
# OpenAI API key for voice message transcription
|
|
22
|
+
# Without this, voice messages won't work
|
|
23
|
+
OPENAI_API_KEY=sk-...
|
|
24
|
+
|
|
25
|
+
# ==============================================================================
|
|
26
|
+
# OPTIONAL - Security
|
|
27
|
+
# ==============================================================================
|
|
28
|
+
|
|
29
|
+
# Comma-separated paths Claude can access
|
|
30
|
+
# Default: working dir, ~/Documents, ~/Downloads, ~/Desktop, ~/.claude
|
|
31
|
+
# Note: Setting this OVERRIDES defaults. Include ~/.claude for plan mode to work.
|
|
32
|
+
# ALLOWED_PATHS=/Users/yourname/personal,/Users/yourname/projects,/Users/yourname/.claude
|
|
33
|
+
|
|
34
|
+
# Rate limiting (token bucket)
|
|
35
|
+
# RATE_LIMIT_ENABLED=true
|
|
36
|
+
# RATE_LIMIT_REQUESTS=20
|
|
37
|
+
# RATE_LIMIT_WINDOW=60
|
|
38
|
+
|
|
39
|
+
# ==============================================================================
|
|
40
|
+
# OPTIONAL - Claude Authentication
|
|
41
|
+
# ==============================================================================
|
|
42
|
+
|
|
43
|
+
# API key for environments without Claude Code CLI auth
|
|
44
|
+
# Get from: https://console.anthropic.com/
|
|
45
|
+
# Note: API usage is billed per token - CLI auth is more cost-effective
|
|
46
|
+
# ANTHROPIC_API_KEY=sk-ant-api03-...
|
|
47
|
+
|
|
48
|
+
# Path to Claude CLI (auto-detected from PATH by default)
|
|
49
|
+
# CLAUDE_CLI_PATH=/usr/local/bin/claude
|
|
50
|
+
|
|
51
|
+
# ==============================================================================
|
|
52
|
+
# OPTIONAL - Extended Thinking
|
|
53
|
+
# ==============================================================================
|
|
54
|
+
|
|
55
|
+
# Keywords that trigger extended thinking (comma-separated, case-insensitive)
|
|
56
|
+
# THINKING_KEYWORDS=think,pensa,ragiona
|
|
57
|
+
|
|
58
|
+
# Keywords that trigger deep thinking (50k tokens)
|
|
59
|
+
# THINKING_DEEP_KEYWORDS=ultrathink,think hard,pensa bene
|
|
60
|
+
|
|
61
|
+
# ==============================================================================
|
|
62
|
+
# OPTIONAL - Voice Transcription
|
|
63
|
+
# ==============================================================================
|
|
64
|
+
|
|
65
|
+
# Additional context for voice transcription (names, technical terms, etc.)
|
|
66
|
+
# TRANSCRIPTION_CONTEXT=Common names: John, Alice. Tech: Kubernetes, GraphQL.
|
|
67
|
+
|
|
68
|
+
# ==============================================================================
|
|
69
|
+
# OPTIONAL - Logging
|
|
70
|
+
# ==============================================================================
|
|
71
|
+
|
|
72
|
+
# Audit log path
|
|
73
|
+
# AUDIT_LOG_PATH=/tmp/claude-telegram-audit.log
|
|
74
|
+
|
|
75
|
+
# Output audit logs as JSON (default: human-readable)
|
|
76
|
+
# AUDIT_LOG_JSON=false
|
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Commands
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
bun run start # Run the bot
|
|
9
|
+
bun run dev # Run with auto-reload (--watch)
|
|
10
|
+
bun run typecheck # Run TypeScript type checking
|
|
11
|
+
bun install # Install dependencies
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Architecture
|
|
15
|
+
|
|
16
|
+
This is a Telegram bot (~3,300 lines TypeScript) that lets you control Claude Code from your phone via text, voice, photos, and documents. Built with Bun and grammY.
|
|
17
|
+
|
|
18
|
+
### Message Flow
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
Telegram message → Handler → Auth check → Rate limit → Claude session → Streaming response → Audit log
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### Key Modules
|
|
25
|
+
|
|
26
|
+
- **`src/index.ts`** - Entry point, registers handlers, starts polling
|
|
27
|
+
- **`src/config.ts`** - Environment parsing, MCP loading, safety prompts
|
|
28
|
+
- **`src/session.ts`** - `ClaudeSession` class wrapping Agent SDK V2 with streaming, session persistence (`/tmp/claude-telegram-session.json`), and defense-in-depth safety checks
|
|
29
|
+
- **`src/security.ts`** - `RateLimiter` (token bucket), path validation, command safety checks
|
|
30
|
+
- **`src/formatting.ts`** - Markdown→HTML conversion for Telegram, tool status emoji formatting
|
|
31
|
+
- **`src/utils.ts`** - Audit logging, voice transcription (OpenAI), typing indicators
|
|
32
|
+
- **`src/types.ts`** - Shared TypeScript types
|
|
33
|
+
|
|
34
|
+
### Handlers (`src/handlers/`)
|
|
35
|
+
|
|
36
|
+
Each message type has a dedicated async handler:
|
|
37
|
+
- **`commands.ts`** - `/start`, `/new`, `/stop`, `/status`, `/resume`, `/restart`
|
|
38
|
+
- **`text.ts`** - Text messages with intent filtering
|
|
39
|
+
- **`voice.ts`** - Voice→text via OpenAI, then same flow as text
|
|
40
|
+
- **`photo.ts`** - Image analysis with media group buffering (1s timeout for albums)
|
|
41
|
+
- **`document.ts`** - PDF extraction (pdftotext CLI) and text file processing
|
|
42
|
+
- **`callback.ts`** - Inline keyboard button handling for ask_user MCP
|
|
43
|
+
- **`streaming.ts`** - Shared `StreamingState` and status callback factory
|
|
44
|
+
|
|
45
|
+
### Security Layers
|
|
46
|
+
|
|
47
|
+
1. User allowlist (`TELEGRAM_ALLOWED_USERS`)
|
|
48
|
+
2. Rate limiting (token bucket, configurable)
|
|
49
|
+
3. Path validation (`ALLOWED_PATHS`)
|
|
50
|
+
4. Command safety (blocked patterns)
|
|
51
|
+
5. System prompt constraints
|
|
52
|
+
6. Audit logging
|
|
53
|
+
|
|
54
|
+
### Configuration
|
|
55
|
+
|
|
56
|
+
All config via `.env` (copy from `.env.example`). Key variables:
|
|
57
|
+
- `TELEGRAM_BOT_TOKEN`, `TELEGRAM_ALLOWED_USERS` (required)
|
|
58
|
+
- `CLAUDE_WORKING_DIR` - Working directory for Claude
|
|
59
|
+
- `ALLOWED_PATHS` - Directories Claude can access
|
|
60
|
+
- `OPENAI_API_KEY` - For voice transcription
|
|
61
|
+
|
|
62
|
+
MCP servers defined in `mcp-config.ts`.
|
|
63
|
+
|
|
64
|
+
### Runtime Files
|
|
65
|
+
|
|
66
|
+
- `/tmp/claude-telegram-session.json` - Session persistence for `/resume`
|
|
67
|
+
- `/tmp/telegram-bot/` - Downloaded photos/documents
|
|
68
|
+
- `/tmp/claude-telegram-audit.log` - Audit log
|
|
69
|
+
|
|
70
|
+
## Patterns
|
|
71
|
+
|
|
72
|
+
**Adding a command**: Create handler in `commands.ts`, register in `index.ts` with `bot.command("name", handler)`
|
|
73
|
+
|
|
74
|
+
**Adding a message handler**: Create in `handlers/`, export from `index.ts`, register in `index.ts` with appropriate filter
|
|
75
|
+
|
|
76
|
+
**Streaming pattern**: All handlers use `createStatusCallback()` from `streaming.ts` and `session.sendMessageStreaming()` for live updates.
|
|
77
|
+
|
|
78
|
+
**Type checking**: Run `bun run typecheck` periodically while editing TypeScript files. Fix any type errors before committing.
|
|
79
|
+
|
|
80
|
+
**After code changes**: Restart the bot so changes can be tested. Use `launchctl kickstart -k gui/$(id -u)/com.claude-telegram-ts` if running as a service, or `bun run start` for manual runs.
|
|
81
|
+
|
|
82
|
+
## Standalone Build
|
|
83
|
+
|
|
84
|
+
The bot can be compiled to a standalone binary with `bun build --compile`. This is used by the ClaudeBot macOS app wrapper.
|
|
85
|
+
|
|
86
|
+
### External Dependencies
|
|
87
|
+
|
|
88
|
+
PDF extraction uses `pdftotext` CLI instead of an npm package (to avoid bundling issues):
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
brew install poppler # Provides pdftotext
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
### PATH Requirements
|
|
95
|
+
|
|
96
|
+
When running as a standalone binary (especially from a macOS app), the PATH may not include Homebrew. The launcher must ensure PATH includes:
|
|
97
|
+
- `/opt/homebrew/bin` (Apple Silicon Homebrew)
|
|
98
|
+
- `/usr/local/bin` (Intel Homebrew)
|
|
99
|
+
|
|
100
|
+
Without this, `pdftotext` won't be found and PDF parsing will fail silently with an error message.
|
|
101
|
+
|
|
102
|
+
## Commit Style
|
|
103
|
+
|
|
104
|
+
Do not add "Generated with Claude Code" footers or "Co-Authored-By" trailers to commit messages.
|
|
105
|
+
|
|
106
|
+
## Running as Service (macOS)
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
cp launchagent/com.claude-telegram-ts.plist.template ~/Library/LaunchAgents/com.claude-telegram-ts.plist
|
|
110
|
+
# Edit plist with your paths
|
|
111
|
+
launchctl load ~/Library/LaunchAgents/com.claude-telegram-ts.plist
|
|
112
|
+
|
|
113
|
+
# Logs
|
|
114
|
+
tail -f /tmp/claude-telegram-bot-ts.log
|
|
115
|
+
tail -f /tmp/claude-telegram-bot-ts.err
|
|
116
|
+
```
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2025 Fabrizio Rinaldi
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/Makefile
ADDED
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
# Claude Telegram Bot - Makefile
|
|
2
|
+
# Usage: make <target>
|
|
3
|
+
|
|
4
|
+
SHELL := /bin/bash
|
|
5
|
+
|
|
6
|
+
PLIST_NAME := com.claude-telegram-ts
|
|
7
|
+
PLIST_PATH := ~/Library/LaunchAgents/$(PLIST_NAME).plist
|
|
8
|
+
PLIST_TEMPLATE := launchagent/$(PLIST_NAME).plist.template
|
|
9
|
+
LOG_FILE := /tmp/claude-telegram-bot.log
|
|
10
|
+
ERR_FILE := /tmp/claude-telegram-bot.err
|
|
11
|
+
|
|
12
|
+
.PHONY: help install setup run dev stop start restart status logs logs-err clean typecheck test
|
|
13
|
+
|
|
14
|
+
# Default target
|
|
15
|
+
help:
|
|
16
|
+
@echo "Claude Telegram Bot"
|
|
17
|
+
@echo ""
|
|
18
|
+
@echo "Quick start:"
|
|
19
|
+
@echo " make setup - First-time setup (install deps, create .env)"
|
|
20
|
+
@echo " make run - Run bot in foreground"
|
|
21
|
+
@echo " make dev - Run with auto-reload (watch mode)"
|
|
22
|
+
@echo ""
|
|
23
|
+
@echo "Background service (macOS LaunchAgent):"
|
|
24
|
+
@echo " make start - Install and start background service"
|
|
25
|
+
@echo " make stop - Stop background service"
|
|
26
|
+
@echo " make restart - Restart background service"
|
|
27
|
+
@echo " make status - Check if service is running"
|
|
28
|
+
@echo " make logs - Tail stdout logs"
|
|
29
|
+
@echo " make logs-err - Tail stderr logs"
|
|
30
|
+
@echo " make uninstall - Remove background service"
|
|
31
|
+
@echo ""
|
|
32
|
+
@echo "Development:"
|
|
33
|
+
@echo " make install - Install dependencies"
|
|
34
|
+
@echo " make test - Run tests"
|
|
35
|
+
@echo " make typecheck - Run TypeScript type check"
|
|
36
|
+
@echo " make clean - Remove temp files and logs"
|
|
37
|
+
|
|
38
|
+
# Install dependencies
|
|
39
|
+
install:
|
|
40
|
+
bun install
|
|
41
|
+
|
|
42
|
+
# First-time setup
|
|
43
|
+
setup: install
|
|
44
|
+
@if [ ! -f .env ]; then \
|
|
45
|
+
cp .env.example .env; \
|
|
46
|
+
echo "Created .env from template"; \
|
|
47
|
+
echo ">>> Edit .env with your TELEGRAM_BOT_TOKEN and TELEGRAM_ALLOWED_USERS"; \
|
|
48
|
+
else \
|
|
49
|
+
echo ".env already exists"; \
|
|
50
|
+
fi
|
|
51
|
+
@echo ""
|
|
52
|
+
@echo "Next steps:"
|
|
53
|
+
@echo " 1. Edit .env with your credentials"
|
|
54
|
+
@echo " 2. Run 'make run' to test"
|
|
55
|
+
@echo " 3. Run 'make start' to run as background service"
|
|
56
|
+
|
|
57
|
+
# Run in foreground
|
|
58
|
+
run:
|
|
59
|
+
bun run start
|
|
60
|
+
|
|
61
|
+
# Run with watch mode
|
|
62
|
+
dev:
|
|
63
|
+
bun run dev
|
|
64
|
+
|
|
65
|
+
# Run tests
|
|
66
|
+
test:
|
|
67
|
+
bun test
|
|
68
|
+
|
|
69
|
+
# TypeScript type check
|
|
70
|
+
typecheck:
|
|
71
|
+
bun run typecheck
|
|
72
|
+
|
|
73
|
+
# === Background Service (macOS LaunchAgent) ===
|
|
74
|
+
|
|
75
|
+
# Install and start service
|
|
76
|
+
start:
|
|
77
|
+
@if [ ! -f .env ]; then \
|
|
78
|
+
echo "Error: .env not found. Run 'make setup' first."; \
|
|
79
|
+
exit 1; \
|
|
80
|
+
fi
|
|
81
|
+
@echo "Installing LaunchAgent..."
|
|
82
|
+
@mkdir -p ~/Library/LaunchAgents
|
|
83
|
+
@export $$(grep -v '^#' .env | xargs) && \
|
|
84
|
+
sed -e "s|/Users/USERNAME/.bun/bin/bun|$$(command -v bun)|g" \
|
|
85
|
+
-e "s|/Users/USERNAME/Dev/claude-telegram-bot-ts|$$(pwd)|g" \
|
|
86
|
+
-e "s|<string>/Users/USERNAME/Dev</string>|<string>$${CLAUDE_WORKING_DIR:-$$(pwd)}</string>|g" \
|
|
87
|
+
-e "s|your-bot-token-here|$${TELEGRAM_BOT_TOKEN}|g" \
|
|
88
|
+
-e "s|<string>123456789</string>|<string>$${TELEGRAM_ALLOWED_USERS}</string>|g" \
|
|
89
|
+
-e "s|<string>sk-...</string>|<string>$${OPENAI_API_KEY:-}</string>|g" \
|
|
90
|
+
-e "s|USERNAME|$$(whoami)|g" \
|
|
91
|
+
$(PLIST_TEMPLATE) > $(PLIST_PATH)
|
|
92
|
+
@echo "Created $(PLIST_PATH) with values from .env"
|
|
93
|
+
@launchctl unload $(PLIST_PATH) 2>/dev/null || true
|
|
94
|
+
@launchctl load $(PLIST_PATH)
|
|
95
|
+
@echo "Service started. Check 'make logs' for output."
|
|
96
|
+
|
|
97
|
+
# Stop service
|
|
98
|
+
stop:
|
|
99
|
+
@launchctl unload $(PLIST_PATH) 2>/dev/null || echo "Service not running"
|
|
100
|
+
@echo "Service stopped"
|
|
101
|
+
|
|
102
|
+
# Restart service
|
|
103
|
+
restart:
|
|
104
|
+
@launchctl kickstart -k gui/$$(id -u)/$(PLIST_NAME) 2>/dev/null || \
|
|
105
|
+
(echo "Service not loaded. Run 'make start' first." && exit 1)
|
|
106
|
+
@echo "Service restarted"
|
|
107
|
+
|
|
108
|
+
# Check service status
|
|
109
|
+
status:
|
|
110
|
+
@if launchctl list | grep -q $(PLIST_NAME); then \
|
|
111
|
+
echo "Service: RUNNING"; \
|
|
112
|
+
launchctl list $(PLIST_NAME); \
|
|
113
|
+
else \
|
|
114
|
+
echo "Service: NOT RUNNING"; \
|
|
115
|
+
fi
|
|
116
|
+
|
|
117
|
+
# Uninstall service
|
|
118
|
+
uninstall: stop
|
|
119
|
+
@rip $(PLIST_PATH) 2>/dev/null || true
|
|
120
|
+
@echo "Service uninstalled"
|
|
121
|
+
|
|
122
|
+
# Tail stdout logs
|
|
123
|
+
logs:
|
|
124
|
+
@if [ -f $(LOG_FILE) ]; then \
|
|
125
|
+
tail -f $(LOG_FILE); \
|
|
126
|
+
else \
|
|
127
|
+
echo "No log file yet. Start the service first."; \
|
|
128
|
+
fi
|
|
129
|
+
|
|
130
|
+
# Tail stderr logs
|
|
131
|
+
logs-err:
|
|
132
|
+
@if [ -f $(ERR_FILE) ]; then \
|
|
133
|
+
tail -f $(ERR_FILE); \
|
|
134
|
+
else \
|
|
135
|
+
echo "No error log yet."; \
|
|
136
|
+
fi
|
|
137
|
+
|
|
138
|
+
# Clean temp files
|
|
139
|
+
clean:
|
|
140
|
+
rip $(LOG_FILE) $(ERR_FILE) 2>/dev/null || true
|
|
141
|
+
rip /tmp/telegram-bot 2>/dev/null || true
|
|
142
|
+
@echo "Cleaned temp files"
|
package/README.md
ADDED
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
# Claude Telegram Bot
|
|
2
|
+
|
|
3
|
+
[](https://opensource.org/licenses/MIT)
|
|
4
|
+
[](https://bun.sh/)
|
|
5
|
+
|
|
6
|
+
**Turn [Claude Code](https://claude.com/product/claude-code) into your personal assistant, accessible from anywhere via Telegram.**
|
|
7
|
+
|
|
8
|
+
Send text, voice, photos, and documents. See responses and tools usage in real-time.
|
|
9
|
+
|
|
10
|
+

|
|
11
|
+
|
|
12
|
+
## Claude Code as a Personal Assistant
|
|
13
|
+
|
|
14
|
+
I've started using Claude Code as a personal assistant, and I've built this bot so I can access it from anywhere.
|
|
15
|
+
|
|
16
|
+
In fact, while Claude Code is described as a powerful AI **coding agent**, it's actually a very capable **general-purpose agent** too when given the right instructions, context, and tools.
|
|
17
|
+
|
|
18
|
+
To achieve this, I set up a folder with a CLAUDE.md that teaches Claude about me (my preferences, where my notes live, my workflows), has a set of tools and scripts based on my needs, and pointed this bot at that folder.
|
|
19
|
+
|
|
20
|
+
→ **[📄 See the Personal Assistant Guide](docs/personal-assistant-guide.md)** for detailed setup and examples.
|
|
21
|
+
|
|
22
|
+
## Bot Features
|
|
23
|
+
|
|
24
|
+
- 💬 **Text**: Ask questions, give instructions, have conversations
|
|
25
|
+
- 🎤 **Voice**: Speak naturally - transcribed via OpenAI and processed by Claude
|
|
26
|
+
- 📸 **Photos**: Send screenshots, documents, or anything visual for analysis
|
|
27
|
+
- 📄 **Documents**: PDFs, text files, and archives (ZIP, TAR) are extracted and analyzed
|
|
28
|
+
- 🔄 **Session persistence**: Conversations continue across messages
|
|
29
|
+
- 📨 **Message queuing**: Send multiple messages while Claude works - they queue up automatically. Prefix with `!` or use `/stop` to interrupt and send immediately
|
|
30
|
+
- 🧠 **Extended thinking**: Trigger Claude's reasoning by using words like "think" or "reason" - you'll see its thought process as it works (configurable via `THINKING_TRIGGER_KEYWORDS`)
|
|
31
|
+
- 🔘 **Interactive buttons**: Claude can present options as tappable inline buttons via the built-in `ask_user` MCP tool
|
|
32
|
+
|
|
33
|
+
## Quick Start
|
|
34
|
+
|
|
35
|
+
### Install via npm (Recommended)
|
|
36
|
+
|
|
37
|
+
```bash
|
|
38
|
+
# Install globally
|
|
39
|
+
npm install -g ctb
|
|
40
|
+
|
|
41
|
+
# Run in any project directory
|
|
42
|
+
cd ~/my-project
|
|
43
|
+
ctb
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
On first run, `ctb` will prompt for your Telegram bot token and allowed user IDs, then optionally save them to `.env`.
|
|
47
|
+
|
|
48
|
+
**Run multiple instances:** Each project directory gets its own isolated bot session. Open multiple terminals and run `ctb` in different directories.
|
|
49
|
+
|
|
50
|
+
### Install from Source
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
git clone https://github.com/htlin/claude-telegram-bot
|
|
54
|
+
cd claude-telegram-bot
|
|
55
|
+
|
|
56
|
+
cp .env.example .env
|
|
57
|
+
# Edit .env with your credentials
|
|
58
|
+
|
|
59
|
+
bun install
|
|
60
|
+
bun run start
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
### Prerequisites
|
|
64
|
+
|
|
65
|
+
- **Bun 1.0+** - [Install Bun](https://bun.sh/)
|
|
66
|
+
- **Claude Agent SDK** - `@anthropic-ai/claude-agent-sdk` (installed via bun install)
|
|
67
|
+
- **Telegram Bot Token** from [@BotFather](https://t.me/BotFather)
|
|
68
|
+
- **OpenAI API Key** (optional, for voice transcription)
|
|
69
|
+
|
|
70
|
+
### Claude Authentication
|
|
71
|
+
|
|
72
|
+
The bot uses the `@anthropic-ai/claude-agent-sdk` which supports two authentication methods:
|
|
73
|
+
|
|
74
|
+
| Method | Best For | Setup |
|
|
75
|
+
| -------------------------- | --------------------------------------- | --------------------------------- |
|
|
76
|
+
| **CLI Auth** (recommended) | High usage, cost-effective | Run `claude` once to authenticate |
|
|
77
|
+
| **API Key** | CI/CD, environments without Claude Code | Set `ANTHROPIC_API_KEY` in `.env` |
|
|
78
|
+
|
|
79
|
+
**CLI Auth** (recommended): The SDK automatically uses your Claude Code login. Just ensure you've run `claude` at least once and authenticated. This uses your Claude Code subscription which is much more cost-effective for heavy usage.
|
|
80
|
+
|
|
81
|
+
**API Key**: For environments where Claude Code isn't installed. Get a key from [console.anthropic.com](https://console.anthropic.com/) and add to `.env`:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
ANTHROPIC_API_KEY=sk-ant-api03-...
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Note: API usage is billed per token and can get expensive quickly for heavy use.
|
|
88
|
+
|
|
89
|
+
## Configuration
|
|
90
|
+
|
|
91
|
+
### 1. Create Your Bot
|
|
92
|
+
|
|
93
|
+
1. Open [@BotFather](https://t.me/BotFather) on Telegram
|
|
94
|
+
2. Send `/newbot` and follow the prompts to create your bot
|
|
95
|
+
3. Copy the token (looks like `1234567890:ABC-DEF...`)
|
|
96
|
+
|
|
97
|
+
Then send `/setcommands` to BotFather and paste this:
|
|
98
|
+
|
|
99
|
+
```
|
|
100
|
+
start - Show status and user ID
|
|
101
|
+
new - Start a fresh session
|
|
102
|
+
resume - Resume last session
|
|
103
|
+
stop - Interrupt current query
|
|
104
|
+
status - Check what Claude is doing
|
|
105
|
+
cd - Change working directory
|
|
106
|
+
bookmarks - Manage directory bookmarks
|
|
107
|
+
restart - Restart the bot
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### 2. Configure Environment
|
|
111
|
+
|
|
112
|
+
Create `.env` with your settings:
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
# Required
|
|
116
|
+
TELEGRAM_BOT_TOKEN=1234567890:ABC-DEF... # From @BotFather
|
|
117
|
+
TELEGRAM_ALLOWED_USERS=123456789 # Your Telegram user ID
|
|
118
|
+
|
|
119
|
+
# Recommended
|
|
120
|
+
CLAUDE_WORKING_DIR=/path/to/your/folder # Where Claude runs (loads CLAUDE.md, skills, MCP)
|
|
121
|
+
OPENAI_API_KEY=sk-... # For voice transcription
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
**Finding your Telegram user ID:** Message [@userinfobot](https://t.me/userinfobot) on Telegram.
|
|
125
|
+
|
|
126
|
+
**File access paths:** By default, Claude can access:
|
|
127
|
+
|
|
128
|
+
- `CLAUDE_WORKING_DIR` (or home directory if not set)
|
|
129
|
+
- `~/Documents`, `~/Downloads`, `~/Desktop`
|
|
130
|
+
- `~/.claude` (for Claude Code plans and settings)
|
|
131
|
+
|
|
132
|
+
To customize, set `ALLOWED_PATHS` in `.env` (comma-separated). Note: this **overrides** all defaults, so include `~/.claude` if you want plan mode to work:
|
|
133
|
+
|
|
134
|
+
```bash
|
|
135
|
+
ALLOWED_PATHS=/your/project,/other/path,~/.claude
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
### 3. Configure MCP Servers (Optional)
|
|
139
|
+
|
|
140
|
+
Copy and edit the MCP config:
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
cp mcp-config.ts mcp-config.local.ts
|
|
144
|
+
# Edit mcp-config.local.ts with your MCP servers
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
The bot includes a built-in `ask_user` MCP server that lets Claude present options as tappable inline keyboard buttons. Add your own MCP servers (Things, Notion, Typefully, etc.) to give Claude access to your tools.
|
|
148
|
+
|
|
149
|
+
## Bot Commands
|
|
150
|
+
|
|
151
|
+
| Command | Description |
|
|
152
|
+
| ------------ | --------------------------------- |
|
|
153
|
+
| `/start` | Show status and your user ID |
|
|
154
|
+
| `/new` | Start a fresh session |
|
|
155
|
+
| `/resume` | Resume last session after restart |
|
|
156
|
+
| `/stop` | Interrupt current query |
|
|
157
|
+
| `/status` | Check what Claude is doing |
|
|
158
|
+
| `/cd <path>` | Change working directory |
|
|
159
|
+
| `/bookmarks` | Manage directory bookmarks |
|
|
160
|
+
| `/restart` | Restart the bot |
|
|
161
|
+
|
|
162
|
+
### Directory Navigation
|
|
163
|
+
|
|
164
|
+
Use `/cd` and `/bookmarks` to quickly switch between project directories:
|
|
165
|
+
|
|
166
|
+
```
|
|
167
|
+
/cd ~/projects/myapp # Change to directory, shows "Add to bookmarks" button
|
|
168
|
+
/cd # Show current working directory
|
|
169
|
+
/bookmarks # List saved bookmarks with navigation buttons
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
Each bookmark shows two buttons:
|
|
173
|
+
|
|
174
|
+
- **🆕 Name** - Start a new session in that directory
|
|
175
|
+
- **🗑️** - Remove from bookmarks
|
|
176
|
+
|
|
177
|
+
## Running as a Service (macOS)
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
cp launchagent/com.claude-telegram-ts.plist.template ~/Library/LaunchAgents/com.claude-telegram-ts.plist
|
|
181
|
+
# Edit the plist with your paths and env vars
|
|
182
|
+
launchctl load ~/Library/LaunchAgents/com.claude-telegram-ts.plist
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
The bot will start automatically on login and restart if it crashes.
|
|
186
|
+
|
|
187
|
+
**Prevent sleep:** To keep the bot running when your Mac is idle, go to **System Settings → Battery → Options** and enable **"Prevent automatic sleeping when the display is off"** (when on power adapter).
|
|
188
|
+
|
|
189
|
+
**Logs:**
|
|
190
|
+
|
|
191
|
+
```bash
|
|
192
|
+
tail -f /tmp/claude-telegram-bot-ts.log # stdout
|
|
193
|
+
tail -f /tmp/claude-telegram-bot-ts.err # stderr
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
**Shell aliases:** If running as a service, these aliases make it easy to manage the bot (add to `~/.zshrc` or `~/.bashrc`):
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
alias cbot='launchctl list | grep com.claude-telegram-ts'
|
|
200
|
+
alias cbot-stop='launchctl bootout gui/$(id -u)/com.claude-telegram-ts 2>/dev/null && echo "Stopped"'
|
|
201
|
+
alias cbot-start='launchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/com.claude-telegram-ts.plist 2>/dev/null && echo "Started"'
|
|
202
|
+
alias cbot-restart='launchctl kickstart -k gui/$(id -u)/com.claude-telegram-ts && echo "Restarted"'
|
|
203
|
+
alias cbot-logs='tail -f /tmp/claude-telegram-bot-ts.log'
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## Development
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
# Run with auto-reload
|
|
210
|
+
bun --watch run src/index.ts
|
|
211
|
+
|
|
212
|
+
# Type check
|
|
213
|
+
bun run typecheck
|
|
214
|
+
|
|
215
|
+
# Or directly
|
|
216
|
+
bun run --bun tsc --noEmit
|
|
217
|
+
```
|
|
218
|
+
|
|
219
|
+
## Security
|
|
220
|
+
|
|
221
|
+
> **⚠️ Important:** This bot runs Claude Code with **all permission prompts bypassed**. Claude can read, write, and execute commands without confirmation within the allowed paths. This is intentional for a seamless mobile experience, but you should understand the implications before deploying.
|
|
222
|
+
|
|
223
|
+
**→ [Read the full Security Model](SECURITY.md)** for details on how permissions work and what protections are in place.
|
|
224
|
+
|
|
225
|
+
Multiple layers protect against misuse:
|
|
226
|
+
|
|
227
|
+
1. **User allowlist** - Only your Telegram IDs can use the bot
|
|
228
|
+
2. **Intent classification** - AI filter blocks dangerous requests
|
|
229
|
+
3. **Path validation** - File access restricted to `ALLOWED_PATHS`
|
|
230
|
+
4. **Command safety** - Destructive patterns like `rm -rf /` are blocked
|
|
231
|
+
5. **Rate limiting** - Prevents runaway usage
|
|
232
|
+
6. **Audit logging** - All interactions logged to `/tmp/claude-telegram-audit.log`
|
|
233
|
+
|
|
234
|
+
## Troubleshooting
|
|
235
|
+
|
|
236
|
+
**Bot doesn't respond**
|
|
237
|
+
|
|
238
|
+
- Verify your user ID is in `TELEGRAM_ALLOWED_USERS`
|
|
239
|
+
- Check the bot token is correct
|
|
240
|
+
- Look at logs: `tail -f /tmp/claude-telegram-bot-ts.err`
|
|
241
|
+
- Ensure the bot process is running
|
|
242
|
+
|
|
243
|
+
**Claude authentication issues**
|
|
244
|
+
|
|
245
|
+
- For CLI auth: run `claude` in terminal and verify you're logged in
|
|
246
|
+
- For API key: check `ANTHROPIC_API_KEY` is set and starts with `sk-ant-api03-`
|
|
247
|
+
- Verify the API key has credits at [console.anthropic.com](https://console.anthropic.com/)
|
|
248
|
+
|
|
249
|
+
**Voice messages fail**
|
|
250
|
+
|
|
251
|
+
- Ensure `OPENAI_API_KEY` is set in `.env`
|
|
252
|
+
- Verify the key is valid and has credits
|
|
253
|
+
|
|
254
|
+
**Claude can't access files**
|
|
255
|
+
|
|
256
|
+
- Check `CLAUDE_WORKING_DIR` points to an existing directory
|
|
257
|
+
- Verify `ALLOWED_PATHS` includes directories you want Claude to access
|
|
258
|
+
- Ensure the bot process has read/write permissions
|
|
259
|
+
|
|
260
|
+
**MCP tools not working**
|
|
261
|
+
|
|
262
|
+
- Verify `mcp-config.ts` exists and exports properly
|
|
263
|
+
- Check that MCP server dependencies are installed
|
|
264
|
+
- Look for MCP errors in the logs
|
|
265
|
+
|
|
266
|
+
## License
|
|
267
|
+
|
|
268
|
+
MIT
|