Files
go-telegram/dispatch/conversation/key.go
T
lukaszraczylo ac7cae8fa7 Initial release of go-telegram
A fully-generated, strongly-typed Go client for the Telegram Bot API.

* 176 methods + 301 types generated from Bot API v10.0
* 1408 auto-generated tests (8 scenarios per method)
* Typed unions throughout — no 'any' in the public surface
* Pluggable HTTP transport and JSON codec (default goccy/go-json)
* Built-in retry middleware honouring Telegram's retry_after
* Generic dispatcher with filters and conversation handlers
* Self-verifying codegen pipeline (regen → audit → emit → run tests)
* 14 example bots covering common patterns
2026-05-09 13:09:27 +01:00

80 lines
2.3 KiB
Go

package conversation
import (
"fmt"
"github.com/lukaszraczylo/go-telegram/api"
)
// 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).
type KeyStrategy func(u *api.Update) string
// KeyByUser derives a key from the sending user's ID. Useful for DM
// conversations and any flow that should follow the user across chats.
var KeyByUser KeyStrategy = func(u *api.Update) string {
if uid := userID(u); uid != 0 {
return fmt.Sprintf("u:%d", uid)
}
return ""
}
// KeyByChat derives a key from the chat ID. Useful for group flows where
// any user in the chat can drive the conversation.
var KeyByChat KeyStrategy = func(u *api.Update) string {
if cid := chatID(u); cid != 0 {
return fmt.Sprintf("c:%d", cid)
}
return ""
}
// KeyByUserAndChat derives a key from both user and chat IDs. The most
// common strategy: each user has their own conversation per chat.
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)
}
// userID extracts the sending user's ID from any update payload.
func userID(u *api.Update) int64 {
switch {
case u.Message != nil && u.Message.From != nil:
return u.Message.From.ID
case u.EditedMessage != nil && u.EditedMessage.From != nil:
return u.EditedMessage.From.ID
case u.CallbackQuery != nil:
return u.CallbackQuery.From.ID
case u.InlineQuery != nil:
return u.InlineQuery.From.ID
}
return 0
}
// chatID extracts the relevant chat ID.
func chatID(u *api.Update) int64 {
switch {
case u.Message != nil:
return u.Message.Chat.ID
case u.EditedMessage != nil:
return u.EditedMessage.Chat.ID
case u.ChannelPost != nil:
return u.ChannelPost.Chat.ID
case u.EditedChannelPost != nil:
return u.EditedChannelPost.Chat.ID
case u.CallbackQuery != nil && u.CallbackQuery.Message != nil:
if msg, ok := u.CallbackQuery.Message.(*api.Message); ok {
return msg.Chat.ID
}
}
return 0
}