В этой статье я расскажу как создать чат бота на React с помощью библиотеки Urban Bot, над которой я работаю в последнее время. Мы создадим простой Telegram чат бот как на этой гифке.
Что понадобится:
- node.js: 10+
- telegram bot token — Можно получить у @BotFather, инструкция.
Чтобы создавать чат боты на React, мы будем использовать новую библиотеку Urban Bot. Она адаптирует React для рендера чат ботов на разных платформах. В данный момент поддерживается Telegram, Facebook и Slack. В дальнейшем планируется поддержка Discord, WhatsApp, VK, Viber и других.
Главный плюс Urban Bot - это то, что не нужно ничего знать про API мессенджеров, как чат боты работают изнутри. Все что нужно - это базовые знания React. Вы просто описываете ваше приложение через готовые компоненты и хуки. Для управления несколькими сценами можно использовать Router компонент. Также можно легко использовать что угодно из React экосистемы, например, MobX или Redux для управления состоянием, или просто использовать готовые части из ваших React Web или React Native приложений.
Установка
Самый простой способ начать — это взять готовый Urban Bot стартер. Есть TypeScript и JavaScript версии.
Чтобы установить, просто введите в терминале.
TypeScript
npx create-urban-bot my-app
JavaScript
npx create-urban-bot my-app --template js
После установки готовый шаблон будет в директории my-app
, там где вы запускали create-urban-bot
.
Настройка
Откройте my-app
в вашем любимом редакторе, файл .env
и введите Telegram токен.
Также нам надо активировать Telegram render. Раскомментируйте // import ‘./render/telegram’;
внутри src/index.ts
или src/index.js.
Все готово чтобы разрабатывать Telegram бота! Запустите npm run dev
скрипт и напишите что-нибудь своему боту, который связан с Telegram токеном. Он должен отвечать двумя командами /echo
и /logo
.
Если вы видите ошибку вида
error: [polling_error] {"code":"EFATAL","message":"EFATAL: Error: connect ECONNREFUSED 127.0.0.1:9150"}
возможно интернет провайдер блокирует Telegram трафик. Вам нужно использовать VPN или вы можете использовать Tor браузер, здесь пример.
Разработка
Для начала нам нужно открыть src/App.js
или src/App.ts
, удалить весь код кроме функии App
которая возращает null
.
Во-вторых, давайте добавим пустое значение todos
и действия addTodo
и toggleTodo
. Мы будем использовать useState
React hook чтобы связать значение и рендер. Будьте осторожны, если мы меняем значение todos
, мы не должны мутировать его, нам нужно всегда передавать новое значение.
Теперь нам нужно, чтобы когда пользователь отправлял сообщение в чат, мы добавляли новое значение в todos
. Urban Bot предоставляет React hooks для того чтобы подписываться на действия пользователей. Для нашей цели мы можем использовать useText
hook из @urban-bot/core
.
Теперь все готово чтобы показать наши todos
. Urban Bot предоставляет HTML
синтаксис для форматирования текста. Давайте создадим новый массив с форматтированным текстом. <s>...</s>
используется для зачеркнутого текста, <br />
для переноса строки.
Также нам нужно создать массив кнопок, чтобы менять “выполненный” статус задачи. Чтобы исползовать кнопки мы можем воспользоваться компонентом Button
. Чтобы было действие после клика нам нужно вызывать функцию toggleTodo
и передавать ей айди конкретной задачи.
Сейчас функции App
возращает null, поэтому наш бот ничего не показывает. Чтобы это исправить, нам нужно передать готовые значения в компонент ButtonGroup
и вернуть его. Мы передаем форматируемый текст в ButtonGroup
title
prop и готовые кнопки в ButtonGroup
children
. maxColumns
— это не обязательный prop чтобы кнопки автоматически разбивались по три в ряд.
Также если todos
пустое значение, можем возращать соответствующий текст.
Давайте проверим нашего бота! Для примера, если вы напишите “прочитать статью” боту, он должен вернуть задачу с этим текстом и кнопку чтобы менять ее статус.
Если вы напишите второе сообщение, то вернется новое свообщение от бота с двумя задачами. Давайте сделаем, чтобы было одно первое сообщение, а потом оно изменялось каждый раз. Чтобы сделать так, нужно передать isNewMessageEveryRender={false}
prop в ButtonGroup
. Можно сделать такое поведение для всех компонентов по умолчанию передав этот prop в компонент Root
, который находится в src/render/telegram.js
.
<ButtonGroup title={title} maxColumns={3} isNewMessageEveryRender={false}>
Финальный код src/App.js.
Мы не стали рассматривать функционал удаления, так как это не раскрывает новых возможностей, полный пример можно увидеть на github.
Последнее важное уточнение, что если два человека или больше начнут писать в чатбот, не будет ли пересечений? Нет, Urban Bot показывает приложение уникальным для каждого пользователя, так что вам не нужно думать об управлении сессией, у каждого пользователя будет свои todos
. Не смотря на то, что это серверное приложение, вы не почувствуете разницу, так, будто вы пишите обычное React приложение, которое запускается на стороне клиента.
Итого
Мы рассмотрели, как написать простой Todo List, используя React. Главная цель статьи — это рассказать о базовых принципах Urban Bot. Мы использовали только один компонент App
, но нет ничего сложного, чтобы использовать десятки и сотни компонентов и создавать действительно сложные SPA приложения внутри любого чат бота. Из этой статьи мы узнали только о Telegram версии, также возможно запустить этот пример в Facebook или Slack. Urban Bot — это ядро к которому можно подключить любой мессенджер.
Если вам понравилась идея, поставьте звезду в репозитории Urban Bot. Это будет лучшей мотивацией развивать проект дальше.
Ссылки