mirror of
https://github.com/MarshalX/telegram-crawler.git
synced 2025-03-15 13:22:43 +01:00
Update content of files
This commit is contained in:
parent
7075e70dd9
commit
ddf1032963
24 changed files with 7816 additions and 9209 deletions
198
data/web/core.telegram.org/bug-bounty.html
Normal file
198
data/web/core.telegram.org/bug-bounty.html
Normal file
|
@ -0,0 +1,198 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Telegram Bug Bounty Program</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta property="description" content="Telegram welcomes developers and the security research community to audit its services, code and protocol seeking vulnerabilities or security-related issues.">
|
||||
<meta property="og:title" content="Telegram Bug Bounty Program">
|
||||
<meta property="og:image" content="">
|
||||
<meta property="og:description" content="Telegram welcomes developers and the security research community to audit its services, code and protocol seeking vulnerabilities or security-related issues.">
|
||||
<link rel="icon" type="image/svg+xml" href="/img/website_icon.svg?4">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/img/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/img/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/img/favicon-16x16.png">
|
||||
<link rel="alternate icon" href="/img/favicon.ico" type="image/x-icon" />
|
||||
<link href="/css/bootstrap.min.css?3" rel="stylesheet">
|
||||
|
||||
<link href="/css/telegram.css?232" rel="stylesheet" media="screen">
|
||||
<style>
|
||||
</style>
|
||||
</head>
|
||||
<body class="preload">
|
||||
<div class="dev_page_wrap">
|
||||
<div class="dev_page_head navbar navbar-static-top navbar-tg">
|
||||
<div class="navbar-inner">
|
||||
<div class="container clearfix">
|
||||
<ul class="nav navbar-nav navbar-right hidden-xs"><li class="navbar-twitter"><a href="https://twitter.com/telegram" target="_blank" data-track="Follow/Twitter" onclick="trackDlClick(this, event)"><i class="icon icon-twitter"></i><span> Twitter</span></a></li></ul>
|
||||
<ul class="nav navbar-nav">
|
||||
<li><a href="//telegram.org/">Home</a></li>
|
||||
<li class="hidden-xs"><a href="//telegram.org/faq">FAQ</a></li>
|
||||
<li class="hidden-xs"><a href="//telegram.org/apps">Apps</a></li>
|
||||
<li class=""><a href="/api">API</a></li>
|
||||
<li class=""><a href="/mtproto">Protocol</a></li>
|
||||
<li class=""><a href="/schema">Schema</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container clearfix">
|
||||
<div class="dev_page">
|
||||
<div id="dev_page_content_wrap" class=" ">
|
||||
<div class="dev_page_bread_crumbs"></div>
|
||||
<h1 id="dev_page_title">Telegram Bug Bounty Program</h1>
|
||||
|
||||
<div id="dev_page_content"><p>Telegram welcomes developers and the security research community to audit its services, <a href="https://telegram.org/apps#source-code">code</a> and <a href="https://core.telegram.org/mtproto">protocol</a> seeking vulnerabilities or security-related issues.</p>
|
||||
<p>Security researchers can <a href="#submission">submit</a> any relevant issues they find at <a href="mailto:security@telegram.org">security@telegram.org</a>. All reports submitted in accordance with the <a href="#rules-and-principles">rules</a> and <a href="#program-scope">scope</a> outlined below which result in a change of code or configuration are eligible for bounties, ranging from <strong>$100</strong> to <strong>$100,000</strong> or more, depending on the severity of the issue.</p>
|
||||
<blockquote>
|
||||
<p>Telegram's <strong>bug bounty program</strong> has been continuously active <a href="https://telegram.org/blog/cryptocontest">since 2014</a>.</p>
|
||||
</blockquote>
|
||||
<h3><a class="anchor" name="rules-and-principles" href="#rules-and-principles"><i class="anchor-icon"></i></a>Rules and Principles</h3>
|
||||
<p>Generally speaking, the purpose of Telegram's <strong>bug bounty program</strong> is to improve the safety of our platform thanks to cutting-edge technologies and modern penetration testing techniques. In accordance with this principle, we expect security professionals to employ common sense and to operate in good faith when researching issues – below is a <strong>non-exhaustive</strong> list of rules that always apply: </p>
|
||||
<ul>
|
||||
<li>Your testing <strong>cannot violate any law</strong>, <strong>disrupt</strong> Telegram's services or <strong>negatively affect</strong> other users in any way.</li>
|
||||
<li>Vulnerabilities that are disclosed to the public or to third parties <strong>before they are addressed</strong> are not eligible for our bug bounty program. This includes vulnerability brokers. </li>
|
||||
<li>Attempting to gain <strong>physical access</strong> to any of Telegram’s equipment is strictly prohibited.</li>
|
||||
<li><p>Should you be eligible for a prize, you are <strong>responsible for any taxes</strong> and fees depending on your country of residency.</p>
|
||||
</li>
|
||||
<li><p>This bounty program is <strong>security-focused</strong> and therefore <strong>does not</strong> cover denial of service or load balancing issues resulting from spam, brute forcing, coordinated DDoS attacks, etc. Consequently, you are <strong>not allowed</strong> to perform any such action on our services.</p>
|
||||
</li>
|
||||
</ul>
|
||||
<p>Researchers are welcome to use our dedicated <strong>test environment</strong> if they require it – instructions on how to access it can be found <a href="#test-environment">here</a>.</p>
|
||||
<blockquote>
|
||||
<p>Telegram will not take legal action against anyone who responsibly researches and discloses vulnerabilities in accordance with our rules.</p>
|
||||
</blockquote>
|
||||
<h3><a class="anchor" name="non-qualifying-issues" href="#non-qualifying-issues"><i class="anchor-icon"></i></a>Non-qualifying issues</h3>
|
||||
<p>Reports should focus on the <strong>security-related</strong> severity and impact of the vulnerability. Below is a non-exhaustive list of issues that generally <strong>do not</strong> qualify for our program.</p>
|
||||
<p><strong>1</strong>. Phishing attacks, spam<br><strong>2</strong>. Token or session hijacking as a result of external <strong>malware</strong> on the OS<br><strong>3</strong>. Irrelevant reports from scanners or automated tools<br><strong>4</strong>. Attacks requiring physical access to the user's device<br><strong>5</strong>. Missing cookie flags (HttpOnly, Secure, etc.)<br><strong>6</strong>. Attacks requiring root access to the user's device<br><strong>7</strong>. Clickjacking<br><strong>8</strong>. Non-reproducible vulnerabilities deriving from outdated or reportedly flawed versions of open-source software<br><strong>9</strong>. Vulnerabilities that rely on social engineering to either obtain sensitive credentials or have the user perform an unlikely sequence of actions<br><strong>10</strong>. Presence of banner or version information, SSL/TLS best practices, etc.</p>
|
||||
<blockquote>
|
||||
<p>An issue may only be submitted <strong>once</strong>. Duplicate issues submitted by either the same person or multiple people do not qualify – only the first report will be evaluated.</p>
|
||||
</blockquote>
|
||||
<h3><a class="anchor" name="program-scope" href="#program-scope"><i class="anchor-icon"></i></a>Program Scope</h3>
|
||||
<p>Generally, any <strong>Telegram-owned</strong> or <strong>operated</strong> app, web service, domain, server and protocol that either handles or stores <strong>private user data</strong> is in scope. </p>
|
||||
<p>Any <strong>unrelated bug</strong> (e.g. usability, interface, etc.) that doesn't impact security in any way is out of scope and should instead be reported on our dedicated public <a href="https://bugs.telegram.org/">bug tracking platform</a>.</p>
|
||||
<h4><a class="anchor" name="protocol" href="#protocol"><i class="anchor-icon"></i></a>Protocol</h4>
|
||||
<p>Telegram relies on <strong>MTProto 2.0</strong>, a protocol specifically designed for <strong>speed and security</strong>. The full technical documentation is available <a href="https://core.telegram.org/mtproto">here</a>. We welcome any reports about vulnerabilities or design flaws in the protocol which could realistically result in <strong>unauthorized access</strong> to user data.</p>
|
||||
<h4><a class="anchor" name="applications" href="#applications"><i class="anchor-icon"></i></a>Applications</h4>
|
||||
<p>Official Telegram apps are <strong>open source</strong> and support <a href="https://core.telegram.org/reproducible-builds">reproducible builds</a>. <strong>Pre-built executables</strong> can be found <a href="https://telegram.org/apps">here</a>, while the full <strong>source code</strong> for each app is available <a href="https://telegram.org/apps#source-code">here</a>.</p>
|
||||
<h4><a class="anchor" name="domains" href="#domains"><i class="anchor-icon"></i></a>Domains</h4>
|
||||
<p>Below is a list of <strong>Telegram domains</strong> which can be considered in scope. Third-party domains that integrate Telegram pages or services are <strong>out of scope</strong>. Low-impact issues which don't pose a significant risk and don't fall under our <a href="#non-qualifying-issues">non-qualifying issues</a> may be in scope but could be awarded a smaller prize.</p>
|
||||
<ul>
|
||||
<li>telegram.org, *.telegram.org</li>
|
||||
<li>t.me, *.t.me</li>
|
||||
<li>tg.dev, *.tg.dev</li>
|
||||
<li>telegram.me, *.telegram.me</li>
|
||||
<li>*.telesco.pe</li>
|
||||
<li>*.stel.com</li>
|
||||
<li>contest.com</li>
|
||||
<li>quiz.directory</li>
|
||||
<li>telegra.ph</li>
|
||||
</ul>
|
||||
<h4><a class="anchor" name="third-party-applications-and-services" href="#third-party-applications-and-services"><i class="anchor-icon"></i></a>Third-Party Applications and Services</h4>
|
||||
<p>Apps developed by <strong>third parties</strong> using the open <a href="https://core.telegram.org/schema">Telegram API</a>, as well as bots running under <a href="https://core.telegram.org/bots/api">Telegram's Bot API</a>, can only be considered in scope if the report targets a <strong>vulnerability on our end</strong> (e.g. vulnerable endpoint which poses a security risk). </p>
|
||||
<p>Issues caused by third-party developers' <strong>malpractice</strong>, <strong>negligence</strong> or <strong>incorrect implementation</strong> of our <a href="https://core.telegram.org/mtproto/security_guidelines">Security Guidelines</a> are <strong>out of scope</strong> and should instead be promptly reported to the relevant developers.</p>
|
||||
<h3><a class="anchor" name="submission" href="#submission"><i class="anchor-icon"></i></a>Submission</h3>
|
||||
<p>If you found an issue which is <a href="#program-scope">in scope</a>, is <a href="#non-qualifying-issues">eligible</a> and was found in accordance to our <a href="#rules-and-principles">rules</a>, you are welcome to submit it to <a href="mailto:security@telegram.org">security@telegram.org</a>.</p>
|
||||
<p>We expect all reports to be written in English and to <strong>follow a consistent template</strong>, spacing included:</p>
|
||||
<pre><code># Attack surface: (e.g. my.telegram.org/auth)
|
||||
# Severity: (e.g. 7) [Optional, CVSS v3 rating]
|
||||
|
||||
## Description:
|
||||
[Describe the vulnerability briefly here, including its type]
|
||||
|
||||
## Steps to reproduce:
|
||||
[1] Step one...
|
||||
[2] Step two...
|
||||
[n] Finally...
|
||||
|
||||
## Impact:
|
||||
[What practical, realistic risk does this vulnerability pose?]
|
||||
|
||||
## Additional details:
|
||||
[Tools used, preconditions, media proof, session and timestamps as needed]</code></pre>
|
||||
<h3><a class="anchor" name="prize" href="#prize"><i class="anchor-icon"></i></a>Prize</h3>
|
||||
<p>Valid reports that result in a change of code or configuration are eligible for bounties, ranging from <strong>$100</strong> to <strong>$100,000</strong> or more, depending on the severity of the issue. We reserve the right to ultimately determine both the validity and the appropriate compensation for each report at our discretion.</p>
|
||||
<hr>
|
||||
<h4><a class="anchor" name="test-environment" href="#test-environment"><i class="anchor-icon"></i></a>Test Environment</h4>
|
||||
<p>To log in to the <strong>test environment</strong>, use either of the following:</p>
|
||||
<p><strong>iOS</strong>: tap 10 times on the Settings icon > Accounts > Login to another account > Test.<br><strong>Telegram Desktop</strong>: open ☰ Settings > Shift + Alt + Right click ‘Add Account’ and select ‘Test Server’.<br><strong>macOS</strong>: click the Settings icon 10 times to open the Debug Menu, ⌘ + click ‘Add Account’ and log in via phone number.</p>
|
||||
<p>The test environment is <strong>completely separate</strong> from the main environment, so you will need to create a new user account (or a new bot with <a href="https://t.me/botfather">@BotFather</a>).</p>
|
||||
<p>You can send requests to the test <a href="https://core.telegram.org/bots/api">Bot API</a> in this format:</p>
|
||||
<p><code>https://api.telegram.org/bot<token>/test/METHOD_NAME</code></p>
|
||||
<blockquote>
|
||||
<p>When working within the test environment, you may use HTTP links without TLS to test Web Apps.</p>
|
||||
</blockquote>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer_wrap">
|
||||
<div class="footer_columns_wrap footer_desktop">
|
||||
<div class="footer_column footer_column_telegram">
|
||||
<h5>Telegram</h5>
|
||||
<div class="footer_telegram_description"></div>
|
||||
Telegram is a cloud-based mobile and desktop messaging app with a focus on security and speed.
|
||||
</div>
|
||||
|
||||
<div class="footer_column">
|
||||
<h5><a href="//telegram.org/faq">About</a></h5>
|
||||
<ul>
|
||||
<li><a href="//telegram.org/faq">FAQ</a></li>
|
||||
<li><a href="//telegram.org/privacy">Privacy</a></li>
|
||||
<li><a href="//telegram.org/press">Press</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer_column">
|
||||
<h5><a href="//telegram.org/apps#mobile-apps">Mobile Apps</a></h5>
|
||||
<ul>
|
||||
<li><a href="//telegram.org/dl/ios">iPhone/iPad</a></li>
|
||||
<li><a href="//telegram.org/android">Android</a></li>
|
||||
<li><a href="//telegram.org/dl/web">Mobile Web</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer_column">
|
||||
<h5><a href="//telegram.org/apps#desktop-apps">Desktop Apps</a></h5>
|
||||
<ul>
|
||||
<li><a href="//desktop.telegram.org/">PC/Mac/Linux</a></li>
|
||||
<li><a href="//macos.telegram.org/">macOS</a></li>
|
||||
<li><a href="//telegram.org/dl/web">Web-browser</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer_column footer_column_platform">
|
||||
<h5><a href="/">Platform</a></h5>
|
||||
<ul>
|
||||
<li><a href="/api">API</a></li>
|
||||
<li><a href="//translations.telegram.org/">Translations</a></li>
|
||||
<li><a href="//instantview.telegram.org/">Instant View</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer_columns_wrap footer_mobile">
|
||||
<div class="footer_column">
|
||||
<h5><a href="//telegram.org/faq">About</a></h5>
|
||||
</div>
|
||||
<div class="footer_column">
|
||||
<h5><a href="//telegram.org/blog">Blog</a></h5>
|
||||
</div>
|
||||
<div class="footer_column">
|
||||
<h5><a href="//telegram.org/apps">Apps</a></h5>
|
||||
</div>
|
||||
<div class="footer_column">
|
||||
<h5><a href="/">Platform</a></h5>
|
||||
</div>
|
||||
<div class="footer_column">
|
||||
<h5><a href="https://twitter.com/telegram" target="_blank" data-track="Follow/Twitter" onclick="trackDlClick(this, event)">Twitter</a></h5>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="/js/main.js?46"></script>
|
||||
|
||||
<script>backToTopInit("Go up");
|
||||
removePreloadInit();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
587
data/web/corefork.telegram.org/bots/features.html
Normal file
587
data/web/corefork.telegram.org/bots/features.html
Normal file
|
@ -0,0 +1,587 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Telegram Bot Features</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta property="description" content="This page describes individual bot elements in greater detail. For a general overview of bots, read the introduction to bots first.">
|
||||
<meta property="og:title" content="Telegram Bot Features">
|
||||
<meta property="og:image" content="https://corefork.telegram.org/file/464001858/11318/ahAJjwERIX8.164875/ce1372cbf73e3ea94e">
|
||||
<meta property="og:description" content="This page describes individual bot elements in greater detail. For a general overview of bots, read the introduction to bots first.">
|
||||
<link rel="icon" type="image/svg+xml" href="/img/website_icon.svg?4">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/img/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/img/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/img/favicon-16x16.png">
|
||||
<link rel="alternate icon" href="/img/favicon.ico" type="image/x-icon" />
|
||||
<link href="/css/bootstrap.min.css?3" rel="stylesheet">
|
||||
|
||||
<link href="/css/telegram.css?232" rel="stylesheet" media="screen">
|
||||
<style>
|
||||
</style>
|
||||
</head>
|
||||
<body class="preload">
|
||||
<div class="dev_page_wrap">
|
||||
<div class="dev_page_head navbar navbar-static-top navbar-tg">
|
||||
<div class="navbar-inner">
|
||||
<div class="container clearfix">
|
||||
<ul class="nav navbar-nav navbar-right hidden-xs"><li class="navbar-twitter"><a href="https://twitter.com/telegram" target="_blank" data-track="Follow/Twitter" onclick="trackDlClick(this, event)"><i class="icon icon-twitter"></i><span> Twitter</span></a></li></ul>
|
||||
<ul class="nav navbar-nav">
|
||||
<li><a href="//telegram.org/">Home</a></li>
|
||||
<li class="hidden-xs"><a href="//telegram.org/faq">FAQ</a></li>
|
||||
<li class="hidden-xs"><a href="//telegram.org/apps">Apps</a></li>
|
||||
<li class=""><a href="/api">API</a></li>
|
||||
<li class=""><a href="/mtproto">Protocol</a></li>
|
||||
<li class=""><a href="/schema">Schema</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container clearfix">
|
||||
<div class="dev_page">
|
||||
<div id="dev_page_content_wrap" class=" ">
|
||||
<div class="dev_page_bread_crumbs"><ul class="breadcrumb clearfix"><li><a href="/bots" >Telegram Bots</a></li><i class="icon icon-breadcrumb-divider"></i><li><a href="/bots/features" >Telegram Bot Features</a></li></ul></div>
|
||||
<h1 id="dev_page_title">Telegram Bot Features</h1>
|
||||
|
||||
<div id="dev_page_content"><!-- scroll_nav -->
|
||||
|
||||
<p>This page describes individual <strong>bot elements</strong> and <strong>features</strong> in detail. See also:</p>
|
||||
<ul>
|
||||
<li><a href="/bots">A General Bot Platform Overview</a></li>
|
||||
<li><a href="/bots/api">Full API Reference for Developers</a></li>
|
||||
</ul>
|
||||
<h3><a class="anchor" href="#what-features-do-bots-have" id="what-features-do-bots-have" name="what-features-do-bots-have"><i class="anchor-icon"></i></a>What features do bots have?</h3>
|
||||
<ul>
|
||||
<li><a href="#inputs"><strong>Inputs</strong></a><ul>
|
||||
<li><a href="#inputs">Text</a></li>
|
||||
<li><a href="#commands">Commands</a></li>
|
||||
<li><a href="#keyboards">Buttons</a> </li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#interactions"><strong>Interactions</strong></a><ul>
|
||||
<li><a href="#inline-requests">Inline</a></li>
|
||||
<li><a href="#deep-linking">Deep Linking</a></li>
|
||||
<li><a href="#attachment-menu">Attachment Menu</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#integration"><strong>Integration</strong></a><ul>
|
||||
<li><a href="#web-apps">Web Apps</a></li>
|
||||
<li><a href="#payments">Payments</a></li>
|
||||
<li><a href="#web-login">Web Login</a></li>
|
||||
<li><a href="#html5-games">HTML5 Games</a></li>
|
||||
<li><a href="#stickers">Stickers</a> </li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#language-support"><strong>Language Support</strong></a></li>
|
||||
<li><a href="#bot-management"><strong>Bot Management</strong></a><ul>
|
||||
<li><a href="#privacy-mode">Privacy Mode</a></li>
|
||||
<li><a href="#status-alerts">Status Alerts</a></li>
|
||||
<li><a href="#local-bot-api">Local API</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><a href="#botfather"><strong>BotFather, creating and managing bots</strong></a></li>
|
||||
</ul>
|
||||
<hr>
|
||||
<h3><a class="anchor" href="#inputs" id="inputs" name="inputs"><i class="anchor-icon"></i></a>Inputs</h3>
|
||||
<p>Users can send <strong>messages of all types</strong> to bots, including text, files, locations, stickers, voice messages and even <a href="/bots/api#dice">dice</a> if they're feeling lucky. However, Telegram bots offer many other tools for building flexible interfaces tailored to your specific needs:</p>
|
||||
<ul>
|
||||
<li><a href="#commands">Commands</a> that are highlighted in messages and can be selected from a list after typing <code>/</code>.</li>
|
||||
<li><a href="#keyboards">Keyboards</a> that replace the user's keyboard with predefined answer options.</li>
|
||||
<li><a href="#inline-keyboards">Buttons</a> that are shown next to messages from the bot.</li>
|
||||
</ul>
|
||||
<p>For even more flexibility, <a href="#web-apps">Web Apps</a> support 100% custom interfaces with JavaScript. </p>
|
||||
<div>
|
||||
<a href="/file/464001858/11318/ahAJjwERIX8.164875/ce1372cbf73e3ea94e" target="_blank"><img src="/file/464001858/11318/ahAJjwERIX8.164875/ce1372cbf73e3ea94e" title="Inputs" class="dev_page_image" width="70%"></a>
|
||||
</div>
|
||||
<blockquote>
|
||||
<p><strong>Note:</strong> Telegram bots can support <a href="#language-support">multiple languages</a> that adapt to the users' language settings in the app.</p>
|
||||
</blockquote>
|
||||
<h4><a class="anchor" href="#commands" id="commands" name="commands"><i class="anchor-icon"></i></a>Commands</h4>
|
||||
<p>A command is a simple <code>/keyword</code> that tells the bot what to do. Telegram apps will:</p>
|
||||
<ul>
|
||||
<li><strong>Highlight</strong> commands in messages. When the user taps a highlighted command, that command is immediately sent again.</li>
|
||||
<li>Suggest a <strong>list of supported commands</strong> with descriptions when the user enters a <code>/</code> (for this to work, you need to have provided a list of commands to <a href="https://t.me/botfather">@BotFather</a> or via the <a href="/bots/api#setmycommands">appropriate API method</a>). Selecting a command from the list immediately sends it.</li>
|
||||
<li>Show a <a href="#menu-button">menu button</a> containing all or some of a bot’s commands (which you set via <a href="https://t.me/botfather">@BotFather</a>).</li>
|
||||
</ul>
|
||||
<p>Commands must always start with the <code>/</code> symbol and contain <strong>up to 32 characters</strong>. They can use <strong>Latin letters</strong>, <strong>numbers</strong> and <strong>underscores</strong>, though simple lowercase text is recommended for a cleaner look. </p>
|
||||
<p>Here are a few examples:</p>
|
||||
<ul>
|
||||
<li>/next </li>
|
||||
<li>/cancel </li>
|
||||
<li>/newlocation </li>
|
||||
<li>/newrule </li>
|
||||
</ul>
|
||||
<p>Commands should be <strong>as specific as possible</strong> – for example <code>/newlocation</code> or <code>/newrule</code> <strong>is better</strong> than a <code>/new</code> command that then requires an additional parameter from the user like "<em>location</em>" or "<em>rule</em>".</p>
|
||||
<div>
|
||||
<a href="/file/464001775/10227/HCr0XgSUHrg.119089/c17ff5d34fe528361e" target="_blank"><img src="/file/464001775/10227/HCr0XgSUHrg.119089/c17ff5d34fe528361e" title="Commands" class="dev_page_image" width="44%"></a>
|
||||
</div>
|
||||
<blockquote>
|
||||
<p>We require <strong>all developers</strong> to support several <a href="#global-commands">Global Commands</a> to make sure Telegram bots offer a consistent and user-friendly experience.</p>
|
||||
</blockquote>
|
||||
<h5><a class="anchor" href="#command-scopes" id="command-scopes" name="command-scopes"><i class="anchor-icon"></i></a>Command Scopes</h5>
|
||||
<p>Your bot is able to <strong>show different commands</strong> to different users and groups – you can control this using <a href="/bots/api#botcommandscope">scopes</a>. For example, your bot could show additional commands to group admins or translate the list based on the user’s <a href="/bots/api#user">language_code</a>.</p>
|
||||
<blockquote>
|
||||
<p>Keep in mind that Bot API <a href="/bots/api#update">updates</a> <strong>will not contain any information</strong> about the scope of a command sent by the user – in fact, they may contain commands that don’t exist at all in your bot. Your backend should <strong>always</strong> verify that received commands are valid and that the user was authorized to use them regardless of scope.</p>
|
||||
</blockquote>
|
||||
<blockquote>
|
||||
<p>Bots with privacy mode enabled will only receive commands in groups under special conditions, <a href="#privacy-mode">see here</a>.</p>
|
||||
</blockquote>
|
||||
<h4><a class="anchor" href="#keyboards" id="keyboards" name="keyboards"><i class="anchor-icon"></i></a>Keyboards</h4>
|
||||
<p>Bots are able to interpret free text input from users, but offering <strong>specific suggestions</strong> is often more intuitive – this is where <strong>custom keyboards</strong> can be extremely useful.</p>
|
||||
<p>Whenever your bot sends a message, it can <strong>display a special keyboard</strong> with predefined reply options (see <a href="/bots/api#replykeyboardmarkup">ReplyKeyboardMarkup</a>). Telegram apps that receive the message will display your keyboard to the user. Using any of the buttons will immediately send the respective text. This way you can drastically <strong>simplify</strong> and <strong>streamline</strong> user interaction with your bot.</p>
|
||||
<div>
|
||||
<a href="/file/464001950/1191a/2RwpmgU-swU.123554/b50478c124d5914c23" target="_blank"><img src="/file/464001950/1191a/2RwpmgU-swU.123554/b50478c124d5914c23" title="Keyboards" class="dev_page_image" width="44%"></a>
|
||||
</div>
|
||||
<blockquote>
|
||||
<p>Check out the <a href="/bots/api#replykeyboardmarkup">one_time_keyboard</a> parameter to automatically hide your bot's keyboard as soon as it's been used.</p>
|
||||
</blockquote>
|
||||
<p>You can also <strong>customize the text placeholder</strong> in the input field by setting the <code>input_field_placeholder</code> parameter.</p>
|
||||
<h4><a class="anchor" href="#inline-keyboards" id="inline-keyboards" name="inline-keyboards"><i class="anchor-icon"></i></a>Inline Keyboards</h4>
|
||||
<p>There are times when you'd prefer to do things <strong>without sending any messages</strong> to the chat – like when a user is changing settings, toggling options or navigating search results. In such cases, you can use <a href="/bots/api#inlinekeyboardmarkup">Inline Keyboards</a> that are shown directly below their relevant messages.</p>
|
||||
<p>Unlike with custom reply keyboards, pressing buttons on inline keyboards <strong>doesn't send messages to the chat</strong>. Instead, inline keyboards support buttons that can work behind the scenes or open different interfaces: <a href="/bots/api#inlinekeyboardbutton">callback buttons</a>, <a href="/bots/api#inlinekeyboardbutton">URL buttons</a>, <a href="/bots/api#inlinekeyboardbutton">switch-to-inline buttons</a>, <a href="/bots/api#inlinekeyboardbutton">game buttons</a> and <a href="/bots/api#inlinekeyboardbutton">payment buttons</a>. </p>
|
||||
<div>
|
||||
<a href="/file/464001863/110f3/I47qTXAD9Z4.120010/e0ea04f66357b640ec" target="_blank"><img src="/file/464001863/110f3/I47qTXAD9Z4.120010/e0ea04f66357b640ec" title="Inline Keyboard" class="dev_page_image" width="44%"></a>
|
||||
</div>
|
||||
<blockquote>
|
||||
<p>To provide a <strong>better user experience</strong>, consider <a href="/bots/api#editmessagereplymarkup">editing your keyboard</a> when the user toggles a setting button or navigates to a new page – this is both <strong>faster</strong> and <strong>smoother</strong> than sending a whole new message and deleting the previous one.</p>
|
||||
</blockquote>
|
||||
<h4><a class="anchor" href="#menu-button" id="menu-button" name="menu-button"><i class="anchor-icon"></i></a>Menu Button</h4>
|
||||
<p>In all bot chats, a menu button appears near the message field. By default, tapping this button <strong>opens a menu</strong> that can hold some or all of a bot's commands, including a short description for each. Users can then <strong>select a command from the menu</strong> without needing to type it out.</p>
|
||||
<p>You can set different texts of the menu button and its command descriptions for various <strong>individual users</strong> or <strong>groups of users</strong> – for example, showing translated text based on the user’s language, as explained <a href="#commands">here</a>.</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/464001581/11d85/f42u9c5Wncg.133752/b5a95b7f1221032d7d" style="max-width: 400px;" title="Bot Menu Button" alt="Video: Bot Menu Button">
|
||||
<source src="/file/464001555/10fbd/jvTuV2Ke7WQ.1916669.mp4/a056de323645db409d" type="video/mp4">
|
||||
</source></video>
|
||||
</div>
|
||||
<p>The <strong>menu button</strong> can alternatively be used to launch a <a href="#web-apps">Web App</a>.</p>
|
||||
<h4><a class="anchor" href="#global-commands" id="global-commands" name="global-commands"><i class="anchor-icon"></i></a>Global Commands</h4>
|
||||
<p>To make basic interactions more uniform, we ask all developers to support a few <strong>basic commands</strong>. Telegram apps will have interface shortcuts for these commands.</p>
|
||||
<ul>
|
||||
<li>/start - begins the interaction with the user, like sending an introductory message. This command can also be used to pass additional parameters to the bot (see <a href="#deep-linking">Deep Linking</a>).</li>
|
||||
<li>/help - returns a help message, like a short text about what your bot can do and a list of commands.</li>
|
||||
<li>/settings - (if applicable) shows the bot's settings for this user and suggests commands to edit them.</li>
|
||||
</ul>
|
||||
<p>Users will see a <strong>Start</strong> button the first time they open a chat with your bot. <strong>Help</strong> and <strong>Settings</strong> links will be available in the menu on the bot's profile page if you add them in <a href="https://t.me/botfather">@BotFather</a>.</p>
|
||||
<hr>
|
||||
<h3><a class="anchor" href="#interactions" id="interactions" name="interactions"><i class="anchor-icon"></i></a>Interactions</h3>
|
||||
<p>In addition to sending commands and messages to the chat with the bot, there are several ways of interacting with them without opening any specific chat or group.</p>
|
||||
<ul>
|
||||
<li><a href="#inline-requests"><strong>Inline mode</strong></a> allows sending requests to bots right from the input field – from any chat on Telegram.</li>
|
||||
<li><a href="#deep-linking"><strong>Deep linking</strong></a> allows special links that send certain parameters to the bot when opened.</li>
|
||||
<li><a href="#attachment-menu"><strong>Attachment menu</strong></a> integration makes it possible to use bots from the attachment menu in chats.</li>
|
||||
</ul>
|
||||
<h4><a class="anchor" href="#inline-requests" id="inline-requests" name="inline-requests"><i class="anchor-icon"></i></a>Inline Requests</h4>
|
||||
<p>Users can interact with your bot via <strong>inline queries</strong> straight from the message field <strong>in any chat</strong>. All they need to do is start a message with your bot's <em>@username</em> and enter a keyword.</p>
|
||||
<p>Having received the query, your bot can return some results. As soon as the user selects one, it is sent to the <strong>relevant chat</strong>. This way, people can request and send content from your bot in any of their chats, groups or channels.</p>
|
||||
<p>Remember that inline functionality has to be enabled via <a href="https://t.me/botfather">@BotFather</a>, or your bot will not receive inline <a href="/bots/api#update">Updates</a>.</p>
|
||||
<div>
|
||||
<a href="/file/464001466/10e4a/r4FKyQ7gw5g.134366/f2606a53d683374703" target="_blank"><img src="/file/464001466/10e4a/r4FKyQ7gw5g.134366/f2606a53d683374703" title="Inline Mode" class="dev_page_image" width="51%/"></a>
|
||||
</div>
|
||||
<blockquote>
|
||||
<p>Examples of inline bots include <a href="https://t.me/gif">@gif</a>, <a href="https://t.me/bing">@bing</a> and <a href="https://t.me/wiki">@wiki</a>.</p>
|
||||
</blockquote>
|
||||
<h4><a class="anchor" href="#deep-linking" id="deep-linking" name="deep-linking"><i class="anchor-icon"></i></a>Deep Linking</h4>
|
||||
<p>Telegram bots have a deep linking mechanism that allows <strong>additional parameters</strong> to be passed to the bot on startup. It could be a command that launches the bot – or an authentication token to connect the user's Telegram account to their account on another platform.</p>
|
||||
<p>Each bot has a link that <strong>opens a conversation</strong> with it in Telegram – <code>https://t.me/<bot_username></code>. Parameters can be added directly to this link to let your bot work with additional information on the fly, without any user input.</p>
|
||||
<blockquote>
|
||||
<p>A-Z, a-z, 0-9, _ and - are allowed. We recommend using base64url to encode parameters with binary and other types of content. The parameter can be up to 64 characters long.</p>
|
||||
</blockquote>
|
||||
<p><strong>Private Chats</strong>
|
||||
In private chats, you can use the <code>start</code> parameter to automatically pass any value to your bot whenever a user presses the link. For example, you could use:</p>
|
||||
<pre><code>https://t.me/your_bot?start=airplane</code></pre>
|
||||
<p>When someone opens a chat with your bot via this link, you will receive:</p>
|
||||
<pre><code>/start airplane</code></pre>
|
||||
<p><strong>Groups</strong>
|
||||
In groups, you can add the parameter <code>startgroup</code> to this link. For example:</p>
|
||||
<pre><code>https://t.me/your_bot?startgroup=spaceship</code></pre>
|
||||
<p>Following a link with this parameter prompts the user to select a group to add the bot to – the resulting update will contain text in the form:</p>
|
||||
<pre><code>/start@your_bot spaceship</code></pre>
|
||||
<blockquote>
|
||||
<p><a href="#web-apps">Web Apps</a> also support deep linking, for more information check out our <a href="/bots/webapps#adding-bots-to-the-attachment-menu">dedicated guide</a>.</p>
|
||||
</blockquote>
|
||||
<h4><a class="anchor" href="#attachment-menu" id="attachment-menu" name="attachment-menu"><i class="anchor-icon"></i></a>Attachment Menu</h4>
|
||||
<p>Certain bots can be added directly to a user’s <strong>attachment menu</strong> – giving them easy access to the bot in any chat. Currently, this option is restricted to certain <a href="/bots/webapps#launching-web-apps-from-the-attachment-menu">approved bots</a>, but may be expanded later.</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/464001491/11651/uwMWNdO29NE.215169/1b37285bbd8fc81244" style="max-width: 400px;" title="Attachment Menu" alt="Video: Bot Attachment Menu">
|
||||
<source src="/file/464001177/11b03/ruSbBLQiLJ8.928268.mp4/d9ad95048d23f3cc3f" type="video/mp4">
|
||||
</source></video>
|
||||
</div>
|
||||
<blockquote>
|
||||
<p>Try adding <a href="https://t.me/durgerkingbot?startattach">@DurgerKingBot</a> to your attachment menu.</p>
|
||||
</blockquote>
|
||||
<hr>
|
||||
<h3><a class="anchor" href="#integration" id="integration" name="integration"><i class="anchor-icon"></i></a>Integration</h3>
|
||||
<p>There are various ways of futher integrating bots with Telegram and other services.</p>
|
||||
<ul>
|
||||
<li>Use <a href="#web-apps">Web Apps</a> to replace any website.</li>
|
||||
<li>Accept <a href="#payments">Payments</a> via dozens of integrated third-party payment providers.</li>
|
||||
<li>Connect to Telegram using the <a href="#web-login">Web Login</a> functionality.</li>
|
||||
<li>Create gaming bots by integrating <a href="#html5-games">HTML5 Games</a>.</li>
|
||||
<li>Help users create and manage <a href="#stickers">Telegram Stickers</a>.</li>
|
||||
</ul>
|
||||
<h3><a class="anchor" href="#web-apps" id="web-apps" name="web-apps"><i class="anchor-icon"></i></a>Web Apps</h3>
|
||||
<p>Bots can easily process <strong>complex inputs</strong> of any kind and <strong>dynamic interaction flows</strong> via <a href="webapps">Web Apps</a>. With this unique feature, you can develop any number of flexible, streamlined interfaces in <strong>JavaScript</strong>.</p>
|
||||
<blockquote>
|
||||
<p>Web Apps are covered in detail in our <a href="webapps">dedicated guide</a> – you should read it carefully to learn the wide variety of features they can offer.</p>
|
||||
</blockquote>
|
||||
<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/464001434/100bf/eWprjdgzEbE.100386/644bbea83084f44c8f" style="max-width: 400px;" title="Attachment Menu" alt="Video: Bot Attachment Menu">
|
||||
<source src="/file/464001679/11aa9/KQx_BlPVXRo.4922145.mp4/c65433c8ac11a347a8" type="video/mp4">
|
||||
</source></video>
|
||||
</div>
|
||||
<p>If you develop a <strong>Web App</strong>, be sure to follow our <a href="webapps#design-guidelines">design guidelines</a> – you'll want your custom interface to <strong>seamlessly integrate</strong> into the app to provide users the best possible experience.</p>
|
||||
<h3><a class="anchor" href="#payments" id="payments" name="payments"><i class="anchor-icon"></i></a>Payments</h3>
|
||||
<p>Telegram bots can accept payments with a sleek, streamlined interface that collects all necessary data from the user. Telegram <strong>doesn't collect</strong> any payment data – like the user's credit card information – and sends it directly to one of the supported <a href="payments#supported-payment-providers">payment providers</a>.</p>
|
||||
<p>Here is a <strong>quick start guide</strong> to implement payments:</p>
|
||||
<ul>
|
||||
<li>Pick a <a href="payments#supported-payment-providers">provider</a> and obtain the <a href="payments#getting-a-token">proper token</a> as well as a <strong>test token</strong> from the "<strong>Stripe TEST MODE</strong>" provider.</li>
|
||||
<li>Implement payments via the <a href="/bots/api#payments">appropriate API methods</a>.</li>
|
||||
<li>Test your implementation by using your <strong>test token</strong> along with a <a href="https://stripe.com/docs/testing#cards">test credit card</a>.</li>
|
||||
</ul>
|
||||
<p>Then, to issue an <strong>invoice</strong> and process the order flow:</p>
|
||||
<ul>
|
||||
<li><a href="/bots/api#sendinvoice">Send an invoice</a> to the user for the goods or services you are offering.</li>
|
||||
<li>Validate the order and accept the checkout via <a href="/bots/api#answerprecheckoutquery">answerPreCheckoutQuery</a>.</li>
|
||||
<li>Confirm the payment by checking for a <a href="/bots/api#successfulpayment">successful payment service message</a>.</li>
|
||||
<li>Ship the goods or provide the services.</li>
|
||||
</ul>
|
||||
<p>A full and exhaustive guide, including live checklist, parameters and in-depth method descriptions is available <a href="/bots/payments">here</a>. We <strong>strongly recommend</strong> that you read the full guide before going live.</p>
|
||||
<div>
|
||||
<a href="/file/464001393/101fc/SB_bFCLR0tg.130549/7ecf91aaa44737e8cb" target="_blank"><img src="/file/464001393/101fc/SB_bFCLR0tg.130549/7ecf91aaa44737e8cb" title="Payments" class="dev_page_image" width="50%"></a>
|
||||
</div>
|
||||
<blockquote>
|
||||
<p>Telegram does not directly process the payments, does not store data about orders and does not collect any fees. Invoices are forwarded directly to the payment provider.
|
||||
For this reason, disputes must be solved between the user, the bot developer and the payment provider. You can read more about this in the <a href="https://telegram.org/privacy#7-third-party-payment-services">Privacy Policy</a>.</p>
|
||||
</blockquote>
|
||||
<h3><a class="anchor" href="#web-login" id="web-login" name="web-login"><i class="anchor-icon"></i></a>Web Login</h3>
|
||||
<p>Telegram offers a <strong>flexible</strong>, <strong>lightweight</strong> and <strong>free</strong> framework to authenticate users on any website and app. This can be used to bridge your platform with Telegram, providing a smooth experience to your users. You can also freely rely on this framework to implement a <strong>fast</strong> and <strong>signup-free</strong> login on your site, regardless of its connection to Telegram.</p>
|
||||
<h4><a class="anchor" href="#login-widget" id="login-widget" name="login-widget"><i class="anchor-icon"></i></a>Login widget</h4>
|
||||
<p>The Telegram login widget is a <strong>simple and secure way to authorize users</strong> on your website.</p>
|
||||
<ol>
|
||||
<li>Choose a bot – ideally its name and profile pic <strong>should match</strong> the website title and logo.</li>
|
||||
<li>Use the <code>/setdomain</code> command in <a href="https://t.me/botfather">@BotFather</a> to pair the bot with your website domain. </li>
|
||||
<li>Configure your widget using <a href="/widgets/login#widget-configuration">our dedicated tool</a> and embed it on your website.</li>
|
||||
</ol>
|
||||
<h4><a class="anchor" href="#inline-login" id="inline-login" name="inline-login"><i class="anchor-icon"></i></a>Inline Login</h4>
|
||||
<p>When users open your website via an <strong>inline button</strong>, you can use the <a href="/bots/api#loginurl">login_url</a> parameter as an alternative to login widgets. This way, you'll be able to <a href="https://telegram.org/blog/privacy-discussions-web-bots#meet-seamless-web-bots">seamlessly authorize</a> them on your website or app before the page even loads.</p>
|
||||
<div>
|
||||
<a href="/file/464001287/105ea/23bO4ntH4tc.43741/c9624e36c3462b6540" target="_blank"><img src="/file/464001287/105ea/23bO4ntH4tc.43741/c9624e36c3462b6540" width="50%" title="Login Widget" class="dev_page_image"></a>
|
||||
</div>
|
||||
<blockquote>
|
||||
<p>Make sure to review our <a href="/widgets/login#checking-authorization">guide</a> on authenticating the received data as well as our <a href="https://gist.github.com/anonymous/6516521b1fb3b464534fbc30ea3573c2">sample code</a>.</p>
|
||||
</blockquote>
|
||||
<h3><a class="anchor" href="#html5-games" id="html5-games" name="html5-games"><i class="anchor-icon"></i></a>HTML5 Games</h3>
|
||||
<p>Bots can serve as <strong>standalone gaming platforms</strong> – with our <a href="/bots/api#games">HTML5 Gaming API</a> you can develop multiplayer or single-player games and let your users have fun comparing <strong>ranks</strong>, <strong>scores</strong> and much more.</p>
|
||||
<p>To get started, follow these simple steps:</p>
|
||||
<ul>
|
||||
<li>Send the <code>/newgame</code> command to <a href="https://t.me/botfather">@BotFather</a></li>
|
||||
<li>Provide a <strong>description text</strong>, an <strong>image</strong> or an <strong>optional gif</strong> to showcase its gameplay</li>
|
||||
<li>Send the game to users via the <a href="/bots/api#sendgame">sendGame</a> method or via an <a href="/bots/api#inlinequeryresultgame">inline query</a></li>
|
||||
<li>When someone wants to play, you'll receive the appropriate <code>game_short_name</code> in a <a href="/bots/api#callbackquery">CallbackQuery</a></li>
|
||||
<li>To launch the game, provide the <strong>HTML5 Game URL</strong> as the <code>url</code> param of <a href="/bots/api#answercallbackquery">answerCallbackQuery</a></li>
|
||||
</ul>
|
||||
<p>Then, to handle <strong>highscores</strong>:</p>
|
||||
<ul>
|
||||
<li>Use <a href="/bots/api#setgamescore">setGameScore</a> to post high scores in the chat with the game</li>
|
||||
<li>Use <a href="/bots/api#getgamehighscores">getGameHighScores</a> to get in-game high score tables</li>
|
||||
</ul>
|
||||
<p>You can also <strong>embed a share button</strong> within your game, play around with <strong>custom inline buttons</strong>, <strong>URL parameters</strong> and much more. To get a better idea, make sure to check out:</p>
|
||||
<ul>
|
||||
<li><a href="/bots/games">HTML5 Games Manual</a></li>
|
||||
<li><a href="/bots/api#games">HTML5 Games Bot API Docs</a></li>
|
||||
</ul>
|
||||
<div>
|
||||
<a href="/file/464001558/11b92/y_Fu9QQWtj0.141959/dc9db48f66800bf271" target="_blank"><img src="/file/464001558/11b92/y_Fu9QQWtj0.141959/dc9db48f66800bf271" title="Games" width="50%" class="dev_page_image"></a>
|
||||
</div>
|
||||
<blockquote>
|
||||
<p>Check out <a href="https://t.me/gamebot">@GameBot</a> and <a href="https://t.me/gamee">@gamee</a> for examples of what you can do using our Gaming Platform.</p>
|
||||
</blockquote>
|
||||
<h3><a class="anchor" href="#stickers" id="stickers" name="stickers"><i class="anchor-icon"></i></a>Stickers</h3>
|
||||
<p><a href="/stickers">Stickers</a> are a distinctive Telegram feature used by millions of users to share artwork every day. Stickers take many forms – ranging from <strong>basic images</strong> to smooth <strong>vector animations</strong> and high-detail <strong>.WEBM videos</strong>.</p>
|
||||
<p>All these formats are supported by our <a href="/bots/api#stickers">Bot API</a>, which allows bots to <strong>create</strong>, <strong>edit</strong>, <strong>delete</strong> and <strong>share</strong> new sticker packs on the fly. Telegram's <a href="/import-stickers">Import API</a> lets users <strong>migrate packs</strong> from other platforms and sticker apps.</p>
|
||||
<p>To create a <strong>new sticker pack</strong>, follow these simple steps:</p>
|
||||
<ul>
|
||||
<li><strong>Upload</strong> a new sticker file via <a href="/bots/api#uploadstickerfile">uploadStickerFile</a>. Repeat for all the stickers in the set. You will use the returned <a href="/bots/api#file">files</a> in the next step, so keep them around.</li>
|
||||
<li><strong>Create</strong> a new sticker pack via <a href="/bots/api#createnewstickerset">createStickerSet</a>. Attach the first sticker as a <a href="/bots/api#file">file</a> you collected in <strong>step 1</strong> and remember to only specify <strong>one</strong> of the three avaiable fields – <code>png_sticker</code>, <code>tgs_sticker</code> and <code>webm_sticker</code> – depending on which sticker format you uploaded.</li>
|
||||
<li><strong>Complete</strong> the pack by adding each remaining sticker in sequence via <a href="/bots/api#addstickertoset">addStickerToSet</a>.</li>
|
||||
</ul>
|
||||
<blockquote>
|
||||
<p>Once you're done, don't forget to check out our <a href="/bots/api#stickers">remaining sticker methods</a> to find out how to <a href="/bots/api#setstickersetthumb">edit</a>, <a href="/bots/api#deletestickerfromset">delete</a> and even <a href="/bots/api#setstickerpositioninset">reorder</a> your pack.
|
||||
Note that these methods will only work on packs <strong>created by the bot that is calling them</strong>.</p>
|
||||
</blockquote>
|
||||
<h3><a class="anchor" href="#language-support" id="language-support" name="language-support"><i class="anchor-icon"></i></a>Language Support</h3>
|
||||
<p>Bots can tailor their interfaces to <strong>support multiple languages</strong> – updating inputs and information on the fly. A user’s <a href="/bots/api#user">language_code</a> is included in every relevant <a href="/bots/api#update">update</a> as an <a href="https://en.wikipedia.org/wiki/IETF_language_tag">IETF language tag</a>, allowing bots to adapt accordingly. </p>
|
||||
<p>We recommend that you follow our guidelines to provide <strong>the best user experience</strong>.</p>
|
||||
<ul>
|
||||
<li>Your interfaces, texts and <a href="/bots/api#answerinlinequery">inline results</a> should adapt seamlessly to the <em>language_code</em>, without user intervention.</li>
|
||||
<li>Connected <a href="/bots/webapps">WebApps</a> will receive the user's <em>language_code</em> – your HTML page should account for it.</li>
|
||||
<li><a href="/bots/games">HTML5 Games</a> can obtain language information if you specify it as a <a href="/bots/games#using-url-parameters">URL parameter</a>. You can generate this parameter from the <em>language_code</em> field in the <a href="/bots/api#user">User</a> object served with the initial game <a href="/bots/api#callbackquery">CallbackQuery</a>.</li>
|
||||
<li>Command lists can also be specified for individual languages – more on this <a href="#commands">here</a>.</li>
|
||||
</ul>
|
||||
<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/10cd0/EvtvjnhA-kA.132475/e285952b505535d85a" style="max-width: 400px;" title="Language Support" alt="Video: Language Support">
|
||||
<source src="/file/464001083/105cd/NF4ViAHfTJc.3601652.mp4/0fd787953c11a6371d" type="video/mp4">
|
||||
</source></video>
|
||||
</div>
|
||||
<blockquote>
|
||||
<p>The <em>language_code</em> is an <strong>optional field</strong> – it could be empty.
|
||||
If you target the general public, your code should always fall back to either the last recorded language tag or English (in this order) when the field is missing for a specific user. </p>
|
||||
</blockquote>
|
||||
<hr>
|
||||
<h3><a class="anchor" href="#bot-management" id="bot-management" name="bot-management"><i class="anchor-icon"></i></a>Bot Management</h3>
|
||||
<h4><a class="anchor" href="#privacy-mode" id="privacy-mode" name="privacy-mode"><i class="anchor-icon"></i></a>Privacy Mode</h4>
|
||||
<p>Bots are frequently added to groups to perform basic tasks or assist moderators – like automatically posting company announcements or even celebrating birthdays. By default, <strong>all bots</strong> added to groups run in Privacy Mode and only see relevant messages and commands:</p>
|
||||
<ul>
|
||||
<li>Commands explicitly meant for them (e.g., <code>/command@this_bot</code>).</li>
|
||||
<li>General commands (e.g. <code>/start</code>) if the bot was the last bot to send a message to the group.</li>
|
||||
<li>Inline messages sent <a href="/bots/api#inline-mode">via</a> the bot.</li>
|
||||
<li>Replies to any messages implicitly or explicitly meant for this bot.</li>
|
||||
</ul>
|
||||
<p>All bots will also receive, <strong>regardless of privacy mode</strong>:</p>
|
||||
<ul>
|
||||
<li>All service messages.</li>
|
||||
<li>All messages from private chats.</li>
|
||||
<li>All messages from channels where they are a member.</li>
|
||||
</ul>
|
||||
<p>Privacy mode is <strong>enabled by default</strong> for all bots, except bots that were added to a group as admins (bot admins always receive <strong>all messages</strong>). It can be disabled so that the bot receives all messages like an ordinary user (the bot will need to be re-added to the group for this change to take effect). We only recommend doing this in cases where it is <strong>absolutely necessary</strong> for your bot to work. In most cases, using the force reply option for the bot's messages should be more than enough.</p>
|
||||
<div>
|
||||
<a href="/file/464001338/107af/JdbERa0BATg.62371/28977e9a96aed3860a" target="_blank"><img src="/file/464001338/107af/JdbERa0BATg.62371/28977e9a96aed3860a" title="Privacy Mode" class="dev_page_image" width="50%/"></a>
|
||||
</div>
|
||||
<blockquote>
|
||||
<p>This mode not only increases user privacy, but also makes the bot more efficient by reducing the number of inputs it needs to process. Users can always see a bot’s current privacy setting in the list of group members.</p>
|
||||
</blockquote>
|
||||
<h4><a class="anchor" href="#status-alerts" id="status-alerts" name="status-alerts"><i class="anchor-icon"></i></a>Status alerts</h4>
|
||||
<p>Millions choose Telegram for its speed. To best benefit users, your bot also <strong>needs to be responsive</strong>. In order to help developers keep their bots in shape, <a href="https://t.me/botfather">@BotFather</a> will send <strong>status alerts</strong> if it sees something is wrong.</p>
|
||||
<p>We check the number of replies and the <em>request/response</em> conversion rate for popular bots (~300 requests per minute, this value may change in the future). If your bot returns an <strong>abnormally low number</strong>, you will receive a notification from <a href="https://t.me/botfather">@BotFather</a>.</p>
|
||||
<h5><a class="anchor" href="#responding-to-alerts" id="responding-to-alerts" name="responding-to-alerts"><i class="anchor-icon"></i></a>Responding to alerts</h5>
|
||||
<p>By default, <strong>you will only get one alert per bot per hour</strong>. </p>
|
||||
<p>Each alert has the following buttons:</p>
|
||||
<ul>
|
||||
<li><strong>Fixed</strong> - Use this if you found an issue with your bot and fixed it. If you press the fix button, we will resume sending alerts in the regular way so that you can see if your fix worked within 5-10 minutes instead of having to wait for an hour.</li>
|
||||
<li><strong>Support</strong> - Use this to open a chat with <a href="https://t.me/botsupport">@BotSupport</a> if you don't see any issues with your bot or if you think the problem is on our side.</li>
|
||||
<li><strong>Mute for 8h/1w</strong> - Use this if you can't fix your bot at the moment. This will disable all alerts for the bot in question for the specified period of time. <strong>We do not recommend</strong> using this option since your users may migrate to a more stable bot. You can unmute alerts in your bot's settings via <a href="https://t.me/botfather">@BotFather</a>.</li>
|
||||
</ul>
|
||||
<h5><a class="anchor" href="#monitored-issues" id="monitored-issues" name="monitored-issues"><i class="anchor-icon"></i></a>Monitored issues</h5>
|
||||
<p>We currently notify you about the following issues:</p>
|
||||
<ul>
|
||||
<li>
|
||||
<p><strong>Too few private messages are sent.</strong> Value: <strong>{value}</strong> - Your bot is sending far fewer messages than it did in previous weeks. This is useful for newsletter-style bots that send messages without prompts from users. The larger the value, the more significant the difference.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><strong>Too few replies to incoming private messages</strong>. Conversion rate: <strong>{value}</strong> - Your bot is not replying to all messages that are being sent to it (the request/response conversion rate for your bot was too low for at least two of the last three 5-minute periods). </p>
|
||||
</li>
|
||||
</ul>
|
||||
<blockquote>
|
||||
<p>To provide a good user experience, please respond to all messages that are sent to your bot. Respond to message updates by calling send… methods (e.g. <a href="/bots/api#sendmessage">sendMessage</a>).</p>
|
||||
</blockquote>
|
||||
<ul>
|
||||
<li>
|
||||
<p><strong>Too few answers to inline queries</strong>. Conversion rate: <strong>{value}</strong> - Your bot is not replying to all inline queries that are being sent to it, calculated in the same way as above. Respond to <code>inline_query</code> updates by calling <a href="/bots/api#answerinlinequery">answerInlineQuery</a>.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><strong>Too few answers to callback queries</strong>. Conversion rate: <strong>{value}</strong></p>
|
||||
</li>
|
||||
<li>
|
||||
<p><strong>Too few answers to callback game queries</strong>. Conversion rate: <strong>{value}</strong> - Your bot is not replying to all callback queries that are being sent to it (with or without games), calculated in the same way as above. Respond to <code>callback_query</code> updates by calling <a href="/bots/api#answercallbackquery">answerCallbackQuery</a>.</p>
|
||||
</li>
|
||||
</ul>
|
||||
<h4><a class="anchor" href="#local-bot-api" id="local-bot-api" name="local-bot-api"><i class="anchor-icon"></i></a>Local Bot API</h4>
|
||||
<p>You can host and work with <strong>your own instance</strong> of our open-source <a href="/bots/api">Bot API</a>.
|
||||
The <strong>source code</strong> is available <a href="https://github.com/tdlib/telegram-bot-api">here</a>, along with a quick <a href="https://github.com/tdlib/telegram-bot-api#installation">installation guide</a>.</p>
|
||||
<p>After <strong>installing the server</strong>, remember to use the <a href="/bots/api#logout">logOut</a> method before <strong>redirecting requests</strong> to your new local API URL.</p>
|
||||
<blockquote>
|
||||
<p>Your local instance runs on port <code>8081</code> by default and will only accept HTTP requests, so a TLS termination proxy has to be used to handle remote HTTPS requests.</p>
|
||||
</blockquote>
|
||||
<p>By hosting our API locally you'll gain access to <strong>some upgrades</strong>, including:</p>
|
||||
<table class="table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>API</th>
|
||||
<th>Max File Download</th>
|
||||
<th>Max File Upload</th>
|
||||
<th>WHook URL</th>
|
||||
<th>WHook Port</th>
|
||||
<th>WHook Max Connections</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td><a href="/bots/api#making-requests">Official</a></td>
|
||||
<td>20MB</td>
|
||||
<td>50MB</td>
|
||||
<td>HTTPS</td>
|
||||
<td>443,80,88,8443</td>
|
||||
<td>1-100</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><a href="/bots/api#using-a-local-bot-api-server">Local</a></td>
|
||||
<td>Unlimited</td>
|
||||
<td>2000MB</td>
|
||||
<td>HTTP</td>
|
||||
<td>Any port</td>
|
||||
<td>1-100000</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<blockquote>
|
||||
<p>You can find an exhaustive list <a href="/bots/api#using-a-local-bot-api-server">here</a>.
|
||||
All limits may be subject to change in the future, so make sure to follow <a href="https://t.me/botnews">@BotNews</a>.</p>
|
||||
</blockquote>
|
||||
<hr>
|
||||
<h3><a class="anchor" href="#botfather" id="botfather" name="botfather"><i class="anchor-icon"></i></a>BotFather</h3>
|
||||
<p>Below is a detailed guide to using <a href="https://t.me/botfather">@BotFather</a>, Telegram’s tool for <strong>creating</strong> and <strong>managing</strong> bots.</p>
|
||||
<h4><a class="anchor" href="#creating-a-new-bot" id="creating-a-new-bot" name="creating-a-new-bot"><i class="anchor-icon"></i></a>Creating a new bot</h4>
|
||||
<p>Use the <code>/newbot</code> command to create a new bot. <a href="https://t.me/botfather">@BotFather</a> will ask you for a name and username, then generate an authentication token for your new bot.</p>
|
||||
<ul>
|
||||
<li>
|
||||
<p>The <strong>name</strong> of your bot is displayed in contact details and elsewhere.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>The <strong>username</strong> is a short name, used in search, mentions and t.me links. Usernames are 5-32 characters long and not case sensitive – but may only include Latin characters, numbers, and underscores. Your bot's username must end in 'bot’, like 'tetris_bot' or 'TetrisBot'.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p>The <strong>token</strong> is a string, like <code>110201543:AAHdqTcvCH1vGWJxfSeofSAs0K5PALDsaw</code>, which is required to authorize the bot and send requests to the Bot API. Keep your token secure and store it safely, it can be used by anyone to control your bot. </p>
|
||||
</li>
|
||||
</ul>
|
||||
<blockquote>
|
||||
<p>Unlike the bot’s name, the username cannot be changed later – so choose it carefully.
|
||||
When sending a request to api.telegram.org, remember to prefix the word ‘bot’ to your token.</p>
|
||||
</blockquote>
|
||||
<h4><a class="anchor" href="#about-text-description-and-profile-media" id="about-text-description-and-profile-media" name="about-text-description-and-profile-media"><i class="anchor-icon"></i></a>About text, description and profile media</h4>
|
||||
<p>When new users open your bot, they will be met with a helpful description in a box titled "What can this bot do?".</p>
|
||||
<p>Properly <a href="#edit-bots">setting this field</a> in <a href="https://t.me/botfather">@BotFather</a> allows everyone to immediately get an idea of what your bot can do – your description should be <strong>brief</strong>, <strong>to the point</strong> and <strong>on topic</strong>.</p>
|
||||
<blockquote>
|
||||
<p>You can also add a photo or video to this field with <code>Edit Description Picture</code> in <a href="https://t.me/botfather">@BotFather</a>.</p>
|
||||
</blockquote>
|
||||
<p>Additionally, just like normal users, bots also come with a <strong>short bio</strong> available on their profile. If you didn't specify this field while first creating your bot, you can set it at any time with the <code>/setabouttext</code> command in <a href="https://t.me/botfather">@BotFather</a>. Users can interact with many bots and they won't have access to their description after starting them – having a quick reminder of the bot's purpose can be very useful.</p>
|
||||
<p>Bots can also have a <strong>profile picture</strong> – you should pick something unique and original so that users can find it in their chat list at a glance.</p>
|
||||
<blockquote>
|
||||
<p>Once set, the description, about text and profile pic can be <strong>replaced</strong> but never fully <strong>removed</strong>.</p>
|
||||
</blockquote>
|
||||
<h4><a class="anchor" href="#generating-an-authentication-token" id="generating-an-authentication-token" name="generating-an-authentication-token"><i class="anchor-icon"></i></a>Generating an authentication token</h4>
|
||||
<p>If your existing token is <strong>compromised</strong> or <strong>you lost it</strong> for some reason, use the <code>/token</code> command to generate a new one.</p>
|
||||
<h4><a class="anchor" href="#transfer-ownership" id="transfer-ownership" name="transfer-ownership"><i class="anchor-icon"></i></a>Transfer ownership</h4>
|
||||
<p>You can transfer ownership of your bot <strong>to another user</strong>.
|
||||
To do this, send <code>/mybots</code>, select your bot, then <em>transfer ownership</em>.
|
||||
You can only transfer a bot to users who have interacted with it at least once.</p>
|
||||
<blockquote>
|
||||
<p>Transferring ownership will give full control of the bot to another user – they will be able to access the bot’s messages and even delete it. The transfer is permanent, so please consider it carefully.</p>
|
||||
</blockquote>
|
||||
<h4><a class="anchor" href="#botfather-commands" id="botfather-commands" name="botfather-commands"><i class="anchor-icon"></i></a>BotFather commands</h4>
|
||||
<p>The remaining commands are pretty self-explanatory:</p>
|
||||
<ul>
|
||||
<li>/mybots – returns a list of your bots with handy controls to edit their settings.</li>
|
||||
<li>/mygames – does the same for your games.</li>
|
||||
</ul>
|
||||
<h4><a class="anchor" href="#edit-bots" id="edit-bots" name="edit-bots"><i class="anchor-icon"></i></a>Edit bots</h4>
|
||||
<p>To edit your bot, you have two options.</p>
|
||||
<p>You can use the available commands:</p>
|
||||
<ul>
|
||||
<li>/setname – change your bot's <strong>name</strong>.</li>
|
||||
<li>/setdescription – change the bot's <strong>description</strong> (short text up to 512 characters). Users will see this text at the beginning of the conversation with the bot, titled '<em>What can this bot do?</em>'.</li>
|
||||
<li>/setabouttext – change the bot's <strong>about info</strong>, a shorter text up to 120 characters. Users will see this text on the bot's profile page. When they share your bot with someone, this text is sent together with the link.</li>
|
||||
<li>/setuserpic – change the bot's <strong>profile picture</strong>. </li>
|
||||
<li>/setcommands – change the list of <strong>commands</strong> supported by your bot. Users will see these commands as suggestions when they type <code>/</code> in the chat with your bot. See <a href="#commands">commands</a> for more info.</li>
|
||||
<li>/setdomain – link a <strong>website domain</strong> to your bot. See the <a href="#login-widget">login widget</a> section.</li>
|
||||
<li>/deletebot – delete your bot and <strong>free its username</strong>. Cannot be undone.</li>
|
||||
</ul>
|
||||
<p>Or you can use the <code>/mybots</code> command, tap on your bot and use the modern inline interface to edit it.</p>
|
||||
<h4><a class="anchor" href="#edit-settings" id="edit-settings" name="edit-settings"><i class="anchor-icon"></i></a>Edit settings</h4>
|
||||
<ul>
|
||||
<li>/setinline – toggle <strong>inline mode</strong> for your bot.</li>
|
||||
<li>/setinlinegeo – request <strong>location data</strong> to provide location-based inline results.</li>
|
||||
<li>/setjoingroups – toggle whether your bot can be <strong>added to groups</strong> or not. All bots must be able to process direct messages, but if your bot was not designed to work in groups, you can disable this.</li>
|
||||
<li>/setinlinefeedback – toggle whether the API should <strong>send updates about the results</strong> chosen by users. See an in-depth explanation <a href="/bots/inline#collecting-feedback">here</a>.</li>
|
||||
<li>/setprivacy – set which messages your bot will receive when added to a group. See <a href="#privacy-mode">privacy-mode</a> for more info.</li>
|
||||
</ul>
|
||||
<h4><a class="anchor" href="#manage-games" id="manage-games" name="manage-games"><i class="anchor-icon"></i></a>Manage games</h4>
|
||||
<ul>
|
||||
<li>/newgame – create a new game.</li>
|
||||
<li>/listgames – see a list of your games.</li>
|
||||
<li>/editgame – edit a game.</li>
|
||||
<li>/deletegame – delete an existing game.</li>
|
||||
</ul>
|
||||
<blockquote>
|
||||
<p>Please note that it may take a few minutes for changes to take effect.</p>
|
||||
</blockquote>
|
||||
<hr>
|
||||
<p>With this information, you are ready to proceed to our <a href="/bots/api">Full API Reference for Developers</a>.</p>
|
||||
<ul>
|
||||
<li>If you have any questions, check out our <a href="/bots/faq">Bot FAQ</a>.</li>
|
||||
<li>If you're experiencing issues with our API, please contact <a href="https://t.me/botsupport">@BotSupport</a> on Telegram.</li>
|
||||
</ul></div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer_wrap">
|
||||
<div class="footer_columns_wrap footer_desktop">
|
||||
<div class="footer_column footer_column_telegram">
|
||||
<h5>Telegram</h5>
|
||||
<div class="footer_telegram_description"></div>
|
||||
Telegram is a cloud-based mobile and desktop messaging app with a focus on security and speed.
|
||||
</div>
|
||||
|
||||
<div class="footer_column">
|
||||
<h5><a href="//telegram.org/faq">About</a></h5>
|
||||
<ul>
|
||||
<li><a href="//telegram.org/faq">FAQ</a></li>
|
||||
<li><a href="//telegram.org/privacy">Privacy</a></li>
|
||||
<li><a href="//telegram.org/press">Press</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer_column">
|
||||
<h5><a href="//telegram.org/apps#mobile-apps">Mobile Apps</a></h5>
|
||||
<ul>
|
||||
<li><a href="//telegram.org/dl/ios">iPhone/iPad</a></li>
|
||||
<li><a href="//telegram.org/android">Android</a></li>
|
||||
<li><a href="//telegram.org/dl/web">Mobile Web</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer_column">
|
||||
<h5><a href="//telegram.org/apps#desktop-apps">Desktop Apps</a></h5>
|
||||
<ul>
|
||||
<li><a href="//desktop.telegram.org/">PC/Mac/Linux</a></li>
|
||||
<li><a href="//macos.telegram.org/">macOS</a></li>
|
||||
<li><a href="//telegram.org/dl/web">Web-browser</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer_column footer_column_platform">
|
||||
<h5><a href="//core.telegram.org/">Platform</a></h5>
|
||||
<ul>
|
||||
<li><a href="//core.telegram.org/api">API</a></li>
|
||||
<li><a href="//translations.telegram.org/">Translations</a></li>
|
||||
<li><a href="//instantview.telegram.org/">Instant View</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer_columns_wrap footer_mobile">
|
||||
<div class="footer_column">
|
||||
<h5><a href="//telegram.org/faq">About</a></h5>
|
||||
</div>
|
||||
<div class="footer_column">
|
||||
<h5><a href="//telegram.org/blog">Blog</a></h5>
|
||||
</div>
|
||||
<div class="footer_column">
|
||||
<h5><a href="//telegram.org/apps">Apps</a></h5>
|
||||
</div>
|
||||
<div class="footer_column">
|
||||
<h5><a href="//core.telegram.org/">Platform</a></h5>
|
||||
</div>
|
||||
<div class="footer_column">
|
||||
<h5><a href="https://twitter.com/telegram" target="_blank" data-track="Follow/Twitter" onclick="trackDlClick(this, event)">Twitter</a></h5>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="/js/main.js?46"></script>
|
||||
<script src="/js/jquery.min.js?1"></script>
|
||||
<script src="/js/bootstrap.min.js?1"></script>
|
||||
|
||||
<script>window.initDevPageNav&&initDevPageNav();
|
||||
backToTopInit("Go up");
|
||||
removePreloadInit();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
620
data/web/corefork.telegram.org/bots/tutorial.html
Normal file
620
data/web/corefork.telegram.org/bots/tutorial.html
Normal file
|
@ -0,0 +1,620 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>From BotFather to 'Hello World'</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta property="description" content="Building your first bot">
|
||||
<meta property="og:title" content="From BotFather to 'Hello World'">
|
||||
<meta property="og:image" content="">
|
||||
<meta property="og:description" content="Building your first bot">
|
||||
<link rel="icon" type="image/svg+xml" href="/img/website_icon.svg?4">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/img/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/img/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/img/favicon-16x16.png">
|
||||
<link rel="alternate icon" href="/img/favicon.ico" type="image/x-icon" />
|
||||
<link href="/css/bootstrap.min.css?3" rel="stylesheet">
|
||||
|
||||
<link href="/css/telegram.css?232" rel="stylesheet" media="screen">
|
||||
<style>
|
||||
</style>
|
||||
</head>
|
||||
<body class="preload">
|
||||
<div class="dev_page_wrap">
|
||||
<div class="dev_page_head navbar navbar-static-top navbar-tg">
|
||||
<div class="navbar-inner">
|
||||
<div class="container clearfix">
|
||||
<ul class="nav navbar-nav navbar-right hidden-xs"><li class="navbar-twitter"><a href="https://twitter.com/telegram" target="_blank" data-track="Follow/Twitter" onclick="trackDlClick(this, event)"><i class="icon icon-twitter"></i><span> Twitter</span></a></li></ul>
|
||||
<ul class="nav navbar-nav">
|
||||
<li><a href="//telegram.org/">Home</a></li>
|
||||
<li class="hidden-xs"><a href="//telegram.org/faq">FAQ</a></li>
|
||||
<li class="hidden-xs"><a href="//telegram.org/apps">Apps</a></li>
|
||||
<li class=""><a href="/api">API</a></li>
|
||||
<li class=""><a href="/mtproto">Protocol</a></li>
|
||||
<li class=""><a href="/schema">Schema</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container clearfix">
|
||||
<div class="dev_page">
|
||||
<div id="dev_page_content_wrap" class=" ">
|
||||
<div class="dev_page_bread_crumbs"><ul class="breadcrumb clearfix"><li><a href="/bots" >Telegram Bots</a></li><i class="icon icon-breadcrumb-divider"></i><li><a href="/bots/tutorial" >From BotFather to 'Hello World'</a></li></ul></div>
|
||||
<h1 id="dev_page_title">From BotFather to 'Hello World'</h1>
|
||||
|
||||
<div id="dev_page_content"><!-- scroll_nav -->
|
||||
|
||||
<p>This guide will walk you through everything you need to know to build your first <strong>Telegram Bot</strong>.
|
||||
If you already know your way around some of the basic steps, you can jump directly to the part you're missing. Equivalent examples are available in <a href="https://gitlab.com/Athamaxy/telegram-bot-tutorial/-/blob/main/TutorialBot.cs">C#</a>, <a href="https://gitlab.com/Athamaxy/telegram-bot-tutorial/-/blob/main/TutorialBot.py">Python</a>, <a href="https://gitlab.com/Athamaxy/telegram-bot-tutorial/-/blob/main/TutorialBot.go">Go</a> and <a href="https://gitlab.com/Athamaxy/telegram-bot-tutorial/-/tree/main/Nodejs">TypeScript</a> .</p>
|
||||
<ul>
|
||||
<li><a href="#introduction">Introduction</a></li>
|
||||
<li><a href="#getting-ready"><strong>Basic Tutorial</strong></a></li>
|
||||
</ul>
|
||||
<div id="dev_page_content">
|
||||
<ul style="padding-left: 30px;">
|
||||
<li style="margin-top: -5px"><a href="#getting-ready">Environment</a></li>
|
||||
<li><a href="#first-run">First Run</a></li>
|
||||
<li><a href="#echo-bot">Echo Bot</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<ul>
|
||||
<li><a href="#executing-commands"><strong>Advanced Tutorial</strong></a></li>
|
||||
</ul>
|
||||
<div id="dev_page_content">
|
||||
<ul style="padding-left: 30px;">
|
||||
<li style="margin-top: -5px"><a href="#executing-commands">Commands</a></li>
|
||||
<li><a href="#navigation">Navigation</a></li>
|
||||
<li><a href="#database">Database</a></li>
|
||||
<li><a href="#hosting">Hosting</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<ul>
|
||||
<li><a href="#further-reading">Further Reading</a></li>
|
||||
</ul>
|
||||
<hr>
|
||||
<h3><a class="anchor" href="#introduction" id="introduction" name="introduction"><i class="anchor-icon"></i></a>Introduction</h3>
|
||||
<p>At its core, you can think of the Telegram <a href="api">Bot API</a> as software that provides <a href="https://en.wikipedia.org/wiki/JSON">JSON-encoded</a> responses to your queries.</p>
|
||||
<p>A bot, on the other hand, is essentially a routine, software or script that queries the API by means of an <a href="https://core.telegram.org/bots/api#making-requests">HTTPS request</a> and waits for a response. There are several types of <a href="api#available-methods">requests</a> you can make, as well as many different <a href="api#available-types">objects</a> that you can use and receive as responses.</p>
|
||||
<p>Since <strong>your browser</strong> is capable of sending HTTPS requests, you can use it to quickly try out the API. After <a href="#obtain-your-bot-token">obtaining your token</a>, try pasting this string into your browser:</p>
|
||||
<pre><code>https://api.telegram.org/bot<YOUR_BOT_TOKEN>/getMe</code></pre>
|
||||
<p>In theory, you could interact with the API with <strong>basic requests</strong> like this, either via your browser or other tailor-made tools like <a href="https://curl.se/">cURL</a>. While this can work for simple requests like the example above, it's not practical for larger applications and doesn't scale well.
|
||||
For that reason, this guide will show you how to use <a href="samples">libraries and frameworks</a>, along with some <strong>basic programming skills</strong>, to build a more robust and scalable project.</p>
|
||||
<p>If you know how to code, you'll fly right through each step in no time – and if you're just starting out, this guide will show you everything you need to learn.</p>
|
||||
<blockquote>
|
||||
<p>We will use <a href="https://en.wikipedia.org/wiki/Java_%28programming_language%29">Java</a> throughout this guide as it's one of the most popular programming languages, however, you can follow along with any language as all the steps are fundamentally the same.
|
||||
Since Java is fully cross-platform, each code example will work with any operating system.
|
||||
If you pick another language, equivalent examples are available in <a href="https://gitlab.com/Athamaxy/telegram-bot-tutorial/-/blob/main/TutorialBot.cs">C#</a>, <a href="https://gitlab.com/Athamaxy/telegram-bot-tutorial/-/blob/main/TutorialBot.py">Python</a>, <a href="https://gitlab.com/Athamaxy/telegram-bot-tutorial/-/blob/main/TutorialBot.go">Go</a> and <a href="https://gitlab.com/Athamaxy/telegram-bot-tutorial/-/tree/main/Nodejs">TypeScript</a> .</p>
|
||||
</blockquote>
|
||||
<h3><a class="anchor" href="#getting-ready" id="getting-ready" name="getting-ready"><i class="anchor-icon"></i></a>Getting Ready</h3>
|
||||
<p>First, we will briefly cover how to <strong>create your first project</strong>, obtain your <strong>API token</strong> and download all necessary <strong>dependencies and libraries</strong>.</p>
|
||||
<p>For the purposes of this guide, a copy of the bot you will be creating is also live at <a href="https://t.me/tutorialbot">@TutorialBot</a> – feel free to check it out along the way to see how your own implementation should look after each step.</p>
|
||||
<h4><a class="anchor" href="#obtain-your-bot-token" id="obtain-your-bot-token" name="obtain-your-bot-token"><i class="anchor-icon"></i></a>Obtain Your Bot Token</h4>
|
||||
<p>In this context, a <strong>token</strong> is a string that authenticates your bot (not your account) on the bot API. Each bot has a unique token which can also be revoked at any time via <a href="https://t.me/botfather">@BotFather</a>.</p>
|
||||
<p>Obtaining a token is as simple as contacting <a href="https://t.me/botfather">@BotFather</a>, issuing the <code>/newbot</code> command and following the steps until you're given a new token. You can find a step-by-step guide <a href="features#creating-a-new-bot">here</a>.</p>
|
||||
<p>Your token will look something like this:</p>
|
||||
<pre><code>4839574812:AAFD39kkdpWt3ywyRZergyOLMaJhac60qc</code></pre>
|
||||
<blockquote>
|
||||
<p>Make sure to save your token in a secure place, treat it like a password and <strong>don't share it with anyone</strong>.</p>
|
||||
</blockquote>
|
||||
<h4><a class="anchor" href="#download-an-ide" id="download-an-ide" name="download-an-ide"><i class="anchor-icon"></i></a>Download an IDE</h4>
|
||||
<p>To program in Java you'll need an <a href="https://en.wikipedia.org/wiki/Integrated_development_environment">IDE</a> – a special text editor that will let you write, compile and run your code.
|
||||
In this tutorial, we'll use IntelliJ – there are several free, open source alternatives like <a href="https://www.eclipse.org/ide/">Eclipse</a> or <a href="https://netbeans.apache.org/download/index.html">NetBeans</a> which work in the exact same way.</p>
|
||||
<p>You will also need a <a href="https://en.wikipedia.org/wiki/Java_Development_Kit">JDK</a>, a software kit that allows your Java code to run.
|
||||
Most IDEs don't include a JDK, so you should download a version compatible with your operating system separately. You can find a free, open source version <a href="https://adoptium.net/temurin/releases/">here</a>.</p>
|
||||
<blockquote>
|
||||
<p>If you use another language, the steps are identical. You will just have to download a different IDE and software development kit.</p>
|
||||
</blockquote>
|
||||
<h4><a class="anchor" href="#pick-a-framework-or-library" id="pick-a-framework-or-library" name="pick-a-framework-or-library"><i class="anchor-icon"></i></a>Pick a Framework or Library</h4>
|
||||
<p>You can think of a framework as software that handles all the low-level logic for you, including the API calls, and lets you focus on your bot-specific logic.</p>
|
||||
<p>In this tutorial, we'll use <a href="https://github.com/rubenlagus/TelegramBots">TelegramBots</a>, but you can follow along with any equivalent implementation, since all the underlying methods are either similar or exactly the same.</p>
|
||||
<blockquote>
|
||||
<p>You can find many frameworks, along with code examples, in <a href="samples">our dedicated list</a>.</p>
|
||||
</blockquote>
|
||||
<h4><a class="anchor" href="#create-your-project" id="create-your-project" name="create-your-project"><i class="anchor-icon"></i></a>Create Your Project</h4>
|
||||
<p>In IntelliJ, go to <code>File > New > Project</code>.</p>
|
||||
<p>Fill in the fields accordingly:</p>
|
||||
<ul>
|
||||
<li><strong>Name</strong> - The name of your project. For example, <em>BotTutorial</em>.</li>
|
||||
<li><strong>Location</strong> - Where to store your project. You can use the default value.</li>
|
||||
<li><strong>Language</strong> - Java</li>
|
||||
<li><strong>Build System</strong> - The framework that will handle your dependencies. Pick <em>Maven</em>.</li>
|
||||
<li><strong>JDK</strong> - Pick whichever version you downloaded. We'll be using version <em>17</em>.</li>
|
||||
<li><strong>Add Sample Code</strong> - Leave this <strong>selected</strong>, it will generate some needed files for you.</li>
|
||||
<li><strong>Advanced Settings > GroupId</strong> - We suggest <em>tutorial</em>.</li>
|
||||
<li><strong>Advanced Settings > ArtifactId</strong> - You can use the default value.</li>
|
||||
</ul>
|
||||
<p>After hitting <em>Create</em>, if you did everything correctly, your <strong>Project</strong> view in the top left should show a <strong>project structure</strong> along these lines:</p>
|
||||
<pre><code>BotTutorial
|
||||
├─ .idea
|
||||
├─ src
|
||||
│ └─ main
|
||||
│ └─ java
|
||||
│ └─ tutorial
|
||||
│ └─ Main
|
||||
└─ pom.xml</code></pre>
|
||||
<blockquote>
|
||||
<p>Other IDEs will follow a similar pattern. Your dependency management system will have a different name (or no name at all if it's built-in) depending on the language you chose.</p>
|
||||
</blockquote>
|
||||
<p>If this looks scary, don't worry. We will only be using the <code>Main</code> file and the <code>pom.xml</code> file.
|
||||
In fact, to check that everything is working so far, double click on <em>Main</em> and click on the small green arrow on the left of <em>public class Main</em>, then select the first option.
|
||||
If you followed the steps correctly, <em>Hello world!</em> should appear in the console below.</p>
|
||||
<h4><a class="anchor" href="#add-framework-dependency" id="add-framework-dependency" name="add-framework-dependency"><i class="anchor-icon"></i></a>Add Framework Dependency</h4>
|
||||
<p>We will now instruct the IDE to download and configure everything needed to work with the API.
|
||||
This is very easy and happens automatically behind the scenes.</p>
|
||||
<p>First, locate your <code>pom.xml</code> file on the left side of the screen.
|
||||
Open it by double-clicking and simply add:</p>
|
||||
<pre><code><dependencies>
|
||||
<dependency>
|
||||
<groupId>org.telegram</groupId>
|
||||
<artifactId>telegrambots</artifactId>
|
||||
<version>6.0.1</version>
|
||||
</dependency>
|
||||
</dependencies></code></pre>
|
||||
<p>right after the <code></properties></code> tag.</p>
|
||||
<p>When you're done, your <code>pom.xml</code> should look something like <a href="https://gitlab.com/Athamaxy/telegram-bot-tutorial/-/blob/main/pom.xml">this</a>.</p>
|
||||
<h3><a class="anchor" href="#start-coding" id="start-coding" name="start-coding"><i class="anchor-icon"></i></a>Start Coding</h3>
|
||||
<p>We are ready to start coding. If you're a beginner, consider that being familiar with your language of choice will greatly help. With this tutorial, you'll be able to teach your bot basic behaviors, though more advanced features will require some coding experience.</p>
|
||||
<h4><a class="anchor" href="#creating-a-bot-class" id="creating-a-bot-class" name="creating-a-bot-class"><i class="anchor-icon"></i></a>Creating a Bot Class</h4>
|
||||
<p>If you're familiar with <a href="https://en.wikipedia.org/wiki/Object-oriented_programming">object-oriented programming</a>, you'll know what a class is.
|
||||
If you've never heard of it before, consider a class as a file where you write some logic.</p>
|
||||
<p>To <strong>create the class</strong> that will contain the bot logic, right click on <em>tutorial</em> from the project tree on the left and select <em>New > Java Class</em>. Name it <em>Bot</em> and hit enter.</p>
|
||||
<p>Now we have to connect this class to the bot framework. In other words, we must make sure it extends <code>TelegramLongPollingBot</code>. To do that, just add <em>extends TelegramLongPollingBot</em> right after <em>Bot</em>.
|
||||
A red line will appear – it simply means we're missing some important methods.</p>
|
||||
<p>To fix this, hover over the red line, click on <em>implement methods</em>, then hit OK.
|
||||
Depending on the IDE, this option may be called <em>implement missing methods</em> or something similar.</p>
|
||||
<p>You should end up with this – if something went wrong, feel free to copy it from here and paste it in your class:</p>
|
||||
<pre><code>package tutorial;
|
||||
import org.telegram.telegrambots.bots.TelegramLongPollingBot;
|
||||
import org.telegram.telegrambots.meta.api.objects.Update;
|
||||
|
||||
public class Bot extends TelegramLongPollingBot {
|
||||
|
||||
@Override
|
||||
public String getBotUsername() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBotToken() {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdateReceived(Update update) {}
|
||||
|
||||
}</code></pre>
|
||||
<blockquote>
|
||||
<p>If you get a red line under TelegramLongPollingBot, it means you didn't set up your pom.xml correctly. If this is the case, restart from <a href="#add-framework-dependency">here</a>.</p>
|
||||
</blockquote>
|
||||
<h4><a class="anchor" href="#available-methods" id="available-methods" name="available-methods"><i class="anchor-icon"></i></a>Available Methods</h4>
|
||||
<p>Let's look into these 3 methods one by one.</p>
|
||||
<ul>
|
||||
<li><strong>getBotUsername</strong> - This method must be edited to always return your bot's username. You should replace the <em>null</em> return value with it.</li>
|
||||
<li><strong>getBotToken</strong> - This method will be used by the framework to retrieve your bot token. You should replace the <em>null</em> return value with the token.</li>
|
||||
<li><strong>onUpdateReceived</strong> - This is the most important method. It will be called automatically whenever a new Update is available. Let's add a <code>System.out.println(update);</code> call in there to quickly show what we are getting.</li>
|
||||
</ul>
|
||||
<p>After you've replaced all the strings, you should end up with this:</p>
|
||||
<pre><code>@Override
|
||||
public String getBotUsername() {
|
||||
return "TutorialBot";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getBotToken() {
|
||||
return "4839574812:AAFD39kkdpWt3ywyRZergyOLMaJhac60qc";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onUpdateReceived(Update update) {
|
||||
System.out.println(update);
|
||||
}</code></pre>
|
||||
<p>At this point, the bot is configured and ready to go – time to register it on the API and start processing updates.</p>
|
||||
<blockquote>
|
||||
<p>In the future, you should consider storing your token in a dedicated settings file or in <a href="https://en.wikipedia.org/wiki/Environment_variable">environment variables</a>. Keeping it in the code is fine for the scope of this tutorial, however, it's not very versatile and is generally considered bad practice. </p>
|
||||
</blockquote>
|
||||
<h4><a class="anchor" href="#registering-the-bot" id="registering-the-bot" name="registering-the-bot"><i class="anchor-icon"></i></a>Registering the Bot</h4>
|
||||
<p>To <strong>register the bot</strong> on the API, simply add a couple of lines <strong>in the main method</strong> that will launch the application. If you named your class <code>Bot</code>, this is what your main method should look like:</p>
|
||||
<pre><code>public static void main(String[] args) throws TelegramApiException {
|
||||
TelegramBotsApi botsApi = new TelegramBotsApi(DefaultBotSession.class);
|
||||
botsApi.registerBot(new Bot());
|
||||
}</code></pre>
|
||||
<blockquote>
|
||||
<p>You can place this method in any class. Since we have an auto-generated <code>main</code> method in the Main class, we'll be using that one for this tutorial.</p>
|
||||
</blockquote>
|
||||
<h3><a class="anchor" href="#first-run" id="first-run" name="first-run"><i class="anchor-icon"></i></a>First Run</h3>
|
||||
<p>It's time to <strong>run your bot</strong> for the first time.
|
||||
Hit the green arrow to the left of <code>public static void main</code> and select the first option.</p>
|
||||
<p><em>And then there was nothing</em>. Yes, a bit anticlimactic.
|
||||
This is because your bot <strong>has nothing to print</strong> – there are <strong>no new updates</strong> because nobody messaged it yet.</p>
|
||||
<p>If you try messaging the bot on Telegram, you'll then see <strong>new updates</strong> pop up in the console. At this point, you have your very own Telegram Bot – quite the achievement. Now, on to making it a bit more intelligent.</p>
|
||||
<blockquote>
|
||||
<p>If nothing pops up, make sure you messaged the right bot and that the token you pasted in the code is correct.</p>
|
||||
</blockquote>
|
||||
<h3><a class="anchor" href="#receiving-messages" id="receiving-messages" name="receiving-messages"><i class="anchor-icon"></i></a>Receiving Messages</h3>
|
||||
<p>Every time someone sends a <strong>private message</strong> to your bot, your <code>onUpdateReceived</code> method will be called automatically and you'll be able to handle the <code>update</code> parameter, which contains the <strong>message</strong>, along with a great deal of other info which you can see detailed <a href="api#update">here</a>.</p>
|
||||
<p>Let's focus on two values for now:</p>
|
||||
<ul>
|
||||
<li><strong>The user</strong> - Who sent the message. Access it via <code>update.getMessage().getFrom()</code>.</li>
|
||||
<li><strong>The message</strong> - What was sent. Access it via <code>update.getMessage()</code>.</li>
|
||||
</ul>
|
||||
<p>Knowing this, we can make it a bit more clear in the <strong>console output</strong>.</p>
|
||||
<pre><code>@Override
|
||||
public void onUpdateReceived(Update update) {
|
||||
var <a href='/constructor/msg'>msg</a> = <a href='/constructor/update.getMessage%28%29'>update.getMessage()</a>;
|
||||
var <a href='/constructor/user'>user</a> = <a href='/constructor/msg.getFrom%28%29'>msg.getFrom()</a>;
|
||||
|
||||
System.out.println(user.getFirstName() + " wrote " + msg.getText());
|
||||
}</code></pre>
|
||||
<p>This is just a basic example – you can now play around with all the methods to see everything you can pull out of these objects. You can try <code>getUsername</code>, <code>getLanguageCode</code>, and dozens more.</p>
|
||||
<p>Knowing how to receive, process and print <strong>incoming messages</strong>, now it's time to learn how to <strong>answer them</strong>.</p>
|
||||
<blockquote>
|
||||
<p>Remember to stop and re-launch your bot after each change to the code.</p>
|
||||
</blockquote>
|
||||
<h3><a class="anchor" href="#sending-messages" id="sending-messages" name="sending-messages"><i class="anchor-icon"></i></a>Sending Messages</h3>
|
||||
<p>To send a private text message, you generally need <strong>three things</strong>:</p>
|
||||
<ul>
|
||||
<li>The user <strong>must</strong> have contacted your bot first. (Unless the user sent a join request to a group where your bot is an admin, but that's a more advanced scenario).</li>
|
||||
<li>You <strong>must</strong> have previously saved the <strong>User ID</strong> (<code>user.getId()</code>)</li>
|
||||
<li>A <code>String</code> object containing the message text, 1-4096 characters.</li>
|
||||
</ul>
|
||||
<p>With that out of the way, let's create a <strong>new method</strong> to send the first message:</p>
|
||||
<pre><code>public void sendText(Long who, String what){
|
||||
SendMessage sm = SendMessage.builder()
|
||||
.chatId(who.toString()) //Who are we sending a message to
|
||||
.text(what).build(); //Message content
|
||||
try {
|
||||
execute(sm); //Actually sending the message
|
||||
} catch (TelegramApiException e) {
|
||||
throw new RuntimeException(e); //Any error will be printed here
|
||||
}
|
||||
}</code></pre>
|
||||
<p>And proceed to run this in the <code>main</code> method, right after registering the bot.
|
||||
For this example, we'll assume your User ID is <code>1234</code>.</p>
|
||||
<pre><code>public static void main(String[] args) throws TelegramApiException {
|
||||
TelegramBotsApi botsApi = new TelegramBotsApi(DefaultBotSession.class);
|
||||
Bot bot = new Bot(); //We moved this line out of the register method, to access it later
|
||||
botsApi.registerBot(bot);
|
||||
bot.sendText(1234L, "Hello World!"); //The L just turns the Integer into a Long
|
||||
}</code></pre>
|
||||
<p>If you did everything correctly, your bot should text you <em>Hello World!</em> every time you launch your code. Sending messages to groups or channels – assuming you have the relevant permissions – is as simple as replacing <code>1234</code> with the ID of the respective chat.</p>
|
||||
<blockquote>
|
||||
<p>Try experimenting with other types of messages, like SendPhoto, SendSticker, SendDice...
|
||||
A full list is available starting <a href="https://core.telegram.org/bots/api#sendmessage">here</a>.</p>
|
||||
</blockquote>
|
||||
<h3><a class="anchor" href="#echo-bot" id="echo-bot" name="echo-bot"><i class="anchor-icon"></i></a>Echo Bot</h3>
|
||||
<p>Let's practice everything we tried so far by coding an <strong>Echo Bot</strong>.
|
||||
Its functionality will be rather simple: every text message it receives will be sent right back to the user.</p>
|
||||
<h4><a class="anchor" href="#copying-text" id="copying-text" name="copying-text"><i class="anchor-icon"></i></a>Copying Text</h4>
|
||||
<p>The most intuitive way of coding this is saving the User ID and calling <code>sendText</code> right after each update.</p>
|
||||
<p>In other words:</p>
|
||||
<pre><code>@Override
|
||||
public void onUpdateReceived(Update update) {
|
||||
var <a href='/constructor/msg'>msg</a> = <a href='/constructor/update.getMessage%28%29'>update.getMessage()</a>;
|
||||
var <a href='/constructor/user'>user</a> = <a href='/constructor/msg.getFrom%28%29'>msg.getFrom()</a>;
|
||||
var <a href='/constructor/id'>id</a> = <a href='/constructor/user.getId%28%29'>user.getId()</a>;
|
||||
|
||||
sendText(id, msg.getText());
|
||||
}</code></pre>
|
||||
<p>This works for text but can be extended to stickers, media and files.</p>
|
||||
<h4><a class="anchor" href="#copying-everything" id="copying-everything" name="copying-everything"><i class="anchor-icon"></i></a>Copying Everything</h4>
|
||||
<p>There are more specific functions that can be used to copy messages and send them back.
|
||||
Let's build a method to do just that:</p>
|
||||
<pre><code>public void copyMessage(Long who, Integer msgId){
|
||||
CopyMessage cm = CopyMessage.builder()
|
||||
.fromChatId(who.toString()) //We copy from the user
|
||||
.chatId(who.toString()) //And send it back to him
|
||||
.messageId(msgId) //Specifying what message
|
||||
.build();
|
||||
try {
|
||||
execute(cm);
|
||||
} catch (TelegramApiException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}</code></pre>
|
||||
<p>After replacing the method call in<code>onUpdateReceived</code>, running the code will result in a fully functional <strong>Echo Bot</strong>.</p>
|
||||
<blockquote>
|
||||
<p>This tutorial assumes that updates always contain messages for the sake of simplicity. This may not always be true – be sure to implement all the proper checks in your code to handle every type of update with the appropriate methods.</p>
|
||||
</blockquote>
|
||||
<h3><a class="anchor" href="#executing-commands" id="executing-commands" name="executing-commands"><i class="anchor-icon"></i></a>Executing Commands</h3>
|
||||
<p>To learn what a command is and how it works, we recommend reading this <a href="features#commands">dedicated summary</a>.
|
||||
In this guide, we'll focus on the technical side of things.</p>
|
||||
<h4><a class="anchor" href="#creating-your-command" id="creating-your-command" name="creating-your-command"><i class="anchor-icon"></i></a>Creating Your Command</h4>
|
||||
<p>Begin by opening <a href="https://t.me/botfather">@BotFather</a>.
|
||||
Type <code>/mybots</code> > <em>Your_Bot_Name</em> > Edit Bot > Edit Commands.</p>
|
||||
<p>Now send a new command, followed by a brief description.
|
||||
For the purpose of this tutorial, we'll implement two simple commands:</p>
|
||||
<pre><code>scream - Speak, I'll scream right back
|
||||
whisper - Shhhhhhh</code></pre>
|
||||
<h4><a class="anchor" href="#command-logic" id="command-logic" name="command-logic"><i class="anchor-icon"></i></a>Command Logic</h4>
|
||||
<p>We want the <strong>Echo Bot</strong> to reply in uppercase when it's in <strong>scream mode</strong> and normally otherwise.</p>
|
||||
<p>First, let's <strong>create a variable</strong> to store the current mode.</p>
|
||||
<pre><code>public class Bot extends TelegramLongPollingBot {
|
||||
|
||||
private boolean <a href='/constructor/screaming'>screaming</a> = <a href='/constructor/false'>false</a>;
|
||||
|
||||
[...]
|
||||
}</code></pre>
|
||||
<p>Then, let's change some logic to <strong>account for this mode</strong>.</p>
|
||||
<pre><code>public void onUpdateReceived(Update update) {
|
||||
[...] //Same variables as the previous versions
|
||||
if(screaming) //If we are screaming
|
||||
scream(id, update.getMessage()); //Call a custom method
|
||||
else
|
||||
copyMessage(id, msg.getMessageId()); //Else proceed normally
|
||||
}
|
||||
|
||||
private void scream(Long id, Message msg) {
|
||||
if(msg.hasText())
|
||||
sendText(id, msg.getText().toUpperCase());
|
||||
else
|
||||
copyMessage(id, msg.getMessageId()); //We can't really scream a sticker
|
||||
}</code></pre>
|
||||
<p>Finally, let's add a couple more lines to the <code>onUpdateReceived</code> method to process each command before replying.</p>
|
||||
<pre><code>if(msg.isCommand()){
|
||||
if(msg.getText().equals("/scream")) //If the command was /scream, we switch gears
|
||||
<a href='/constructor/screaming'>screaming</a> = <a href='/constructor/true'>true</a>;
|
||||
else if (msg.getText().equals("/whisper")) //Otherwise, we return to normal
|
||||
<a href='/constructor/screaming'>screaming</a> = <a href='/constructor/false'>false</a>;
|
||||
|
||||
return; //We don't want to echo commands, so we exit
|
||||
}</code></pre>
|
||||
<p>As you can see, it checks if the message <strong>is a command</strong>. If it is, the bot enters <strong>scream mode</strong>.
|
||||
In the update method, we check <strong>which mode we are in</strong> and either copy the message or convert it to upper case before <strong>sending it back</strong>.</p>
|
||||
<p>And that's it. Now the bot can <strong>execute commands</strong> and change its behavior accordingly.</p>
|
||||
<p>Naturally, this simplified logic will change the bot's behavior for <strong>everyone</strong> – not just the person who sent the command. This can be fun for this tutorial but <strong>won't work in a production environment</strong> – consider using a Map, dictionary or equivalent data structure to assign settings for individual users.</p>
|
||||
<blockquote>
|
||||
<p>Remember to always implement a few basic <a href="features#global-commands">global commands</a>.
|
||||
You can practice by implementing a simple feedback to the <code>/start</code> command, which we intentionally left out.</p>
|
||||
</blockquote>
|
||||
<h3><a class="anchor" href="#buttons-and-keyboards" id="buttons-and-keyboards" name="buttons-and-keyboards"><i class="anchor-icon"></i></a>Buttons and Keyboards</h3>
|
||||
<p>To streamline and simplify user interaction with your bot, you can replace many text-based exchanges with handy buttons. These buttons can perform a wide variety of actions and can be customized for each user.</p>
|
||||
<h4><a class="anchor" href="#button-types" id="button-types" name="button-types"><i class="anchor-icon"></i></a>Button Types</h4>
|
||||
<p>There are two main types of buttons:</p>
|
||||
<ul>
|
||||
<li><strong>Reply Buttons</strong> - used to provide a list of predefined text <a href="features#keyboards">reply options</a>.</li>
|
||||
<li><strong>Inline Buttons</strong> - used to offer quick navigation, shortcuts, URLs, games and <a href="features##inline-keyboards">so much more</a>.</li>
|
||||
</ul>
|
||||
<p>Using these buttons is as easy as attaching a <code>ReplyKeyboardMarkup</code> or an <code>InlineKeyboardMarkup</code> to your <code>SendMessage</code> object.</p>
|
||||
<p>This guide will focus on <strong>inline buttons</strong> since they only require a few extra lines of code.</p>
|
||||
<h4><a class="anchor" href="#creating-buttons" id="creating-buttons" name="creating-buttons"><i class="anchor-icon"></i></a>Creating Buttons</h4>
|
||||
<p>First of all, let's create some buttons.</p>
|
||||
<pre><code> var next = InlineKeyboardButton.builder()
|
||||
.text("Next").callbackData("next")
|
||||
.build();
|
||||
|
||||
var back = InlineKeyboardButton.builder()
|
||||
.text("Back").callbackData("back")
|
||||
.build();
|
||||
|
||||
var url = InlineKeyboardButton.builder()
|
||||
.text("Tutorial")
|
||||
.url("https://core.telegram.org/bots/api")
|
||||
.build();</code></pre>
|
||||
<p>Let's go back through the fields we specified:</p>
|
||||
<ul>
|
||||
<li><strong>Text</strong> - This is what the user will see, the text that appears on the button</li>
|
||||
<li><strong>Callback Data</strong> - This will be sent back to the code instance as part of a new <code>Update</code>, so we can quickly identify what button was clicked.</li>
|
||||
<li><strong>Url</strong> - A button that specifies a URL doesn't specify callbackdata since its behavior is predefined – it will open the given link when tapped.</li>
|
||||
</ul>
|
||||
<h4><a class="anchor" href="#creating-keyboards" id="creating-keyboards" name="creating-keyboards"><i class="anchor-icon"></i></a>Creating Keyboards</h4>
|
||||
<p>The <strong>buttons</strong> we created can be assembled into two <strong>keyboards</strong>, which will then be used to navigate back and forth between two <strong>sample menus</strong>.</p>
|
||||
<p>First, <strong>add two fields</strong> to store the necessary keyboards.</p>
|
||||
<pre><code>private boolean <a href='/constructor/screaming'>screaming</a> = <a href='/constructor/false'>false</a>;
|
||||
|
||||
private InlineKeyboardMarkup keyboardM1;
|
||||
private InlineKeyboardMarkup keyboardM2;</code></pre>
|
||||
<p>Then, <strong>build</strong> and <strong>assign</strong> them.</p>
|
||||
<pre><code>keyboardM1 = InlineKeyboardMarkup.builder()
|
||||
.keyboardRow(List.of(next)).build();
|
||||
|
||||
//Buttons are wrapped in lists since each keyboard is a set of button rows
|
||||
keyboardM2 = InlineKeyboardMarkup.builder()
|
||||
.keyboardRow(List.of(back))
|
||||
.keyboardRow(List.of(url))
|
||||
.build();</code></pre>
|
||||
<blockquote>
|
||||
<p>You can place this code wherever you prefer, the important thing is making sure that keyboard variables are accessible from the method call that will send the new menu. If you're confused by this concept and don't know where to put them, just paste them above the command processing flow.</p>
|
||||
</blockquote>
|
||||
<h4><a class="anchor" href="#sending-keyboards" id="sending-keyboards" name="sending-keyboards"><i class="anchor-icon"></i></a>Sending Keyboards</h4>
|
||||
<p>Sending a keyboard only requires specifying a reply markup for the message.</p>
|
||||
<pre><code>public void sendMenu(Long who, String txt, InlineKeyboardMarkup kb){
|
||||
SendMessage sm = SendMessage.builder().chatId(who.toString())
|
||||
.parseMode("HTML").text(txt)
|
||||
.replyMarkup(kb).build();
|
||||
|
||||
try {
|
||||
execute(sm);
|
||||
} catch (TelegramApiException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}</code></pre>
|
||||
<blockquote>
|
||||
<p>You may have noticed that we also added a new parameter, <code>HTML</code>.
|
||||
This is called a <a href="api#formatting-options">formatting option</a> and will allow us to use HTML tags and add formatting to the text later on.</p>
|
||||
</blockquote>
|
||||
<h4><a class="anchor" href="#menu-trigger" id="menu-trigger" name="menu-trigger"><i class="anchor-icon"></i></a>Menu Trigger</h4>
|
||||
<p>We could send a new menu for each new user, but for simplicity let's add a new command that will spawn a menu. We can achieve this by adding a new <strong>else clause</strong> to the previous command flow.</p>
|
||||
<pre><code> var <a href='/constructor/txt'>txt</a> = <a href='/constructor/msg.getText%28%29'>msg.getText()</a>;
|
||||
if(msg.isCommand()) {
|
||||
if (txt.equals("/scream"))
|
||||
<a href='/constructor/screaming'>screaming</a> = <a href='/constructor/true'>true</a>;
|
||||
else if (txt.equals("/whisper"))
|
||||
<a href='/constructor/screaming'>screaming</a> = <a href='/constructor/false'>false</a>;
|
||||
else if (txt.equals("/menu"))
|
||||
sendMenu(id, "<b>Menu 1</b>", keyboard1);
|
||||
return;
|
||||
}</code></pre>
|
||||
<p>Try sending <code>/menu</code> to your bot now. If you did everything correctly, you should see a brand new menu pop up.</p>
|
||||
<blockquote>
|
||||
<p>In a production environment, commands should be handled with an appropriate design pattern that isolates them into different executor classes – modular and separated from the main logic.</p>
|
||||
</blockquote>
|
||||
<h3><a class="anchor" href="#navigation" id="navigation" name="navigation"><i class="anchor-icon"></i></a>Navigation</h3>
|
||||
<p>When building complex bots, navigation is essential. Your users must be able to move seamlessly from one menu to the next. </p>
|
||||
<p>In this example, we want the <code>Next</code> button to lead the user to the second menu.
|
||||
The <code>Back</code> button will send us back.
|
||||
To do that, we will start processing incoming <code>CallbackQueries</code>, which are the results we get after the user taps on a button.</p>
|
||||
<p>A <code>CallbackQuery</code> is essentially composed of three main parameters:</p>
|
||||
<ul>
|
||||
<li><strong>queryId</strong> - Needed to close the query. You <strong>must always</strong> close new queries after processing them – if you don't, a loading symbol will keep showing on the user's side on top of each button.</li>
|
||||
<li><strong>data</strong> - This identifies which button was pressed.</li>
|
||||
<li><strong>from</strong> - The user who pressed the button.</li>
|
||||
</ul>
|
||||
<p>Processing in this context just means <strong>executing the action</strong> uniquely identified by the button, then <strong>closing the query</strong>.</p>
|
||||
<p>A very basic button handler could look something like:</p>
|
||||
<pre><code>private void buttonTap(Long id, String queryId, String data, int msgId) {
|
||||
|
||||
EditMessageText newTxt = EditMessageText.builder()
|
||||
.chatId(id.toString())
|
||||
.messageId(msgId).text("").build();
|
||||
|
||||
EditMessageReplyMarkup newKb = EditMessageReplyMarkup.builder()
|
||||
.chatId(id.toString()).messageId(msgId).build();
|
||||
|
||||
if(data.equals("next")) {
|
||||
newTxt.setText("MENU 2");
|
||||
newKb.setReplyMarkup(keyboardM2);
|
||||
} else if(data.equals("back")) {
|
||||
newTxt.setText("MENU 1");
|
||||
newKb.setReplyMarkup(keyboardM1);
|
||||
}
|
||||
|
||||
AnswerCallbackQuery close = AnswerCallbackQuery.builder()
|
||||
.callbackQueryId(queryId).build();
|
||||
|
||||
execute(close);
|
||||
execute(newTxt);
|
||||
execute(newKb);
|
||||
}</code></pre>
|
||||
<p>With this handler, whenever a button is tapped, your bot will automatically navigate between inline menus.
|
||||
Expanding on this concept allows for endless combinations of navigable submenus, settings and dynamic pages.</p>
|
||||
<h3><a class="anchor" href="#database" id="database" name="database"><i class="anchor-icon"></i></a>Database</h3>
|
||||
<p>Telegram <strong>does not</strong> host an update database for you – once you process and consume an update, it will no longer be available. This means that features like user lists, message lists, current user inline menu, settings, etc. <strong>have to be implemented and maintained</strong> by bot developers.</p>
|
||||
<p>If your bot needs one of these features and you want to get started on <strong>data persistence</strong>, we recommend that you look into <a href="https://en.wikipedia.org/wiki/Serialization">serialization</a> practices and libraries for your language of choice, as well as available databases.</p>
|
||||
<p>Implementing a database is out of scope for this guide, however, several guides are available online for simple embedded <strong>open source</strong> software solutions like <a href="https://www.sqlite.org/index.html">SQLite</a>, <a href="https://hsqldb.org/">HyperSQL</a>, <a href="https://db.apache.org/derby/">Derby</a> and many more.</p>
|
||||
<blockquote>
|
||||
<p>Your language of choice will also influence which databases are available and supported – the list above assumes you followed this Java tutorial.</p>
|
||||
</blockquote>
|
||||
<h3><a class="anchor" href="#hosting" id="hosting" name="hosting"><i class="anchor-icon"></i></a>Hosting</h3>
|
||||
<p>So far, your bot has been running on your <strong>local machine</strong> – your PC. While this may be good for <strong>developing</strong>, <strong>testing</strong> and <strong>debugging</strong>, it is not ideal for a production environment.
|
||||
You'll want your bot to be available and responsive at all times, but your computer might not always be online.</p>
|
||||
<p>This can be done in four steps:</p>
|
||||
<ul>
|
||||
<li>
|
||||
<p><strong>Package your code</strong>
|
||||
Making your bot <strong>easy to move</strong> and <strong>runnable</strong> outside of an IDE is essential to <strong>host it elsewhere</strong>.
|
||||
If you followed this tutorial, this <a href="https://www.jetbrains.com/help/idea/compiling-applications.html#run_packaged_jar">standard guide</a> will work for you. If you didn't, look into <strong>export or packaging guides</strong> for your IDE and language of choice – procedures may vary but the end result is the same.</p>
|
||||
</li>
|
||||
<li>
|
||||
<p><strong>Purchase a VPS or equivalent service</strong>
|
||||
A server is essentially a machine that is always online and running, without you having to worry about anything. To host your bot, you can opt for a <a href="https://en.wikipedia.org/wiki/Virtual_private_server">VPS</a> which serves this purpose and can be rented from several different providers.
|
||||
Another option would be to purchase a network-capable <a href="https://en.wikipedia.org/wiki/Microcontroller">microcontroller</a>, which come in all different specs and sizes depending on your needs.</p>
|
||||
</li>
|
||||
</ul>
|
||||
<blockquote>
|
||||
<p>You should ensure that all user data remains <strong>heavily encrypted at all times</strong> in your database to guarantee the privacy of your users. The same concept applies to your local instance, however, this becomes especially important once you transfer your database to a remote server.</p>
|
||||
</blockquote>
|
||||
<ul>
|
||||
<li><strong>Upload your executable/package</strong></li>
|
||||
</ul>
|
||||
<p>Once you have a working <a href="https://en.wikipedia.org/wiki/Secure_Shell">ssh</a> connection between your machine and your new server, you should upload your executable and all associated files.
|
||||
We will assume the runnable jar <code>TutorialBot.jar</code> and its database <code>dbase.db</code> are currently in the <code>/TBot</code> folder.</p>
|
||||
<pre><code>$ scp -r /TBot/ username@server_ip:/bots/TBotRemote/</code></pre>
|
||||
<ul>
|
||||
<li><strong>Run your application</strong></li>
|
||||
</ul>
|
||||
<p>Depending on which language you chose, you might have to configure your server environment differently. If you chose Java, you just need to install a compatible JDK.</p>
|
||||
<pre><code>$ apt install openjdk-17-jre
|
||||
$ java -version</code></pre>
|
||||
<p>If you did everything correctly, you should see a Java version as the output, along with a few other values. This means you're ready to run your application.</p>
|
||||
<p>Now, to run the executable:</p>
|
||||
<pre><code>$ cd /bots/TBotRemote/
|
||||
$ java -jar TutorialBot.jar</code></pre>
|
||||
<p>Your bot is now online and users can interact with it at any time.</p>
|
||||
<blockquote>
|
||||
<p>To streamline and modularize this process, you could employ a specialized <a href="https://www.docker.com/resources/what-container/">docker container</a> or equivalent service.
|
||||
If you followed along in one of the equivalent examples (<a href="https://gitlab.com/Athamaxy/telegram-bot-tutorial/-/blob/main/TutorialBot.cs">C#</a>, <a href="https://gitlab.com/Athamaxy/telegram-bot-tutorial/-/blob/main/TutorialBot.py">Python</a>, <a href="https://gitlab.com/Athamaxy/telegram-bot-tutorial/-/blob/main/TutorialBot.go">Go</a> and <a href="https://gitlab.com/Athamaxy/telegram-bot-tutorial/-/tree/main/Nodejs">TypeScript</a>) you can find a detailed set of instructions to export and run your code <a href="https://gitlab.com/Athamaxy/telegram-bot-tutorial/-/tree/main/">here</a>.</p>
|
||||
</blockquote>
|
||||
<h3><a class="anchor" href="#further-reading" id="further-reading" name="further-reading"><i class="anchor-icon"></i></a>Further Reading</h3>
|
||||
<p>If you got this far, you might be interested in these additional guides and docs:</p>
|
||||
<ul>
|
||||
<li><a href="/bots">General Bot Platform Overview</a></li>
|
||||
<li><a href="/bots/features">Detailed List of Bot Features</a></li>
|
||||
<li><a href="/bots/api">Full API Reference</a></li>
|
||||
</ul>
|
||||
<p>If you encounter any issues while following this guide, you can contact us on Telegram at <a href="https://t.me/botsupport">@BotSupport</a>.</p></div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer_wrap">
|
||||
<div class="footer_columns_wrap footer_desktop">
|
||||
<div class="footer_column footer_column_telegram">
|
||||
<h5>Telegram</h5>
|
||||
<div class="footer_telegram_description"></div>
|
||||
Telegram is a cloud-based mobile and desktop messaging app with a focus on security and speed.
|
||||
</div>
|
||||
|
||||
<div class="footer_column">
|
||||
<h5><a href="//telegram.org/faq">About</a></h5>
|
||||
<ul>
|
||||
<li><a href="//telegram.org/faq">FAQ</a></li>
|
||||
<li><a href="//telegram.org/privacy">Privacy</a></li>
|
||||
<li><a href="//telegram.org/press">Press</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer_column">
|
||||
<h5><a href="//telegram.org/apps#mobile-apps">Mobile Apps</a></h5>
|
||||
<ul>
|
||||
<li><a href="//telegram.org/dl/ios">iPhone/iPad</a></li>
|
||||
<li><a href="//telegram.org/android">Android</a></li>
|
||||
<li><a href="//telegram.org/dl/web">Mobile Web</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer_column">
|
||||
<h5><a href="//telegram.org/apps#desktop-apps">Desktop Apps</a></h5>
|
||||
<ul>
|
||||
<li><a href="//desktop.telegram.org/">PC/Mac/Linux</a></li>
|
||||
<li><a href="//macos.telegram.org/">macOS</a></li>
|
||||
<li><a href="//telegram.org/dl/web">Web-browser</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer_column footer_column_platform">
|
||||
<h5><a href="//core.telegram.org/">Platform</a></h5>
|
||||
<ul>
|
||||
<li><a href="//core.telegram.org/api">API</a></li>
|
||||
<li><a href="//translations.telegram.org/">Translations</a></li>
|
||||
<li><a href="//instantview.telegram.org/">Instant View</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer_columns_wrap footer_mobile">
|
||||
<div class="footer_column">
|
||||
<h5><a href="//telegram.org/faq">About</a></h5>
|
||||
</div>
|
||||
<div class="footer_column">
|
||||
<h5><a href="//telegram.org/blog">Blog</a></h5>
|
||||
</div>
|
||||
<div class="footer_column">
|
||||
<h5><a href="//telegram.org/apps">Apps</a></h5>
|
||||
</div>
|
||||
<div class="footer_column">
|
||||
<h5><a href="//core.telegram.org/">Platform</a></h5>
|
||||
</div>
|
||||
<div class="footer_column">
|
||||
<h5><a href="https://twitter.com/telegram" target="_blank" data-track="Follow/Twitter" onclick="trackDlClick(this, event)">Twitter</a></h5>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="/js/main.js?46"></script>
|
||||
<script src="/js/jquery.min.js?1"></script>
|
||||
<script src="/js/bootstrap.min.js?1"></script>
|
||||
|
||||
<script>window.initDevPageNav&&initDevPageNav();
|
||||
backToTopInit("Go up");
|
||||
removePreloadInit();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
267
data/web/corefork.telegram.org/stickers.html
Normal file
267
data/web/corefork.telegram.org/stickers.html
Normal file
|
@ -0,0 +1,267 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Telegram Stickers</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta property="description" content="All users can create, send and share custom artwork using Telegram's open platform for stickers and emoji. Stickers take…">
|
||||
<meta property="og:title" content="Telegram Stickers">
|
||||
<meta property="og:image" content="">
|
||||
<meta property="og:description" content="All users can create, send and share custom artwork using Telegram's open platform for stickers and emoji. Stickers take…">
|
||||
<link rel="icon" type="image/svg+xml" href="/img/website_icon.svg?4">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/img/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/img/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/img/favicon-16x16.png">
|
||||
<link rel="alternate icon" href="/img/favicon.ico" type="image/x-icon" />
|
||||
<link href="/css/bootstrap.min.css?3" rel="stylesheet">
|
||||
|
||||
<link href="/css/telegram.css?232" rel="stylesheet" media="screen">
|
||||
<style>
|
||||
</style>
|
||||
</head>
|
||||
<body class="preload">
|
||||
<div class="dev_page_wrap">
|
||||
<div class="dev_page_head navbar navbar-static-top navbar-tg">
|
||||
<div class="navbar-inner">
|
||||
<div class="container clearfix">
|
||||
<ul class="nav navbar-nav navbar-right hidden-xs"><li class="navbar-twitter"><a href="https://twitter.com/telegram" target="_blank" data-track="Follow/Twitter" onclick="trackDlClick(this, event)"><i class="icon icon-twitter"></i><span> Twitter</span></a></li></ul>
|
||||
<ul class="nav navbar-nav">
|
||||
<li><a href="//telegram.org/">Home</a></li>
|
||||
<li class="hidden-xs"><a href="//telegram.org/faq">FAQ</a></li>
|
||||
<li class="hidden-xs"><a href="//telegram.org/apps">Apps</a></li>
|
||||
<li class=""><a href="/api">API</a></li>
|
||||
<li class=""><a href="/mtproto">Protocol</a></li>
|
||||
<li class=""><a href="/schema">Schema</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container clearfix">
|
||||
<div class="dev_page">
|
||||
<div id="dev_page_content_wrap" class=" ">
|
||||
<div class="dev_page_bread_crumbs"></div>
|
||||
<h1 id="dev_page_title">Telegram Stickers</h1>
|
||||
|
||||
<div id="dev_page_content"><p>All users can create, send and share custom artwork using Telegram's <strong>open platform</strong> for stickers and <a href="#custom-emoji">emoji</a>. Stickers take many forms – from <strong>basic images</strong> to stunning <strong>vector animations</strong>.</p>
|
||||
<p>To start building your own custom sets, click below:</p>
|
||||
<ul>
|
||||
<li><strong>Creating Stickers</strong><ul>
|
||||
<li><a href="#creating-animations">Animated</a></li>
|
||||
<li><a href="#video-stickers-and-emoji">Video</a></li>
|
||||
<li><a href="#static-stickers-and-emoji">Static</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li><strong>Uploading Stickers</strong><ul>
|
||||
<li><a href="#using-the-stickers-bot">How to Upload</a></li>
|
||||
<li><a href="#importing-stickers-from-other-apps">Importing from other apps</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
<h3><a class="anchor" name="animated-stickers-and-emoji" href="#animated-stickers-and-emoji"><i class="anchor-icon"></i></a>Animated Stickers and Emoji</h3>
|
||||
<p>Telegram stickers and emoji can move with smooth <strong>60 FPS animations</strong> to bring your characters to life in high resolution.</p>
|
||||
<blockquote>
|
||||
<p>Animations require Telegram's unique <strong>.TGS format</strong> – click <a href="#video-stickers-and-emoji">here</a> for <strong>Video Stickers and Emoji</strong> made in <strong>.WEBM format</strong>.</p>
|
||||
</blockquote>
|
||||
<h4><a class="anchor" name="creating-animations" href="#creating-animations"><i class="anchor-icon"></i></a>Creating Animations</h4>
|
||||
<p>To create vector-animated stickers and emoji you will need the following:</p>
|
||||
<ol>
|
||||
<li>Any vector graphics editor that allows exporting vector objects to Adobe After Effects to turn them into animations.</li>
|
||||
<li>Adobe After Effects.</li>
|
||||
<li>The <a href="https://github.com/TelegramMessenger/bodymovin-extension">Bodymovin-TG</a> plugin, a fork of Bodymovin for Adobe After Effects that can be used to export animations to Telegram's <strong>.TGS format</strong>.</li>
|
||||
</ol>
|
||||
<blockquote>
|
||||
<p>The Lottie-based .TGS format allows for incredibly detailed animations that are <strong>less than 30 KB</strong> in size – six times smaller than the average photo.</p>
|
||||
</blockquote>
|
||||
<h4><a class="anchor" name="animation-requirements" href="#animation-requirements"><i class="anchor-icon"></i></a>Animation Requirements</h4>
|
||||
<ul>
|
||||
<li>The canvas size must be <strong>512х512 pixels</strong>.</li>
|
||||
<li>Objects must not leave the canvas.</li>
|
||||
<li>Animation length must not exceed <strong>3 seconds</strong>.</li>
|
||||
<li>All animations must be looped.</li>
|
||||
<li>Final file size must not exceed <strong>64 KB</strong> after rendering in Bodymovin.</li>
|
||||
<li>All animations must run at <strong>60 Frames Per Second</strong>.</li>
|
||||
<li>You <strong>must not</strong> use the following Adobe After Effects functionality when animating your artwork: <em>Auto-bezier keys, Expressions, Masks, Layer Effects, Images, Solids, Texts, 3D Layers, Merge Paths, Star Shapes, Gradient Strokes, Repeaters, Time Stretching, Time Remapping, Auto-Oriented Layers</em>.</li>
|
||||
</ul>
|
||||
<h4><a class="anchor" name="uploading-animations" href="#uploading-animations"><i class="anchor-icon"></i></a>Uploading Animations</h4>
|
||||
<p>When your files are ready, send the <code>/newanimated</code> command to the <a href="https://t.me/Stickers">@Stickers</a> bot – then send it the .TGS files.</p>
|
||||
<p>To upload emoji, send <code>/newemojipack</code> to <a href="https://t.me/Stickers">@Stickers</a>. The requirements for .TGS stickers and emoji are <strong>exactly the same</strong>.</p>
|
||||
<p>Your set will need an icon. Icons for your sets must be <strong>100x100 pixels</strong>, with a looped animation not exceeding 3 seconds.</p>
|
||||
<hr>
|
||||
<h3><a class="anchor" name="video-stickers-and-emoji" href="#video-stickers-and-emoji"><i class="anchor-icon"></i></a>Video Stickers and Emoji</h3>
|
||||
<p>Stickers and emoji can also be built with <strong>.WEBM</strong> – an open-source format that is compatible with many graphics editors to create high-detail images. Requires <a href="https://telegram.org/apps">Telegram 8.5</a> or higher.</p>
|
||||
<!--
|
||||
> This format also allows you to [import custom stickers](https://core.telegram.org/import-stickers) to Telegram from other apps.
|
||||
-->
|
||||
|
||||
<h4><a class="anchor" name="creating-videos" href="#creating-videos"><i class="anchor-icon"></i></a>Creating Videos</h4>
|
||||
<p>To create stickers and emoji from video files, you only need <a href="https://core.telegram.org/stickers/webm-vp9-encoding">editing software</a> that lets you export your project as a <strong>.WEBM video file</strong>.</p>
|
||||
<h4><a class="anchor" name="video-requirements" href="#video-requirements"><i class="anchor-icon"></i></a>Video Requirements</h4>
|
||||
<blockquote>
|
||||
<p>See this <a href="https://core.telegram.org/stickers/webm-vp9-encoding">Encoding .WEBM with VP9 Guide</a> for details </p>
|
||||
</blockquote>
|
||||
<ul>
|
||||
<li>For stickers, one side must be exactly <strong>512 pixels</strong> in size – the other side can be 512 pixels <strong>or less</strong>.</li>
|
||||
<li>For emoji, the video must be exactly <strong>100x100 pixels</strong> in size</li>
|
||||
<li>Video duration must not exceed <strong>3 seconds</strong>.</li>
|
||||
<li>Frame rate can be up to <strong>30 FPS</strong>.</li>
|
||||
<li>Video should be looped for optimal user experience.</li>
|
||||
<li>Video size should not exceed <strong>256 KB</strong>. </li>
|
||||
<li>Video must be in .WEBM format encoded with the <strong>VP9 codec</strong>.</li>
|
||||
<li>Video must have <strong>no audio stream</strong>.</li>
|
||||
</ul>
|
||||
<h4><a class="anchor" name="uploading-videos" href="#uploading-videos"><i class="anchor-icon"></i></a>Uploading Videos</h4>
|
||||
<p>Once your stickers are ready, send the <code>/newvideo</code> command to the <a href="https://t.me/Stickers">@Stickers</a> bot – then send it the .WEBM files.</p>
|
||||
<p>To upload emoji, send <code>/newemojipack</code> to <a href="https://t.me/Stickers">@Stickers</a>. Note that video emoji need to be a <a href="#video-requirements">smaller resolution</a> than stickers.</p>
|
||||
<p>Your set will need a .WEBM icon. Icons for video sticker sets must be <strong>100x100 pixels</strong>, with a looped animation not exceeding 3 seconds.</p>
|
||||
<hr>
|
||||
<h3><a class="anchor" name="static-stickers-and-emoji" href="#static-stickers-and-emoji"><i class="anchor-icon"></i></a>Static Stickers and Emoji</h3>
|
||||
<p>Turn your favorite drawings and memes into packs of images that are easily to share and access on any device.</p>
|
||||
<h4><a class="anchor" name="creating-images" href="#creating-images"><i class="anchor-icon"></i></a>Creating Images</h4>
|
||||
<p>To create static stickers and emoji for Telegram, you only need an image editor that lets you export in <strong>.PNG</strong> or <strong>.WEBP</strong> format.</p>
|
||||
<h4><a class="anchor" name="image-requirements" href="#image-requirements"><i class="anchor-icon"></i></a>Image Requirements</h4>
|
||||
<ul>
|
||||
<li>For stickers, one side must be exactly <strong>512 pixels</strong> in size – the other side can be 512 pixels <strong>or less</strong>.</li>
|
||||
<li>For emoji, images must be exactly <strong>100x100 pixels</strong> in size.</li>
|
||||
<li>The image file must be in either .PNG or .WEBP format.</li>
|
||||
</ul>
|
||||
<blockquote>
|
||||
<p>Tip: a transparent background, white stroke and black shadow effect will make your sticker stand out.</p>
|
||||
</blockquote>
|
||||
<h4><a class="anchor" name="uploading-images" href="#uploading-images"><i class="anchor-icon"></i></a>Uploading Images</h4>
|
||||
<p>Once your stickers are ready, start a chat with the <a href="https://t.me/Stickers">@Stickers</a> bot and send the command <code>/newpack</code>. Your sticker set can also have a <strong>custom icon</strong> – a <strong>100x100 pixel image</strong> in .PNG or .WEBP format.</p>
|
||||
<p>To upload emoji, send <code>/newemojipack</code> to <a href="https://t.me/Stickers">@Stickers</a>. Note that static emoji need to be a <a href="#image-requirements">smaller resolution</a> than stickers.</p>
|
||||
<blockquote>
|
||||
<p>For more info about using the <a href="https://t.me/Stickers">@Stickers</a> bot, click <a href="#using-the-stickers-bot">here</a>.</p>
|
||||
</blockquote>
|
||||
<h3><a class="anchor" name="custom-emoji" href="#custom-emoji"><i class="anchor-icon"></i></a>Custom Emoji</h3>
|
||||
<p>As of version 8.9 released in August 2022, Telegram apps support <a href="https://telegram.org/blog/custom-emoji">custom emoji</a>.<br>Emoji use the same technology as stickers, making it very easy to convert your art to <strong>both formats</strong>. Check out the <a href="#video-requirements">video</a> and <a href="#image-requirements">image</a> sections for details on the different size requirements.<br>To upload them, use the <code>/newemojipack</code> command in <a href="https://t.me/stickers">@Stickers</a>. </p>
|
||||
<blockquote>
|
||||
<p>Everyone can create new custom emoji, however, adding and using custom sets is currently an exclusive <a href="https://t.me/premium">feature</a> of <a href="https://telegram.org/blog/700-million-and-premium">Telegram Premium</a> users.</p>
|
||||
</blockquote>
|
||||
<hr>
|
||||
<h3><a class="anchor" name="using-the-stickers-bot" href="#using-the-stickers-bot"><i class="anchor-icon"></i></a>Using the @Stickers Bot</h3>
|
||||
<p>Publishing and <a href="#editing-a-sticker-pack">editing</a> sticker packs is <strong>simple</strong> and <strong>automated</strong>, thanks to the <a href="https://t.me/Stickers">@Stickers</a> bot. It can also show you <a href="#sticker-stats">detailed stats</a> for stickers and packs.</p>
|
||||
<h4><a class="anchor" name="publishing-a-sticker-pack" href="#publishing-a-sticker-pack"><i class="anchor-icon"></i></a>Publishing a Sticker Pack</h4>
|
||||
<p>Once you open the bot, press the <strong>Start button</strong> or send <code>/start</code>. The bot will reply, describing its different commands. It will walk you through step by step, but here's a quick guide:</p>
|
||||
<ul>
|
||||
<li>Open the <a href="https://t.me/TelegramTips/283">bot menu</a> in the message bar and select the <code>/newpack</code> command to start uploading <a href="#uploading-images">static stickers</a>. For <a href="#uploading-animations">animated stickers</a> use <code>/newanimated</code>, or <code>/newvideo</code> for <a href="#uploading-videos">video stickers</a>.</li>
|
||||
<li>Give your sticker pack a <strong>name</strong> – this name will appear <strong>as the title</strong> for your pack in the sticker panel.</li>
|
||||
<li>Send your first sticker file – an <a href="#static-stickers-and-emoji">image file</a>, <a href="#animated-stickers-and-emoji">.TGS file</a>, or <a href="#video-stickers-and-emoji">.WEBM file</a>. Using one of the <a href="https://telegram.org/apps#desktop-apps">Desktop</a> or <a href="https://telegram.org/apps#web-apps">Web apps</a> is <strong>strongly recommended</strong>.</li>
|
||||
<li>Choose an <strong>emoji</strong> that corresponds to your sticker – this lets users quickly find it with <a href="https://t.me/TelegramTips/294">sticker suggestions</a>.</li>
|
||||
<li>Continue uploading all your sticker files.</li>
|
||||
<li>When you're done uploading, send the <code>/publish</code> command.</li>
|
||||
<li>Set an icon for your pack – <a href="#static-stickers-and-emoji">static sticker</a> packs can <code>/skip</code> this step, but it is required for <a href="#animated-stickers-and-emoji">animated</a> or <a href="#video-stickers-and-emoji">video stickers</a>.</li>
|
||||
<li>Choose a <strong>short name</strong> for your sticker pack – it will be used to create a <strong>shareable link</strong> for the pack like <a href="https://t.me/addstickers/HotCherry">t.me/addstickers/HotCherry</a>. Congratulations! Your stickers are ready for the world.</li>
|
||||
</ul>
|
||||
<blockquote>
|
||||
<p>After your pack is finished, you can send <code>/start</code> again to see the full list of commands, or use the bot menu to create another pack, <a href="#editing-a-sticker-pack">edit an existing pack</a>, or <a href="#sticker-stats">see statistics</a>.</p>
|
||||
</blockquote>
|
||||
<h4><a class="anchor" name="editing-a-sticker-pack" href="#editing-a-sticker-pack"><i class="anchor-icon"></i></a>Editing a Sticker Pack</h4>
|
||||
<p>Once you've created <a href="#publishing-a-sticker-pack">one or more packs</a>, you can <strong>add</strong>, <strong>edit</strong> or <strong>replace stickers</strong> in your existing sets.</p>
|
||||
<ul>
|
||||
<li>Use <code>/addsticker</code> if you have more artwork you'd like to add to a set. Choose one of your packs from the list – the upload process is <a href="#publishing-a-sticker-pack">exactly the same</a> as before.</li>
|
||||
<li>Use <code>/editsticker</code> to <strong>change the emoji</strong> you assigned to a sticker – select the pack and sticker, or simply send the intended sticker from your panel.</li>
|
||||
<li>Use <code>/replacesticker</code> if you want to swap out an older sticker for an updated version.</li>
|
||||
<li>Use <code>/ordersticker</code> to <strong>change the order</strong> of stickers in your pack. Choose the pack and one of the stickers, then choose another sticker to appear before it (to the left) in the panel.</li>
|
||||
<li>Use <code>/delsticker</code> to <strong>remove a sticker</strong> from the pack – you can always use <code>/addsticker</code> to add it again if you change your mind.</li>
|
||||
<li>Use <code>/seticon</code> to set an icon for your pack or to <strong>change the icon</strong>. Static sticker packs without a custom icon will use the first sticker as its icon.</li>
|
||||
</ul>
|
||||
<blockquote>
|
||||
<p>Edits to your sticker packs may take up to an hour to update for all users.</p>
|
||||
</blockquote>
|
||||
<h4><a class="anchor" name="sticker-stats" href="#sticker-stats"><i class="anchor-icon"></i></a>Sticker Stats</h4>
|
||||
<p>There are a number of commands that let you <strong>see statistics</strong> for your stickers – here's what they all do:</p>
|
||||
<ul>
|
||||
<li><code>/packstats</code> shows how many times your pack was <strong>used</strong>, <strong>installed</strong> and <strong>removed</strong> – both recently and overall.</li>
|
||||
<li><code>/stats</code> shows how many times an <strong>individual sticker</strong> has been sent.</li>
|
||||
<li><code>/top</code> shows the most popular stickers from <strong>all your packs</strong>.</li>
|
||||
<li><code>/packtop</code> shows your most popular sticker packs and their <strong>individual stats</strong>.</li>
|
||||
<li><code>/topbypack</code> shows the top stickers from a <strong>specific sticker pack</strong>.</li>
|
||||
<li><code>/packusagetop</code> shows your most popular packs by <strong>recent usage</strong>.</li>
|
||||
</ul>
|
||||
<blockquote>
|
||||
<p>You can filter the results of <code>/top</code>, <code>/packtop</code>, <code>/topbypack</code> and <code>/packusagetop</code>. For example <code>/top 20</code> would show your top 20 stickers, and <code>/topbypack -5</code> would show the 5 least popular stickers from a pack.</p>
|
||||
</blockquote>
|
||||
<h3><a class="anchor" name="importing-stickers-from-other-apps" href="#importing-stickers-from-other-apps"><i class="anchor-icon"></i></a>Importing Stickers From Other Apps</h3>
|
||||
<p>Developers can build apps to automate importing stickers using Telegram’s API. With these tools, users can instantly bring their favorite stickers to Telegram.</p>
|
||||
<h4><a class="anchor" name="for-developers" href="#for-developers"><i class="anchor-icon"></i></a>For Developers</h4>
|
||||
<p>As of version 7.8, Telegram apps support a simple API for importing stickers. Developers can use this to <strong>build apps</strong> or <strong>add tools</strong> to apps that let users instantly transfer stickers to Telegram – or create custom stickers from photos or videos.</p>
|
||||
<blockquote>
|
||||
<p>Click <a href="https://core.telegram.org/import-stickers#sticker-formats">here</a> for more information about developing apps for importing stickers.</p>
|
||||
</blockquote>
|
||||
<h4><a class="anchor" name="for-users" href="#for-users"><i class="anchor-icon"></i></a>For Users</h4>
|
||||
<p>Users can find apps that allow them to import stickers or quickly <strong>generate their own</strong>. They can also easily <a href="#publishing-a-sticker-pack">publish custom stickers</a> with the <a href="https://t.me/Stickers">@Stickers</a> bot using <a href="#static-stickers-and-emoji">.PNG</a>, <a href="#static-stickers-and-emoji">.WEBP</a> or <a href="#video-stickers-and-emoji">.WEBM</a> files for stickers from other apps.</p>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer_wrap">
|
||||
<div class="footer_columns_wrap footer_desktop">
|
||||
<div class="footer_column footer_column_telegram">
|
||||
<h5>Telegram</h5>
|
||||
<div class="footer_telegram_description"></div>
|
||||
Telegram is a cloud-based mobile and desktop messaging app with a focus on security and speed.
|
||||
</div>
|
||||
|
||||
<div class="footer_column">
|
||||
<h5><a href="//telegram.org/faq">About</a></h5>
|
||||
<ul>
|
||||
<li><a href="//telegram.org/faq">FAQ</a></li>
|
||||
<li><a href="//telegram.org/privacy">Privacy</a></li>
|
||||
<li><a href="//telegram.org/press">Press</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer_column">
|
||||
<h5><a href="//telegram.org/apps#mobile-apps">Mobile Apps</a></h5>
|
||||
<ul>
|
||||
<li><a href="//telegram.org/dl/ios">iPhone/iPad</a></li>
|
||||
<li><a href="//telegram.org/android">Android</a></li>
|
||||
<li><a href="//telegram.org/dl/web">Mobile Web</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer_column">
|
||||
<h5><a href="//telegram.org/apps#desktop-apps">Desktop Apps</a></h5>
|
||||
<ul>
|
||||
<li><a href="//desktop.telegram.org/">PC/Mac/Linux</a></li>
|
||||
<li><a href="//macos.telegram.org/">macOS</a></li>
|
||||
<li><a href="//telegram.org/dl/web">Web-browser</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer_column footer_column_platform">
|
||||
<h5><a href="//core.telegram.org/">Platform</a></h5>
|
||||
<ul>
|
||||
<li><a href="//core.telegram.org/api">API</a></li>
|
||||
<li><a href="//translations.telegram.org/">Translations</a></li>
|
||||
<li><a href="//instantview.telegram.org/">Instant View</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer_columns_wrap footer_mobile">
|
||||
<div class="footer_column">
|
||||
<h5><a href="//telegram.org/faq">About</a></h5>
|
||||
</div>
|
||||
<div class="footer_column">
|
||||
<h5><a href="//telegram.org/blog">Blog</a></h5>
|
||||
</div>
|
||||
<div class="footer_column">
|
||||
<h5><a href="//telegram.org/apps">Apps</a></h5>
|
||||
</div>
|
||||
<div class="footer_column">
|
||||
<h5><a href="//core.telegram.org/">Platform</a></h5>
|
||||
</div>
|
||||
<div class="footer_column">
|
||||
<h5><a href="https://twitter.com/telegram" target="_blank" data-track="Follow/Twitter" onclick="trackDlClick(this, event)">Twitter</a></h5>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="/js/main.js?46"></script>
|
||||
|
||||
<script>backToTopInit("Go up");
|
||||
removePreloadInit();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
155
data/web/my.telegram.org/auth.html
Normal file
155
data/web/my.telegram.org/auth.html
Normal file
|
@ -0,0 +1,155 @@
|
|||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Authorization</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta name="apple-itunes-app" content="app-id=686449807">
|
||||
<link rel="icon" type="image/svg+xml" href="/img/website_icon.svg?4">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/img/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/img/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/img/favicon-16x16.png">
|
||||
<link rel="alternate icon" href="/img/favicon.ico" type="image/x-icon" />
|
||||
<link href="/css/bootstrap.min.css?3" rel="stylesheet">
|
||||
<link href="/css/bootstrap-extra.css?2" rel="stylesheet">
|
||||
|
||||
<link href="/css/telegram.css?232" rel="stylesheet" media="screen">
|
||||
<style>
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div id="fb-root"></div>
|
||||
<div class="tl_page_wrap">
|
||||
<div class="tl_page_head navbar navbar-static-top navbar-tg">
|
||||
<div class="navbar-inner">
|
||||
<div class="container">
|
||||
<ul class="nav navbar-nav">
|
||||
<li><a href="//telegram.org/">Home</a></li>
|
||||
<li><a href="//telegram.org/faq">FAQ</a></li>
|
||||
<li><a href="//telegram.org/apps">Apps</a></li>
|
||||
<li class="hidden-xs"><a href="//core.telegram.org/api">API</a></li>
|
||||
<li class="hidden-xs"><a href="//core.telegram.org/mtproto">Protocol</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container tl_page_container">
|
||||
<div class="tl_page">
|
||||
<div class="my_page_wrap">
|
||||
<div class="container clearfix">
|
||||
<div class="row">
|
||||
<div class="col-md-4">
|
||||
<div class="tl_main_card tl_main_card_decentralized"></div>
|
||||
</div>
|
||||
<div class="col-md-8">
|
||||
|
||||
<div id="my_login_form_wrap">
|
||||
|
||||
<h1>Delete Account or Manage Apps</h1>
|
||||
<p class="my_login_form_details help-block">Log in here to <strong>manage your apps</strong> using Telegram API or <strong>delete your account</strong>. Enter your number and we will send you a confirmation code via Telegram (not SMS).</p>
|
||||
|
||||
<div id="my_login_alert"></div>
|
||||
|
||||
<form id="my_send_form" onsubmit="return sendPassword(event);">
|
||||
<div class="form-group">
|
||||
<label for="my_login_phone">Your Phone Number</label>
|
||||
<input type="text" class="form-control input-large" id="my_login_phone" placeholder="+12223334455" autocomplete="off"/>
|
||||
<p class="help-block">Please enter your number in <a href="https://telegram.org/faq#login-and-sms" target="_blank">international format</a></p>
|
||||
</div>
|
||||
<div class="support_submit">
|
||||
<button type="submit" class="btn btn-primary btn-lg">Next</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<form method="POST" action="/auth/login" class="hide" id="my_login_form" onsubmit="return checkPassword(event);">
|
||||
<input type="hidden" id="my_login_phone_input" name="phone">
|
||||
<input type="hidden" id="my_random_hash" name="random_hash">
|
||||
<div class="form-group">
|
||||
<label>Your Phone Number</label>
|
||||
<span class="form-control input input-large uneditable-input"><strong id="my_login_phone_field"></strong> (<a href="/auth">Incorrect?</a>)</span>
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<label for="my_password">Confirmation code</label>
|
||||
<input type="text" id="my_password" class="form-control input-large" name="password" placeholder="Confirmation code">
|
||||
</div>
|
||||
<div class="checkbox">
|
||||
<label>
|
||||
<input type="checkbox" name="remember" value="1"> Remember Me
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="support_submit">
|
||||
<button type="submit" class="btn btn-primary btn-lg">Sign In</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="/js/jquery.min.js?1"></script>
|
||||
<script src="/js/bootstrap.min.js"></script>
|
||||
<script src="/js/main.js?4"></script>
|
||||
<script>function showLoginError(error_text) {
|
||||
$('#my_login_alert').html('<div class="alert alert-danger"> <a class="close" data-dismiss="alert" href="#">×</a>' + error_text + ' </div>').show();
|
||||
}
|
||||
|
||||
function sendPassword (event) {
|
||||
event.preventDefault();
|
||||
|
||||
$('#my_login_alert').hide();
|
||||
|
||||
var phone = $('#my_login_phone').val();
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: '/auth/send_password',
|
||||
data: {phone: phone},
|
||||
success: function (result) {
|
||||
$('#my_login_phone_input').val(phone);
|
||||
$('#my_login_phone_field').text(phone);
|
||||
$('#my_random_hash').val(result.random_hash);
|
||||
|
||||
$('#my_send_form').addClass('hide');
|
||||
$('#my_login_form').removeClass('hide');
|
||||
$('#my_password').focus();
|
||||
},
|
||||
error: function (xhr, error_text) {
|
||||
showLoginError(xhr.responseText);
|
||||
},
|
||||
dataType: 'json'
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function checkPassword (event) {
|
||||
event.preventDefault();
|
||||
|
||||
$('#my_login_alert').hide();
|
||||
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
url: '/auth/login',
|
||||
data: $('#my_login_form').serialize(),
|
||||
success: function () {
|
||||
location.href = "\/";
|
||||
},
|
||||
error: function (xhr, error_text) {
|
||||
showLoginError(xhr.responseText);
|
||||
},
|
||||
dataType: 'json'
|
||||
});
|
||||
|
||||
return false;
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
5087
data/web/my.telegram.org/css/telegram.css
Normal file
5087
data/web/my.telegram.org/css/telegram.css
Normal file
File diff suppressed because it is too large
Load diff
713
data/web/my.telegram.org/js/main.js
Normal file
713
data/web/my.telegram.org/js/main.js
Normal file
|
@ -0,0 +1,713 @@
|
|||
var startTime = +(new Date());
|
||||
function dT() {
|
||||
return '[' + ((+(new Date()) - startTime)/ 1000.0) + '] ';
|
||||
}
|
||||
|
||||
var jsonpCallbacks = [];
|
||||
function twitterCustomShareInit () {
|
||||
var btns = document.querySelectorAll
|
||||
? document.querySelectorAll('.tl_twitter_share_btn')
|
||||
: [document.getElementById('tl_twitter_share_btn')];
|
||||
|
||||
if (!btns.length) {
|
||||
return;
|
||||
}
|
||||
var head = document.getElementsByTagName('head')[0], i, script;
|
||||
for (i = 0; i < btns.length; i++) {
|
||||
(function (btn) {
|
||||
var status = btn.getAttribute('data-text'),
|
||||
url = btn.getAttribute('data-url') || location.toString() || 'https://telegram.org/',
|
||||
via = btn.getAttribute('data-via'),
|
||||
urlEncoded = encodeURIComponent(url),
|
||||
popupUrl = 'https://twitter.com/intent/tweet?text=' + encodeURIComponent(status) + '&url=' + urlEncoded + '&via=' + encodeURIComponent(via);
|
||||
|
||||
btn.setAttribute('href', popupUrl);
|
||||
btn.href = popupUrl;
|
||||
|
||||
btn.addEventListener('click', function (e) {
|
||||
var popupW = 550,
|
||||
popupH = 450,
|
||||
params = [
|
||||
'width=' + popupW,
|
||||
'height=' + popupH,
|
||||
'left=' + Math.round(screen.width / 2 - popupW / 2),
|
||||
'top=' + Math.round(screen.height / 2 - popupH / 2),
|
||||
'personalbar=0',
|
||||
'toolbar=0',
|
||||
'scrollbars=1',
|
||||
'resizable=1'
|
||||
].join(','),
|
||||
popup = window.open(popupUrl, '_blank', params);
|
||||
|
||||
if (popup) {
|
||||
try {
|
||||
popup.focus();
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
return cancelEvent(e);
|
||||
}, false);
|
||||
})(btns[i]);
|
||||
}
|
||||
}
|
||||
|
||||
function blogRecentNewsInit () {
|
||||
if (document.querySelectorAll) {
|
||||
var sideImages = document.querySelectorAll('.blog_side_image_wrap');
|
||||
var sideImage, parent, i;
|
||||
var len = len = sideImages.length;
|
||||
for (i = 0; i < len; i++) {
|
||||
sideImage = sideImages[i];
|
||||
parent = sideImage.parentNode.parentNode;
|
||||
if (parent) {
|
||||
parent.insertBefore(sideImage, parent.firstChild);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var moreBtn = document.getElementById('tlb_blog_head_more_link');
|
||||
if (!moreBtn) {
|
||||
return false;
|
||||
}
|
||||
|
||||
var activeClassName = 'tlb_blog_head_recent_active';
|
||||
moreBtn.addEventListener('click', function (event) {
|
||||
var parent = this.parentNode;
|
||||
var className = parent.className;
|
||||
if (className.indexOf(activeClassName) == -1) {
|
||||
className += ' ' + activeClassName;
|
||||
} else {
|
||||
className = className.replace(' ' + activeClassName, '');
|
||||
}
|
||||
parent.className = className;
|
||||
|
||||
return cancelEvent(event);
|
||||
});
|
||||
}
|
||||
|
||||
function blogSideImageUpdate(argument) {
|
||||
var isDesktop = document.documentElement.offsetWidth >= 1000
|
||||
document.querySelectorAll('.blog_side_image_wrap').forEach(function (imageWrap) {
|
||||
if (isDesktop) {
|
||||
var titleHeight = imageWrap.parentNode.previousElementSibling.clientHeight;
|
||||
var beforeTitleEl = imageWrap.parentNode.previousElementSibling.previousElementSibling;
|
||||
if (beforeTitleEl) {
|
||||
titleHeight += beforeTitleEl.clientHeight;
|
||||
}
|
||||
imageWrap.firstElementChild.style.marginTop = (-titleHeight - 8) + 'px';
|
||||
} else {
|
||||
imageWrap.firstElementChild.style.marginTop = '';
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function blogSideImageInit() {
|
||||
window.addEventListener('resize', blogSideImageUpdate, false);
|
||||
setTimeout(blogSideImageUpdate, 0);
|
||||
}
|
||||
|
||||
function cancelEvent (event) {
|
||||
event = event || window.event;
|
||||
if (event) event = event.originalEvent || event;
|
||||
|
||||
if (event.stopPropagation) event.stopPropagation();
|
||||
if (event.preventDefault) event.preventDefault();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
function trackDlClick (element, event) {
|
||||
var href = element.getAttribute('href'),
|
||||
track = element.getAttribute('data-track') || false;
|
||||
|
||||
if (!track || !window.ga) {
|
||||
return;
|
||||
}
|
||||
|
||||
var trackData = track.toString().split('/');
|
||||
|
||||
ga('send', 'event', trackData[0], trackData[1], href);
|
||||
|
||||
if ((element.getAttribute('target') || '').toLowerCase() != '_blank') {
|
||||
setTimeout(function() { location.href = href; }, 200);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
var toTopWrapEl,
|
||||
toTopEl,
|
||||
pageContentWrapEl,
|
||||
curVisible,
|
||||
curShown = false;
|
||||
function backToTopInit (labelHtml) {
|
||||
pageContentWrapEl = document.getElementById('dev_page_content_wrap');
|
||||
if (!pageContentWrapEl) {
|
||||
return false;
|
||||
}
|
||||
var t = document.createElement('div');
|
||||
|
||||
t.innerHTML = '<div class="back_to_top"><i class="icon icon-to-top"></i>' + labelHtml + '</div>';
|
||||
toTopEl = t.firstChild;
|
||||
t.innerHTML = '<a class="back_to_top_wrap' + (pageContentWrapEl.classList.contains('is_rtl') ? ' is_rtl' : '') + '" onclick="backToTopGo()"></a>';
|
||||
toTopWrapEl = t.firstChild;
|
||||
|
||||
toTopWrapEl.appendChild(toTopEl);
|
||||
document.body.appendChild(toTopWrapEl);
|
||||
|
||||
if (window.addEventListener) {
|
||||
window.addEventListener('resize', backToTopResize, false);
|
||||
window.addEventListener('scroll', backToTopScroll, false);
|
||||
}
|
||||
backToTopResize();
|
||||
}
|
||||
|
||||
function backToTopGo () {
|
||||
window.scroll(0, 0);
|
||||
backToTopScroll();
|
||||
}
|
||||
|
||||
function backToTopResize () {
|
||||
var left = getXY(pageContentWrapEl)[0],
|
||||
dwidth = Math.max(window.innerWidth, document.documentElement.clientWidth, 0),
|
||||
dheight = Math.max(window.innerHeight, document.documentElement.clientHeight);
|
||||
|
||||
curVisible = pageContentWrapEl && left > 130 && dwidth > 640;
|
||||
toTopWrapEl.style.width = left + 'px';
|
||||
toTopEl.style.height = dheight + 'px';
|
||||
backToTopScroll();
|
||||
}
|
||||
|
||||
function backToTopScroll () {
|
||||
var st = window.pageYOffset || document.body.scrollTop || document.documentElement.scrollTop || document.documentElement.scrollTop;
|
||||
if ((st > 400 && curVisible) != curShown) {
|
||||
curShown = !curShown;
|
||||
if (curShown) {
|
||||
toTopWrapEl.classList.add('back_to_top_shown');
|
||||
} else {
|
||||
toTopWrapEl.classList.remove('back_to_top_shown');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function removePreloadInit() {
|
||||
if (window.addEventListener) {
|
||||
window.addEventListener('load', function () {
|
||||
document.body.classList.remove('preload');
|
||||
}, false);
|
||||
} else {
|
||||
setTimeout(function () {
|
||||
document.body.classList.remove('preload');
|
||||
}, 1000)
|
||||
}
|
||||
}
|
||||
|
||||
function getXY (obj) {
|
||||
if (!obj) return [0, 0];
|
||||
|
||||
var left = 0, top = 0;
|
||||
if (obj.offsetParent) {
|
||||
do {
|
||||
left += obj.offsetLeft;
|
||||
top += obj.offsetTop;
|
||||
} while (obj = obj.offsetParent);
|
||||
}
|
||||
return [left, top];
|
||||
}
|
||||
|
||||
|
||||
var onDdBodyClick,
|
||||
currentDd;
|
||||
function dropdownClick (element, event) {
|
||||
var parent = element.parentNode;
|
||||
var isOpen = (parent.className || '').indexOf('open') > 0;
|
||||
if (currentDd && currentDd != parent) {
|
||||
dropdownHide(currentDd);
|
||||
}
|
||||
if (!isOpen) {
|
||||
parent.className = (parent.className || '') + ' open';
|
||||
if (!onDdBodyClick) {
|
||||
window.addEventListener('click', dropdownPageClick, false);
|
||||
}
|
||||
currentDd = parent;
|
||||
} else {
|
||||
dropdownHide(currentDd);
|
||||
currentDd = false;
|
||||
}
|
||||
event.cancelBubble = true;
|
||||
return false;
|
||||
}
|
||||
|
||||
function dropdownHide (parent) {
|
||||
parent.className = parent.className.replace(' open', '');
|
||||
}
|
||||
|
||||
function dropdownPageClick (event) {
|
||||
if (currentDd) {
|
||||
dropdownHide(currentDd);
|
||||
currentDd = false;
|
||||
}
|
||||
}
|
||||
|
||||
function escapeHTML (html) {
|
||||
html = html || '';
|
||||
return html.replace(/&/g, '&')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/</g, '<')
|
||||
.replace(/"/g, '"')
|
||||
.replace(/'/g, ''');
|
||||
}
|
||||
|
||||
function videoTogglePlay(el) {
|
||||
if (el.paused) {
|
||||
el.play();
|
||||
} else {
|
||||
el.pause();
|
||||
}
|
||||
}
|
||||
|
||||
function getDevPageNav() {
|
||||
// console.time('page nav');
|
||||
var menu = $('<ul class="nav navbar-nav navbar-default"></ul>');
|
||||
var lastLi = false;
|
||||
var items = 0;
|
||||
$('a.anchor').each(function (k, anchor) {
|
||||
var parentTag = anchor.parentNode.tagName;
|
||||
var matches = parentTag.match(/^h([34])$/i);
|
||||
var anchorName = anchor.name;
|
||||
if (!matches || !anchorName) {
|
||||
return;
|
||||
}
|
||||
anchor.id = anchor.name;
|
||||
var level = parseInt(matches[1]);
|
||||
var li = $('<li><a href="#'+ anchorName +'" data-target="#'+ anchorName +'" onmouseenter="showTitleIfOverflows(this)">' + escapeHTML(anchor.nextSibling.textContent) + '</a></li>');
|
||||
if (level == 3) {
|
||||
li.appendTo(menu);
|
||||
lastLi = li;
|
||||
} else {
|
||||
// console.log(lastLi);
|
||||
if (!lastLi) {
|
||||
return;
|
||||
}
|
||||
var subMenu = $('ul', lastLi)[0] || $('<ul class="nav"></ul>').appendTo(lastLi);
|
||||
// console.log(subMenu);
|
||||
li.appendTo(subMenu);
|
||||
}
|
||||
items++;
|
||||
});
|
||||
// console.log(items, menu);
|
||||
// console.timeEnd('page nav');
|
||||
if (items < 2) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
function showTitleIfOverflows(element) {
|
||||
if (element &&
|
||||
element.innerText &&
|
||||
element.scrollWidth &&
|
||||
element.offsetWidth &&
|
||||
element.offsetWidth < element.scrollWidth) {
|
||||
element.setAttribute('title', element.innerText);
|
||||
}
|
||||
else if (element.removeAttribute) {
|
||||
element.removeAttribute('title');
|
||||
}
|
||||
}
|
||||
|
||||
function initDevPageNav() {
|
||||
window.hasDevPageNav = true;
|
||||
var menu = getDevPageNav();
|
||||
if (!menu) {
|
||||
return;
|
||||
}
|
||||
var sideNavCont = $('#dev_side_nav_cont');
|
||||
if (!sideNavCont.length) {
|
||||
sideNavCont = $('#dev_page_content_wrap');
|
||||
}
|
||||
var sideNavWrap = $('<div class="dev_side_nav_wrap"></div>').prependTo(sideNavCont);
|
||||
var sideNav = $('<div class="dev_side_nav"></div>').appendTo(sideNavWrap);
|
||||
menu.appendTo(sideNav);
|
||||
$('body').css({position: 'relative'}).scrollspy({ target: '.dev_side_nav' });
|
||||
|
||||
$('body').on('activate.bs.scrollspy', function () {
|
||||
$('.dev_side_nav > ul').affix('checkPosition');
|
||||
var active_el = $('.dev_side_nav li.active').get(-1);
|
||||
if (active_el) {
|
||||
if (active_el.scrollIntoViewIfNeeded) {
|
||||
active_el.scrollIntoViewIfNeeded();
|
||||
} else if (active_el.scrollIntoView) {
|
||||
active_el.scrollIntoView(false);
|
||||
}
|
||||
}
|
||||
});
|
||||
$('body').trigger('activate.bs.scrollspy');
|
||||
|
||||
updateMenuAffix(menu);
|
||||
}
|
||||
|
||||
function updateDevPageNav() {
|
||||
if (!window.hasDevPageNav) {
|
||||
return;
|
||||
}
|
||||
var menu = getDevPageNav() || $('<ul></ul>');
|
||||
$('.dev_side_nav > ul').replaceWith(menu);
|
||||
$('body').scrollspy('refresh');
|
||||
updateMenuAffix(menu);
|
||||
}
|
||||
|
||||
function updateMenuAffix(menu) {
|
||||
menu.affix({
|
||||
offset: {
|
||||
top: function () {
|
||||
return $('.dev_side_nav_wrap').offset().top;
|
||||
},
|
||||
bottom: function () {
|
||||
return (this.bottom = $('.footer_wrap').outerHeight(true) + 20)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function initScrollVideos(desktop) {
|
||||
var videos = document.querySelectorAll
|
||||
? document.querySelectorAll('video.tl_blog_vid_autoplay')
|
||||
: [];
|
||||
|
||||
window.pageVideos = Array.prototype.slice.apply(videos);
|
||||
if (!pageVideos.length) {
|
||||
return;
|
||||
}
|
||||
window.pageVideosPlaying = {};
|
||||
|
||||
var index = 1;
|
||||
var tgStickersCnt = document.querySelectorAll('.js-tgsticker_image').length;
|
||||
var preloadVideos = tgStickersCnt > 1 ? 0 : (tgStickersCnt ? 1 : 2);
|
||||
var isSafari = /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
|
||||
for (var i = 0; i < pageVideos.length; i++) {
|
||||
var videoEl = pageVideos[i];
|
||||
videoEl.setAttribute('vindex', index++);
|
||||
var preloadValue = i >= preloadVideos ? (isSafari ? 'none' : 'metadata') : 'auto';
|
||||
videoEl.setAttribute('preload', preloadValue);
|
||||
videoEl.preload = preloadValue;
|
||||
if (desktop) {
|
||||
videoEl.removeAttribute('controls');
|
||||
videoEl.autoplay = false;
|
||||
videoEl.removeAttribute('autoplay');
|
||||
} else {
|
||||
videoEl.autoplay = true;
|
||||
videoEl.playsinline = true;
|
||||
videoEl.setAttribute('autoplay', 'autoplay');
|
||||
videoEl.setAttribute('playsinline', 'playsinline');
|
||||
}
|
||||
var posterUrl = videoEl.poster;
|
||||
if (posterUrl && isSafari) {
|
||||
videoEl.parentNode.style.background = "url('" + escapeHTML(posterUrl) + "') center no-repeat";
|
||||
videoEl.parentNode.style.backgroundSize = "cover";
|
||||
videoEl.parentNode.style.lineHeight = "0";
|
||||
videoPreloadPosterDimensions(videoEl, posterUrl);
|
||||
}
|
||||
}
|
||||
if (!desktop) {
|
||||
return;
|
||||
}
|
||||
|
||||
window.addEventListener('scroll', checkScrollVideos, false);
|
||||
window.addEventListener('resize', checkScrollVideos, false);
|
||||
setTimeout(checkScrollVideos, 1000);
|
||||
}
|
||||
|
||||
function checkScrollVideos() {
|
||||
var w = window,
|
||||
d = document,
|
||||
e = d.documentElement,
|
||||
g = d.getElementsByTagName('body')[0],
|
||||
winWidth = w.innerWidth || e.clientWidth || g.clientWidth,
|
||||
winHeight = w.innerHeight|| e.clientHeight|| g.clientHeight,
|
||||
scrollTop = e.scrollTop || g.scrollTop || w.pageYOffset;
|
||||
|
||||
for (var i = 0; i < pageVideos.length; i++) {
|
||||
var videoEl = pageVideos[i];
|
||||
var curIndex = videoEl.getAttribute('vindex');
|
||||
var posY = getFullOffsetY(videoEl);
|
||||
var height = videoEl.offsetHeight;
|
||||
// console.log(scrollTop, winHeight, posY, height);
|
||||
|
||||
|
||||
if (isVisibleEnough(posY, height, scrollTop, winHeight, 0.7, 0.9)) {
|
||||
if (!pageVideosPlaying[curIndex]) {
|
||||
pageVideosPlaying[curIndex] = true;
|
||||
console.log('play', videoEl);
|
||||
videoEl.play();
|
||||
}
|
||||
} else {
|
||||
if (pageVideosPlaying[curIndex]) {
|
||||
delete pageVideosPlaying[curIndex];
|
||||
console.log('pause', videoEl);
|
||||
videoEl.pause();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function videoPreloadPosterDimensions(videoEl, posterUrl) {
|
||||
var img = new Image();
|
||||
img.onload = function () {
|
||||
if (img.width > 0 && img.height > 0) {
|
||||
videoEl.style.aspectRatio = img.width / img.height;
|
||||
}
|
||||
};
|
||||
img.src = posterUrl;
|
||||
}
|
||||
|
||||
function isVisibleEnough(boxOffset, boxSize, viewOffset, viewSize, boxThreshold, viewThreshold) {
|
||||
var boxEnd = boxOffset + boxSize;
|
||||
var viewEnd = viewOffset + viewSize;
|
||||
var viewBox = Math.min(viewEnd, boxEnd) - Math.max(boxOffset, viewOffset);
|
||||
if (viewBox < 0) {
|
||||
return false;
|
||||
}
|
||||
if (viewBox / boxSize > boxThreshold) {
|
||||
return true;
|
||||
}
|
||||
if (viewThreshold && viewBox / viewSize > viewThreshold) {
|
||||
return true;
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
function getFullOffsetY(el) {
|
||||
var offsetTop = el.offsetTop || 0;
|
||||
if (el.offsetParent) {
|
||||
offsetTop += getFullOffsetY(el.offsetParent);
|
||||
}
|
||||
return offsetTop;
|
||||
}
|
||||
|
||||
function redraw(el) {
|
||||
el.offsetTop + 1;
|
||||
}
|
||||
|
||||
function initRipple() {
|
||||
if (!document.querySelectorAll) return;
|
||||
var rippleTextFields = document.querySelectorAll('.textfield-item input.form-control');
|
||||
for (var i = 0; i < rippleTextFields.length; i++) {
|
||||
(function(rippleTextField) {
|
||||
function onTextRippleStart(e) {
|
||||
if (document.activeElement === rippleTextField) return;
|
||||
var rect = rippleTextField.getBoundingClientRect();
|
||||
if (e.type == 'touchstart') {
|
||||
var clientX = e.targetTouches[0].clientX;
|
||||
} else {
|
||||
var clientX = e.clientX;
|
||||
}
|
||||
var ripple = rippleTextField.parentNode.querySelector('.textfield-item-underline');
|
||||
var rippleX = (clientX - rect.left) / rippleTextField.offsetWidth * 100;
|
||||
ripple.style.transition = 'none';
|
||||
redraw(ripple);
|
||||
ripple.style.left = rippleX + '%';
|
||||
ripple.style.right = (100 - rippleX) + '%';
|
||||
redraw(ripple);
|
||||
ripple.style.left = '';
|
||||
ripple.style.right = '';
|
||||
ripple.style.transition = '';
|
||||
}
|
||||
rippleTextField.removeEventListener('mousedown', onTextRippleStart);
|
||||
rippleTextField.removeEventListener('touchstart', onTextRippleStart);
|
||||
rippleTextField.addEventListener('mousedown', onTextRippleStart);
|
||||
rippleTextField.addEventListener('touchstart', onTextRippleStart);
|
||||
})(rippleTextFields[i]);
|
||||
}
|
||||
var rippleHandlers = document.querySelectorAll('.ripple-handler');
|
||||
for (var i = 0; i < rippleHandlers.length; i++) {
|
||||
(function(rippleHandler) {
|
||||
function onRippleStart(e) {
|
||||
var rippleMask = rippleHandler.querySelector('.ripple-mask');
|
||||
if (!rippleMask) return;
|
||||
var rect = rippleMask.getBoundingClientRect();
|
||||
if (e.type == 'touchstart') {
|
||||
var clientX = e.targetTouches[0].clientX;
|
||||
var clientY = e.targetTouches[0].clientY;
|
||||
} else {
|
||||
var clientX = e.clientX;
|
||||
var clientY = e.clientY;
|
||||
}
|
||||
var rippleX = (clientX - rect.left) - rippleMask.offsetWidth / 2;
|
||||
var rippleY = (clientY - rect.top) - rippleMask.offsetHeight / 2;
|
||||
var ripple = rippleHandler.querySelector('.ripple');
|
||||
ripple.style.transition = 'none';
|
||||
redraw(ripple);
|
||||
ripple.style.transform = 'translate3d(' + rippleX + 'px, ' + rippleY + 'px, 0) scale3d(0.2, 0.2, 1)';
|
||||
ripple.style.opacity = 1;
|
||||
redraw(ripple);
|
||||
ripple.style.transform = 'translate3d(' + rippleX + 'px, ' + rippleY + 'px, 0) scale3d(1, 1, 1)';
|
||||
ripple.style.transition = '';
|
||||
|
||||
function onRippleEnd(e) {
|
||||
ripple.style.transitionDuration = '.2s';
|
||||
ripple.style.opacity = 0;
|
||||
document.removeEventListener('mouseup', onRippleEnd);
|
||||
document.removeEventListener('touchend', onRippleEnd);
|
||||
document.removeEventListener('touchcancel', onRippleEnd);
|
||||
}
|
||||
document.addEventListener('mouseup', onRippleEnd);
|
||||
document.addEventListener('touchend', onRippleEnd);
|
||||
document.addEventListener('touchcancel', onRippleEnd);
|
||||
}
|
||||
rippleHandler.removeEventListener('mousedown', onRippleStart);
|
||||
rippleHandler.removeEventListener('touchstart', onRippleStart);
|
||||
rippleHandler.addEventListener('mousedown', onRippleStart);
|
||||
rippleHandler.addEventListener('touchstart', onRippleStart);
|
||||
})(rippleHandlers[i]);
|
||||
}
|
||||
}
|
||||
|
||||
function mainInitRetinaVideos() {
|
||||
var videoEls = document.querySelectorAll('video.video__init_retina');
|
||||
var isRetina = window.devicePixelRatio >= 1.5;
|
||||
var videoEl, i, badChildren, j, badChild, sources, sourceEl;
|
||||
for (i = 0; i < videoEls.length; i++) {
|
||||
videoEl = videoEls[i];
|
||||
sources = (videoEl.getAttribute('data-sources')||'').split(',');
|
||||
sourceEl = document.createElement('source');
|
||||
sourceEl.type = 'video/mp4';
|
||||
sourceEl.src = sources[isRetina ? 1 : 0];
|
||||
videoEl.appendChild(sourceEl);
|
||||
videoEl.classList.remove('video__init_retina');
|
||||
videoEl.setAttribute('preload', 'auto');
|
||||
}
|
||||
}
|
||||
|
||||
function mainInitDemoAutoplay(videoLinkElsSelector) {
|
||||
var videoLinkEls = document.querySelectorAll(videoLinkElsSelector);
|
||||
var videoLinkEl, videoEl, i;
|
||||
for (i = 0; i < videoLinkEls.length; i++) {
|
||||
videoLinkEl = videoLinkEls[i];
|
||||
videoEl = videoLinkEl.querySelector('video');
|
||||
if (!videoEl) {
|
||||
continue;
|
||||
}
|
||||
if (videoEl.readyState > 1) {
|
||||
mainDemoVideoHover(videoLinkEl, 1);
|
||||
} else {
|
||||
videoEl.load();
|
||||
videoEl.addEventListener('loadeddata', (function(el) {
|
||||
return function () {
|
||||
setTimeout(function () {
|
||||
mainDemoVideoHover(el, 1);
|
||||
}, 0)
|
||||
}
|
||||
})(videoLinkEl), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function mainDemoVideoHover(videoLinkEl, isHover) {
|
||||
var outTimeout = videoLinkEl.outTimeout;
|
||||
var curIsHover = videoLinkEl.isHover || 0;
|
||||
if (outTimeout) {
|
||||
clearTimeout(outTimeout);
|
||||
}
|
||||
if (curIsHover == isHover) {
|
||||
return false;
|
||||
}
|
||||
if (!isHover) {
|
||||
outTimeout = setTimeout(function () {
|
||||
mainDemoVideoDoHover(videoLinkEl, isHover)
|
||||
}, 100);
|
||||
videoLinkEl.outTimeout = outTimeout;
|
||||
return false;
|
||||
}
|
||||
mainDemoVideoDoHover(videoLinkEl, isHover);
|
||||
}
|
||||
|
||||
function mainDemoVideoDoHover(videoLinkEl, isHover) {
|
||||
delete videoLinkEl.outTimeout;
|
||||
|
||||
var videoEl = videoLinkEl.querySelector('video');
|
||||
if (isHover) {
|
||||
if (videoEl.readyState > 1) {
|
||||
videoLinkEl.classList.add('video_play');
|
||||
videoEl.play();
|
||||
videoLinkEl.isHover = 1;
|
||||
}
|
||||
} else {
|
||||
videoLinkEl.isHover = 0;
|
||||
}
|
||||
if (!videoEl.inited) {
|
||||
videoEl.inited = true;
|
||||
// videoEl.onended =
|
||||
videoEl.addEventListener('ended', function onVideoEnded(e) {
|
||||
if (videoLinkEl.isHover) {
|
||||
videoEl.currentTime = 0;
|
||||
videoEl.play();
|
||||
} else {
|
||||
videoEl.pause();
|
||||
videoEl.currentTime = 0;
|
||||
videoLinkEl.classList.remove('video_play')
|
||||
}
|
||||
}, false);
|
||||
}
|
||||
}
|
||||
|
||||
function mainInitLogo(logo_url) {
|
||||
var img = new Image();
|
||||
img.onload = function() {
|
||||
var logo = document.querySelector('div.tl_main_logo');
|
||||
logo.style.backgroundImage = 'url(\'' + logo_url + '\')';
|
||||
logo.classList.add('play');
|
||||
};
|
||||
img.src = logo_url;
|
||||
}
|
||||
|
||||
function mainInitTgStickers(options) {
|
||||
options = options || {};
|
||||
if (!RLottie.isSupported) {
|
||||
if (options.unsupportedURL) {
|
||||
if (!getCookie('stel_notgs')) {
|
||||
setCookie('stel_notgs', 1, 7);
|
||||
}
|
||||
location = options.unsupportedURL;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
document.querySelectorAll('.js-tgsticker_image').forEach(function (imgEl) {
|
||||
RLottie.init(imgEl, options);
|
||||
});
|
||||
}
|
||||
|
||||
function setCookie(name, value, days) {
|
||||
var expires = '';
|
||||
if (days) {
|
||||
var date = new Date();
|
||||
date.setTime(date.getTime() + (days * 86400000));
|
||||
expires = "; expires=" + date.toUTCString();
|
||||
}
|
||||
document.cookie = name + "=" + (value || "") + expires + "; path=/";
|
||||
}
|
||||
|
||||
function getCookie(name) {
|
||||
var nameEQ = name + '=';
|
||||
var ca = document.cookie.split(';');
|
||||
for (var i = 0; i < ca.length; i++) {
|
||||
var c = ca[i];
|
||||
while (c.charAt(0) == ' ') {
|
||||
c = c.substr(1, c.length);
|
||||
}
|
||||
if (c.indexOf(nameEQ) == 0) {
|
||||
return c.substr(nameEQ.length, c.length);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function mainScrollTo(element) {
|
||||
if (typeof element === 'string') {
|
||||
element = document.querySelector(element)
|
||||
}
|
||||
if (element) {
|
||||
window.scroll(0, getFullOffsetY(element));
|
||||
}
|
||||
}
|
189
data/web/telegram.org/css/font-roboto.css
Normal file
189
data/web/telegram.org/css/font-roboto.css
Normal file
|
@ -0,0 +1,189 @@
|
|||
/* cyrillic-ext */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url('../fonts/Roboto/KFOmCnqEu92Fr1Mu72xKKTU1Kvnz.woff2') format('woff2');
|
||||
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
|
||||
}
|
||||
/* cyrillic */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url('../fonts/Roboto/KFOmCnqEu92Fr1Mu5mxKKTU1Kvnz.woff2') format('woff2');
|
||||
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||
}
|
||||
/* greek-ext */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url('../fonts/Roboto/KFOmCnqEu92Fr1Mu7mxKKTU1Kvnz.woff2') format('woff2');
|
||||
unicode-range: U+1F00-1FFF;
|
||||
}
|
||||
/* greek */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url('../fonts/Roboto/KFOmCnqEu92Fr1Mu4WxKKTU1Kvnz.woff2') format('woff2');
|
||||
unicode-range: U+0370-03FF;
|
||||
}
|
||||
/* vietnamese */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url('../fonts/Roboto/KFOmCnqEu92Fr1Mu7WxKKTU1Kvnz.woff2') format('woff2');
|
||||
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB;
|
||||
}
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url('../fonts/Roboto/KFOmCnqEu92Fr1Mu7GxKKTU1Kvnz.woff2') format('woff2');
|
||||
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: url('../fonts/Roboto/KFOmCnqEu92Fr1Mu4mxKKTU1Kg.woff2') format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
/* cyrillic-ext */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
font-display: swap;
|
||||
src: url('../fonts/Roboto/KFOlCnqEu92Fr1MmEU9fCRc4AMP6lbBP.woff2') format('woff2');
|
||||
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
|
||||
}
|
||||
/* cyrillic */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
font-display: swap;
|
||||
src: url('../fonts/Roboto/KFOlCnqEu92Fr1MmEU9fABc4AMP6lbBP.woff2') format('woff2');
|
||||
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||
}
|
||||
/* greek-ext */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
font-display: swap;
|
||||
src: url('../fonts/Roboto/KFOlCnqEu92Fr1MmEU9fCBc4AMP6lbBP.woff2') format('woff2');
|
||||
unicode-range: U+1F00-1FFF;
|
||||
}
|
||||
/* greek */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
font-display: swap;
|
||||
src: url('../fonts/Roboto/KFOlCnqEu92Fr1MmEU9fBxc4AMP6lbBP.woff2') format('woff2');
|
||||
unicode-range: U+0370-03FF;
|
||||
}
|
||||
/* vietnamese */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
font-display: swap;
|
||||
src: url('../fonts/Roboto/KFOlCnqEu92Fr1MmEU9fCxc4AMP6lbBP.woff2') format('woff2');
|
||||
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB;
|
||||
}
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
font-display: swap;
|
||||
src: url('../fonts/Roboto/KFOlCnqEu92Fr1MmEU9fChc4AMP6lbBP.woff2') format('woff2');
|
||||
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
font-display: swap;
|
||||
src: url('../fonts/Roboto/KFOlCnqEu92Fr1MmEU9fBBc4AMP6lQ.woff2') format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
/* cyrillic-ext */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-display: swap;
|
||||
src: url('../fonts/Roboto/KFOlCnqEu92Fr1MmWUlfCRc4AMP6lbBP.woff2') format('woff2');
|
||||
unicode-range: U+0460-052F, U+1C80-1C88, U+20B4, U+2DE0-2DFF, U+A640-A69F, U+FE2E-FE2F;
|
||||
}
|
||||
/* cyrillic */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-display: swap;
|
||||
src: url('../fonts/Roboto/KFOlCnqEu92Fr1MmWUlfABc4AMP6lbBP.woff2') format('woff2');
|
||||
unicode-range: U+0301, U+0400-045F, U+0490-0491, U+04B0-04B1, U+2116;
|
||||
}
|
||||
/* greek-ext */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-display: swap;
|
||||
src: url('../fonts/Roboto/KFOlCnqEu92Fr1MmWUlfCBc4AMP6lbBP.woff2') format('woff2');
|
||||
unicode-range: U+1F00-1FFF;
|
||||
}
|
||||
/* greek */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-display: swap;
|
||||
src: url('../fonts/Roboto/KFOlCnqEu92Fr1MmWUlfBxc4AMP6lbBP.woff2') format('woff2');
|
||||
unicode-range: U+0370-03FF;
|
||||
}
|
||||
/* vietnamese */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-display: swap;
|
||||
src: url('../fonts/Roboto/KFOlCnqEu92Fr1MmWUlfCxc4AMP6lbBP.woff2') format('woff2');
|
||||
unicode-range: U+0102-0103, U+0110-0111, U+0128-0129, U+0168-0169, U+01A0-01A1, U+01AF-01B0, U+1EA0-1EF9, U+20AB;
|
||||
}
|
||||
/* latin-ext */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-display: swap;
|
||||
src: url('../fonts/Roboto/KFOlCnqEu92Fr1MmWUlfChc4AMP6lbBP.woff2') format('woff2');
|
||||
unicode-range: U+0100-024F, U+0259, U+1E00-1EFF, U+2020, U+20A0-20AB, U+20AD-20CF, U+2113, U+2C60-2C7F, U+A720-A7FF;
|
||||
}
|
||||
/* latin */
|
||||
@font-face {
|
||||
font-family: 'Roboto';
|
||||
font-style: normal;
|
||||
font-weight: 700;
|
||||
font-display: swap;
|
||||
src: url('../fonts/Roboto/KFOlCnqEu92Fr1MmWUlfBBc4AMP6lQ.woff2') format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
|
@ -1,283 +0,0 @@
|
|||
<!DOCTYPE html>
|
||||
<html class="">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Telegram Messenger</title>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<meta property="og:title" content="Telegram – a new era of messaging">
|
||||
<meta property="og:image" content="https://telegram.org/img/t_logo.png">
|
||||
<meta property="og:site_name" content="Telegram">
|
||||
<meta property="og:description" content="Fast. Secure. Powerful.">
|
||||
|
||||
<meta property="fb:app_id" content="254098051407226">
|
||||
<meta property="vk:app_id" content="3782569">
|
||||
<meta name="apple-itunes-app" content="app-id=686449807">
|
||||
<meta name="telegram:channel" content="@telegram">
|
||||
|
||||
<link rel="icon" type="image/svg+xml" href="/img/website_icon.svg?4">
|
||||
<link rel="apple-touch-icon" sizes="180x180" href="/img/apple-touch-icon.png">
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/img/favicon-32x32.png">
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/img/favicon-16x16.png">
|
||||
<link rel="alternate icon" href="/img/favicon.ico" type="image/x-icon" />
|
||||
<link href="/css/bootstrap.min.css?3" rel="stylesheet">
|
||||
|
||||
<link href="/css/telegram.css?232" rel="stylesheet" media="screen">
|
||||
</head>
|
||||
<body class="preload">
|
||||
<div id="fb-root"></div>
|
||||
<div class="tl_page_wrap">
|
||||
<div class="tl_page_head navbar navbar-static-top navbar navbar-tg">
|
||||
<div class="navbar-inner">
|
||||
<div class="container clearfix">
|
||||
<ul class="nav navbar-nav navbar-right"><li class="dropdown top_lang_select"><a class="dropdown-toggle" onclick="return dropdownClick(this, event)" href="#"><i class="dev_top_lang_icon"></i>EN <b class="minicaret"></b></a>
|
||||
<ul class="dropdown-menu"><li class="chosen "><a href="?setln=en">English</a></li><li class="long "><a href="?setln=id">Bahasa Indonesia</a></li><li class="long "><a href="?setln=ms">Bahasa Melayu</a></li><li class=""><a href="?setln=de">Deutsch</a></li><li class=""><a href="?setln=es">Español</a></li><li class=""><a href="?setln=fr">Français</a></li><li class=""><a href="?setln=it">Italiano</a></li><li class=""><a href="?setln=nl">Nederlands</a></li><li class=""><a href="?setln=uz">O‘zbek</a></li><li class=""><a href="?setln=pl">Polski</a></li><li class="long "><a href="?setln=pt-br">Português (Brasil)</a></li><li class=""><a href="?setln=tr">Türkçe</a></li><li class=""><a href="?setln=be">Беларуская</a></li><li class=""><a href="?setln=ru">Русский</a></li><li class=""><a href="?setln=uk">Українська</a></li><li class=""><a href="?setln=ar">العربية</a></li><li class=""><a href="?setln=fa">فارسی</a></li><li class=""><a href="?setln=ko">한국어</a></li></ul></li><li class="navbar-twitter hidden-xs"><a href="https://twitter.com/telegram" target="_blank" data-track="Follow/Twitter" onclick="trackDlClick(this, event)"><i class="icon icon-twitter"></i> Twitter</a></li></ul>
|
||||
<ul class="nav navbar-nav">
|
||||
<li class=""><a href="/">Home</a></li>
|
||||
<li class=""><a href="/faq">FAQ</a></li>
|
||||
<li class=""><a href="/apps">Apps</a></li>
|
||||
<li class="hidden-xs "><a href="//core.telegram.org/api">API</a></li>
|
||||
<li class="hidden-xs "><a href="//core.telegram.org/mtproto">Protocol</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="container clearfix tl_page_container tl_main_page_container">
|
||||
<div class="tl_page">
|
||||
<div class="tl_main_wrap">
|
||||
<div class="tl_main_head">
|
||||
<div class="tl_main_side_blog"><div class="side_blog_wrap">
|
||||
<div class="side_blog">
|
||||
<a href="/blog" class="side_blog_header">Recent News</a>
|
||||
<div class="side_blog_entries">
|
||||
<a href="/blog/infinite-reactions-statuses" class="side_blog_entry">
|
||||
<div class="side_blog_date">Sep 16</div>
|
||||
<div class="side_blog_title">Infinite Reactions, Emoji Statuses and Much More</div>
|
||||
</a><a href="/blog/custom-emoji" class="side_blog_entry">
|
||||
<div class="side_blog_date">Aug 12</div>
|
||||
<div class="side_blog_title">Custom Animated Emoji, Gifting Telegram Premium, and More</div>
|
||||
</a><a href="/blog/700-million-and-premium" class="side_blog_entry">
|
||||
<div class="side_blog_date">Jun 21</div>
|
||||
<div class="side_blog_title">700 Million Users and Telegram Premium</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div></div>
|
||||
<div class="tl_main_logo_wrap">
|
||||
<a href="/" class="tl_main_logo">
|
||||
<div class="tl_main_logo"></div>
|
||||
<svg alt="Telegram" class="tl_main_logo_title_image" height="72" viewBox="0 0 288 72" width="288" xmlns="http://www.w3.org/2000/svg"><path d="m57.015 16.258c5.18 0 9.181 1.652 12.006 4.957 2.824 3.305 4.236 7.98 4.236 14.027v3.446h-24.855c.257 3.14 1.306 5.625 3.146 7.453s4.154 2.742 6.943 2.742c3.914 0 7.102-1.582 9.563-4.746l4.605 4.394c-1.523 2.274-3.556 4.037-6.099 5.291s-5.397 1.881-8.561 1.881c-5.414 0-9.803-1.705-13.166-5.115s-5.045-7.951-5.045-13.623v-1.055c0-3.797.733-7.189 2.198-10.178 1.464-2.988 3.521-5.314 6.169-6.978 2.649-1.664 5.602-2.496 8.86-2.496zm-15.827-12.445v7.171h-15.961v44.016h-8.825v-44.016h-15.82v-7.171zm15.792 19.3c-2.344 0-4.237.821-5.678 2.461-1.441 1.641-2.361 3.926-2.76 6.856h16.278v-.633c-.188-2.859-.95-5.022-2.286-6.486-1.336-1.465-3.187-2.198-5.554-2.198zm30.292 31.887h-8.543v-54h8.543zm24.051.703c-5.414 0-9.803-1.705-13.166-5.115-3.364-3.41-5.045-7.951-5.045-13.623v-1.055c0-3.797.732-7.189 2.197-10.178 1.465-2.988 3.521-5.314 6.17-6.978 2.648-1.664 5.601-2.496 8.859-2.496 5.18 0 9.182 1.652 12.006 4.957s4.236 7.98 4.236 14.027v3.446h-24.855c.258 3.14 1.307 5.625 3.146 7.453 1.84 1.828 4.155 2.742 6.944 2.742 3.914 0 7.101-1.582 9.562-4.746l4.606 4.394c-1.524 2.274-3.557 4.037-6.1 5.291s-5.396 1.881-8.56 1.881zm-1.02-32.59c-2.344 0-4.236.821-5.678 2.461-1.441 1.641-2.361 3.926-2.759 6.856h16.277v-.633c-.188-2.859-.949-5.022-2.285-6.486-1.336-1.465-3.188-2.198-5.555-2.198zm20.41 12.586c0-5.906 1.389-10.623 4.166-14.15 2.778-3.528 6.463-5.291 11.057-5.291 4.336 0 7.746 1.512 10.23 4.535l.387-3.832h7.699v36.879c0 4.992-1.552 8.93-4.658 11.812-3.105 2.883-7.295 4.325-12.568 4.325-2.789 0-5.514-.581-8.174-1.741s-4.682-2.677-6.065-4.552l4.043-5.133c2.625 3.117 5.86 4.676 9.704 4.676 2.836 0 5.074-.768 6.714-2.303 1.641-1.535 2.461-3.791 2.461-6.768v-2.566c-2.461 2.742-5.742 4.113-9.843 4.113-4.454 0-8.092-1.769-10.916-5.308-2.825-3.54-4.237-8.438-4.237-14.696zm8.508.739c0 3.82.779 6.826 2.338 9.017s3.721 3.287 6.486 3.287c3.446 0 6-1.476 7.664-4.429v-16.735c-1.617-2.883-4.148-4.324-7.593-4.324-2.813 0-4.998 1.113-6.557 3.34-1.559 2.226-2.338 5.508-2.338 9.844zm52.719-11.672c-1.125-.188-2.285-.282-3.481-.282-3.914 0-6.55 1.5-7.91 4.5v26.016h-8.543v-38.039h8.156l.211 4.254c2.063-3.305 4.922-4.957 8.579-4.957 1.218 0 2.226.164 3.023.492zm26.07 30.234c-.375-.727-.703-1.91-.984-3.551-2.719 2.836-6.047 4.254-9.985 4.254-3.82 0-6.937-1.09-9.351-3.269-2.414-2.18-3.621-4.875-3.621-8.086 0-4.055 1.506-7.166 4.517-9.334 3.012-2.168 7.319-3.252 12.92-3.252h5.239v-2.496c0-1.969-.551-3.545-1.653-4.729-1.101-1.183-2.777-1.775-5.027-1.775-1.945 0-3.539.486-4.781 1.459-1.243.972-1.864 2.209-1.864 3.709h-8.543c0-2.086.692-4.037 2.075-5.854 1.382-1.816 3.263-3.24 5.642-4.271 2.379-1.032 5.033-1.547 7.963-1.547 4.453 0 8.004 1.119 10.652 3.357 2.649 2.239 4.008 5.385 4.078 9.44v17.156c0 3.422.481 6.152 1.442 8.191v.598zm-9.387-6.152c1.688 0 3.276-.41 4.764-1.231 1.488-.82 2.608-1.922 3.358-3.304v-7.172h-4.606c-3.164 0-5.543.55-7.137 1.652-1.593 1.102-2.39 2.66-2.39 4.676 0 1.64.545 2.947 1.634 3.92 1.09.972 2.549 1.459 4.377 1.459zm32.645-31.887.246 3.973c2.672-3.118 6.328-4.676 10.969-4.676 5.086 0 8.566 1.945 10.441 5.836 2.766-3.891 6.656-5.836 11.672-5.836 4.195 0 7.318 1.16 9.369 3.48 2.051 2.321 3.1 5.742 3.147 10.266v24.996h-8.543v-24.75c0-2.414-.528-4.184-1.582-5.309-1.055-1.125-2.801-1.687-5.239-1.687-1.945 0-3.533.521-4.763 1.564-1.231 1.043-2.092 2.409-2.584 4.096l.035 26.086h-8.543v-25.031c-.117-4.477-2.402-6.715-6.856-6.715-3.421 0-5.847 1.394-7.277 4.184v27.562h-8.543v-38.039z" fill="#4d4d4d"/></svg>
|
||||
</a>
|
||||
<p class="tl_main_logo_lead">a new era of messaging</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tl_main_download_mobile clearfix">
|
||||
<a href="/android" class="tl_main_download_link tl_main_download_link_android" data-track="AppDownload/Android" onclick="trackDlClick(this, event)" onmouseover="mainDemoVideoHover(this, 1)" onmouseout="mainDemoVideoHover(this, 0)">
|
||||
<i class="icon icon-android "></i>Telegram for <b>Android</b>
|
||||
<div class="tl_main_download_image__android"></div>
|
||||
<video class="tl_main_video_player tl_main_video_player__android video__init_retina" muted="" vindex="1" preload="none" data-sources="/img/t_main_Android_demo.mp4,/img/t_main_Android_demo_2x.mp4"></video>
|
||||
</a><a href="/dl/ios" class="tl_main_download_link tl_main_download_link_ios" target="_blank" data-track="AppDownload/iOS" onclick="trackDlClick(this, event)" onmouseover="mainDemoVideoHover(this, 1)" onmouseout="mainDemoVideoHover(this, 0)">
|
||||
<i class="icon icon-ios "></i>Telegram for <b>iPhone</b> / <b>iPad</b>
|
||||
<div class="tl_main_download_image__ios"></div>
|
||||
<video class="tl_main_video_player tl_main_video_player__ios video__init_retina" muted="" vindex="1" preload="none" data-sources="/img/t_main_iOS_demo.mp4,/img/t_main_iOS_demo_2x.mp4"></video>
|
||||
</a>
|
||||
<a href="//desktop.telegram.org/" class="tl_main_download_link tl_main_download_link_tdesktop" data-track="AppDownload/TDesktop" onclick="trackDlClick(this, event)">
|
||||
Telegram for <b>Windows / Mac / Linux</b>
|
||||
</a>
|
||||
|
||||
<a class="tl_main_download_more_btn" href="/apps">Browse more Telegram apps<i class="icon icon-arrow-more"></i></a>
|
||||
</div>
|
||||
<div class="tl_main_download_desktop_section">
|
||||
<h3 class="tl_main_download_desktop_header"></h3>
|
||||
<div class="tl_main_download_desktop_wrap1">
|
||||
<div class="tl_main_download_desktop_wrap">
|
||||
<div class="tl_main_download_desktop clearfix">
|
||||
<div class="tl_main_download_desktop_links clearfix">
|
||||
<a href="//desktop.telegram.org/" class="tl_main_download_desktop_link tl_main_download_link_td" data-track="DesktopDownload/TDesktop" onclick="trackDlClick(this, event)">
|
||||
Telegram for <b>PC / Linux</b>
|
||||
</a><a href="//macos.telegram.org/" class="tl_main_download_desktop_link tl_main_download_link_osx" data-track="DesktopDownload/OSX" onclick="trackDlClick(this, event)">
|
||||
Telegram for <b>macOS</b>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tl_main_recent_news_wrap tl_blog_list_page_wrap">
|
||||
<h3 class="tl_main_recent_news_header">
|
||||
<a href="/blog">Recent News</a>
|
||||
</h3>
|
||||
<div class="tl_main_recent_news_cards clearfix">
|
||||
<a class="dev_blog_card_link_wrap" href="/blog/infinite-reactions-statuses"><div class="dev_blog_card_wrap">
|
||||
<img class="dev_blog_card_image" src="https://telegram.org/file/464001851/10bd6/sDwj4p_0m-0.293264/66eebb00fd46acb1ce" />
|
||||
<div class="dev_blog_card_alltext_wrap">
|
||||
<h4 class="dev_blog_card_title">Infinite Reactions, Emoji Statuses and Much More</h4>
|
||||
<div class="dev_blog_card_lead">Telegram's previous update revolutionized emoji, adding an open platform for creating custom animated emoji. This update gives you even…</div>
|
||||
</div>
|
||||
<div class="dev_blog_card_date">Sep 16, 2022</div>
|
||||
</div></a><a class="dev_blog_card_link_wrap" href="/blog/custom-emoji"><div class="dev_blog_card_wrap">
|
||||
<img class="dev_blog_card_image" src="https://telegram.org/file/464001738/111e0/RVvmuGtCK0A.285280/6148669b1197e199ff" />
|
||||
<div class="dev_blog_card_alltext_wrap">
|
||||
<h4 class="dev_blog_card_title">Telegram Emoji Platform, Custom Animated Emoji Packs, Gifting Telegram Premium, and More</h4>
|
||||
<div class="dev_blog_card_lead">Today's update introduces the Telegram Emoji Platform, animated emoji in messages and captions…</div>
|
||||
</div>
|
||||
<div class="dev_blog_card_date">Aug 12, 2022</div>
|
||||
</div></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tl_main_body tl_main_cards_animated_wrap">
|
||||
<a name="what-can-you-do-with-Telegram"></a>
|
||||
<h3 class="tl_main_body_header">Why Telegram?</h3>
|
||||
|
||||
<div class="tl_main_cards">
|
||||
<div class="tl_main_card_cell">
|
||||
<div class="tl_main_card_wrap">
|
||||
<picture class="dev_page_tgsticker tl_main_card_animated js-tgsticker_image"><div></div><source type="application/x-tgsticker" srcset="/file/464001484/1/bzi7gr7XRGU.10147/815df2ef527132dd23"><img src="/file/464001897/3/f0Go0rLpEwk.11343.png/dd4eeb46cc5efc0688" /></picture>
|
||||
<h3 class="tl_main_card_header">Simple</h3>
|
||||
<div class="tl_main_card_lead"><b>Telegram</b> is so simple you already know how to use it.</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tl_main_card_cell">
|
||||
<div class="tl_main_card_wrap">
|
||||
<picture class="dev_page_tgsticker tl_main_card_animated js-tgsticker_image"><div></div><source type="application/x-tgsticker" srcset="/file/464001418/1/fabnJFzygPY.17422/bc9dec9fd8bd26e00e"><img src="/file/464001737/4/Fn57W9l3xI0.15286.png/d4b936ecc2c939f4fa" /></picture>
|
||||
<h3 class="tl_main_card_header">Private</h3>
|
||||
<div class="tl_main_card_lead"><b>Telegram</b> messages are heavily encrypted and can self-destruct.</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tl_main_card_cell">
|
||||
<div class="tl_main_card_wrap">
|
||||
<picture class="dev_page_tgsticker tl_main_card_animated js-tgsticker_image"><div></div><source type="application/x-tgsticker" srcset="/file/464001560/1/zLlKYgeDLoA.14496/62085b07461f2d87e4"><img src="/file/464001560/2/n7EACfx4FPY.16465.png/7318c11715aa2ec45b" /></picture>
|
||||
<h3 class="tl_main_card_header">Synced</h3>
|
||||
<div class="tl_main_card_lead"><b>Telegram</b> lets you access your chats from multiple devices.</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tl_main_card_cell">
|
||||
<div class="tl_main_card_wrap">
|
||||
<picture class="dev_page_tgsticker tl_main_card_animated js-tgsticker_image"><div></div><source type="application/x-tgsticker" srcset="/file/464001493/2/hV6uPcaHk_E.17388/dcccb066a7b4fe44ee"><img src="/file/464001132/3/-1qvqKPZsQQ.17975.png/7d57d7159cf4fbe9b2" /></picture>
|
||||
<h3 class="tl_main_card_header">Fast</h3>
|
||||
<div class="tl_main_card_lead"><b>Telegram</b> delivers messages faster than any other application.</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tl_main_card_cell">
|
||||
<div class="tl_main_card_wrap">
|
||||
<picture class="dev_page_tgsticker tl_main_card_animated js-tgsticker_image"><div></div><source type="application/x-tgsticker" srcset="/file/464001803/1/cnqy4KrA5bE.12755/b97780ca9da88b4f84"><img src="/file/464001871/3/Uyg3R7LmX1I.17628.png/911807f65dfb4f8f20" /></picture>
|
||||
<h3 class="tl_main_card_header">Powerful</h3>
|
||||
<div class="tl_main_card_lead"><b>Telegram</b> has no limits on the size of your media and chats.</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tl_main_card_cell">
|
||||
<div class="tl_main_card_wrap">
|
||||
<picture class="dev_page_tgsticker tl_main_card_animated js-tgsticker_image"><div></div><source type="application/x-tgsticker" srcset="/file/464001880/2/VGTLBN3QuYM.10959/8940838e7dddc787d8"><img src="/file/464001880/3/xOpm7ohoHQ0.12690.png/feb1e161b1d3608613" /></picture>
|
||||
<h3 class="tl_main_card_header">Open</h3>
|
||||
<div class="tl_main_card_lead"><b>Telegram</b> has an open <a href="https://core.telegram.org/api">API</a> and source code free for everyone.</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tl_main_card_cell">
|
||||
<div class="tl_main_card_wrap">
|
||||
<picture class="dev_page_tgsticker tl_main_card_animated js-tgsticker_image"><div></div><source type="application/x-tgsticker" srcset="/file/464001453/2/eW_MzRhUGoM.10926/fe1f3bc3dd08367c0a"><img src="/file/464001453/3/mNzXWC3RX0c.15740.png/9ce5fa5f3fb74460b4" /></picture>
|
||||
<h3 class="tl_main_card_header">Secure</h3>
|
||||
<div class="tl_main_card_lead"><b>Telegram</b> keeps your messages safe from hacker attacks.</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tl_main_card_cell">
|
||||
<div class="tl_main_card_wrap">
|
||||
<picture class="dev_page_tgsticker tl_main_card_animated js-tgsticker_image"><div></div><source type="application/x-tgsticker" srcset="/file/464001812/2/kLAK2TPyvUU.12545/f68c1caf735a2ea3db"><img src="/file/464001402/5/eOMSj3GzJXo.13579.png/f3cec6c451d023c109" /></picture>
|
||||
<h3 class="tl_main_card_header">Social</h3>
|
||||
<div class="tl_main_card_lead"><b>Telegram</b> groups can hold up to 200,000 members.</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="tl_main_card_cell">
|
||||
<div class="tl_main_card_wrap">
|
||||
<picture class="dev_page_tgsticker tl_main_card_animated js-tgsticker_image"><div></div><source type="application/x-tgsticker" srcset="/file/464001166/1/01aTJ2ISKeU.21801/24028c7b6d07639794"><img src="/file/464001166/2/FzTl8_M5mQA.19325.png/b6c5dbc0e4f6553805" /></picture>
|
||||
<h3 class="tl_main_card_header">Expressive</h3>
|
||||
<div class="tl_main_card_lead"><b>Telegram</b> lets you completely customize your messenger.</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="tl_main_noshare clearfix"></div>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer_wrap">
|
||||
<div class="footer_columns_wrap footer_desktop">
|
||||
<div class="footer_column footer_column_telegram">
|
||||
<h5>Telegram</h5>
|
||||
<div class="footer_telegram_description"></div>
|
||||
Telegram is a cloud-based mobile and desktop messaging app with a focus on security and speed.
|
||||
</div>
|
||||
|
||||
<div class="footer_column">
|
||||
<h5><a href="/faq">About</a></h5>
|
||||
<ul>
|
||||
<li><a href="/faq">FAQ</a></li>
|
||||
<li><a href="/privacy">Privacy</a></li>
|
||||
<li><a href="/press">Press</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer_column">
|
||||
<h5><a href="/apps#mobile-apps">Mobile Apps</a></h5>
|
||||
<ul>
|
||||
<li><a href="/dl/ios">iPhone/iPad</a></li>
|
||||
<li><a href="/android">Android</a></li>
|
||||
<li><a href="/dl/web">Mobile Web</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer_column">
|
||||
<h5><a href="/apps#desktop-apps">Desktop Apps</a></h5>
|
||||
<ul>
|
||||
<li><a href="//desktop.telegram.org/">PC/Mac/Linux</a></li>
|
||||
<li><a href="//macos.telegram.org/">macOS</a></li>
|
||||
<li><a href="/dl/web">Web-browser</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="footer_column footer_column_platform">
|
||||
<h5><a href="//core.telegram.org/">Platform</a></h5>
|
||||
<ul>
|
||||
<li><a href="//core.telegram.org/api">API</a></li>
|
||||
<li><a href="//translations.telegram.org/">Translations</a></li>
|
||||
<li><a href="//instantview.telegram.org/">Instant View</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer_columns_wrap footer_mobile">
|
||||
<div class="footer_column">
|
||||
<h5><a href="/faq">About</a></h5>
|
||||
</div>
|
||||
<div class="footer_column">
|
||||
<h5><a href="/blog">Blog</a></h5>
|
||||
</div>
|
||||
<div class="footer_column">
|
||||
<h5><a href="/apps">Apps</a></h5>
|
||||
</div>
|
||||
<div class="footer_column">
|
||||
<h5><a href="//core.telegram.org/">Platform</a></h5>
|
||||
</div>
|
||||
<div class="footer_column">
|
||||
<h5><a href="https://twitter.com/telegram" target="_blank" data-track="Follow/Twitter" onclick="trackDlClick(this, event)">Twitter</a></h5>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="/js/main.js?46"></script>
|
||||
<script src="/js/tgsticker.js?29"></script>
|
||||
|
||||
<script>mainInitRetinaVideos();
|
||||
mainInitLogo("\/img\/t_logo_sprite.svg");
|
||||
mainInitTgStickers({"maxDeviceRatio":2,"cachingModulo":3,"unsupportedURL":"\/?notgs=1"});
|
||||
backToTopInit("Go up");
|
||||
removePreloadInit();
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
3274
data/web/themes.telegram.org/css/bootstrap-extra.css
vendored
3274
data/web/themes.telegram.org/css/bootstrap-extra.css
vendored
File diff suppressed because it is too large
Load diff
File diff suppressed because one or more lines are too long
11
data/web/themes.telegram.org/js/bootstrap.min.js
vendored
11
data/web/themes.telegram.org/js/bootstrap.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load diff
3274
data/web/tsf.telegram.org/css/bootstrap-extra.css
vendored
3274
data/web/tsf.telegram.org/css/bootstrap-extra.css
vendored
File diff suppressed because it is too large
Load diff
10
data/web/tsf.telegram.org/css/bootstrap.min.css
vendored
10
data/web/tsf.telegram.org/css/bootstrap.min.css
vendored
File diff suppressed because one or more lines are too long
11
data/web/tsf.telegram.org/js/bootstrap.min.js
vendored
11
data/web/tsf.telegram.org/js/bootstrap.min.js
vendored
File diff suppressed because one or more lines are too long
4
data/web/tsf.telegram.org/js/jquery.min.js
vendored
4
data/web/tsf.telegram.org/js/jquery.min.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue