mirror of
https://github.com/lukaszraczylo/go-telegram.git
synced 2026-06-05 22:43:59 +00:00
docs: auto-generate markdown reference + soften README
- Add gomarkdoc-driven reference docs in docs/reference/, regenerated automatically by 'make regen' alongside the api/ codegen - New 'make docs' target installs gomarkdoc on first run; 'make docs-check' is a CI gate - Fold doc-clean assertion into existing codegen-clean job (single diff check covers spec + api + reference) - Rewrite README header: logo via <picture>, friendlier tagline, emoji-led 'Why you'll like it' bullets instead of Why-table - Drop duplicate echo snippet, soften 'Codegen pipeline' section into 'Keeping up with Telegram' - Link reference from README, Pages nav, and a new Markdown reference card on index.html (target = GitHub source view, renders .md natively)
This commit is contained in:
@@ -0,0 +1,243 @@
|
||||
<!-- Code generated by gomarkdoc. DO NOT EDIT -->
|
||||
|
||||
# conversation
|
||||
|
||||
```go
|
||||
import "github.com/lukaszraczylo/go-telegram/dispatch/conversation"
|
||||
```
|
||||
|
||||
Package conversation implements a stateful conversation handler for the go\-telegram dispatch router. It provides a state\-machine abstraction over multi\-step Telegram bot interactions, with pluggable storage and flexible key strategies.
|
||||
|
||||
## Index
|
||||
|
||||
- [Variables](<#variables>)
|
||||
- [func End\(\) error](<#End>)
|
||||
- [func Next\(s State\) error](<#Next>)
|
||||
- [type Conversation](<#Conversation>)
|
||||
- [func \(c \*Conversation\) Dispatch\(next dispatch.Handler\[\*api.Update\]\) dispatch.Handler\[\*api.Update\]](<#Conversation.Dispatch>)
|
||||
- [type Handler](<#Handler>)
|
||||
- [type KeyStrategy](<#KeyStrategy>)
|
||||
- [type MemoryStorage](<#MemoryStorage>)
|
||||
- [func NewMemoryStorage\(\) \*MemoryStorage](<#NewMemoryStorage>)
|
||||
- [func \(s \*MemoryStorage\) Delete\(\_ context.Context, key string\) error](<#MemoryStorage.Delete>)
|
||||
- [func \(s \*MemoryStorage\) Get\(\_ context.Context, key string\) \(State, error\)](<#MemoryStorage.Get>)
|
||||
- [func \(s \*MemoryStorage\) Set\(\_ context.Context, key string, state State\) error](<#MemoryStorage.Set>)
|
||||
- [type State](<#State>)
|
||||
- [type Step](<#Step>)
|
||||
- [type Storage](<#Storage>)
|
||||
|
||||
|
||||
## Variables
|
||||
|
||||
<a name="ErrKeyNotFound"></a>ErrKeyNotFound is returned by Storage.Get when no conversation is active for the given key.
|
||||
|
||||
```go
|
||||
var ErrKeyNotFound = errors.New("conversation: key not found")
|
||||
```
|
||||
|
||||
<a name="End"></a>
|
||||
## func End
|
||||
|
||||
```go
|
||||
func End() error
|
||||
```
|
||||
|
||||
End signals the conversation has finished and state should be cleared. Conversation handlers return End\(\) to terminate.
|
||||
|
||||
<a name="Next"></a>
|
||||
## func Next
|
||||
|
||||
```go
|
||||
func Next(s State) error
|
||||
```
|
||||
|
||||
Next signals the conversation should advance to the given state. Conversation handlers return Next\("state\_name"\) to transition.
|
||||
|
||||
<a name="Conversation"></a>
|
||||
## type Conversation
|
||||
|
||||
Conversation is a stateful handler with entry, per\-state, exit and fallback steps. A conversation is keyed by KeyStrategy \(default KeyByUserAndChat\) and persisted by Storage \(default in\-memory\).
|
||||
|
||||
```go
|
||||
type Conversation struct {
|
||||
// EntryPoints starts a new conversation when a matching filter fires
|
||||
// and no conversation is already active for the key.
|
||||
EntryPoints []Step
|
||||
|
||||
// States maps each state to the steps that handle it.
|
||||
States map[State][]Step
|
||||
|
||||
// Exits, if any match, end the active conversation early. Useful for
|
||||
// /cancel-style commands.
|
||||
Exits []Step
|
||||
|
||||
// Fallbacks run when no state step matches the current update.
|
||||
Fallbacks []Step
|
||||
|
||||
// Storage persists conversation state. Defaults to NewMemoryStorage.
|
||||
Storage Storage
|
||||
|
||||
// KeyStrategy derives the persistence key. Defaults to KeyByUserAndChat.
|
||||
KeyStrategy KeyStrategy
|
||||
|
||||
// AllowReEntry, when true, lets entry-point steps fire even while a
|
||||
// conversation is already active for the key (effectively restarting it).
|
||||
AllowReEntry bool
|
||||
}
|
||||
```
|
||||
|
||||
<a name="Conversation.Dispatch"></a>
|
||||
### func \(\*Conversation\) Dispatch
|
||||
|
||||
```go
|
||||
func (c *Conversation) Dispatch(next dispatch.Handler[*api.Update]) dispatch.Handler[*api.Update]
|
||||
```
|
||||
|
||||
Dispatch is a global middleware\-shaped Handler that consumes updates and routes them through the conversation graph. Register via router.Use\(conv.Dispatch\).
|
||||
|
||||
If the conversation claims an update, downstream handlers are skipped. If the conversation does not claim it, downstream handlers run as normal.
|
||||
|
||||
<a name="Handler"></a>
|
||||
## type Handler
|
||||
|
||||
Handler defines a step in the conversation. Receives the dispatch context and the raw update. Returns:
|
||||
|
||||
- nil to stay in the current state
|
||||
- Next\("state"\) to transition to a different state
|
||||
- End\(\) to end the conversation
|
||||
- any other non\-nil error to surface to the dispatcher \(state unchanged\)
|
||||
|
||||
```go
|
||||
type Handler func(ctx *dispatch.Context, u *api.Update) error
|
||||
```
|
||||
|
||||
<a name="KeyStrategy"></a>
|
||||
## type KeyStrategy
|
||||
|
||||
KeyStrategy derives a persistence key from an update. Strategies determine how conversation scope works — per\-user, per\-chat, or per\-user\-and\-chat. Implementations must return a stable string for the same logical scope across updates.
|
||||
|
||||
Returns the empty string if the update doesn't have enough context to derive a key \(in which case the conversation handler skips it\).
|
||||
|
||||
```go
|
||||
type KeyStrategy func(u *api.Update) string
|
||||
```
|
||||
|
||||
<a name="KeyByChat"></a>KeyByChat derives a key from the chat ID. Useful for group flows where any user in the chat can drive the conversation.
|
||||
|
||||
```go
|
||||
var KeyByChat KeyStrategy = func(u *api.Update) string {
|
||||
if cid := chatID(u); cid != 0 {
|
||||
return fmt.Sprintf("c:%d", cid)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
```
|
||||
|
||||
<a name="KeyByUser"></a>KeyByUser derives a key from the sending user's ID. Useful for DM conversations and any flow that should follow the user across chats.
|
||||
|
||||
```go
|
||||
var KeyByUser KeyStrategy = func(u *api.Update) string {
|
||||
if uid := userID(u); uid != 0 {
|
||||
return fmt.Sprintf("u:%d", uid)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
```
|
||||
|
||||
<a name="KeyByUserAndChat"></a>KeyByUserAndChat derives a key from both user and chat IDs. The most common strategy: each user has their own conversation per chat.
|
||||
|
||||
```go
|
||||
var KeyByUserAndChat KeyStrategy = func(u *api.Update) string {
|
||||
uid := userID(u)
|
||||
cid := chatID(u)
|
||||
if uid == 0 || cid == 0 {
|
||||
return ""
|
||||
}
|
||||
return fmt.Sprintf("uc:%d:%d", cid, uid)
|
||||
}
|
||||
```
|
||||
|
||||
<a name="MemoryStorage"></a>
|
||||
## type MemoryStorage
|
||||
|
||||
MemoryStorage is the default in\-process Storage. It is safe for concurrent use. Conversation state is lost on process restart; use a custom Storage backed by a database for persistent flows.
|
||||
|
||||
```go
|
||||
type MemoryStorage struct {
|
||||
// contains filtered or unexported fields
|
||||
}
|
||||
```
|
||||
|
||||
<a name="NewMemoryStorage"></a>
|
||||
### func NewMemoryStorage
|
||||
|
||||
```go
|
||||
func NewMemoryStorage() *MemoryStorage
|
||||
```
|
||||
|
||||
NewMemoryStorage constructs an empty in\-memory storage.
|
||||
|
||||
<a name="MemoryStorage.Delete"></a>
|
||||
### func \(\*MemoryStorage\) Delete
|
||||
|
||||
```go
|
||||
func (s *MemoryStorage) Delete(_ context.Context, key string) error
|
||||
```
|
||||
|
||||
|
||||
|
||||
<a name="MemoryStorage.Get"></a>
|
||||
### func \(\*MemoryStorage\) Get
|
||||
|
||||
```go
|
||||
func (s *MemoryStorage) Get(_ context.Context, key string) (State, error)
|
||||
```
|
||||
|
||||
|
||||
|
||||
<a name="MemoryStorage.Set"></a>
|
||||
### func \(\*MemoryStorage\) Set
|
||||
|
||||
```go
|
||||
func (s *MemoryStorage) Set(_ context.Context, key string, state State) error
|
||||
```
|
||||
|
||||
|
||||
|
||||
<a name="State"></a>
|
||||
## type State
|
||||
|
||||
State is a label identifying a node in the conversation graph. The empty string is the implicit "no active conversation" state.
|
||||
|
||||
```go
|
||||
type State string
|
||||
```
|
||||
|
||||
<a name="Step"></a>
|
||||
## type Step
|
||||
|
||||
Step pairs a filter with a handler for one conversation step.
|
||||
|
||||
```go
|
||||
type Step struct {
|
||||
Filter dispatch.Filter[*api.Update]
|
||||
Handler Handler
|
||||
}
|
||||
```
|
||||
|
||||
<a name="Storage"></a>
|
||||
## type Storage
|
||||
|
||||
Storage persists per\-user \(or per\-chat, per\-message — depending on the KeyStrategy in use\) conversation state across update deliveries.
|
||||
|
||||
Implementations must be safe for concurrent use.
|
||||
|
||||
```go
|
||||
type Storage interface {
|
||||
Get(ctx context.Context, key string) (State, error)
|
||||
Set(ctx context.Context, key string, state State) error
|
||||
Delete(ctx context.Context, key string) error
|
||||
}
|
||||
```
|
||||
|
||||
Generated by [gomarkdoc](<https://github.com/princjef/gomarkdoc>)
|
||||
Reference in New Issue
Block a user