Тестирование стало богаче, CallbackData — надёжнее, TypeScript API Reference запущен
18–22 февраля 2026
Насыщенная неделя по всей экосистеме GramIO. @gramio/test v0.3.0 — 9 новых методов: editMessage, forwardMessage, sendMediaGroup, pinMessage, clickByText, три новых медиа-метода, ChatObject.post() для ботов в каналах, а также хелперы env.clearApiCalls() и env.lastApiCall(). @gramio/callback-data v0.1.0 вводит safeUnpack() — типизированный распаковщик, который никогда не бросает исключений, — и делает добавление optional-полей в существующие схемы полностью обратно совместимым. Новый пакет @gramio/schema-parser заменяет Rust-крейт tg-bot-api в основе @gramio/types: теперь есть точные InputFile | string-юнионы, семантические маркеры типов, синтезированный enum Currencies с XTR, и ранее отсутствовавшие типы APIResponse*. Из неопубликованного: @gramio/composer получает filter-only .on() с автоопределением CompatibleEvents<TEventMap, Narrowing> и типизированный Patch-дженерик для use(); сам gramio — filter-only перегрузки .on() и полноценную библиотеку предикатов filters.* с сужением через forwardOrigin(type?) и senderChat(type?). Документационный рывок не меньше: полный TypeDoc API Reference по /api/, 200+ страниц методов Telegram Bot API по /telegram/, новый Cheat Sheet, страницы JSX и Split-плагинов, интерактивные визуализаторы middleware и рассылок, production-архитектурное руководство по Composer, расширенные docs по сессиям и антипаттернам форматирования, и глобальная кнопка копирования в Markdown на каждой странице.
@gramio/test v0.3.0 — больше акторов, больше действий
9 новых методов: правка, пересылка, закрепление, медиагруппа и clickByText
Библиотека для тестирования серьёзно выросла. Вот что появилось:
user.editMessage(msg, text) — отправляет событие edited_message. Тестируйте обработчики редактирования без лишнего кода:
const msg = await user.sendMessage("Привет");
await user.editMessage(msg, "Привет, мир!");
expect(env.apiCalls[0].method).toBe("editMessageText");user.forwardMessage(msg, toChat?) — отправляет событие message с заполненным forward_origin. Удобно для тестирования логики определения пересланных сообщений:
const msg = await user.sendMessage("Оригинальное сообщение");
await user.forwardMessage(msg, group); // переслано в группуuser.sendMediaGroup(chat, payloads[]) — отправляет несколько событий message с одним media_group_id. Для тестирования обработки альбомов:
await user.sendMediaGroup(group, [
{ photo: {} },
{ video: {} },
]);user.pinMessage(msg, inChat?) — отправляет служебное сообщение с pinned_message. GramIO направляет такие сообщения в событие "pinned_message":
const msg = await user.sendMessage("Важное объявление");
await user.pinMessage(msg);user.on(msg).clickByText(buttonText) — ищет в inline_keyboard кнопку с нужным текстом и кликает на её callback_data. Выбрасывает исключение, если кнопка не найдена:
// (бот ответил сообщением с кнопками "Да" и "Нет")
await user.on(botReply).clickByText("Да");Три новых медиа-метода: sendAudio(), sendAnimation(), sendVideoNote() — с автогенерацией file_id и тем же API, что и у остальных медиа-методов:
await user.sendAudio({ caption: "Отличный трек" });
await user.sendAnimation(group, { caption: "Смешная гифка" });
await user.sendVideoNote(); // кружочекChatObject.post(text) — отправляет событие channel_post (без поля from) для тестирования ботов в каналах:
const channel = env.createChat({ type: "channel", title: "Мой канал" });
await channel.post("Новый пост из канала");env.clearApiCalls() и env.lastApiCall()
Два новых хелпера для чистых проверок:
// Сбросить лог вызовов между фазами теста
env.clearApiCalls();
// Получить последний вызов для конкретного метода
const lastSend = env.lastApiCall("sendMessage");
expect(lastSend?.params.text).toBe("Добро пожаловать!");@gramio/callback-data v0.1.0 — safeUnpack() и обратно-совместимые схемы
safeUnpack() — больше не падаем на устаревших кнопках
Кнопки инлайн-клавиатуры живут в истории чата днями и неделями. Если схема изменилась, unpack() падает на старых данных. Новый safeUnpack() никогда не бросает исключение — вместо этого возвращает дискриминированный union.
Важно: Если вы используете
bot.callbackQuery(schema, handler), распаковка происходит автоматически — вctx.queryDataуже есть типизированные данные,safeUnpackне нужен. Метод полезен при обработкеcallback_queryчерезbot.on()или когда нужно поддерживать несколько версий схемы в одном обработчике.
const data = new CallbackData("action").number("id").string("type");
// Нужен только вне bot.callbackQuery() — например, в общем catch-all обработчике
bot.on("callback_query", (ctx) => {
const result = data.safeUnpack(ctx.data ?? "");
if (!result.success) {
// кнопка из старой версии схемы
return ctx.answerCallbackQuery({ text: "Эта кнопка устарела!" });
}
ctx.answerCallbackQuery({ text: `ID: ${result.data.id}` }); // типизировано
});Тип SafeUnpackResult<T> экспортируется для использования в собственных type guard-ах.
Добавление optional-полей теперь обратно совместимо
Раньше любое добавление поля в схему — даже optional — ломало уже упакованные строки. Теперь, если данные упакованы без битмаски, все optional-поля считаются отсутствующими (значение undefined или дефолтное). Добавление optional-полей в конец схемы стало безопасной операцией:
// v1 схема (строки уже есть в истории чата)
const v1 = new CallbackData("page").number("id");
// v2 схема — добавление optional-поля безопасно!
const v2 = new CallbackData("page")
.number("id")
.string("tab", { optional: true }); // новое поле
// Старые v1-строки нормально распаковываются в v2
const result = v2.safeUnpack(v1PackedString);
// result.success === true, result.data.tab === undefinedОпасные операции (добавление required-поля, смена порядка, переименование nameId) по-прежнему остаются breaking change-ами.
@gramio/schema-parser v1.0.1 — новый движок схем
Новый TypeScript-пакет для парсинга HTML-документации Telegram Bot API в структурированную типизированную схему. Питает @gramio/types — заменяя прежнюю зависимость от Rust-крейта tg-bot-api.
Схема поддерживает:
- Семантические маркеры —
semanticType: "formattable"для текстовых полей,"markup"для объектов клавиатур,"updateType"для типов контекста - Определение загрузки файлов — string-поля, принимающие файлы, становятся
InputFile | string-юнионами - Enum валют — синтезируется из
currencies.jsonTelegram сXTR(Telegram Stars) - Правильные const-значения — булевые литералы
true/falseвместо строк - Поддержка oneOf — union-типы с ссылками и описаниями
@gramio/types v9.4.2 — нативная схема, улучшенная семантика
Пакет переехал с tg-bot-api (Rust-крейт) на @gramio/schema-parser (TypeScript). Генерируемый вывод теперь содержит:
- Более точные
InputFile | string-юнионы для параметров загрузки файлов - Formattable-поля правильно типизированы через семантические маркеры
- Enum
Currenciesсо всеми поддерживаемыми валютами, включаяXTRдля Stars - Типы
APIResponse,APIResponseOk,APIResponseError(раньше отсутствовали)
@gramio/composer — Filter-Only .on() и CompatibleEvents (в разработке)
Новые возможности приземлились в ветке main репозитория composer вместе с работой над системой фильтров gramio:
Filter-only .on() в Composer
Composer теперь поддерживает вызов .on(filter, handler) без имени события. Утилитарный тип CompatibleEvents<TEventMap, Narrowing> автоматически определяет, какие события содержат все ключи, до которых сужает предикат:
// Type-narrowing предикат — Composer сам находит совместимые события
app.on(
(ctx): ctx is { text: string } => typeof ctx.text === "string",
(ctx) => {
ctx.text; // string — сужено, обработчик срабатывает только на событиях с .text
}
);Patch-дженерик в use()
use<Patch extends object>(handler) теперь принимает type parameter для локального расширения контекста без изменения TOut для downstream middleware:
app.use<{ requestId: string }>((ctx, next) => {
ctx.requestId = crypto.randomUUID();
return next();
});gramio — новая система фильтров (в разработке)
В релиз ещё не попало, но на main уже приземлилось:
Перегрузки filter-only .on()
.on() теперь принимает просто предикат — без указания имени события. GramIO сам определяет совместимые события из type-narrowing предиката:
// Type-narrowing предикат — сужает тип контекста в обработчике
bot.on((ctx): ctx is { text: string } => typeof ctx.text === "string", (ctx) => {
ctx.text; // string (не string | undefined)
});Новые фильтры по свойствам сообщения
Standalone-предикаты для сужения типов в обработчиках:
import { filters } from "gramio";
bot.on("message", filters.reply, (ctx) => {
ctx.replyToMessage; // гарантированно присутствует
});
bot.on("message", filters.entities, handler); // есть entities
bot.on("message", filters.quote, handler); // цитата
bot.on("message", filters.isBot, handler); // отправитель — бот
bot.on("message", filters.isPremium, handler); // есть PremiumforwardOrigin() и senderChat() как callable-перегрузки
Раньше были отдельными фильтрами, теперь — единая callable-перегрузка с опциональным сужением типа:
// Сужает до сообщений, пересланных от пользователя
bot.on("message", filters.forwardOrigin("user"), (ctx) => {
ctx.forwardOrigin; // MessageOriginUser — полностью типизировано
});
// Без аргумента — матчит любое пересланное сообщение
bot.on("message", filters.forwardOrigin(), handler);Документация
Запущен TypeScript API Reference по адресу /api/
Полный TypeDoc-справочник доступен по адресу /api/. Охватывает все основные и плагиновые пакеты — gramio, @gramio/contexts, @gramio/types, @gramio/keyboards, @gramio/callback-data, @gramio/composer и дюжину плагинов. Сайдбар генерируется автоматически и выпрямляет пути внутренних модулей.
Справочник Telegram Bot API — 200+ методов по адресу /telegram/
Более 200 методов и типов Telegram Bot API теперь имеют отдельные страницы. На каждой — примеры использования с GramIO, таблицы параметров (с ограничениями, типами, значениями enum и пометками required/optional), таблицы ошибок и перекрёстные ссылки на связанные методы. Компонент ApiParam рендерит встроенные значки типов со ссылками на связанные типы Telegram. Кликабельные значки типов, курсивные литералы True/False, составные значки и аннотации docsLink для перекрёстных ссылок Files/Keyboards/Formattable добавлены в этом цикле (da3a4eb, 526b4db, b2167cc).
Страница Cheat Sheet
Быстрый справочник теперь доступен в навигации по адресу /cheat-sheet. Распространённые паттерны GramIO в одном месте — не нужно искать нужную сигнатуру по нескольким страницам руководств.
Документация JSX-плагина
Новая страница /plugins/official/jsx посвящена плагину @gramio/jsx — форматирование текста, построение inline- и reply-клавиатур через JSX, примеры использования на двух языках.
Расширена документация Split-плагина
Страница @gramio/split по адресу /plugins/official/split теперь включает полные шаги установки, детальный справочник API, объяснение механики разбиения entity, примеры кастомных лимитов и паттерны использования без привязки к конкретному фреймворку.
Интерактивный визуализатор middleware-пайплайна
В руководство по middleware добавлен интерактивный компонент UpdatePipelineVisualizer — выбирайте типы апдейтов, симулируйте debug-режим и наблюдайте, как контекст проходит по цепочке, в реальном времени.
Документация rate limits — BroadcastVisualizer и детальный разбор
Страница ограничений частоты запросов обновилась: добавлен компонент BroadcastVisualizer и детальный разбор механики HTTP 429, антипаттернов рассылки (наивный цикл for) и сравнение простого цикла vs @gramio/broadcast vs BullMQ — с диаграммами времени.
Руководство по production-архитектуре @gramio/composer
Справочник по composer теперь охватывает механику Named Composer deduplication, внутреннее устройство isolation group, паттерны scoped/global propagation и подводные камни dedup/shared-data. Включён пример production-архитектуры с withUser/router assembly (bcc0c8f).
Антипаттерны форматирования
В руководство по форматированию добавлены критические правила:
// ❌ НЕПРАВИЛЬНО — никогда не используйте parse_mode вместе с @gramio/format
ctx.send({ text: format`${bold("привет")}`, parse_mode: "HTML" });
// ❌ НЕПРАВИЛЬНО — никогда не делайте .join() из массива Formattable (теряются offset)
[bold("а"), italic("б")].join(", ");
// ✅ ПРАВИЛЬНО — используйте хелпер join() из @gramio/format
import { join } from "gramio";
join([bold("а"), italic("б")], ", ");Расширена документация плагина Session
Документация сессий теперь включает ленивую загрузку, $clear() для удаления сессии, функции кастомных ключей для разграничения по чату/пользователю и явную типизацию для обоих режимов — eager и lazy.
Кнопки «Скопировать / Скачать как Markdown» на каждой странице
Компонент CopyOrDownloadAsMarkdownButtons теперь зарегистрирован глобально — на каждой странице документации есть кнопка, чтобы одним кликом скопировать или скачать содержимое в виде чистого Markdown. Удобно для передачи документации в AI-ассистенты.