Skip to content

Commit a2d8808

Browse files
ernadoclaude
andcommitted
docs: expand package overview; remove third-party library references
Flesh out doc.go with construction, sending, receiving, errors and sealed-union sections. Drop references to specific third-party libraries across the docs and comments in favor of generic 'HTTP Bot API client' wording. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
1 parent 117d6d0 commit a2d8808

6 files changed

Lines changed: 80 additions & 29 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ round trip, and keeps the raw `gotd/td` client one method call away
1717
1818
## Why MTProto instead of HTTP
1919

20-
| | HTTP Bot API client (e.g. telego) | botapi |
20+
| | HTTP Bot API client | botapi |
2121
| --- | --- | --- |
2222
| Transport | HTTPS to `api.telegram.org` | MTProto via `gotd/td` |
2323
| Updates | `getUpdates` long-poll / webhook | persistent connection, no polling |

doc.go

Lines changed: 55 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,60 @@
22
// github.com/gotd/td.
33
//
44
// Unlike HTTP Bot API clients, botapi does not talk to api.telegram.org. It
5-
// exposes the Bot API surface (types, methods, updates) but speaks MTProto
6-
// directly, which avoids Bot API server rate limits and gives access to the
7-
// raw client when needed (Bot.Raw).
5+
// exposes the familiar Bot API surface (types, methods, updates) but speaks
6+
// MTProto directly. That avoids the public Bot API server's rate limits, keeps
7+
// updates flowing over one persistent connection, and gives access to the raw
8+
// gotd client when the Bot API surface does not cover something (Bot.Raw).
89
//
9-
// This package is under active reconstruction; see docs/roadmap.md.
10+
// # Construction
11+
//
12+
// New builds an unconnected bot from a BotFather token and an MTProto app
13+
// identity (AppID/AppHash from https://my.telegram.org — these are not the bot
14+
// token). Run connects, authorizes as a bot and serves updates until the
15+
// context is canceled:
16+
//
17+
// bot, err := botapi.New(token, botapi.Options{AppID: id, AppHash: hash})
18+
// if err != nil {
19+
// return err
20+
// }
21+
// bot.OnCommand("start", func(c *botapi.Context) error {
22+
// _, err := c.Reply("hello")
23+
// return err
24+
// })
25+
// return bot.Run(ctx)
26+
//
27+
// # Sending
28+
//
29+
// Outgoing methods hang off *Bot, take a context first and a ChatID target, and
30+
// share functional SendOptions (ReplyTo, Silent, WithReplyMarkup,
31+
// WithParseMode, ...). A ChatID is constructed with ID (numeric) or Username:
32+
//
33+
// bot.SendMessage(ctx, botapi.ID(chatID), "*hi*", botapi.WithParseMode(botapi.ParseModeMarkdownV2))
34+
// bot.SendPhoto(ctx, botapi.Username("@channel"), botapi.FileURL("https://.../x.jpg"), "caption")
35+
//
36+
// # Receiving
37+
//
38+
// Updates are dispatched through a small handler framework. Register handlers
39+
// with the On* helpers (OnMessage, OnCommand, OnCallbackQuery, OnInlineQuery,
40+
// ...), narrow them with Predicates (Command, HasText, Regex, CallbackPrefix,
41+
// And/Or/Not, ...), and group shared middleware with Group/Use. Each handler
42+
// receives a *Context with helpers (Message, Sender, Reply, Send,
43+
// AnswerCallback, AnswerInline).
44+
//
45+
// # Errors
46+
//
47+
// Methods return errors shaped like the HTTP Bot API: an *Error with a Code and
48+
// Description (see errors_map.go). Extract it with errors.As, or use the
49+
// helpers Code, AsFloodWait and AsChatMigrated. Context cancellation passes
50+
// through unchanged so callers can errors.Is on ctx.Err().
51+
//
52+
// # Sealed unions
53+
//
54+
// Where the Bot API uses "one of" objects (ChatID, InputFile, ReplyMarkup,
55+
// InputMedia, ChatMember, InlineQueryResult, InputMessageContent, ...) this
56+
// package uses sealed interfaces: an interface with an unexported marker method
57+
// and a fixed set of concrete implementations, so an illegal state is
58+
// unrepresentable and switches over them are checked for exhaustiveness.
59+
//
60+
// See docs/roadmap.md for the implementation status.
1061
package botapi

docs/architecture.md

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99

1010
A Go library that exposes the **Telegram Bot API** surface (types, methods,
1111
updates) 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

1515
Design 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.
2525
4. **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
9899
interfaces (a private method makes them unforgeable from outside the package),
99100
with ergonomic constructors:
100101

@@ -113,8 +114,7 @@ type InputFile interface{ isInputFile() }
113114
Discriminated incoming unions (`ChatMember`, `MessageOrigin`, `ReactionType`,
114115
`MenuButton`, `InputMedia`, inline-query results) are sealed interfaces with one
115116
concrete 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

171171
Predicates 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

docs/building-blocks.md

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
# gotd/td building blocks
22

33
This document maps the high-level `github.com/gotd/td` primitives the Bot API
4-
library is built on. Unlike `telego`, this library does **not** talk HTTP to
5-
`api.telegram.org`. It implements the Bot API *surface* directly over MTProto
6-
using `gotd/td`. Everything below is a building block we wrap or translate.
4+
library is built on. Unlike HTTP Bot API clients, this library does **not** talk
5+
HTTP to `api.telegram.org`. It implements the Bot API *surface* directly over
6+
MTProto using `gotd/td`. Everything below is a building block we wrap or
7+
translate.
78

89
All signatures verified against the local checkout at `/src/gotd/td`
910
(`github.com/gotd/td`, module path confirmed). File:line references are to that
@@ -393,9 +394,9 @@ MTProto, peer resolution, gap recovery, or file transfer.
393394

394395
---
395396

396-
## 11. What this buys us over telego
397+
## 11. What this buys us over HTTP Bot API clients
397398

398-
| telego (HTTP Bot API) | this library (MTProto) |
399+
| HTTP Bot API client | this library (MTProto) |
399400
| --- | --- |
400401
| Subject to Bot API server rate limits | Direct MTProto; flood-wait only |
401402
| `file_id` opaque, must round-trip server | `fileid` codec is local; can construct locations |

docs/roadmap.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
# Roadmap
22

33
> Rebuild `github.com/gotd/botapi` from a codegen-first OpenAPI/ogen project into
4-
> a hand-written, MTProto-backed Bot API **library** that beats `telego`.
4+
> a hand-written, MTProto-backed Bot API **library** that beats existing HTTP
5+
> Bot API clients on ergonomics and performance.
56
> Companion docs: `architecture.md`, `building-blocks.md`.
67
78
Legend: ☐ todo · ◐ in progress · ☑ done
@@ -48,9 +49,8 @@ The hand-written Bot API surface. This is the bulk of the work. **Done** on
4849
the union discriminators
4950
- ☑ Sealed-interface unions: `ChatID`, `InputFile`, `ReplyMarkup`,
5051
`MessageOrigin`, `ChatMember`, `ReactionType`, `MenuButton`, `InputMedia`
51-
- ◐ Constructors / fluent setters (`ID`, `Username`, keyboard builders) — done;
52-
the `telegoutil` equivalent. More fluent setters land alongside the methods
53-
in Phase 3.
52+
- ◐ Constructors / fluent setters (`ID`, `Username`, keyboard builders) — done.
53+
More fluent setters land alongside the methods in Phase 3.
5454
- ☑ Typed error hierarchy (`Error`, `AsFloodWait`, `ErrNotImplemented`)
5555
- ☑ Exhaustiveness lint config for unions (`gochecksumtype` + `exhaustive`;
5656
golangci config migrated to v2)
@@ -171,9 +171,9 @@ Deferred within Phase 5: payment answers
171171
-`pool.Pool` re-pointed at public `Bot`; GC, keepalive
172172
-`cmd/botapi` HTTP server as an optional example (local Bot-API server)
173173
- ☐ Examples: echo bot, media bot, inline bot, handler/middleware
174-
- ☐ Allocation tests on hot paths; benchmarks vs telego
174+
- ☐ Allocation tests on hot paths; benchmarks vs HTTP Bot API clients
175175
- ☐ Conformance test against kept `botdoc` extractor (API-version drift guard)
176-
- ☐ Docs: package docs, migration-from-telego guide, README
176+
- ☐ Docs: package docs, migration guide, README
177177

178178
## Phase 8 — Release
179179

markup.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ func (*ReplyKeyboardMarkup) isReplyMarkup() {}
7777
func (*ReplyKeyboardRemove) isReplyMarkup() {}
7878
func (*ForceReply) isReplyMarkup() {}
7979

80-
// --- Constructors / builders (the type-safe telegoutil equivalent) ---
80+
// --- Constructors / builders (type-safe keyboard helpers) ---
8181

8282
// InlineKeyboard builds an inline keyboard from rows of buttons.
8383
func InlineKeyboard(rows ...[]InlineKeyboardButton) *InlineKeyboardMarkup {

0 commit comments

Comments
 (0)