Files
2026-11-08 03:46:11 +00:00

104 lines
2.8 KiB
Go

package telegram
import (
"github.com/mymmrac/telego"
th "github.com/mymmrac/telego/telegohandler"
"git.entityseven.com/rilaxik/pllist/internal/telegram/shared"
)
func (b *Bot) answerCallback(ctx *th.Context, update telego.Update) error {
if update.CallbackQuery != nil {
err := b.api.AnswerCallbackQuery(ctx, &telego.AnswerCallbackQueryParams{
CallbackQueryID: update.CallbackQuery.ID,
})
if err != nil {
b.logger.Warn("answer callback failed",
"callback_id", update.CallbackQuery.ID, "error", err)
}
}
return ctx.Next(update)
}
// serialize runs updates from the same Telegram user one at a time. Telego
// handles updates in parallel, while pending prompts and list edits are stateful.
func (b *Bot) serialize(ctx *th.Context, update telego.Update) error {
from := updateFrom(update)
if from == nil {
return ctx.Next(update)
}
unlock := b.locker.Lock(from.ID)
defer unlock()
return ctx.Next(update)
}
func (b *Bot) privateOnly(ctx *th.Context, update telego.Update) error {
chatID, ok := updateChatID(update)
if !ok {
return ctx.Next(update)
}
if !isPrivateChat(update) {
return b.sender.Send(ctx, chatID, privateChatOnlyText, nil)
}
return ctx.Next(update)
}
// requireAccess is the bot-level gate: the owner and explicitly allowed users
// pass, everyone else gets a single denial and no handler runs.
func (b *Bot) requireAccess(ctx *th.Context, update telego.Update) error {
from := updateFrom(update)
if from == nil || from.IsBot {
return nil
}
allowed, err := b.botAccess.EnsureAllowed(ctx, from.ID, from.Username)
if err != nil {
return err
}
if allowed {
return ctx.Next(update)
}
chatID, ok := updateChatID(update)
if !ok {
return nil
}
return b.sender.Send(ctx, chatID, noAccessText, nil)
}
func (b *Bot) withUser(ctx *th.Context, update telego.Update) error {
from := updateFrom(update)
if from == nil || from.IsBot {
return nil
}
user, err := b.users.Ensure(ctx, from.ID)
if err != nil {
return err
}
if err := b.shares.ResolvePending(ctx, user.ID, from.ID, from.Username); err != nil {
return err
}
return shared.WithUser(ctx, user).Next(update)
}
func (b *Bot) handleError(ctx *th.Context, update telego.Update, err error) {
attrs := []any{"update_id", update.UpdateID}
if from := updateFrom(update); from != nil {
attrs = append(attrs, "user_id", from.ID)
}
chatID, ok := updateChatID(update)
if ok {
attrs = append(attrs, "chat_id", chatID)
}
attrs = append(attrs, "error", err)
if shared.IsExpectedError(err) {
b.logger.Warn("update rejected", attrs...)
} else {
b.logger.Error("update failed", attrs...)
}
if !ok {
return
}
if sendErr := b.sender.Send(ctx, chatID, shared.UserMessage(err), nil); sendErr != nil {
b.logger.Error("send error message failed", "chat_id", chatID, "error", sendErr)
}
}