mirror of
https://github.com/MarshalX/telegram-crawler.git
synced 2025-01-01 09:06:24 +01:00
Update content of files
This commit is contained in:
parent
c8fd38b3a1
commit
0af5b24069
11 changed files with 193 additions and 186 deletions
|
@ -263,7 +263,7 @@ A full list of these parameters can be seen in the <a href="#client-configuratio
|
|||
<p>Some <a href="/api/channel">channel/supergroup</a>-related suggestions can also be contained in the <code>pending_suggestions</code> field of the <a href="/constructor/channelFull">channelFull</a> constructor, returned by <a href="/method/channels.getFullChannel">channels.getFullChannel</a>.<br>
|
||||
Here's a list of possible suggestions: </p>
|
||||
<ul>
|
||||
<li><code>CONVERT_GIGAGROUP</code> - The <a href="/api/channel">supergroup</a> has many participants: the admin should call <a href="/method/channels.convertToGigaGroup">channels.convertToGigaGroup</a> to convert it to a gigagroup.</li>
|
||||
<li><code>CONVERT_GIGAGROUP</code> - The <a href="/api/channel">supergroup</a> has many participants: the admin should call <a href="/method/channels.convertToGigagroup">channels.convertToGigagroup</a> to convert it to a gigagroup.</li>
|
||||
</ul>
|
||||
<h4><a class="anchor" href="#dismissing-suggestions" id="dismissing-suggestions" name="dismissing-suggestions"><i class="anchor-icon"></i></a>Dismissing suggestions</h4>
|
||||
<pre><code><a href='/constructor/boolFalse'>boolFalse</a>#bc799737 = <a href='/type/Bool'>Bool</a>;
|
||||
|
|
|
@ -4,11 +4,11 @@
|
|||
<meta charset="utf-8">
|
||||
<title>Introducing Bot API 2.0</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta property="description" content="Howdy! This text assumes that you‘re familiar with Telegram’s bot platform.
|
||||
<meta property="description" content="Howdy! This text assumes that you're familiar with Telegram's bot platform.
|
||||
If this is not the case, kindly check out our…">
|
||||
<meta property="og:title" content="Introducing Bot API 2.0">
|
||||
<meta property="og:image" content="4cffbe607dd6ff44bc">
|
||||
<meta property="og:description" content="Howdy! This text assumes that you‘re familiar with Telegram’s bot platform.
|
||||
<meta property="og:description" content="Howdy! This text assumes that you're familiar with Telegram's bot platform.
|
||||
If this is not the case, kindly check out our…">
|
||||
<link rel="shortcut icon" href="/favicon.ico?4" type="image/x-icon" />
|
||||
|
||||
|
@ -44,114 +44,108 @@ If this is not the case, kindly check out our…">
|
|||
<div id="dev_page_content"><!-- scroll_nav -->
|
||||
|
||||
<blockquote>
|
||||
<p>Howdy! This text assumes that you‘re familiar with Telegram’s bot platform.<br>If this is not the case, kindly check out our <a href="/bots"><strong>Introduction to Bots</strong></a>.</p>
|
||||
<p>Howdy! This text assumes that you're familiar with Telegram's bot platform.
|
||||
If this is not the case, kindly check out our <a href="/bots"><strong>Introduction to Bots</strong></a>.</p>
|
||||
</blockquote>
|
||||
<p>Today we‘re introducing the biggest change to Telegram’s Bot Platform since June 2015. These new tools will help you create fluid and intuitive interfaces for your bots. And bots are becoming a lot more capable. They can now send any type of content supported on Telegram, provide location-based services and integrate with other services deeply based on users' phone numbers.</p>
|
||||
<p>If you'd like a more concise changelog, you can find one in the <a href="/bots/api#recent-changes"><strong>Bot API Manual</strong></a>.</p>
|
||||
<h3><a class="anchor" name="new-inline-keyboards" href="#new-inline-keyboards"><i class="anchor-icon"></i></a>New Inline Keyboards</h3>
|
||||
<p>To begin with, we're adding a new type of keyboard that is integrated directly into the message it belongs to. Inline keyboards are available for messages sent both in chat mode and inline mode.</p>
|
||||
<p>Today we're introducing the biggest change to Telegram's Bot Platform since June 2015. These new tools will help you create fluid and intuitive interfaces for your bots. And bots are becoming a lot more capable. They can now send any type of content supported on Telegram, provide location-based services and integrate with other services deeply based on users' phone numbers.</p>
|
||||
<p>If you'd like a more concise changelog, you can find one in the <a href="/bots/api#recent-changes"><strong>Bot API Manual</strong></a>.</p>
|
||||
<h3><a class="anchor" href="#new-inline-keyboards" id="new-inline-keyboards" name="new-inline-keyboards"><i class="anchor-icon"></i></a>New Inline Keyboards</h3>
|
||||
<p>To begin with, we're adding a new type of keyboard that is integrated directly into the message it belongs to. Inline keyboards are available for messages sent both in chat mode and inline mode.</p>
|
||||
<div><center>
|
||||
<a href="/file/811140217/1/NkRCCLeQZVc/17a804837802700ea4" target="_blank"><img src="/file/811140217/1/NkRCCLeQZVc/17a804837802700ea4" title="Callback buttons in @music" style="width: 295px; padding: 10px 20px;" /></a>
|
||||
<a href="/file/811140659/1/RRJyulbtLBY/ea6163411c7eb4f4dc" target="_blank"><img src="/file/811140659/1/RRJyulbtLBY/ea6163411c7eb4f4dc" title="More callback buttons in @music" style="width: 295px; padding: 10px 20px;" /></a>
|
||||
|
||||
</center><br>
|
||||
|
||||
|
||||
|
||||
<a href="/file/811140217/1/NkRCCLeQZVc/17a804837802700ea4" target="_blank"><img src="/file/811140217/1/NkRCCLeQZVc/17a804837802700ea4" title="Callback buttons in @music" style="width: 295px; padding: 10px 20px;"></a>
|
||||
<a href="/file/811140659/1/RRJyulbtLBY/ea6163411c7eb4f4dc" target="_blank"><img src="/file/811140659/1/RRJyulbtLBY/ea6163411c7eb4f4dc" title="More callback buttons in @music" style="width: 295px; padding: 10px 20px;"></a>
|
||||
</center><br>
|
||||
</div>
|
||||
|
||||
<p>Unlike with custom reply keyboards, pressing buttons on inline keyboards doesn't result in messages sent to the chat. Instead, inline keyboards support buttons that work behind the scenes: <a href="#callback-buttons">callback buttons</a>, <a href="#url-buttons">URL buttons</a> and <a href="#switch-to-inline-buttons">switch to inline buttons</a>.</p>
|
||||
<p>Unlike with custom reply keyboards, pressing buttons on inline keyboards doesn't result in messages sent to the chat. Instead, inline keyboards support buttons that work behind the scenes: <a href="#callback-buttons">callback buttons</a>, <a href="#url-buttons">URL buttons</a> and <a href="#switch-to-inline-buttons">switch to inline buttons</a>.</p>
|
||||
<blockquote>
|
||||
<p><a href="/bots/api#inlinekeyboardmarkup">Manual: Inline keyboards »</a></p>
|
||||
</blockquote>
|
||||
<h4><a class="anchor" name="callback-buttons" href="#callback-buttons"><i class="anchor-icon"></i></a>Callback buttons</h4>
|
||||
<h4><a class="anchor" href="#callback-buttons" id="callback-buttons" name="callback-buttons"><i class="anchor-icon"></i></a>Callback buttons</h4>
|
||||
<p>When a user presses a <strong>callback button</strong>, no messages are sent to the chat. Instead, your bot simply receives the relevant query. Upon receiving the query, your bot can display some <a href="/bots/api#answercallbackquery">result in a notification</a> at the top of the chat screen or in an alert.</p>
|
||||
<div><center>
|
||||
<a href="/file/811140423/1/6BVlO7dWPeo/64d0d842ff73ff3dc8" target="_blank"><img src="/file/811140423/1/6BVlO7dWPeo/64d0d842ff73ff3dc8" title="Notification at the top" style="width:295px; padding:10px 20px"/></a></center><br>
|
||||
<a href="/file/811140423/1/6BVlO7dWPeo/64d0d842ff73ff3dc8" target="_blank"><img src="/file/811140423/1/6BVlO7dWPeo/64d0d842ff73ff3dc8" title="Notification at the top" style="width:295px; padding:10px 20px"></a></center><br>
|
||||
</div>
|
||||
|
||||
<p><strong>Sample bot</strong><br><a href="https://telegram.me/music">@music</a> – This sample music bot uses inline callback buttons to flip pages and reload random results.</p>
|
||||
<p><strong>Sample bot</strong>
|
||||
<a href="https://telegram.me/music">@music</a> – This sample music bot uses inline callback buttons to flip pages and reload random results.</p>
|
||||
<p>Read on to <a href="#updating-messages">updating messages</a> to find out how callback buttons can get even cooler.</p>
|
||||
<h4><a class="anchor" name="url-buttons" href="#url-buttons"><i class="anchor-icon"></i></a>URL buttons</h4>
|
||||
<p>Buttons of this type have a small arrow icon to help the user understand that tapping on a <strong>URL button</strong> will open an external link. Naturally, we'll show them a confirmation alert before opening the link in the browser.</p>
|
||||
<h4><a class="anchor" href="#url-buttons" id="url-buttons" name="url-buttons"><i class="anchor-icon"></i></a>URL buttons</h4>
|
||||
<p>Buttons of this type have a small arrow icon to help the user understand that tapping on a <strong>URL button</strong> will open an external link. Naturally, we'll show them a confirmation alert before opening the link in the browser.</p>
|
||||
<div><center>
|
||||
<a href="/file/811140999/1/2JSoUVlWKa0/4fad2e2743dc8eda04" target="_blank"><img src="/file/811140999/1/2JSoUVlWKa0/4fad2e2743dc8eda04" title="URL button" style="width:295px; padding:10px 20px"/></a></center>
|
||||
<a href="/file/811140999/1/2JSoUVlWKa0/4fad2e2743dc8eda04" target="_blank"><img src="/file/811140999/1/2JSoUVlWKa0/4fad2e2743dc8eda04" title="URL button" style="width:295px; padding:10px 20px"></a></center>
|
||||
</div>
|
||||
|
||||
<h4><a class="anchor" name="switch-to-inline-buttons" href="#switch-to-inline-buttons"><i class="anchor-icon"></i></a>Switch to Inline buttons</h4>
|
||||
<p>Pressing a switch to inline button prompts the user to select a chat, opens it and inserts the bot's username into the input field. You can also pass a query that will be inserted along with the username – this way your users will immediately get some inline results they can share.</p>
|
||||
<h4><a class="anchor" href="#switch-to-inline-buttons" id="switch-to-inline-buttons" name="switch-to-inline-buttons"><i class="anchor-icon"></i></a>Switch to Inline buttons</h4>
|
||||
<p>Pressing a switch to inline button prompts the user to select a chat, opens it and inserts the bot's username into the input field. You can also pass a query that will be inserted along with the username – this way your users will immediately get some inline results they can share.</p>
|
||||
<div><center>
|
||||
<a href="/file/811140659/1/RRJyulbtLBY/ea6163411c7eb4f4dc" target="_blank"><img src="/file/811140659/1/RRJyulbtLBY/ea6163411c7eb4f4dc" title="More callback buttons in @music" style="width: 295px; padding: 10px 20px;" /></a></center><br>
|
||||
<a href="/file/811140659/1/RRJyulbtLBY/ea6163411c7eb4f4dc" target="_blank"><img src="/file/811140659/1/RRJyulbtLBY/ea6163411c7eb4f4dc" title="More callback buttons in @music" style="width: 295px; padding: 10px 20px;"></a></center><br>
|
||||
</div>
|
||||
|
||||
<p><strong>Sample bot</strong><br><a href="https://telegram.me/sticker">@sticker</a> – This sticker search bot offers a <a href="#switch-to-inline-buttons">‘switch to inline’ button</a> to teach users how to use it in inline mode. </p>
|
||||
<h3><a class="anchor" name="updating-messages" href="#updating-messages"><i class="anchor-icon"></i></a>Updating Messages</h3>
|
||||
<p>Since inline keyboards don‘t send additional messages to the chat, it made sense to give bots a way of manipulating their existing messages, so that they don’t have to send a new message each time they need to update something. This helps reduce clutter and build more fluid interfaces.</p>
|
||||
<p><strong>Sample bot</strong>
|
||||
<a href="https://telegram.me/sticker">@sticker</a> – This sticker search bot offers a <a href="#switch-to-inline-buttons">'switch to inline' button</a> to teach users how to use it in inline mode. </p>
|
||||
<h3><a class="anchor" href="#updating-messages" id="updating-messages" name="updating-messages"><i class="anchor-icon"></i></a>Updating Messages</h3>
|
||||
<p>Since inline keyboards don't send additional messages to the chat, it made sense to give bots a way of manipulating their existing messages, so that they don't have to send a new message each time they need to update something. This helps reduce clutter and build more fluid interfaces.</p>
|
||||
<div class="smartphone_video_player_wrap">
|
||||
<div class="smartphone_video_player_iphone">
|
||||
<video class="smartphone_video_player tl_blog_vid_autoplay" onclick="videoTogglePlay(this)" poster="/resources/video/cover/Music.png" loop controls muted>
|
||||
<source src="/resources/video/Music.mp4" type="video/mp4">
|
||||
</video>
|
||||
</source></video>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p><strong>Sample bot</strong><br><a href="https://telegram.me/music">@music</a> – Watch how the music bot updates its messages with search results when you press the navigation buttons.</p>
|
||||
<p><strong>Sample bot</strong>
|
||||
<a href="https://telegram.me/music">@music</a> – Watch how the music bot updates its messages with search results when you press the navigation buttons.</p>
|
||||
<blockquote>
|
||||
<p><a href="/bots/api#updating-messages">Manual: Updating messages »</a></p>
|
||||
</blockquote>
|
||||
<h3><a class="anchor" name="locations-and-numbers" href="#locations-and-numbers"><i class="anchor-icon"></i></a>Locations and Numbers</h3>
|
||||
<p>Some bots need extra data from the user to work properly. For example, knowing the user‘s location helps provide more relevant geo-specific results. The user’s phone number can be very useful for integrations with other services, like banks, etc.</p>
|
||||
<p>We've added an easy way for bots to ask the user for their <strong>location</strong> and <strong>phone number</strong> using special buttons. Note that both phone number and location request buttons will only work in private chats.</p>
|
||||
<h3><a class="anchor" href="#locations-and-numbers" id="locations-and-numbers" name="locations-and-numbers"><i class="anchor-icon"></i></a>Locations and Numbers</h3>
|
||||
<p>Some bots need extra data from the user to work properly. For example, knowing the user's location helps provide more relevant geo-specific results. The user's phone number can be very useful for integrations with other services, like banks, etc.</p>
|
||||
<p>We've added an easy way for bots to ask the user for their <strong>location</strong> and <strong>phone number</strong> using special buttons. Note that both phone number and location request buttons will only work in private chats.</p>
|
||||
<div><center>
|
||||
<a href="/file/811140587/2/jaowDLZg2l0/5ba3f7d7fd5c6c28dc" target="_blank"><img src="/file/811140587/2/jaowDLZg2l0/5ba3f7d7fd5c6c28dc" title="Phone number and location sharing buttons" style="width: 295px; padding: 10px 20px;" /></a></center><br>
|
||||
<a href="/file/811140587/2/jaowDLZg2l0/5ba3f7d7fd5c6c28dc" target="_blank"><img src="/file/811140587/2/jaowDLZg2l0/5ba3f7d7fd5c6c28dc" title="Phone number and location sharing buttons" style="width: 295px; padding: 10px 20px;"></a></center><br>
|
||||
</div>
|
||||
|
||||
<p>When these buttons are pressed, Telegram clients will display a confirmation alert that tells the user what's about to happen.</p>
|
||||
<p>When these buttons are pressed, Telegram clients will display a confirmation alert that tells the user what's about to happen.</p>
|
||||
<blockquote>
|
||||
<p><a href="/bots/api#keyboardbutton">Manual: Number and location buttons »</a></p>
|
||||
</blockquote>
|
||||
<p>Inline bots can also request location data from their users. Use the <code>/setinlinegeo</code> command with <a href="https://telegram.me/botfather">@BotFather</a> to enable this. Your bot will ask the user for permission to access their location whenever they send an inline request.</p>
|
||||
<p><strong>Sample bot</strong><br><a href="https://telegram.me/foursquare">@foursquare</a> – This bot will ask for permission to access the user's location, then provide geo-targeted results.</p>
|
||||
<h3><a class="anchor" name="inline-bots-2-0" href="#inline-bots-2-0"><i class="anchor-icon"></i></a>Inline Bots 2.0</h3>
|
||||
<p><strong>Sample bot</strong>
|
||||
<a href="https://telegram.me/foursquare">@foursquare</a> – This bot will ask for permission to access the user's location, then provide geo-targeted results.</p>
|
||||
<h3><a class="anchor" href="#inline-bots-20" id="inline-bots-20" name="inline-bots-20"><i class="anchor-icon"></i></a>Inline Bots 2.0</h3>
|
||||
<p>Speaking of inline bots, they are also getting a major upgrade today.</p>
|
||||
<h4><a class="anchor" name="new-types-of-content" href="#new-types-of-content"><i class="anchor-icon"></i></a>New types of content</h4>
|
||||
<h4><a class="anchor" href="#new-types-of-content" id="new-types-of-content" name="new-types-of-content"><i class="anchor-icon"></i></a>New types of content</h4>
|
||||
<p>Inline bots now support <strong>all types of content</strong> available in Telegram (19 in all), they are now capable of sending stickers, videos, music, locations, documents and more. </p>
|
||||
<div><center>
|
||||
<a href="/file/811140994/2/fvw-q_CRaBQ/c618325e119b0a8229" target="_blank"><img src="/file/811140994/2/fvw-q_CRaBQ/c618325e119b0a8229" title="All kinds of inline content" style="width: 295px; padding: 10px 20px;" /></a></center><br>
|
||||
<a href="/file/811140994/2/fvw-q_CRaBQ/c618325e119b0a8229" target="_blank"><img src="/file/811140994/2/fvw-q_CRaBQ/c618325e119b0a8229" title="All kinds of inline content" style="width: 295px; padding: 10px 20px;"></a></center><br>
|
||||
</div>
|
||||
|
||||
<p><strong>Sample bots</strong><br><a href="https://telegram.me/sticker">@sticker</a> – This sticker bot will accept one or more emoji and search for relevant stickers.<br><a href="https://telegram.me/music">@music</a> – The music bot allows users to send mp3 tracks from a database of public domain classical music.</p>
|
||||
<p><strong>Sample bots</strong>
|
||||
<a href="https://telegram.me/sticker">@sticker</a> – This sticker bot will accept one or more emoji and search for relevant stickers.
|
||||
<a href="https://telegram.me/music">@music</a> – The music bot allows users to send mp3 tracks from a database of public domain classical music.</p>
|
||||
<blockquote>
|
||||
<p><a href="/bots/api#inlinequeryresult">Manual: Types of inline content »</a></p>
|
||||
</blockquote>
|
||||
<h4><a class="anchor" name="switching-between-inline-mode-and-private-chat" href="#switching-between-inline-mode-and-private-chat"><i class="anchor-icon"></i></a>Switching between inline mode and private chat</h4>
|
||||
<p>Some inline bots can benefit from an initial setup process, like connecting them to an account on an external service (e.g., YouTube). We've added an easy way of switching between the private chat with a bot and whatever chat the user wants to share inline results in.</p>
|
||||
<h4><a class="anchor" href="#switching-between-inline-mode-and-private-chat" id="switching-between-inline-mode-and-private-chat" name="switching-between-inline-mode-and-private-chat"><i class="anchor-icon"></i></a>Switching between inline mode and private chat</h4>
|
||||
<p>Some inline bots can benefit from an initial setup process, like connecting them to an account on an external service (e.g., YouTube). We've added an easy way of switching between the private chat with a bot and whatever chat the user wants to share inline results in.</p>
|
||||
<div><center>
|
||||
<a href="/file/811140951/1/FD93gAgDVDI/8d8bdd16e6a7b40c12" target="_blank"><img src="/file/811140951/1/FD93gAgDVDI/8d8bdd16e6a7b40c12" title="Switch to PM button" style="width: 295px; padding: 10px 20px;" /></a></center><br>
|
||||
<a href="/file/811140951/1/FD93gAgDVDI/8d8bdd16e6a7b40c12" target="_blank"><img src="/file/811140951/1/FD93gAgDVDI/8d8bdd16e6a7b40c12" title="Switch to PM button" style="width: 295px; padding: 10px 20px;"></a></center><br>
|
||||
</div>
|
||||
|
||||
<p>You can now display a special ‘Switch to PM’ button above the inline results (or instead of them). This button will open a private chat with the bot and pass a parameter of your choosing, so that you can prompt the user for the relevant setup actions. Once done, you can use an inline keyboard with a <a href="/bots/api#inlinekeyboardmarkup"><em>switch_inline_query</em></a> button to send the user back to the original chat. </p>
|
||||
<p><strong>Sample bots</strong><br><a href="https://telegram.me/youtube">@youtube</a> – Shows a ‘Sign in to YouTube’ button, then suggests personalized results.</p>
|
||||
<p>You can now display a special 'Switch to PM' button above the inline results (or instead of them). This button will open a private chat with the bot and pass a parameter of your choosing, so that you can prompt the user for the relevant setup actions. Once done, you can use an inline keyboard with a <a href="/bots/api#inlinekeyboardmarkup"><em>switch_inline_query</em></a> button to send the user back to the original chat. </p>
|
||||
<p><strong>Sample bots</strong>
|
||||
<a href="https://telegram.me/youtube">@youtube</a> – Shows a 'Sign in to YouTube' button, then suggests personalized results.</p>
|
||||
<blockquote>
|
||||
<p><a href="/bots/api#answerinlinequery">Manual: Switch to PM</a></p>
|
||||
</blockquote>
|
||||
<h4><a class="anchor" name="better-inline-ui" href="#better-inline-ui"><i class="anchor-icon"></i></a>Better inline UI</h4>
|
||||
<p>Since sending content via inline bots works differently from sending ordinary messages, we‘ve changed the interface a little. There’s hardly a more effective way of explaining that there‘s no need to hit ’Send':</p>
|
||||
<h4><a class="anchor" href="#better-inline-ui" id="better-inline-ui" name="better-inline-ui"><i class="anchor-icon"></i></a>Better inline UI</h4>
|
||||
<p>Since sending content via inline bots works differently from sending ordinary messages, we've changed the interface a little. There's hardly a more effective way of explaining that there's no need to hit 'Send':</p>
|
||||
<div><center>
|
||||
<a href="/file/811140558/1/POjp00-nHqE/50d0312845a05e6da9" target="_blank"><img src="/file/811140558/1/POjp00-nHqE/50d0312845a05e6da9" title="New input field" style="width: 295px; padding: 10px 20px;" /></a></center><br>
|
||||
<a href="/file/811140558/1/POjp00-nHqE/50d0312845a05e6da9" target="_blank"><img src="/file/811140558/1/POjp00-nHqE/50d0312845a05e6da9" title="New input field" style="width: 295px; padding: 10px 20px;"></a></center><br>
|
||||
</div>
|
||||
|
||||
<p>Tapping on the cross icon once will clear the query, tapping twice will give the ‘Send’ button back to the user.</p>
|
||||
<h3><a class="anchor" name="group-admins" href="#group-admins"><i class="anchor-icon"></i></a>Group Admins</h3>
|
||||
<p>As a dessert, we‘re beginning to roll out tools that will allow you to create bot solutions for group admins. As the first step, we’ve added methods to remove members from groups and supergroups.</p>
|
||||
<p>Tapping on the cross icon once will clear the query, tapping twice will give the 'Send' button back to the user.</p>
|
||||
<h3><a class="anchor" href="#group-admins" id="group-admins" name="group-admins"><i class="anchor-icon"></i></a>Group Admins</h3>
|
||||
<p>As a dessert, we're beginning to roll out tools that will allow you to create bot solutions for group admins. As the first step, we've added methods to remove members from groups and supergroups.</p>
|
||||
<blockquote>
|
||||
<p><a href="/bots/api#kickchatmember">Manual: Group management »</a></p>
|
||||
</blockquote>
|
||||
<p>And that's about it for now. Stay tuned for more updates and subscribe to our official <a href="https://telegram.me/botnews">@Botnews</a> channel on Telegram.</p>
|
||||
<p>And that's about it for now. Stay tuned for more updates and subscribe to our official <a href="https://telegram.me/botnews">@Botnews</a> channel on Telegram.</p>
|
||||
<blockquote>
|
||||
<p><a href="/bots/api#recent-changes">Read the full changelog for this update »</a></p>
|
||||
</blockquote>
|
||||
</div>
|
||||
</blockquote></div>
|
||||
|
||||
</div>
|
||||
|
||||
|
|
|
@ -44,66 +44,65 @@
|
|||
<div class="dev_side_image">
|
||||
<a href="/file/811140221/1/fW9vnLya4Fg/e2b5c530c7b0e019c4" target="_blank"><img src="/file/811140530/1/h-eMmPp2vp4/cd4a109f75e6561305" title="Inline bots. Click for hi-res picture">
|
||||
</a></div>
|
||||
|
||||
<p>Beyond sending commands in private messages or groups, users can interact with your bot via <a href="/bots/api#inline-mode"><strong>inline queries</strong></a>. If inline queries are enabled, users can call your bot by typing its username and a query in the <strong>text input field</strong> in <strong>any</strong> chat. The query is sent to your bot in an update. This way, people can request content from your bot in <strong>any</strong> of their chats, groups, or channels without sending any messages at all.</p>
|
||||
<div><center>
|
||||
<a href="/file/811140995/1/I-wubuXAnzk/2e39739d0ac6bd5458" target="_blank"><img src="/file/811140995/1/I-wubuXAnzk/2e39739d0ac6bd5458" title="Users can type the bot’s username in any chat, then type a query without sending any messages" style="width:300px; padding:10px 0px 10px"/></a></center>
|
||||
<a href="/file/811140995/1/I-wubuXAnzk/2e39739d0ac6bd5458" target="_blank"><img src="/file/811140995/1/I-wubuXAnzk/2e39739d0ac6bd5458" title="Users can type the bot’s username in any chat, then type a query without sending any messages" style="width:300px; padding:10px 0px 10px"></a></center>
|
||||
<br></div>
|
||||
|
||||
|
||||
<p>To enable this option, send the <code>/setinline</code> command to <a href="https://telegram.me/botfather">@BotFather</a> and provide the placeholder text that the user will see in the input field after typing your bot’s name.</p>
|
||||
<blockquote>
|
||||
<p>See the <a href="/bots/api#inline-mode">Bot API Manual</a> for the relevant methods and objects.</p>
|
||||
</blockquote>
|
||||
<h3><a class="anchor" name="inline-results" href="#inline-results"><i class="anchor-icon"></i></a>Inline results</h3>
|
||||
<h3><a class="anchor" href="#inline-results" id="inline-results" name="inline-results"><i class="anchor-icon"></i></a>Inline results</h3>
|
||||
<p>Inline bots support <strong>all types of content</strong> available in Telegram (20 in all). They are capable of sending stickers, videos, music, locations, documents and more. </p>
|
||||
<div><center>
|
||||
<a href="/file/811140994/2/fvw-q_CRaBQ/c618325e119b0a8229" target="_blank"><img src="/file/811140994/2/fvw-q_CRaBQ/c618325e119b0a8229" title="All kinds of inline content" style="width: 295px; padding: 10px 20px;" /></a></center><br>
|
||||
<a href="/file/811140994/2/fvw-q_CRaBQ/c618325e119b0a8229" target="_blank"><img src="/file/811140994/2/fvw-q_CRaBQ/c618325e119b0a8229" title="All kinds of inline content" style="width: 295px; padding: 10px 20px;"></a></center><br>
|
||||
</div>
|
||||
|
||||
<p>Clients can display the results with vertical or horizontal scrolling, depending on the type of content:</p>
|
||||
<div><center>
|
||||
|
||||
<a href="/file/811140049/2/M2mzqjZoiUw/2d872f0df2aed182d6" target="_blank"><img src="/file/811140049/2/M2mzqjZoiUw/2d872f0df2aed182d6" title="Vertical scrolling" style="width: 295px; padding: 0px 20px;" /></a>
|
||||
|
||||
<a href="/file/811140592/2/P4-tFhmBsCg/57418af08f1a252d45" target="_blank"><img src="/file/811140592/2/P4-tFhmBsCg/57418af08f1a252d45" title="Horizontal scrolling" style="width: 295px; padding: 0px 20px;" /></a>
|
||||
|
||||
<p><a href="/file/811140049/2/M2mzqjZoiUw/2d872f0df2aed182d6" target="_blank"><img src="/file/811140049/2/M2mzqjZoiUw/2d872f0df2aed182d6" title="Vertical scrolling" style="width: 295px; padding: 0px 20px;"></a></p>
|
||||
<p><a href="/file/811140592/2/P4-tFhmBsCg/57418af08f1a252d45" target="_blank"><img src="/file/811140592/2/P4-tFhmBsCg/57418af08f1a252d45" title="Horizontal scrolling" style="width: 295px; padding: 0px 20px;"></a></p>
|
||||
</center>
|
||||
<br></div>
|
||||
|
||||
<p>As soon as the user taps on an item, it's immediately sent to the recipient, and the input field is cleared.</p>
|
||||
<h3><a class="anchor" name="switching-inline-pm-modes" href="#switching-inline-pm-modes"><i class="anchor-icon"></i></a>Switching inline/PM modes</h3>
|
||||
<p>Some inline bots can benefit from an initial setup process, like connecting them to an account on an external service (e.g., YouTube). We've added an easy way of switching between the private chat with a bot and whatever chat the user wants to share inline results in.</p>
|
||||
<p>As soon as the user taps on an item, it's immediately sent to the recipient, and the input field is cleared.</p>
|
||||
<h3><a class="anchor" href="#switching-inlinepm-modes" id="switching-inlinepm-modes" name="switching-inlinepm-modes"><i class="anchor-icon"></i></a>Switching inline/PM modes</h3>
|
||||
<p>Some inline bots can benefit from an initial setup process, like connecting them to an account on an external service (e.g., YouTube). We've added an easy way of switching between the private chat with a bot and whatever chat the user wants to share inline results in.</p>
|
||||
<div><center>
|
||||
<a href="/file/811140951/1/FD93gAgDVDI/8d8bdd16e6a7b40c12" target="_blank"><img src="/file/811140951/1/FD93gAgDVDI/8d8bdd16e6a7b40c12" title="Switch to PM button" style="width: 295px; padding: 10px 20px;" /></a></center><br>
|
||||
<a href="/file/811140951/1/FD93gAgDVDI/8d8bdd16e6a7b40c12" target="_blank"><img src="/file/811140951/1/FD93gAgDVDI/8d8bdd16e6a7b40c12" title="Switch to PM button" style="width: 295px; padding: 10px 20px;"></a></center><br>
|
||||
</div>
|
||||
|
||||
<p>You can display a special ‘Switch to PM’ button above the inline results (or instead of them). This button will open a private chat with the bot and pass a parameter of your choosing, so that you can prompt the user for the relevant setup actions. Once done, you can use an inline keyboard with a <a href="/bots/api#inlinekeyboardmarkup"><em>switch_inline_query</em></a> button to send the user back to the original chat. </p>
|
||||
<p><strong>Sample bots</strong><br><a href="https://telegram.me/youtube">@youtube</a> – Shows a ‘Sign in to YouTube’ button, then suggests personalized results.</p>
|
||||
<p>You can display a special 'Switch to PM' button above the inline results (or instead of them). This button will open a private chat with the bot and pass a parameter of your choosing, so that you can prompt the user for the relevant setup actions. Once done, you can use an inline keyboard with a <a href="/bots/api#inlinekeyboardmarkup"><em>switch_inline_query</em></a> button to send the user back to the original chat. </p>
|
||||
<p><strong>Sample bots</strong>
|
||||
<a href="https://telegram.me/youtube">@youtube</a> – Shows a 'Sign in to YouTube' button, then suggests personalized results.</p>
|
||||
<blockquote>
|
||||
<p><a href="/bots/api#answerinlinequery">Manual: Switch to PM</a></p>
|
||||
</blockquote>
|
||||
<h3><a class="anchor" name="location-based-results" href="#location-based-results"><i class="anchor-icon"></i></a>Location-based results</h3>
|
||||
<h3><a class="anchor" href="#location-based-results" id="location-based-results" name="location-based-results"><i class="anchor-icon"></i></a>Location-based results</h3>
|
||||
<p>Inline bots can request location data from their users. Use the <code>/setinlinegeo</code> command with <a href="https://telegram.me/botfather">@BotFather</a> to enable this. Your bot will ask the user for permission to access their location whenever they send an inline request.</p>
|
||||
<p><strong>Sample bot</strong><br><a href="https://telegram.me/foursquare">@foursquare</a> – This bot will ask for permission to access the user's location, then provide geo-targeted results.</p>
|
||||
<h3><a class="anchor" name="spreading-virally" href="#spreading-virally"><i class="anchor-icon"></i></a>Spreading virally</h3>
|
||||
<p>Messages sent with the help of your bot will show its username next to the sender's name.</p>
|
||||
<p><strong>Sample bot</strong>
|
||||
<a href="https://telegram.me/foursquare">@foursquare</a> – This bot will ask for permission to access the user's location, then provide geo-targeted results.</p>
|
||||
<h3><a class="anchor" href="#spreading-virally" id="spreading-virally" name="spreading-virally"><i class="anchor-icon"></i></a>Spreading virally</h3>
|
||||
<p>Messages sent with the help of your bot will show its username next to the sender's name.</p>
|
||||
<div><center>
|
||||
|
||||
<a href="/file/811140680/2/P3E5RVFzGZ8/5ae6f9c9610b0cbace" target="_blank"><img src="/file/811140680/2/P3E5RVFzGZ8/5ae6f9c9610b0cbace" title="Gif shared via a bot" style="width: 295px; padding: 0px 20px;" /></a>
|
||||
<a href="/file/811140016/2/2b_B7nq9OQA/161b06d38843930fe5" target="_blank"><img src="/file/811140016/2/2b_B7nq9OQA/161b06d38843930fe5" title="Inline bot suggestions" style="width: 295px; padding: 0px 20px;" /></a>
|
||||
|
||||
|
||||
<br><br></center></div>
|
||||
|
||||
<p><a href="/file/811140680/2/P3E5RVFzGZ8/5ae6f9c9610b0cbace" target="_blank"><img src="/file/811140680/2/P3E5RVFzGZ8/5ae6f9c9610b0cbace" title="Gif shared via a bot" style="width: 295px; padding: 0px 20px;"></a>
|
||||
<a href="/file/811140016/2/2b_B7nq9OQA/161b06d38843930fe5" target="_blank"><img src="/file/811140016/2/2b_B7nq9OQA/161b06d38843930fe5" title="Inline bot suggestions" style="width: 295px; padding: 0px 20px;"></a></p>
|
||||
<p><br><br></p></center></div>
|
||||
<p>When a user taps on the bot username in the message header, the mention is automatically inserted into the input field. Entering the <code>@</code> symbol in the input field brings up a list of suggestions, featuring recently used inline bots.</p>
|
||||
<h4><a class="anchor" name="collecting-feedback" href="#collecting-feedback"><i class="anchor-icon"></i></a>Collecting feedback</h4>
|
||||
<h4><a class="anchor" href="#collecting-feedback" id="collecting-feedback" name="collecting-feedback"><i class="anchor-icon"></i></a>Collecting feedback</h4>
|
||||
<p>To know which of the provided results your users are sending to their chat partners, send <a href="https://telegram.me/botfather">@Botfather</a> the <code>/setinlinefeedback</code> command. With this enabled, you will receive updates on the results chosen by your users.</p>
|
||||
<p>Please note that this can create load issues for popular bots – you may receive more results than actual requests due to caching (see the <em>cache_time</em> parameter in <a href="/bots/api#answerinlinequery">answerInlineQuery</a>). For these cases, we recommend adjusting the probability setting to receive 1/10, 1/100 or 1/1000 of the results.</p>
|
||||
<h3><a class="anchor" name="inline-bot-samples" href="#inline-bot-samples"><i class="anchor-icon"></i></a>Inline bot samples</h3>
|
||||
<p>Here are some sample inline bots, in case you’re curious to see one in action. Try any of these:<br><a href="https://telegram.me/gif">@gif</a> – GIF search<br><a href="https://telegram.me/vid">@vid</a> – Video search<br><a href="https://telegram.me/pic">@pic</a> – Yandex image search<br><a href="https://telegram.me/bing">@bing</a> – Bing image search<br><a href="https://telegram.me/wiki">@wiki</a> – Wikipedia search<br><a href="https://telegram.me/imdb">@imdb</a> – IMDB search<br><a href="https://telegram.me/bold">@bold</a> – Make bold, italic or fixed sys text</p>
|
||||
<p><strong>NEW</strong><br><a href="https://telegram.me/youtube">@youtube</a> - Connect your account for personalized results<br><a href="https://telegram.me/music">@music</a> - Search and send classical music<br><a href="https://telegram.me/foursquare">@foursquare</a> – Find and send venue addresses<br><a href="https://telegram.me/sticker">@sticker</a> – Find and send stickers based on emoji</p>
|
||||
</div>
|
||||
<h3><a class="anchor" href="#inline-bot-samples" id="inline-bot-samples" name="inline-bot-samples"><i class="anchor-icon"></i></a>Inline bot samples</h3>
|
||||
<p>Here are some sample inline bots, in case you’re curious to see one in action. Try any of these:
|
||||
<a href="https://telegram.me/gif">@gif</a> – GIF search
|
||||
<a href="https://telegram.me/vid">@vid</a> – Video search
|
||||
<a href="https://telegram.me/pic">@pic</a> – Yandex image search
|
||||
<a href="https://telegram.me/bing">@bing</a> – Bing image search
|
||||
<a href="https://telegram.me/wiki">@wiki</a> – Wikipedia search
|
||||
<a href="https://telegram.me/imdb">@imdb</a> – IMDB search
|
||||
<a href="https://telegram.me/bold">@bold</a> – Make bold, italic or fixed sys text</p>
|
||||
<p><strong>NEW</strong>
|
||||
<a href="https://telegram.me/youtube">@youtube</a> - Connect your account for personalized results
|
||||
<a href="https://telegram.me/music">@music</a> - Search and send classical music
|
||||
<a href="https://telegram.me/foursquare">@foursquare</a> – Find and send venue addresses
|
||||
<a href="https://telegram.me/sticker">@sticker</a> – Find and send stickers based on emoji</p></div>
|
||||
|
||||
</div>
|
||||
|
||||
|
|
|
@ -40,34 +40,41 @@
|
|||
<h1 id="dev_page_title">Using self-signed certificates</h1>
|
||||
|
||||
<div id="dev_page_content"><p>Upload your certificate using the <em>certificate</em> parameter in the <a href="/bots/api#setwebhook">setWebhook</a> method. The certificate supplied should be <strong>PEM encoded</strong> (ASCII BASE64), the pem file should only contain the <strong>public key</strong> (including BEGIN and END portions). When converting from a bundle format, please split the file to only include the public key.</p>
|
||||
<h3><a class="anchor" name="generating-a-self-signed-certificate-pair-pem" href="#generating-a-self-signed-certificate-pair-pem"><i class="anchor-icon"></i></a>Generating a self-signed certificate pair (PEM):</h3>
|
||||
<h4><a class="anchor" name="openssl" href="#openssl"><i class="anchor-icon"></i></a>Openssl</h4>
|
||||
<h3><a class="anchor" href="#generating-a-self-signed-certificate-pair-pem" id="generating-a-self-signed-certificate-pair-pem" name="generating-a-self-signed-certificate-pair-pem"><i class="anchor-icon"></i></a>Generating a self-signed certificate pair (PEM):</h3>
|
||||
<h4><a class="anchor" href="#openssl" id="openssl" name="openssl"><i class="anchor-icon"></i></a>Openssl</h4>
|
||||
<blockquote>
|
||||
<p>Windows binaries for Openssl are available online</p>
|
||||
</blockquote>
|
||||
<p><code>openssl req -newkey rsa:2048 -sha256 -nodes -keyout YOURPRIVATE.key -x509 -days 365 -out YOURPUBLIC.pem -subj "/C=US/ST=New York/L=Brooklyn/O=Example Brooklyn Company/CN=YOURDOMAIN.EXAMPLE"</code></p>
|
||||
<p><code>openssl req -newkey rsa:2048 -sha256 -nodes -keyout YOURPRIVATE.key -x509 -days 365 -out YOURPUBLIC.pem -subj "/C=US/ST=New York/L=Brooklyn/O=Example Brooklyn Company/CN=YOURDOMAIN.EXAMPLE"</code></p>
|
||||
<p>YOURPUBLIC.pem has to be used as input for setting the self-signed webhook.</p>
|
||||
<p>You can inspect the generated certificate with:<br><code>openssl x509 -text -noout -in YOURPUBLIC.pem</code></p>
|
||||
<p>Converting from a previously generated DER:<br><code>openssl x509 -inform der -in YOURDER.der -out YOURPEM.pem</code></p>
|
||||
<p>Converting from a previously generated PKCS12:<br><code>openssl pkcs12 -in YOURPKCS.p12 -out YOURPEM.pem</code></p>
|
||||
<p>You can inspect the generated certificate with:
|
||||
<code>openssl x509 -text -noout -in YOURPUBLIC.pem</code></p>
|
||||
<p>Converting from a previously generated DER:
|
||||
<code>openssl x509 -inform der -in YOURDER.der -out YOURPEM.pem</code></p>
|
||||
<p>Converting from a previously generated PKCS12:
|
||||
<code>openssl pkcs12 -in YOURPKCS.p12 -out YOURPEM.pem</code></p>
|
||||
<blockquote>
|
||||
<p>More information: https://www.openssl.org/</p>
|
||||
<p>More information: <a href="https://www.openssl.org/">https://www.openssl.org/</a></p>
|
||||
</blockquote>
|
||||
<h4><a class="anchor" name="java-keystore" href="#java-keystore"><i class="anchor-icon"></i></a>Java keystore</h4>
|
||||
<p>Generate self-signed JKS:<br><code>keytool -genkey -keyalg RSA -alias YOURDOMAIN.EXAMPLE -keystore YOURJKS.jks -storepass YOURPASSWORD -validity 360 -keysize 2048</code></p>
|
||||
<p>Converting JKS to pkcs12 (intermediate step for conversion to PEM):<br><code>keytool -importkeystore -srckeystore YOURJKS.jks -destkeystore YOURPKCS.p12 -srcstoretype jks -deststoretype pkcs12</code></p>
|
||||
<p>Convert PKCS12 to PEM (requires openssl):<br><code>openssl pkcs12 -in YOURPKCS.p12 -out YOURPEM.pem</code></p>
|
||||
<h4><a class="anchor" href="#java-keystore" id="java-keystore" name="java-keystore"><i class="anchor-icon"></i></a>Java keystore</h4>
|
||||
<p>Generate self-signed JKS:
|
||||
<code>keytool -genkey -keyalg RSA -alias YOURDOMAIN.EXAMPLE -keystore YOURJKS.jks -storepass YOURPASSWORD -validity 360 -keysize 2048</code></p>
|
||||
<p>Converting JKS to pkcs12 (intermediate step for conversion to PEM):
|
||||
<code>keytool -importkeystore -srckeystore YOURJKS.jks -destkeystore YOURPKCS.p12 -srcstoretype jks -deststoretype pkcs12</code></p>
|
||||
<p>Convert PKCS12 to PEM (requires openssl):
|
||||
<code>openssl pkcs12 -in YOURPKCS.p12 -out YOURPEM.pem</code></p>
|
||||
<blockquote>
|
||||
<p>More information: https://docs.oracle.com</p>
|
||||
<p>More information: <a href="https://docs.oracle.com">https://docs.oracle.com</a></p>
|
||||
</blockquote>
|
||||
<h4><a class="anchor" name="windows" href="#windows"><i class="anchor-icon"></i></a>Windows</h4>
|
||||
<h4><a class="anchor" href="#windows" id="windows" name="windows"><i class="anchor-icon"></i></a>Windows</h4>
|
||||
<p>Creating a self-signed certificate using Windows native utilities is also possible, although OpenSSL binaries for Windows are available online.</p>
|
||||
<p>On the commandline:<br><code>certreq -new TEMPLATE.txt RequestFileOut</code></p>
|
||||
<p>On the commandline:
|
||||
<code>certreq -new TEMPLATE.txt RequestFileOut</code></p>
|
||||
<p>TEMPLATE.txt example file:</p>
|
||||
<pre><code>[NewRequest]
|
||||
|
||||
; At least one value must be set in this section
|
||||
Subject = "CN=DOMAIN.EXAMPLE"
|
||||
Subject = "CN=DOMAIN.EXAMPLE"
|
||||
KeyLength = 2048
|
||||
KeyAlgorithm = RSA
|
||||
HashAlgorithm = sha256
|
||||
|
@ -75,17 +82,22 @@ HashAlgorithm = sha256
|
|||
RequestType = Cert
|
||||
UseExistingKeySet=false ;generates a new private key (for export)
|
||||
Exportable = true ;makes the private key exportable with the PFX</code></pre>
|
||||
<p>A self-signed certificate will be generated and installed, to view the certificate:<br><code>certutil -store -user my</code></p>
|
||||
<p>To export in DER format (intermediate step for conversion to PEM)<br><code>certutil -user -store -split my SERIALNUMBER YOURDER.crt</code></p>
|
||||
<p>Converting to PEM (used for setting the webhook)<br><code>certutil -encode YOURDER.crt YOURPEM.cer</code></p>
|
||||
<p>To delete a certificate from your store:<br><code>certutil -delstore -user my SERIALNUMBER</code> (from view)</p>
|
||||
<p>To export in PFX(PKCS12) format<br><code>certutil -exportpfx -user YOURDOMAIN.EXAMPLE YOURPKCS.pfx NoChain</code></p>
|
||||
<p>A self-signed certificate will be generated and installed, to view the certificate:
|
||||
<code>certutil -store -user my</code></p>
|
||||
<p>To export in DER format (intermediate step for conversion to PEM)
|
||||
<code>certutil -user -store -split my SERIALNUMBER YOURDER.crt</code></p>
|
||||
<p>Converting to PEM (used for setting the webhook)
|
||||
<code>certutil -encode YOURDER.crt YOURPEM.cer</code></p>
|
||||
<p>To delete a certificate from your store:
|
||||
<code>certutil -delstore -user my SERIALNUMBER</code> (from view)</p>
|
||||
<p>To export in PFX(PKCS12) format
|
||||
<code>certutil -exportpfx -user YOURDOMAIN.EXAMPLE YOURPKCS.pfx NoChain</code></p>
|
||||
<blockquote>
|
||||
<p>More information: https://technet.microsoft.com</p>
|
||||
<p>More information: <a href="https://technet.microsoft.com">https://technet.microsoft.com</a></p>
|
||||
</blockquote>
|
||||
<p>Converting YOURPKCS.pfx to PEM including the private key is best done with OpenSSL:<br><code>openssl pkcs12 -in YOURPKCS.pfx -out YOURPEM.cer</code></p>
|
||||
<p>Remember that only the public key is needed as input for the self-signed webhook certificate parameter. certmgr.msc can also be used as a GUI to export the public part of self-signed certificates to PEM.</p>
|
||||
</div>
|
||||
<p>Converting YOURPKCS.pfx to PEM including the private key is best done with OpenSSL:
|
||||
<code>openssl pkcs12 -in YOURPKCS.pfx -out YOURPEM.cer</code></p>
|
||||
<p>Remember that only the public key is needed as input for the self-signed webhook certificate parameter. certmgr.msc can also be used as a GUI to export the public part of self-signed certificates to PEM.</p></div>
|
||||
|
||||
</div>
|
||||
|
||||
|
|
|
@ -39,82 +39,82 @@
|
|||
<div class="dev_page_bread_crumbs"></div>
|
||||
<h1 id="dev_page_title">Encrypted CDNs for Speed and Security</h1>
|
||||
|
||||
<div id="dev_page_content"><p>Following the launch of version 4.2 of the official apps, Telegram client apps may be required to download popular files that were published in public channels with more than <strong>100,000</strong> members from secondary <a href="https://en.wikipedia.org/wiki/Content_delivery_network">Content Delivery Network</a> data centers. These CDN DCs are located in regions with significant Telegram traffic where we wouldn't want to place Telegram servers for various reasons.</p>
|
||||
<p>The CDN DCs are not a part of the Telegram cloud and should be considered enemy territory. For this reason, each file that is to be sent to these CDN DCs is encrypted with a unique key using AES-256-CTR encryption. The CDN <strong>can't access the data</strong> it stores because these keys are only accessible to the main MTProto server and to the authorized client.</p>
|
||||
<div id="dev_page_content"><p>Following the launch of version 4.2 of the official apps, Telegram client apps may be required to download popular files that were published in public channels with more than <strong>100,000</strong> members from secondary <a href="https://en.wikipedia.org/wiki/Content_delivery_network">Content Delivery Network</a> data centers. These CDN DCs are located in regions with significant Telegram traffic where we wouldn't want to place Telegram servers for various reasons.</p>
|
||||
<p>The CDN DCs are not a part of the Telegram cloud and should be considered enemy territory. For this reason, each file that is to be sent to these CDN DCs is encrypted with a unique key using AES-256-CTR encryption. The CDN <strong>can't access the data</strong> it stores because these keys are only accessible to the main MTProto server and to the authorized client.</p>
|
||||
<blockquote>
|
||||
<p><strong>See also:</strong> <a href="/techfaq#encrypted-cdns">More about CDNs and governments in the Advanced FAQ</a></p>
|
||||
</blockquote>
|
||||
<h3><a class="anchor" name="how-this-works" href="#how-this-works"><i class="anchor-icon"></i></a>How this works</h3>
|
||||
<h3><a class="anchor" href="#how-this-works" id="how-this-works" name="how-this-works"><i class="anchor-icon"></i></a>How this works</h3>
|
||||
<p>When a file from a public channel with <strong>~100,000</strong> members becomes popular in a particular region, the Telegram server may encrypt this file with a unique AES-256-CTR key and send it to a relevant CDN DC for storage.</p>
|
||||
<p>When a file is stored in a CDN DC close to the end user, the download speed will be much higher because the data needs to travel smaller distances and will likely avoid many bottlenecks that exist between regions.</p>
|
||||
<p>This is secure because CDN DCs are treated the same way as internet providers / random third parties:</p>
|
||||
<ul>
|
||||
<li>CDN DCs don‘t have the keys to decrypt files that are stored there, so they can’t access the data even if a DC becomes compromised.</li>
|
||||
<li>CDN DCs don't have the keys to decrypt files that are stored there, so they can't access the data even if a DC becomes compromised.</li>
|
||||
<li>Encrypted files fragments are protected from tampering by their SHA-256 hash which is checked on the client upon receipt.</li>
|
||||
<li>No private data is stored in or passed to the CDN DCs.</li>
|
||||
<li>The server only allows media from public channels with more than <strong>100,000</strong> subscribers to be cached in CDN DCs (this includes media forwarded from those channels and viral media that originated from other large public channels).</li>
|
||||
</ul>
|
||||
<div>
|
||||
<a href="/file/811140934/1815/aSQ-nSUHJzc.45662/40c2955965574cef80" target="_blank"><img src="/file/811140934/1815/aSQ-nSUHJzc.45662/40c2955965574cef80" title="CDNs explained" class="dev_page_image" /></a>
|
||||
<a href="/file/811140934/1815/aSQ-nSUHJzc.45662/40c2955965574cef80" target="_blank"><img src="/file/811140934/1815/aSQ-nSUHJzc.45662/40c2955965574cef80" title="CDNs explained" class="dev_page_image"></a>
|
||||
</div>
|
||||
|
||||
<p>CDNs are very limited when it comes to communication: the master data center only uploads encrypted files for storage and will accept no data from the CDN. The client apps only download encrypted files and accept no other updates. The client apps obtain the keys necessary to decrypt the file from the main Telegram server and verify the integrity of the file by its hash, which means that the CDN may only supply the correct file – anything different will be immediately discarded by the client.</p>
|
||||
<p>CDNs are very limited when it comes to communication: the master data center only uploads encrypted files for storage and will accept no data from the CDN. The client apps only download encrypted files and accept no other updates. The client apps obtain the keys necessary to decrypt the file from the main Telegram server and verify the integrity of the file by its hash, which means that the CDN may only supply the correct file – anything different will be immediately discarded by the client.</p>
|
||||
<p>CDN DCs do not store files on hard disks – only in memory. When a CDN server runs out of memory, a simple LRU algorithm is used to replace the least popular files with new ones.</p>
|
||||
<h3><a class="anchor" name="how-cdn-dcs-are-different-from-the-master-dcs" href="#how-cdn-dcs-are-different-from-the-master-dcs"><i class="anchor-icon"></i></a>How CDN DCs are different from the master DCs</h3>
|
||||
<h3><a class="anchor" href="#how-cdn-dcs-are-different-from-the-master-dcs" id="how-cdn-dcs-are-different-from-the-master-dcs" name="how-cdn-dcs-are-different-from-the-master-dcs"><i class="anchor-icon"></i></a>How CDN DCs are different from the master DCs</h3>
|
||||
<ul>
|
||||
<li><strong>CDNs may not be trusted.</strong></li>
|
||||
<li>Client developers can use <a href="/method/help.getCdnConfig">help.getCdnConfig</a> to obtain a list of public RSA keys for CDN DCs, which are different from public RSA keys of the master DCs.</li>
|
||||
<li>CDNs support only the following methods: <a href="/method/upload.getCdnFile">upload.getCdnFile</a>, <a href="/method/initConnection">initConnection</a>, <a href="/method/invokeWithLayer">invokeWithLayer</a>.</li>
|
||||
<li>When working with CDNs, client developers must remember that auth_key may be deleted at any given moment (resulting in a -404 error, in which case a new key must be generated).</li>
|
||||
<li>Client apps must not accept updates from CDN DCs (apps should only accept updates from their main connection to the master DC).</li>
|
||||
<li>Client apps must not accept updates from CDN DCs (apps should only accept updates from their main connection to the master DC).</li>
|
||||
<li>Clients must not allow the CDN DCs to substitute replies to queries sent to other DCs.</li>
|
||||
<li>Clients must not send private user info that is passed in <a href="/method/initConnection">initConnection</a> to the CDNs.</li>
|
||||
</ul>
|
||||
<h3><a class="anchor" name="getting-files-from-a-cdn" href="#getting-files-from-a-cdn"><i class="anchor-icon"></i></a>Getting files from a CDN</h3>
|
||||
<h3><a class="anchor" href="#getting-files-from-a-cdn" id="getting-files-from-a-cdn" name="getting-files-from-a-cdn"><i class="anchor-icon"></i></a>Getting files from a CDN</h3>
|
||||
<p>The API may return the <a href="/constructor/upload.fileCdnRedirect">upload.fileCdnRedirect</a> constructor after an <a href="/method/upload.getFile">upload.getFile</a> query. In this case, the client must request the required file from a CDN DC. The <em>dc_id</em> in the response is the id of the new CDN. The IP address for the connection will be available in <a href="/method/help.getConfig">help.getConfig</a>, same as with the master DCs. The corresponding <a href="/constructor/dcOption">dcOption</a> will have the flag <em>cdn:flags.3?true</em>.</p>
|
||||
<p>Once a successful connection to the CDN-dc_id is established, the client must generate an auth_key (after confirming that the public RSA MTProto key of the CDN DC matches one from the list returned in <a href="/method/help.getCdnConfig">help.getCdnConfig</a>). Then the client must perform an <a href="/method/upload.getCdnFile">upload.getCdnFile</a> for each <em>offset</em>. For files of an unknown size it is necessary to repeat the query until an empty reply is returned.</p>
|
||||
<p><a href="/method/upload.getCdnFile">upload.getCdnFile</a> may return the <a href="/constructor/upload.cdnFileReuploadNeeded">upload.cdnFileReuploadNeeded</a> constructor. In this case, the client needs to send an <a href="/method/upload.reuploadCdnFile">upload.reuploadCdnFile</a> request to the DC that got the original <a href="/method/upload.getFile">upload.getFile</a> request. Once <a href="/method/upload.reuploadCdnFile">upload.reuploadCdnFile</a> is successfull, the app needs to request the file from the CDN DC again.</p>
|
||||
<p>The main DC for a file is the DC where its main copy is stored (not to be confused with the main DC of the user) – either <em>userProfilePhoto.dc_id</em>, <em>chatPhoto.dc_id</em>, <em>photo.dc_id</em>, or <em>document.dc_id</em>.</p>
|
||||
<h3><a class="anchor" name="decrypting-files" href="#decrypting-files"><i class="anchor-icon"></i></a>Decrypting files</h3>
|
||||
<h3><a class="anchor" href="#decrypting-files" id="decrypting-files" name="decrypting-files"><i class="anchor-icon"></i></a>Decrypting files</h3>
|
||||
<p>In <a href="/constructor/upload.fileCdnRedirect">upload.fileCdnRedirect</a>, the server sends a decryption key and IV for the file (the fields <code>encryption_key:bytes</code> and <code>encryption_iv:bytes</code> respectively).</p>
|
||||
<p>Having received a portion of encrypted data from the CDN DC inside <a href="/constructor/upload.cdnFile">upload.cdnFile</a>, the client must decrypt this data using <code>AES-256-CTR</code>. For IV, it should use the value of <code>encryption_iv</code>, modified in the following manner: for each <code>offset</code> replace the last 4 bytes of the <code>encryption_iv</code> with <code>offset / 16</code> in big-endian. This allows to effectively decrypt a file and to use random access to a file's content (e.g., for streaming).</p>
|
||||
<h3><a class="anchor" name="verifying-files" href="#verifying-files"><i class="anchor-icon"></i></a>Verifying files</h3>
|
||||
<p>Having received a portion of encrypted data from the CDN DC inside <a href="/constructor/upload.cdnFile">upload.cdnFile</a>, the client must decrypt this data using <code>AES-256-CTR</code>. For IV, it should use the value of <code>encryption_iv</code>, modified in the following manner: for each <code>offset</code> replace the last 4 bytes of the <code>encryption_iv</code> with <code>offset / 16</code> in big-endian. This allows to effectively decrypt a file and to use random access to a file's content (e.g., for streaming).</p>
|
||||
<h3><a class="anchor" href="#verifying-files" id="verifying-files" name="verifying-files"><i class="anchor-icon"></i></a>Verifying files</h3>
|
||||
<p>In order to confirm that the CDN DC passed an untampered file, clients must verify hashes for each downloaded part. <a href="/constructor/upload.fileCdnRedirect">upload.fileCdnRedirect</a>, <a href="/method/upload.reuploadCdnFile">upload.reuploadCdnFile</a> and <a href="/method/upload.getCdnFileHashes">upload.getCdnFileHashes</a> contain <a href="/type/FileHash">FileHash</a> constructors. Each of these constructors contains the SHA-256 hash of a part of the file that starts with <code>offset</code> and takes <code>limit</code> bytes.</p>
|
||||
<p>Before saving each portion of the data received from the CDN DC into the file, the client must confirm that its hash matches the hash that was received from the master DC. If missing a hash for any file part, client developers must use the <a href="/method/upload.getCdnFileHashes">upload.getCdnFileHashes</a> method to obtain the missing hash.</p>
|
||||
<h3><a class="anchor" name="schema" href="#schema"><i class="anchor-icon"></i></a>Schema</h3>
|
||||
<pre><code>fileHash#6242c773 offset:int limit:int hash:bytes = FileHash;
|
||||
<h3><a class="anchor" href="#schema" id="schema" name="schema"><i class="anchor-icon"></i></a>Schema</h3>
|
||||
<pre><code><a href='/constructor/fileHash'>fileHash</a>#6242c773 offset:<a href='/type/int'>int</a> limit:<a href='/type/int'>int</a> hash:<a href='/type/bytes'>bytes</a> = <a href='/type/FileHash'>FileHash</a>;
|
||||
|
||||
upload.fileCdnRedirect#f18cda44 dc_id:int file_token:bytes encryption_key:bytes encryption_iv:bytes file_hashes:Vector<FileHash> = upload.File;
|
||||
<a href='/constructor/upload.fileCdnRedirect'>upload.fileCdnRedirect</a>#f18cda44 dc_id:<a href='/type/int'>int</a> file_token:<a href='/type/bytes'>bytes</a> encryption_key:<a href='/type/bytes'>bytes</a> encryption_iv:<a href='/type/bytes'>bytes</a> file_hashes:<a href='/type/Vector%20t'>Vector</a><<a href='/type/FileHash'>FileHash</a>> = <a href='/type/upload.File'>upload.File</a>;
|
||||
|
||||
upload.cdnFileReuploadNeeded#eea8e46e request_token:bytes = upload.CdnFile;
|
||||
upload.cdnFile#a99fca4f bytes:bytes = upload.CdnFile;
|
||||
<a href='/constructor/upload.cdnFileReuploadNeeded'>upload.cdnFileReuploadNeeded</a>#eea8e46e request_token:<a href='/type/bytes'>bytes</a> = <a href='/type/upload.CdnFile'>upload.CdnFile</a>;
|
||||
<a href='/constructor/upload.cdnFile'>upload.cdnFile</a>#a99fca4f bytes:<a href='/type/bytes'>bytes</a> = <a href='/type/upload.CdnFile'>upload.CdnFile</a>;
|
||||
|
||||
|
||||
dcOption#18b7a10d flags:# ipv6:flags.0?true media_only:flags.1?true tcpo_only:flags.2?true cdn:flags.3?true static:flags.4?true id:int ip_address:string port:int secret:flags.10?bytes = DcOption;
|
||||
<a href='/constructor/dcOption'>dcOption</a>#18b7a10d flags:<a href='/type/%23'>#</a> ipv6:flags.0?<a href='/constructor/true'>true</a> media_only:flags.1?<a href='/constructor/true'>true</a> tcpo_only:flags.2?<a href='/constructor/true'>true</a> cdn:flags.3?<a href='/constructor/true'>true</a> static:flags.4?<a href='/constructor/true'>true</a> id:<a href='/type/int'>int</a> ip_address:<a href='/type/string'>string</a> port:<a href='/type/int'>int</a> secret:flags.10?<a href='/type/bytes'>bytes</a> = <a href='/type/DcOption'>DcOption</a>;
|
||||
|
||||
cdnPublicKey#c982eaba dc_id:int public_key:string = CdnPublicKey;
|
||||
<a href='/constructor/cdnPublicKey'>cdnPublicKey</a>#c982eaba dc_id:<a href='/type/int'>int</a> public_key:<a href='/type/string'>string</a> = <a href='/type/CdnPublicKey'>CdnPublicKey</a>;
|
||||
|
||||
|
||||
cdnConfig#5725e40a public_keys:Vector<CdnPublicKey> = CdnConfig;
|
||||
<a href='/constructor/cdnConfig'>cdnConfig</a>#5725e40a public_keys:<a href='/type/Vector%20t'>Vector</a><<a href='/type/CdnPublicKey'>CdnPublicKey</a>> = <a href='/type/CdnConfig'>CdnConfig</a>;
|
||||
|
||||
---functions---
|
||||
|
||||
// CDN DC
|
||||
upload.getCdnFile#2000bcc3 file_token:bytes offset:int limit:int = upload.CdnFile;
|
||||
<a href='/method/upload.getCdnFile'>upload.getCdnFile</a>#2000bcc3 file_token:<a href='/type/bytes'>bytes</a> offset:<a href='/type/int'>int</a> limit:<a href='/type/int'>int</a> = <a href='/type/upload.CdnFile'>upload.CdnFile</a>;
|
||||
|
||||
// Master DC
|
||||
upload.reuploadCdnFile#9b2754a8 file_token:bytes request_token:bytes = Vector<FileHash>;
|
||||
upload.getCdnFileHashes#4da54231 file_token:bytes offset:int = Vector<FileHash>;
|
||||
<a href='/method/upload.reuploadCdnFile'>upload.reuploadCdnFile</a>#9b2754a8 file_token:<a href='/type/bytes'>bytes</a> request_token:<a href='/type/bytes'>bytes</a> = <a href='/type/Vector%20t'>Vector</a><<a href='/type/FileHash'>FileHash</a>>;
|
||||
<a href='/method/upload.getCdnFileHashes'>upload.getCdnFileHashes</a>#4da54231 file_token:<a href='/type/bytes'>bytes</a> offset:<a href='/type/int'>int</a> = <a href='/type/Vector%20t'>Vector</a><<a href='/type/FileHash'>FileHash</a>>;
|
||||
|
||||
help.getCdnConfig#52029342 = CdnConfig;</code></pre>
|
||||
<h3><a class="anchor" name="restrictions-on-upload-getfile-and-upload-getcdnfile-parameters" href="#restrictions-on-upload-getfile-and-upload-getcdnfile-parameters"><i class="anchor-icon"></i></a>Restrictions on upload.getFile and upload.getCdnFile parameters</h3>
|
||||
<a href='/method/help.getCdnConfig'>help.getCdnConfig</a>#52029342 = <a href='/type/CdnConfig'>CdnConfig</a>;</code></pre>
|
||||
<h3><a class="anchor" href="#restrictions-on-uploadgetfile-and-uploadgetcdnfile-parameters" id="restrictions-on-uploadgetfile-and-uploadgetcdnfile-parameters" name="restrictions-on-uploadgetfile-and-uploadgetcdnfile-parameters"><i class="anchor-icon"></i></a>Restrictions on upload.getFile and upload.getCdnFile parameters</h3>
|
||||
<ul>
|
||||
<li><code>offset</code> must be divisible by 4096 bytes</li>
|
||||
<li><code>limit</code> must be divisible by 4096 bytes</li>
|
||||
<li>1048576 (1MB) must be divisible by <code>limit</code></li>
|
||||
<li><code>offset / (1024 * 1024) == (offset + limit - 1) / (1024 * 1024)</code><br>(file parts that are being downloaded must always be inside the same megabyte-sized fragment)</li>
|
||||
<li><code>offset / (1024 * 1024) == (offset + limit - 1) / (1024 * 1024)</code>
|
||||
(file parts that are being downloaded must always be inside the same megabyte-sized fragment)</li>
|
||||
</ul>
|
||||
<h3><a class="anchor" name="possible-errors-and-their-meanings" href="#possible-errors-and-their-meanings"><i class="anchor-icon"></i></a>Possible errors and their meanings</h3>
|
||||
<h3><a class="anchor" href="#possible-errors-and-their-meanings" id="possible-errors-and-their-meanings" name="possible-errors-and-their-meanings"><i class="anchor-icon"></i></a>Possible errors and their meanings</h3>
|
||||
<table class="table">
|
||||
<tbody>
|
||||
<tr>
|
||||
|
@ -133,8 +133,7 @@ help.getCdnConfig#52029342 = CdnConfig;</code></pre>
|
|||
<td>The master DC did not accept the <code>request_token</code> from the CDN DC. Continue downloading the file from the master DC using upload.getFile.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</table></div>
|
||||
|
||||
</div>
|
||||
|
||||
|
|
|
@ -4,10 +4,24 @@
|
|||
<meta charset="utf-8">
|
||||
<title>FileHash</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta property="description" content="SHA256 Hash of an uploaded file, to be checked for validity after download">
|
||||
<meta property="description" content="SHA256 Hash of an uploaded file, to be checked for validity after download
|
||||
Parameters
|
||||
Name
|
||||
Type
|
||||
Description
|
||||
offset
|
||||
int
|
||||
Offset…">
|
||||
<meta property="og:title" content="FileHash">
|
||||
<meta property="og:image" content="">
|
||||
<meta property="og:description" content="SHA256 Hash of an uploaded file, to be checked for validity after download">
|
||||
<meta property="og:description" content="SHA256 Hash of an uploaded file, to be checked for validity after download
|
||||
Parameters
|
||||
Name
|
||||
Type
|
||||
Description
|
||||
offset
|
||||
int
|
||||
Offset…">
|
||||
<link rel="shortcut icon" href="/favicon.ico?4" type="image/x-icon" />
|
||||
|
||||
<link href="/css/bootstrap.min.css?3" rel="stylesheet">
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
<h1 id="dev_page_title">payments.ValidatedRequestedInfo</h1>
|
||||
|
||||
<div id="dev_page_content"><p>Validated user-provided info</p>
|
||||
<p>{scheme}</p>
|
||||
<p>{schema}</p>
|
||||
<h3><a class="anchor" href="#parameters" id="parameters" name="parameters"><i class="anchor-icon"></i></a>Parameters</h3>
|
||||
<table class="table">
|
||||
<thead>
|
||||
|
|
|
@ -4,20 +4,10 @@
|
|||
<meta charset="utf-8">
|
||||
<title>upload.getWebfile</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta property="description" content="Returns content of an HTTP file or a part, by proxying the request through telegram.
|
||||
Parameters
|
||||
Name
|
||||
Type
|
||||
Description
|
||||
location…">
|
||||
<meta property="description" content="Returns content of an HTTP file or a part, by proxying the request through telegram.">
|
||||
<meta property="og:title" content="upload.getWebfile">
|
||||
<meta property="og:image" content="">
|
||||
<meta property="og:description" content="Returns content of an HTTP file or a part, by proxying the request through telegram.
|
||||
Parameters
|
||||
Name
|
||||
Type
|
||||
Description
|
||||
location…">
|
||||
<meta property="og:description" content="Returns content of an HTTP file or a part, by proxying the request through telegram.">
|
||||
<link rel="shortcut icon" href="/favicon.ico?4" type="image/x-icon" />
|
||||
|
||||
<link href="/css/bootstrap.min.css?3" rel="stylesheet">
|
||||
|
@ -107,12 +97,7 @@ location…">
|
|||
<tr>
|
||||
<td>400</td>
|
||||
<td>LOCATION_INVALID</td>
|
||||
<td>The provided location is invalid</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>400</td>
|
||||
<td>BOT_METHOD_INVALID</td>
|
||||
<td>This method can't be used by a bot</td>
|
||||
<td>The provided location is invalid.</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table></div>
|
||||
|
|
|
@ -44,11 +44,11 @@ End-to-end encryption in MTProto,…">
|
|||
<h1 id="dev_page_title">Current end-to-end TL-schema</h1>
|
||||
|
||||
<div id="dev_page_content"><blockquote>
|
||||
<p>Below you will find the current end-to-end TL-schema. <a href="/mtproto/TL">More details on TL »</a></p>
|
||||
<p>Below you will find the current end-to-end TL-schema. <a href="/mtproto/TL">More details on TL »</a> </p>
|
||||
</blockquote>
|
||||
<p>See also:
|
||||
<a href="/api/end-to-end">End-to-end encryption in MTProto, Secret Chats</a>
|
||||
<a href="/schema/end-to-end-json">Detailed schema in JSON</a></p></div>
|
||||
<p>See also:<br>
|
||||
<a href="/api/end-to-end">End-to-end encryption in MTProto, Secret Chats</a><br>
|
||||
<a href="/schema/end-to-end-json">Detailed schema in JSON</a> </p></div>
|
||||
<div class="clearfix">
|
||||
<ul class="dev_layer_select slightly-pull-right nav nav-pills">
|
||||
<li class="dropdown">
|
||||
|
|
|
@ -43,8 +43,8 @@ int ? = Int;…">
|
|||
<div class="dev_page_bread_crumbs"><ul class="breadcrumb clearfix"><li><a href="/mtproto" >Mobile Protocol</a></li><i class="icon icon-breadcrumb-divider"></i><li><a href="/schema/mtproto" >Current MTProto TL-schema</a></li></ul></div>
|
||||
<h1 id="dev_page_title">Current MTProto TL-schema</h1>
|
||||
|
||||
<div id="dev_page_content"><p>Below you will find the current MTProto TL-schema. <a href="/mtproto/TL">More details on TL »</a></p>
|
||||
<p>See also the <a href="/schema/mtproto-json">detailed schema in JSON »</a></p>
|
||||
<div id="dev_page_content"><p>Below you will find the current MTProto TL-schema. <a href="/mtproto/TL">More details on TL »</a> </p>
|
||||
<p>See also the <a href="/schema/mtproto-json">detailed schema in JSON »</a> </p>
|
||||
<p><br></p>
|
||||
<pre><code>int ? = Int;
|
||||
long ? = Long;
|
||||
|
|
|
@ -135,11 +135,15 @@
|
|||
|
||||
<h3><a class="anchor" name="ad-info" href="#ad-info"><i class="anchor-icon"></i></a>Ad Info</h3>
|
||||
<p>Click any of your ads on the <a href="http://promote.telegram.org/account">homepage</a> to make changes to its <strong>content</strong> and <strong>CPM</strong>, increase its <strong>budget</strong>, or see <strong>statistics</strong>. The title, text and URL of your sponsored message can be updated at any time (but not its targeting parameters) – to see a preview of how the sponsored message looks inside a channel, click ‘Preview Ad’.</p>
|
||||
<div class="blog_video_player_wrap" style="max-width: 400px; margin: 20px auto 20px;">
|
||||
<video class="blog_video_player tl_blog_vid_autoplay" onclick="videoTogglePlay(this)" autoplay loop controls muted poster="/file/464001822/2/7LDj5vvqN-A.44634/9b076decf0c3e89fee" style="max-width: 400px;" title="TITLE" alt="TITLE">
|
||||
<source src="/file/464001106/3/oozYA9s9aoY.995176.mp4/44b270207efac83a9a" type="video/mp4">
|
||||
</video>
|
||||
</div>
|
||||
|
||||
<blockquote>
|
||||
<p>If you would like to change the targeting parameters, click <strong>‘Create a similar ad’</strong> – this opens a new template with the same content so you can quickly make a new version.</p>
|
||||
</blockquote>
|
||||
<!--[screenshot of ad preview window]-->
|
||||
|
||||
<h3><a class="anchor" name="ad-budget" href="#ad-budget"><i class="anchor-icon"></i></a>Ad Budget</h3>
|
||||
<p>To <strong>increase the budget</strong> of your ad, click the ‘Current Budget’ field. You can also change the <strong>CPM</strong> to be higher or lower from the ‘CPM’ field. If you need to <strong>delete</strong> your ad (perhaps to resubmit it with new targeting parameters or a lower budget) tap ‘Delete Ad’.</p>
|
||||
<blockquote>
|
||||
|
@ -169,16 +173,16 @@
|
|||
<p>Once you've <a href="#adding-funds">added funds</a> to your account, you will get access to Telegram's dedicated <strong>Ad Platform Support</strong>.</p>
|
||||
<!--
|
||||
|
||||
<div class="blog_image_wrap blog_medium_image_wrap">
|
||||
<a href="LARGE" target="_blank"><img src="SMALL" title="TITLE" alt="TITLE" srcset="LARGE , 2x" /></a>
|
||||
</div>
|
||||
|
||||
<div class="blog_video_player_wrap" style="max-width: 400px; margin: 20px auto 20px;">
|
||||
<video class="blog_video_player tl_blog_vid_autoplay" onclick="videoTogglePlay(this)" autoplay loop controls muted poster="PHOTO" style="max-width: 400px;" title="TITLE" alt="TITLE">
|
||||
<source src="VIDEO" type="video/mp4">
|
||||
</video>
|
||||
</div>
|
||||
|
||||
<div class="blog_image_wrap blog_medium_image_wrap">
|
||||
<a href="LARGE" target="_blank"><img src="SMALL" title="TITLE" alt="TITLE" srcset="LARGE , 2x" /></a>
|
||||
</div>
|
||||
|
||||
--></div>
|
||||
|
||||
</div></section>
|
||||
|
|
Loading…
Reference in a new issue