Обзор плагинов
Система плагинов GramIO построена на том же механизме .extend(), который лежит в основе всего фреймворка. Каждый плагин компонуется чисто — плагины могут добавлять свойства контекста, регистрировать обработчики и встраиваться в жизненный цикл бота, и всё это с полным распространением типов в каждый последующий обработчик.
const bot = new Bot(token)
.extend(session()) // ctx.session теперь типизирован
.extend(scenes([...])) // ctx.scene теперь типизирован
.extend(i18n()) // ctx.i18n теперь типизирован
.on("message", (ctx) => {
ctx.session; // ✅
ctx.scene; // ✅
ctx.i18n; // ✅
});Официальные плагины
Scenes — @gramio/scenes
Многошаговые диалоговые потоки. Создавайте мастера, сценарии онбординга и многошаговые формы, где каждый шаг ожидает следующего сообщения от пользователя.
- Шаги типизированы: состояние передаётся между шагами
- Войти в сцену можно из любого обработчика; выйти или перейти к любому шагу
- Работает с session для сохранения состояния между перезапусками
const registerScene = new Scene("register")
.step("message", (ctx) => {
if (ctx.scene.step.firstTime) return ctx.send("Как вас зовут?");
return ctx.scene.update({ name: ctx.text });
})
.step("message", (ctx) =>
ctx.send(`Добро пожаловать, ${ctx.scene.state.name}!`),
);Session — @gramio/session
Постоянное состояние для каждого пользователя между сообщениями. Чтение и запись прозрачны — просто используйте ctx.session как обычный объект.
- По умолчанию в памяти; подключите любой адаптер хранилища
- Фабрика начального состояния полностью типизирована
- Отлично работает со Scenes для сохранения состояния сцены
const bot = new Bot(token).extend(
session({ initial: () => ({ count: 0, name: "" }) }),
);
bot.command("count", (ctx) => {
ctx.session.count++;
return ctx.send(`Счётчик: ${ctx.session.count}`);
});I18n — @gramio/i18n
TypeScript-нативная интернационализация с полной проверкой типов во время компиляции — без кодогенерации, без .ftl файлов. Переводы — это обычные TS-функции; ShouldFollowLanguage гарантирует, что каждая локаль совпадает с ключами и сигнатурами основного языка.
- Переводы — обычные функции: используйте
format/bold/и т.д. напрямую - Локаль для каждого пользователя из любого источника (база данных, session, Telegram
language_code) - Автодополнение ключей и типов аргументов в редакторе
- Поддержка Fluent
.ftlтакже доступна для сложных правил склонения
import {
defineI18n,
type LanguageMap,
type ShouldFollowLanguage,
} from "@gramio/i18n";
import { format, bold } from "gramio";
const en = {
welcome: (name: string) => format`Hello, ${bold(name)}!`,
} satisfies LanguageMap;
const ru = {
welcome: (name: string) => format`Привет, ${bold(name)}!`,
} satisfies ShouldFollowLanguage<typeof en>;
const i18n = defineI18n({ primaryLanguage: "en", languages: { en, ru } });
const bot = new Bot(token)
// строим t() для каждого запроса по локали пользователя
.derive((ctx) => ({
t: i18n.buildT(ctx.from?.language_code ?? "en"),
}));
bot.command("start", (ctx) =>
ctx.send(ctx.t("welcome", ctx.from?.firstName ?? "незнакомец")),
);Autoload — @gramio/autoload
Файловая регистрация обработчиков. Просто добавьте файл в src/commands/ — он зарегистрируется автоматически, без ручных импортов и центрального реестра.
- Паттерн glob настраивается (по умолчанию
src/commands/**/*.ts) - Каждый файл экспортирует функцию
(bot: Bot) => Botпо умолчанию - Отлично подходит для больших ботов, разбитых на множество файлов фич
// src/index.ts
const bot = new Bot(token).extend(autoload());
// src/commands/start.ts
export default (bot: Bot) => bot.command("start", (ctx) => ctx.send("Привет!"));Prompt — @gramio/prompt
Ожидаемые одиночные ответы. Задайте вопрос и await ответа пользователя в линейном, читаемом потоке — без конечных автоматов.
- Приостанавливает выполнение и возобновляет, когда пользователь отвечает
- Опциональный таймаут
- Естественно сочетается со Scenes для сложных потоков
bot.command("rename", async (ctx) => {
const reply = await ctx.prompt("Какое ваше новое имя?");
await ctx.send(`Имя обновлено: ${reply.text}`);
});Auto Retry — @gramio/auto-retry
Автоматическая обработка ограничений скорости Telegram. Когда Telegram отвечает retry_after, плагин прозрачно ждёт и повторяет запрос — без изменений в вашем коде.
- Автоматически обрабатывает ошибки
Too Many Requests(429) - Настраиваемое количество повторов и стратегия задержки
- Работает для рассылок, высоконагруженных ботов
const bot = new Bot(token).extend(autoRetry());
// Все вызовы API теперь повторяются автоматически при превышении лимитаAuto Answer Callback Query — @gramio/auto-answer-callback-query
Никогда не забывайте подтверждать callback query. Автоматически отвечает на все необработанные обновления callback_query — Telegram требует ответа в течение 10 секунд, иначе показывает ошибку.
const bot = new Bot(token).extend(autoAnswerCallbackQuery());
// Теперь каждое нажатие инлайн-кнопки автоматически подтверждаетсяMedia Cache — @gramio/media-cache
Загрузите файл один раз, используйте его file_id бесконечно. Прозрачно кэширует file_id загруженных медиа, чтобы Telegram не повторял загрузку одного файла при каждой отправке.
- Работает с любым бэкендом хранилища
- Снижает задержку при повторных отправках
- Прозрачен — никаких изменений в вызовах send
Media Group — @gramio/media-group
Агрегация обновлений медиагруппы. Telegram отправляет сообщения media_group как отдельные обновления. Этот плагин буферизует их и доставляет полную группу в ваш обработчик как одно событие.
bot.on("message", (ctx) => {
if (ctx.mediaGroup) {
// ctx.mediaGroup — полный массив элементов медиагруппы
ctx.send(`Получено ${ctx.mediaGroup.length} фото`);
}
});Pagination — @gramio/pagination
Типизированные постраничные инлайн-клавиатуры. Создавайте многостраничные списки с типобезопасными данными страниц, кнопками следующей/предыдущей и понятной логикой обработчиков.
const paginationData = new CallbackData("page").number("offset");
const keyboard = pagination({
data: paginationData,
total: items.length,
pageSize: 5,
current: offset,
});Views — @gramio/views
Шаблоны сообщений для переиспользования. Определите сообщение (текст + клавиатура + параметры) один раз и используйте везде, разделяя UI и логику.
JSX — @gramio/jsx
Пишите сообщения бота с использованием JSX. Используйте привычный синтаксис в стиле React для составления сообщений с форматированием.
bot.command("start", (ctx) =>
ctx.send(<b>Привет!</b> <i>Добро пожаловать в моего бота.</i>)
);PostHog — @gramio/posthog
Аналитика для вашего бота. Отслеживайте команды пользователей, события и поведение в PostHog с автоматической фиксацией событий.
OpenTelemetry — @gramio/opentelemetry
Распределённая трассировка. Инструментируйте бота с помощью OpenTelemetry для полной наблюдаемости — трассирует каждый вызов API, обработчик и хук.
Sentry — @gramio/sentry
Мониторинг ошибок. Автоматически перехватывает необработанные ошибки и отправляет их в Sentry с контекстом (тип обновления, ID пользователя и т.д.).
Split — @gramio/split
Маршрутизация нескольких экземпляров. Распределяйте входящие обновления между несколькими экземплярами бота или воркерами для высокопроизводительных сценариев.
Какой плагин мне нужен?
| Сценарий | Используйте |
|---|---|
| Многошаговые формы / мастера | Scenes |
| Хранение настроек / состояния пользователя | Session |
| Мультиязычный бот | I18n |
| Большой бот с множеством файлов команд | Autoload |
| Задать вопрос, ждать ответа | Prompt |
| Автоматическая обработка ограничений скорости | Auto Retry |
| Избежать ошибок неподтверждённых callback | Auto Answer Callback Query |
| Избежать повторной загрузки одних файлов | Media Cache |
| Обработка сообщений альбома/медиагруппы | Media Group |
| Пагинированные списки с инлайн-кнопками | Pagination |
| Отслеживание событий и воронок пользователей | PostHog |
| Мониторинг ошибок в продакшене | Sentry |
| Распределённая трассировка / наблюдаемость | OpenTelemetry |
Комбинирование плагинов
Плагины компонуются — подключайте столько, сколько нужно, и типы остаются корректными везде:
const bot = new Bot(token)
.extend(session({ initial: () => ({ locale: "ru", name: "" }) }))
.extend(i18n())
.extend(scenes([registerScene]))
.extend(autoAnswerCallbackQuery())
.extend(autoRetry());
// В любом обработчике: ctx.session, ctx.i18n, ctx.scene — все типизированы ✅Напишите свой плагин
Любой Composer можно упаковать как плагин. Класс Plugin добавляет имя и чистый интерфейс .extend().
import { Plugin } from "gramio";
export const myPlugin = new Plugin("my-plugin").derive((ctx) => ({
isAdmin: ctx.from?.id === ADMIN_ID,
}));
// В боте:
bot.extend(myPlugin);
// ctx.isAdmin теперь типизирован везде ✅