Я всегда скептически относился к чат-ботам. Когда-то они были на хайпе. Говорили, что это новый UI – он же No UI. Но я всегда утверждал, что пользователю проще и быстрее все действия сделать через сайт, а не играть с ботом в вопрос-ответ. Каково же было моё удивление, когда через несколько лет я сам буду пропагандировать чат-ботов всем моим друзьям - backend-разработчикам? В данной статье расскажу, как я до этого дошел.

Каждый раз, когда я задумываю pet-project, в полный рост встаёт вопрос, как реализовывать пользовательский интерфейс. Честно признаюсь, я умею во фронтенд. Умею вот в эти ваши JavaScript. Знаком даже с React.js. Но так уж вышло, что специализируюсь на серверной разработке, и UI по-взрослому касаюсь очень редко, наскоками. Поэтому реализация UI у меня всегда как в первый раз. Вероятно из-за этого многие задуманные мною pet-project’ты так и остаются на уровне идеи… С этим нужно было что-то делать.

Как чат-боты уже упрощают работу целой социальной платформе

Осенью 2021 года, я присоединился к платформе Strike, которая помогает с самоорганизацией и профсоюзной деятельностью. Вся платформа крутится вокруг чат-бота в Telegram. Никаких сайтов - только чат-бот. И, черт возьми, какое же это было простое и, по своему, элегантное решение. Ничего космического и технически передового в этом боте не было. Но он эффективно решал поставленную задачу - учить людей самоорганизации и борьбе за свои трудовые права.

И тут меня осенило… Это ведь можно, совершенно не влезая во всякие фронтенды, сделать полноценный сервис! Изучив вопрос лучше, я с удивлением обнаружил богатые возможности в Telegram для реализации ботов (в сравнении с другими мессенджерами). Тут тебе и просто кнопки, и inline-кнопки. И текст можно вводить. И файлы посылать. А с недавних пор можно и JavaScript засунуть! В общем, всё что нужно для эффективной коммуникации.

Конечно, Telegram это жесткий vendor lock. Все мы знаем, что привязываться к какой-то определённой платформе не очень здорово. Но, как говорится, колхоз - дело добровольное. Это компромисс, на который я сознательно пошел.

Мне захотелось самому реализовать какого-нибудь бота, который был бы полезен платформе Strike. Я поинтересовался, какие у платформы есть проблемы. Как оказалось, у Strike’a есть внутри целый юридический отдел, который помогает с трудовыми спорами. Там работают волонтеры и, как и в любом волонтерском деле, людей порой не хватает. Посему, любая автоматизация рутинной работы тут была бы очень кстати. Мы обсудили несколько идей с Андреем Чируком, руководителем юр отдела платформы Strike, и остановились на идее бота, который умел бы составлять исковые заявления. Для меня был неожиданностью тот факт, что составление искового заявления отнимает у юриста несколько дней! Если упростить этот процесс с помощью бота - это бы значительно сократило трудозатраты юр отдела Strike.

Первый этап: декомпозиция задачи

Как известно, прежде чем начинать любую реализацию программного обеспечения нужно подумать. Необходимо пообщаться с экспертом в той области, для которой это ПО и разрабатывается. Привет Domain Driven Design! По прошествии нескольких итераций вопросов-ответов, я стал лучше понимать доменную область. Изначально мы хотели реализовывать функционал только для узкого числа исковых заявлений - исключительно по трудовым спорам. Потому как такова специфика платформы Strike. Но чем больше мы разбирались с доменной зоной, тем больше понимали, что можно сделать лучше и не прибивать всё жестко гвоздями. В итоге нам с Андреем удалось декомпозировать любое исковое заявление на шесть частей, которые и должен заполнить пользователь. А именно:

  1. Шапку заявления, где указываются реквизиты истца и ответчика.

  2. Фабулу, где описывается ситуация в хронологическом порядке.

  3. Суть нарушения, где истец указывает, почему он считает, что его права нарушены.

  4. Доказательства, подтверждающие нарушение прав истца.

  5. Требования истца к ответчику.

  6. Приложение.

декомпозиция искового заявления
декомпозиция искового заявления

После заполнения всех разделов, пользователь сможет получить сгенерированное исковое заявление в виде *.docx документа.

Приятный side-effect от грамотной декомпозиции задачи

Одним из результатов декомпозиции искового заявления на составные части стала возможность создания шаблонов для различных типов исковых заявлений. А не только по трудовым спорам, как планировалось изначально.

// Фрагметр шаблона для искового заявления
{
   "theme" : "восстановление на работе",
   "story" : {
       "examples" : [
           "инженер",
           "{end_work_date} приказом №2 от {end_work_date} я был уволен на основании пп. 'а' п. ст.81 Трудового кодекса Российской Федерации за прогул."
       ],
       "actions" : [
           "enter_end_date",
           "enter_avr_salary"
       ]
   },
…
}

Эти шаблоны описываются в JSON файлике с определённой схемой. Бот, опираясь на данные из шаблона, спрашивает те или иные вопросы в зависимости от типа искового заявления. Сейчас командой юристов платформы Strike составлено два шаблона исков для наиболее часто встречающихся трудовых споров. Это исковое заявление о “восстановлении на работе” и о “взыскании заработной платы”. В планах добавить другие шаблоны. Каждый может попробовать составить свой шаблон и прислать его нам, создав Pull Request. А мы уже попробуем  интегрировать его в бота. Документация, как описывать шаблон, доступна на github в репозитории проекта.

Этап второй: реализация

Сама реализация бота заняла не так много времени - около двух месяцев работы по 1-2 часа в свободное время. И даже не каждый день. По техническому стеку использовал то, что умею готовить. В качестве основы: Python + aiogram (фреймворк для Telegram ботов), в качестве БД - mongoDB. Всё это дело погружено на docker контейнеры, и поднимается с помощью docker-compose. Минималистичный джентльменский набор. При этом я ни разу не прикасался к JavaScript (брр…). Но это не значит, что пользовательский интерфейс бота - это чисто текстовый ввод и вывод. В процессе разработки я придумал\прикрутил несколько интересных велосипедов. После всех этих, казалось бы косметических улучшений, интерфейс бота стал более дружелюбным к пользователю. 

Первое, что я придумал, это использовать эмодзи на кнопках. Это, по моему мнению, пошло на пользу UX. Ведь одного взгляда на кнопку с эмодзи хватает, чтобы понять, какое действие за ней стоит. Ну и как приятный бонус - так проще в коде писать регулярки для распознавания команд.

навигация стала гораздо нагляднее
навигация стала гораздо нагляднее

Второе улучшение, которое я подсмотрел в github репозитории aiogram_calendar, это отрисовка виджета календаря с помощью inline-кнопок. Пришлось немного адаптировать исходный код под свою задачу, но результат меня очень порадовал. Я снял с себя кучу головной боли по парсингу дат из текста! Вместо этого пользователь просто жмакает на кнопку, и ему даже нотификация о действии приходит!

 пример работы виджета календаря
пример работы виджета календаря

Отдельно стоит упомянуть про подсказки-примеры. В процессе общения с ботом, пользователь вводит какие-то данные. Например, размер своей заработной платы. Или должность. А потом бот просит пользователя описать, почему он считает, что его права нарушены. И если жмакнуть по кнопке примера, то бот покажет пример ответа с уже подставленными пользовательскими данными. Этот пример можно в большинстве случаев использовать в качестве ответа, так как ситуации достаточно стандартные в рамках одного типа искового.

Ну и конечно во многих случаях бот предоставляет список вариантов ответа (например, список доказательств). Пользователю остается только выбрать необходимые. Или ввести свои - по ситуации.

пример выбора опциональных значений (список доказательств
пример выбора опциональных значений (список доказательств

Этап третий: 3 полезные фичи

Одной из киллер-фич бота является поиск суда, в который пользователь должен направить исковое заявление после заполнения. Суд подбирается в данном случае на основе адреса истца (т.е. пользователя). Под капотом идет обращение к API ГАС “Правосудие”. Но есть нюанс - работает оно хорошо только для крупных городов. В лучшем случае районных центров. Как говорится, дареному коню в зубы не смотрят.

Для некоторых исковых заявлений нужно прилагать дополнительные расчеты. Например, расчет компенсации за задержку выплат по заработной плате. Бот генерирует такой расчет автоматически, основываясь на данных, введенных пользователем. Это очень нетривиальная задача, если производить расчеты самому. За это я получил отдельный респект от юридического отдела Strike.

Еще одной малозаметной, но исключительно важной фичей, является подстановка введенной пользователем информация в нужном падеже с необходимым окончанием. Реализовано это под капотом с помощью библиотеки pymorphy2.

Этап четвертый: работа с персональными данными

Когда ты делаешь подобный сервис, в полный рост встаёт вопрос о работе с персональными данными. Исковое заявление содержит их в полной мере. При заполнении заявления бот спрашивает у пользователя его ФИО, адрес и ИНН. Пользователь может ввести любые данные, даже абракадабру, и потом поправить их на валидные в уже сгенерированном документе. Это такой хак для параноиков. Исключение тут составляет адрес. Как я уже упоминал ранее, по нему происходит поиск суда для подачи заявления. Но и тут предоставляется возможность ввести всё что угодно, а затем указать суд самостоятельно.

Для подачи заявления в суд, исковое заявления должно содержать дату и место рождения истца, а также паспортные данные. Мы с Андреем решили, что эта информация очень чувствительная и просто отметили место (жирненько и красненько) в сгенерированном файле, куда их нужно ввести уже после общения с ботом.

Все персональные данные так или иначе хранятся в зашифрованном виде. И лишь в течении двух часов. Потом специальный демон чистит базу.

Заключение: Telegram бот отличный выбор для pet-project

Работа над этим проектом принесла мне массу позитивных эмоций. Я открыл для себя мир telegram ботов, где для реализации приложения не нужно знать кучу фреймворков, которые устаревают быстрее, чем ты их изучаешь. Мир, где для апробации идеи нужно всего несколько вечеров.

Конечно, все мои аргументы в пользу “взрослых” приложений в начале статьи никуда не делись. Я по прежнему считаю, что полноценный сайт лучше бота. Но если ты backend разработчик и тебе хочется реализовать что-то посимпатичнее CLI тулзы - присмотрись к telegram боту. Возможно тебе его будет достаточно. А если идея взлетит - всегда можно найти специально обученного человека для UI.

P.S. Данная статья написана по горячим следам моего выступления на форуме, который был посвящен самоорганизации. Там, помимо моего выступления, можно найти много другой, не ИТ-шной, но актуальной годноты.

P.P.S. Ссылка на бота-истца (не дай бог кому пригодится).

Комментарии (15)


  1. olku
    07.06.2022 22:12
    +3

    Телега как фронтенд экспертной системы. Любопытно, спасибо.


  1. 12rbah
    07.06.2022 23:24
    +2

    где для реализации приложения не нужно знать кучу фреймворков, которые устаревают быстрее, чем ты их изучаешь.
    Я вот хотел узнать, только я вижу, что последние лет 5 жалуются на это очень активно, но большая часть фронта пишется на vue/react/angular?


    1. mentin
      08.06.2022 00:32
      +1

      Знакомый фронтендщик половину времени кажется занят переходом с одной версии angular на другую. Там уже за дюжину версий, и апгрейд на каждую следующую - это новые сюрпризы. Большинство конечно пропускают часть версий, но иногда апдейтить код таки приходится.


      1. dopusteam
        09.06.2022 08:30

        Странный у Вас знакомый, в целом никто не заставляет каждую неделю обновляться, да и обновления обычно ничего не требуют. Разве что дело в конкретном коде

        'За дюжину версий' - это считая с 16 года, ~ две версии в год


    1. Chelovekovek
      08.06.2022 08:16

      Во-первых, не надо спорить с фольклором. Хорошая же сказка.

      Во-вторых, шутки в сторону, инструментарий меняется. AngularJS заменён Angular 2 (и это два совсем разных фреймворка). Vue 2 стал Vue 3 — здесь обошлось без масштабных изменений в подходе, но подучить новую документацию придётся. У реакта тоже потихоньку меняется стиль написания приложений, и развивается API.

      В целом таких сильных изменений, как при переходе со spagetty code и jQuery на полноценные фреймворка нет, но и совсем не учить новое тоже не получится.


      1. 12rbah
        09.06.2022 23:23

        Ну так можно сравнить старый c++ и c++ 11 стандарта, с использованием мета программирования или без, сколько версий явы/го вышло за последние 5 лет, в сфере БД и деплоя приложений тоже не мало произошло, так что не только на фронте надо что-то учить.


    1. FluffyArt
      08.06.2022 08:16

      Появляются иногда и такие товарищи как svelte.

      Но не суть, мне кажется, что в последнее время устаревает именно версия фреймворка и либы.

      То есть, если брать в пример vue, то есть классная надстройка в виде nuxt, которая обеспечивает хорошую архитектурную базу и ssr. Проблема в том, что на нее уже все достаточно устарело, все активно пилять vue3 и все, что с ним связано, а ты сидишь и ждешь пока умрет nuxt2 и восстанет стабильный и чутка полированный nuxt3 ????


  1. garbagecollected
    08.06.2022 04:27

    Не удержался от комментария.

    Первое, что я придумал, это использовать эмодзи на кнопках. Это, по моему мнению, пошло на пользу UX. Ведь одного взгляда на кнопку с эмодзи хватает, чтобы понять, какое действие за ней стоит.

    Реально?

    Второе улучшение, которое я подсмотрел в github репозитории aiogram_calendar, это отрисовка виджета календаря с помощью inline-кнопок. Я снял с себя кучу головной боли по парсингу дат из текста! Вместо этого пользователь просто жмакает на кнопку, и ему даже нотификация о действии приходит!

    Правильно ли я понимаю, вы вместо реальной задачи по автоматизации, такой как парсинг текста, решили нарисовать календарик, при этом называя процесс достижения автоматизации головной болью, которую вы перекладываете на пользователя?

    А теперь, давайте немного задумаемся, и поразмышляем над наводящими вопросами. Как именно Телеграм помогает решать такие задачи? какую роль автоматизации выполняет бот?

    Чтобы было понятна мысль, которую я хочу донести, постараюсь объяснить на пальцах. Пример конечно немного притянут за уши. Ситуация вымышленная. Все совпадения случайны.

    Одним прекрасным майским днем, засиживаясь в персональной кабинке, листал переговоры знакомых о какой-то неважной ерунде. Сделав свое дело, ко мне пришло озарение. Эврика! Почему бы мне не автоматизировать с помощью Телеграма сливной механизм унитаза? Ведь это же так удобно - смывать за собой жмакнув по кнопке не выходя из любимого мессенжера! И как я без этого столько лет дулся.

    Проанализируйте ситуацию. Какую роль в автоматизации процесса играет Телеграм? Разве что, отрисовка кнопок. Первый же issue придет во время отключения интернета. А ваша задача, если не брать в расчет подключение к серверам судов, носит локальный характер и должна выполняться независимо от наличия интернета. А какую роль играют боты? Вряд ли вы найдете на github такого бота, который умеет подключаться по всем API. Подключение к серверам реализуется одинаково, что с ботом, что без бота. И не смотря на отсутствие необходимости касаться сливного бочка, после туалета все равно приходится мыть руки... также тщательно... с мылом...

    Вряд ли в ближайшие годы боты Телеграма вытеснят JavaScript. Но даже использование JS - это не лучший выбор для таких задачей как ваша.


    1. Klems
      08.06.2022 10:48
      +1

      Ну почему часто критика останавливается на "не стоит так делать". А как надо то? Какой выбор - лучший?


    1. John_Balag Автор
      08.06.2022 11:02
      +1

      Реально?

      Это зависит от того, с чем сравнивать. Т.е. мой посыл был в том, что эмодзи + текст на кнопке лучше, чем просто текст

      Правильно ли я понимаю, вы вместо реальной задачи по автоматизации, такой как парсинг текста, решили нарисовать календарик, при этом называя процесс достижения автоматизации головной болью, которую вы перекладываете на пользователя?

      А при чем тут "реальная" автоматизация? Виджет календаря упрощает для пользователя работу с датами.

      А теперь, давайте немного задумаемся, и поразмышляем над наводящими вопросами. Как именно Телеграм помогает решать такие задачи? какую роль автоматизации выполняет бот?

      Телеграм предоставляет платформу, на которой можно сделать полезную штуку. Т.е. разработчик больше концентрируется на бизне логике, а не фронтенд-части. Особенно, если разработчик не особо шарит во фронтенде, а сделать полезную штуку хочется.

      Чтобы было понятна мысль, которую я хочу донести, постараюсь объяснить на пальцах. Пример конечно немного притянут за уши. Ситуация вымышленная. Все совпадения случайны.

      Мне кажется пример некорректный. Просто потому, что в примере пользователь знает, как сделать "действие" (слить бачок унитаза) без привлечения эксперта. Бот, описанный в статье, как раз позволяет обойтись без эксперта (юриста). Как правильно заметил @olku - это экспертная система на платформе бота.


  1. TedBeer
    08.06.2022 09:53
    +1

    исключительно важной фичей, является подстановка введенной пользователем информация в нужном падеже с необходимым окончанием

    Это правильно что воспользовались библиотекой, вручную не всегда попадаете в нужный падеж :-)


  1. Mansur_85
    08.06.2022 10:48
    +1

    Телеграм боты везде. Дуров через ботов будет захватывать мир ))


  1. savostin
    08.06.2022 13:52

    Как пользователь ни разу не встречал бота в мессенжере, который был бы действительно хоть немного удобен. Все они напоминают Нокию, когда пытаешься набрать смс.


  1. iddqda
    08.06.2022 14:10
    +1

    плюсую за основной посыл - чат-боты как замена фронта некоторых приложений

    использую для задач автоматизации сети

    правда совсем без JS не обошлось, так как в качестве платформы использую self-hosted rocket.chat и Bot SDK к нему на JS


  1. Valerdos_UA
    08.06.2022 14:26

    Да, "кнопочками" и проч., Delphi когда-то завоевал рынок прикладного программирования. ????