104 lines
2.8 KiB
Go
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)
|
|
}
|
|
}
|