Я продолжаю описывать собственное погружение в мир телеграм-ботов, начатое в предыдущей публикации. Тогда я создал простого бота на Node.js с тремя стандартными командами (/start, /help, /settings) с использованием библиотеки grammY, который мог работать в режимах long polling и webhook. В этот раз я разработал бота, который манипулирует данными в базе по шаблону CRUD + List (CRUDL) с помощью аргументов команд. Из-за своей простоты, граничащей с примитивностью, это решение не подходит для коммерческих проектов, но может быть полезным в персональных проектах.
Демонстрационный телеграм-бот @flancer64/tg-demo-crudl позволяет создавать в БД список контактов и номеров телефонов. Вот список соответствующих команд:
- /create <имя> <номер телефона>: добавляет новый контакт в список (- /create John 123456789)
- /read <id>: выводит информацию о контакте по указанному идентификатору (- /read 1)
- /update <id> <новое имя> <новый номер телефона>: обновляет существующий контакт (- /update 1 Jane 987654321)
- /delete <id>: удаляет контакт из списка (- /delete 1)
- /list: отображает все сохранённые контакты
Основные технологии проекта
- grammY — npm-пакет для взаимодействия с Telegram API из Node.js. 
- Knex.js — npm-пакет, который позволяет работать с различными СУБД (уровень абстракции базы данных, DBAL). 
- @teqfw/di — npm-пакет для внедрения зависимостей, обеспечивающий гибкость и расширяемость приложения. 
- @flancer32/teq-telegram-bot — npm-пакет для выполнения типовых операций телеграм-бота (запуск в режиме long polling и webhook, создание списка команд, настройка бота и т.п.). 
Типовая команда
Создание каркаса бота, его регистрация в Телеграм, запуск и остановку я подробно рассмотрел в предыдущей публикации. Там же описана и архитектура проекта. Здесь я продемонстрирую реализацию типовой команды на примере /create (Demo_Crudl_Back_Bot_Cmd_Create).
Внедрение зависимостей
ES6-модуль ./src/Back/Bot/Cmd/Create.js обрабатывается контейнером объектов, который создаёт и внедряет необходимые зависимости:
Скрытый текст
export default class Demo_Crudl_Back_Bot_Cmd_Create {
    constructor(
        {
            TeqFw_Core_Shared_Api_Logger$$: logger,
            TeqFw_Db_Back_RDb_IConnect$: conn,
            TeqFw_Db_Back_Api_RDb_CrudEngine$: crud,
            Demo_Crudl_Back_Store_RDb_Schema_Phone$: rdbPhone,
        }
    ) {}
}- TeqFw_Core_Shared_Api_Logger$$: logger— логгер для трассировки выполнения команды.
- TeqFw_Db_Back_RDb_IConnect$: conn— соединение с базой данных.
- TeqFw_Db_Back_Api_RDb_CrudEngine$: crud— объект для выполнения базовых операций с БД.
- Demo_Crudl_Back_Store_RDb_Schema_Phone$: rdbPhone— DTO для описания структуры данных, хранимых в базе данных.
Первые три зависимости являются стандартными инструментами из моего набора TeqFW, а последняя относится непосредственно к предметной области.
DTO для БД
DTO Demo_Crudl_Back_Store_RDb_Schema_Phone описывает простую структуру из четырёх полей:
class Dto {
    date_created; 
    id; 
    name;
    phone;
}
которая соответствует следующей таблице в базе данных SQLite:
CREATE TABLE main.phone
(
    id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
    name VARCHAR(255) NOT NULL,
    phone VARCHAR(255) NOT NULL,
    date_created DATETIME DEFAULT CURRENT_TIMESTAMP NOT NULL
);
Этого достаточно, чтобы иметь представление о структуре данных в БД. Демо-бот работает с SQLite, но DBAL Knex.js позволяет также использовать PostgreSQL, MariaDB/MySQL, MS SQL и Oracle. Нужно лишь установить соответствующий npm-пакет для работы с выбранной СУБД.
Параметры подключения Knex.js к соответствующей СУБД прописываются в конфигурационном файле ./cfg/local.json (шаблон настроек - в ./cfg/init.json). В демо-версии используется SQLite, файл в базой располагается в ./var/data.db. Для работы с базой предназначены команды:
$ ./bin/tequila.mjs db-init
$ ./bin/tequila.mjs db-export -f ./var/data.json
$ ./bin/tequila.mjs db-import -f ./var/data.jsonНазначения команд понятны из названия: создание структур данных (таблица), экспорт и импорт данных в JSON-формат.
Шаблон обработки Телеграм-команды
Так как наш бот для работы использует платформу grammY, то типовой обработчик команд работает с объектами кода этой платформы (ctx). Вот скелет обработчика:
const handler = async (ctx) => {
    let msg = 'The command has failed.';
    const from = ctx.message.from;
    logger.info(`Command has been received from user '${from.username}' (id:${from.id})`);
    const trx = await conn.startTransaction();
    try {
        // const parts = ctx.message.text.split(' ');
        // ... 
        await trx.commit();
    } catch (e) {
        await trx.rollback();
        msg = e.toString();
        logger.error(msg);
    }
    // https://core.telegram.org/bots/api#sendmessage
    await ctx.reply(msg, {
        parse_mode: 'HTML',
    });
};Алгоритм действий в обработчике такой:
- залогировать принятую команду 
- инициировать транзакцию для работы с БД 
- выполнить действия с БД в рамках транзакции и сформировать ответ на принятую команду 
- зафиксировать изменения в БД 
- сфомировать сообщение для пользователя об успешном завершении выполнения команды 
- в случае возникновения ошибок отдать пользователю сообщение об ошибке 
Выполнение команды
Данный фрагмент кода демонстрирует непосредственно обработку самой команды create - извлечение данных из команды и сохранение их в БД:
try {
    const parts = ctx.message.text.split(' ');
    const dto = rdbPhone.createDto();
    dto.name = parts[1];
    dto.phone = parts[2];
    const {[A_PHONE.ID]: id} = await crud.create(trx, rdbPhone, dto);
    await trx.commit();
    msg = `New record #${id} has been created.`;
    logger.info(msg);
} catch (e) {...}Я использую свою собственную обёртку для DBAL Knex.js, которая позволяет мне выполнять базовые операции (CRUD) с DTO. Если у вас другая библиотека для работы с данными в БД (например, sequelize или prisma), то у вас здесь будет другой код. Но всю остальную обвязку можно оставлять (за исключением транзакций).
Пример работы бота
После создания бота в BotFather, получения API-ключа и конфигурировании бота (./cfg/local.json) нужно создать таблицы в БД:
$ ./bin/tequila.mjs db-initЗапуск бота в режиме long polling:
$ ./bin/tequila.mjs tg-bot-startили
$ npm startВызов справки

Create

Read

Update

List

Delete

Заключение
В данной статье я описал процесс создания простого телеграм-бота на Node.js с использованием библиотеки grammY, который поддерживает операции CRUD-L (создание, чтение, обновление, удаление и список). Мы рассмотрели, как с помощью команд с аргументами можно манипулировать данными в базе данных. Несмотря на простоту, данный подход открывает возможности для персональных проектов, где не требуется сложная бизнес-логика, но важна простота в реализации.
Если вы ищете простое, но мощное решение для работы с базами данных через телеграм-ботов, то данный проект может стать отличной отправной точкой для реализации ваших фантазий.
 
           
 

liquiddeath13
Проблема телеграм бота - не очень юзер френдли интерфейс для взаимодействия с данными. Если записей будет много (хотя бы больше 100), то взаимодействие с ними будет не очень удобным
Чатбот на то и чатбот - пообщаться, что-то мелкое автоматизировать. Для взаимодействия с данными, если уж очень нужно в телеге, лучше реализовать мини дэшборд в вебаппе (имхо)
Спасибо за статью!