mirror of
https://github.com/lukaszraczylo/go-telegram.git
synced 2026-06-05 22:43:59 +00:00
ac7cae8fa7
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
80 lines
2.3 KiB
Go
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
|
|
}
|