tgbotapisfm

package module
v1.0.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 1, 2025 License: MIT Imports: 9 Imported by: 0

README

Telegram Bot API State & Flow Manager (tgbotapisfm)

Надстройка над telegram-bot-api, расширяющая базовый функционал:

  • 🔄 FSM (Finite State Machine) - для управления состояниями диалогов
  • 🚦 Rate Limiter - ограничитель для соблюденя лимитов Telegram API
  • 🔍 Логирование через zerolog

🚀 Установка

go get github.com/DEPTH-STRIDA/telegram-bot-api-sfm

🔥 Особенности

  1. Глобальные состояния собираются в отдельную map'у в конструкторе, поэтому добавлять глобальные состояние во время работы бота бесмысленно.

  2. Бот использует zerolog'ер. Можно настроить свой экземпляр zerolog'ера и установить его методом SetLogger. Главное сделать это, до запуска обработчика.

  3. Можно добавить метод, который будет запускаться для любого обновления. Например, для создания/обновления пользователя в БД.

  4. Структура бота имеет глобальное поле с экземпляром tgbotapi.BotAPI, чтобы иметь возможность использовать функционал tgbotapi.

Если найден обработчик в глобальных состояниях, то проверка локальных состояний не будет выполняться.

  1. Ограничитель имеет не идеальный механизм, поэтому может быть ощущение заторможенности.

Documentation

Index

Constants

View Source
const (
	GlobalLimit    = 30          // Максимум запросов в секунду к API
	ChatLimit      = 1           // Максимум сообщений в секунду в один чат
	MultiChatLimit = 30          // Максимум сообщений в секунду в разные чаты
	WaitTime       = time.Second // Ждем полную секунду при превышении лимита
)

Variables

View Source
var (
	// ErrStatesNil возникает когда карта состояний nil
	ErrStatesNil = fmt.Errorf("states map is nil")

	// ErrInvalidToken возникает при пустом или невалидном токене
	ErrInvalidToken = fmt.Errorf("invalid bot token")

	// ErrNegativeExpiration возникает при отрицательном времени хранения
	ErrNegativeExpiration = fmt.Errorf("expiration time cannot be negative")

	// ErrNegativeCleanup возникает при отрицательном интервале очистки
	ErrNegativeCleanup = fmt.Errorf("cleanup interval cannot be negative")

	// ErrTelegramInit возникает при ошибке инициализации Telegram API
	ErrTelegramInit = fmt.Errorf("failed to initialize telegram bot api")

	// ErrBotStarted возникает при попытке изменить конфигурацию запущенного бота
	ErrBotStarted = fmt.Errorf("cannot modify running bot")

	// ErrStateNotFound возникает когда состояние не найдено в кеше
	ErrStateNotFound = fmt.Errorf("user state not found")

	// ErrInvalidStateType возникает при ошибке приведения типа состояния
	ErrInvalidStateType = fmt.Errorf("invalid state type in cache")

	// ErrStateHandlerNotFound возникает когда обработчик для состояния не найден
	ErrStateHandlerNotFound = fmt.Errorf("state handler not found")

	// ErrSendMessageFailed возникает при неудачных попытках отправки сообщения
	ErrSendMessageFailed = fmt.Errorf("all attempts to send message failed")

	// ErrEditMessageFailed возникает при неудачных попытках редактирования сообщения
	ErrEditMessageFailed = fmt.Errorf("all attempts to edit message failed")

	// ErrDeleteMessageFailed возникает при неудачных попытках удалить сообщения
	ErrDeleteMessageFailed = fmt.Errorf("all attempts to delete message failed")
)

Functions

func NewValidationError

func NewValidationError(err error, value interface{}) error

NewValidationError создает новую ошибку валидации

Types

type Bot

type Bot struct {
	BotAPI *tgbotapi.BotAPI // API бота. Экспортируется для доступа к нему из вне
	// contains filtered or unexported fields
}

Bot структура для бота

func NewBot

func NewBot(config Config) (*Bot, error)

NewBot конструктор нового бота

func (*Bot) DeleteMessage

func (b *Bot) DeleteMessage(deleteMsg tgbotapi.DeleteMessageConfig) error

func (*Bot) DeleteMessageRepet

func (b *Bot) DeleteMessageRepet(msgToDelete tgbotapi.DeleteMessageConfig, numberRepetion int) error

func (*Bot) EditMessage

func (b *Bot) EditMessage(editMsg tgbotapi.EditMessageTextConfig) (*tgbotapi.APIResponse, error)

func (*Bot) EditMessageRepet

func (b *Bot) EditMessageRepet(editMsg tgbotapi.EditMessageTextConfig, numberRepetion int) (*tgbotapi.APIResponse, error)

func (*Bot) GetUserState

func (app *Bot) GetUserState(userId int64) (string, error)

GetUserState возвращает название состояния, в котором находится пользователь

func (*Bot) HandleGlobalStates

func (app *Bot) HandleGlobalStates(update tgbotapi.Update) (bool, error)

HandleGlobalStates проверяет подходит ли действие пользователя под глобальные состояния и если подходит, то выполняет его. Возвращает true, если обработчик нашелся и выполнился.

func (*Bot) HandleUpdates

func (app *Bot) HandleUpdates(offset, timeout int)

HandleUpdates запускает обработку всех обновлений поступающих боту из телеграмма

func (*Bot) SelectHandler

func (app *Bot) SelectHandler(update tgbotapi.Update, userState *State) (bool, error)

func (*Bot) SendDeleteMessage

func (b *Bot) SendDeleteMessage(msg tgbotapi.DeleteMessageConfig) (*tgbotapi.APIResponse, error)

func (*Bot) SendMessage

func (b *Bot) SendMessage(msg tgbotapi.MessageConfig) (tgbotapi.Message, error)

func (*Bot) SendMessageRepet

func (b *Bot) SendMessageRepet(msg tgbotapi.MessageConfig, numberRepetion int) (tgbotapi.Message, error)

SendMessageRepet пытается отправить сообщение указанное количество раз

func (*Bot) SendPinMessageEvent

func (b *Bot) SendPinMessageEvent(messageID int, ChatID int64, disableNotification bool) (*tgbotapi.APIResponse, error)

func (*Bot) SendSticker

func (b *Bot) SendSticker(stickerID string, chatID int64) (*tgbotapi.Message, error)

func (*Bot) SendUnPinAllMessageEvent

func (b *Bot) SendUnPinAllMessageEvent(ChannelUsername string, chatID int64) (*tgbotapi.APIResponse, error)

func (*Bot) SetLogger

func (b *Bot) SetLogger(logger *zerolog.Logger) error

SetLogger заменяет текущий логгер Должен вызываться до Start()

func (*Bot) SetUpdateHandler

func (b *Bot) SetUpdateHandler(handler HandlerFunc) error

SetUpdateHandler устанавливает обработчик обновлений Должен вызываться до Start()

func (*Bot) SetUserState

func (app *Bot) SetUserState(userId int64, state string) error

SetUserState меняет состояние пользователя

func (*Bot) SetUserStateImmediate

func (app *Bot) SetUserStateImmediate(userId int64, state string, update tgbotapi.Update) error

SetUserStateImmediate меняет состояние пользователя и сразу обрабатывает текущее обновление

func (*Bot) Start

func (b *Bot) Start(offset, timeout int)

Start запускает обработку обновлений

func (*Bot) Stop

func (b *Bot) Stop()

Stop останавливает обработку обновлений

type Config

type Config struct {
	Token           string           // Токен бота
	Expiration      time.Duration    // Время хранения состояний пользователя
	CleanupInterval time.Duration    // Интервал очистки кеша
	States          map[string]State // Карта состояний
}

Config структура для конфигурации бота

type Handler

type Handler struct {
	// Handle обрабатывает входящее обновление от Telegram.
	Handle HandlerFunc

	// Description описание обработчика.
	Description string
}

type HandlerFunc

type HandlerFunc func(b *Bot, u tgbotapi.Update) error

type Limiter

type Limiter struct {
	ChatTimes    map[int64]time.Time
	MessageTimes []time.Time
	ApiTimes     []time.Time
	// contains filtered or unexported fields
}

Limiter управляет ограничениями запросов к API

func NewLimiter

func NewLimiter() *Limiter

NewLimiter создает новый лимитер

func (*Limiter) CheckAPI

func (l *Limiter) CheckAPI()

CheckAPI проверяет возможность отправки запроса к API

func (*Limiter) CheckMessage

func (l *Limiter) CheckMessage(chatID int64)

CheckMessage проверяет возможность отправки сообщения в чат

type State

type State struct {
	// Если true, триггеры обработчиков проверяются независимо от текущего состояния пользователя
	// Если в глобальном состоянии найден подходящий обработчик, то он выполняется, а тригеры другого
	// состояния не выполняются.
	// После первого подходящего глобального состояния, другие глобальные состояния не выполняются.
	// Глобальные состояния устанавливаются один раз при иницилизации.
	Global bool
	// Выполняется при входе в состояние. Каждый раз, когда от пользователя приходит обновление, а пользователь находится в состоянии.
	AtEntranceFunc *Handler
	// Выполняется для всех событий, которые не попали в маршруты.
	CatchAllFunc *Handler
	// Сопоставляет текст сообщения с ключом обработчика и выполняет его.
	// Текст пользователя переводится в lowercase, поэтому ключи должны быть в таком же формате.
	MessageHandlers map[string]Handler
	// Сопоставляет текст сообщения с ключом обработчика и выполняет его
	CallbackHandlers map[string]Handler
}

State представляет состояние бота и определяет правила обработки сообщений.

func NewState

func NewState(global bool, atEntranceFunc *Handler, catchAllFunc *Handler) *State

NewState создает новый экземпляр State с заданными параметрами.

type ValidationError

type ValidationError struct {
	Err   error
	Value interface{}
}

ValidationError представляет ошибку валидации с дополнительной информацией

func (*ValidationError) Error

func (e *ValidationError) Error() string

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL