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 |
|
true |
|
|
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.- Create pkg/bot/bot.go with:
-
Configstruct: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)
-
Botstruct:cfg Configbot *telego.Botupdates <-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
- Create telego.Bot via
-
Start(ctx context.Context) error:- Create cancelable context from parent
- Call
bot.SetMyCommandsto 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 viabot.SendMessage.
-
Use telego's MarkdownV2 parse mode for all replies. Create helper:
reply(bot *telego.Bot, chatID int64, text string) error— sends MarkdownV2 messagereplyPlain(bot *telego.Bot, chatID int64, text string) error— sends plain text (for error messages)
-
Per-user rate limiting:
rateLimits map[int64]time.Timewith mutex.checkRateLimit(userID int64, cooldown time.Duration) boolreturns 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>