REPOSITORY / ScuroNeko/Laniakea
Wiki
Expand wiki with full Russian translation
Add Russian companion pages for the full wiki surface Link every English and Russian page pair directly for language switching Rework Home-RU into a complete Russian navigation hub
@@ -0,0 +1,81 @@
|
||||
# Auto-Generated Commands RU
|
||||
|
||||
English version: [[Auto-Generated-Commands]]
|
||||
|
||||
Это краткая русскоязычная версия страницы про автоматическую публикацию Telegram-команд. Полная и наиболее актуальная страница: [[Auto-Generated-Commands]].
|
||||
|
||||
## Что делает эта функция
|
||||
|
||||
Laniakea может пройтись по уже зарегистрированным plugin commands, собрать подходящие команды и отправить их в Telegram через `setMyCommands`.
|
||||
|
||||
Для этого используются:
|
||||
- `AutoGenerateCommands()`
|
||||
- `AutoGenerateCommandsForScope(...)`
|
||||
|
||||
Это удобно, потому что не нужно вручную поддерживать отдельный список команд вне кода плагинов.
|
||||
|
||||
## Откуда берутся команды
|
||||
|
||||
Автогенерация работает только по уже зарегистрированным commands.
|
||||
|
||||
Учитывается:
|
||||
- имя команды;
|
||||
- описание команды;
|
||||
- skip-флаги на command или plugin уровне.
|
||||
|
||||
Не участвуют:
|
||||
- payload handlers;
|
||||
- update handlers;
|
||||
- команды, которые ты явно исключил из автогенерации.
|
||||
|
||||
## Когда вызывать
|
||||
|
||||
Обычный порядок такой:
|
||||
|
||||
1. создать bot;
|
||||
2. создать plugins;
|
||||
3. зарегистрировать commands;
|
||||
4. добавить plugins через `AddPlugins(...)`;
|
||||
5. вызвать `AutoGenerateCommands()` или `AutoGenerateCommandsForScope(...)`;
|
||||
6. запустить bot.
|
||||
|
||||
Важно: `AddPlugins(...)` — это snapshot point. Если ты меняешь plugin после регистрации, автогенерация не обязана увидеть эти изменения.
|
||||
|
||||
## Ограничения Telegram
|
||||
|
||||
Для slash-команд Telegram накладывает свои правила:
|
||||
- имя команды должно быть коротким;
|
||||
- нельзя использовать произвольные символы;
|
||||
- существует лимит на количество команд в одном наборе.
|
||||
|
||||
Поэтому автогенерация удобна, но не отменяет необходимости держать command names аккуратными и валидными.
|
||||
|
||||
## Scope-based регистрация
|
||||
|
||||
Если нужно публиковать разные команды для разных аудиторий, используй `AutoGenerateCommandsForScope(...)`.
|
||||
|
||||
Это полезно, когда:
|
||||
- есть отдельный набор команд для админов;
|
||||
- у бота есть разные user segments;
|
||||
- хочется не засорять глобальный command list.
|
||||
|
||||
## Skip controls
|
||||
|
||||
Если команду не нужно публиковать в Telegram command menu, ее можно исключить из автогенерации.
|
||||
|
||||
Это полезно для:
|
||||
- внутренних технических commands;
|
||||
- переходных migration commands;
|
||||
- редко используемых maintenance commands.
|
||||
|
||||
## Рекомендации
|
||||
|
||||
- Вызывай автогенерацию после полной регистрации plugins.
|
||||
- Следи, чтобы descriptions были короткими и понятными.
|
||||
- Не путай payload handlers с обычными slash-командами.
|
||||
|
||||
## Что читать дальше
|
||||
|
||||
- [[Commands-and-Plugins-RU]]
|
||||
- [[Bot-Lifecycle-RU]]
|
||||
- [[Auto-Generated-Commands]]
|
||||
@@ -1,5 +1,7 @@
|
||||
# Auto-Generated Commands
|
||||
|
||||
Russian version: [[Auto-Generated-Commands-RU]]
|
||||
|
||||
This page explains how Laniakea derives Telegram command metadata from registered plugins and publishes it through the Bot API. It covers `AutoGenerateCommands(...)`, scope-specific registration, skip controls, and the command-name rules Telegram enforces.
|
||||
|
||||
## What auto-generation does
|
||||
|
||||
+107
@@ -0,0 +1,107 @@
|
||||
# Bot Lifecycle RU
|
||||
|
||||
English version: [[Bot-Lifecycle]]
|
||||
|
||||
Это краткая русскоязычная версия страницы про lifecycle `Bot`. Полная и наиболее актуальная страница: [[Bot-Lifecycle]].
|
||||
|
||||
## Жизненный цикл в одном списке
|
||||
|
||||
1. Собрать `BotOpts`.
|
||||
2. Создать `Bot` через `NewBot[T](opts)`.
|
||||
3. Полностью настроить bot: plugins, middleware, runners, payload policy, l10n, db context.
|
||||
4. Запустить через `Run()` или `RunWithContext(...)`.
|
||||
5. Остановить runtime через завершение `Run()` или cancel context.
|
||||
6. Освободить локальные ресурсы через `Close()`.
|
||||
7. Для следующего запуска создать новый `Bot`.
|
||||
|
||||
Главное правило: `Bot` single-use.
|
||||
|
||||
## Что делает `NewBot(...)`
|
||||
|
||||
Конструктор:
|
||||
- валидирует `opts`;
|
||||
- создает внутренние `tgapi.API` и `Uploader`;
|
||||
- поднимает логгеры;
|
||||
- готовит default `DraftProvider`;
|
||||
- вызывает `getMe`, чтобы проверить токен и получить username бота.
|
||||
|
||||
`NewBot(...)` сразу падает, если:
|
||||
- `opts == nil`;
|
||||
- токен пустой;
|
||||
- Telegram не принимает токен.
|
||||
|
||||
## Что нужно закончить до `Run`
|
||||
|
||||
До запуска обычно нужно завершить:
|
||||
- `DatabaseContext(...)`
|
||||
- `AddPlugins(...)`
|
||||
- `AddMiddleware(...)`
|
||||
- `AddRunner(...)`
|
||||
- `AddL10n(...)`
|
||||
- `SetPayloadType(...)`
|
||||
- `SetStrictPayloadType(...)`
|
||||
- `SetDraftProvider(...)`
|
||||
|
||||
Это важно, потому что runtime не рассчитан на модель “запустили, а потом продолжаем собирать конфигурацию на лету”.
|
||||
|
||||
## Почему `AddPlugins(...)` так важен
|
||||
|
||||
`AddPlugins(...)` копирует конфигурацию plugin внутрь bot.
|
||||
|
||||
Практически это значит:
|
||||
- сначала закончи настройку plugin;
|
||||
- потом регистрируй его;
|
||||
- не рассчитывай, что дальнейшая мутация исходного `*Plugin` будет официально поддерживаемой частью API.
|
||||
|
||||
## `Run()` и `RunWithContext(...)`
|
||||
|
||||
`Run()` — это короткая форма для простых случаев.
|
||||
|
||||
`RunWithContext(...)` — основной production-вариант, потому что он:
|
||||
- умеет graceful shutdown через `ctx.Done()`;
|
||||
- ждет завершения queued updates;
|
||||
- корректно дожидается runners.
|
||||
|
||||
Если bot уже был запущен раньше, повторный запуск вернет `ErrBotAlreadyRun`.
|
||||
|
||||
## Что происходит во время runtime
|
||||
|
||||
Во время работы bot делает три вещи:
|
||||
- long-polling `getUpdates`;
|
||||
- складывает updates во внутреннюю очередь;
|
||||
- обрабатывает их через worker pool.
|
||||
|
||||
Полезно помнить:
|
||||
- размер worker pool управляется через `MaxWorkers`;
|
||||
- polling при ошибках использует exponential backoff;
|
||||
- после cancel сначала прекращается polling, потом дренируется очередь, потом дожидаются runners.
|
||||
|
||||
## `Close()` и `CloseRemote()`
|
||||
|
||||
Это разные вещи.
|
||||
|
||||
`Close()`:
|
||||
- закрывает plugins через `Plugin.Close()`;
|
||||
- закрывает uploader;
|
||||
- закрывает локальный API client;
|
||||
- закрывает request logger и main logger.
|
||||
|
||||
`CloseRemote(ctx)`:
|
||||
- отправляет Telegram Bot API метод `close`;
|
||||
- относится к удаленной сессии, а не к локальным ресурсам процесса.
|
||||
|
||||
Обычно боту нужен именно `Close()`.
|
||||
|
||||
## Частые ошибки
|
||||
|
||||
- Пытаться повторно использовать тот же `Bot`.
|
||||
- Забывать `Close()` после завершения `RunWithContext(...)`.
|
||||
- Менять plugins после `AddPlugins(...)` и ждать, что bot это гарантированно увидит.
|
||||
- Регистрировать repeating runner без timeout.
|
||||
|
||||
## Что читать дальше
|
||||
|
||||
- [[Bot-Options-and-Configuration-RU]]
|
||||
- [[Runners-RU]]
|
||||
- [[Commands-and-Plugins-RU]]
|
||||
- [[Bot-Lifecycle]]
|
||||
@@ -1,5 +1,7 @@
|
||||
# Bot Lifecycle
|
||||
|
||||
Russian version: [[Bot-Lifecycle-RU]]
|
||||
|
||||
This page explains how a `Bot` is created, configured, started, stopped, and retired. The important rule is that a `Bot` instance is single-use: configure it fully, run it once, then create a new instance for the next session.
|
||||
|
||||
## Lifecycle at a glance
|
||||
|
||||
@@ -0,0 +1,122 @@
|
||||
# Bot Options and Configuration RU
|
||||
|
||||
English version: [[Bot-Options-and-Configuration]]
|
||||
|
||||
Это краткая русскоязычная версия страницы про `BotOpts`. Полная и наиболее актуальная страница: [[Bot-Options-and-Configuration]].
|
||||
|
||||
## Зачем нужен `BotOpts`
|
||||
|
||||
`BotOpts` — это construction-time конфигурация для `Bot`.
|
||||
|
||||
Через него настраиваются:
|
||||
- токен и API endpoint;
|
||||
- update types и command prefixes;
|
||||
- logging behavior;
|
||||
- rate limiting;
|
||||
- strict payload decoding;
|
||||
- размер worker pool.
|
||||
|
||||
Обычный flow:
|
||||
1. собрать `BotOpts` вручную или через `LoadOptsFromEnv()`;
|
||||
2. при необходимости донастроить setter methods;
|
||||
3. передать в `NewBot(...)`.
|
||||
|
||||
## Два способа собрать `BotOpts`
|
||||
|
||||
### Вручную
|
||||
|
||||
```go
|
||||
opts := (&laniakea.BotOpts{}).
|
||||
SetToken("TOKEN").
|
||||
SetPrefixes("/", "!").
|
||||
SetRateLimit(30).
|
||||
SetMaxWorkers(32)
|
||||
```
|
||||
|
||||
### Через environment
|
||||
|
||||
```go
|
||||
opts := laniakea.LoadOptsFromEnv()
|
||||
```
|
||||
|
||||
Это удобно для production, containers и CI.
|
||||
|
||||
## Что обязательно
|
||||
|
||||
Обязателен только `Token`.
|
||||
|
||||
Если токен пустой, `NewBot(...)` вернет `ErrTokenRequired`.
|
||||
|
||||
## Дефолты, которые стоит помнить
|
||||
|
||||
- `Prefixes` по умолчанию `["/"]`
|
||||
- `RateLimit` по умолчанию `30`
|
||||
- `MaxWorkers` по умолчанию `32`
|
||||
- `ErrorTemplate` по умолчанию `"%s"`
|
||||
- request logging и file logging выключены
|
||||
- strict payload decoding выключен
|
||||
|
||||
## Важные поля
|
||||
|
||||
### `UpdateTypes`
|
||||
|
||||
Ограничивает, какие update types bot запрашивает у Telegram.
|
||||
|
||||
Полезно, когда ты не хочешь принимать лишние update types и шуметь в routing layer.
|
||||
|
||||
### `Prefixes`
|
||||
|
||||
Определяет command prefixes вроде `/` или `!`.
|
||||
|
||||
### `ErrorTemplate`
|
||||
|
||||
Определяет, как пользователю показываются returned handler errors.
|
||||
|
||||
### `Debug`
|
||||
|
||||
Включает debug logging.
|
||||
|
||||
### `UseRequestLogger`
|
||||
|
||||
Включает логирование сырых updates после `getUpdates`.
|
||||
|
||||
### `WriteToFile` и `LoggerBasePath`
|
||||
|
||||
Управляют записью логов в файлы.
|
||||
|
||||
### `UseTestServer` и `APIUrl`
|
||||
|
||||
Полезны для test environment, proxy или custom Telegram gateway.
|
||||
|
||||
### `RateLimit` и `DropRLOverflow`
|
||||
|
||||
Управляют политикой limiter:
|
||||
- ждать и доставлять надежнее;
|
||||
- или дропать overflow ради отзывчивости.
|
||||
|
||||
### `StrictPayloadType`
|
||||
|
||||
Включает строгую политику декодирования callback payloads без fallback между JSON и Base64.
|
||||
|
||||
### `MaxWorkers`
|
||||
|
||||
Определяет максимальное количество concurrent update handlers.
|
||||
|
||||
## Когда выбирать маленький или большой `MaxWorkers`
|
||||
|
||||
Меньше:
|
||||
- если handlers CPU-bound;
|
||||
- если downstream services не выдержат много параллелизма.
|
||||
|
||||
Больше:
|
||||
- если handlers в основном I/O-bound;
|
||||
- если bot часто ждет БД или внешние API.
|
||||
|
||||
Стартовая безопасная точка обычно 16-32.
|
||||
|
||||
## Что читать дальше
|
||||
|
||||
- [[Bot-Lifecycle-RU]]
|
||||
- [[Rate-Limiting-RU]]
|
||||
- [[Logging-RU]]
|
||||
- [[Bot-Options-and-Configuration]]
|
||||
@@ -1,5 +1,7 @@
|
||||
# Bot Options and Configuration
|
||||
|
||||
Russian version: [[Bot-Options-and-Configuration-RU]]
|
||||
|
||||
This page explains how to configure a bot before calling `NewBot(...)`. It focuses on `BotOpts`, environment-based configuration, and the practical meaning of the most important knobs.
|
||||
|
||||
## Overview
|
||||
|
||||
@@ -0,0 +1,262 @@
|
||||
# Commands and Plugins RU
|
||||
|
||||
English version: [[Commands-and-Plugins]]
|
||||
|
||||
Это краткая русскоязычная версия страницы про архитектуру `Bot`, `Plugin`, commands, payloads и update handlers. Полная и наиболее актуальная страница: [[Commands-and-Plugins]].
|
||||
|
||||
## Главное сначала
|
||||
|
||||
Обычная модель в Laniakea такая:
|
||||
- `Bot` владеет runtime, polling, логированием и API-клиентами;
|
||||
- `Plugin` группирует связанную функциональность;
|
||||
- commands обрабатывают текстовые команды вроде `/start`;
|
||||
- payload handlers обрабатывают callback data от inline-кнопок;
|
||||
- update handlers обрабатывают остальные update types вне обычного command/payload flow.
|
||||
|
||||
Для большинства ботов стартовая структура выглядит так:
|
||||
- один или несколько плагинов;
|
||||
- несколько команд;
|
||||
- plugin middleware для общих проверок;
|
||||
- payload handlers, когда появляются inline-кнопки.
|
||||
|
||||
## Что такое `Plugin`
|
||||
|
||||
Плагин — это именованная группа:
|
||||
- commands;
|
||||
- payload handlers;
|
||||
- update handlers;
|
||||
- общих middleware;
|
||||
- optional logger и `OnClose` hook.
|
||||
|
||||
Пример:
|
||||
|
||||
```go
|
||||
plugin := laniakea.NewPlugin[laniakea.NoDB]("admin")
|
||||
```
|
||||
|
||||
Обычно плагины удобно делить по смыслу:
|
||||
- `admin`
|
||||
- `payments`
|
||||
- `profile`
|
||||
- `support`
|
||||
|
||||
Так проще держать границы ответственности и не превращать весь бот в один большой registry-файл.
|
||||
|
||||
## Command handlers
|
||||
|
||||
Сигнатура command handler такая:
|
||||
|
||||
```go
|
||||
func(ctx *laniakea.MsgContext, db T) error
|
||||
```
|
||||
|
||||
Где:
|
||||
- `ctx` — текущий `MsgContext`;
|
||||
- `db` — значение generic-параметра `T`, которое ты передал в `Bot`.
|
||||
|
||||
Возвращай:
|
||||
- `nil`, если все прошло успешно;
|
||||
- `error`, если хочешь отдать ошибку в централизованный error flow.
|
||||
|
||||
Пример:
|
||||
|
||||
```go
|
||||
func start(ctx *laniakea.MsgContext, db *App) error {
|
||||
ctx.Answer("Welcome")
|
||||
return nil
|
||||
}
|
||||
```
|
||||
|
||||
## Как регистрировать команды
|
||||
|
||||
Самый обычный путь:
|
||||
|
||||
```go
|
||||
plugin := laniakea.NewPlugin[*App]("main")
|
||||
plugin.AddCommand(plugin.NewCommand(start, "start"))
|
||||
```
|
||||
|
||||
Важно:
|
||||
- в имени команды не нужно писать `/`;
|
||||
- `"start"` матчится с `/start`;
|
||||
- `"help"` матчится с `/help`.
|
||||
|
||||
## Что приходит в `ctx.Text` и `ctx.Args`
|
||||
|
||||
Для команды:
|
||||
|
||||
```text
|
||||
/echo hello world
|
||||
```
|
||||
|
||||
в handler'е будет:
|
||||
- `ctx.Text == "hello world"`
|
||||
- `ctx.Args == []string{"hello", "world"}`
|
||||
|
||||
Это удобно, потому что текст команды уже очищен от префикса и имени команды.
|
||||
|
||||
## Валидация аргументов команды
|
||||
|
||||
Для commands можно описывать аргументы через `CommandArg`.
|
||||
|
||||
Пример:
|
||||
|
||||
```go
|
||||
plugin.AddCommand(
|
||||
plugin.NewCommand(banUser, "ban",
|
||||
laniakea.NewCommandArg("user_id").
|
||||
SetValueType(laniakea.CommandValueIntType).
|
||||
SetRequired(),
|
||||
),
|
||||
)
|
||||
```
|
||||
|
||||
Это позволяет валидировать:
|
||||
- наличие обязательных аргументов;
|
||||
- базовый тип вроде `int` или `string`;
|
||||
- regex-ограничения через конфигурацию аргумента.
|
||||
|
||||
Если валидация не проходит, handler не запускается, а ошибка идет в обычный error flow.
|
||||
|
||||
## Payload handlers
|
||||
|
||||
Payload handlers нужны для callback data от inline-кнопок.
|
||||
|
||||
Пример:
|
||||
|
||||
```go
|
||||
func confirmDelete(ctx *laniakea.MsgContext, db *App) error {
|
||||
ctx.EditCallback("Deleted", nil)
|
||||
return nil
|
||||
}
|
||||
|
||||
plugin.AddPayload(plugin.NewPayload(confirmDelete, "delete.confirm"))
|
||||
```
|
||||
|
||||
Важно помнить:
|
||||
- payload handler использует ту же сигнатуру, что и command handler;
|
||||
- аргументы decoded payload попадают в `ctx.Args`;
|
||||
- payload — это не текстовая команда, а callback from button.
|
||||
|
||||
Подробности: [[Inline-Keyboards-and-Payloads]]
|
||||
|
||||
## Update handlers
|
||||
|
||||
Update handlers нужны для update types вне обычного command/payload flow.
|
||||
|
||||
Пример:
|
||||
|
||||
```go
|
||||
plugin.AddUpdateHandler(tgapi.UpdateTypeInlineQuery, func(ctx *laniakea.MsgContext, db *App) error {
|
||||
return nil
|
||||
})
|
||||
```
|
||||
|
||||
Это правильный инструмент для вещей вроде:
|
||||
- `inline_query`
|
||||
- `chosen_inline_result`
|
||||
- `poll`
|
||||
- `chat_member`
|
||||
|
||||
Но есть важное исключение:
|
||||
- `message`
|
||||
- `channel_post`
|
||||
- `callback_query`
|
||||
|
||||
не должны идти через `AddUpdateHandler(...)`, потому что они уже обслуживаются обычным command/payload pipeline.
|
||||
|
||||
## Как выглядит runtime flow
|
||||
|
||||
Для текстовой команды поток примерно такой:
|
||||
|
||||
1. Приходит Telegram update.
|
||||
2. `Bot` готовит `MsgContext`.
|
||||
3. Выполняется bot middleware.
|
||||
4. Находится подходящий plugin.
|
||||
5. Выполняется plugin middleware.
|
||||
6. Выполняется валидация аргументов.
|
||||
7. Выполняется command-specific middleware.
|
||||
8. Запускается handler.
|
||||
9. Если handler вернул ошибку, она идет в централизованный error flow.
|
||||
|
||||
Для payload flow идея та же самая, только trigger приходит не из текста сообщения, а из decoded callback data.
|
||||
|
||||
## Где использовать middleware
|
||||
|
||||
Есть два основных уровня:
|
||||
|
||||
### Plugin middleware
|
||||
|
||||
Добавляется через:
|
||||
|
||||
```go
|
||||
plugin.AddMiddleware(...)
|
||||
```
|
||||
|
||||
Подходит для общей логики внутри одного плагина:
|
||||
- auth checks;
|
||||
- rate limiting;
|
||||
- shared logging;
|
||||
- common preconditions.
|
||||
|
||||
### Command-specific middleware
|
||||
|
||||
Добавляется через:
|
||||
|
||||
```go
|
||||
plugin.NewCommand(handler, "name").Use(middleware)
|
||||
```
|
||||
|
||||
Подходит, когда проверка нужна только одной команде или одному payload handler.
|
||||
|
||||
Подробности: [[Middleware]]
|
||||
|
||||
## Частые ошибки
|
||||
|
||||
### Добавлять `/` в имя команды
|
||||
|
||||
Неправильно:
|
||||
|
||||
```go
|
||||
plugin.NewCommand(start, "/start")
|
||||
```
|
||||
|
||||
Правильно:
|
||||
|
||||
```go
|
||||
plugin.NewCommand(start, "start")
|
||||
```
|
||||
|
||||
### Считать payload обычной командой
|
||||
|
||||
Payload handler вызывается не из текста сообщения, а из callback data кнопки.
|
||||
|
||||
### Использовать `AddUpdateHandler(...)` для `message` или `callback_query`
|
||||
|
||||
Эти update types относятся к обычному command/payload pipeline.
|
||||
|
||||
### Возвращать `error` там, где это просто обычная ветка UX
|
||||
|
||||
Если пользователю надо просто показать usage или denial message, часто лучше сделать так:
|
||||
|
||||
```go
|
||||
ctx.Answer("Usage: /ban <id>")
|
||||
return nil
|
||||
```
|
||||
|
||||
## Когда использовать что
|
||||
|
||||
Используй:
|
||||
- commands для slash-команд;
|
||||
- payload handlers для inline button callbacks;
|
||||
- update handlers для остальных Telegram updates;
|
||||
- plugin middleware для общих проверок;
|
||||
- command middleware для локальных, узких проверок.
|
||||
|
||||
## Что читать дальше
|
||||
|
||||
- [[Getting-Started-RU]]
|
||||
- [[FAQ-RU]]
|
||||
- [[Commands-and-Plugins]]
|
||||
- [[MsgContext]]
|
||||
- [[Inline-Keyboards-and-Payloads]]
|
||||
@@ -1,5 +1,7 @@
|
||||
# Commands and Plugins
|
||||
|
||||
Russian version: [[Commands-and-Plugins-RU]]
|
||||
|
||||
Laniakea organizes most bot behavior through plugins.
|
||||
|
||||
If you understand how plugins, commands, payload handlers, and update handlers fit together, the rest of the library becomes much easier to reason about.
|
||||
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
# Drafts RU
|
||||
|
||||
English version: [[Drafts]]
|
||||
|
||||
Это краткая русскоязычная версия страницы про drafts. Полная и наиболее актуальная страница: [[Drafts]].
|
||||
|
||||
## Когда нужны drafts
|
||||
|
||||
Drafts полезны, когда ответ:
|
||||
- собирается постепенно;
|
||||
- должен быть отредактирован до финальной отправки;
|
||||
- выгодно держать как временное состояние, а не отправлять куски сразу.
|
||||
|
||||
Для обычного one-shot ответа чаще проще использовать `Answer(...)` или `AnswerLong(...)`.
|
||||
|
||||
## Главные части модели
|
||||
|
||||
Есть две основные сущности:
|
||||
- `Draft`
|
||||
- `DraftProvider`
|
||||
|
||||
Внутри handler'а самый удобный вход:
|
||||
- `ctx.NewDraft()`
|
||||
- `ctx.NewDraftMarkdown()`
|
||||
|
||||
## Базовый пример
|
||||
|
||||
```go
|
||||
draft := ctx.NewDraft()
|
||||
draft.Text("Line 1")
|
||||
draft.Text("Line 2")
|
||||
draft.Flush()
|
||||
```
|
||||
|
||||
Такой подход удобен, когда текст строится несколькими шагами.
|
||||
|
||||
## Lifecycle draft'а
|
||||
|
||||
Типичный flow такой:
|
||||
1. создать draft;
|
||||
2. добавлять текст и настройки;
|
||||
3. при необходимости делать `Push(...)` как промежуточную отправку;
|
||||
4. завершить через `Flush()`;
|
||||
5. при необходимости удалить через `Delete()`.
|
||||
|
||||
## `Push(...)` и `Flush()`
|
||||
|
||||
`Push(...)` полезен, когда нужно отправить промежуточное состояние, но draft остается рабочим.
|
||||
|
||||
`Flush()`:
|
||||
- отправляет финальное состояние;
|
||||
- очищает pending state у draft.
|
||||
|
||||
## `FlushAll()`
|
||||
|
||||
У provider есть `FlushAll()`.
|
||||
|
||||
Это best-effort операция:
|
||||
- provider пытается отправить все pending drafts;
|
||||
- ошибки одного draft не отменяют попытки для остальных.
|
||||
|
||||
## IDs и стратегии генерации
|
||||
|
||||
У draft provider есть стратегия ID generation.
|
||||
|
||||
Обычно по умолчанию используется random-подход.
|
||||
|
||||
Если нужны более предсказуемые или внешне совместимые ID, можно поставить свой provider.
|
||||
|
||||
## Markdown-вариант
|
||||
|
||||
`NewDraftMarkdown()` включает `MarkdownV2`.
|
||||
|
||||
Как и в остальных Markdown helper methods, пользовательский ввод надо экранировать отдельно.
|
||||
|
||||
## Что читать дальше
|
||||
|
||||
- [[MsgContext-RU]]
|
||||
- [[Bot-Lifecycle-RU]]
|
||||
- [[Drafts]]
|
||||
+2
@@ -1,5 +1,7 @@
|
||||
# Drafts
|
||||
|
||||
Russian version: [[Drafts-RU]]
|
||||
|
||||
Drafts provide a staged way to accumulate message text and send it later as a final message. They are useful when you want to build a response incrementally instead of sending each intermediate state directly to the chat.
|
||||
|
||||
## When drafts are useful
|
||||
|
||||
@@ -0,0 +1,92 @@
|
||||
# Error Handling RU
|
||||
|
||||
English version: [[Error-Handling]]
|
||||
|
||||
Это краткая русскоязычная версия страницы про centralized error flow. Полная и наиболее актуальная страница: [[Error-Handling]].
|
||||
|
||||
## Базовая идея
|
||||
|
||||
В Laniakea handlers возвращают `error`.
|
||||
|
||||
Это относится к:
|
||||
- command handlers;
|
||||
- payload handlers;
|
||||
- update handlers.
|
||||
|
||||
Если handler возвращает ошибку, bot:
|
||||
- форматирует user-facing текст через `ErrorTemplate(...)`;
|
||||
- отправляет этот текст пользователю;
|
||||
- логирует исходную ошибку через текущий logger.
|
||||
|
||||
## Как это выглядит
|
||||
|
||||
```go
|
||||
func ping(ctx *laniakea.MsgContext, db *App) error {
|
||||
ctx.Answer("pong")
|
||||
return nil
|
||||
}
|
||||
```
|
||||
|
||||
или:
|
||||
|
||||
```go
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
```
|
||||
|
||||
## Когда возвращать `error`
|
||||
|
||||
Возвращай `error`, когда:
|
||||
- хочешь единый стиль user-facing ошибок;
|
||||
- ошибка действительно exceptional;
|
||||
- хочешь централизованное логирование и formatting.
|
||||
|
||||
## Когда лучше ответить вручную
|
||||
|
||||
Лучше ответить вручную и вернуть `nil`, когда:
|
||||
- это обычная UX-ветка, а не реальная ошибка;
|
||||
- тебе нужен специальный ответ;
|
||||
- ты уже сам показал пользователю нужный текст.
|
||||
|
||||
Пример:
|
||||
|
||||
```go
|
||||
if !allowed {
|
||||
ctx.Answer("Access denied")
|
||||
return nil
|
||||
}
|
||||
```
|
||||
|
||||
## Callback-specific поведение
|
||||
|
||||
Для callback flow returned error превращается не в обычное сообщение в чат, а в ответ на callback query.
|
||||
|
||||
Если нужен другой UX, лучше:
|
||||
- вызвать `AnswerCbQueryText(...)` или `AnswerCbQueryAlert(...)`;
|
||||
- вернуть `nil`.
|
||||
|
||||
## `ErrorTemplate(...)`
|
||||
|
||||
Через `Bot.ErrorTemplate(...)` или `BotOpts.ErrorTemplate` можно настроить user-facing шаблон.
|
||||
|
||||
Пример:
|
||||
|
||||
```go
|
||||
bot.ErrorTemplate("Error\n\n%s")
|
||||
```
|
||||
|
||||
## Middleware и ошибки
|
||||
|
||||
Middleware не возвращает `error`, он возвращает `bool`.
|
||||
|
||||
Поэтому если middleware хочет остановить цепочку:
|
||||
- он сам показывает ответ;
|
||||
- возвращает `false`.
|
||||
|
||||
## Что читать дальше
|
||||
|
||||
- [[FAQ-RU]]
|
||||
- [[Logging-RU]]
|
||||
- [[Middleware-RU]]
|
||||
- [[Error-Handling]]
|
||||
@@ -1,5 +1,7 @@
|
||||
# Error Handling
|
||||
|
||||
Russian version: [[Error-Handling-RU]]
|
||||
|
||||
Laniakea uses error-returning handlers so command, payload, and update-handler failures can flow through one consistent mechanism. This page explains when to return errors, when to answer manually, and how `ErrorTemplate(...)` affects what users see.
|
||||
|
||||
## Overview
|
||||
|
||||
+7
-5
@@ -1,13 +1,15 @@
|
||||
# FAQ RU
|
||||
|
||||
English version: [[FAQ]]
|
||||
|
||||
Это краткая русскоязычная версия частых вопросов о дизайне Laniakea. Полная и наиболее актуальная страница: [[FAQ]].
|
||||
|
||||
## Почему handlers возвращают `error`?
|
||||
## Почему хендлеры возвращают `error`?
|
||||
|
||||
Чтобы ошибки проходили через единый, централизованный flow, а не обрабатывались вручную в каждом command или payload handler.
|
||||
|
||||
Это дает несколько плюсов:
|
||||
- handlers остаются проще;
|
||||
- хендлеры остаются проще;
|
||||
- user-facing error format можно контролировать через `ErrorTemplate(...)`;
|
||||
- command, payload и non-command update handlers используют один и тот же контракт.
|
||||
|
||||
@@ -52,7 +54,7 @@
|
||||
|
||||
## Когда использовать `MsgContext`, а когда `tgapi`?
|
||||
|
||||
Используй `MsgContext`, когда ты уже внутри handler'а и тебе нужен удобный reply/edit/delete flow с текущим chat, message и logger.
|
||||
Используй `MsgContext`, когда ты уже внутри хендлера и тебе нужен удобный reply/edit/delete flow с текущим chat, message и logger.
|
||||
|
||||
Используй `tgapi`, когда:
|
||||
- нужного helper method нет в `MsgContext`
|
||||
@@ -74,11 +76,11 @@
|
||||
|
||||
Поэтому `Close()` все равно нужен.
|
||||
|
||||
## Почему plugin нужно полностью настроить до `AddPlugins(...)`?
|
||||
## Почему `Plugin` нужно полностью настроить до `AddPlugins(...)`?
|
||||
|
||||
Потому что `AddPlugins(...)` — это configuration snapshot point.
|
||||
|
||||
После регистрации bot хранит внутреннюю копию plugin state, и изменения исходного `*Plugin` уже не считаются поддерживаемым API.
|
||||
После регистрации `Bot` хранит внутреннюю копию состояния плагина, и изменения исходного `*Plugin` уже не считаются поддерживаемым API.
|
||||
|
||||
До `AddPlugins(...)` стоит завершить:
|
||||
- commands
|
||||
|
||||
+2
@@ -1,5 +1,7 @@
|
||||
# FAQ
|
||||
|
||||
Russian version: [[FAQ-RU]]
|
||||
|
||||
This page collects recurring questions about why Laniakea behaves the way it does. It focuses on design choices that are easy to miss when you only look at examples.
|
||||
|
||||
## Why do handlers return `error`?
|
||||
|
||||
+20
-17
@@ -1,5 +1,7 @@
|
||||
# Getting Started RU
|
||||
|
||||
English version: [[Getting-Started]]
|
||||
|
||||
Начни с этой страницы, если ты впервые подключаешь Laniakea к новому боту. Это сокращенная русскоязычная версия старта. Полная и наиболее актуальная страница: [[Getting-Started]].
|
||||
|
||||
## Что нужно сначала
|
||||
@@ -60,13 +62,13 @@ func main() {
|
||||
|
||||
## Что важно понять сразу
|
||||
|
||||
### 1. `NewBot[T]` использует generic-тип зависимости
|
||||
### 1. `NewBot[T]` использует generic-параметр зависимости
|
||||
|
||||
Параметр `T` — это общий dependency context, который попадает в handlers, middleware и runners.
|
||||
Параметр `T` — это общий контекст зависимостей, который попадает в хендлеры, middleware и runners.
|
||||
|
||||
Используй:
|
||||
- `laniakea.NoDB`, если dependency injection не нужен
|
||||
- pointer type, например `*sql.DB`, `*Store` или `*App`, если общий state нужен
|
||||
- pointer type, например `*sql.DB`, `*Store` или `*App`, если нужен общий state
|
||||
|
||||
Пример:
|
||||
|
||||
@@ -85,14 +87,14 @@ if err != nil {
|
||||
bot.DatabaseContext(app)
|
||||
```
|
||||
|
||||
### 2. Команды живут внутри plugins
|
||||
### 2. Команды живут внутри плагинов
|
||||
|
||||
Обычный путь такой:
|
||||
|
||||
1. создать bot
|
||||
2. создать plugin
|
||||
3. добавить команды в plugin
|
||||
4. зарегистрировать plugin через `AddPlugins(...)`
|
||||
1. создать `Bot`
|
||||
2. создать `Plugin`
|
||||
3. добавить команды в `Plugin`
|
||||
4. зарегистрировать `Plugin` через `AddPlugins(...)`
|
||||
|
||||
Пример:
|
||||
|
||||
@@ -104,9 +106,9 @@ bot.AddPlugins(plugin)
|
||||
|
||||
Подробности: [[Commands-and-Plugins]]
|
||||
|
||||
### 3. Handlers возвращают `error`
|
||||
### 3. Хендлеры возвращают `error`
|
||||
|
||||
Сигнатура handler'а:
|
||||
Сигнатура хендлера:
|
||||
|
||||
```go
|
||||
func(ctx *laniakea.MsgContext, db T) error
|
||||
@@ -114,7 +116,7 @@ func(ctx *laniakea.MsgContext, db T) error
|
||||
|
||||
То есть:
|
||||
- на успехе возвращай `nil`
|
||||
- если хочешь централизованный error flow, возвращай `error`
|
||||
- если хочешь централизованный flow обработки ошибок, возвращай `error`
|
||||
|
||||
Пример:
|
||||
|
||||
@@ -160,9 +162,9 @@ defer bot.Close()
|
||||
1. Собрать `BotOpts`
|
||||
2. Вызвать `NewBot[T](opts)`
|
||||
3. Подключить database context, localization и другие настройки
|
||||
4. Создать plugins
|
||||
5. Добавить commands, payloads и middleware в plugins
|
||||
6. Зарегистрировать plugins через `AddPlugins(...)`
|
||||
4. Создать плагины
|
||||
5. Добавить команды, payloads и middleware в плагины
|
||||
6. Зарегистрировать плагины через `AddPlugins(...)`
|
||||
7. При необходимости вызвать `AutoGenerateCommands()`
|
||||
8. Вызвать `Run()` или `RunWithContext(...)`
|
||||
9. Закрыть bot через `Close()`
|
||||
@@ -173,13 +175,13 @@ defer bot.Close()
|
||||
|
||||
`NewBot(...)` вернет ошибку, если токен не настроен.
|
||||
|
||||
### Нет plugins
|
||||
### Нет плагинов
|
||||
|
||||
Запуск бота без зарегистрированных plugins невалиден.
|
||||
Запуск бота без зарегистрированных плагинов невалиден.
|
||||
|
||||
### Неожидание, что `ctx.Text` уже очищен от команды
|
||||
|
||||
Для message command flow:
|
||||
Для обычного command flow:
|
||||
- сообщение: `/echo hello world`
|
||||
- имя команды: `echo`
|
||||
- `ctx.Text`: `hello world`
|
||||
@@ -191,6 +193,7 @@ defer bot.Close()
|
||||
|
||||
## Куда идти дальше
|
||||
|
||||
- [[Commands-and-Plugins-RU]]
|
||||
- [[FAQ-RU]]
|
||||
- [[Getting-Started]]
|
||||
- [[Commands-and-Plugins]]
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
# Getting Started
|
||||
|
||||
Russian version: [[Getting-Started-RU]]
|
||||
|
||||
Start here if you are integrating Laniakea into a new bot for the first time.
|
||||
|
||||
This page covers the shortest path to a working bot, the minimum concepts you need to understand, and the most important defaults that affect startup and runtime behavior.
|
||||
|
||||
+43
-21
@@ -1,44 +1,66 @@
|
||||
# Laniakea Wiki RU
|
||||
|
||||
Это краткая русскоязычная точка входа в wiki Laniakea. Подробная и наиболее полная документация остается в основной англоязычной wiki, поэтому для глубоких API-деталей лучше переходить по ссылкам на соответствующие английские страницы.
|
||||
English version: [[Home]]
|
||||
|
||||
## С чего начать
|
||||
Это краткая русскоязычная точка входа в wiki Laniakea. Подробная и наиболее полная документация остается в англоязычной части wiki, поэтому за полным API-справочником лучше переходить по ссылкам на соответствующие английские страницы.
|
||||
|
||||
- [[Getting-Started-RU]]
|
||||
- [[FAQ-RU]]
|
||||
- [[Getting-Started]]
|
||||
- [[Commands-and-Plugins]]
|
||||
- [[MsgContext]]
|
||||
|
||||
## Что уже есть на русском
|
||||
## Старт здесь
|
||||
|
||||
- [[Getting-Started-RU]]
|
||||
- [[Bot-Options-and-Configuration-RU]]
|
||||
- [[Commands-and-Plugins-RU]]
|
||||
- [[MsgContext-RU]]
|
||||
- [[FAQ-RU]]
|
||||
|
||||
## Основные англоязычные страницы
|
||||
## Runtime и архитектура
|
||||
|
||||
Если нужен полный и актуальный reference, начни отсюда:
|
||||
- [[Bot-Lifecycle-RU]]
|
||||
- [[Middleware-RU]]
|
||||
- [[Runners-RU]]
|
||||
- [[Error-Handling-RU]]
|
||||
- [[Logging-RU]]
|
||||
|
||||
## Telegram API и взаимодействие
|
||||
|
||||
- [[Inline-Keyboards-and-Payloads-RU]]
|
||||
- [[tgapi-Overview-RU]]
|
||||
- [[Auto-Generated-Commands-RU]]
|
||||
- [[Rate-Limiting-RU]]
|
||||
- [[Drafts-RU]]
|
||||
- [[Localization-RU]]
|
||||
|
||||
## Практические страницы
|
||||
|
||||
- [[Recipes-RU]]
|
||||
- [[Testing-Bots-with-Laniakea-RU]]
|
||||
|
||||
## Миграция и сопровождение
|
||||
|
||||
- [[Migration-RU]]
|
||||
- [[Semver-and-Releases-RU]]
|
||||
- [[Page-Priority-RU]]
|
||||
- [[FAQ-RU]]
|
||||
|
||||
## Полный английский reference
|
||||
|
||||
Если нужен полный и наиболее свежий reference, смотри исходные англоязычные страницы:
|
||||
|
||||
- [[Getting-Started]]
|
||||
- [[Bot-Options-and-Configuration]]
|
||||
- [[Commands-and-Plugins]]
|
||||
- [[MsgContext]]
|
||||
- [[Bot-Lifecycle]]
|
||||
- [[Inline-Keyboards-and-Payloads]]
|
||||
- [[tgapi-Overview]]
|
||||
|
||||
## Практические и служебные страницы
|
||||
|
||||
- [[Recipes]]
|
||||
- [[Migration]]
|
||||
- [[Semver-and-Releases]]
|
||||
- [[Page-Priority]]
|
||||
|
||||
## Как использовать русскую wiki
|
||||
|
||||
Рекомендуемый маршрут для русскоязычного пользователя:
|
||||
|
||||
1. Прочитать [[Getting-Started-RU]].
|
||||
2. Посмотреть [[FAQ-RU]].
|
||||
3. Перейти в англоязычные страницы по нужной теме, если требуется полный reference.
|
||||
2. Прочитать [[Commands-and-Plugins-RU]] и [[MsgContext-RU]].
|
||||
3. Перейти в runtime-страницы вроде [[Bot-Lifecycle-RU]] и [[Middleware-RU]].
|
||||
4. При необходимости открыть специализированные страницы вроде [[Drafts-RU]], [[Rate-Limiting-RU]] или [[tgapi-Overview-RU]].
|
||||
5. Для максимальной точности переходить в соответствующую англоязычную страницу.
|
||||
|
||||
Это позволяет держать русскоязычный входной слой полезным, но не дублировать всю wiki целиком.
|
||||
Такой подход позволяет пользоваться русской wiki как полноценным слоем документации, но при этом при желании всегда уходить в англоязычный source of truth.
|
||||
|
||||
+2
@@ -1,5 +1,7 @@
|
||||
# Laniakea Wiki
|
||||
|
||||
Russian version: [[Home-RU]]
|
||||
|
||||
Laniakea is a Go framework and Telegram Bot API wrapper built around plugins, typed handlers, middleware, and explicit control over update and reply flow.
|
||||
|
||||
Use this wiki as the structured companion to the README: start with setup, then move through commands, context, keyboards, and lower-level API usage.
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
# Inline Keyboards and Payloads RU
|
||||
|
||||
English version: [[Inline-Keyboards-and-Payloads]]
|
||||
|
||||
Это краткая русскоязычная версия страницы про inline keyboards и callback payloads. Полная и наиболее актуальная страница: [[Inline-Keyboards-and-Payloads]].
|
||||
|
||||
## Главное сначала
|
||||
|
||||
- `InlineKeyboard` строит inline keyboard row by row;
|
||||
- callback button хранит `CallbackData` с command name и args;
|
||||
- payload может кодироваться как JSON или Base64;
|
||||
- у bot есть default payload type;
|
||||
- конкретная keyboard может переопределить его локально.
|
||||
|
||||
## Как строить keyboard
|
||||
|
||||
Основные конструкторы:
|
||||
- `NewInlineKeyboardJson(maxRow)`
|
||||
- `NewInlineKeyboardBase64(maxRow)`
|
||||
- `NewInlineKeyboard(payloadType, maxRow)`
|
||||
|
||||
Пример:
|
||||
|
||||
```go
|
||||
kb := laniakea.NewInlineKeyboardJson(2).
|
||||
AddCallbackButton("Open", "open", 42).
|
||||
AddCallbackButton("Delete", "delete", 42).
|
||||
AddUrlButton("Docs", "https://example.com/docs")
|
||||
```
|
||||
|
||||
`maxRow` определяет, сколько кнопок автоматически помещается в один ряд.
|
||||
|
||||
## Что такое payload
|
||||
|
||||
Callback payload логически содержит:
|
||||
- command name;
|
||||
- список string arguments.
|
||||
|
||||
Ты обычно не собираешь JSON вручную. Вместо этого используешь:
|
||||
- `AddCallbackButton(...)`
|
||||
- `AddCallbackButtonStyle(...)`
|
||||
- `NewCallbackData(...)`
|
||||
|
||||
Все аргументы через `fmt.Sprint` превращаются в строки, поэтому в handler'е ты читаешь их через `ctx.Args`.
|
||||
|
||||
## `ctx.Args`, а не `ctx.Payload`
|
||||
|
||||
В текущем API нет отдельного `ctx.Payload`.
|
||||
|
||||
В payload handler'е decoded args доступны через:
|
||||
- `ctx.Args`
|
||||
|
||||
А выбор handler'а происходит по имени payload command.
|
||||
|
||||
## JSON vs Base64
|
||||
|
||||
`BotPayloadJson`:
|
||||
- удобнее читать в логах и тестах;
|
||||
- проще дебажить.
|
||||
|
||||
`BotPayloadBase64`:
|
||||
- более компактный transport form;
|
||||
- выглядит более “непрозрачно” в callback data.
|
||||
|
||||
Логическая структура payload при этом одна и та же.
|
||||
|
||||
## Strict vs tolerant decoding
|
||||
|
||||
По умолчанию bot tolerant:
|
||||
- если основной decoder не сработал, может попробовать второй формат.
|
||||
|
||||
Strict mode отключает этот fallback:
|
||||
|
||||
```go
|
||||
bot.SetStrictPayloadType(true)
|
||||
```
|
||||
|
||||
или через `BotOpts`.
|
||||
|
||||
Это полезно, если payload-format drift нужно считать настоящей ошибкой.
|
||||
|
||||
## Keyboard-local override
|
||||
|
||||
Даже если у bot есть default payload type, keyboard можно переопределить локально:
|
||||
|
||||
```go
|
||||
kb := ctx.NewInlineKeyboard(2).
|
||||
SetPayloadType(laniakea.BotPayloadJson)
|
||||
```
|
||||
|
||||
Это удобно для migration или debugging-сценариев.
|
||||
|
||||
## `KeyboardLong(...)`
|
||||
|
||||
Если текст длинный, используй `KeyboardLong(...)`.
|
||||
|
||||
Keyboard прикрепляется только к последнему chunk, чтобы не дублировать кнопки на каждой части.
|
||||
|
||||
## Что читать дальше
|
||||
|
||||
- [[Commands-and-Plugins-RU]]
|
||||
- [[MsgContext-RU]]
|
||||
- [[Inline-Keyboards-and-Payloads]]
|
||||
@@ -1,5 +1,7 @@
|
||||
# Inline Keyboards and Payloads
|
||||
|
||||
Russian version: [[Inline-Keyboards-and-Payloads-RU]]
|
||||
|
||||
Inline keyboards in Laniakea are built explicitly: you choose a row width, add URL or callback buttons, and decide how callback payloads are encoded. The high-level goal is simple: keep button construction ergonomic while keeping payload routing predictable in handlers.
|
||||
|
||||
## The important model first
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
# Localization RU
|
||||
|
||||
English version: [[Localization]]
|
||||
|
||||
Это краткая русскоязычная версия страницы про `L10n`. Полная и наиболее актуальная страница: [[Localization]].
|
||||
|
||||
## Базовая модель
|
||||
|
||||
Localization в Laniakea строится вокруг `L10n`:
|
||||
- создаешь store с fallback language;
|
||||
- добавляешь переводы по ключам;
|
||||
- подключаешь store к bot через `AddL10n(...)`;
|
||||
- внутри handler'ов используешь `ctx.Translate(key)`.
|
||||
|
||||
## Как создать словарь
|
||||
|
||||
```go
|
||||
l10n := laniakea.NewL10n("en")
|
||||
```
|
||||
|
||||
Fallback language используется, когда:
|
||||
- у пользователя нет перевода для нужного key;
|
||||
- язык пользователя неизвестен;
|
||||
- для key нет конкретной локали, но есть fallback.
|
||||
|
||||
## Как добавлять переводы
|
||||
|
||||
```go
|
||||
l10n.AddDictEntry("greeting", laniakea.DictEntry{
|
||||
"en": "Hello",
|
||||
"ru": "Привет",
|
||||
})
|
||||
```
|
||||
|
||||
Ключи лучше делать семантическими:
|
||||
- `greeting`
|
||||
- `errors.denied`
|
||||
- `menu.settings`
|
||||
|
||||
## Порядок fallback
|
||||
|
||||
`L10n.Translate(lang, key)` ищет:
|
||||
1. exact match для `lang`;
|
||||
2. fallback language;
|
||||
3. сам `key`.
|
||||
|
||||
Поэтому отсутствие перевода не приводит к пустой строке.
|
||||
|
||||
## Подключение к bot
|
||||
|
||||
```go
|
||||
bot.AddL10n(l10n)
|
||||
```
|
||||
|
||||
После этого доступны:
|
||||
- `bot.L10n(lang, key)`
|
||||
- `ctx.Translate(key)`
|
||||
|
||||
Если вызвать `AddL10n(nil)`, bot залогирует warning и оставит текущий provider без изменений.
|
||||
|
||||
## `ctx.Translate(...)`
|
||||
|
||||
Это основной ergonomic helper внутри handler'ов.
|
||||
|
||||
Он:
|
||||
- берет language code из `ctx.From`, если он есть;
|
||||
- при необходимости использует fallback language;
|
||||
- возвращает `key`, если перевода нет.
|
||||
|
||||
## Потокобезопасность
|
||||
|
||||
`L10n` безопасен для concurrent use.
|
||||
|
||||
Также `AddDictEntry(...)` копирует входной `DictEntry`, поэтому внешняя мутация исходной map не переписывает store неожиданно.
|
||||
|
||||
## Что читать дальше
|
||||
|
||||
- [[Getting-Started-RU]]
|
||||
- [[Recipes-RU]]
|
||||
- [[Localization]]
|
||||
+3
-1
@@ -1,5 +1,7 @@
|
||||
# Localization
|
||||
|
||||
Russian version: [[Localization-RU]]
|
||||
|
||||
Localization in Laniakea is centered around `L10n`, a small key-based translation store with fallback behavior. It is designed to keep handler code simple: handlers ask for keys, and the bot resolves the best available translation for the current user.
|
||||
|
||||
## Overview
|
||||
@@ -77,7 +79,7 @@ From then on:
|
||||
- `bot.L10n(lang, key)` is available for manual lookups;
|
||||
- `MsgContext.Translate(key)` becomes the ergonomic handler-level helper.
|
||||
|
||||
If `AddL10n(nil)` is called, the bot logs a warning and keeps localization disabled.
|
||||
If `AddL10n(nil)` is called, the bot logs a warning and keeps the existing localization provider unchanged.
|
||||
|
||||
## `MsgContext.Translate`
|
||||
|
||||
|
||||
+95
@@ -0,0 +1,95 @@
|
||||
# Logging RU
|
||||
|
||||
English version: [[Logging]]
|
||||
|
||||
Это краткая русскоязычная версия страницы про logging. Полная и наиболее актуальная страница: [[Logging]].
|
||||
|
||||
## Какие logger layers есть
|
||||
|
||||
У Laniakea обычно есть несколько уровней логирования:
|
||||
- main bot logger;
|
||||
- optional request logger;
|
||||
- plugin loggers;
|
||||
- внутренние loggers у `tgapi.API` и `tgapi.Uploader`.
|
||||
|
||||
Они нужны для разных задач:
|
||||
- bot logger покрывает lifecycle и routing;
|
||||
- request logger пишет сырые updates;
|
||||
- plugin loggers помогают разделять логи по модулям;
|
||||
- API/uploader loggers полезны для low-level tracing.
|
||||
|
||||
## Main bot logger
|
||||
|
||||
Создается при `NewBot(...)`.
|
||||
|
||||
Используется для:
|
||||
- startup/shutdown сообщений;
|
||||
- runner и middleware warnings;
|
||||
- bot-level operational logs.
|
||||
|
||||
Получить можно через:
|
||||
|
||||
```go
|
||||
logger := bot.GetLogger()
|
||||
```
|
||||
|
||||
## Request logger
|
||||
|
||||
Включается через `BotOpts.UseRequestLogger`.
|
||||
|
||||
Он логирует raw updates после успешного `getUpdates`.
|
||||
|
||||
Это особенно полезно для:
|
||||
- debugging routing;
|
||||
- изучения реальной формы Telegram updates;
|
||||
- подготовки тестовых samples.
|
||||
|
||||
## Plugin loggers и `ctx.Logger`
|
||||
|
||||
У plugin может быть свой logger.
|
||||
|
||||
Если он есть, в handler'е `ctx.Logger` обычно указывает именно на него.
|
||||
|
||||
Если нет, `ctx.Logger` падает обратно на bot logger.
|
||||
|
||||
Из-за этого внутри handler'ов чаще всего правильнее использовать именно `ctx.Logger`.
|
||||
|
||||
## Debug mode
|
||||
|
||||
`Bot.Debug(true)` или `BotOpts.Debug`:
|
||||
- поднимает уровень логирования;
|
||||
- влияет на bot logger;
|
||||
- влияет на request logger;
|
||||
- влияет на уже зарегистрированные plugin loggers.
|
||||
|
||||
## File logging
|
||||
|
||||
Если включить:
|
||||
- `WriteToFile`
|
||||
- и при необходимости `LoggerBasePath`
|
||||
|
||||
бот может писать:
|
||||
- `main.log`
|
||||
- `requests.log`
|
||||
|
||||
Если создание file logger не удалось, bot не падает, а остается на stdout logging.
|
||||
|
||||
## `AddDatabaseLoggerWriter(...)`
|
||||
|
||||
Этот метод позволяет прикрепить writer, полученный из DB/shared context, сразу к нескольким logger layers.
|
||||
|
||||
Он добавляется в:
|
||||
- bot logger;
|
||||
- request logger;
|
||||
- API/uploader loggers;
|
||||
- уже зарегистрированные plugin loggers.
|
||||
|
||||
Важно:
|
||||
- сначала должен быть задан `DatabaseContext(...)`;
|
||||
- если хочешь, чтобы plugin loggers точно получили writer, вызывай метод после `AddPlugins(...)`.
|
||||
|
||||
## Что читать дальше
|
||||
|
||||
- [[Error-Handling-RU]]
|
||||
- [[Bot-Options-and-Configuration-RU]]
|
||||
- [[Logging]]
|
||||
+2
@@ -1,5 +1,7 @@
|
||||
# Logging
|
||||
|
||||
Russian version: [[Logging-RU]]
|
||||
|
||||
Laniakea has several logger layers: the main bot logger, an optional request logger, per-plugin loggers, and internal API or uploader loggers. This page explains how they are created, how they relate to each other, and where to customize them.
|
||||
|
||||
## Logger layers
|
||||
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
# Middleware RU
|
||||
|
||||
English version: [[Middleware]]
|
||||
|
||||
Это краткая русскоязычная версия страницы про middleware. Полная и наиболее актуальная страница: [[Middleware]].
|
||||
|
||||
## Зачем нужен middleware
|
||||
|
||||
Middleware позволяет запускать логику до command handlers, payload handlers и update handlers.
|
||||
|
||||
Это главное место для cross-cutting concerns:
|
||||
- auth checks;
|
||||
- request logging;
|
||||
- feature flags;
|
||||
- простая подготовка контекста;
|
||||
- side effects вроде analytics.
|
||||
|
||||
## Уровни middleware
|
||||
|
||||
Есть три уровня:
|
||||
- bot-level через `Bot.AddMiddleware(...)`;
|
||||
- plugin-level через `Plugin.AddMiddleware(...)`;
|
||||
- command/payload-level через `Command.Use(...)`.
|
||||
|
||||
Их удобно понимать так:
|
||||
- bot-level действует на весь bot;
|
||||
- plugin-level на один plugin;
|
||||
- command-level на одну конкретную command или payload.
|
||||
|
||||
## Порядок выполнения
|
||||
|
||||
Для commands и payloads порядок такой:
|
||||
1. bot middleware;
|
||||
2. plugin middleware;
|
||||
3. command/payload middleware;
|
||||
4. final handler.
|
||||
|
||||
Для update handlers:
|
||||
1. bot middleware;
|
||||
2. plugin middleware для каждого подходящего plugin;
|
||||
3. update handler.
|
||||
|
||||
## Synchronous middleware
|
||||
|
||||
Сигнатура:
|
||||
|
||||
```go
|
||||
func(ctx *laniakea.MsgContext, db T) bool
|
||||
```
|
||||
|
||||
Возвращает:
|
||||
- `true` — продолжать;
|
||||
- `false` — остановить текущую цепочку.
|
||||
|
||||
Это правильный вариант для:
|
||||
- access control;
|
||||
- required validation;
|
||||
- rate limiting gates;
|
||||
- любой логики, которая должна уметь реально остановить handler path.
|
||||
|
||||
## Asynchronous middleware
|
||||
|
||||
Можно включить `SetAsync(true)`.
|
||||
|
||||
Но это меняет semantics:
|
||||
- middleware идет в goroutine;
|
||||
- выполнение цепочки продолжается сразу;
|
||||
- `bool` return value игнорируется;
|
||||
- middleware получает копию `MsgContext`.
|
||||
|
||||
Поэтому async middleware подходит только для:
|
||||
- telemetry;
|
||||
- audit logs;
|
||||
- fire-and-forget notifications;
|
||||
- best-effort side effects.
|
||||
|
||||
Он не подходит для:
|
||||
- auth checks;
|
||||
- required validation;
|
||||
- логики, которая должна переписать `ctx` и повлиять на handler.
|
||||
|
||||
## Почему async middleware получает копию `MsgContext`
|
||||
|
||||
Так библиотека избегает очевидных data races между goroutine middleware и основной handler chain.
|
||||
|
||||
Практический вывод:
|
||||
- изменения `ctx` внутри async middleware не становятся canonical context для handler'а;
|
||||
- async middleware не может надежно остановить flow.
|
||||
|
||||
## Ordering
|
||||
|
||||
Только bot-level middleware имеет explicit sorting:
|
||||
- сначала по `order`;
|
||||
- потом по `name`.
|
||||
|
||||
Plugin-level и command-level middleware сохраняют insertion order.
|
||||
|
||||
## Частые ошибки
|
||||
|
||||
- Использовать async middleware для блокировки доступа.
|
||||
- Надеяться, что async middleware сможет изменить `ctx.Text` для handler'а.
|
||||
- Настраивать plugin middleware после `AddPlugins(...)`.
|
||||
- Оставлять middleware без внятного имени.
|
||||
|
||||
## Что читать дальше
|
||||
|
||||
- [[Commands-and-Plugins-RU]]
|
||||
- [[MsgContext-RU]]
|
||||
- [[Middleware]]
|
||||
@@ -1,5 +1,7 @@
|
||||
# Middleware
|
||||
|
||||
Russian version: [[Middleware-RU]]
|
||||
|
||||
Middleware lets you run logic before commands, payloads, and non-command update handlers. It is the main place for cross-cutting concerns such as access checks, request logging, feature flags, and lightweight context preparation.
|
||||
|
||||
## What middleware can do
|
||||
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
# Migration RU
|
||||
|
||||
English version: [[Migration]]
|
||||
|
||||
Это краткая русскоязычная версия страницы про миграцию между release candidates. Полная и наиболее актуальная страница: [[Migration]].
|
||||
|
||||
## Как пользоваться этой страницей
|
||||
|
||||
Используй ее как карту основных изменений между `rc`-версиями.
|
||||
|
||||
Особенно полезно смотреть вместе с:
|
||||
- [[Bot-Lifecycle-RU]]
|
||||
- [[Commands-and-Plugins-RU]]
|
||||
- [[Inline-Keyboards-and-Payloads-RU]]
|
||||
- [[Semver-and-Releases-RU]]
|
||||
|
||||
## Что важно помнить при апгрейде
|
||||
|
||||
- Сначала прочитай `CHANGELOG.md`.
|
||||
- Потом проверь runtime model, если затрагивались `Bot`, plugins или handlers.
|
||||
- После этого отдельно пройди по payloads, drafts и command generation, если используешь эти части API.
|
||||
|
||||
## Ключевые изменения последних `rc`
|
||||
|
||||
### `rc.12`
|
||||
|
||||
Главный смысл релиза:
|
||||
- handlers стали возвращать `error`;
|
||||
- появились long reply helpers;
|
||||
- появился strict payload mode.
|
||||
|
||||
Что обычно нужно менять:
|
||||
- перевести handlers на `error`-return signature;
|
||||
- если длинные ответы могли выходить за Telegram limit, перейти на `AnswerLong(...)` или `KeyboardLong(...)`;
|
||||
- если payload policy важна, решить, нужен ли strict mode.
|
||||
|
||||
### `rc.10`
|
||||
|
||||
Главные изменения:
|
||||
- `NewBot[T](opts)` теперь возвращает `(*Bot[T], error)`;
|
||||
- `Run()` и `RunWithContext(...)` возвращают `error`;
|
||||
- `AddPlugins(...)` стал configuration snapshot point.
|
||||
|
||||
Что обычно нужно менять:
|
||||
- добавить error handling после `NewBot`, `Run`, `RunWithContext`;
|
||||
- перестать мутировать plugins после регистрации.
|
||||
|
||||
### `rc.7`
|
||||
|
||||
На этой стадии заметно укрепился plugin lifecycle:
|
||||
- logger APIs;
|
||||
- shutdown hooks;
|
||||
- `Plugin.Close()`.
|
||||
|
||||
### `rc.4`
|
||||
|
||||
Ранние изменения в основном затрагивали общую структуру API и helper surface.
|
||||
|
||||
## Практическая стратегия миграции
|
||||
|
||||
1. Сначала собери проект.
|
||||
2. Исправь signature-level ошибки.
|
||||
3. Проверь runtime behavior: startup, shutdown, plugins.
|
||||
4. Отдельно прогоняй callbacks, middleware и long replies.
|
||||
5. Добавь regression tests под найденные переломы.
|
||||
|
||||
## Что читать дальше
|
||||
|
||||
- [[Semver-and-Releases-RU]]
|
||||
- [[FAQ-RU]]
|
||||
- [[Migration]]
|
||||
+2
@@ -1,5 +1,7 @@
|
||||
# Migration
|
||||
|
||||
Russian version: [[Migration-RU]]
|
||||
|
||||
Use this page when upgrading an existing bot between Laniakea release candidates. It focuses on migration-impacting API and behavior changes, especially the larger RC transitions that require code edits instead of just a rebuild.
|
||||
|
||||
## How to use this page
|
||||
|
||||
+131
@@ -0,0 +1,131 @@
|
||||
# MsgContext RU
|
||||
|
||||
English version: [[MsgContext]]
|
||||
|
||||
Это краткая русскоязычная версия страницы про `MsgContext`. Полная и наиболее актуальная страница: [[MsgContext]].
|
||||
|
||||
## Что такое `MsgContext`
|
||||
|
||||
`MsgContext` — это runtime object, который приходит в:
|
||||
- command handlers;
|
||||
- payload handlers;
|
||||
- middleware;
|
||||
- update handlers.
|
||||
|
||||
Через него ты получаешь:
|
||||
- incoming update;
|
||||
- текущее сообщение и отправителя;
|
||||
- parsed command/payload args;
|
||||
- helpers для reply, edit, delete, callback, drafts и localization.
|
||||
|
||||
## Поля, которые используются чаще всего
|
||||
|
||||
### `Text`
|
||||
|
||||
`ctx.Text` — это текст после имени команды.
|
||||
|
||||
Пример:
|
||||
- вход: `/echo hello world`
|
||||
- command: `echo`
|
||||
- `ctx.Text == "hello world"`
|
||||
|
||||
### `Args`
|
||||
|
||||
`ctx.Args` — tokenized версия `ctx.Text`.
|
||||
|
||||
Пример:
|
||||
- `ctx.Text == "hello world"`
|
||||
- `ctx.Args == []string{"hello", "world"}`
|
||||
|
||||
### `Msg`
|
||||
|
||||
`ctx.Msg` указывает на текущее Telegram message, если у текущего update оно есть.
|
||||
|
||||
Полезно для:
|
||||
- chat ID;
|
||||
- thread ID;
|
||||
- доступа к metadata исходного сообщения.
|
||||
|
||||
### `From` и `FromID`
|
||||
|
||||
`ctx.From` — текущий user, если он есть.
|
||||
|
||||
`ctx.FromID` — тот же ID, но уже вынесенный для удобства.
|
||||
|
||||
## Основные helper methods
|
||||
|
||||
### `Answer(...)`
|
||||
|
||||
Базовый helper для обычного текстового ответа.
|
||||
|
||||
### `AnswerLong(...)`
|
||||
|
||||
Используется, когда текст может превысить Telegram message limit.
|
||||
|
||||
Это отдельный API специально для явной multi-message semantics.
|
||||
|
||||
### `Keyboard(...)`
|
||||
|
||||
Отправляет текст вместе с inline keyboard.
|
||||
|
||||
### `KeyboardLong(...)`
|
||||
|
||||
Подходит для длинного текста, где keyboard должен остаться на последнем chunk.
|
||||
|
||||
## Markdown helpers
|
||||
|
||||
Есть `...Markdown` варианты:
|
||||
- `AnswerMarkdown(...)`
|
||||
- `KeyboardMarkdown(...)`
|
||||
- `EditCallbackMarkdown(...)`
|
||||
|
||||
Важно:
|
||||
- пользовательский ввод нужно экранировать через `EscapeMarkdownV2(...)`.
|
||||
|
||||
## Edit и delete helpers
|
||||
|
||||
Если у тебя уже есть `AnswerMessage`, его можно:
|
||||
- редактировать;
|
||||
- удалять;
|
||||
- менять caption.
|
||||
|
||||
Это удобно для progressive UX вроде “Working... -> Done”.
|
||||
|
||||
## Callback-specific helpers
|
||||
|
||||
В callback flow особенно полезны:
|
||||
- `EditCallback(...)`
|
||||
- `AnswerCbQuery()`
|
||||
- `AnswerCbQueryText(...)`
|
||||
- `AnswerCbQueryAlert(...)`
|
||||
- `AnswerCbQueryUrl(...)`
|
||||
- `CallbackDelete()`
|
||||
|
||||
Они покрывают most common callback UX без ручного хождения в `tgapi`.
|
||||
|
||||
## Drafts и localization
|
||||
|
||||
У `MsgContext` есть:
|
||||
- `NewDraft()`
|
||||
- `NewDraftMarkdown()`
|
||||
- `Translate(key)`
|
||||
|
||||
Это делает `MsgContext` основным ergonomic surface почти для всего handler-time кода.
|
||||
|
||||
## `NewInlineKeyboard(...)`
|
||||
|
||||
Внутри handler'ов keyboard обычно удобнее всего строить так:
|
||||
|
||||
```go
|
||||
kb := ctx.NewInlineKeyboard(2)
|
||||
```
|
||||
|
||||
Этот builder автоматически наследует текущую payload policy context'а.
|
||||
|
||||
## Что читать дальше
|
||||
|
||||
- [[Commands-and-Plugins-RU]]
|
||||
- [[Inline-Keyboards-and-Payloads-RU]]
|
||||
- [[Drafts-RU]]
|
||||
- [[Localization-RU]]
|
||||
- [[MsgContext]]
|
||||
@@ -1,5 +1,7 @@
|
||||
# MsgContext
|
||||
|
||||
Russian version: [[MsgContext-RU]]
|
||||
|
||||
`MsgContext` is the runtime object passed into command handlers, payload handlers, middleware, and update handlers.
|
||||
|
||||
It gives you access to:
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
# Page Priority RU
|
||||
|
||||
English version: [[Page-Priority]]
|
||||
|
||||
Это краткая русскоязычная версия maintenance-страницы про приоритеты wiki. Полная и наиболее актуальная страница: [[Page-Priority]].
|
||||
|
||||
## Зачем нужна эта страница
|
||||
|
||||
Когда wiki уже в целом заполнена, вопрос обычно не в том, “чего совсем нет”, а в том:
|
||||
- какие страницы важнее поддерживать свежими;
|
||||
- где чаще всего появляются расхождения с кодом;
|
||||
- что надо обновлять первым при API-изменениях.
|
||||
|
||||
## Самые приоритетные страницы
|
||||
|
||||
В первую очередь стоит поддерживать в актуальном состоянии:
|
||||
- `Getting-Started`
|
||||
- `Commands-and-Plugins`
|
||||
- `MsgContext`
|
||||
- `Bot-Lifecycle`
|
||||
- `Inline-Keyboards-and-Payloads`
|
||||
- `Bot-Options-and-Configuration`
|
||||
|
||||
Именно эти страницы чаще всего читают новички и именно они сильнее всего влияют на first-run experience.
|
||||
|
||||
## Средний приоритет
|
||||
|
||||
Далее идут страницы, которые важны для уже работающих пользователей:
|
||||
- `Middleware`
|
||||
- `Error-Handling`
|
||||
- `Runners`
|
||||
- `Localization`
|
||||
- `Rate-Limiting`
|
||||
- `Drafts`
|
||||
- `Logging`
|
||||
|
||||
## Более редкие, но все еще важные
|
||||
|
||||
- `Migration`
|
||||
- `Semver-and-Releases`
|
||||
- `Testing-Bots-with-Laniakea`
|
||||
- `tgapi-Overview`
|
||||
- `Auto-Generated-Commands`
|
||||
|
||||
Эти страницы не всегда нужны с первого дня, но становятся критичными при развитии проекта и релизном процессе.
|
||||
|
||||
## Практический maintenance-подход
|
||||
|
||||
При изменении кода сначала проверяй:
|
||||
1. страницы core API;
|
||||
2. страницы по runtime behavior;
|
||||
3. advanced и maintenance pages.
|
||||
|
||||
## Что читать дальше
|
||||
|
||||
- [[Home-RU]]
|
||||
- [[Page-Priority]]
|
||||
@@ -1,5 +1,7 @@
|
||||
# Page Priority
|
||||
|
||||
Russian version: [[Page-Priority-RU]]
|
||||
|
||||
This page tracks maintenance priority for the wiki now that the core page set is in place. Use it to decide where future edits, expansions, and API-alignment work should land first.
|
||||
|
||||
## Priority 1
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
# Rate Limiting RU
|
||||
|
||||
English version: [[Rate-Limiting]]
|
||||
|
||||
Это краткая русскоязычная версия страницы про rate limiting. Полная и наиболее актуальная страница: [[Rate-Limiting]].
|
||||
|
||||
## Где действует limiter
|
||||
|
||||
Rate limiting в Laniakea относится к Telegram API client layer.
|
||||
|
||||
Он влияет на исходящие запросы бота и помогает:
|
||||
- не превысить Telegram limits;
|
||||
- переживать bursts;
|
||||
- корректно обрабатывать `retry_after`.
|
||||
|
||||
## Основные режимы
|
||||
|
||||
Есть два общих режима поведения:
|
||||
- waiting mode;
|
||||
- drop mode.
|
||||
|
||||
В waiting mode запросы ждут своей очереди.
|
||||
|
||||
В drop mode overflow можно отклонять сразу, чтобы сохранить отзывчивость под нагрузкой.
|
||||
|
||||
## Ключевые настройки
|
||||
|
||||
Через `BotOpts` особенно важны:
|
||||
- `RateLimit`
|
||||
- `DropRLOverflow`
|
||||
|
||||
Это задает общий policy для API client'а, который bot строит внутри `NewBot(...)`.
|
||||
|
||||
## `retry_after`
|
||||
|
||||
Если Telegram отвечает `429 retry_after`, библиотека:
|
||||
- обновляет limiter state;
|
||||
- ждет нужное время;
|
||||
- повторяет запрос, если context не был отменен.
|
||||
|
||||
Это значит, что delayed delivery иногда нормальна и не обязательно означает поломку логики.
|
||||
|
||||
## Global и per-chat поведение
|
||||
|
||||
На практике limiter связан не только с глобальным потоком запросов, но и с chat-aware поведением в API layer.
|
||||
|
||||
Из-за этого важно думать не только о “сколько запросов в секунду вообще”, но и о burst behavior внутри одного chat flow.
|
||||
|
||||
## Когда дропать, а когда ждать
|
||||
|
||||
Обычно waiting mode лучше, когда:
|
||||
- важнее надежная доставка;
|
||||
- бот обрабатывает пользовательские команды, которые нельзя терять.
|
||||
|
||||
Drop mode может быть полезен, когда:
|
||||
- бот работает под очень высоким наплывом;
|
||||
- часть исходящих запросов допустимо потерять;
|
||||
- важнее быстрый ответ системы под перегрузкой.
|
||||
|
||||
## Практические советы
|
||||
|
||||
- Начинай с дефолтного rate limit.
|
||||
- Повышай `MaxWorkers` и rate limit только после реальных наблюдений.
|
||||
- Ожидай, что `retry_after` иногда будет нормальной частью жизни бота.
|
||||
|
||||
## Что читать дальше
|
||||
|
||||
- [[Bot-Options-and-Configuration-RU]]
|
||||
- [[tgapi-Overview-RU]]
|
||||
- [[Rate-Limiting]]
|
||||
@@ -1,5 +1,7 @@
|
||||
# Rate Limiting
|
||||
|
||||
Russian version: [[Rate-Limiting-RU]]
|
||||
|
||||
This page explains how Laniakea throttles outgoing Telegram API requests and how it reacts when Telegram answers with `429 Too Many Requests`. The built-in limiter is designed to protect both the global bot throughput and hot chats that might otherwise overwhelm the API.
|
||||
|
||||
## Overview
|
||||
|
||||
+62
@@ -0,0 +1,62 @@
|
||||
# Recipes RU
|
||||
|
||||
English version: [[Recipes]]
|
||||
|
||||
Это краткая русскоязычная версия страницы с практическими рецептами. Полная и наиболее актуальная страница: [[Recipes]].
|
||||
|
||||
## Зачем нужна эта страница
|
||||
|
||||
Если основные страницы объясняют модель библиотеки, то recipes показывают короткие копируемые паттерны для типовых задач.
|
||||
|
||||
## Полезные сценарии
|
||||
|
||||
### Admin-only command
|
||||
|
||||
Используй plugin middleware или command middleware, если команда должна быть доступна только ограниченной группе пользователей.
|
||||
|
||||
### Callback flow
|
||||
|
||||
Комбинируй:
|
||||
- `NewInlineKeyboard(...)`
|
||||
- payload handler;
|
||||
- `AnswerCbQuery...`;
|
||||
- `EditCallback(...)`
|
||||
|
||||
### Long reply
|
||||
|
||||
Если текст может быть длинным, используй `AnswerLong(...)` или `KeyboardLong(...)`, а не обычный `Answer(...)`.
|
||||
|
||||
### Localized command
|
||||
|
||||
Подключи `L10n` к bot и используй `ctx.Translate(...)` внутри handler'ов.
|
||||
|
||||
### Non-command update handler
|
||||
|
||||
Для `inline_query`, `poll`, `chat_member` и других update types используй `AddUpdateHandler(...)`.
|
||||
|
||||
### Draft-based flow
|
||||
|
||||
Если ответ строится постепенно, начни с `ctx.NewDraft()`.
|
||||
|
||||
### Upload через `tgapi`
|
||||
|
||||
Когда нужны multipart uploads или lower-level file APIs, выходи в `tgapi`.
|
||||
|
||||
### Strict payload mode
|
||||
|
||||
Если payload format mismatch должен считаться ошибкой, включай `SetStrictPayloadType(true)`.
|
||||
|
||||
## Как использовать recipes правильно
|
||||
|
||||
Recipes хороши как стартовые шаблоны, но не заменяют более подробные страницы про:
|
||||
- lifecycle;
|
||||
- middleware;
|
||||
- payload model;
|
||||
- testing.
|
||||
|
||||
## Что читать дальше
|
||||
|
||||
- [[Getting-Started-RU]]
|
||||
- [[Commands-and-Plugins-RU]]
|
||||
- [[Localization-RU]]
|
||||
- [[Recipes]]
|
||||
+2
@@ -1,5 +1,7 @@
|
||||
# Recipes
|
||||
|
||||
Russian version: [[Recipes-RU]]
|
||||
|
||||
This page collects short, task-focused examples for common bot patterns. Each recipe is intentionally small and copy-friendly, and you can combine them with the deeper pages such as [[Commands-and-Plugins]], [[Middleware]], and [[Inline-Keyboards-and-Payloads]].
|
||||
|
||||
## Admin-only command
|
||||
|
||||
+80
@@ -0,0 +1,80 @@
|
||||
# Runners RU
|
||||
|
||||
English version: [[Runners]]
|
||||
|
||||
Это краткая русскоязычная версия страницы про runners. Полная и наиболее актуальная страница: [[Runners]].
|
||||
|
||||
## Что такое runner
|
||||
|
||||
Runner — это background или one-time task, который живет рядом с bot runtime, но не относится к конкретному update handler.
|
||||
|
||||
Типичные use cases:
|
||||
- cleanup jobs;
|
||||
- maintenance tasks;
|
||||
- health checks;
|
||||
- startup warmups.
|
||||
|
||||
## Как создается runner
|
||||
|
||||
Основной конструктор:
|
||||
|
||||
```go
|
||||
runner := laniakea.NewRunner("cleanup", fn)
|
||||
```
|
||||
|
||||
Потом конфигурируются builder methods:
|
||||
- `Onetime(bool)`
|
||||
- `Async(bool)`
|
||||
- `Timeout(duration)`
|
||||
|
||||
## Основные режимы
|
||||
|
||||
### One-time sync
|
||||
|
||||
- выполняется один раз;
|
||||
- блокирует startup;
|
||||
- полезен для startup-critical работы.
|
||||
|
||||
### One-time async
|
||||
|
||||
- выполняется один раз;
|
||||
- стартует в goroutine;
|
||||
- не блокирует startup.
|
||||
|
||||
### Repeating async
|
||||
|
||||
- работает циклически;
|
||||
- использует ticker;
|
||||
- живет до `ctx.Done()`.
|
||||
|
||||
## Невалидная конфигурация
|
||||
|
||||
Повторяющийся synchronous runner считается невалидным и пропускается с warning.
|
||||
|
||||
Также repeating async runner без `Timeout(...)` пропускается.
|
||||
|
||||
## Когда стартуют runners
|
||||
|
||||
Runners стартуют из `RunWithContext(...)`, а не из `NewBot(...)`.
|
||||
|
||||
Это часть runtime phase, а не construction phase.
|
||||
|
||||
## Shutdown semantics
|
||||
|
||||
При graceful shutdown bot:
|
||||
- ждет one-time async runners;
|
||||
- ждет завершения background runners после того, как они заметят `ctx.Done()`.
|
||||
|
||||
Поэтому runner body должен завершаться reasonably promptly.
|
||||
|
||||
## Рекомендации
|
||||
|
||||
- Для periodic jobs используй repeating async runner с timeout.
|
||||
- Для startup-critical work используй one-time sync runner.
|
||||
- Не держи сложную бизнес-логику внутри runner body; лучше делегируй ее в обычные сервисы приложения.
|
||||
|
||||
## Что читать дальше
|
||||
|
||||
- [[Bot-Lifecycle-RU]]
|
||||
- [[Testing-Bots-with-Laniakea-RU]]
|
||||
- [[Runners]]
|
||||
+2
@@ -1,5 +1,7 @@
|
||||
# Runners
|
||||
|
||||
Russian version: [[Runners-RU]]
|
||||
|
||||
Runners are background or one-time tasks that start with the bot and live alongside update processing. They are useful for periodic cleanup, maintenance jobs, health checks, and startup work that belongs to the bot process but not to any single update handler.
|
||||
|
||||
## Overview
|
||||
|
||||
@@ -0,0 +1,57 @@
|
||||
# Semver and Releases RU
|
||||
|
||||
English version: [[Semver-and-Releases]]
|
||||
|
||||
Это краткая русскоязычная версия страницы про semver и release policy. Полная и наиболее актуальная страница: [[Semver-and-Releases]].
|
||||
|
||||
## Зачем нужна эта страница
|
||||
|
||||
Она объясняет, как в проекте понимать:
|
||||
- что считается public API;
|
||||
- что считается breaking change;
|
||||
- как выбирать target version;
|
||||
- как changelog и version file должны соотноситься.
|
||||
|
||||
## Что считается public API
|
||||
|
||||
Обычно сюда входят:
|
||||
- exported types и methods;
|
||||
- helper methods вроде `AnswerLong(...)`;
|
||||
- behavior, на который пользователи библиотеки разумно опираются;
|
||||
- documented runtime semantics.
|
||||
|
||||
## Что считается breaking change
|
||||
|
||||
Breaking change — это не только удаление функции.
|
||||
|
||||
Сюда же относятся:
|
||||
- несовместимые signature changes;
|
||||
- изменение runtime behavior, которое ломает существующий код;
|
||||
- удаление или переименование публичных helper methods;
|
||||
- изменение documented semantics без совместимого fallback.
|
||||
|
||||
## Как выбирать версию
|
||||
|
||||
Логика обычная semver:
|
||||
- patch для совместимых fixes;
|
||||
- minor для совместимых additions;
|
||||
- major для breaking changes.
|
||||
|
||||
Release candidates дополнительно обозначают нестабильную стадию развития API.
|
||||
|
||||
## Связь с changelog
|
||||
|
||||
При изменениях в main repository changelog должен отражать user-visible изменения и совпадать с version file.
|
||||
|
||||
Wiki-only изменения в `.wiki` в основной `CHANGELOG.md` не попадают.
|
||||
|
||||
## Практический вывод
|
||||
|
||||
- Не делай breaking changes без осознанного version decision.
|
||||
- Сначала определяй target version, потом меняй API.
|
||||
- Поддерживай changelog, tags и version file согласованными.
|
||||
|
||||
## Что читать дальше
|
||||
|
||||
- [[Migration-RU]]
|
||||
- [[Semver-and-Releases]]
|
||||
@@ -1,5 +1,7 @@
|
||||
# Semver and Releases
|
||||
|
||||
Russian version: [[Semver-and-Releases-RU]]
|
||||
|
||||
This page is for maintainers and contributors who need the project's release rules in one place. It complements `SEMVER.md`, the changelog, and the repository workflow rules in `AGENTS.md`.
|
||||
|
||||
## Sources of truth
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
# Testing Bots with Laniakea RU
|
||||
|
||||
English version: [[Testing-Bots-with-Laniakea]]
|
||||
|
||||
Это краткая русскоязычная версия страницы про тестирование. Полная и наиболее актуальная страница: [[Testing-Bots-with-Laniakea]].
|
||||
|
||||
## Почему библиотеку удобно тестировать
|
||||
|
||||
Laniakea хорошо тестируется обычными Go unit tests.
|
||||
|
||||
В репозитории уже используются паттерны вроде:
|
||||
- fake HTTP transport для `tgapi`;
|
||||
- direct tests для `MsgContext` helpers;
|
||||
- routing tests для commands и payloads;
|
||||
- runner tests.
|
||||
|
||||
## Что стоит тестировать в первую очередь
|
||||
|
||||
- public handler flows;
|
||||
- argument validation;
|
||||
- callbacks и payload decoding;
|
||||
- middleware behavior;
|
||||
- long replies;
|
||||
- startup/shutdown semantics;
|
||||
- migration-sensitive regressions.
|
||||
|
||||
## Тесты для `tgapi`
|
||||
|
||||
Для low-level API удобно подменять `http.Client` transport и проверять:
|
||||
- request body;
|
||||
- method name;
|
||||
- response parsing;
|
||||
- retry/error behavior.
|
||||
|
||||
## Тесты для handler logic
|
||||
|
||||
Для handler-level тестов обычно полезно:
|
||||
- собрать `MsgContext`;
|
||||
- вызвать handler напрямую;
|
||||
- проверить side effects и ответы.
|
||||
|
||||
## Тесты для routing
|
||||
|
||||
Отдельно полезно тестировать:
|
||||
- command matching;
|
||||
- payload matching;
|
||||
- middleware order;
|
||||
- изоляцию контекста между plugin chains.
|
||||
|
||||
## Тесты для runners
|
||||
|
||||
Для runners важно проверить:
|
||||
- какие режимы реально запускаются;
|
||||
- какие конфигурации скипаются;
|
||||
- как ведет себя shutdown.
|
||||
|
||||
## Практические советы
|
||||
|
||||
- Предпочитай table-driven tests там, где много сценариев.
|
||||
- Добавляй regression tests на найденные bugs.
|
||||
- Не ограничивайся только happy path.
|
||||
|
||||
## Что читать дальше
|
||||
|
||||
- [[Runners-RU]]
|
||||
- [[MsgContext-RU]]
|
||||
- [[Testing-Bots-with-Laniakea]]
|
||||
@@ -1,5 +1,7 @@
|
||||
# Testing Bots with Laniakea
|
||||
|
||||
Russian version: [[Testing-Bots-with-Laniakea-RU]]
|
||||
|
||||
Laniakea is very testable with ordinary Go tests. The repository itself already uses unit-style tests for handlers, context helpers, argument validation, long replies, runners, and request-shape assertions. This page collects the most useful testing patterns.
|
||||
|
||||
## What to test
|
||||
|
||||
@@ -0,0 +1,89 @@
|
||||
# tgapi Overview RU
|
||||
|
||||
English version: [[tgapi-Overview]]
|
||||
|
||||
Это краткая русскоязычная версия страницы про `tgapi`. Полная и наиболее актуальная страница: [[tgapi-Overview]].
|
||||
|
||||
## Что такое `tgapi`
|
||||
|
||||
`tgapi` — это low-level Telegram Bot API layer под высокоуровневым runtime Laniakea.
|
||||
|
||||
Используй его, когда нужен:
|
||||
- direct access к Telegram methods;
|
||||
- явный контроль над parameter structs;
|
||||
- uploads и downloads;
|
||||
- raw request building.
|
||||
|
||||
## Два главных клиента
|
||||
|
||||
- `tgapi.API` для JSON requests;
|
||||
- `tgapi.Uploader` для multipart uploads.
|
||||
|
||||
Это разделение специально сделано, чтобы JSON methods и file upload methods не смешивались в одну слишком размытую abstraction.
|
||||
|
||||
## Когда использовать `MsgContext`, а когда `tgapi`
|
||||
|
||||
Используй `MsgContext`, когда:
|
||||
- ты уже внутри handler'а;
|
||||
- нужен обычный reply/edit/delete/callback flow.
|
||||
|
||||
Используй `tgapi`, когда:
|
||||
- у `MsgContext` нет нужного helper method;
|
||||
- ты работаешь вне handler flow;
|
||||
- нужен lower-level control;
|
||||
- нужно работать с uploads/downloads напрямую.
|
||||
|
||||
## Typed methods first
|
||||
|
||||
Обычный `tgapi`-подход — использовать typed methods и typed params.
|
||||
|
||||
```go
|
||||
api := tgapi.NewAPI(tgapi.NewAPIOpts(token))
|
||||
defer api.Close()
|
||||
```
|
||||
|
||||
Это безопаснее и удобнее, чем вручную собирать raw requests.
|
||||
|
||||
## `APIOpts`
|
||||
|
||||
Через `NewAPIOpts(token)` можно настраивать:
|
||||
- HTTP client;
|
||||
- test server;
|
||||
- custom API URL;
|
||||
- limiter;
|
||||
- limiter drop mode.
|
||||
|
||||
## `API` и `Uploader`
|
||||
|
||||
`API` отвечает за:
|
||||
- JSON request encoding;
|
||||
- HTTP execution;
|
||||
- retry и limiter behavior;
|
||||
- response decoding.
|
||||
|
||||
`Uploader` отвечает за:
|
||||
- multipart file uploads;
|
||||
- методы, которым нужны binary bodies.
|
||||
|
||||
## `Close()` важен
|
||||
|
||||
У `API` и `Uploader` есть собственный lifecycle.
|
||||
|
||||
Если ты владеешь этими объектами напрямую, их надо закрывать явно.
|
||||
|
||||
Если ими владеет `Bot`, это делает `bot.Close()`.
|
||||
|
||||
## Downloads и low-level escape hatches
|
||||
|
||||
`tgapi` покрывает и file download flow, и raw request builders.
|
||||
|
||||
Это полезно, когда typed helper метода еще нет или нужен очень точный контроль.
|
||||
|
||||
Но в day-to-day bot code лучше оставаться на более высоком уровне, если он уже покрывает нужный кейс.
|
||||
|
||||
## Что читать дальше
|
||||
|
||||
- [[MsgContext-RU]]
|
||||
- [[Inline-Keyboards-and-Payloads-RU]]
|
||||
- [[Rate-Limiting-RU]]
|
||||
- [[tgapi-Overview]]
|
||||
@@ -1,5 +1,7 @@
|
||||
# tgapi Overview
|
||||
|
||||
Russian version: [[tgapi-Overview-RU]]
|
||||
|
||||
`tgapi` is the low-level Telegram Bot API layer used under Laniakea’s higher-level bot runtime. Use it when you need direct access to Telegram methods, explicit parameter structs, upload control, or raw request building that sits below plugins and `MsgContext` helpers.
|
||||
|
||||
## The important split first
|
||||
|
||||
Reference in New Issue
Block a user