Files

6.5 KiB

phase, plan, type, wave, depends_on, files_modified, autonomous, requirements, must_haves
phase plan type wave depends_on files_modified autonomous requirements must_haves
17-telegram-scheduler 01 execute 1
pkg/bot/bot.go
pkg/bot/bot_test.go
go.mod
go.sum
true
TELE-01
truths artifacts key_links
Bot struct initializes with telego client given a valid token
Bot registers command handlers and starts long polling
Bot respects allowed_chats restriction (empty = allow all)
Bot gracefully shuts down on context cancellation
path provides exports
pkg/bot/bot.go Bot struct, New, Start, Stop, RegisterHandlers, auth middleware
Bot
New
Config
Start
Stop
path provides
pkg/bot/bot_test.go Unit tests for Bot creation and auth filtering
from to via pattern
pkg/bot/bot.go github.com/mymmrac/telego telego.NewBot + long polling telego.NewBot
Create the pkg/bot/ package foundation: Bot struct wrapping telego v1.8.0, command registration, long-polling lifecycle, and chat ID authorization middleware.

Purpose: Establishes the Telegram bot infrastructure that all command handlers (Plan 17-03, 17-04) build on. Output: pkg/bot/bot.go with Bot struct, pkg/bot/bot_test.go with unit tests.

<execution_context> @$HOME/.claude/get-shit-done/workflows/execute-plan.md @$HOME/.claude/get-shit-done/templates/summary.md </execution_context>

@.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md @.planning/phases/17-telegram-scheduler/17-CONTEXT.md @cmd/stubs.go @pkg/storage/db.go Task 1: Add telego dependency and create Bot package skeleton go.mod, go.sum, pkg/bot/bot.go 1. Run `go get github.com/mymmrac/telego@v1.8.0` to add telego as a direct dependency.
  1. Create pkg/bot/bot.go with:
  • Config struct:

    • Token string (Telegram bot token)
    • AllowedChats []int64 (empty = allow all)
    • DB *storage.DB (for subscriber queries, finding lookups)
    • ScanEngine *engine.Engine (for /scan handler)
    • ReconEngine *recon.Engine (for /recon handler)
    • ProviderRegistry *providers.Registry (for /providers, /verify)
    • EncKey []byte (encryption key for finding decryption)
  • Bot struct:

    • cfg Config
    • bot *telego.Bot
    • updates <-chan telego.Update (long polling channel)
    • cancel context.CancelFunc (for shutdown)
  • New(cfg Config) (*Bot, error):

    • Create telego.Bot via telego.NewBot(cfg.Token) (no options needed for long polling)
    • Return &Bot with config stored
  • Start(ctx context.Context) error:

    • Create cancelable context from parent
    • Call bot.SetMyCommands to register command descriptions (scan, verify, recon, status, stats, providers, help, key, subscribe, unsubscribe)
    • Get updates via bot.UpdatesViaLongPolling(nil) which returns a channel
    • Loop over updates channel, dispatch to handler based on update.Message.Text command prefix
    • Check authorization via isAllowed(chatID) before dispatching any handler
    • On ctx.Done(), call bot.StopLongPolling() and return
  • Stop():

    • Call cancel function to trigger shutdown
  • isAllowed(chatID int64) bool:

    • If cfg.AllowedChats is empty, return true
    • Otherwise check if chatID is in the list
  • Handler stubs (will be implemented in Plan 17-03):

    • handleScan(bot *telego.Bot, msg telego.Message)
    • handleVerify(bot *telego.Bot, msg telego.Message)
    • handleRecon(bot *telego.Bot, msg telego.Message)
    • handleStatus(bot *telego.Bot, msg telego.Message)
    • handleStats(bot *telego.Bot, msg telego.Message)
    • handleProviders(bot *telego.Bot, msg telego.Message)
    • handleHelp(bot *telego.Bot, msg telego.Message)
    • handleKey(bot *telego.Bot, msg telego.Message) Each stub sends "Not yet implemented" reply via bot.SendMessage.
  • Use telego's MarkdownV2 parse mode for all replies. Create helper:

    • reply(bot *telego.Bot, chatID int64, text string) error — sends MarkdownV2 message
    • replyPlain(bot *telego.Bot, chatID int64, text string) error — sends plain text (for error messages)
  • Per-user rate limiting: rateLimits map[int64]time.Time with mutex. checkRateLimit(userID int64, cooldown time.Duration) bool returns false if user sent a command within cooldown window. Default cooldown 60s for /scan, /verify, /recon; 5s for others.

Import paths: github.com/mymmrac/telego, github.com/mymmrac/telego/telegoutil (for SendMessageParams construction). cd /home/salva/Documents/apikey && go build ./pkg/bot/... pkg/bot/bot.go compiles with telego dependency. Bot struct, New, Start, Stop, isAllowed, and all handler stubs exist.

Task 2: Unit tests for Bot creation and auth filtering pkg/bot/bot_test.go - Test 1: New() with empty token returns error from telego - Test 2: isAllowed with empty AllowedChats returns true for any chatID - Test 3: isAllowed with AllowedChats=[100,200] returns true for 100, false for 999 - Test 4: checkRateLimit returns true on first call, false on immediate second call, true after cooldown Create pkg/bot/bot_test.go:
  • TestNew_EmptyToken: Verify New(Config{Token:""}) returns an error.
  • TestIsAllowed_EmptyList: Create Bot with empty AllowedChats, verify isAllowed(12345) returns true.
  • TestIsAllowed_RestrictedList: Create Bot with AllowedChats=[100,200], verify isAllowed(100)==true, isAllowed(999)==false.
  • TestCheckRateLimit: Create Bot, verify checkRateLimit(1, 60s)==true first call, ==false second call.

Note: Since telego.NewBot requires a valid token format, for tests that need a Bot struct without a real connection, construct the Bot struct directly (bypassing New) to test isAllowed and rate limit logic independently. cd /home/salva/Documents/apikey && go test ./pkg/bot/... -v -count=1 All 4 test cases pass. Bot auth filtering and rate limiting logic verified.

- `go build ./pkg/bot/...` compiles without errors - `go test ./pkg/bot/... -v` passes all tests - `grep telego go.mod` shows direct dependency at v1.8.0

<success_criteria>

  • pkg/bot/bot.go exists with Bot struct, New, Start, Stop, isAllowed, handler stubs
  • telego v1.8.0 is a direct dependency in go.mod
  • All unit tests pass </success_criteria>
After completion, create `.planning/phases/17-telegram-scheduler/17-01-SUMMARY.md`