Как добавить web app в телеграм бот
Перейти к содержимому

Как добавить web app в телеграм бот

  • автор:

Web Apps в Telegram

Безусловно,сейчас все обсуждают последнее обновление Telegram Bot API, в котором были добавлены Web Apps — кастомные страницы, которые открываются прямо внутри переписки с ботами!

Нам начало поступать множество вопросов от клиентов касательно этой новой фичи, поэтому мы решили подробно пройтись по документации API и разложить все по полочкам. Поехали:

1. Как отобразить пользователю Web App?

Сейчас доступно 3 способа: по нажатию на reply-кнопку, по нажатию на inline-кнопку, по нажатию на кнопку «Меню» внутри бота (за которой раньше скрывался список команд). Во всех способах пользователю открывается указанный вами URL по HTTPS, поэтому вам нужно иметь собственный веб-сервер с SSL-сертификатом для отображения страниц.

2. Как боты общаются с Web Apps?

Это происходит через специальный объект Telegram.WebApp, который вы можете использовать с помощью JavaScript внутри своей кастомной страницы. Кроме этого, никто не запрещает передавать в URL открытия Web App’а нужные вам параметры для получения информации о юзере.

3. Как сделать интерфейс для Web App?

Доступны все возможности HTML, CSS и JavaScript, без каких-либо ограничений (по крайней мере, они не описаны в документации). Важно понимать, что у всех пользователей разные размеры экрана и цветовые настройки, поэтому при разработке Web App нужно учитывать множество вариантов, благо Telegram с этим помогает.

Как создать веб-приложение на базе Telegram Mini Apps

Показываем, как завести и настроить Telegram-приложение на базе Angular и telegraf, а после — задеплоить на сервер.

Введение

Telegram Mini Apps — отличная возможность выйти за пределы обычных ботов и попробовать себя в создании более интересных интерфейсов приложений. На базе этого инструмента можно создать магазин или даже сервис для заказа шавермы.

В этой статье познакомимся с Telegram Mini Apps и попробуем создать простое приложение. Сделаем это с использованием обновленного Angular 17 и telegraf, а в конце — задеплоим проект на виртуальный сервер.

Инициализация бота

1. Для начала создаем новый проект Node.js, в котором мы объединим Angular и telegraf:

npm init -y 

2. Следующим этапом нужно создать Telegram-бота. Для этого понадобится API-токен, который можно получить у @BotFather с помощью команды /newbot:

3. Устанавливаем telegraf и описываем базовую структуру программы в файле main.js:

import < Telegraf, Markup >from 'telegraf' import < message >from 'telegraf/filters' const token = '6908588510:AAGJ8Lhf_ItjNl9gQoCnK7IejRWQHWpPfiE' const webAppUrl = 'https://vk.com/' const bot = new Telegraf(token) bot.command('start', (ctx) => < ctx.reply( 'Добро пожаловать! Нажмите на кнопку ниже, чтобы запустить приложение', Markup.keyboard([ Markup.button.webApp('Отправить сообщение', `$/feedback`), ]) ) >) bot.launch() 

Markup позволяет отправлять пользователю клавиатуру в ответ на команду start. API-токен бота при желании можно вынести в конфигурацию — пример есть в прошлой инструкции.

4. Далее добавим структуру в package.json — это нужно инициализации main.js:

"type": "module", "scripts": < "start": "node main.js" >, 

5. В @BotFather пропишем команду /setmenubutton, чтоб добавить красивую кнопку запуска приложения в нашем боте:

Создание веб-приложения на Angular

Теперь создадим новый проект для веб-приложения на Angular. На самом деле, вместо него можно использовать нативную связку из HTML, CSS и JavScript — выбирайте инструменты из своих предпочтений.

npm install -g @angular/cli ng new tg-angular-app 

Создадим необходимые страницы для сайта с помощью Angular CLI. Это довольно удобный способ добавлять новые сущности и сервисы в проект:

ng g c pages/feedback ng g c pages/product ng g c pages/shop 
ng g s services/products ng g s services/telegram 

Теперь подключим библиотеку Telegram к index.html в секции head:

В ./src/app/services/telegram.service.ts пропишем базовый функционал:

import < DOCUMENT >from '@angular/common'; import < Inject, Injectable >from '@angular/core'; // интерфейс для функционала кнопок interface TgButton < show(): void; hide(): void; setText(text: string): void; onClick(fn: Function): void; offClick(fn: Function): void; enable(): void; disable(): void; >@Injectable(< providedIn: 'root', >) export class TelegramService < private window; tg; constructor(@Inject(DOCUMENT) private _document) < this.window = this._document.defaultView; this.tg = this.window.Telegram.WebApp; >get MainButton(): TgButton < return this.tg.MainButton; >get BackButton(): TgButton < return this.tg.BackButton; >sendData(data: object) < this.tg.sendData(JSON.stringify(data)); >ready() < this.tg.ready(); >> 

Выше описан сервис, который получает доступ к глобальному объекту window и Telegram. Также в коде добавлены удобные типизированные методы для работы с библиотекой внутри Angular.

Далее app.component.ts добавим роутинг в поле template , чтобы Angular знал, куда рендерить динамические страницы. После подключаем ранее созданный Telegram-сервис и вызываем метод ready , чтобы он знал, когда приложение готово к работе:

import < Component, inject >from '@angular/core'; import < CommonModule >from '@angular/common'; import < RouterOutlet >from '@angular/router'; import < TelegramService >from './services/telegram.service'; @Component(< selector: 'app-root', standalone: true, imports: [CommonModule, RouterOutlet], template: ``, >) export class AppComponent < telegram = inject(TelegramService); constructor() < this.telegram.ready(); >> 

В app.routes.ts добавим следующую конфигурацию для трех страниц:

import < Routes >from '@angular/router'; import < ShopComponent >from './pages/shop/shop.component'; import < FeedbackComponent >from './pages/feedback/feedback.component'; import < ProductComponent >from './pages/product/product.component'; export const routes: Routes = [ < path: '', component: ShopComponent, pathMatch: 'full' >, < path: 'feedback', component: FeedbackComponent >, < path: 'product/:id', component: ProductComponent >, ]; 

Далее создадим сервис для работы со списком продуктов в services/product.services.ts. Ниже привожу пример на базе списков обучающих программ по программированию:

import < Injectable >from '@angular/core'; const domain = 'https://result.school'; export enum ProductType < Skill = 'skill', Intensive = 'intensive', Course = 'course', >export interface IProduct < id: string; text: string; title: string; link: string; image: string; time: string; type: ProductType; >function addDomainToLinkAndImage(product: IProduct) < return < . product, image: domain + product.image, link: domain + product.link, >; > const products: IProduct[] = [ < id: '29', title: 'TypeScript', link: '/products/typescript', image: '/img/icons/products/icon-ts.svg', text: 'Основы, типы, компилятор, классы, generic, утилиты, декораторы, advanced. ', time: 'С опытом • 2 недели', type: ProductType.Skill, >, < id: '33', title: 'Продвинутый JavaScript. Создаем свой Excel', link: '/products/advanced-js', image: '/img/icons/products/icon-advanced-js.svg', text: 'Webpack, Jest, Node.js, State Managers, ООП, ESlint, SASS, Data Layer', time: 'С опытом • 2 месяца', type: ProductType.Intensive, >, < id: '26', title: 'Марафон JavaScript «5 дней — 5 проектов»', link: '/products/marathon-js', image: '/img/icons/products/icon-marathon-five-x-five.svg', text: 'плагин для картинок, мини-кол Trello, слайдер картинок, мини-игра, анимированная игра', time: 'С нуля • 1 неделя', type: ProductType.Course, >, ]; @Injectable(< providedIn: 'root', >) export class ProductsService < readonly products: IProduct[] = products.map(addDomainToLinkAndImage); // получаем конкретный продукт getById(id: string) < return this.products.find((p) =>p.id === id); > // для удобного распределения по блокам в компоненте get byGroup() < return this.products.reduce((group, prod) => < if (!group[prod.type]) < group[prod.type] = []; >group[prod.type].push(prod); return group; >, <>); > > 

Создадим также компонент для отображения списка элементов и добавим в него код:

ng g c components/product-list 

import < Component, Input >from '@angular/core'; import < IProduct >from '../../services/products.service'; import < RouterLink >from '@angular/router'; @Component(< selector: 'app-product-list', standalone: true, imports: [RouterLink], // подключаем директиву, которая работает в шаблоне template: ` 

>

>

    >

    >

    >

    >
`, >) export class ProductListComponent < // прописываем входящие параметры в компонент и их тип @Input() title: string; @Input() subtitle: string; @Input() products: IProduct[]; >

Обратите внимание на новый синтаксис итерации внутри шаблона с директивой @for . По сути, этот компонент просто принимает три входящих параметра и выводит их красиво в шаблон.

Далее реализуем shop-page.component.ts:

import < ProductsService >from './../../services/products.service'; import < Component, inject >from '@angular/core'; import < TelegramService >from '../../services/telegram.service'; import < ProductListComponent >from '../../components/product-list/product-list.component'; @Component( < selector: 'app-shop', standalone: true, imports: [ProductListComponent], // регистрация компонента template: `   `, >) export class ShopComponent < // подключаем сервисы в компонент telegram = inject(TelegramService); products = inject(ProductsService); // прячем кнопку назад внутри телеграм constructor() < this.telegram.BackButton.hide(); >> 

Остальные страницы тоже не оставим без внимания:

import < Component, OnDestroy, OnInit >from '@angular/core'; import < IProduct, ProductsService >from '../../services/products.service'; import < TelegramService >from '../../services/telegram.service'; import < ActivatedRoute, Router >from '@angular/router'; @Component(< selector: 'app-product', standalone: true, template: ` 
>

>

>

Посмотреть курс
`, >) export class ProductComponent implements OnInit, OnDestroy < product: IProduct; constructor( private products: ProductsService, private telegram: TelegramService, private route: ActivatedRoute, private router: Router ) < // получаем динамический айди из адресной строки const // получаем конкретный продукт из сервиса this.product = this.products.getById(id); this.goBack = this.goBack.bind(this); >goBack() < this.router.navigate(['/']); >ngOnInit(): void < this.telegram.BackButton.show(); // добавляем функционал для перехода назад в телеграм this.telegram.BackButton.onClick(this.goBack); >ngOnDestroy(): void < this.telegram.BackButton.offClick(this.goBack); >>

pages/product.component.ts — выводит детальные данные отдельного продукта, найденного по id.

import < Component, OnDestroy, OnInit, signal >from '@angular/core'; import < TelegramService >from '../../services/telegram.service'; @Component( < selector: 'app-feedback', standalone: true, styles: ` .form < heigth: 70vh; justify-content: center; >`, template: ` 

`, >) export class FeedbackComponent implements OnInit, OnDestroy < // создаем стейт через сигнал feedback = signal(''); constructor(private telegram: TelegramService) < this.sendData = this.sendData.bind(this); >ngOnInit(): void < this.telegram.MainButton.setText('Отправить сообщение'); this.telegram.MainButton.show(); this.telegram.MainButton.disable(); this.telegram.MainButton.onClick(this.sendData); >sendData() < // отправляем данные в телеграм this.telegram.sendData(< feedback: this.feedback() >); > handleChange(event) < // изменение стейта при изменении textarea this.feedback.set(event.target.value); if (this.feedback().trim()) < this.telegram.MainButton.enable(); >else < this.telegram.MainButton.disable(); >> ngOnDestroy(): void < this.telegram.MainButton.offClick(this.sendData); >>

pages/feedback-component.ts. В последнем компоненте обратите внимание на использование signal в качестве local state.

Деплой фронтенда с Firebase

Чтобы связать наш фронтенд с Telegram, его нужно захостить. Переходим в Firebase, делаем новый проект и открываем Hosting. Далее по инструкции устанавливаем пакеты, а после — локально:

firebase login firebase init 

В файле firebase.json обновляем публичный путь до приложения:

"public": "dist/[PROJECT-NAME]/browser" 

Деплоим и получаем публичный URL:

firebase deploy 

Публичный URL заносим в константу webAppUrl в боте. Теперь при его запуске мы видим наше приложение.

Связка бота и веб-приложения

До этого в feedback.component.ts мы добавили отправку данных из формы:

sendData() < this.telegram.sendData(< feedback: this.feedback() >); > 

Теперь эти данные мы можем обработать в боте:

bot.on(message('web_app_data'), async (ctx) => < const data = ctx.webAppData.data.json() ctx.reply(`Ваше сообщение: $` ?? 'empty message') >) 

Супер — бот и приложение могут коммуницировать друг с другом!

Деплой проекта на облачный сервер

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

Подготовка

Будем деплоить бота в Docker — добавим два файла:

FROM node:16-alpine WORKDIR /app COPY package*.json ./ RUN npm ci COPY . . ENV PORT=3000 EXPOSE $PORT CMD ["npm", "start"] 
build: docker build -t tgbot . run: docker run -d -p 3000:3000 --name tgbot --rm tgbot 

Загрузка проекта

1. Переходим в раздел Облачная платформа внутри панели управления:

2. Создаем сервер. Для работы нашего приложения много мощностей не нужно, поэтому будет достаточно одного ядра vCPU с долей 20% и 512 МБ оперативной памяти:

3. Авторизуемся на сервере через консоль:

4. Обновляем систему и устанавливаем Git:

apt update apt install git 

5. Устанавливаем Node.js — полная инструкция доступна в Академии Selectel:

curl -o- | bash source ~/.bashrc nvm install 20 nvm use 20 npm -v node -v 

6. Устанавливаем на сервер Docker по инструкции.

7. Создаем репозиторий на GitHub, загружаем туда с компьютера наш проект и клонируем на сервер:

apt install git git clone REPO_URL 

8. Запускаем проект:

cd PROJECT_NAME make build make run 

Готово — бот c Telegram Mini Apps запущен.

Заключение

В этой инструкции мы не просто сделали интересное приложение, а изучили основы Telegram Mini Apps — от создания простого скрипта до деплоя на сервер. Полученные знания можно использовать при работе с более крупными проектами. Вне зависимости от того, какой они сложности, — в Selectel есть подходящая конфигурация.

Автор: Владилен Минин, создатель YouTube-канала.

Зарегистрируйтесь в панели управления

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

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

Инструкция

Как создать 100 серверов в облаке за минуту? Работа с OpenStack клиентом

Инструкция

Что делает команда chmod и как ее использовать в Linux

Инструкция

Как разработать gRCP-сервис на Go

Магазин в Телеграм-канале вместо бота. Инструкция: как настроить

Телеграм выпустил обновление и анонсировал возможность открывать WebApp по ссылке внутри каналов и чатов. Теперь вы можете закреплять сайты, игры, приложения и магазины, сделанные в WebApp, прямо внутри каналов и чатов. Покупки в Телеграме стали быстрыми и удобными – клиентам не нужно постоянно переходить в бот, чтобы просмотреть каталог и оформить заказ.

*Web app – это дословно веб-приложение, которое открывается внутри мессенджера.

Далее вы узнаете, как быстро интегрировать магазин в канал и продавать напрямую без перевода в бота.

Прежде всего, у вас уже должен быть магазин – на базе TGShop (настройка 10 минут) или другой платформы, где есть возможность скопировать ссылку на ваш WebApp. Магазин так же создается на базе бота – этого не избежать. Далее вы сможете выводить каталог в канал. В этом примере я взял магазин косметики.

Когда вы создали магазин, следуйте шагам:

1. Копируем ссылку на WebApp (ваш готовый магазин, приложение внутри Телеграма). Не перепутайте с юзернеймом бота в самом Телеграме. На скрине ниже показано, как это сделать на платформе TGShop. На других может быть иначе.

2. Переходим в BotFather в Телеграме. Выбираем команду /newapp и бота, в котором есть ваш магазин в WebApp.

3. Придумайте название и краткое описание для вашего WebApp, загрузите фото, следуя инструкциям BotFather. Описания могут быть такими же, когда вы создавали бот для магазина. Всё, что вы вводите на этом этапе, будет отображаться в предпросмотре ссылки ↓

4. Введите Web App URL (ссылку, которую вы скопировали в админке) и название для вашей ссылки (shop/menu/catalog или свой вариант).

5. Скопируйте готовую ссылку и закрепите в канале, чтобы ваши подписчики могли сразу перейти в магазин, а не в бота.

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

Если у вас остались вопросы, пишите!

#8 – Web Apps. Полноценные веб приложения в Телеграм

#8 – Web Apps. Полноценные веб приложения в Телеграм

Одним из новшеств Телеграм Ботов являются Веб приложения. За урок мы научимся создавать Web Apps, работать с их API, выводить данные про пользователя, а также получать информацию из Web App.

Видеоурок

Полезная ссылка:

  • Документация по Web Apps

Веб приложения были добавлены не так давно в Телеграм и уже стали очень популярным инструментом. Благодаря Web Apps вы можете добавить к вашему боту полноценное веб приложения, что может быть сайтом, игрой, магазином или чем-то еще.

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *