13 мин чтения
Как обрабатывать данные Telegram WebApp Bot без дополнительного HTTP сервера используя aiogram python библиотеку?
В статье разбираемся как написать telegram webapp бота на python? какими способами можно запустить telegram mini-app? как создать webapp с помощью aiogram? как обрабатывать данные telegram webapp без внешнего http-сервера? как работает tg.sendData?
Введение
В Telegram существует несколько способов обработки данных MiniApp (WebApp-приложений), которые зависят от способа загрузки приложения в Telegram-боте. Каждый из способов имеет свои особенности и ограничения, которые необходимо учитывать при разработке приложения. Некоторым способам требуется обработка callback на стороннем сервере для валидации данных, а другим достаточно просто отправить данные в бота с помощью JavaScript-функции и обработать их там. В этой заметке мы рассмотрим, как отправить данные в Telegram-боте с помощью aiogram без использования внешнего HTTP-сервера, каким приложениям подходит этот способ, а также какие ограничения существуют при его использовании. Весь исходный код приложения доступен на GitHub по ссылке в репозитории JoraDevLab/aiogram-webapp-keyboard-launch-starter, который можно использовать в качестве шаблона для создания своего бота.
Подготовка
Это руководство идеально подойдет, если вы уже умеете создавать ботов в Telegram с помощью BotFather, а также имеете базовые знания Python и принципов работы aiogram. В этой заметке мы сосредоточимся на механизмах отправки данных с помощью aiogram, а не на создании самого бота.
Для успешного запуска примеров кода вам понадобятся следующие инструменты:
- Python 3.8+
- aiogram 3.20+
- PyCharm или другая удобная для вас IDE для разработки на Python
- VSCode 2023.2+ или любая другая IDE для веб-разработки
- Node.js 18.0+ и npm 8.0+ для локального тестирования webapp
- Telegram-аккаунт
Способы запуска webapp
Веб-приложение может быть загружено в Telegram-боте несколькими способами:
- через inline-клавиатуру (inline keyboard button),
- через кнопку в меню бота (menu button),
- через custom-клавиатуру (custom keyboard button).

Способы запуска webapp (картинка с сайта https://core.telegram.org/bots/webapps)
Какими способами можно получить данные пользователя в webapp?
- initData / initDataUnsafe: строка, содержащая информацию о пользователе и его настройках. Она передается в webapp при его запуске и может быть использована для авторизации пользователя. Доступна только при запуске webapp через inline-клавиатуру или кнопку меню.
- sendData: метод, позволяющий отправить данные из webapp в бота. Он может быть использован для передачи данных, собранных в webapp, например, формы или других пользовательских данных. Доступен при запуске webapp через custom-кнопку клавиатуры.
NOTE: initData и sendData
initData
и sendData
- это два разных способа передачи данных между webapp и ботом в Telegram, которые не могут быть использованы одновременно!
Как использовать initData в webapp?
При запуске WebApp в Telegram через inline-клавиатуру или кнопку меню (что с точки зрения Telegram API является разновидностью inline-кнопки)
Telegram передает информацию о пользователе, query_id и API answerWebAppQuery для многократной отправки данных в бекенд бота.
Упомянутые данные пользователя доступны в контексте JavaScript-приложения через объект window.Telegram.WebApp.initData
и window.Telegram.WebApp.initDataUnsafe
.
Однако для корректной авторизации пользователя информация из initDataUnsafe
должна быть отправлена на бекенд-сервер бота для проверки и валидации данных пользователя с использованием hash-алгоритма по hashId сообщения и токену бота
(подробнее об алгоритме можно узнать по ссылке на официальную документацию Telegram).
Таким образом, в этом случае необходимо использовать сторонний HTTP-сервер для валидации данных пользователя бота.
Шаблон приложения с запуском webapp по кнопке меню и авторизацией пользователей через отдельный HTTP-сервер можно найти в документации aiogram по ссылке github.com/aiogram/aiogram/tree/dev-3.x/examples/web_app.
Как использовать sendData в webapp?
В этом случае необходимо использовать метод window.Telegram.WebApp.sendData
для передачи данных из webapp в бота.
Этот метод позволяет отправить данные из webapp в бота без необходимости использования стороннего HTTP сервера.
При этом данные передаются в виде строки и могут быть обработаны обычным обработчиком сообщений в боте.
Какие ограничения существуют при запуске webapp через custom keyboard button?
- Информация пользователя не доступна в UI: в ui нет доступа ни к
tg.initData
, ни кtg.initDataUnsafe
, соответственно невозможно отобразить данные пользователя в интерфейсе или использовать данные пользователя для 3rd-party авторизации. - Отправить данные из webapp можно только 1 раз: после старта webapp в боте отправить данные в бота с помощью
tg.sendData
можно только 1 раз за сессию вызова webapp. - Ограничение в 4 Кб на данные: максимальный размер данных, которые можно отправить в бота с помощью
tg.sendData
, составляет 4096 байт. Это ограничение связано с тем, что данные передаются через URL и могут быть ограничены длиной URL.
Таким образом способ с custom клавиатурой подходит для простых приложений, в которых интерфейс используется для заполнения форм и однократной отправки данных в бота для дальнейшей обработки. Если такое решение вам подходит, то предлагаю рассмотреть минимальную необходимую конфигурацию для создания подобного бота в дальнейших шагах.
Step 1. Создаем бота в BotFather
В первую очедерь нужно создать нового бота в @BotFather и получите токен доступа. Пропустите этот шаг, если у вас уже есть бот и токен доступа к нему. Для этого необходимо выполнить несколько простых шагов:
- начать диалог с https://t.me/BotFather
- ввести команду
/newbot
- ввести имя бота
- ввести username бота
- получить токен доступа к боту и сохранить его для следующих шагов.
Step 2. Пишем код бота на aiogram
В этом шаге создадим бота на aiogram, который будет обрабатывать данные, отправленные из webapp. Для запуска бота из примеров в этой заметке можно просто активировать необходимый venv(при наличии) и установить необходимые зависимости из requirements.txt:
pip install -r requirements.txt
При создании нового проекта на Python с нуля и установим необходимые зависимости:
pip install -U aiogram
pip install -U python-dotenv
Создадим файл .env в корне проекта и добавим туда токен доступа к боту полученный на предыдущем шаге и URL(который мы заполним позднее) для запуска webapp:
# .env
BOT_TOKEN=...
WEB_APP_URL=...
Создадим файл web_app_bot.py
и добавим туда код бота.
В этом коде мы создаем бота, который обрабатывает команду /start
и отправляет пользователю клавиатуру с кнопкой для запуска webapp.
При нажатии на кнопку запускается webapp, который мы создадим в следующем шаге.
При нажатии на кнопку "ℹ️ Information" бот отправляет пользователю сообщение с информацией о боте.
При нажатии на кнопку "🚀 Launch WebApp" запускается webapp, который мы создадим в следующем шаге.
import asyncio
import logging
from os import getenv
import dotenv
from aiogram import Bot, Dispatcher, types, F
from aiogram.filters import CommandStart
from aiogram.types import WebAppInfo, ReplyKeyboardMarkup
dotenv.load_dotenv()
API_TOKEN = getenv('BOT_TOKEN')
WEBAPP_URL = getenv('WEB_APP_URL')
bot = Bot(token=API_TOKEN)
dp = Dispatcher()
logging.basicConfig(level=logging.INFO)
@dp.message(CommandStart())
async def start(message: types.Message):
"""Handle the /start command from user and print custom keyboard."""
kb = [
[
types.KeyboardButton(text="🚀 Launch WebApp", web_app=WebAppInfo(url=WEBAPP_URL))
],
[
types.KeyboardButton(text="ℹ️ Information")
],
]
keyboard = ReplyKeyboardMarkup(
keyboard=kb,
resize_keyboard=True,
input_field_placeholder="Choose an action"
)
await message.answer("Welcome! Choose an action:", reply_markup=keyboard)
@dp.message(F.text == "ℹ️ Information")
async def info(message: types.Message):
"""Handle the information button and print predefined message."""
await message.answer("This is a Telegram bot with a WebApp interface. Click the first button to launch the WebApp.")
#@dp.message(F.content_type == types.ContentType.WEB_APP_DATA)
@dp.message(F.web_app_data)
async def web_app_data_handler(message: types.Message):
"""Handle data sent from the WebApp."""
await message.answer(f"✅ Data received from WebApp:\n{message.web_app_data.data}")
async def main() -> None:
"""Start the bot."""
await dp.start_polling(bot)
if __name__ == "__main__":
asyncio.run(main())
Step 3. Создаем UI
Для создания UI webapp можно использовать любой фреймворк для создания веб-приложений, например React, Vue.js или просто HTML и CSS.
В этом примере мы создадим простое HTML-приложение с формой, которая будет отправлять данные в бота при нажатии на кнопку "Отправить" на чистом javascript.
Создадим файл webapp.html
в папке static
и добавим туда следующий код:
Подключаем скрипт telegram-web-app.js
в хедере страницы и создаем кнопку для отправки данных в бота.
<script src="https://telegram.org/js/telegram-web-app.js"></script>
Инициализируем объект tg
и используем функуию tg.sendData
для отправки заполненной формы и текущего времени в бота.
Полный код страницы представлен ниже.
NOTE: --tg- CSS префикс
Переменные с префиксом --tg- (например, --tg-theme-bg-color, --tg-theme-text-color) — это пользовательские CSS-свойства (также известные как CSS-переменные), предоставляемые JavaScript-библиотекой Telegram WebApp. Эти переменные динамически задаются Telegram для отражения текущей темы приложения Telegram (например, светлой или темной) и позволяют разработчикам стилизовать свои WebApp в соответствии с интерфейсом Telegram.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Telegram WebApp</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
body {
font-family: sans-serif;
display: flex;
flex-direction: column;
align-items: center;
padding-top: 50px;
background-color: var(--tg-theme-bg-color, #ffffff);
color: var(--tg-theme-text-color, #000000);
}
input {
padding: 0.5em;
font-size: 16px;
margin-bottom: 20px;
border: 1px solid var(--tg-theme-hint-color, #cccccc);
border-radius: 4px;
width: 80%;
max-width: 300px;
}
button {
padding: 1em 2em;
font-size: 16px;
background: var(--tg-theme-button-color, #2ea6ff);
color: var(--tg-theme-button-text-color, white);
border: none;
border-radius: 8px;
cursor: pointer;
}
button:hover {
opacity: 0.9;
}
</style>
<script src="https://telegram.org/js/telegram-web-app.js"></script>
</head>
<body>
<h2>Telegram WebApp</h2>
<input id="user-input" type="text" placeholder="Enter some data" />
<button id="send-btn">Send Data</button>
<script>
const tg = window.Telegram.WebApp;
tg.ready();
document.getElementById('send-btn').addEventListener('click', () => {
const userInput = document.getElementById('user-input').value;
// const user = tg.initDataUnsafe.user; NOT SUPPORTED DURING INLINE BUTTON LAUNCH
tg.sendData(JSON.stringify({
timestamp: Date.now(),
userInput: userInput
}));
});
</script>
</body>
</html>

Интерфейс нашего webapp, открытого в Telegram
Step 4. Обработка web_app данных в боте
Напишем обработчик для данных, отправленных из webapp в бота, в файле web_app_bot.py
на aiogram.
За это отвечает фильтр F.web_app_data
.
@dp.message(F.web_app_data)
async def web_app_data_handler(message: types.Message):
"""Handle data sent from the WebApp."""
await message.answer(f"✅ Data received from WebApp:\n{message.web_app_data.data}")
В этом обработчике мы просто отправляем обратно данные, которые были отправлены из webapp в бота. В реальном приложении вы можете использовать эти данные для дальнейшей обработки, например, сохранить их в базе данных или отправить пользователю сообщение с результатами обработки.
NOTE: Фильтры F.web_app_data и F.content_type
Разница между использованием F.content_type == types.ContentType.WEB_APP_DATA
и фильтром F.web_app_data
в aiogram заключается в механизме фильтрации входящих обновлений.
F.content_type == types.ContentType.WEB_APP_DATA
- это более низкоуровневый фильтр, который проверяет тип контента сообщения. Он может быть использован для фильтрации сообщений по различным типам контента, включая текстовые сообщения, фотографии и т.д. В данном случае он проверяет, является ли сообщение типа WEB_APP_DATA
.
F.web_app_data
- это более высокоуровневый фильтр, который специально предназначен для обработки данных, отправленных из WebApp. Он автоматически обрабатывает входящие сообщения, если они содержат поле web_app_data
. Последний способ более универсален, так как наличие этого поля в сообщении гарантирует, что данные из webapp были получены.
Step 5. Как настроить локальный запуск Telegram WebApp?
Запускаем локально статический сервер из папки static
с помощью npm-библиотеки serve:
cd static
npx serve
Проверяем, что сервер запущен и доступен по адресу http://localhost:3000/webapp.html. Если все работает, переходим к следующему шагу.
Теперь нужно сделать так, чтобы бот знал, по какому адресу доступен webapp.
Telegram не позволяет запускать webapp по локальному адресу, поэтому нужно использовать публичный адрес по HTTPS-протоколу.
Для тестирования нужно использовать сервис для порт-форвардинга, чтобы сделать локальный сервер доступным из интернета.
Используем для этого VSCode Port Forwarding. Для этого откроем наш проект в Visual Studio Code.
Переходим во вкладку PORTS, как на скриншоте, и нажимаем на кнопку "Forward a Port", вводим 3000.
После этого внизу появится ссылка на ваш локальный сервер, который будет доступен из интернета.
Переходим на пункт меню visibility
и выбираем Public
.
Полученную ссылку вставляем в .env
файл в переменную WEBAPP_URL
.

Настраиваем форвардинг портов в VSCode
НЕ ЗАБУДЬТЕ ВЫКЛЮЧИТЬ ПОРТ-ФОРВАРДИНГ ПОСЛЕ ТЕСТИРОВАНИЯ, ЧТОБЫ НЕ ПОДВЕРГАТЬ СВОЙ КОМПЬЮТЕР РИСКУ.
Step 6. Запускаем бота и тестируем
- Запустите бота командой
python web_app_bot.py
в терминале или в вашей IDE. - Начните диалог с ботом командой
/start
и перейдите в меню бота. - Нажмите на кнопку
🚀 Launch WebApp
, чтобы открыть веб-приложение. - Введите данные в форму и нажмите кнопку "Отправить".
- Проверьте, что данные были успешно отправлены в бота и обработаны - подтверждением этого будет служить системное сообщение в чате с ботом
Data from the "🚀 Launch WebApp" button was transferred to the bot.
как на скриншоте.

Пример использования webapp в Telegram
PROFIT!
Заключение
Спасибо что прочитали эту заметку до конца! Исходный код приложения доступен на GitHub по ссылке в репозитории JoraDevLab/aiogram-webapp-keyboard-launch-starter. Если у вас есть вопросы или предложения, не стесняйтесь открывать issue в репозитории, а также пожалуйста поставьте звезду ⭐ репозиторию если статья была для вас полезна. Удачи в разработке ваших Telegram WebApp ботов!