Interactive HTML5 Mini Apps on Telegram can completely replace any website.
They support seamless authorization, integrated payments via multiple payment providers (with Google Pay and Apple Pay out of the box), delivering tailored push notifications to users, and much more.
This article offers a client-side overview of the implementation of bot mini apps using the MTProto API: see here for an overview of the mini-app side JS API ».
Schema:
user#83314fca flags:# self:flags.10?true contact:flags.11?true mutual_contact:flags.12?true deleted:flags.13?true bot:flags.14?true bot_chat_history:flags.15?true bot_nochats:flags.16?true verified:flags.17?true restricted:flags.18?true min:flags.20?true bot_inline_geo:flags.21?true support:flags.23?true scam:flags.24?true apply_min_photo:flags.25?true fake:flags.26?true bot_attach_menu:flags.27?true premium:flags.28?true attach_menu_enabled:flags.29?true flags2:# bot_can_edit:flags2.1?true close_friend:flags2.2?true stories_hidden:flags2.3?true stories_unavailable:flags2.4?true contact_require_premium:flags2.10?true bot_business:flags2.11?true bot_has_main_app:flags2.13?true id:long access_hash:flags.0?long first_name:flags.1?string last_name:flags.2?string username:flags.3?string phone:flags.4?string photo:flags.5?UserProfilePhoto status:flags.6?UserStatus bot_info_version:flags.14?int restriction_reason:flags.18?Vector<RestrictionReason> bot_inline_placeholder:flags.19?string lang_code:flags.22?string emoji_status:flags.30?EmojiStatus usernames:flags2.0?Vector<Username> stories_max_id:flags2.5?int color:flags2.8?PeerColor profile_color:flags2.9?PeerColor bot_active_users:flags2.12?int = User;
webViewResultUrl#4d22ff98 flags:# fullsize:flags.1?true query_id:flags.0?long url:string = WebViewResult;
---functions---
messages.requestMainWebView#c9e01e7b flags:# compact:flags.7?true peer:InputPeer bot:InputUser start_param:flags.1?string theme_params:flags.0?DataJSON platform:string = WebViewResult;
Main Mini Apps are configured through @botfather.
Once enabled, the user.bot_has_main_app
flag will be set, and an "Open App" button should be shown on the bot's profile page.
Clicking on this button should open the Main Mini App, by invoking messages.requestMainWebView: no URL needs to be passed to the method, because the Main Mini App URL is configured through @botfather.
After invoking messages.requestMainWebView and obtaining a webViewResultUrl result, clients should open a webview using the url
contained in the returned webViewResultUrl.
The bot's profile page should also show a list of photos and videos, previewing the features offered by the Main Mini App, see Main Mini App previews for more info on how to configure and render them.
Main Mini Apps are also featured in the in-app Mini App Store ».
The Main Mini App should also be directly opened when clicking on a Main Mini App deep link »; the compact
flag of the method must be set if the mode
parameter in the link is set and equal to compact
; any eventual start_param
present in the link must also be passed to the method.
botInfo#82437e74 flags:# has_preview_medias:flags.6?true user_id:flags.0?long description:flags.1?string description_photo:flags.4?Photo description_document:flags.5?Document commands:flags.2?Vector<BotCommand> menu_button:flags.3?BotMenuButton privacy_policy_url:flags.7?string = BotInfo;
user#83314fca flags:# self:flags.10?true contact:flags.11?true mutual_contact:flags.12?true deleted:flags.13?true bot:flags.14?true bot_chat_history:flags.15?true bot_nochats:flags.16?true verified:flags.17?true restricted:flags.18?true min:flags.20?true bot_inline_geo:flags.21?true support:flags.23?true scam:flags.24?true apply_min_photo:flags.25?true fake:flags.26?true bot_attach_menu:flags.27?true premium:flags.28?true attach_menu_enabled:flags.29?true flags2:# bot_can_edit:flags2.1?true close_friend:flags2.2?true stories_hidden:flags2.3?true stories_unavailable:flags2.4?true contact_require_premium:flags2.10?true bot_business:flags2.11?true bot_has_main_app:flags2.13?true id:long access_hash:flags.0?long first_name:flags.1?string last_name:flags.2?string username:flags.3?string phone:flags.4?string photo:flags.5?UserProfilePhoto status:flags.6?UserStatus bot_info_version:flags.14?int restriction_reason:flags.18?Vector<RestrictionReason> bot_inline_placeholder:flags.19?string lang_code:flags.22?string emoji_status:flags.30?EmojiStatus usernames:flags2.0?Vector<Username> stories_max_id:flags2.5?int color:flags2.8?PeerColor profile_color:flags2.9?PeerColor bot_active_users:flags2.12?int = User;
botPreviewMedia#23e91ba3 date:int media:MessageMedia = BotPreviewMedia;
bots.previewInfo#0ca71d64 media:Vector<BotPreviewMedia> lang_codes:Vector<string> = bots.PreviewInfo;
---functions---
bots.getPreviewMedias#a2a5594d bot:InputUser = Vector<BotPreviewMedia>;
messages.uploadMedia#14967978 flags:# business_connection_id:flags.0?string peer:InputPeer media:InputMedia = MessageMedia;
bots.getPreviewInfo#423ab3ad bot:InputUser lang_code:string = bots.PreviewInfo;
bots.addPreviewMedia#17aeb75a bot:InputUser lang_code:string media:InputMedia = BotPreviewMedia;
bots.editPreviewMedia#8525606f bot:InputUser lang_code:string media:InputMedia new_media:InputMedia = BotPreviewMedia;
bots.deletePreviewMedia#2d0135b3 bot:InputUser lang_code:string media:Vector<InputMedia> = Bool;
bots.reorderPreviewMedias#b627f3aa bot:InputUser lang_code:string order:Vector<InputMedia> = Bool;
After enabling a main mini app » in @botfather, bots gain the ability to display localized preview medias (photos and videos) on their profile page, offering examples of what the app can do.
If a bot has some preview medias, the botInfo.has_preview_medias
flag will be set (botInfo is contained in the bot's userFull).
Clients should then invoke bots.getPreviewMedias to fetch&download the preview medias once the user opens the bot's profile page.
The method will automatically select the correctly localized variant of each preview, according to the language code of the user (as passed to initConnection when first setting up the client).
Bot owners may edit the preview medias directly through the API.
To check whether the current user can edit the preview medias of a bot, make sure both the bot_can_edit
and bot_has_main_app
flags of the bot's user constructor are set.
Then, bots.getPreviewInfo should be invoked by bot owners to fetch the previously configured preview medias.
Pass an empty string to lang_code
when first invoking the method to fetch the previously configured default preview medias (used as fallback if there is no preview for the current user's language), and the list of lang_codes
for which there are localized previews; then re-invoke the method to fetch the previously configured previews for each of the returned lang_codes
.
(Note: technically non-owners may also invoke bots.getPreviewInfo, but it will always behave exactly as bots.getPreviewMedias, returning only previews for the current language and an empty lang_codes
array, regardless of the passed lang_code
, so please only use bots.getPreviewMedias if you're not the owner).
Then, use bots.addPreviewMedia, bots.editPreviewMedia, bots.reorderPreviewMedias, bots.deletePreviewMedia, uploading medias using messages.uploadMedia as usual to setup fallback and localized previews for existing and new languages.
As specified above, each language can have a distinct set of previews that may be edited and reordered independently.
The default, fallback language has an empty lang_code
.
A maximum of bot_preview_medias_max » preview medias may be added per localization key.
Schema:
replyKeyboardMarkup#85dd99d1 flags:# resize:flags.0?true single_use:flags.1?true selective:flags.2?true persistent:flags.4?true rows:Vector<KeyboardButtonRow> placeholder:flags.3?string = ReplyMarkup;
keyboardButtonSimpleWebView#a0c0505c text:string url:string = KeyboardButton;
messageActionWebViewDataSentMe#47dd8079 text:string data:string = MessageAction;
messageActionWebViewDataSent#b4c38cb5 text:string = MessageAction;
webViewResultUrl#4d22ff98 flags:# fullsize:flags.1?true query_id:flags.0?long url:string = WebViewResult;
---functions---
messages.requestSimpleWebView#413a3e73 flags:# from_switch_webview:flags.1?true from_side_menu:flags.2?true compact:flags.7?true bot:InputUser url:flags.3?string start_param:flags.4?string theme_params:flags.0?DataJSON platform:string = WebViewResult;
messages.sendWebViewData#dc0242c8 bot:InputUser random_id:long button_text:string data:string = Updates;
Keyboard Button Mini Apps should be opened when the user clicks a keyboardButtonSimpleWebView contained in a reply keyboard identified by a replyKeyboardMarkup constructor, by invoking messages.requestSimpleWebView passing the button's url
to the url
parameter.
After invoking messages.requestSimpleWebView and obtaining a webViewResultUrl result, clients should open a webview using the url
contained in the returned webViewResultUrl.
Keyboard Button Mini Apps can send data back to the bot through the MTProto API via a web_app_data_send
JS event ».
Upon receiving a web_app_data_send
JS event » only from Keyboard Button Mini Apps, clients should invoke messages.sendWebViewData, passing the following arguments:
bot
- Bot IDrandom_id
- Unique random ID to avoid resending the same event multiple timesbutton_text
- Text of the keyboardButtonSimpleWebView that was pressed to open the simple Mini Appdata
- Contents of the data
field of the JS event. Make sure to ignore all web_app_data_send
events sent after the first one, messages.sendWebViewData must be called only once. The webview must be closed after invoking the messages.sendWebViewData method.
This will generate a messageActionWebViewDataSent update for the user, and a messageActionWebViewDataSentMe update for the bot, containing the event data.
Schema:
keyboardButtonWebView#13767230 text:string url:string = KeyboardButton;
webViewResultUrl#4d22ff98 flags:# fullsize:flags.1?true query_id:flags.0?long url:string = WebViewResult;
inputBotInlineResult#88bf9319 flags:# id:string type:string title:flags.1?string description:flags.2?string url:flags.3?string thumb:flags.4?InputWebDocument content:flags.5?InputWebDocument send_message:InputBotInlineMessage = InputBotInlineResult;
inputBotInlineResultPhoto#a8d864a7 id:string type:string photo:InputPhoto send_message:InputBotInlineMessage = InputBotInlineResult;
inputBotInlineResultDocument#fff8fdc4 flags:# id:string type:string title:flags.1?string description:flags.2?string document:InputDocument send_message:InputBotInlineMessage = InputBotInlineResult;
inputBotInlineResultGame#4fa417f2 id:string short_name:string send_message:InputBotInlineMessage = InputBotInlineResult;
updateWebViewResultSent#1592b79d query_id:long = Update;
webViewMessageSent#c94511c flags:# msg_id:flags.0?InputBotInlineMessageID = WebViewMessageSent;
---functions---
messages.requestWebView#269dc2c1 flags:# from_bot_menu:flags.4?true silent:flags.5?true compact:flags.7?true peer:InputPeer bot:InputUser url:flags.1?string start_param:flags.3?string theme_params:flags.2?DataJSON platform:string reply_to:flags.0?InputReplyTo send_as:flags.13?InputPeer = WebViewResult;
messages.prolongWebView#b0d81a83 flags:# silent:flags.5?true peer:InputPeer bot:InputUser query_id:long reply_to:flags.0?InputReplyTo send_as:flags.13?InputPeer = Bool;
messages.sendWebViewResultMessage#a4314f5 bot_query_id:string result:InputBotInlineResult = WebViewMessageSent;
Inline Button Mini Apps work similarly to inline bots »: they send messages on behalf of the user to the chat from which the query originated.
When the user clicks on an keyboardButtonWebView inline button contained in an inline keyboard identified by a replyInlineMarkup constructor, messages.requestWebView should be invoked, passing keyboardButtonWebView.url
must be passed to the method's url
parameter.
Then, clients should open a webview using the url
contained in the returned webViewResultUrl.
After loading the webview, until it is closed by a web_app_close event, the user client must invoke messages.prolongWebView every 60 seconds: if the method call returns QUERY_ID_INVALID
, the webview must be closed.
The opened URL's fragment parameters already contain basic information about the user and a query_id
parameter, that is exposed by the bot Mini Apps JS library: this query_id
can then be passed to the bot (within the Mini App itself, for example via an AJAX query or form submission to the server hosting the Mini App and the bot) and then used by the bot to invoke messages.sendWebViewResultMessage, passing an InputBotInlineResult constructor that will automatically send a message with optionally attached media, and even inline buttons on behalf of the user.
Menu button Mini Apps work similarly to inline button Mini Apps »: they send messages on behalf of the user to the chat from where the bot menu button » was clicked.
Menu button Mini Apps can be opened from a botMenuButton menu button »: in this case, the messages.requestWebView.from_bot_menu
flag should be set, and the botMenuButton.url
field must be passed to the method's url
parameter.
The full flow is identical to the flow for inline button Mini Apps », apart from the different flags passed to messages.requestWebView, as described above.
Attachment menu Mini Apps work similarly to inline button Mini Apps »: they send messages on behalf of the user to the chat where the bot's attachment menu » was opened.
Attachment menu Mini Apps can be opened from an attachment menu entry »: in this case, no special flag should be set when invoking messages.requestWebView.
Attachment menu Mini Apps can also be opened from a bot attachment menu deep link, in which case the start_parameter
should be provided to messages.requestWebView.start_param
, if present, and the compact
flag must be set if the mode
parameter is set and equal to compact
.
The full flow is identical to the flow for inline button Mini Apps », apart from the different flags passed to messages.requestWebView, as described above.
messages.botResults#e021f2f6 flags:# gallery:flags.0?true query_id:long next_offset:flags.1?string switch_pm:flags.2?InlineBotSwitchPM switch_webview:flags.3?InlineBotWebView results:Vector<BotInlineResult> cache_time:int users:Vector<User> = messages.BotResults;
inlineBotWebView#b57295d5 text:string url:string = InlineBotWebView;
webViewResultUrl#4d22ff98 flags:# fullsize:flags.1?true query_id:flags.0?long url:string = WebViewResult;
---functions---
messages.getInlineBotResults#514e999d flags:# bot:InputUser peer:InputPeer geo_point:flags.0?InputGeoPoint query:string offset:string = messages.BotResults;
messages.requestSimpleWebView#413a3e73 flags:# from_switch_webview:flags.1?true from_side_menu:flags.2?true compact:flags.7?true bot:InputUser url:flags.3?string start_param:flags.4?string theme_params:flags.0?DataJSON platform:string = WebViewResult;
Not to be confused with inline button mini apps ».
Inline mode Mini Apps can be used to generate a custom set of inline results in response to a user's inline query » via a web_app_switch_inline_query
JS event ».
Inline mode Mini Apps can be opened by clicking on an inlineBotWebView button returned at the top of the inline result list, contained in messages.botResults.switch_webview
, returned by messages.getInlineBotResults.
Pass the url
to messages.requestSimpleWebView, while also setting the from_switch_webview
flag.
After invoking messages.requestSimpleWebView and obtaining a webViewResultUrl result, clients should open a webview using the url
contained in the returned webViewResultUrl.
Once the user has finished making their choices in the Mini App, a web_app_switch_inline_query
JS event » should be emitted, containing a JSON object with the following fields:
query
- The inline query that will be inserted in the chat's input field, after the bot's username.chat_types
- An array of strings, containing a combination of users
, bots
, groups
, channels
.Upon receiving a web_app_switch_inline_query
JS event » from the Mini App, the client should make a new inline query » to the same bot, with the newly specified query
, either in the current chat or in the newly chosen chat, as specified by the chat_types
field.
webViewResultUrl#4d22ff98 flags:# fullsize:flags.1?true query_id:flags.0?long url:string = WebViewResult;
---functions---
messages.requestSimpleWebView#413a3e73 flags:# from_switch_webview:flags.1?true from_side_menu:flags.2?true compact:flags.7?true bot:InputUser url:flags.3?string start_param:flags.4?string theme_params:flags.0?DataJSON platform:string = WebViewResult;
Side menu Mini Apps can be opened by clicking on the installed side menu entry ».
This action must trigger a messages.requestSimpleWebView query with the from_side_menu
flag set: clients should open a webview using the url
contained in the returned webViewResultUrl.
After invoking messages.requestSimpleWebView and obtaining a webViewResultUrl result, clients should open a webview using the url
contained in the returned webViewResultUrl.
Schema:
inputBotAppID#a920bd7a id:long access_hash:long = InputBotApp;
inputBotAppShortName#908c0407 bot_id:InputUser short_name:string = InputBotApp;
botAppNotModified#5da674b7 = BotApp;
botApp#95fcd1d6 flags:# id:long access_hash:long short_name:string title:string description:string photo:Photo document:flags.0?Document hash:long = BotApp;
messages.botApp#eb50adf5 flags:# inactive:flags.0?true request_write_access:flags.1?true has_settings:flags.2?true app:BotApp = messages.BotApp;
webViewResultUrl#4d22ff98 flags:# fullsize:flags.1?true query_id:flags.0?long url:string = WebViewResult;
---functions---
messages.getBotApp#34fdc5c3 app:InputBotApp hash:long = messages.BotApp;
messages.requestAppWebView#53618bce flags:# write_allowed:flags.0?true compact:flags.7?true peer:InputPeer app:InputBotApp start_param:flags.1?string theme_params:flags.2?DataJSON platform:string = WebViewResult;
Another way to open Mini Apps is by using Direct Mini App links ».
These links are different from all other Mini App links, because they don't require the user to install an attachment menu, and a single bot can offer multiple Mini Apps, distinguished by their short_name
.
These links should be handled as follows:
Check if bot_username
parameter of the link is indeed a bot username, if so then
Invoke messages.getBotApp, passing an inputBotAppShortName with the short_name
contained in the appname
query string parameter.
If the client has already encountered an app with this short name from the same bot before, pass the hash
of the cached botApp constructor to messages.getBotApp.
If a messages.botApp constructor is returned, open the Mini App by invoking messages.requestAppWebView, generating an inputBotAppID constructor from id
and access_hash
of the returned botApp, or from previously cached information if we already met the bot app and botAppNotModified was returned.
If the client has clicked on the link in a Telegram chat, pass the chat's peer information into peer
; otherwise pass the bot's peer information, instead.
If the messages.botApp.request_write_access
flag is set, the bot is asking permission to send messages to the user: ask confirmation from the user with a prompt and a checkbox, and if the user agrees, set the write_allowed
flag when invoking messages.requestAppWebView.
If the messages.botApp.inactive
flag is set, ask confirmation from the user before opening the Mini App; the request_write_access
checkbox should be shown in this prompt, if needed.
Confirmation should always be asked, even if the inactive
flag is not set, when opening the link from places where the full link is not visible (i.e. messageEntityTextUrl text links, inline buttons etc.).
Don't use two prompts if confirmation to open the Mini App is required and request_write_access
is set, use just one prompt with an optional checkbox for request_write_access
.
If the startapp
query string parameter is present, pass it to start_param
when invoking messages.requestAppWebView.
Finally, open the webview using the url
contained in the returned webViewResultUrl.
Mini Apps can send web events starting with web_app_
; see the web event documentation for the full list of events that can be sent by the Mini App to the client ».
Mini Apps can also receive events, by exposing a window.Telegram.WebView.receiveEvent("event_name", params)
method.
Here's the full list of events that can be received by a Mini App from the client, if the client invokes the receiveEvent
method.
main_button_pressed
Params: null
Sent by the client when the user presses the main button located at the bottom of the webview, handle this event only if the main button was previously configured by a web_app_setup_main_button
event ».
back_button_pressed
Params: null
Sent by the client when the user presses the (OS or UI) back button, if it was previously enabled by a web_app_setup_back_button
event ».
settings_button_pressed
Params: null
Sent by the client when the user presses the settings button, if it was previously enabled by a web_app_setup_settings_button
event ».
invoice_closed
Params: JSON object with the following fields:
slug
- Invoice identifier (string)status
- One of the following values (string):cancelled
– The user closed the invoice popup without paying, before the call to payments.sendPaymentForm.failed
– The user tried to pay, but the payment failed: the call to payments.sendPaymentForm returned an RPC error and the popup was closed.pending
– The payment is still processing: the bot will receive a further service message about a successful payment. payments.sendPaymentForm was successfully invoked returning payments.paymentVerificationNeeded, the user completed all additional verification forms returned by the method and the invoice popup was closed, but the client hasn't received a messageActionPaymentSent service message yet.failed
event if the user fails additional validation (ie 3-D Secure) returned by payments.paymentVerificationNeeded: the state will remaing pending
. paid
– The invoice was paid successfully: the client completed the payment flow », the invoice popup was closed and a messageActionPaymentSent service message was received by the client.Sent by the client to report the payment status of an invoice obtained from a web_app_open_invoice
event ».
viewport_changed
Params: a JSON object with the following fields:
height
- The current height of the visible area of the Mini App (excluding the bottom main button, if visible) (integer)is_state_stable
- If true, the viewport is currently being resized (animation in progress), more events of this type may be emitted. (boolean)is_expanded
- Whether the Mini App is expanded to its maximum height after the user swiped up or after the Mini App emitted a web_app_expand event (boolean)Emitted when the viewport is changed.
theme_changed
Params: a JSON object with the following fields:
theme_params
- A theme parameters object » (object)Emitted when requested by the Mini App using a web_app_request_theme
event », or when the app theme changes.
Bot Mini Apps can be themed according to the following theme parameters, passed as a JSON object to the theme_params
parameter of the messages.requestSimpleWebView, messages.requestWebView and messages.requestAppWebView methods.
This JSON object has the following keys, containing color theme information (hex string, RGB, no alpha) to pass to the Mini App:
bg_color
- Background colorsecondary_bg_color
- Secondary background colortext_color
- Text colorhint_color
- Hint text colorlink_color
- Link colorbutton_color
- Button colorbutton_text_color
- Button text colorheader_bg_color
- Header background coloraccent_text_color
- Accent text colorsection_bg_color
- Section background colorsection_header_text_color
- Section header text colorsection_separator_color
- Section separator colorsubtitle_text_color
- Sub title text colordestructive_text_color
- Text color for destructive action buttons in promptspopup_closed
Params: a JSON object with an optional button_id
string field.
Emitted when the user presses a button or cancels a popup brought up by a previous web_app_open_popup
event ».
write_access_requested
Params: a JSON object with the following fields:
status
- allowed
or cancelled
Used by clients to reply to a web_app_request_write_access
event », indicating whether the user has allowed the bot to send messages to the user (allowed
) or not (cancelled
).
phone_requested
Params: a JSON object with the following fields:
status
- sent
or cancelled
Used by clients to reply to a web_app_request_phone
event », indicating whether the user has shared their phone number with the bot (allowed
) or not (cancelled
).
biometry_info_received
Params: a JSON object with the following fields:
available
- boolean, if true, indicates that biometric authentication is available on the current device.type
- optional string, set if available
is true, contains the type of biometric authentication, one of:finger
- fingerprint-based biometricsface
- face-based biometricsunknown
- biometrics of an unknown typeaccess_requested
- boolean, indicates whether the app has previously requested permission to use biometrics through a web_app_biometry_request_access
event »access_granted
- boolean, indicates whether the user has granted the app permission to use biometrics in response to a web_app_biometry_request_access
event ».access_requested
is true, the user has denied the app permission to use biometrics, in which case the app should open a prompt notifying the user that the biometric settings must be changed to use biometrics, and if the user clicks on the in-app confirm button, a web_app_biometry_open_settings event » must be emitted.token_saved
- boolean, whether a token was safely stored on-device by a previous web_app_biometry_update_token event ». device_id
- string, a unique device identifier that can be used to match the token to the device.Used by clients to reply to a web_app_biometry_get_info
event » or a web_app_biometry_request_access
event ».
biometry_token_updated
Params: a JSON object with the following fields:
status
- string, one of:updated
- If the token was successfully updated.removed
- If the token was successfully removed.failed
- If biometric authentication failed, or the app doesn't have permission to use biometrics (a biometry_info_received event » event will also be emitted if the app hasn't previously initialized the state using web_app_biometry_get_info
event » or a web_app_biometry_request_access
event »). Used by clients to reply to a web_app_biometry_update_token
event ».
biometry_auth_requested
Params: a JSON object with the following fields:
status
- string, either authorized
or failed
.failed
, a biometry_info_received event » event will also be emitted if the app hasn't previously initialized the state using web_app_biometry_get_info
event » or a web_app_biometry_request_access
event ». token
- optional string, set if status
is authorized
, contains the token previously set using the web_app_biometry_update_token
event ». Used by clients to reply to a web_app_biometry_request_auth
biometric authentication request ».
custom_method_invoked
Params: a JSON object with the following fields:
req_id
- The req_id
from the web_app_invoke_custom_method
requestresult
- The JSON data contained in the response of the bots.invokeWebViewCustomMethod method, if the method call succeedederror
- The text of the RPC error, if the method call failedUsed by clients to reply to web_app_invoke_custom_method
events ».
clipboard_text_received
Params: a JSON object with the following fields:
req_id
- The req_id
from the web_app_read_text_from_clipboard
requestdata
- A string with the clipboard contents (optional, if not provided consider the request failed)Used by clients to reply to web_app_read_text_from_clipboard
events ».
qr_text_received
Params: a JSON object with the following fields:
data
- string with the contents of a scanned QR code.Emitted by clients if a new QR code was scanned by the native QR code scanner opened with a web_app_open_scan_qr_popup
event ».
scan_qr_popup_closed
Params: null
or an empty object
Emitted by clients if the QR code scanner popup opened with a web_app_open_scan_qr_popup
event » was closed by the user or failed to open altogether due to permission issues.