99
1010A Go library that exposes the ** Telegram Bot API** surface (types, methods,
1111updates) but implements it ** directly over MTProto** via ` gotd/td ` — not over
12- HTTP to ` api.telegram.org ` . ` telego ` is the ergonomic bar to beat; the Bot API
13- docs (< https://core.telegram.org/bots/api > ) are the spec.
12+ HTTP to ` api.telegram.org ` . Existing HTTP Bot API clients set the ergonomic bar
13+ to beat; the Bot API docs (< https://core.telegram.org/bots/api > ) are the spec.
1414
1515Design goals, in priority order (per project decision):
1616
@@ -23,7 +23,7 @@ Design goals, in priority order (per project decision):
2323 errors (` FloodWait ` , retry-after, network vs API vs not-implemented);
2424 proactive rate limiting.
25254 . ** A great handler framework** — composable middleware/router/predicates over
26- a native MTProto update stream, cleaner than ` telegohandler ` .
26+ a native MTProto update stream.
2727
2828## What changes from today's ` botapi `
2929
@@ -69,7 +69,7 @@ botapi/ root package — the public library
6969 errors_map.go tgerr -> botapi error codes
7070 engine.go owns sender/peers/uploader/downloader/dispatcher
7171
72- handler/ the dispatcher framework (telegohandler rival)
72+ handler/ the dispatcher framework
7373 handler.go Group, Use (middleware), predicates, routing
7474 predicates.go
7575 context.go
@@ -93,8 +93,9 @@ botapi/ root package — the public library
9393
9494### Type-safe unions
9595
96- ` telego ` models ` ChatID ` as a two-field struct (` {ID int64; Username string} ` )
97- and ` InputFile ` similarly — illegal states are representable. We use sealed
96+ A common HTTP-client approach models ` ChatID ` as a two-field struct
97+ (` {ID int64; Username string} ` ) and ` InputFile ` similarly — illegal states are
98+ representable. We use sealed
9899interfaces (a private method makes them unforgeable from outside the package),
99100with ergonomic constructors:
100101
@@ -113,8 +114,7 @@ type InputFile interface{ isInputFile() }
113114Discriminated incoming unions (` ChatMember ` , ` MessageOrigin ` , ` ReactionType ` ,
114115` MenuButton ` , ` InputMedia ` , inline-query results) are sealed interfaces with one
115116concrete type per variant and a type switch — compile-time exhaustiveness via a
116- linter, no ` interface{} ` + reflection, no runtime "try each type" unmarshal that
117- ` telego ` does.
117+ linter, no ` interface{} ` + reflection, no runtime "try each type" unmarshal.
118118
119119### Typed enums
120120
@@ -170,10 +170,9 @@ grp.Use(Recover(), Timeout(30*time.Second))
170170
171171Predicates are `func(ctx, Update) bool`; middleware is
172172`func(next Handler) Handler`. Context carries the `*Bot`, the update, and
173- per-update values — designed in from the start (telego bolts a `Context` wrapper
174- on after the fact and has the webhook `context.WithoutCancel` foot-gun, which we
175- avoid because updates arrive over a persistent MTProto stream, not per-request
176- HTTP).
173+ per-update values — designed in from the start, with no per-request HTTP
174+ `context.WithoutCancel` foot-gun because updates arrive over a persistent
175+ MTProto stream rather than per-request HTTP.
177176
178177## Update flow (no long-poll, no webhook)
179178
0 commit comments