FILE / ScuroNeko/Laniakea
methods.go
Исходный файл и его история в репозитории.
Golang lint / lint (push) Successful in 2m15s
(new): sneklog migration (refactor): idiomatic names (fix): polling lifecycle (tests): polling regressions (doc): rc16 changelog
90 lines
2.4 KiB
Go
90 lines
2.4 KiB
Go
package laniakea
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"iter"
|
|
|
|
"git.scuroneko.dev/scuroneko/laniakea/tgapi"
|
|
)
|
|
|
|
// Updates fetches new updates from Telegram API using long polling.
|
|
// It respects the bot's current update offset and automatically advances it
|
|
// after successful retrieval. The method supports selective update types
|
|
// through AllowedUpdates and includes optional request logging.
|
|
//
|
|
// Parameters:
|
|
// - ctx: request context used to cancel the in-flight long polling request
|
|
//
|
|
// Returns:
|
|
// - []tgapi.Update: slice of received updates (empty if none available)
|
|
// - error: any error encountered during the API call
|
|
//
|
|
// Behavior:
|
|
// 1. Uses the bot's current update offset (via GetUpdateOffset)
|
|
// 2. Requests updates with 30-second timeout
|
|
// 3. Filters updates by types specified in bot.GetUpdateTypes()
|
|
// 4. Logs raw update JSON if RequestLogger is configured
|
|
// 5. Automatically updates the offset to the last received update ID + 1
|
|
// 6. Returns all received updates (empty slice if none)
|
|
//
|
|
// Note: This is a blocking call that waits up to 30 seconds for new updates,
|
|
// unless ctx is canceled earlier. For non-blocking behavior, consider using
|
|
// webhooks instead.
|
|
//
|
|
// Example:
|
|
//
|
|
// updates, err := bot.Updates(ctx)
|
|
// if err != nil {
|
|
// log.Fatal(err)
|
|
// }
|
|
// for _, update := range updates {
|
|
// // process update
|
|
// }
|
|
func (bot *Bot[T]) Updates(ctx context.Context) ([]tgapi.Update, error) {
|
|
offset := bot.GetUpdateOffset()
|
|
params := tgapi.UpdateParams{
|
|
Offset: new(offset),
|
|
Timeout: new(30),
|
|
AllowedUpdates: bot.GetUpdateTypes(),
|
|
}
|
|
|
|
updates, err := bot.api.GetUpdatesWithContext(ctx, params)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if bot.requestLogger != nil {
|
|
for _, u := range updates {
|
|
j, err := json.Marshal(u)
|
|
if err != nil {
|
|
bot.GetLogger().Error(err)
|
|
}
|
|
bot.requestLogger.Debugf("UPDATE %s\n", j)
|
|
}
|
|
}
|
|
if len(updates) > 0 {
|
|
bot.SetUpdateOffset(updates[len(updates)-1].UpdateID + 1)
|
|
}
|
|
return updates, err
|
|
}
|
|
|
|
// UpdatesIter fetches updates once and yields each update in order.
|
|
//
|
|
// If fetching updates fails, the iterator yields the error once with a zero
|
|
// update and then stops.
|
|
func (bot *Bot[T]) UpdatesIter(ctx context.Context) iter.Seq2[tgapi.Update, error] {
|
|
return func(yield func(tgapi.Update, error) bool) {
|
|
updates, err := bot.Updates(ctx)
|
|
if err != nil {
|
|
yield(tgapi.Update{}, err)
|
|
return
|
|
}
|
|
for _, u := range updates {
|
|
if !yield(u, nil) {
|
|
return
|
|
}
|
|
}
|
|
}
|
|
}
|