Telegram bots can completely replace any website. They support seamless authorization, integrated payments via 15 payment providers (with Google Pay and Apple Pay out of the box), delivering tailored push notifications to users, and much more.
With Web Apps, bots get a whole new dimension. Bot developers can create infinitely flexible interfaces with JavaScript, the most widely used programming language in the world.
To see a Web App in action, try our sample @DurgerKingBot.
Web Apps always receive data about the user's current color theme in real time, so you can adjust the appearance of your interfaces to match it. For example, when users switch between Day and Night modes or use various custom themes.
Telegram apps are known for being snappy, smooth and following a consistent cross-platform design. Your Web App should ideally reflect these principles.
Telegram currently supports four different ways of launching Web Apps: from a keyboard button, from an inline button, from the bot menu button – and even from the attachment menu.
TL;DR: Web Apps launched from a web_app type keyboard button can send data back to the bot in a service message using Telegram.WebApp.sendData. This makes it possible for the bot to produce a response without communicating with any external servers.
Users can interact with bots using custom keyboards, buttons under bot messages, as well as by sending freeform text messages or any of the attachment types supported by Telegram: photos and videos, files, locations, contacts and polls. For even more flexibility, bots can utilize the full power of HTML5 to create user-friendly input interfaces.
You can send a web_app type KeyboardButton that opens a Web App from the specified URL.
To transmit data from the user back to the bot, the Web App can call the Telegram.WebApp.sendData method. Data will be transmitted to the bot as a String in a service message. The bot can continue communicating with the user after receiving it.
Good for:
TL;DR: For more interactive Web Apps like @DurgerKingBot, use a web_app type Inline KeyboardButton, which gets basic user information and can be used to send a message on behalf of the user to the chat with the bot.
If receiving text data alone is insufficient or you need a more advanced and personalized interface, you can open a Web App using a web_app type Inline KeyboardButton.
From the button, a Web App will open with the URL specified in the button. In addition to the user's theme settings, it will receive basic user information (ID
, name
, username
, language_code
) and a unique identifier for the session, query_id, which allows messages on behalf of the user to be sent back to the bot.
The bot can call the Bot API method answerWebAppQuery to send an inline message from the user back to the bot and close the Web App. After receiving the message, the bot can continue communicating with the user.
Good for:
TL;DR: Web Apps can be launched from a customized menu button. This simply offers a quicker way to access the app and is otherwise identical to launching a Web App from an inline button.
By default, chats with bots always show a convenient menu button that provides quick access to all listed commands. With Bot API 6.0, this button can be used to launch a Web App instead.
To configure the menu button, you must specify the text it should show and the Web App URL. There are two ways to set these parameters:
/setmenubutton
command or Bot Settings > Menu Button).Apart from this, Web Apps opened via the menu button work in the exact same way as when using inline buttons.
@DurgerKingBot allows launching its Web App both from an inline button and from the menu button.
TL;DR: Web App Bots can request to be added directly to a user's attachment menu, allowing them to be quickly launched from any private chat. To try this mode, open this attachment menu link for @DurgerKingBot, then use the menu in any private chat.
Web App Bots can request to be added directly to a user's attachment menu, allowing them to be quickly launched from any private chat (with either a user or another bot).
Attachment menu integration is currently only available for major advertisers on the Telegram Ad Platform. However, all bots can use it in the test server environment.
To enable this feature for your bot, open @BotFather from an account on the test server and send the /setattach
command – or go to Bot Settings > Configure Attachment Menu. Then specify the URL that will be opened to launch the bot's Web App via its icon in the attachment menu.
In addition to the user's theme settings, the bot will receive basic user information (ID
, name
, username
, language_code
, photo
), as well as public info about the chat partner (ID
, name
, username
, photo
) and a unique identifier for the web view session query_id, which allows messages of any type to be sent to the chat on behalf of the user that opened the bot.
The bot can call the Bot API method answerWebAppQuery, which sends an inline message from the user via the bot to the private chat where it was launched and closes the Web App.
You can read more about adding bots to the attachment menu here.
To connect your Web App to the Telegram client, place the script telegram-web-app.js in the <head>
tag before any other scripts, using this code:
<script src="https://telegram.org/js/telegram-web-app.js"></script>
Once the script is connected, a window.Telegram.WebApp
object will become available with the following fields:
Field | Type | Description |
---|---|---|
initData | String | A string with raw data transferred to the Web App, convenient for validating data. WARNING: Validate data from this field before using it on the bot's server. |
initDataUnsafe | WebAppInitData | An object with input data transferred to the Web App. WARNING: Data from this field should not be trusted. You should only use data from initData on the bot's server and only after it has been validated. |
colorScheme | String | The color scheme currently used in the Telegram app. Either “light” or “dark”. Also available as the CSS variable var(--tg-color-scheme) . |
themeParams | ThemeParams | An object containing the current theme settings used in the Telegram app. |
isExpanded | Boolean | True if the Web App is expanded to the maximum available height. False, if the Web App occupies part of the screen and can be expanded to the full height using the expand() method. |
viewportHeight | Float | The current height of the visible area of the Web App. Also available in CSS as the variable var(--tg-viewport-height) .The application can display just the top part of the Web App, with its lower part remaining outside the screen area. From this position, the user can “pull” the Web App to its maximum height, while the bot can do the same by calling the expand() method. As the position of the Web App changes, the current height value of the visible area will be updated in real time. Please note that the refresh rate of this value is not sufficient to smoothly follow the lower border of the window. It should not be used to pin interface elements to the bottom of the visible area. It's more appropriate to use the value of the viewportStableHeight field for this purpose. |
viewportStableHeight | Float | The height of the visible area of the Web App in its last stable state. Also available in CSS as a variable var(--tg-viewport-stable-height) .The application can display just the top part of the Web App, with its lower part remaining outside the screen area. From this position, the user can “pull” the Web App to its maximum height, while the bot can do the same by calling the expand() method. Unlike the value of viewportHeight , the value of viewportStableHeight does not change as the position of the Web App changes with user gestures or during animations. The value of viewportStableHeight will be updated after all gestures and animations are completed and the Web App reaches its final size.Note the event viewportChanged with the passed parameter isStateStable=true , which will allow you to track when the stable state of the height of the visible area changes. |
MainButton | MainButton | An object for controlling the main button, which is displayed at the bottom of the Web App in the Telegram interface. |
onEvent(eventType, eventHandler) | Function | A method that sets the app event handler. Check the list of available events. |
offEvent(eventType, eventHandler) | Function | A method that deletes a previously set event handler. |
sendData(data) | Function | A method used to send data to the bot. When this method is called, a service message is sent to the bot containing the data data of the length up to 4096 bytes, and the Web App is closed. See the field web_app_data in the class Message. This method is only available for Web Apps launched via a Keyboard button. |
ready() | Function | A method that informs the Telegram app that the Web App is ready to be displayed. It is recommended to call this method as early as possible, as soon as all essential interface elements are loaded. Once this method is called, the loading placeholder is hidden and the Web App is shown. If the method is not called, the placeholder will be hidden only when the page is fully loaded. |
expand() | Function | A method that expands the Web App to the maximum available height. To find out if the Web App is expanded to the maximum height, refer to the value of the Telegram.WebApp.isExpanded parameter |
close() | Function | A method that closes the Web App. |
Web Apps can adjust the appearance of the interface to match the Telegram user's app in real time. This object contains the user's current theme settings:
Field | Type | Description |
---|---|---|
bg_color | String | Optional. Background color in the #RRGGBB format.Also available as the CSS variable var(--tg-theme-bg-color) . |
text_color | String | Optional. Main text color in the #RRGGBB format.Also available as the CSS variable var(--tg-theme-text-color) . |
hint_color | String | Optional. Hint text color in the #RRGGBB format.Also available as the CSS variable var(--tg-theme-hint-color) . |
link_color | String | Optional. Link color in the #RRGGBB format.Also available as the CSS variable var(--tg-theme-link-color) . |
button_color | String | Optional. Button color in the #RRGGBB format.Also available as the CSS variable var(--tg-theme-button-color) . |
button_text_color | String | Optional. Button text color in the #RRGGBB format.Also available as the CSS variable var(--tg-theme-button-text-color) . |
This object controls the main button, which is displayed at the bottom of the Web App in the Telegram interface.
Field | Type | Description |
---|---|---|
text | String | Current button text. Set to CONTINUE by default. |
color | String | Current button color. Set to themeParams.button_color by default. |
textColor | String | Current button text color. Set to themeParams.button_text_color by default. |
isVisible | Boolean | Shows whether the button is visible. Set to false by default. |
isActive | Boolean | Shows whether the button is active. Set to true by default. |
isProgressVisible | Boolean | Readonly. Shows whether the button is displaying a loading indicator. |
setText(text) | Function | A method to set the button text. |
onClick(callback) | Function | A method that sets the button press event handler. An alias for Telegram.WebApp.onEvent('mainButtonClicked', callback) |
show() | Function | A method to make the button visible. Note that opening the Web App from the attachment menu hides the main button until the user interacts with the Web App interface. |
hide() | Function | A method to hide the button. |
enable() | Function | A method to enable the button. |
disable() | Function | A method to disable the button. |
showProgress(leaveActive) | Function | A method to show a loading indicator on the button. It is recommended to display loading progress if the action tied to the button may take a long time. By default, the button is disabled while the action is in progress. If the parameter leaveActive=true is passed, the button remains enabled. |
hideProgress() | Function | A method to hide the loading indicator. |
setParams(params) | Function | A method to set the button parameters. The params parameter is an object containing one or several fields that need to be changed: text - button text; color - button color; text_color - button text color; is_active - enable the button; is_visible - show the button. |
All these methods return the MainButton object so they can be chained.
This object contains data that is transferred to the Web App when it is opened. It is empty if the Web App was launched from a keyboard button.
Field | Type | Description |
---|---|---|
query_id | String | Optional. A unique identifier for the Web App session, required for sending messages via the answerWebAppQuery method. |
user | WebAppUser | Optional. An object containing data about the current user. |
receiver | WebAppUser | Optional. An object containing data about the chat partner of the current user in the chat where the bot was launched via the attachment menu. Returned only for Web Apps launched via the attachment menu. |
start_param | String | Optional. The value of the startattach parameter, passed via link. Only returned for Web Apps when launched from the attachment menu via link. The value of the start_param parameter will also be passed in the GET-parameter tgWebAppStartParam , so the Web App can load the correct interface right away. |
auth_date | Integer | Unix time when the form was opened. |
hash | String | A hash of all passed parameters, which the bot server can use to check their validity. |
This object contains the data of the Web App user.
Field | Type | Description |
---|---|---|
id | Integer | A unique identifier for the user or bot. This number may have more than 32 significant bits and some programming languages may have difficulty/silent defects in interpreting it. It has at most 52 significant bits, so a 64-bit integer or a double-precision float type is safe for storing this identifier. |
is_bot | Boolean | Optional. True, if this user is a bot. Returns in the receiver field only. |
first_name | String | First name of the user or bot. |
last_name | String | Optional. Last name of the user or bot. |
username | String | Optional. Username of the user or bot. |
language_code | String | Optional. IETF language tag of the user's language. Returns in user field only. |
photo_url | String | Optional. URL of the user’s profile photo. The photo can be in .jpeg or .svg formats. Only returned for Web Apps launched from the attachment menu. |
To validate data received via the Web App, one should send the data from the Telegram.WebApp.initData field to the bot's backend. The data is a query string, which is composed of a series of field-value pairs.
You can verify the integrity of the data received by comparing the received hash parameter with the hexadecimal representation of the HMAC-SHA-256 signature of the data-check-string with the secret key, which is the HMAC-SHA-256 signature of the bot's token with the constant string WebAppData
used as a key.
Data-check-string is a chain of all received fields, sorted alphabetically, in the format key=<value>
with a line feed character ('\n', 0x0A) used as separator – e.g., 'auth_date=<auth_date>\nquery_id=<query_id>\nuser=<user>'
.
The full check might look like:
data_check_string = ...
secret_key = HMAC_SHA256(<bot_token>, "WebAppData")
if (hex(HMAC_SHA256(data_check_string, secret_key)) == hash) {
// data is from Telegram
}
To prevent the use of outdated data, you can additionally check the auth_date field, which contains a Unix timestamp of when it was received by the Web App.
Once validated, the data may be used on your server. Complex data types are represented as JSON-serialized objects.
The Web App can receive events from the Telegram app, onto which a handler can be attached using the Telegram.WebApp.onEvent(eventType, eventHandler)
method. Inside eventHandler
the this object refers to Telegram.WebApp, the set of parameters sent to the handler depends on the event type. Below is a list of possible events:
eventType | Description |
---|---|
themeChanged |
Occurs whenever theme settings are changed in the user's Telegram app (including switching to night mode). eventHandler receives no parameters, new theme settings and color scheme can be received via this.themeParams and this.colorScheme respectively. |
viewportChanged |
Occurs when the visible section of the Web App is changed. eventHandler receives an object with the single field isStateStable. If isStateStable = true, the resizing of the Web App is finished. If it is false, the resizing is ongoing (the user is expanding or collapsing the Web App or an animated object is playing). The current value of the visible section’s height is available in this.viewportHeight. |
mainButtonClicked |
Occurs when the main button is pressed. eventHandler receives no parameters. |
Attachment menu integration is currently only available for major advertisers on the Telegram Ad Platform. However, all bots can use it in the test server environment. Talk to Botfather on the test server to set up the integration.
A special link is used to add bots to the attachment menu:
https://t.me/botusername?startattach
orhttps://t.me/botusername?startattach=command
For example, open this attachment menu link for @DurgerKingBot, then use the menu in any private chat.
Opening the link prompts the user to add the bot to their attachment menu. If the bot has already been added, the attachment menu will open in the current chat and redirect to the bot there (if the link is opened from a 1-on-1 chat). If a non-empty startattach parameter was included in the link, it will be passed to the Web App in the start_param field and in the GET parameter tgWebAppStartParam.
The following link formats are also supported:
https://t.me/username?attach=botusername
https://t.me/username?attach=botusername&startattach=command
https://t.me/+1234567890?attach=botusername
https://t.me/+1234567890?attach=botusername&startattach=command
These links open the Web App in the attachment menu in the chat with a specific user. If the bot wasn't already added to the attachment menu, the user will be prompted to do so. If a non-empty startattach parameter was included in the link, it will be passed to the Web App in the start_param field and in the GET parameter tgWebAppStartParam.
To log in to the test environment, use either of the following:
The test environment is completely separate from the main environment, so you will need to create a new user account and a new bot with @BotFather.
After receiving your bot token, you can send requests to the Bot API in this format:
https://api.telegram.org/bot<token>/test/METHOD_NAME