docs(17): telegram bot + scheduler context
This commit is contained in:
116
.planning/phases/17-telegram-scheduler/17-CONTEXT.md
Normal file
116
.planning/phases/17-telegram-scheduler/17-CONTEXT.md
Normal file
@@ -0,0 +1,116 @@
|
||||
# Phase 17: Telegram Bot & Scheduled Scanning - Context
|
||||
|
||||
**Gathered:** 2026-04-06
|
||||
**Status:** Ready for planning
|
||||
**Mode:** Auto-generated
|
||||
|
||||
<domain>
|
||||
## Phase Boundary
|
||||
|
||||
Two capabilities:
|
||||
1. **Telegram Bot** — Long-polling bot using telego v1.8.0. Commands: /scan, /verify, /recon, /status, /stats, /providers, /help, /key, /subscribe. Runs via `keyhunter serve --telegram`. Private chat only. Keys always masked except `/key <id>` which sends full detail.
|
||||
2. **Scheduled Scanning** — Cron-based recurring scans using gocron v2.19.1. Stored in SQLite. CLI: `keyhunter schedule add/list/remove`. Jobs persist across restarts. New findings trigger Telegram notification to subscribers.
|
||||
|
||||
</domain>
|
||||
|
||||
<decisions>
|
||||
## Implementation Decisions
|
||||
|
||||
### Telegram Bot (TELE-01..07)
|
||||
- **Library**: `github.com/mymmrac/telego` v1.8.0 (already in go.mod from Phase 1 dep planning)
|
||||
- **Package**: `pkg/bot/`
|
||||
- `bot.go` — Bot struct, Start/Stop, command registration
|
||||
- `handlers.go` — command handlers for /scan, /verify, /recon, /status, /stats, /providers, /help, /key
|
||||
- `subscribe.go` — /subscribe handler + subscriber storage (SQLite table)
|
||||
- `notify.go` — notification dispatcher (send findings to all subscribers)
|
||||
- **Long polling**: Use `telego.WithLongPolling` option
|
||||
- **Auth**: Bot token from config `telegram.token`; restrict to allowed chat IDs from `telegram.allowed_chats` (array, empty = allow all)
|
||||
- **Message formatting**: Use Telegram MarkdownV2 for rich output
|
||||
- **Key masking**: ALL output masks keys. `/key <id>` sends full key only to the requesting user's DM (never group chat)
|
||||
- **Command routing**: Register each command handler via `bot.Handle("/scan", scanHandler)` etc.
|
||||
|
||||
### Scheduled Scanning (SCHED-01..03)
|
||||
- **Library**: `github.com/go-co-op/gocron/v2` v2.19.1 (already in go.mod)
|
||||
- **Package**: `pkg/scheduler/`
|
||||
- `scheduler.go` — Scheduler struct wrapping gocron with SQLite persistence
|
||||
- `jobs.go` — Job struct + CRUD in SQLite `scheduled_jobs` table
|
||||
- **Storage**: `scheduled_jobs` table: id, name, cron_expr, scan_command, notify_telegram, created_at, last_run, next_run, enabled
|
||||
- **Persistence**: On startup, load all enabled jobs from DB and register with gocron
|
||||
- **Notification**: On job completion with new findings, call `pkg/bot/notify.go` to push to subscribers
|
||||
- **CLI commands**: Replace `schedule` stub in cmd/stubs.go with:
|
||||
- `keyhunter schedule add --name=X --cron="..." --scan=<path> [--notify=telegram]`
|
||||
- `keyhunter schedule list`
|
||||
- `keyhunter schedule remove <name>`
|
||||
- `keyhunter schedule run <name>` (manual trigger)
|
||||
|
||||
### Integration: serve command
|
||||
- `keyhunter serve [--telegram] [--port=8080]`
|
||||
- If `--telegram`: start bot in goroutine, start scheduler, block until signal
|
||||
- If no `--telegram`: start scheduler + web server only (Phase 18)
|
||||
- Replace `serve` stub in cmd/stubs.go
|
||||
|
||||
### New SQLite Tables
|
||||
```sql
|
||||
CREATE TABLE IF NOT EXISTS subscribers (
|
||||
chat_id INTEGER PRIMARY KEY,
|
||||
username TEXT,
|
||||
subscribed_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS scheduled_jobs (
|
||||
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
||||
name TEXT UNIQUE NOT NULL,
|
||||
cron_expr TEXT NOT NULL,
|
||||
scan_command TEXT NOT NULL,
|
||||
notify_telegram BOOLEAN DEFAULT FALSE,
|
||||
enabled BOOLEAN DEFAULT TRUE,
|
||||
last_run DATETIME,
|
||||
next_run DATETIME,
|
||||
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
```
|
||||
|
||||
### Dependencies
|
||||
- `github.com/mymmrac/telego` — already indirect in go.mod, promote to direct
|
||||
- `github.com/go-co-op/gocron/v2` — already indirect, promote to direct
|
||||
|
||||
</decisions>
|
||||
|
||||
<code_context>
|
||||
## Existing Code Insights
|
||||
|
||||
### Reusable Assets
|
||||
- pkg/engine/ — engine.Scan() for bot /scan command
|
||||
- pkg/verify/ — verifier for bot /verify command
|
||||
- pkg/recon/ — Engine.SweepAll() for bot /recon command
|
||||
- pkg/storage/ — DB for findings, settings
|
||||
- pkg/output/ — formatters for bot message rendering
|
||||
- cmd/stubs.go — serve, schedule stubs to replace
|
||||
- cmd/scan.go — openDBWithKey() helper to reuse
|
||||
|
||||
### Key Integration Points
|
||||
- Bot handlers call the same packages as CLI commands
|
||||
- Scheduler wraps the same scan logic but triggered by cron
|
||||
- Notification bridges scheduler → bot subscribers
|
||||
|
||||
</code_context>
|
||||
|
||||
<specifics>
|
||||
## Specific Ideas
|
||||
|
||||
- /status should show: total findings, last scan time, active scheduled jobs, bot uptime
|
||||
- /stats should show: findings by provider, top 10 providers, findings last 24h
|
||||
- Bot should rate-limit commands per user (1 scan per 60s)
|
||||
- Schedule jobs should log last_run and next_run for monitoring
|
||||
|
||||
</specifics>
|
||||
|
||||
<deferred>
|
||||
## Deferred Ideas
|
||||
|
||||
- Webhook notifications (Slack, Discord) — separate from Telegram
|
||||
- Inline query mode for Telegram — out of scope
|
||||
- Multi-bot instances — out of scope
|
||||
- Job output history (keep last N results) — defer to v2
|
||||
|
||||
</deferred>
|
||||
Reference in New Issue
Block a user