🎉 grammY 1.10
На днях вышло большое обновление для grammY — современной typescript-библиотеки для создания телеграм-ботов.
Главная тема обновления — первый стабильный релиз @grammyjs/conversations. Это библиотека, позволяющая строить сложные диалоговые взаимодействия с пользователем, почти об этом не задумываясь.
Наверное, каждый, кто пробовал писать телеграм-ботов, хотя бы раз думал «как круто было бы, если бы можно было написать "подожди следующего сообщения от пользователя и продолжи функцию"». Так вот, conversations позволяют делать именно так! Например:
async function greeting(conversation: MyConversation, ctx: MyContext) { await ctx.reply("Hi there! What is your name?"); const { message } = await conversation.wait(); await ctx.reply(`Welcome to the chat, ${message.text}!`); }
Причём, в отличие от наивных реализаций через промисы, все данные тут хранятся в сессии, и бот получается полностью устойчив к перезагрузкам.
И хотя я всё ещё придерживаюсь классического подхода со сценами (grammy-views), conversations — это интересная новая абстракция, которая (наверное) будет более интуитивно понятна для начинающих разработчиков. Подробнее »
Кроме этого добавили ctx.has
— набор методов у контекста, позволяющих выполнять проверки. Раньше это было доступно только со стороны Composer'а. Например:
composer.command('start', (ctx) => ctx.reply(ctx.match.toString()))
Эквивалент этого с помощью ctx.has будет выглядеть примерно так:
composer.use((ctx, next) => { if (ctx.hasCommand('start')) { return ctx.reply(ctx.match.toString()) } return next() })
В обычных ситуациях ctx.has
пригодится нечасто, но главное его применение — в conversations. Из-за более императивного подхода в них недоступны привычные методы Composer'а, их и заменит ctx.has
. Подробнее »
Ещё обновили сессии. Добавили мульти-сессии, позволяющие хранить разные части данных в разных хранилищах; добавили «улучшатель» хранилищ, добавляющий TTL для сессий и инструмент для миграций. Первые два кажутся мне не такими важными, а вот миграции — это правда полезно.
По мере развития бота формат данных в сессии может меняться. При этом у старых пользователей могут оставаться данные в старом формате, с которыми бот может работать неправильно. Раньше с этим приходилось бороться обходными путями: добавлять проверки на отсутствующие поля, мигрировать из одного формата в другой.
Новый плагин упрощает эти действия. Он позволяет создавать функции, которые мигрируют данные из одной версии формата в следующую. При этом плагин сам следит за версией данных у каждого пользователя и запускает миграции при необходимости. Подробнее »
Ну и напоследок — обновили плагин для создания клавиатур. Наконец-то добавили поддержку resize_keyboard, one_time_keyboard и других полей для обычных клавиатур, без них было очень неудобно (хотя я и не пользуюсь обычными клавиатурами). А самое главное, добавили фичу, за которую я топил больше двух месяцев — конструкторы для клавиатур.
Встроенный в grammY плагин для построения клавиатур написан в императивном стиле. Например:
const keyboard = new InlineKeyboard() .text('1', 'a').text('2', 'b').row() .text('3', 'c')
И это не всегда может быть удобно (например, если нужно создать клавиатуру из динамического массива)
Поэтому я предпочитаю декларативный подход на базе обычных двумерных массивов. Я сделал плагин grammy-markup, который предоставляет функции-помощники для создания кнопок Button и IButton. Но вот незадача: в Keyboard и InlineKeyboard нельзя передать сырые данные о клавиатуре в виде двумерного массива! Было нельзя, до этого обновления. Теперь клавиатуры можно строить так (с помощью плагина grammy-markup):
const keyboard = new InlineKeyboard([ [IButton.text('1', 'a'), IButton.text('2', 'b')], [IButton.text('3', 'c'), ])
Плагин grammy-markup в связи с этим получает версию 1.0! Репо »