<p>When interacting with HTML5 games, websites of payment gateways and <ahref="/api/bots/webapps">bot mini apps</a>, Telegram apps should expose APIs to allow receiving data and events from the websites.</p>
<p>Games, payment gateways and <ahref="/api/bots/webapps">bot mini apps</a> can generate events that are meant to be received by the Telegram apps.
Typically events are generated by using the <code>postEvent</code> method of the <ahref="https://github.com/TelegramMessenger/GamingCommunication/blob/master/games.js">GamingCommunication library</a>, or by the <ahref="/bots/webapps#initializing-mini-apps">bot mini apps library</a>.<br>
<p>In mobile apps, the event receiver API should be typically exposed as a <code>window.TelegramWebviewProxy</code> object with a <code>postEvent</code> method.</p>
<p>Finally, web MTProto clients that need to open a game, open a <ahref="/api/bots/webapps">bot mini app</a> or process a payment in an iframe can use the <ahref="https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage">postMessage API</a> to receive events from iframes.<br>
The GamingCommunication and bot mini apps libraries by default will use <code>'*'</code> as <code>targetOrigin</code>, sending messages to parent pages regardless of the origin of the embedder.</p>
<p><code>eventType</code> is a simple string indicating the event type, and <code>eventData</code> is a payload with an object that will be parsed by the Telegram app.</p>
<p>Event data: a JSON object with the following fields (which should be properly validated by the client).</p>
<ul>
<li><code>title</code> - Title for the popup (optional string, max 64 characters)</li>
<li><code>message</code> - Message of the popup (string, max 256 characters)</li>
<li><code>buttons</code> - An array of the following objects (array of 1-3 objects)<ul>
<li><code>type</code> - Button type (string, one of <code>ok</code>, <code>close</code>, <code>cancel</code>, <code>default</code>, <code>destructive</code> (in this case, the button must be red))</li>
<li><code>text</code> - Button text (string, optional for <code>ok</code>, <code>close</code> and <code>cancel</code> types)</li>
<li><code>id</code> - Button ID (unique string)</li>
<li>If the user presses any of the buttons, call <code>window.Telegram.WebView.receiveEvent("popup_closed", {"button_id": "<button id>"})</code></li>
<li>If the user cancels the interaction without pressing any of the specified buttons, call <code>window.Telegram.WebView.receiveEvent("popup_closed", {})</code></li>
</ul>
<p>Disable handling of this event if a popup is already being displayed, re-enable handling only after the <code>popup_closed</code> response event is emitted.<br>
While handling is enabled, maximum 3 consecutive valid events of this type can be handled in a timespan of 3 seconds, ignore excess events. </p>
<p>Emitted by <ahref="/api/bots/webapps">bot mini apps</a> to ask permission from the user to send them messages. </p>
<p>Upon receiving this event, clients should first invoke <ahref="/method/bots.canSendMessage">bots.canSendMessage</a>, to check whether they have already granted the bot permission to write them in some way. </p>
<ul>
<li>If the method returns <ahref="/constructor/boolTrue">boolTrue</a>, a <ahref="/api/bots/webapps#write-access-requested">write_access_requested event »</a> with <code>{"status": "allowed"}</code> should be sent to the Mini App.</li>
<li>Otherwise, if the method returns <ahref="/constructor/boolFalse">boolFalse</a>, a prompt should be shown to the user, indicating that the bot is asking permission to send messages to them.<br>
If the user accepts, invoke <ahref="/method/bots.allowSendMessage">bots.allowSendMessage</a>, and if the method call succeeds emit a <ahref="/api/bots/webapps#write-access-requested">write_access_requested event »</a> with <code>{"status": "allowed"}</code>.<br>
Otherwise, if the user refuses or the <ahref="/method/bots.allowSendMessage">bots.allowSendMessage</a> call fails, emit a <ahref="/api/bots/webapps#write-access-requested">write_access_requested event »</a> with <code>{"status": "cancelled"}</code>.</li>
<p>Emitted by <ahref="/api/bots/webapps">bot mini apps</a> to ask the user to share their phone number as a contact.</p>
<p>Upon receiving this event, clients should show a prompt to the user, indicating that the bot is asking them to share their phone number (optionally also asking the user to unblock the bot, if it's currently blocked). </p>
<p>If they accept, the user's phone number should be shared by sending a contact to the bot (unblocking it first, if it's currently blocked by the user); if all RPC queries (to unblock the bot, to send the message) succeed, a <ahref="/api/bots/webapps#write-access-requested">phone_requested event »</a> should be sent with <code>{"status": "sent"}</code>. </p>
<p>If the user refuses or any intermdiate method call fails, a <ahref="/api/bots/webapps#write-access-requested">phone_requested event »</a> should be sent with <code>{"status": "cancelled"}</code>. </p>
<p>Event data: a JSON object with the following fields:</p>
<ul>
<li><code>req_id</code> - A string with the ID of the current request</li>
<li><code>method</code> - A string, containing the name of the called custom method</li>
<li><code>params</code> - An object containing the parameters of the method call</li>
</ul>
<p>Emitted by <ahref="/api/bots/webapps">bot mini apps</a> to make custom method calls to Telegram's servers on behalf of the user. </p>
<p>This event should trigger a <ahref="/method/bots.invokeWebViewCustomMethod">bots.invokeWebViewCustomMethod</a> request, passing the <code>method</code> to <code>custom_method</code>, and the <code>params</code> to <code>params</code>. </p>
<p>Upon receiving a reply, a <ahref="/api/bots/webapps#custom-method-invoked">custom_method_invoked event »</a> should be emitted, with the following fields:</p>
<ul>
<li><code>req_id</code> - The <code>req_id</code> from the <code>web_app_invoke_custom_method</code> object</li>
<li><code>result</code> - The JSON data contained in the response of the <ahref="/method/bots.invokeWebViewCustomMethod">bots.invokeWebViewCustomMethod</a> method, if the method call succeeded</li>
<li><code>error</code> - The text of the RPC error, if the method call failed</li>
<p>Event data: a JSON object with the following fields:</p>
<ul>
<li><code>req_id</code> - A string with the ID of the current request</li>
</ul>
<p>Emitted by <ahref="/api/bots/webapps">bot mini apps</a> to obtain the contents of the system clipboard. </p>
<p>Only for Mini Apps owned by bots added to the <ahref="/api/bots/attach">attachment menu</a>, regardles of how the Mini App itself was launched, this event should trigger a <ahref="/api/bots/webapps#clipboard-text-received">clipboard_text_received event »</a> with the following payload: </p>
<ul>
<li><code>req_id</code> - The <code>req_id</code> from the <code>web_app_read_text_from_clipboard</code> request</li>
<li><code>data</code> - A string with the clipboard contents</li>
</ul>
<p>Note that this method can be called only in response to a user interaction with the Mini App interface (e.g. a click inside the Mini App or on the main or settings button).<br>
Note that user interactions must have a TTL of 10 seconds: events of this type must be ignored and a <ahref="/api/bots/webapps#clipboard-text-received">clipboard_text_received event »</a> with the correct <code>req_id</code> and no <code>data</code> field must be sent if the last Mini App user interaction (as described above) happened more than 10 seconds ago. </p>
<p>A <ahref="/api/bots/webapps#clipboard-text-received">clipboard_text_received event »</a> with the correct <code>req_id</code> and no <code>data</code> field must also be sent if the bot is not installed in the <ahref="/api/bots/attach">attachment menu</a>.</p>
<p>Event data: a JSON object with the following fields:</p>
<ul>
<li><code>text</code> - Optional string, containing the text to be displayed under the 'Scan QR' heading, 0-64 characters. </li>
</ul>
<p>Emitted by <ahref="/api/bots/webapps">bot mini apps</a> to prompt the client to open the native QR code scanner and start continuously scanning for QR codes. </p>
<p>A <ahref="/api/bots/webapps#qr-text-received"><code>qr_text_received</code> event »</a> should be emitted every time a new QR code is scanned, until the user closes the popup via the UI or the Mini App closes the popup with a <ahref="#web-app-close-scan-qr-popup">web_app_close_scan_qr_popup</a> event.</p>
<p>Closing the popup should emit a <ahref="/api/bots/webapps#scan-qr-popup-closed"><code>scan_qr_popup_closed</code> event »</a>; the same event should be emitted if the scan QR code popup cannot be opened due to permission issues. </p>
<p>Emitted by <ahref="/api/bots/webapps">bot mini apps</a> to prompt the client to close the native QR code scanner opened using <ahref="#web-app-open-scan-qr-popup">web_app_open_scan_qr_popup</a>. </p>
<p>The <ahref="/api/bots/webapps#scan-qr-popup-closed"><code>scan_qr_popup_closed</code> event »</a> event should <em>not</em> be emitted if the QR code popup is closed using this event. </p>
<p>Event data: a JSON object with a boolean <code>need_confirmation</code>.</p>
<p>If equal to <code>true</code>, the client should require user confirmation with a "Changes that you made may not be saved." popup with "Cancel"/"Close anyway" buttons before closing the webview, to avoid accidentally aborting a sensitive operation; otherwise no confirmation should be requested. </p>
<li><code>bg_color</code> - The <code>bg_color</code> from the <ahref="/api/bots/webapps#theme-parameters">theme parameters</a> should be used.</li>
<li><code>secondary_bg_color</code> - The <code>secondary_bg_color</code> from the <ahref="/api/bots/webapps#theme-parameters">theme parameters</a> should be used.</li>
<p>Used <strong>only</strong> by <ahref="/api/bots/webapps#keyboard-button-mini-apps">keyboard button mini apps</a> to send back data to the bot as specified <ahref="/api/bots/webapps#keyboard-button-mini-apps">here »</a>. The Mini App will be closed. </p>
<p>Event data: a JSON object with the following keys:</p>
<ul>
<li><code>query</code> - The inline query that will be inserted in the chat's input field, after the bot's username.<br>
May be an empty string, in which case just the bot's username will be inserted, triggering an empty inline query.</li>
<li><code>chat_types</code> - An array of strings, containing a combination of <code>users</code>, <code>bots</code>, <code>groups</code>, <code>channels</code>.<br>
If non-empty, the client should prompt the user to choose a specific chat of the specified type(s), then open the chosen chat and inserts the bot's username and the specified inline query in the input field.<br>
The array values specify which types of chats the user will be able to choose from.<br>
If empty, the current chat is used. </li>
</ul>
<p>Used by <ahref="/api/bots/webapps#inline-mode-mini-apps">inline mode mini apps</a> to send back data to the bot as specified <ahref="/api/bots/webapps#inline-mode-mini-apps">here »</a>. The Mini App will be closed. </p>
<p>Event data: a JSON object with the following fields:</p>
<ul>
<li><code>url</code> - The URL to open</li>
<li><code>try_instant_view</code> - Optional boolean, if set, equal to <code>true</code> and the scheme of the URL is either <code>http</code> or <code>https</code>, the link should be opened in <ahref="/methods#working-with-instant-view-pages">Instant View mode</a> if possible. </li>
</ul>
<p>Used to open a link in an external browser (or in a new tab for browser clients). The Mini App will not be closed. </p>
<p>Note that this method can be called only in response to a user interaction with the Mini App interface (e.g. a click inside the Mini App or on the main or settings button).<br>
After opening the URL, further events of this type should be ignored until the user interacts again with the Mini App interface (as above).<br>
Note that user interactions must have a TTL of 1 second: events of this type must be ignored if the last Mini App user interaction happened more than 1 second ago.</p>
<p>Event data: a JSON object with a string <code>path_full</code> field, containing the path+query component of a <ahref="/api/links">t.me deep link</a> (<code>url = 'https://t.me' + path_full</code>). </p>
<p>Used to initiate <ahref="/api/payments">payment of an invoice »</a>, by opening an invoice popup over the Mini App: the Mini App itself must not be closed. </p>
<p>The payment status must be reported back to the mini app using <ahref="/api/bots/webapps#invoice-closed">invoice_closed</a>.</p>
<p>Used by mini apps to request information about the viewport, clients should emit a <ahref="/api/bots/webapps#viewport-changed">viewport_changed event</a>.</p>
<p>Used by mini apps to request information about the current theme, clients should emit a <ahref="/api/bots/webapps#theme-changed">theme_changed event</a>.</p>
<p>Emitted by mini apps when they are fully loaded, signaling to client apps that the loading spinner placeholder can be removed. </p>
<p>Note that there is no guarantee that this event will be emitted when the mini app is fully loaded: clients should remove the loading spinner upon receiving this event or when the page finishes loading (native webview/iframe event), whichever event comes first.</p>
<p>Event payload: JSON object with the following fields:</p>
<ul>
<li><code>is_visible</code> - Whether the main button is visible (boolean, false by default)</li>
<li><code>is_active</code> - Whether the main button is active (boolean, true by default)</li>
<li><code>text</code> - Button text (string, if <code>trim(text)</code> is empty the button must be hidden)</li>
<li><code>color</code> - Button color in hex RGB format (string, defaults to the <ahref="/api/bots/webapps#theme-parameters"><code>button_color</code> theme parameter</a>)</li>
<li><code>text_color</code> - Button text color in hex RGB format (string, defaults to the <ahref="/api/bots/webapps#theme-parameters"><code>button_text_color</code> theme parameter</a>)</li>
<li><code>is_progress_visible</code> - Indicates whether the button should display a loading indicator (boolean, false by default)</li>
</ul>
<p>Configures the main button, located immediately below the webview: when the user presses it a <ahref="/api/bots/webapps#main-button-pressed"><code>main_button_pressed</code> event should be emitted by the client</a>. </p>
<p>Some clients implement a horizontal media type tab bar located at the bottom of the screen, opened when the user clicks on the attachment menu button: this tab bar contains a horizontal list of buttons used to attach media of a certain type and to open installed <ahref="/api/bots/attach">attachment menu mini apps</a>.<br>
In clients that implements a tab bar, iff the user opens a mini app through a tab bar button and the mini app emits a <code>web_app_setup_main_button</code> with <code>is_visible=true</code>, the main button should be displayed (replacing the tab bar) only after the first tap inside of the webview, to prevent bots from immediately blocking the tab bar. </p>
<p>Otherwise, the main button can be displayed right away with no user interaction when receiving a <code>web_app_setup_main_button</code> event with <code>is_visible=true</code>. </p>
<p>Event data: a JSON object with an <code>is_visible</code> boolean field.</p>
<p>Determines whether to show or hide the back button: when the user presses it a <ahref="/api/bots/webapps#back-button-pressed"><code>back_button_pressed</code> event should be emitted by the client</a>.<br>
Note that on supported platforms, the OS back button can be used instead of a custom back button: in this case, if <code>is_visible</code> is true pressing the OS back button should emit a <ahref="/api/bots/webapps#back-button-pressed"><code>back_button_pressed</code> event</a>, otherwise the webview should be closed.</p>
<p>Event data: a JSON object with an <code>is_visible</code> boolean field.</p>
<p>Determines whether to show or hide the settings button: when the user presses it a <ahref="/api/bots/webapps#settings-button-pressed"><code>settings_button_pressed</code> event should be emitted by the client</a>. </p>
<p>Event payload: JSON object with <code>credentials</code> and <code>title</code> fields.</p>
<ul>
<li><code>title</code> is the censored credit card title. </li>
<li><code>credentials</code> is a service-specific JSON object with information about the payment credentials provided by the user to the payment system. </li>
</ul>
<p><strong>Neither Telegram, nor bots will have access to your credit card information.</strong><br>
Credit card details will be handled only by the payment system, see the <ahref="/api/payments">payment documentation for more info »</a>. </p>
<p>Will be called by games when the user explicitly clicks on the <strong>share score</strong> button to share the game, along with their score.<br>
Typically done by using <ahref="/method/messages.forwardMessages">messages.forwardMessages</a> on the game message with the <code>with_my_score</code> flag. </p>
<p>Will be called by games when the user explicitly clicks on the <strong>share game</strong> button to share the game, without sharing their score.<br>
Typically done by using <ahref="/method/messages.forwardMessages">messages.forwardMessages</a> on the game message without the <code>with_my_score</code> flag, or by sharing the game's <ahref="/api/links#game-links">deep link</a>.</p>
<p>Event payload: JSON object with <code>height</code> field.</p>
<p>Called by supported pages inside of <ahref="https://instantview.telegram.org">IV</a> iframe embeds, indicates the new size of the embed frame.</p></div>