Как разработать свою версию веб-приложения в Telegram? Инструкция по сборке «интернет-магазина на диване»

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

Как разработать свою версию веб-приложения в Telegram? Инструкция по сборке «интернет-магазина на диване»

Используйте навигацию, чтобы быстро перемещаться по шагам инструкции:

С чего начать разработку

Сначала заведем два проекта: для разработки на front-end мы будем использовать React, а для back-end — node.js.

Начнем с того, что инициализируем react-приложение. Пока создается приложение в существующей папке, выберем путь через точку. Далее инициализируем backend, чтобы в файле .json появились базовые настройки.

Для удобной и актуальной разработки, как dev-зависимость устанавливаем пакет nodemon. Так мы сможем автоматически перезапускать бота после любых изменений в его коде.

Установим пакет API: лучше выбрать Node.js Telegram Bot API как более новую версию. Пока пакет устанавливается, можно перейти к BotFather и ввести команду /newbot.

Вводим уникальное название бота (обязательно содержит Bot). В ответ BotFather отдаст токен, который лучше скопировать себе куда-то в блокнот (а лучше держать в секрете), поскольку он понадобится чуть позже.

Импортировать пакет API можно через require. Часть кода возьмем из документации, заменив демонстрационный токен на собственный.

Разберем ситуацию, когда после команды /start нужно отдать пользователю какие-то кнопки.

Для проверки напишем в боте команду /start, и при нажатии на кнопку будет открываться окно с мини-браузером. Кроме этого, можно написать команду /setmenubutton, выбрать бота, для которого будет использоваться кнопка, и прописать URL, куда она поведет.

Далее мы будем взаимодействовать с полем window.Telegram.WebApp.

import './App.css'; const tg = window.Telegram.WebApp; function App() { const onClose = () => { f } return ( <div className="App"> work <button onClick ={onClose}>Закрыть</button> </div> ); } export default App;

Чтобы дебажить веб-приложение с Telegram-ботом онлайн, придется создать репозиторий на гите и привязать его в netlify. Получив ссылку на приложение, можно вставить ее в код.

Теперь кастомизируем кнопку. Изменим цвет, чтобы соответствовать айдентике мессенджера.

>>Header.jsx

import 'React' from 'react'; import Button from "../button/button"; import './Header.css'; const Header = () => { const tg = window.Telegram.WebApp; const onClose = () => { tg.close() } return ( <div className={'header'}> <button onClick={onClose}>Закрыть</button> <span className={'username'}>{tg.initDataUnsafe?.user?.username}</span> </div> ); };

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

Теперь создадим отдельный хук для корректного получения объекта.

>>useTelegram.js

const tg = window.Telegram.WebApp; export function useTelegram() { const onClose = () => { tg.close() } const onToggleButton = () => { if(tg.MainButton.isVisible) { tg.MainButton.show(); } else { /основная кнопка взаимодействия с ботом/ } return { onClose, tg, user: tg.initDataUnsafe?.user, } }

Общение с ботом происходит при помощи метода Telegram.WebApp.sendData. Теперь можно переходить к созданию страниц и маршрутов.

>>Button.jsx

import React from 'react'; import './button.css'; const Button = (props) => { return ( <button {...props} className={'button ' + props.className} /> ); }; export default Button;

Стили заносим в ProductList.css и переходим к следующему этапу.>>ProductList.jsx

import React from 'react'; import './ProductList.css'; const ProductList = () => { return ( <div> ProductList </div> ); }; export default ProductList;

В index.js файле теперь нужно обернуть все наше приложение:

<React.StrictMode> <BrowserRouter> <App /> </BrowserRouter> </React.StrictMode>

Теперь в App.js импортнем Route, выглядеть это будет так:

import {Route, Routes} from 'react-router-dom'; /используется 6 версия/ Здесь же создаем две страницы для двух адресов: <div className="App"> <Header /> <Routes> <Route index element={<ProductList />} /> <Route path={‘form’} element={<Form />} /> </Routes> </div>

Теперь в приложении по корневому пути будет открываться ProductList.

import React from 'react'; import './from.css'; const Form =() => { return ( <div className={"form"}> <h3>Введите ваши данные</h3> <input className={'input'} type="text" placeholder={'Страна'} /> </div> <select> <option value ={'legal'}>Юр.лицо</option> <option value ={'legal'}>Физ.лицо</option> </select> ); }; export default Form;

Форму можно взять отсюда, здесь все по стандарту. Чтобы форма теперь открывалась в боте, нужно дополнить путь в index.js. [{text: ‘Заполнить форму’, web_app: {url: WebAppUrl + ‘./form’} }].

Теперь сделаем конфигурационный файл netlify.toml с опциями для редиректов. То есть, мы по любому маршруту делаем редирект в index.html.

[[redirects]] from = "/*" to = "/index.html" status = 200

На этом этапе мы уже можем вводить данные в форму, но пока не можем их отправить.

Когда мы получаем данные из веб-приложения, мы можем их отправить. Заметьте, что функции, которые мы добавляем асинхронны.

>>index.js

await bot.SendMessage( chatId, text 'Спасибо за обратную связь!') await bot.SendMessage( chatId, text 'Ваша страна: ' + data? .country ); await bot.SendMessage( chatId, text 'Ваша страна: ' + data? .street); setTimeout(handler ()=> { await bot.SendMessage( chatId, text 'Ваша страна: ' + data? .street); } timeout 3000)

Отправка данных

Мы уже затрагивали использование метода sendData, а сейчас мы посмотрим как работать с теми данными, которые нам пришли. Здесь нам вместе с эффектом важно также прописать коллбек.

useEffect( effect: ()=>) сonst onSendData = useCallback( callback: () => { }

Если данные приходят пустыми, проверьте массив зависимостей. Если в корзине есть хотя бы один товар, мы показываем кнопку.

if(NewItems.length === 0) { tg.MainButton.show() tg.MainButton.setParams( params { text: ‘Купить ${}’ })

Чтобы посчитать общую стоимость товаров, добавим следующую строку в ProductList.jsx.

const getTotalPrice = (items) => return items.reduce((acc, item) => { return acc += item.price

Так мы суммируем в функции стоимость товаров, чтобы потом получить getTotalPrice(newItems).

Осталось разобрать, как должна работать кнопка Купить, когда товары добавлены и стоимость рассчитана. Здесь нам поможет классический fetch-запрос.

fetch(input 'http://localhost:8000', init { method ‘POST’. headers: { 'Content-Type': 'application/json', } body: JSON.stringify(data) }

На этом работу на front-end можно считать законченной, но нам еще нужно поднять сервер.

Серверная часть

Чтобы не было проблем с кросс-доменным запросами, бота мы будем деплоить на облачный сервер. Весь код, который нам потребуется можно найти в файле index.js. Воспользуемся документацией из этого раздела. Сейчас нас интересует вот эта часть:

app.post( path '/web-data, handlers (req, res) => const { queryId, products, totalPrice} = req.body; const PORT = 8000 app.listen(PORT, callback () => console.log => ('server started on PORT ' + PORT))

QueryID в этом сценарии выполняет функцию связующего звена. С его помощью мы можем взаимодействовать с ботом.

app.post( path '/web-data, handlers (req, res) => const { queryId, products, totalPrice} = req.body; try { await bot.answerWebAppQuery (queryId, result { type: 'article', id: queryId, title: 'Успешная покупка' input.message.content {message_text 'Поздравляем с покупкой' +TotalPrice} }

Это сообщение, которое мы уже будем отправлять пользователю, когда платеж пройдет. Для сообщения о неудачных оплатах можно скопировать этот код и вписать новый текст, который уведомит пользователя об ошибке. Разница в том, что в случае успеха http-запрос стоит завершить с кодом 200, а в противном случае статус-код 500.

В панели управления Selectel зайдем во вкладку Облачная платформа -> Серверы и создадим новый.

Как разработать свою версию веб-приложения в Telegram? Инструкция по сборке «интернет-магазина на диване»

Для деплоя бота есть отличный вариант — SharedLine. Это решение подходит пет-проектам, которые не нуждаются в производительном железе. Зачем платить за целое ядро, если вся его мощность точно не потребуется?

Как разработать свою версию веб-приложения в Telegram? Инструкция по сборке «интернет-магазина на диване»

Консоль для администрирования можно открыть прямо из панели. Сначала обновим инструмент работы с пакетами: sudo apt update.

Теперь установим git: sudo apt install git, а затем клонируем проект при помощи обычной команды git clone <ссылка на репозиторий>. Осталось установить npm, чтобы подтянуть все необходимые пакеты и node.js, чтобы запустить сервер. При необходимости, обновите версии sudo npm install -g n. Далее лучше выполнить команду sudo n stable, а не latest, чтобы все точно работало корректно.

После нужно установить зависимости с помощью классической команды npm install.

Дальше нам поможет менеджер процессов, чтобы, например, перезапускать сервер, если он упал или распараллелить процессы. Готово!

Запускаем бота командой pm2 start index.js — путь до нашего корневого файла. Теперь во вкладке порты в панели Selectel можно увидеть IP-адрес, по которому бот будет доступен. Теперь в fetch нужно заменить адрес localhost на IP-адрес облачного сервера. Укажите также новый адрес до самого end-point.

Вместо заключения

В разработке Telegram-бота с кнопками нет ничего сложного. Для хостинга такого интернет-магазина не нужно оплачивать полную стоимость сервера, достаточно использовать Shared Line.

Подпишитесь на блог Selectel, чтобы не пропустить новые инструкции, техобзоры, полезные курсы и ивенты для IT-специалистов.

Читайте также:

3333
6 комментариев

Спасибо большое, все попятно 👍🏼

2

взял на заметку, может когда то руки дойдут и ума хватит :)

1

Stas, рады, что инструкция была полезной! Если решите реализовать, поделитесь потом впечатлениями от процесса :)

кто-то знает реализованные Веб-приложения в ботах телеграм кроме durgerking и wallet ?

Есть, например, полноценные игры, собранные на веб-движках: https://vc.ru/services/527527-server-tower-JapBI0CXP — хотя это не про ботов.

Кстати, мой коллега также поднимал, по сути, веб-приложение для заказа шаверма через Telegram-бота. Решение закрытое, но ознакомиться с опытом вы можете по ссылке: https://vc.ru/services/729298-kak-sozdat-bota-dlya-zakaza-shavermy-i-ostavit-golodnymi-lish-1-1-kolleg

Да, видел магазин кроссовок и доставку еды