Creation of telegram web apps and interaction with them in telegram bots

In update Bot API 6.0 Telegram bots have received many new features. Of these, for developers, the most remarkable is Telegram Web Apps (Web applications inside telegrams). With this innovation, developers can connect web applications to their bots that open in an additional window, which greatly expands the toolkit, and, consequently, the functionality of telegram bots.

Telegram apps are known for their speed, fluidity, and cross-platform design. Your web application should ideally follow these principles.

– All elements should be responsive and designed with mobile devices in mind.
– Interactive elements should mimic the style, behavior, and purpose of already existing user interface components.
– All animations should be smooth, ideally 60 frames per second.
– All inputs and images must contain a label for accessibility.
– The application should provide a seamless experience by tracking the change in theme colors using the API and using them appropriately.

Let’s try it out in practice!

Creating a button

The first thing we need to do is create a web application launch button. This can be done in two ways:

1. With the help of @botfather – button on the bottom left

1.1. Go to @botfather and write the command: /setmenubutton

1.2. Next, select the bot that needs the web application button

1.3. We send a link where our web application is available

1.4. We write the name of the button – it will be displayed at the bottom left

creating a button via @botfather
creating a button via @botfather
what does the main button look like
what does the main button look like

That’s all. In general, if you have a responsive website and just wanted to add it to the bot, you can stop here.

Only when adding a button this way we can get information about user.

2. In the bot code – keyboard buttons.

Launching the bot from an inline button gives the essence the same as the previous option. However, starting from keyboard button allows you to send data from the web application to the bot.

I’ll show you using pytelegrambotapi as an example – I understand that this is not the most popular library for writing telegram bots, but it so happened that I write on it. If you are using another library/language, I think it will not be difficult for you to follow the analogy. You can immediately see example or go to repository and see the code with comments:

2.1. We do all the standard things to start the bot – importing the library, entering the token, infinity_polling, the start command handler. If you don’t understand what I mean, you here.

2.2. We create a function that will return us a keyboard with the desired button.

In order to create a button, you must first create a WebAppInfo object inside which there will be a url to our site.

def webAppKeyboard(): #создание клавиатуры с webapp кнопкой
   keyboard = types.ReplyKeyboardMarkup(row_width=1) #создаем клавиатуру
   webAppTest = types.WebAppInfo("https://telegram.mihailgok.ru") #создаем webappinfo - формат хранения url
   one_butt = types.KeyboardButton(text="Тестовая страница", web_app=webAppTest) #создаем кнопку типа webapp
   keyboard.add(one_butt) #добавляем кнопки в клавиатуру

   return keyboard #возвращаем клавиатуру

2.3. We send a message with our keyboard when we send a command or any other action:

bot.send_message( message.chat.id, 'Привет, я бот для проверки телеграмм webapps!)', reply_markup=webAppKeyboard()) 

Ready. We have buttons.

You can finish here if you just wanted the user to be able to open your site from the bot (for some reason). It will work like this:

how web apps work
how web apps work

Working with the web application

Now let’s go to our web application. At the time of writing, any link opens, even to codepen.

Initialization

To interact with telegrams, we connect the script:

<script src="https://telegram.org/js/telegram-web-app.js"></script>

After that, the object will be available to us: window.Telegram.WebApp

We write it to a variable and start our work.

let tg = window.Telegram.WebApp;

What can we do now? Not as much as I would like, but not enough either. The application consists of: the main button (telegram-object) and the page itself, which was loaded by the link. The remaining elements of the telegram interface are not available to us. However, user theme colors are available:

color navigator
color navigator

Colors

They are available in hex format as css variables:

var(--tg-theme-bg-color)
var(--tg-theme-text-color)
var(--tg-theme-hint-color)
var(--tg-theme-link-color)
var(--tg-theme-button-color)
var(--tg-theme-button-text-color)

Or as an object ThemeParams in js (instead of window.Telegram.WebApp I use tg variable):

tg.ThemeParams.bg_color
tg.ThemeParams.text_color
tg.ThemeParams.hint_color
tg.ThemeParams.link_color
tg.ThemeParams.button_color
tg.ThemeParams.button_text_colorString

But be careful, colors are optional, so it’s worth checking if they are there before using them.

There is also a color scheme change event handler:

Telegram.WebApp.onEvent(themeChanged, function(){});

At change color scheme or window size, you can change something in our web application.

Key features

We figured out the flowers – now to others main parameters:

tg.initData //получаем данные от пользователя в виде строки (работает только при запуске из меню команд бота). 
tg.initDataUnsafe // получаем данные от пользователя в виде объекта (работает только при запуске из меню команд бота). 
tg.isExpanded // возвращает true, если приложение открыто на всю высоту, false - если нет. 
tg.viewportHeight // вернёт ширину окна.
tg.sendData(data) // отправляет данные  боту в строковом виде, после чего закрывает приложение (работает только если приложение запущено с keyboard button). 
tg.ready() // метод позволяет отследить, когда приложение готово к отображению.
tg.expand() // метод позволяет растянуть окно на всю высоту.
tg.close() // метод закрывает приложение.

Main button

We can interact with button at the bottom of the application. Change its text, background and text color, show/hide, make active and deactivate:

tg.MainButton.text // текст кнопки, по умолчанию: "Continue"
tg.MainButton.color // цвет текста
tg.MainButton.textColor // цвет подложки
tg.MainButton.isVisible // видна ли кнопка (по умолчанию false) 
tg.MainButton.isActive // активна ли кнопка (по умолчанию true)
tg.MainButton.setText(text) //  метод для задания текста
tg.MainButton.onClick(callback) // метод при нажатии на кнопку
tg.MainButton.show() // показать кнопку 
tg.MainButton.hide() // скрыть кнопку
tg.MainButton.enable() // сделать активной 
tg.MainButton.disable() // сделать неактивной 
tg.MainButton.setParams(params) // задает параметры в виде объекта 
Main button in test @DurgerKingBot
Main button in test @DurgerKingBot

Web App User

And further information about the user, we can parse the string tg.initData or use tg.initDataUnsafe an object:

tg.initDataUnsafe.user.id // уникальный идентификатор пользователя
tg.initDataUnsafe.user.isBot // бот ли пользователь (true/false)
tg.initDataUnsafe.user.first_name // имя пользователя
tg.initDataUnsafe.user.last_name // "фамилия" пользователя
tg.initDataUnsafe.user.username // username пользователя
tg.initDataUnsafe.user.language_code // код языка пользователя

Writing a web application

With this information, we can write a small application that visually displays the main features.

Don’t forget to include the script:

<script src="https://telegram.org/js/telegram-web-app.js"></script>

1. Let’s create a small html base:

<body>
   <div id="usercard"> <!--Карта профиля, человека, который к нам обратился-->
   </div>
   <p>Just text</p> <!--Просто текст для проверки-->
   <a class="link" href="https://mihailgok.ru">Link</a> <!--Просто ссылка для проверки-->
   <p class="hint">Some little hint</p> <!--Просто текст-подсказка для проверки-->
   <button id="btn" class="button">Show/Hide Main Button</button> <!--Кнопка, чтобы скрыть / показать основную кнопку-->
   <button id="btnED" class="button">Enable/Disable Main Button</button> <!--Кнопка, чтобы сделать кнопку активной/неактивной-->
</body>

2. Write changes to the text of the main button and change the color:

let tg = window.Telegram.WebApp; //получаем объект webapp телеграма 

tg.expand(); //расширяем на все окно  

tg.MainButton.text = "Changed Text"; //изменяем текст кнопки 
tg.MainButton.setText("Changed Text1"); //изменяем текст кнопки иначе
tg.MainButton.textColor = "#F55353"; //изменяем цвет текста кнопки
tg.MainButton.color = "#143F6B"; //изменяем цвет бэкграунда кнопки
tg.MainButton.setParams({"color": "#143F6B"}); //так изменяются все параметры 

3. Next, we will hang an event handler on the first html button and, when pressed, we will show / hide the main telegram button:

btn.addEventListener('click', function(){ //вешаем событие на нажатие html-кнопки
	if (tg.MainButton.isVisible){ //если кнопка показана 
		tg.MainButton.hide() //скрываем кнопку 
	}
  else{ //иначе
  	tg.MainButton.show() //показываем 
  }
});

4. Another event handler for the second html button, when pressed, we will activate / deactivate the main telegram button:

let btnED = document.getElementById("btnED"); //получаем кнопку активировать/деактивировать
btnED.addEventListener('click', function(){ //вешаем событие на нажатие html-кнопки
	if (tg.MainButton.isActive){ //если кнопка показана 
		tg.MainButton.setParams({"color": "#E0FFFF"}); //меняем цвет
		tg.MainButton.disable() //скрываем кнопку 
	}
	else{ //иначе
		tg.MainButton.setParams({"color": "#143F6B"}); //меняем цвет
		tg.MainButton.enable() //показываем 
	}
});

5. As a result, we send data when you click on the main telegram button:

Telegram.WebApp.onEvent('mainButtonClicked', function(){
	tg.sendData("some string that we need to send"); 
	//при клике на основную кнопку отправляем данные в строковом виде
});

Thanks to this method, we can get data from the web application in the bot.

6. We will also display all information about the user (it will only be available when launched from a button added with @botfather).
Available to us: id / isBot / first_name / last_name / username / language_code

let usercard = document.getElementById("usercard"); //получаем блок usercard 

let profName = document.createElement('p'); //создаем параграф
profName.innerText = `${tg.initDataUnsafe.user.first_name}
${tg.initDataUnsafe.user.last_name}
${tg.initDataUnsafe.user.username} (${tg.initDataUnsafe.user.language_code})`;
//выдем имя, "фамилию", через тире username и код языка
usercard.appendChild(profName); //добавляем 

let userid = document.createElement('p'); //создаем еще параграф 
userid.innerText = `${tg.initDataUnsafe.user.id}`; //показываем user_id
usercard.appendChild(userid); //добавляем

7. And add styles using telegram-css variables:

body{
	color: var(--tg-theme-text-color);
	background: var(--tg-theme-bg-color);
	display: flex;
	flex-direction: column;
	align-items: center;
	font-size: 18px;
}

.hint{
	color: var(--tg-theme-hint-color);
}

.link{
	color: var(--tg-theme-link-color);
}

.button{
	background: var(--tg-theme-button-color);
	color: var(--tg-theme-button-text-color);
	border: none;
	font-size: 18px;
}

.button:not(:last-child){
	margin-bottom: 20px
}

#usercard{
	text-align: center;
}

As a result, we get the following web application:

It displays the main features – getting information about the user, using the colors of his theme, and controlling the main button of the application.

We receive data from a web application in a bot

Now we hang an event handler on the message that the web application sends in the send method (it will only work with the keyboard button):

@bot.message_handler(content_types="web_app_data") #получаем отправленные данные 
def answer(webAppMes):
   print(webAppMes) #вся информация о сообщении
   print(webAppMes.web_app_data.data) #конкретно то что мы передали в бота
   bot.send_message(webAppMes.chat.id, f"получили инофрмацию из веб-приложения: {webAppMes.web_app_data.data}") 
   #отправляем сообщение в ответ на отправку данных из веб-приложения 

And that’s all – now we can receive information from the site and respond to it.
There are other ways – but that’s a slightly different story.

Sources: github, code pen
Bot example

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *