REPOSITORY / ScuroNeko/Laniakea

Wiki

KNOWLEDGE REPOSITORY
6
Commands and Plugins RU
ScuroNeko edited this page 2026-05-20 13:28:29 +03:00
This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

Commands and Plugins RU

English version: Commands-and-Plugins

Это краткая русскоязычная версия страницы про архитектуру Bot, Plugin, команды, данные callback и обработчики обновлений. Полная и наиболее актуальная страница: Commands-and-Plugins.

Главное сначала

Обычная модель в Laniakea такая:

  • Bot управляет выполнением, polling, логированием и API-клиентами;
  • Plugin группирует связанную функциональность;
  • команды обрабатывают текстовые команды вроде /start;
  • обработчики данных callback обрабатывают callback data от inline-кнопок;
  • обработчики обновлений обрабатывают остальные типы обновлений вне обычного потока команд и callback.

Для большинства ботов стартовая структура выглядит так:

  • один или несколько плагинов;
  • несколько команд;
  • middleware плагина для общих проверок;
  • обработчики данных callback, когда появляются inline-кнопки.

Что такое Plugin

Плагин — это именованная группа:

  • команд;
  • обработчиков данных callback;
  • обработчиков обновлений;
  • общих middleware;
  • необязательного логгера и OnClose-хука.

Пример:

plugin := laniakea.NewPlugin[laniakea.NoData]("admin")

Обычно плагины удобно делить по смыслу:

  • admin
  • payments
  • profile
  • support

Так проще держать границы ответственности и не превращать весь бот в один большой registry-файл.

Обработчики команд

Сигнатура обработчика команды такая:

func(ctx *laniakea.MessageContext, db T) error

Где:

  • ctx — текущий MessageContext;
  • db — значение generic-параметра T, которое ты передал в Bot.

Возвращай:

  • nil, если все прошло успешно;
  • error, если хочешь отдать ошибку в централизованный поток обработки ошибок.

Пример:

func start(ctx *laniakea.MessageContext, db *App) error {
	ctx.Answer("Welcome")
	return nil
}

Как регистрировать команды

Самый обычный путь:

plugin := laniakea.NewPlugin[*App]("main")
plugin.Command("start", start)

Важно:

  • в имени команды не нужно писать /;
  • "start" матчится с /start;
  • "help" матчится с /help.

Что приходит в ctx.Text и ctx.Args

Для команды:

/echo hello world

в обработчике будет:

  • ctx.Text == "hello world"
  • ctx.Args == []string{"hello", "world"}

Это удобно, потому что текст команды уже очищен от префикса и имени команды.

Валидация аргументов команды

Для commands можно описывать аргументы через CommandArg.

Пример:

plugin.Command(
	"ban",
	banUser,
	laniakea.NewCommandArg("user_id").
		SetValueType(laniakea.CommandValueInt).
		SetRequired(),
)

Это позволяет валидировать:

  • наличие обязательных аргументов;
  • базовый тип вроде int или string;
  • regex-ограничения через конфигурацию аргумента.

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

Обработчики данных callback

Обработчики данных callback нужны для callback data от inline-кнопок.

Пример:

func confirmDelete(ctx *laniakea.MessageContext, db *App) error {
	ctx.EditCallback("Deleted", nil)
	return nil
}

plugin.Payload("delete.confirm", confirmDelete)

Важно помнить:

  • обработчик данных callback использует ту же сигнатуру, что и обработчик команды;
  • аргументы разобранных данных callback попадают в ctx.Args;
  • это не текстовая команда, а callback от кнопки.

Подробности: Inline-Keyboards-and-Payloads

Обработчики обновлений

Обработчики обновлений нужны для типов обновлений вне обычного потока команд и callback.

Пример:

plugin.AddUpdateHandler(tgapi.UpdateTypeInlineQuery, func(ctx *laniakea.MessageContext, db *App) error {
	return nil
})

Это правильный инструмент для вещей вроде:

  • inline_query
  • chosen_inline_result
  • poll
  • chat_member

Но есть важное исключение:

  • message
  • channel_post
  • callback_query

не должны идти через AddUpdateHandler(...), потому что они уже обслуживаются обычным потоком команд и callback.

Как выглядит поток выполнения

Для текстовой команды поток примерно такой:

  1. Приходит Telegram update.
  2. Bot готовит MessageContext.
  3. Выполняется middleware бота.
  4. Находится подходящий плагин.
  5. Выполняется middleware плагина.
  6. Выполняется валидация аргументов.
  7. Выполняется middleware команды.
  8. Запускается обработчик.
  9. Если обработчик вернул ошибку, она идет в централизованный поток обработки ошибок.

Для потока данных callback идея та же самая, только запуск происходит не из текста сообщения, а из разобранных callback data.

Где использовать middleware

Есть два основных уровня:

Middleware плагина

Добавляется через:

plugin.AddMiddleware(...)

Подходит для общей логики внутри одного плагина:

  • проверки доступа;
  • ограничение частоты;
  • общее логирование;
  • общие предусловия.

Middleware команды

Добавляется через:

plugin.Command("name", handler).Use(middleware)

Подходит, когда проверка нужна только одной команде или одному обработчику данных callback.

Подробности: Middleware

Частые ошибки

Добавлять / в имя команды

Неправильно:

plugin.Command("/start", start)

Правильно:

plugin.Command("start", start)

Считать данные callback обычной командой

Обработчик данных callback вызывается не из текста сообщения, а из callback data кнопки.

Использовать AddUpdateHandler(...) для message или callback_query

Эти типы обновлений относятся к обычному потоку команд и callback.

Возвращать error там, где это просто обычная ветка UX

Если пользователю надо просто показать usage или denial message, часто лучше сделать так:

ctx.Answer("Usage: /ban <id>")
return nil

Когда использовать что

Используй:

  • команды для slash-команд;
  • обработчики данных callback для callback кнопок;
  • обработчики обновлений для остальных Telegram updates;
  • middleware плагина для общих проверок;
  • middleware команды для локальных, узких проверок.

Что читать дальше