diff --git a/data/core.telegram.org/api/end-to-end/video-calls.html b/data/core.telegram.org/api/end-to-end/video-calls.html deleted file mode 100644 index e97359be3c..0000000000 --- a/data/core.telegram.org/api/end-to-end/video-calls.html +++ /dev/null @@ -1,215 +0,0 @@ - - -
- -This article describes the end-to-end encryption used for Telegram voice and video calls.
-Before a call is ready, some preliminary actions have to be performed. The calling party needs to contact the party to be called and check whether it is ready to accept the call. Besides that, the parties have to negotiate the protocols to be used, learn the IP addresses of each other or of the Telegram relay servers to be used (so-called reflectors), and generate a one-time encryption key for this voice call with the aid of Diffie--Hellman key exchange. All of this is accomplished in parallel with the aid of several Telegram API methods and related notifications. This document covers details related to key generation, encryption and security.
-The Diffie-Hellman key exchange, as well as the whole protocol used to create a new voice call, is quite similar to the one used for Secret Chats. We recommend studying the linked article before proceeding.
-However, we have introduced some important changes to facilitate the key verification process. Below is the entire exchange between the two communicating parties, the Caller (A) and the Callee (B), through the Telegram servers (S).
-g_a_hash:bytes
, among others. For this call, this field is to be filled with g_a_hash, not g_a itself.g_a:bytes
and key_fingerprint:long
.key_fingerprint:long
received from the other side, as an implementation sanity check.At this point, the Diffie--Hellman key exchange is complete, and both parties have a 256-byte shared secret key key which is used to encrypt all further exchanges between A and B.
-It is of paramount importance to accept each update only once for each instance of the key generation protocol, discarding any duplicates or alternative versions of already received and processed messages (updates).
---This document describes encryption in voice and video calls as implemented in Telegram apps with versions 7.0 and above. See this document for details on encryption used in voice calls in app versions released before August 14, 2020.
-
The Telegram Voice and Video Call Library uses an optimized version of MTProto 2.0 to send and receive packets, consisting of one or more end-to-end encrypted messages of various types (ice candidates list, video formats, remote video status, audio stream data, video stream data, message ack or empty).
-This document describes only the encryption process, leaving out encoding and network-dependent parts.
-The library starts working with:
-key
shared between the parties, as generated above.Both data transfer channels are unreliable (messages may get lost), but signaling is slower and more reliable.
-The body of a packet (decrypted_body
) consists of several messages and their respective seq
numbers concatenated together.
Each decrypted_body
is unique because no two seq
numbers of the first message can be the same. If only old messages need to be re-sent, an empty message with new unique seq
is added to the packet first.
The encryption key key
is used to compute a 128-bit msg_key
and then a 256-bit aes_key
and a 128-bit aes_iv
:
x
depends on whether the call is outgoing or incoming and on the connection type:
This allows apps to decide which packet types will be sent to which connections and work in these connections independently (with each having its own seq
counter).
The resulting aes_key
and aes_iv
are used to encrypt decrypted_body
:
The packet that gets sent consists of msg_key
and encrypted_body
:
When received, the packet gets decrypted using key
and msg_key
, after which msg_key
is checked against the relevant SHA256
substring. If the check fails, the packet must be discarded.
Each of the peers maintains its own 32-bit monotonically increasing counter for outgoing messages, seq
, starting with 1
. This seq
counter is prepended to each sent message and increased by 1
for each new message. No two seq
numbers of the first message in a packet can be the same. If only old messages need to be re-sent, an empty message with a new unique seq
is added to the packet first. When the seq
counter reaches 2^30
, the call must be aborted. Each peer stores seq
values of all the messages it has received (and processed) which are larger than max_received_seq - 64
, where max_received_seq
is the largest seq
number received so far.
If a packet is received, the first message of which has a seq
that is smaller or equal to max_received_seq - 64
or its seq
had already been received, the message is discarded. Otherwise, the seq
values of all incoming messages are memorized and max_received_seq
is adjusted. This guarantees that no two packets will be processed twice.
To verify the key, and ensure that no MITM attack is taking place, both parties concatenate the secret key key with the value g_a of the Caller ( A ), compute SHA256 and use it to generate a sequence of emoticons. More precisely, the SHA256 hash is split into four 64-bit integers; each of them is divided by the total number of emoticons used (currently 333), and the remainder is used to select specific emoticons. The specifics of the protocol guarantee that comparing four emoticons out of a set of 333 is sufficient to prevent eavesdropping (MiTM attack on DH) with a probability of 0.9999999999.
-This is because instead of the standard Diffie-Hellman key exchange which requires only two messages between the parties:
-we use a three-message modification thereof that works well when both parties are online (which also happens to be a requirement for voice calls):
-The idea here is that A commits to a specific value of a (and of g_a) without disclosing it to B. B has to choose its value of b and g_b without knowing the true value of g_a, so that it cannot try different values of b to force the final key (g_a)^b to have any specific properties (such as fixed lower 32 bits of SHA256(key)). At this point, B commits to a specific value of g_b without knowing g_a. Then A has to send its value g_a; it cannot change it even though it knows g_b now, because the other party B would accept only a value of g_a that has a hash specified in the very first message of the exchange.
-If some impostor is pretending to be either A or B and tries to perform a Man-in-the-Middle Attack on this Diffie--Hellman key exchange, the above still holds. Party A will generate a shared key with B -- or whoever pretends to be B -- without having a second chance to change its exponent a depending on the value g_b received from the other side; and the impostor will not have a chance to adapt his value of b depending on g_a, because it has to commit to a value of g_b before learning g_a. The same is valid for the key generation between the impostor and the party B.
-The use of hash commitment in the DH exchange constrains the attacker to only one guess to generate the correct visualization in their attack, which means that using just over 33 bits of entropy represented by four emoji in the visualization is enough to make a successful attack highly improbable.
--For a slightly more user-friendly explanation of the above see: How are calls authenticated?
-
--This article is about Perfect Forward Secrecy in cloud chats, see also PFS in Secret Chats.
-
Telegram supports Perfect Forward Secrecy (PFS).
-To make this possible, the client generates a permanent authorization key using p_q_inner_data and a temporary key using p_q_inner_data_temp. (See Creating an Authorization Key for more info.) These 2 operations may be done in parallel and even using the same connection. The client must save an expires_at unix timestamp expires_at = time + expires_in
.
Important: in order to achieve PFS, the client must never use the permanent auth_key_id directly. Every message that is sent to MTProto, must be encrypted by a temp_auth_key_id, that was bound to the perm_auth_key_id.
-An unbound temp_auth_key_id may only be used with the following methods:
- -In order to bind a temporary authorization key to the permanent key the client creates a special binding message and executes the auth.bindTempAuthKey method using temp_auth_key. Once auth.bindTempAuthKey has been executed successfully, the client may signUp / signIn using other auth.* methods and continue using the API as usual; the client must also rewrite client info using initConnection after each binding. Each permanent key may only be bound to one temporary key at a time, binding a new temporary key overwrites the previous one.
-Once the temporary key expires, the client needs to generate a new temporary key using p_q_inner_data_temp. Then it needs to re-bind that new temporary key to the initial permanent key. A new key can also be generated in advance, so that the client has a new key ready by the time the old one has expired.
-For additional security, the client can store the temporary authorization key in RAM only and never save it in persistent storage.
-A temporary authorization key may expire at any moment before expires_at, since such keys are also stored only in the RAM on the server-side. Be prepared to handle resulting MTProto errors correctly (non-existent auth_key_id results in a 404 error).
Telegram allows scheduling messages.
-message#58ae39c9 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true post:flags.14?true from_scheduled:flags.18?true legacy:flags.19?true edit_hide:flags.21?true pinned:flags.24?true id:int from_id:flags.8?Peer peer_id:Peer fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?int reply_to:flags.3?MessageReplyHeader date:int message:string media:flags.9?MessageMedia reply_markup:flags.6?ReplyMarkup entities:flags.7?Vector<MessageEntity> views:flags.10?int forwards:flags.10?int replies:flags.23?MessageReplies edit_date:flags.15?int post_author:flags.16?string grouped_id:flags.17?long restriction_reason:flags.22?Vector<RestrictionReason> = Message;
-
-updateNewScheduledMessage#39a51dfb message:Message = Update;
-updateDeleteScheduledMessages#90866cee peer:Peer messages:Vector<int> = Update;
-
----functions---
-
-messages.sendMessage#520c3870 flags:# no_webpage:flags.1?true silent:flags.5?true background:flags.6?true clear_draft:flags.7?true peer:InputPeer reply_to_msg_id:flags.0?int message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.10?int = Updates;
-
-messages.sendMedia#3491eba9 flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true peer:InputPeer reply_to_msg_id:flags.0?int media:InputMedia message:string random_id:long reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.10?int = Updates;
-To schedule a message, simply provide a future unixtime in the schedule_date
flag of messages.sendMessage or messages.sendMedia.
The specified message or media will be added to a server-side schedule queue for the current chat, and will be automatically sent at the specified time.
-The method call generates the following updates:
schedule_date
, an updateNewMessage or updateNewChannelMessage with the from_scheduled
flag set, indicating to the sender that the specified scheduled message was sent. schedule_date
, an updateDeleteScheduledMessages, indicating that the message was flushed from the schedule queue.If the schedule_date
is less than 10 seconds in the future, the message will be sent immediately, generating a normal updateNewMessage/updateNewChannelMessage .
updateNewScheduledMessage#39a51dfb message:Message = Update;
-updateDeleteScheduledMessages#90866cee peer:Peer messages:Vector<int> = Update;
-
----functions---
-
-messages.getScheduledHistory#e2c2685b peer:InputPeer hash:int = messages.Messages;
-messages.getScheduledMessages#bdbb0464 peer:InputPeer id:Vector<int> = messages.Messages;
-messages.sendScheduledMessages#bd38850a peer:InputPeer id:Vector<int> = Updates;
-messages.deleteScheduledMessages#59ae2b16 peer:InputPeer id:Vector<int> = Updates;
-
-messages.editMessage#48f71778 flags:# no_webpage:flags.1?true peer:InputPeer id:int message:flags.11?string media:flags.14?InputMedia reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.15?int = Updates;
-Clients can manually edit the schedule queue of a certain chat, providing the scheduled message ID obtained from updateNewScheduledMessage.
-Modifying scheduled messages will generate an updateNewScheduledMessage with the same ID, and updated information.
-Deleting scheduled messages will generate an updateDeleteScheduledMessages.
Telegram allows applying detailed message filters while looking for messages in chats.
-inputMessagesFilterEmpty#57e2f66c = MessagesFilter;
-inputMessagesFilterPhotos#9609a51c = MessagesFilter;
-inputMessagesFilterVideo#9fc00e65 = MessagesFilter;
-inputMessagesFilterPhotoVideo#56e9f0e4 = MessagesFilter;
-inputMessagesFilterDocument#9eddf188 = MessagesFilter;
-inputMessagesFilterUrl#7ef0dd87 = MessagesFilter;
-inputMessagesFilterGif#ffc86587 = MessagesFilter;
-inputMessagesFilterVoice#50f5c392 = MessagesFilter;
-inputMessagesFilterMusic#3751b49e = MessagesFilter;
-inputMessagesFilterChatPhotos#3a20ecb8 = MessagesFilter;
-inputMessagesFilterPhoneCalls#80c99768 flags:# missed:flags.0?true = MessagesFilter;
-inputMessagesFilterRoundVoice#7a7c17a4 = MessagesFilter;
-inputMessagesFilterRoundVideo#b549da53 = MessagesFilter;
-inputMessagesFilterMyMentions#c1f8e69a = MessagesFilter;
-inputMessagesFilterGeo#e7026d0d = MessagesFilter;
-inputMessagesFilterContacts#e062db83 = MessagesFilter;
-inputMessagesFilterPinned#1bb00451 = MessagesFilter;
-
-messages.messages#8c718e87 messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
-messages.messagesSlice#3a54685e flags:# inexact:flags.1?true count:int next_rate:flags.0?int offset_id_offset:flags.2?int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
-messages.channelMessages#64479808 flags:# inexact:flags.1?true pts:int count:int offset_id_offset:flags.2?int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
-messages.messagesNotModified#74535f21 count:int = messages.Messages;
-
----functions---
-
-messages.search#c352eec flags:# peer:InputPeer q:string from_id:flags.0?InputPeer top_msg_id:flags.1?int filter:MessagesFilter min_date:int max_date:int offset_id:int add_offset:int limit:int max_id:int min_id:int hash:int = messages.Messages;
-
-messages.searchGlobal#4bc6589a flags:# folder_id:flags.0?int q:string filter:MessagesFilter min_date:int max_date:int offset_rate:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages;
-When using messages.search or messages.searchGlobal, a certain message filter may be applied.
-This allows the server to filter messages based on a text query, and even on their type, and this feature is often used by graphical clients to implement features like the chat gallery, chat profile pictures and more.
-Available filters:
The returned messages.Messages constructors contain parameters for pagination, the messages themselves and two offset_id_offset
/count
parameters that can be used to display a progress/total
counter like photo 134 of 200
.
-For example, when displaying the chat photo gallery, we could display a photo ${offset_id_offset} of ${count}
indicator on top.
messages.searchCounter#e844ebff flags:# inexact:flags.1?true filter:MessagesFilter count:int = messages.SearchCounter;
-
----functions---
-
-messages.getSearchCounters#732eef00 peer:InputPeer filters:Vector<MessagesFilter> = Vector<messages.SearchCounter>;
-Chat counters with filters can also be returned without fetching the actual messages, as seen in the scheme above.
Bots may ask users to login to a certain website via Telegram when clicking on certain URL buttons in inline keyboards.
-When the user clicks on keyboardButtonUrlAuth, messages.requestUrlAuth should be called, providing the button_id
of the button and the ID and peer of the container message.
-The returned urlAuthResultRequest object will contain more details about the authorization request:
domain
parameter will contain the domain name of the website on which the user will log in (example: comments.app).bot
parameter will contain info about the bot which will be used for user authorization (example: DiscussBot).request_write_access
will be set if the bot would like to send messages to the user.The info should be shown in a prompt:
- -If the user agrees to login to the URL, messages.acceptUrlAuth should be called (eventually setting the write_allowed
if the permission was requested and the user consented).
-The result will be a urlAuthResultAccepted with the final URL to open, which will include a query string with the requested info and a hash that must be verified upon receival by the service.
urlAuthResultDefault could also be returned, instead, in which case the url
of the keyboardButtonUrlAuth must be opened, instead.
-The same must be done if the user opens the link while refusing the authorization request.
Beyond sending commands in private messages or groups, users can interact with your bot via inline queries. If inline queries are enabled, users can call your bot by typing its username and a query in the text input field in any chat. The query is sent to your bot in an update. This way, people can request content from your bot in any of their chats, groups, or channels without sending any messages at all.
- - - -To enable this option, send the /setinline
command to @BotFather and provide the placeholder text that the user will see in the input field after typing your bot’s name.
--See the Bot API Manual for the relevant methods and objects.
-
Inline bots support all types of content available in Telegram (20 in all). They are capable of sending stickers, videos, music, locations, documents and more.
- - -Clients can display the results with vertical or horizontal scrolling, depending on the type of content:
- - -As soon as the user taps on an item, it's immediately sent to the recipient, and the input field is cleared.
-Some inline bots can benefit from an initial setup process, like connecting them to an account on an external service (e.g., YouTube). We've added an easy way of switching between the private chat with a bot and whatever chat the user wants to share inline results in.
- - -You can display a special ‘Switch to PM’ button above the inline results (or instead of them). This button will open a private chat with the bot and pass a parameter of your choosing, so that you can prompt the user for the relevant setup actions. Once done, you can use an inline keyboard with a switch_inline_query button to send the user back to the original chat.
-Sample bots
@youtube – Shows a ‘Sign in to YouTube’ button, then suggests personalized results.
- --
Inline bots can request location data from their users. Use the /setinlinegeo
command with @BotFather to enable this. Your bot will ask the user for permission to access their location whenever they send an inline request.
Sample bot
@foursquare – This bot will ask for permission to access the user's location, then provide geo-targeted results.
Messages sent with the help of your bot will show its username next to the sender's name.
- - -When a user taps on the bot username in the message header, the mention is automatically inserted into the input field. Entering the @
symbol in the input field brings up a list of suggestions, featuring recently used inline bots.
To know which of the provided results your users are sending to their chat partners, send @Botfather the /setinlinefeedback
command. With this enabled, you will receive updates on the results chosen by your users.
Please note that this can create load issues for popular bots – you may receive more results than actual requests due to caching (see the cache_time parameter in answerInlineQuery). For these cases, we recommend adjusting the probability setting to receive 1/10, 1/100 or 1/1000 of the results.
-Here are some sample inline bots, in case you’re curious to see one in action. Try any of these:
@gif – GIF search
@vid – Video search
@pic – Yandex image search
@bing – Bing image search
@wiki – Wikipedia search
@imdb – IMDB search
@bold – Make bold, italic or fixed sys text
NEW
@youtube - Connect your account for personalized results
@music - Search and send classical music
@foursquare – Find and send venue addresses
@sticker – Find and send stickers based on emoji
We currently support two ways of processing bot updates, getUpdates and setWebhook. getUpdates is a pull mechanism, setwebhook is push. Although the concept of a webhook is fairly simple, the setup of the individual components has proven to be tricky for many. This guide provides some extra information for those of you brave enough to venture into the art of the webhook.
-There are some advantages of using a webhook over getUpdates. As soon as an update arrives, we’ll kindly deliver it to your bot for processing.
-This:
-1. Avoids your bot having to ask for updates frequently.
-2. Avoids the need for some kind of polling mechanism in your code.
-Other advantages may include saving some potential CPU cycles and an increase in response time, these things however depend heavily on the usage pattern of your bot.
-Setting a webhook means you supplying Telegram with a location in the form of a URL, on which your bot listens for updates. We need to be able to connect and post updates to that URL.
-To ensure that we can do that, there are some basic requirements:
-You'll need a server that:
-149.154.160.0/20
and 91.108.4.0/22
on port 443, 80, 88, or 8443. That’s almost all there’s to it.
If you decide to limit traffic to our specific range of addresses, keep an eye on this document whenever you seem to run into trouble. Our IP-range might change in the future.
Setting a webhook needs a URL for us to post to. For that you'll need a server with a domain name. If you don't have one, you'll need to obtain one first. Telegram currently doesn't offer hosting or domain name services. There are quite a few VPS/Web hosting providers around the internet, feel free to pick one to your liking.
If you're using a self-signed certificate, you may use the IP as a CN, instead of the domain name.
How do I get a server with a domain name?
A webhook needs an open port on your server. We currently support the following ports: 443, 80, 88 and 8443. Other ports are not supported and will not work. Make sure your bot is running on one of those supported ports, and that the bot is reachable via its public address.
-If you want to limit access to Telegram only, please allow traffic from 149.154.167.197-233 (starting July 2019 please use: 149.154.160.0/20 and 91.108.4.0/22).
-Whenever something stops working in the future, please check this document again as
-the range might expand or change.
-
-A webhook requires SSL/TLS encryption, no matter which port is used. It's not possible to use a plain-text HTTP webhook. You shouldn't want to either, for the sake of your bot and users.
SSL/TLS, why do I have to handle this for a webhook?
We support any SSL/TLS version TLS1.2 and up for your webhook. This means that SSLV2/3/TLS1.0/TSL1.1 are NOT supported, due to security issues associated with those older versions.
How do I check that I’m handling the right version?
The common name (CN) of your certificate (self-signed or verified) has to match the domain name where your bot is hosted. You may also use a subject alternative name (SAN), that matches the domain for your webhook. Server Name Indication (SNI)-routing is supported. If you're using a self-signed certificate, you may use the IP as a CN, instead of the domain name.
A certificate, where do I get one, and how?
A certificate can either be verified or self-signed. Setting a webhook with a self-signed certificate differs a little from setting a webhook with a verified certificate. Ensure you're using the correct setup for the type of certificate you've chosen for your webhook.
How do I set a webhook for either type?
Not all verified certificates are supported. Certificates are based on a network of trust and come in a chain. Trusting your verified certificate means we have to trust the provider of that certificate, the Certificate Authority (and hence its root certificate). Before you pick a certificate provider, Check this list to make sure that we actually trust their root certificate.
What if my root certificate isn’t on that list?
Ok, so you already had a certificate installed and just discovered it’s not on our list.
Start by ignoring it, and just try to set it. We occasionally add extra root certificates to keep up with popular demand, so the list isn't always exhaustive. Unlucky after all? We'll allow you to supply an unsupported root certificate when setting the webhook. This method is nearly identical to setting a self-signed certificate webhook. Instead of your self-signed certificate you'll be sending us the root certificate as inputFile.
Setting a verified webhook with an untrusted root
Some verified certificates require an intermediate certificate. In this construction the provider of your verified certificate has used their root certificate to sign an intermediate certificate. This intermediate certificate is then used to sign your verified certificate. You'll need to provide the intermediate certificate for us to be able to verify the chain of trust. CA's that use this type of chain supply an intermediate certificate.
Supplying an intermediate certificate
Since we know webhooks can be a tad overwhelming, we’re working on a little digital assistant that’ll try and help you with the most common problems, it's not nearly perfect, but you may try using @CanOfWormsBot to check if your chain of certificates is installed correctly before contacting support.
-We took the liberty of adding a set of example updates. They come in handy when testing your bot, no matter which method of getting updates you might be using.
-If by now you're looking for your fishing gear because we've mentioned ports and hooks or you're about to Google what kind of bait URL and TLS exactly are, this guide might not be completely for you. You’re quite likely still a brilliant bot programmer, don’t worry. Perhaps this whole webhook thing is just new to you, not all is lost. If you currently have a working getUpdates situation, it's a good idea to pick up this guide again on a rainy Sunday afternoon and take your time to read up on some subjects around the internet. This guide can only contain a finite amount of information after all.
-If you use a webhook, we have to deliver requests to your bot to a server we can reach. So yes, you need a server we can connect to. It can be anywhere in the galaxy, if you ensure we can reach the server by domain name (or at least via IP for a self-signed certificate), it will work just fine.
-There are quite a few ways to get this done, as a novice however it's likely that you're not directly jumping at the chance of crafting this from scratch. Actually, as a novice, we recommend you don't. It's likely to be a complex and long ride.
-If you got stuck here, make a choice:
-You use getUpdates at the moment and it works, keep it that way. Especially if you're running your bot from a nice machine that does well. There is nothing wrong with using getUpdates.
-Go with a hosted service and let a bunch of professionals worry about things like registering a domain, setting up DNS, a web server, securing it and so on.
-If you're going with a hosted service, make sure to look for a hosting provider that
-not only supports your code’s needs, for example: support for your PHP version,
-but one that also handles SSL and allows you to create/deploy certificates.
-So you have the hosting thing down and all is good so far, however, when you enter the address of your bot in your browser it seems unreachable.
-Explaining every firewall or web server solution in detail isn't possible for us, which we hope you understand. If you’re running a hosted solution, you’re more likely to have a nice UI where you configure these settings. Head to your configuration panel and check all of them. If you’re on a Linux based VPS with shell access, we have some tips for you:
-netstat –ln | grep portnumber
sudo lsof -i | grep process name
(your public IP)
, it can also listen on all addresses (*: or 0.0.0.0)
.netstat
and lsof
-commands mentioned above assist in checking this. If nothing shows up, it is time to check your configuration and fix it. Set the correct IP, make sure it’s listening on a supported port and fire away! Just use a Web Browser to check if you’re reachable. The problem can be in the configuration of your bot, your web server virtual host configuration, or the servers binding configuration.If you still can’t reach your address, check your firewall.sudo iptables –L
ORsudo ufw status verbose
(Ubuntu)
Gives you some insight in the current firewall settings.
If it looks like you’re blocking incoming traffic, let’s fix that.sudo iptables –A INPUT –p tcp –m tcp –dport portnumber -j ACCEPT
ORsudo ufw allow portnumber/tcp
Allows incoming traffic on all interfaces to the specified tcp port.sudo iptables –A INPUT –i interfacename –p tcp –m tcp –dport portnumber -j ACCEPT
ORsudo ufw allow in on interfacename to any port portnumber proto tcp
Allows incoming traffic to a specific interface and a specific port from everywhere.sudo ifconfig
Helps you find the interface with the public address you’re going to use.
If you use iptables, make sure to actually SAVE after changing the configuration.
-On a Debian based system the iptables-persistent package is be a good option.
-RHEL/CentOS offers a service iptables save -command.
-A quick online search for "YOUROPERATINGSYSTEM save iptables" also helps.
-sudo iptables –A INPUT –i interfacename –p tcp –m iprange –src-range 149.154.167.197-149.154.167.233 –dport portnumber -j ACCEPT
sudo ufw allow in on interfacename to any port portnumber proto tcp from 149.154.167.192/26
That’s all for our examples. More information on best practices for setting up your firewall, on whichever operating system you prefer for your bot, is best found on the internet.
-You’re already familiar with it in some form or another. Whenever you see that (nicely green) lock in your browser bar, you know it’s reasonably safe to assume that you’ve landed on the site you actually wanted to visit. If you see the green lock, that's SSL/TLS in action. If you want to learn more about how SSL/TLS works in general, it's best to search the internet.
-The main difference between getUpdates and a webhook is the way the connection takes place. getUpdates means you'll connect to our server, a webhook means we'll be connecting to your server instead. Connecting to your server has to be done secure, we have to know for sure it's you we're talking to after all. This means you'll have to handle all that server side encryption stuff, virtually presenting us with a green lock. If you use a web server for us to post to, you need to support SSL/TLS handling on the port/virtual host of your choice. An online search for “YOURWEBSERVER enable HTTPS” will help you.
-Not using a regular web server? Have a look at our example page, most examples there include code for handling SSL/TLS in a webhook setup.
-You just read up on the whole SSL/TLS stuff, figured out that it’s not all that bad to setup and we add some more requirements. Here are some tips to check if you’re indeed supporting at least TLS1.2.
-Several online services exist that allow you to check your certificate installation,
They give you an overview of your supported TLS versions/Cipher suites and other details. Search online for Symantec crypto report or Qualys ssl. Both supply tools to verify your setup.
Checking locally can also be done, in several ways, here are three options,
-Go simple:
Using Chrome as a browser? Open up the URL to your bot and inspect the certificate details. If you’re supporting TLS Chrome tells you so in the security overview tab. Other browsers are likely able to give you similar basic information.
Using curl:curl --tlsv1.2 -v -k https://yourbotdomain:yourbotport/
You can add --tlsv1.2
to force curl into using TLS1.2 when trying to connect. -k
is optional and used to check against a self-signed certificate. yourbotdomain
is the public hostname your webhook is running on. For local testing purposes you can also use the IP. yourbotport
is the port you’re using.
Using OpenSSLopenssl s_client -tls1_2 -connect yourbotdomain:yourbotport -servername yourbotdomain
You can add -tls1_2
to force OpenSSL into using TLS1.2 when trying to connect. yourbotdomain
is the public hostname your webhook is running on. For local testing purposes you can also use the IP. yourbotport
is the port you’re using. Note that https:// isn’t used for OpenSSL. -servername
is optional, and included here for some shared hosters, which use SNI to route traffic to the correct domain. When SNI is used you’ll notice that your server appears to be returning a certificate for a different domain than your own. Adding -servername yourbotdomain
ensures that SNI negotiation is done, and the correct certificate is returned.
Some additional configuration pointers
-SSLProtocol -all +TLSv1.2
ssl_protocols TLSv1.2;
-Dhttps.protocols=TLSv1.2 -Djdk.tls.client.protocols=TLSv1.2
-Djavax.net.debug=ssl,handshake,record
Other tools that may help in debugging issues:
-You need a certificate, pick on of these types;
-Using a verified certificate means you already have, or will obtain, a certificate backed by a trusted certificate authority (CA). There are many ways to acquire a verified certificate, paid or free. Two popular examples of free suppliers are StartSSL and Let’s Encrypt. You’re welcome to pick another. Just make sure first the supplier is likely to be supported.
Check this list before selecting a CA.
Once you’ve picked a CA and validated your identity with them, you can craft your certificate. This frequently starts by generating a CSR (Certificate Signing Request). Generating a CSR is done either through your host machine, or online via the tools provided by the CA.
Here is an example (PEM format output).
-openssl req -newkey rsa:2048 -keyout yourprivatekey.key -out yoursigningrequest.csr
----
-Generating a 2048 bit RSA private keywriting new private key to yourprivatekey.key
-Enter PEM pass phrase: enter a password for your key here
-Verifying - Enter PEM pass phrase: confirm the entered password
------
-You are about to be asked to enter information that will be incorporated
-into your certificate request.
-What you are about to enter is what is called a Distinguished Name or a DN.
-There are quite a few fields but you can leave some blank
-For some fields there will be a default value,If you enter '.',
-the field will be left blank.-----
-Country Name (2 letter code) [AU]:
-State or Province Name (full name) [Some-State]:
-Locality Name (eg, city) []:
-Organization Name (eg, company) [Internet Widgits Pty Ltd]:
-Organizational Unit Name (eg, section) []:
-Common Name (e.g. server FQDN or YOUR name) []: yourbotdomainname
-Email Address []:
-Please enter the following 'extra' attributes
-to be sent with your certificate request
-A challenge password []:
-An optional company name []:
----
-Another example:
-keytool -genkey -alias yourbotdomainname -keyalg RSA -keystore yourkeystore.jks -keysize 2048
---
-Enter keystore password:
-Re-enter new password:
-What is your first and last name? [Unknown]: yourbotdomainname
-What is the name of your organizational unit? [Unknown]:
-What is the name of your organization? [Unknown]:
-What is the name of your City or Locality? [Unknown]:
-What is the name of your State or Province? [Unknown]:
-What is the two-letter country code for this unit? [Unknown]:
-Is CN=test.telegram.org, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown correct?
-[no]: yes
-Enter key password for yourbotdomainname
-(RETURN if same as keystore password):
----
-This generates the initial keystore, from which you can then create a CSR like this:
-keytool -certreq -alias yourbotdomainname -keystore yourkeystore.jks -file yourbotdomainname.csr
---
-Enter keystore password:
----
-To validate your certificate the Common Name (CN) has to match your webhook domain. Example, if you’re using https://www.example.com/example.php as a webhook address, the certificate CN has to be www.example.com.
So you need an exact match of the FQDN you’re setting for the webhook
There is an exception, if you’re using a SAN (Subject Alternative Name) the webhook address can either match the CN of your certificate, OR one of the SANs provided in the certificate. In most cases you’ll be using the CN.
-Create your CSR and supply the contents of the file to your CA. Most CA’s are kind enough to give you an example command of the input format they expect.
-cat yoursigningrequest.csr
or cat yourbotdomainname.csr
Lets you have a look at the CSR we just generated:
That doesn’t seem to informative, but we can deduce that the file is in PEM format (ASCII base64 encoded) and contains a certificate signing request. Luckily it is possible to look at the human readable contents of the CSR. Use the following commands to double check if all fields are set correctly.
-Using OpenSSLopenssl req -text -noout -verify -in yoursigningrequest.csr
Using Java keytoolkeytool -printcertreq -v -file yourbotdomainname.csr
Verify your CSR and supply it to your CA to get a certificate. We’ll use StartSSL as an example here. StartSSL allows you to set up to 5 names (SAN), Their intermediate certificate is also needed for a webhook to work, which makes for a nice complete example.
-Go to the certificates wizard, enter the required hostname(s) for your SSL certificate (this is the CN you’ve also set in the CSR and an optional SAN).
- - -In the example above we’ve chosen to set a CN (test.telegram.org)
, but also a SAN (sanexample.telegram.org)
The CN given has to match the CN used for generating the CSR.
Set your CN (and optional SAN) and copy the contents of the yoursigningrequest.csr file.
Paste the contents, submit and you’re done.
- - -Now you can download the created certificate directly. In the example used above you’ll receive a zip file with several PEM certificates. The root, intermediate and yourdomain certificate.
You need the intermediate
and yourdomain
to set a webhook with a StartSSL certificate.
You can inspect the set of certificates you’ve just downloaded.
-Here are some example commands:
-Using OpenSSL:openssl x509 -in yourdomain.crt -text -noout
Using Java keytool:keytool -printcert -v -yourdomain.crt
Using Windows:
StartSSL supplies certificates in PEM format with a .crt extension, on Windows you can view the contents of them with a quick double click. Extract the files or open the “Otherserver.zip” and double click each of the certificates for inspection. The details tab supplies you with extra information.
Make sure you have a correct CN in the Subject
-field of the yourdomain
-certificate. If you're using a SAN, make sure that it is listed in the Subject Alternative Name
-field.
With your fresh certificates at hand, you can now continue setting your webhook.
-Using a self-signed certificate means you’ll forfeit on the chain of trust backed by a CA. Instead you are the CA. For this to work, a slight difference in setup is required. Because Telegram will have no chain of trust to verify your certificate, you have to use the generated public certificate as an input file when setting the webhook. Keep in mind that the certificate file has to be uploaded as multipart/form data in PEM encoded (ASCII BASE64) format.
-First let’s generate some certificates:
-Using OpenSSL:openssl req -newkey rsa:2048 -sha256 -nodes -keyout YOURPRIVATE.key -x509 -days 365 -out YOURPUBLIC.pem -subj "/C=US/ST=New York/L=Brooklyn/O=Example Brooklyn Company/CN=YOURDOMAIN.EXAMPLE"
You’ll end up with 2 files, a private key and the public certificate file. Use YOURPUBLIC.PEM as input file for setting the webhook.
Using Java keytool:keytool -genkey -keyalg RSA -alias YOURDOMAIN.EXAMPLE -keystore YOURJKS.jks -storepass YOURPASSWORD -validity 360 -keysize 2048
What is your first and last name?
-[test.telegram.org]:
-What is the name of your organizational unit?
-[Unknown]:
-What is the name of your organization?
-[Unknown]:
-What is the name of your City or Locality?
-[Unknown]:
-What is the name of your State or Province?
-[Unknown]:
-What is the two-letter country code for this unit?
-[Unknown]:
-Is CN=test.telegram.org, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown correct?
-[no]: yes
-Once done you’ll need 2 more commands to export the public certificate file from the generated store (you’ll be using the store for your JVM and the PEM for setting the webhook)
-Convert the JKS to pkcs12 (intermediate step for conversion to PEM):keytool -importkeystore -srckeystore YOURJKS.jks -destkeystore YOURPKCS.p12 -srcstoretype jks -deststoretype pkcs12
Convert PKCS12 to PEM (requires OpenSSL)openssl pkcs12 -in YOURPKCS.p12 -out YOURPEM.pem -nokeys
Using Windows:
Creating a self-signed certificate using Windows native utilities is also possible, although OpenSSL binaries for Windows are available online.certreq -new TEMPLATE.txt RequestFileOut generates a CSR.
TEMPLATE.txt example file:
-[NewRequest]
-; At least one value must be set in this section
-Subject = "CN=DOMAIN.EXAMPLE"
-KeyLength = 2048
-KeyAlgorithm = RSA
-HashAlgorithm = sha256
-;MachineKeySet = true
-RequestType = Cert
-UseExistingKeySet=false ;generates a new private key (for export)
-Exportable = true ;makes the private key exportable with the PFX
-A self-signed certificate is generated and installed, to use the certificate for a self-signed webhook you'll have to export it in PEM format.
-Windows continued:
-You can have a look at the certificates in your store with:certutil -store -user my
To export the installed certificate in DER format (intermediate step for conversion to PEM):certutil -user -store -split my SERIALNUMBER YOURDER.der
Now you can convert the certificate to PEM:certutil -encode YOURDER.der YOURPEM.pem
Remember that only the public certificate is needed as input for the self-signed webhook certificate parameter.certmgr.msc
can also be used as a GUI to export the public part of self-signed certificate to PEM.
After following the above you'll end up with a nice self-signed certificate. You’ll still have to set the webhook, and handle SSL correctly.
-The setWebhook method is needed for both types. For a verified certificate with a trusted root CA, it’s enough to use the setWebhook method with just the URL parameter.
-curl -F "url=https://<YOURDOMAIN.EXAMPLE>/<WEBHOOKLOCATION>" https://api.telegram.org/bot<YOURTOKEN>/setWebhook
For a self-signed certificate an extra parameter is needed, certificate
, with the public certificate in PEM format as data.
curl -F "url=https://<YOURDOMAIN.EXAMPLE>/<WEBHOOKLOCATION>" -F "certificate=@<YOURCERTIFICATE>.pem" https://api.telegram.org/bot<YOURTOKEN>/setWebhook
The -F
means we’re using the multipart/form-data
-type to supply the certificate, the type of the certificate parameter is inputFile. Make sure that you’re supplying the correct type.
Both parameters for the setWebhook method are classed as optional. Calling the method with an empty URL parameter can be used to clear a previously set webhook.
-curl -F "url=" https://api.telegram.org/bot<YOURTOKEN>/setWebhook
Keep in mind that the URL parameter starts with https://
when setting a webhook. By default that means we’re knocking at your door on port 443. If you want to use another port (80,88 or 8443), you’ll have to specify the port in the URL parameter.
url=https://<YOURDOMAIN.EXAMPLE>:88/<WEBHOOKLOCATION>
If you already have a verified certificate and our servers don’t trust your root CA, we have an alternative way for you to set a webhook. Instead of using the setWebhook method without the certificate
parameter, you can use the self-signed method. Your CA's root certificate has to be used as an inputFile for the certificate
parameter.
curl -F "url=https://<YOURDOMAIN.EXAMPLE>" -F "certificate=@<YOURCAROOTCERTIFICATE>.pem" https://api.telegram.org/bot<YOURTOKEN>/setWebhook
You can use these commands to quickly convert a DER formatted root certificate to PEM:
-Using OpenSSL:openssl x509 -inform der -in root.cer -out root.pem
Using Java keytool:keytool -import -alias Root -keystore YOURKEYSTORE.JKS -trustcacerts -file ROOTCERT.CER
The root certificate needs to be imported in your keystore first:keytool -exportcert -alias Root -file <YOURROOTPEMFILE.PEM> -rfc -keystore YOURKEYSTORE.JKS
Once done, set your webhook with the root-pem-file and you’ll be good to go. If you need more pointers, have a look at the self-signed part of this guide.
-Once you’ve crafted your certificate, your CA might present you with a nice bundle. Most bundles contain a root certificate, your public certificate and sometimes an intermediate certificate. StartSSL is one of many CA’s that’ll supply such an intermediate beast. This certificate has to be supplied in the chain of certificates you’re presenting to us when we connect to your server. If an intermediate was used to sign your certificate but isn’t supplied to our servers, we won’t be able to verify the chain of trust and your webhook will not work.
-If your webhook isn’t working and you’re wondering if the chain is complete:
-Search online for Symantec crypto report or Qualys ssl.
-Both supply tools to verify your setup.
-Here’s an example of a complete chain, note that in this case 2 intermediate certificates have been supplied.
- - -Even though your browser might not complain when visiting your page, an incomplete chain will not work for your webhook. If your chain is incomplete we have some tips to add them to your current setup:
-Apache:
Add the intermediate certificate to the end of the file configured in the SSLCertificateFile
directive of your virtual host configuration. If you’re using an older version than Apache 2.4.8, you may use the SSLCertificateChainFile
directive instead.
Nginx:
Add the intermediate certificate to the end of the file configured in the ssl_certificate_key
directive of your virtual host configuration.
A quick command for doing this correctly:cat your_domain_name.pem intermediate.pem >> bundle.pem
Make sure the order is correct, expect failure otherwise.
Java keytool:keytool -import -trustcacerts -alias intermediate -file intermediate.pem -keystore YOURKEYSTORE.jks
The end result of all this is a complete certificate chain, backed by either a root certificate we trust or, in the case of an untrusted root, a root certificate you're supplying to us. Make sure to verify your setup again after adding the intermediate, once done, you're good to go!
-Update examples
A set of example updates, which comes in handy for testing your bot.
Message with text using curl:
-curl --tlsv1.2 -v -k -X POST -H "Content-Type: application/json" -H "Cache-Control: no-cache" -d '{
-"update_id":10000,
-"message":{
- "date":1441645532,
- "chat":{
- "last_name":"Test Lastname",
- "id":1111111,
- "first_name":"Test",
- "username":"Test"
- },
- "message_id":1365,
- "from":{
- "last_name":"Test Lastname",
- "id":1111111,
- "first_name":"Test",
- "username":"Test"
- },
- "text":"/start"
-}
-}' "https://YOUR.BOT.URL:YOURPORT/"
---tlsv1.2
will force using TLS1.2.
Message with text using Postman:
- -More examples in curl:
-curl -v -k -X POST -H "Content-Type: application/json" -H "Cache-Control: no-cache" -d '{
-"update_id":10000,
-"message":{
- "date":1441645532,
- "chat":{
- "last_name":"Test Lastname",
- "id":1111111,
- "type": "private",
- "first_name":"Test Firstname",
- "username":"Testusername"
- },
- "message_id":1365,
- "from":{
- "last_name":"Test Lastname",
- "id":1111111,
- "first_name":"Test Firstname",
- "username":"Testusername"
- },
- "text":"/start"
-}
-}' "https://YOUR.BOT.URL:YOURPORT/"
-curl -v -k -X POST -H "Content-Type: application/json" -H "Cache-Control: no-cache" -d '{
-"update_id":10000,
-"message":{
- "date":1441645532,
- "chat":{
- "last_name":"Test Lastname",
- "id":1111111,
- "type": "private",
- "first_name":"Test Firstname",
- "username":"Testusername"
- },
- "message_id":1365,
- "from":{
- "last_name":"Test Lastname",
- "id":1111111,
- "first_name":"Test Firstname",
- "username":"Testusername"
- },
- "forward_from": {
- "last_name":"Forward Lastname",
- "id": 222222,
- "first_name":"Forward Firstname"
- },
- "forward_date":1441645550,
- "text":"/start"
-}
-}' "https://YOUR.BOT.URL:YOURPORT/"
-curl -v -k -X POST -H "Content-Type: application/json" -H "Cache-Control: no-cache" -d '{
-"update_id":10000,
-"message":{
- "date":1441645532,
- "chat":{
- "last_name":"Test Lastname",
- "type": "private",
- "id":1111111,
- "first_name":"Test Firstname",
- "username":"Testusername"
- },
- "message_id":1365,
- "from":{
- "last_name":"Test Lastname",
- "id":1111111,
- "first_name":"Test Firstname",
- "username":"Testusername"
- },
- "forward_from": {
- "id": -10000000000,
- "type": "channel",
- "title": "Test channel"
- },
- "forward_date":1441645550,
- "text":"/start"
-}
-}' "https://YOUR.BOT.URL:YOURPORT/"
-curl -v -k -X POST -H "Content-Type: application/json" -H "Cache-Control: no-cache" -d '{
-"update_id":10000,
-"message":{
- "date":1441645532,
- "chat":{
- "last_name":"Test Lastname",
- "type": "private",
- "id":1111111,
- "first_name":"Test Firstname",
- "username":"Testusername"
- },
- "message_id":1365,
- "from":{
- "last_name":"Test Lastname",
- "id":1111111,
- "first_name":"Test Firstname",
- "username":"Testusername"
- },
- "text":"/start",
- "reply_to_message":{
- "date":1441645000,
- "chat":{
- "last_name":"Reply Lastname",
- "type": "private",
- "id":1111112,
- "first_name":"Reply Firstname",
- "username":"Testusername"
- },
- "message_id":1334,
- "text":"Original"
- }
-}
-}' "https://YOUR.BOT.URL:YOURPORT/"
-curl -v -k -X POST -H "Content-Type: application/json" -H "Cache-Control: no-cache" -d '{
-"update_id":10000,
-"edited_message":{
- "date":1441645532,
- "chat":{
- "last_name":"Test Lastname",
- "type": "private",
- "id":1111111,
- "first_name":"Test Firstname",
- "username":"Testusername"
- },
- "message_id":1365,
- "from":{
- "last_name":"Test Lastname",
- "id":1111111,
- "first_name":"Test Firstname",
- "username":"Testusername"
- },
- "text":"Edited text",
- "edit_date": 1441646600
-}
-}' "https://YOUR.BOT.URL:YOURPORT/"
-curl -v -k -X POST -H "Content-Type: application/json" -H "Cache-Control: no-cache" -d '{
-"update_id":10000,
-"message":{
- "date":1441645532,
- "chat":{
- "last_name":"Test Lastname",
- "type": "private",
- "id":1111111,
- "first_name":"Test Firstname",
- "username":"Testusername"
- },
- "message_id":1365,
- "from":{
- "last_name":"Test Lastname",
- "id":1111111,
- "first_name":"Test Firstname",
- "username":"Testusername"
- },
- "text":"Bold and italics",
- "entities": [
- {
- "type": "italic",
- "offset": 9,
- "length": 7
- },
- {
- "type": "bold",
- "offset": 0,
- "length": 4
- }
- ]
-}
-}' "https://YOUR.BOT.URL:YOURPORT/"
-curl -v -k -X POST -H "Content-Type: application/json" -H "Cache-Control: no-cache" -d '{
-"update_id":10000,
-"message":{
- "date":1441645532,
- "chat":{
- "last_name":"Test Lastname",
- "type": "private",
- "id":1111111,
- "first_name":"Test Firstname",
- "username":"Testusername"
- },
- "message_id":1365,
- "from":{
- "last_name":"Test Lastname",
- "id":1111111,
- "first_name":"Test Firstname",
- "username":"Testusername"
- },
- "audio": {
- "file_id": "AwADBAADbXXXXXXXXXXXGBdhD2l6_XX",
- "duration": 243,
- "mime_type": "audio/mpeg",
- "file_size": 3897500,
- "title": "Test music file"
- }
-}
-}' "https://YOUR.BOT.URL:YOURPORT/"
-curl -v -k -X POST -H "Content-Type: application/json" -H "Cache-Control: no-cache" -d '{
-"update_id":10000,
-"message":{
- "date":1441645532,
- "chat":{
- "last_name":"Test Lastname",
- "type": "private",
- "id":1111111,
- "first_name":"Test Firstname",
- "username":"Testusername"
- },
- "message_id":1365,
- "from":{
- "last_name":"Test Lastname",
- "id":1111111,
- "first_name":"Test Firstname",
- "username":"Testusername"
- },
- "voice": {
- "file_id": "AwADBAADbXXXXXXXXXXXGBdhD2l6_XX",
- "duration": 5,
- "mime_type": "audio/ogg",
- "file_size": 23000
- }
-}
-}' "https://YOUR.BOT.URL:YOURPORT/"
-curl -v -k -X POST -H "Content-Type: application/json" -H "Cache-Control: no-cache" -d '{
-"update_id":10000,
-"message":{
- "date":1441645532,
- "chat":{
- "last_name":"Test Lastname",
- "type": "private",
- "id":1111111,
- "first_name":"Test Firstname",
- "username":"Testusername"
- },
- "message_id":1365,
- "from":{
- "last_name":"Test Lastname",
- "id":1111111,
- "first_name":"Test Firstname",
- "username":"Testusername"
- },
- "document": {
- "file_id": "AwADBAADbXXXXXXXXXXXGBdhD2l6_XX",
- "file_name": "Testfile.pdf",
- "mime_type": "application/pdf",
- "file_size": 536392
- }
-}
-}' "https://YOUR.BOT.URL:YOURPORT/"
-curl -v -k -X POST -H "Content-Type: application/json" -H "Cache-Control: no-cache" -d '{
-"update_id":10000,
-"inline_query":{
- "id": 134567890097,
- "from":{
- "last_name":"Test Lastname",
- "type": "private",
- "id":1111111,
- "first_name":"Test Firstname",
- "username":"Testusername"
- },
- "query": "inline query",
- "offset": ""
-}
-}' "https://YOUR.BOT.URL:YOURPORT/"
-curl -v -k -X POST -H "Content-Type: application/json" -H "Cache-Control: no-cache" -d '{
-"update_id":10000,
-"chosen_inline_result":{
- "result_id": "12",
- "from":{
- "last_name":"Test Lastname",
- "type": "private",
- "id":1111111,
- "first_name":"Test Firstname",
- "username":"Testusername"
- },
- "query": "inline query",
- "inline_message_id": "1234csdbsk4839"
-}
-}' "https://YOUR.BOT.URL:YOURPORT/"
-curl -v -k -X POST -H "Content-Type: application/json" -H "Cache-Control: no-cache" -d '{
-"update_id":10000,
-"callback_query":{
- "id": "4382bfdwdsb323b2d9",
- "from":{
- "last_name":"Test Lastname",
- "type": "private",
- "id":1111111,
- "first_name":"Test Firstname",
- "username":"Testusername"
- },
- "data": "Data from button callback",
- "inline_message_id": "1234csdbsk4839"
-}
-}' "https://YOUR.BOT.URL:YOURPORT/"
-That's all we have for now!Temporary payment password
-account.tmpPassword#db64fd34 tmp_password:bytes valid_until:int = account.TmpPassword;
-Name | -Type | -Description | -
---|---|---|
tmp_password | -bytes | -Temporary password | -
valid_until | -int | -Validity period | -
No new wallpapers were found
-account.wallPapersNotModified#1c199183 = account.WallPapers;
-This constructor does not require any parameters.
-Time to live in days of the current account
-accountDaysTTL#b8d0afdf days:int = AccountDaysTTL;
-Name | -Type | -Description | -
---|---|---|
days | -int | -This account will self-destruct in the specified number of days | -
The code will be sent via a phone call: a synthesized voice will tell the user which verification code to input.
-auth.sentCodeTypeCall#5353e5a7 length:int = auth.SentCodeType;
-Name | -Type | -Description | -
---|---|---|
length | -int | -Length of the verification code | -
Send a venue
-botInlineMessageMediaVenue#8a86659c flags:# geo:GeoPoint title:string address:string provider:string venue_id:string venue_type:string reply_markup:flags.2?ReplyMarkup = BotInlineMessage;
-Name | -Type | -Description | -
---|---|---|
flags | -# | -Flags, see TL conditional fields | -
geo | -GeoPoint | -Geolocation of venue | -
title | -string | -Venue name | -
address | -string | -Address | -
provider | -string | -Venue provider: currently only "foursquare" needs to be supported | -
venue_id | -string | -Venue ID in the provider's database | -
venue_type | -string | -Venue type in the provider's database | -
reply_markup | -flags.2?ReplyMarkup | -Inline keyboard | -
A message was edited
-channelAdminLogEventActionEditMessage#709b2405 prev_message:Message new_message:Message = ChannelAdminLogEventAction;
-Name | -Type | -Description | -
---|---|---|
prev_message | -Message | -Old message | -
new_message | -Message | -New message | -
A user left the channel/supergroup (in the case of big groups, info of the user that has joined isn't shown)
-channelAdminLogEventActionParticipantLeave#f89777f2 = ChannelAdminLogEventAction;
-This constructor does not require any parameters.
-Slow mode setting for supergroups was changed
-channelAdminLogEventActionToggleSlowMode#53909779 prev_value:int new_value:int = ChannelAdminLogEventAction;
-Name | -Type | -Description | -
---|---|---|
prev_value | -int | -Previous slow mode value | -
new_value | -int | -New slow mode value | -
Toggle supergroup slow mode: if enabled, users will only be able to send one message every seconds
seconds
Banned/kicked user
-channelParticipantBanned#1c0facaf flags:# left:flags.0?true user_id:int kicked_by:int date:int banned_rights:ChatBannedRights = ChannelParticipant;
-Name | -Type | -Description | -
---|---|---|
flags | -# | -Flags, see TL conditional fields | -
left | -flags.0?true | -Whether the user has left the group | -
user_id | -int | -User ID | -
kicked_by | -int | -User was kicked by the specified admin | -
date | -int | -When did the user join the group | -
banned_rights | -ChatBannedRights | -Banned rights | -
How to handle admin permissions, granular bans and global permissions in channels, groups and supergroups.
Fetch only banned participants
-channelParticipantsBanned#1427a5e1 q:string = ChannelParticipantsFilter;
-Name | -Type | -Description | -
---|---|---|
q | -string | -Optional filter for searching banned participants by name (otherwise empty) | -
Represents a channel participant
-channels.channelParticipant#d0d9b163 participant:ChannelParticipant users:Vector<User> = channels.ChannelParticipant;
-Name | -Type | -Description | -
---|---|---|
participant | -ChannelParticipant | -The channel participant | -
users | -Vector<User> | -Users | -
Group members.
-chatParticipants#3f460fed chat_id:int participants:Vector<ChatParticipant> version:int = ChatParticipants;
-Name | -Type | -Description | -
---|---|---|
chat_id | -int | -Group identifier | -
participants | -Vector<ChatParticipant> | -List of group members | -
version | -int | -Group version number | -
The current user's contact list and info on users.
-contacts.contacts#eae87e42 contacts:Vector<Contact> saved_count:int users:Vector<User> = contacts.Contacts;
-Name | -Type | -Description | -
---|---|---|
contacts | -Vector<Contact> | -Contact list | -
saved_count | -int | -Number of contacts that were saved successfully | -
users | -Vector<User> | -User list | -
Users found by name substring and auxiliary data.
-contacts.found#b3134d9d my_results:Vector<Peer> results:Vector<Peer> chats:Vector<Chat> users:Vector<User> = contacts.Found;
-Name | -Type | -Description | -
---|---|---|
my_results | -Vector<Peer> | -Personalized results | -
results | -Vector<Peer> | -List of found user identifiers | -
chats | -Vector<Chat> | -Found chats | -
users | -Vector<User> | -List of users | -
Top peers disabled
-contacts.topPeersDisabled#b52c939d = contacts.TopPeers;
-This constructor does not require any parameters.
-Top peer info hasn't changed
-contacts.topPeersNotModified#de266ef5 = contacts.TopPeers;
-This constructor does not require any parameters.
-Emoji keyword
-emojiKeyword#d5b3b9f9 keyword:string emoticons:Vector<string> = EmojiKeyword;
-Name | -Type | -Description | -
---|---|---|
keyword | -string | -Keyword | -
emoticons | -Vector<string> | -Emojis associated to keyword | -
Discarded or deleted chat.
-encryptedChatDiscarded#13d6dd27 id:int = EncryptedChat;
-Name | -Type | -Description | -
---|---|---|
id | -int | -Chat ID | -
Empty constructor, unexisitng file.
-encryptedFileEmpty#c21f497e = EncryptedFile;
-This constructor does not require any parameters.
-Link to a message in a supergroup/channel
-exportedMessageLink#5dab1af4 link:string html:string = ExportedMessageLink;
-Name | -Type | -Description | -
---|---|---|
link | -string | -URL | -
html | -string | -Embed code | -
File location.
-Constructor schema is available as of layer 86. Switch »
-Name | -Type | -Description | -
---|---|---|
dc_id | -int | -Number of the data center holding the file | -
volume_id | -long | -Server volume | -
local_id | -int | -File ID | -
secret | -long | -Checksum to access the file | -
Password configuration not modified
-help.passportConfigNotModified#bfb9f457 = help.PassportConfig;
-This constructor does not require any parameters.
-No changes were made to telegram's terms of service
-help.termsOfServiceUpdateEmpty#e3309f7f expires:int = help.TermsOfServiceUpdate;
-Name | -Type | -Description | -
---|---|---|
expires | -int | -New TOS updates will have to be queried using help.getTermsOfServiceUpdate in expires seconds |
-
Look for updates of telegram's terms of service
Event that occured in the application.
-inputAppEvent#1d1b1245 time:double type:string peer:long data:JSONValue = InputAppEvent;
-Name | -Type | -Description | -
---|---|---|
time | -double | -Client's exact timestamp for the event | -
type | -string | -Type of event | -
peer | -long | -Arbitrary numeric value for more convenient selection of certain event types, or events referring to a certain object | -
data | -JSONValue | -Details of the event | -
Document (media of any type except for photos)
-inputBotInlineResultDocument#fff8fdc4 flags:# id:string type:string title:flags.1?string description:flags.2?string document:InputDocument send_message:InputBotInlineMessage = InputBotInlineResult;
-Name | -Type | -Description | -
---|---|---|
flags | -# | -Flags, see TL conditional fields | -
id | -string | -Result ID | -
type | -string | -Result type (see bot API docs) | -
title | -flags.1?string | -Result title | -
description | -flags.2?string | -Result description | -
document | -InputDocument | -Document to send | -
send_message | -InputBotInlineMessage | -Message to send when the result is selected | -
Game
-inputBotInlineResultGame#4fa417f2 id:string short_name:string send_message:InputBotInlineMessage = InputBotInlineResult;
-Name | -Type | -Description | -
---|---|---|
id | -string | -Result ID | -
short_name | -string | -Game short name | -
send_message | -InputBotInlineMessage | -Message to send when the result is selected | -
Sets new encrypted file saved by parts using upload.saveFilePart method.
-inputEncryptedFileUploaded#64bd0306 id:long parts:int md5_checksum:string key_fingerprint:int = InputEncryptedFile;
-Name | -Type | -Description | -
---|---|---|
id | -long | -Random file ID created by clien | -
parts | -int | -Number of saved parts | -
md5_checksum | -string | -In case md5-HASH of the (already encrypted) file was transmitted, file content will be checked prior to use | -
key_fingerprint | -int | -32-bit fingerprint of the key used to encrypt a file | -
Document that will be downloaded by the telegram servers
-inputMediaDocumentExternal#fb52dc99 flags:# url:string ttl_seconds:flags.0?int = InputMedia;
-Name | -Type | -Description | -
---|---|---|
flags | -# | -Flags, see TL conditional fields | -
url | -string | -URL of the document | -
ttl_seconds | -flags.0?int | -Self-destruct time to live of document | -
Filter is absent.
-inputMessagesFilterEmpty#57e2f66c = MessagesFilter;
-This constructor does not require any parameters.
-An empty constructor, no user or chat is defined.
-inputPeerEmpty#7f3b18ea = InputPeer;
-This constructor does not require any parameters.
-Allow only participants of certain chats
-inputPrivacyValueAllowChatParticipants#4c81c1ba chats:Vector<int> = InputPrivacyRule;
-Name | -Type | -Description | -
---|---|---|
chats | -Vector<int> | -Allowed chat IDs | -
Allow only certain users
-inputPrivacyValueAllowUsers#131cc67f users:Vector<InputUser> = InputPrivacyRule;
-Name | -Type | -Description | -
---|---|---|
users | -Vector<InputUser> | -Allowed users | -
Report an irrelevant geogroup
-inputReportReasonGeoIrrelevant#dbd4feed = ReportReason;
-This constructor does not require any parameters.
-Other
-inputReportReasonOther#e1746d0a text:string = ReportReason;
-Name | -Type | -Description | -
---|---|---|
text | -string | -Other report reason | -
Defines a min user that was seen in a certain message of a certain chat.
-inputUserFromMessage#2d117597 peer:InputPeer msg_id:int user_id:int = InputUser;
-Name | -Type | -Description | -
---|---|---|
peer | -InputPeer | -The chat where the user was seen | -
msg_id | -int | -The message ID | -
user_id | -int | -The identifier of the user that was seen | -
In some situations user and channel constructors have reduced set of fields present (although id is always there) and min flag set.
Wallpaper by slug (a unique ID)
-inputWallPaperSlug#72091c80 slug:string = InputWallPaper;
-Name | -Type | -Description | -
---|---|---|
slug | -string | -Unique wallpaper ID | -
The document
-inputWebDocument#9bed434d url:string size:int mime_type:string attributes:Vector<DocumentAttribute> = InputWebDocument;
-Name | -Type | -Description | -
---|---|---|
url | -string | -Remote document URL to be downloaded using the appropriate method | -
size | -int | -Remote file size | -
mime_type | -string | -Mime type | -
attributes | -Vector<DocumentAttribute> | -Attributes for media types | -
How to transfer large data batches correctly.
Geolocation
-inputWebFileGeoPointLocation#9f2221c9 geo_point:InputGeoPoint access_hash:long w:int h:int zoom:int scale:int = InputWebFileLocation;
-Name | -Type | -Description | -
---|---|---|
geo_point | -InputGeoPoint | -Geolocation | -
access_hash | -long | -Access hash | -
w | -int | -Map width in pixels before applying scale; 16-1024 | -
h | -int | -Map height in pixels before applying scale; 16-1024 | -
zoom | -int | -Map zoom level; 13-20 | -
scale | -int | -Map scale; 1-3 | -
Location of a remote HTTP(s) file
-inputWebFileLocation#c239d686 url:string access_hash:long = InputWebFileLocation;
-Name | -Type | -Description | -
---|---|---|
url | -string | -HTTP URL of file | -
access_hash | -long | -Access hash | -
JSON object value
-jsonObject#99c1d49d value:Vector<JSONObjectValue> = JSONValue;
-Name | -Type | -Description | -
---|---|---|
value | -Vector<JSONObjectValue> | -Values | -
Button to start a game
-keyboardButtonGame#50f41ccf text:string = KeyboardButton;
-Name | -Type | -Description | -
---|---|---|
text | -string | -Button text | -
Custom action (most likely not supported by the current layer, an upgrade might be needed)
-messageActionCustomAction#fae69f56 message:string = MessageAction;
-Name | -Type | -Description | -
---|---|---|
message | -string | -Action message | -
Someone scored in a game
-messageActionGameScore#92a72876 game_id:long score:int = MessageAction;
-Name | -Type | -Description | -
---|---|---|
game_id | -long | -Game ID | -
score | -int | -Score | -
Message entity representing a bot /command
-messageEntityBotCommand#6cef8ac7 offset:int length:int = MessageEntity;
-Name | -Type | -Description | -
---|---|---|
offset | -int | -Offset of message entity within message (in UTF-8 codepoints) | -
length | -int | -Length of message entity within message (in UTF-8 codepoints) | -
Info about a forwarded message
-messageFwdHeader#5f777dce flags:# imported:flags.7?true from_id:flags.0?Peer from_name:flags.5?string date:int channel_post:flags.2?int post_author:flags.3?string saved_from_peer:flags.4?Peer saved_from_msg_id:flags.4?int psa_type:flags.6?string = MessageFwdHeader;
-Name | -Type | -Description | -
---|---|---|
flags | -# | -Flags, see TL conditional fields | -
from_id | -flags.0?Peer | -The ID of the user that originally sent the message | -
from_name | -flags.5?string | -The name of the user that originally sent the message | -
date | -int | -When was the message originally sent | -
channel_post | -flags.2?int | -ID of the channel message that was forwarded | -
post_author | -flags.3?string | -For channels and if signatures are enabled, author of the channel message | -
saved_from_peer | -flags.4?Peer | -Only for messages forwarded to the current user (inputPeerSelf), full info about the user/channel that originally sent the message | -
saved_from_msg_id | -flags.4?int | -Only for messages forwarded to the current user (inputPeerSelf), ID of the message that was forwarded from the original user/channel | -
psa_type | -flags.6?string | -PSA type | -
Attached photo.
-messageMediaPhoto#695150d7 flags:# photo:flags.0?Photo ttl_seconds:flags.2?int = MessageMedia;
-Name | -Type | -Description | -
---|---|---|
flags | -# | -Flags, see TL conditional fields | -
photo | -flags.0?Photo | -Photo | -
ttl_seconds | -flags.2?int | -Time to live in seconds of self-destructing photo | -
Current version of the client does not support this media type.
-messageMediaUnsupported#9f84f49e = MessageMedia;
-This constructor does not require any parameters.
-List of chats with auxiliary data.
-messages.chats#64ff9fd5 chats:Vector<Chat> = messages.Chats;
-Name | -Type | -Description | -
---|---|---|
chats | -Vector<Chat> | -List of chats | -
Message edit data for media
-messages.messageEditData#26b5dde6 flags:# caption:flags.0?true = messages.MessageEditData;
-Name | -Type | -Description | -
---|---|---|
flags | -# | -Flags, see TL conditional fields | -
caption | -flags.0?true | -Media caption, if the specified media's caption can be edited | -
View, forward counter + info about replies
-messages.messageViews#b6c4f543 views:Vector<MessageViews> chats:Vector<Chat> users:Vector<User> = messages.MessageViews;
-Name | -Type | -Description | -
---|---|---|
views | -Vector<MessageViews> | -View, forward counter + info about replies | -
chats | -Vector<Chat> | -Chats mentioned in constructor | -
users | -Vector<User> | -Users mentioned in constructor | -
Message without file attachemts sent to an encrypted file.
-messages.sentEncryptedMessage#560f8935 date:int = messages.SentEncryptedMessage;
-Name | -Type | -Description | -
---|---|---|
date | -int | -Date of sending | -
The stickerset was installed, but since there are too many stickersets some were archived
-messages.stickerSetInstallResultArchive#35e410a8 sets:Vector<StickerSetCovered> = messages.StickerSetInstallResult;
-Name | -Type | -Description | -
---|---|---|
sets | -Vector<StickerSetCovered> | -Archived stickersets | -
Notifications generated by all users.
-notifyUsers#b4c83b4c = NotifyPeer;
-This constructor does not require any parameters.
-Ordered list of IV blocks
-pageBlockOrderedList#9a8ae1e1 items:Vector<PageListOrderedItem> = PageBlock;
-Name | -Type | -Description | -
---|---|---|
items | -Vector<PageListOrderedItem> | -List items | -
The phone call was missed
-phoneCallDiscardReasonMissed#85e42301 = PhoneCallDiscardReason;
-This constructor does not require any parameters.
-Protocol info for libtgvoip
-phoneCallProtocol#fc878fc8 flags:# udp_p2p:flags.0?true udp_reflector:flags.1?true min_layer:int max_layer:int library_versions:Vector<string> = PhoneCallProtocol;
-Name | -Type | -Description | -
---|---|---|
flags | -# | -Flags, see TL conditional fields | -
udp_p2p | -flags.0?true | -Whether to allow P2P connection to the other participant | -
udp_reflector | -flags.1?true | -Whether to allow connection to the other participants through the reflector servers | -
min_layer | -int | -Minimum layer for remote libtgvoip | -
max_layer | -int | -Maximum layer for remote libtgvoip | -
library_versions | -Vector<string> | -When using phone.requestCall and phone.acceptCall, specify all library versions supported by the client. The server will merge and choose the best library version supported by both peers, returning only the best value in the result of the callee's phone.acceptCall and in the phoneCallAccepted update received by the caller. |
-
Start a telegram phone call
-Accept incoming call
-An accepted phone call
WebRTC connection parameters
-phoneConnectionWebrtc#635fe375 flags:# turn:flags.0?true stun:flags.1?true id:long ip:string ipv6:string port:int username:string password:string = PhoneConnection;
-Name | -Type | -Description | -
---|---|---|
flags | -# | -Flags, see TL conditional fields | -
turn | -flags.0?true | -Whether this is a TURN endpoint | -
stun | -flags.1?true | -Whether this is a STUN endpoint | -
id | -long | -Endpoint ID | -
ip | -string | -IP address | -
ipv6 | -string | -IPv6 address | -
port | -int | -Port | -
username | -string | -Username | -
password | -string | -Password | -
Full list of photos with auxiliary data.
-photos.photos#8dca6aa5 photos:Vector<Photo> users:Vector<User> = photos.Photos;
-Name | -Type | -Description | -
---|---|---|
photos | -Vector<Photo> | -List of photos | -
users | -Vector<User> | -List of mentioned users | -
A possible answer of a poll
-pollAnswer#6ca9c2e9 text:string option:bytes = PollAnswer;
-Name | -Type | -Description | -
---|---|---|
text | -string | -Textual representation of the answer | -
option | -bytes | -The param that has to be passed to messages.sendVote. | -
Vote in a poll
Represents an issue with a list of scans. The error is considered resolved when the list of files containing the scans changes.
-secureValueErrorFiles#666220e9 type:SecureValueType file_hash:Vector<bytes> text:string = SecureValueError;
-Name | -Type | -Description | -
---|---|---|
type | -SecureValueType | -One of secureValueTypeUtilityBill, secureValueTypeBankStatement, secureValueTypeRentalAgreement, secureValueTypePassportRegistration, secureValueTypeTemporaryRegistration | -
file_hash | -Vector<bytes> | -File hash | -
text | -string | -Error message | -
Utility bill
-Bank statement
-Rental agreement
-Internal registration passport
-Temporary registration
Represents an issue with the front side of a document. The error is considered resolved when the file with the front side of the document changes.
-secureValueErrorFrontSide#be3dfa type:SecureValueType file_hash:bytes text:string = SecureValueError;
-Name | -Type | -Description | -
---|---|---|
type | -SecureValueType | -One of secureValueTypePassport, secureValueTypeDriverLicense, secureValueTypeIdentityCard, secureValueTypeInternalPassport | -
file_hash | -bytes | -File hash | -
text | -string | -Error message | -
Passport
-Driver's license
-Identity card
-Internal passport
Identity card
-secureValueTypeIdentityCard#a0d0744b = SecureValueType;
-This constructor does not require any parameters.
-Rental agreement
-secureValueTypeRentalAgreement#8b883488 = SecureValueType;
-This constructor does not require any parameters.
-User is playing a game
-sendMessageGamePlayAction#dd6a8f48 = SendMessageAction;
-This constructor does not require any parameters.
-User is uploading a file.
-sendMessageUploadDocumentAction#aa0cd9e4 progress:int = SendMessageAction;
-Name | -Type | -Description | -
---|---|---|
progress | -int | -Progress percentage | -
This channel statistics graph must be generated asynchronously using stats.loadAsyncGraph to reduce server load
-statsGraphAsync#4a27eb2d token:string = StatsGraph;
-Name | -Type | -Description | -
---|---|---|
token | -string | -Token to use for fetching the async graph | -
Telegram offers detailed channel statistics for channels and supergroups.
-Load channel statistics graph asynchronously
MPEG-4 video. MIME type: video/mp4
.
storage.fileMp4#b3cea0e4 = storage.FileType;
-This constructor does not require any parameters.
-Part of a bigger file.
-storage.filePartial#40bc6f52 = storage.FileType;
-This constructor does not require any parameters.
-Most used bots
-topPeerCategoryBotsPM#ab661b5b = TopPeerCategory;
-This constructor does not require any parameters.
-A user is typing in a supergroup, channel or message thread
-updateChannelUserTyping#ff2abe9f flags:# channel_id:int top_msg_id:flags.0?int user_id:int action:SendMessageAction = Update;
-Name | -Type | -Description | -
---|---|---|
flags | -# | -Flags, see TL conditional fields | -
channel_id | -int | -Channel ID | -
top_msg_id | -flags.0?int | -Thread ID | -
user_id | -int | -User ID | -
action | -SendMessageAction | -Whether the user is typing, sending a media or doing something else | -
Telegram allows commenting on a channel post or on a generic supergroup message, thanks to message threads.
-How to handle channels, supergroups, groups, and what's the difference between them.
Composition of chat participants changed.
-updateChatParticipants#7761198 participants:ChatParticipants = Update;
-Name | -Type | -Description | -
---|---|---|
participants | -ChatParticipants | -Updated chat participants | -
Messages were deleted.
-updateDeleteMessages#a20db0e5 messages:Vector<int> pts:int pts_count:int = Update;
-Name | -Type | -Description | -
---|---|---|
messages | -Vector<int> | -List of identifiers of deleted messages | -
pts | -int | -New quality of actions in a message box | -
pts_count | -int | -Number of generated events | -
How to subscribe to updates and handle them properly.
A message was edited in a channel/supergroup
-updateEditChannelMessage#1b3f4df7 message:Message pts:int pts_count:int = Update;
-Name | -Type | -Description | -
---|---|---|
message | -Message | -The new message | -
pts | -int | -Event count after generation | -
pts_count | -int | -Number of events that were generated | -
How to subscribe to updates and handle them properly.
-How to handle channels, supergroups, groups, and what's the difference between them.
Change of state in an encrypted chat.
-updateEncryption#b4a2e88d chat:EncryptedChat date:int = Update;
-Name | -Type | -Description | -
---|---|---|
chat | -EncryptedChat | -Encrypted chat | -
date | -int | -Date of change | -
Some featured stickers were marked as read
-updateReadFeaturedStickers#571d2742 = Update;
-This constructor does not require any parameters.
-A service message for the user.
-The app must show the message to the user upon receiving this update. In case the popup parameter was passed, the text message must be displayed in a popup alert immediately upon receipt. It is recommended to handle the text as you would an ordinary message in terms of highlighting links, etc. The message must also be stored locally as part of the message history with the user id 777000
(Telegram Notifications).
updateServiceNotification#ebe46819 flags:# popup:flags.0?true inbox_date:flags.1?int type:string message:string media:MessageMedia entities:Vector<MessageEntity> = Update;
-Name | -Type | -Description | -
---|---|---|
flags | -# | -Flags, see TL conditional fields | -
popup | -flags.0?true | -(boolTrue) if the message must be displayed in a popup. | -
inbox_date | -flags.1?int | -When was the notification received The message must also be stored locally as part of the message history with the user id 777000 (Telegram Notifications). |
-
type | -string | -String, identical in format and contents to the type field in API errors. Describes type of service message. It is acceptable to ignore repeated messages of the same type within a short period of time (15 minutes). | -
message | -string | -Message text | -
media | -MessageMedia | -Media content (optional) | -
entities | -Vector<MessageEntity> | -Message entities for styled text | -
How to handle API return errors correctly.
-How to create styled text with message entities
The user is preparing a message; typing, recording, uploading, etc. This update is valid for 6 seconds. If no repeated update received after 6 seconds, it should be considered that the user stopped doing whatever he's been doing.
-updateUserTyping#5c486927 user_id:int action:SendMessageAction = Update;
-Name | -Type | -Description | -
---|---|---|
user_id | -int | -User id | -
action | -SendMessageAction | -Action type Param added in Layer 17. |
-
Below you will find information on scheme changes. For more details on the use of layers, see Invoking API methods.
Incomplete list of occurred events.
-updates.differenceSlice#a8fb1981 new_messages:Vector<Message> new_encrypted_messages:Vector<EncryptedMessage> other_updates:Vector<Update> chats:Vector<Chat> users:Vector<User> intermediate_state:updates.State = updates.Difference;
-Name | -Type | -Description | -
---|---|---|
new_messages | -Vector<Message> | -List of new messgaes | -
new_encrypted_messages | -Vector<EncryptedMessage> | -New messages from the encrypted event sequence | -
other_updates | -Vector<Update> | -List of updates | -
chats | -Vector<Chat> | -List of chats mentioned in events | -
users | -Vector<User> | -List of users mentioned in events | -
intermediate_state | -updates.State | -Intermediary state | -
How to subscribe to updates and handle them properly.
The file must be downloaded from a CDN DC.
-upload.fileCdnRedirect#f18cda44 dc_id:int file_token:bytes encryption_key:bytes encryption_iv:bytes file_hashes:Vector<FileHash> = upload.File;
-Name | -Type | -Description | -
---|---|---|
dc_id | -int | -CDN DC ID | -
file_token | -bytes | -File token (see CDN files) | -
encryption_key | -bytes | -Encryption key (see CDN files) | -
encryption_iv | -bytes | -Encryption IV (see CDN files) | -
file_hashes | -Vector<FileHash> | -File hashes (see CDN files) | -
A user that is not a contact of the current user.
-Constructor schema is available as of layer 18. Switch »
-Name | -Type | -Description | -
---|---|---|
id | -int | -User identifier | -
first_name | -string | -First name as supplied by the user | -
last_name | -string | -Last name as supplied by the user | -
access_hash | -long | -Checksum dependent on the user identifier | -
photo | -UserProfilePhoto | -Profile photo | -
status | -UserStatus | -Current status | -
username | -string | -Username Parameter added in Layer 18. |
-
Extended user info
-userFull#edf17c12 flags:# blocked:flags.0?true phone_calls_available:flags.4?true phone_calls_private:flags.5?true can_pin_message:flags.7?true has_scheduled:flags.12?true video_calls_available:flags.13?true user:User about:flags.1?string settings:PeerSettings profile_photo:flags.2?Photo notify_settings:PeerNotifySettings bot_info:flags.3?BotInfo pinned_msg_id:flags.6?int common_chats_count:int folder_id:flags.11?int = UserFull;
-Name | -Type | -Description | -
---|---|---|
flags | -# | -Flags, see TL conditional fields | -
blocked | -flags.0?true | -Whether you have blocked this user | -
phone_calls_available | -flags.4?true | -Whether this user can make VoIP calls | -
phone_calls_private | -flags.5?true | -Whether this user's privacy settings allow you to call him | -
can_pin_message | -flags.7?true | -Whether you can pin messages in the chat with this user, you can do this only for a chat with yourself | -
has_scheduled | -flags.12?true | -Whether scheduled messages are available | -
video_calls_available | -flags.13?true | -Whether the user can receive video calls | -
user | -User | -Remaining user info | -
about | -flags.1?string | -Bio of the user | -
settings | -PeerSettings | -Peer settings | -
profile_photo | -flags.2?Photo | -Profile photo | -
notify_settings | -PeerNotifySettings | -Notification settings | -
bot_info | -flags.3?BotInfo | -For bots, info about the bot (bot commands, etc) | -
pinned_msg_id | -flags.6?int | -Message ID of the last pinned message | -
common_chats_count | -int | -Chats in common with this user | -
folder_id | -flags.11?int | -Peer folder ID, for more info click here | -
Telegram allows scheduling messages
-Telegram allows pinning multiple messages on top of a specific chat.
-Telegram allows placing chats into folders, based on their type, mute status, or other custom criteria, thanks to folder blacklists and whitelists.
The user's offline status.
-userStatusOffline#8c703f was_online:int = UserStatus;
-Name | -Type | -Description | -
---|---|---|
was_online | -int | -Time the user was last seen online | -
A universal vector constructor.
-vector#1cb5c415 {t:Type} # [ t ] = Vector t;
-This constructor does not require any parameters.
-For serialization write the constructor id 0x1cb5c415
:int, then the number of vector elements - #:int, then, one after another, the # of the elements of the type t, that was implicitly passed to the constructor.
Delete stored Telegram Passport documents, for more info see the passport docs »
-boolFalse#bc799737 = Bool;
-boolTrue#997275b5 = Bool;
----functions---
-account.deleteSecureValue#b880bc4b types:Vector<SecureValueType> = Bool;
-Name | -Type | -Description | -
---|---|---|
types | -Vector<SecureValueType> | -Document types to delete | -
Get days to live of account
-accountDaysTTL#b8d0afdf days:int = AccountDaysTTL;
----functions---
-account.getAccountTTL#8fc711d = AccountDaysTTL;
-This constructor does not require any parameters.
-Gets current notification settings for a given user/group, from all users/all groups.
-peerNotifySettings#af509d20 flags:# show_previews:flags.0?Bool silent:flags.1?Bool mute_until:flags.2?int sound:flags.3?string = PeerNotifySettings;
----functions---
-account.getNotifySettings#12b3ad31 peer:InputNotifyPeer = PeerNotifySettings;
-Name | -Type | -Description | -
---|---|---|
peer | -InputNotifyPeer | -Notification source | -
Returns a PeerNotifySettings object containing current notification settings.
-Code | -Type | -Description | -
---|---|---|
400 | -PEER_ID_INVALID | -The provided peer id is invalid | -
Resend the code to verify an email to use as 2FA recovery method.
-boolFalse#bc799737 = Bool;
-boolTrue#997275b5 = Bool;
----functions---
-account.resendPasswordEmail#7a7f2a15 = Bool;
-This constructor does not require any parameters.
-How to login to a user's account if they have enabled 2FA, how to change password.
Change privacy settings of current account
-account.privacyRules#50a04e45 rules:Vector<PrivacyRule> chats:Vector<Chat> users:Vector<User> = account.PrivacyRules;
----functions---
-account.setPrivacy#c9f81ce8 key:InputPrivacyKey rules:Vector<InputPrivacyRule> = account.PrivacyRules;
-Name | -Type | -Description | -
---|---|---|
key | -InputPrivacyKey | -Peers to which the privacy rules apply | -
rules | -Vector<InputPrivacyRule> | -New privacy rules | -
Code | -Type | -Description | -
---|---|---|
400 | -PRIVACY_KEY_INVALID | -The privacy key is invalid | -
400 | -PRIVACY_VALUE_INVALID | -The specified privacy rule combination is invalid | -
Set a new 2FA password
-boolFalse#bc799737 = Bool;
-boolTrue#997275b5 = Bool;
----functions---
-account.updatePasswordSettings#a59b102f password:InputCheckPasswordSRP new_settings:account.PasswordInputSettings = Bool;
-Name | -Type | -Description | -
---|---|---|
password | -InputCheckPasswordSRP | -The old password (see SRP) | -
new_settings | -account.PasswordInputSettings | -The new password (see SRP) | -
Code | -Type | -Description | -
---|---|---|
400 | -EMAIL_UNCONFIRMED | -Email unconfirmed | -
400 | -EMAIL_UNCONFIRMED_X | -The provided email isn't confirmed, X is the length of the verification code that was just sent to the email: use account.verifyEmail to enter the received verification code and enable the recovery email. | -
400 | -NEW_SALT_INVALID | -The new salt is invalid | -
400 | -NEW_SETTINGS_INVALID | -The new password settings are invalid | -
400 | -PASSWORD_HASH_INVALID | -The old password hash is invalid | -
400 | -SRP_ID_INVALID | -Invalid SRP ID provided | -
How to login to a user's account if they have enabled 2FA, how to change password.
-Verify an email address for telegram passport.
Changes username for the current user.
-userEmpty#200250ba id:int = User;
-user#938458c1 flags:# self:flags.10?true contact:flags.11?true mutual_contact:flags.12?true deleted:flags.13?true bot:flags.14?true bot_chat_history:flags.15?true bot_nochats:flags.16?true verified:flags.17?true restricted:flags.18?true min:flags.20?true bot_inline_geo:flags.21?true support:flags.23?true scam:flags.24?true apply_min_photo:flags.25?true id:int access_hash:flags.0?long first_name:flags.1?string last_name:flags.2?string username:flags.3?string phone:flags.4?string photo:flags.5?UserProfilePhoto status:flags.6?UserStatus bot_info_version:flags.14?int restriction_reason:flags.18?Vector<RestrictionReason> bot_inline_placeholder:flags.19?string lang_code:flags.22?string = User;
----functions---
-account.updateUsername#3e0bdd7c username:string = User;
-Name | -Type | -Description | -
---|---|---|
username | -string | -username or empty string if username is to be removed Accepted characters: a-z (case-insensitive), 0-9 and underscores. Length: 5-32 characters. |
-
Returns updated information on the user in a User type object.
-Code | -Type | -Description | -
---|---|---|
401 | -AUTH_KEY_PERM_EMPTY | -The temporary auth key must be binded to the permanent auth key to use these methods. | -
400 | -USERNAME_INVALID | -Unacceptable username | -
400 | -USERNAME_NOT_MODIFIED | -Username is not different from the current username | -
400 | -USERNAME_OCCUPIED | -Username is taken | -
Verify a phone number for telegram passport.
-boolFalse#bc799737 = Bool;
-boolTrue#997275b5 = Bool;
----functions---
-account.verifyPhone#4dd3a7f6 phone_number:string phone_code_hash:string phone_code:string = Bool;
-Name | -Type | -Description | -
---|---|---|
phone_number | -string | -Phone number | -
phone_code_hash | -string | -Phone code hash received from the call to account.sendVerifyPhoneCode | -
phone_code | -string | -Code received after the call to account.sendVerifyPhoneCode | -
Code | -Type | -Description | -
---|---|---|
400 | -PHONE_CODE_EXPIRED | -The phone code you provided has expired, this may happen if it was sent to any chat on telegram (if the code is sent through a telegram chat (not the official account) to avoid it append or prepend to the code some chars) | -
Send the verification phone code for telegram passport.
-Returns information on whether the passed phone number was registered.
- Method schema is available as of layer 78. Switch »
-Name | -Type | -Description | -
---|---|---|
phone_number | -string | -Phone number in the international format | -
The method returns an auth.CheckedPhone type object with information on whether an account with such a phone number has already been registered, as well as whether invitations were sent to this number (using the auth.sendInvites method).
-(auth.checkPhone "79123413132")
-=
-(auth.checkedPhone
- phone_registered:(boolFalse)
- phone_invited:(boolFalse)
-)
-Code | -Type | -Description | -
---|---|---|
400 | -PHONE_NUMBER_BANNED | -The provided phone number is banned from telegram | -
400 | -PHONE_NUMBER_INVALID | -Invalid phone number | -
Login using a redirected login token, generated in case of DC mismatch during QR code login.
-For more info, see login via QR code.
-auth.loginToken#629f1980 expires:int token:bytes = auth.LoginToken;
-auth.loginTokenMigrateTo#68e9916 dc_id:int token:bytes = auth.LoginToken;
-auth.loginTokenSuccess#390d5c5e authorization:auth.Authorization = auth.LoginToken;
----functions---
-auth.importLoginToken#95ac5ce4 token:bytes = auth.LoginToken;
-Name | -Type | -Description | -
---|---|---|
token | -bytes | -Login token | -
Code | -Type | -Description | -
---|---|---|
400 | -AUTH_TOKEN_EXPIRED | -The authorization token has expired | -
QR code login flow
Get all groups that can be used as discussion groups.
-Returned legacy group chats must be first upgraded to supergroups before they can be set as a discussion group.
-To set a returned supergroup as a discussion group, access to its old messages must be enabled using channels.togglePreHistoryHidden, first.
messages.chats#64ff9fd5 chats:Vector<Chat> = messages.Chats;
-messages.chatsSlice#9cd81144 count:int chats:Vector<Chat> = messages.Chats;
----functions---
-channels.getGroupsForDiscussion#f5dad378 = messages.Chats;
-This constructor does not require any parameters.
-Groups can be associated to a channel as a discussion group, to allow users to discuss about posts.
-How to handle channels, supergroups, groups, and what's the difference between them.
-Hide/unhide message history for new channel/supergroup users
Hide/unhide message history for new channel/supergroup users
-updatesTooLong#e317af7e = Updates;
-updateShortMessage#2296d2c8 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true id:int user_id:int message:string pts:int pts_count:int date:int fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?int reply_to:flags.3?MessageReplyHeader entities:flags.7?Vector<MessageEntity> = Updates;
-updateShortChatMessage#402d5dbb flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true id:int from_id:int chat_id:int message:string pts:int pts_count:int date:int fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?int reply_to:flags.3?MessageReplyHeader entities:flags.7?Vector<MessageEntity> = Updates;
-updateShort#78d4dec1 update:Update date:int = Updates;
-updatesCombined#725b04c3 updates:Vector<Update> users:Vector<User> chats:Vector<Chat> date:int seq_start:int seq:int = Updates;
-updates#74ae4240 updates:Vector<Update> users:Vector<User> chats:Vector<Chat> date:int seq:int = Updates;
-updateShortSentMessage#11f1331c flags:# out:flags.1?true id:int pts:int pts_count:int date:int media:flags.9?MessageMedia entities:flags.7?Vector<MessageEntity> = Updates;
----functions---
-channels.togglePreHistoryHidden#eabbb94c channel:InputChannel enabled:Bool = Updates;
-Name | -Type | -Description | -
---|---|---|
channel | -InputChannel | -Channel/supergroup | -
enabled | -Bool | -Hide/unhide | -
Code | -Type | -Description | -
---|---|---|
400 | -CHANNEL_INVALID | -The provided channel is invalid | -
400 | -CHANNEL_PRIVATE | -You haven't joined this channel/supergroup | -
400 | -CHAT_ADMIN_REQUIRED | -You must be an admin in this chat to do this | -
400 | -CHAT_ID_INVALID | -The provided chat id is invalid | -
400 | -CHAT_LINK_EXISTS | -The chat is public, you can't hide the history to new users | -
400 | -CHAT_NOT_MODIFIED | -The pinned message wasn't modified | -
Reset rating of top peer
-boolFalse#bc799737 = Bool;
-boolTrue#997275b5 = Bool;
----functions---
-contacts.resetTopPeerRating#1ae373ac category:TopPeerCategory peer:InputPeer = Bool;
-Name | -Type | -Description | -
---|---|---|
category | -TopPeerCategory | -Top peer category | -
peer | -InputPeer | -Peer whose rating should be reset | -
Code | -Type | -Description | -
---|---|---|
400 | -PEER_ID_INVALID | -The provided peer id is invalid | -
If enabled, the rating of top peers indicates the relevance of a frequently used peer in a certain category (frequently messaged users, frequently used bots, inline bots, frequently visited channels and so on).
Delete a peer folder
-updatesTooLong#e317af7e = Updates;
-updateShortMessage#2296d2c8 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true id:int user_id:int message:string pts:int pts_count:int date:int fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?int reply_to:flags.3?MessageReplyHeader entities:flags.7?Vector<MessageEntity> = Updates;
-updateShortChatMessage#402d5dbb flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true id:int from_id:int chat_id:int message:string pts:int pts_count:int date:int fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?int reply_to:flags.3?MessageReplyHeader entities:flags.7?Vector<MessageEntity> = Updates;
-updateShort#78d4dec1 update:Update date:int = Updates;
-updatesCombined#725b04c3 updates:Vector<Update> users:Vector<User> chats:Vector<Chat> date:int seq_start:int seq:int = Updates;
-updates#74ae4240 updates:Vector<Update> users:Vector<User> chats:Vector<Chat> date:int seq:int = Updates;
-updateShortSentMessage#11f1331c flags:# out:flags.1?true id:int pts:int pts_count:int date:int media:flags.9?MessageMedia entities:flags.7?Vector<MessageEntity> = Updates;
----functions---
-folders.deleteFolder#1c295881 folder_id:int = Updates;
-Name | -Type | -Description | -
---|---|---|
folder_id | -int | -Peer folder ID, for more info click here | -
Telegram allows placing chats into folders, based on their type, mute status, or other custom criteria, thanks to folder blacklists and whitelists.
Get information about a language in a localization pack
-langPackLanguage#eeca5ce3 flags:# official:flags.0?true rtl:flags.2?true beta:flags.3?true name:string native_name:string lang_code:string base_lang_code:flags.1?string plural_code:string strings_count:int translated_count:int translations_url:string = LangPackLanguage;
----functions---
-langpack.getLanguage#6a596502 lang_pack:string lang_code:string = LangPackLanguage;
-Name | -Type | -Description | -
---|---|---|
lang_pack | -string | -Language pack name | -
lang_code | -string | -Language code | -
Use this to accept a Seamless Telegram Login authorization request, for more info click here »
-urlAuthResultRequest#92d33a0e flags:# request_write_access:flags.0?true bot:User domain:string = UrlAuthResult;
-urlAuthResultAccepted#8f8c0e4e url:string = UrlAuthResult;
-urlAuthResultDefault#a9d6db1f = UrlAuthResult;
----functions---
-messages.acceptUrlAuth#f729ea98 flags:# write_allowed:flags.0?true peer:InputPeer msg_id:int button_id:int = UrlAuthResult;
-Name | -Type | -Description | -
---|---|---|
flags | -# | -Flags, see TL conditional fields | -
write_allowed | -flags.0?true | -Set this flag to allow the bot to send messages to you (if requested) | -
peer | -InputPeer | -The location of the message | -
msg_id | -int | -Message ID of the message with the login button | -
button_id | -int | -ID of the login button | -
Handle Seamless Telegram Login URL authorization requests.
Adds a user to a chat and sends a service message on it.
-updatesTooLong#e317af7e = Updates;
-updateShortMessage#2296d2c8 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true id:int user_id:int message:string pts:int pts_count:int date:int fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?int reply_to:flags.3?MessageReplyHeader entities:flags.7?Vector<MessageEntity> = Updates;
-updateShortChatMessage#402d5dbb flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true id:int from_id:int chat_id:int message:string pts:int pts_count:int date:int fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?int reply_to:flags.3?MessageReplyHeader entities:flags.7?Vector<MessageEntity> = Updates;
-updateShort#78d4dec1 update:Update date:int = Updates;
-updatesCombined#725b04c3 updates:Vector<Update> users:Vector<User> chats:Vector<Chat> date:int seq_start:int seq:int = Updates;
-updates#74ae4240 updates:Vector<Update> users:Vector<User> chats:Vector<Chat> date:int seq:int = Updates;
-updateShortSentMessage#11f1331c flags:# out:flags.1?true id:int pts:int pts_count:int date:int media:flags.9?MessageMedia entities:flags.7?Vector<MessageEntity> = Updates;
----functions---
-messages.addChatUser#f9a0aa09 chat_id:int user_id:InputUser fwd_limit:int = Updates;
-Name | -Type | -Description | -
---|---|---|
chat_id | -int | -Chat ID | -
user_id | -InputUser | -User ID to be added | -
fwd_limit | -int | -Number of last messages to be forwarded | -
Code | -Type | -Description | -
---|---|---|
400 | -CHAT_ADMIN_REQUIRED | -You must be an admin in this chat to do this | -
400 | -CHAT_ID_INVALID | -The provided chat id is invalid | -
403 | -CHAT_WRITE_FORBIDDEN | -You can't write in this chat | -
400 | -INPUT_USER_DEACTIVATED | -The specified user was deleted | -
400 | -PEER_ID_INVALID | -The provided peer id is invalid | -
400 | -USERS_TOO_MUCH | -The maximum number of users has been exceeded (to create a chat, for example) | -
400 | -USER_ALREADY_PARTICIPANT | -The user is already in the group | -
400 | -USER_ID_INVALID | -The provided user ID is invalid | -
403 | -USER_NOT_MUTUAL_CONTACT | -The provided user is not a mutual contact | -
403 | -USER_PRIVACY_RESTRICTED | -The user's privacy settings do not allow you to do this | -
Deletes communication history.
-messages.affectedHistory#b45c69d1 pts:int pts_count:int offset:int = messages.AffectedHistory;
----functions---
-messages.deleteHistory#1c015b09 flags:# just_clear:flags.0?true revoke:flags.1?true peer:InputPeer max_id:int = messages.AffectedHistory;
-Name | -Type | -Description | -
---|---|---|
flags | -# | -Flags, see TL conditional fields | -
just_clear | -flags.0?true | -Just clear history for the current user, without actually removing messages for every chat user | -
revoke | -flags.1?true | -Whether to delete the message history for all chat participants | -
peer | -InputPeer | -User or chat, communication history of which will be deleted | -
max_id | -int | -Maximum ID of message to delete | -
Code | -Type | -Description | -
---|---|---|
400 | -CHAT_ID_INVALID | -The provided chat id is invalid | -
400 | -MESSAGE_ID_INVALID | -The provided message id is invalid | -
400 | -MSG_ID_INVALID | -Invalid message ID provided | -
400 | -PEER_ID_INVALID | -The provided peer id is invalid | -
Edit message
-updatesTooLong#e317af7e = Updates;
-updateShortMessage#2296d2c8 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true id:int user_id:int message:string pts:int pts_count:int date:int fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?int reply_to:flags.3?MessageReplyHeader entities:flags.7?Vector<MessageEntity> = Updates;
-updateShortChatMessage#402d5dbb flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true id:int from_id:int chat_id:int message:string pts:int pts_count:int date:int fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?int reply_to:flags.3?MessageReplyHeader entities:flags.7?Vector<MessageEntity> = Updates;
-updateShort#78d4dec1 update:Update date:int = Updates;
-updatesCombined#725b04c3 updates:Vector<Update> users:Vector<User> chats:Vector<Chat> date:int seq_start:int seq:int = Updates;
-updates#74ae4240 updates:Vector<Update> users:Vector<User> chats:Vector<Chat> date:int seq:int = Updates;
-updateShortSentMessage#11f1331c flags:# out:flags.1?true id:int pts:int pts_count:int date:int media:flags.9?MessageMedia entities:flags.7?Vector<MessageEntity> = Updates;
----functions---
-messages.editMessage#48f71778 flags:# no_webpage:flags.1?true peer:InputPeer id:int message:flags.11?string media:flags.14?InputMedia reply_markup:flags.2?ReplyMarkup entities:flags.3?Vector<MessageEntity> schedule_date:flags.15?int = Updates;
-Name | -Type | -Description | -
---|---|---|
flags | -# | -Flags, see TL conditional fields | -
no_webpage | -flags.1?true | -Disable webpage preview | -
peer | -InputPeer | -Where was the message sent | -
id | -int | -ID of the message to edit | -
message | -flags.11?string | -New message | -
media | -flags.14?InputMedia | -New attached media | -
reply_markup | -flags.2?ReplyMarkup | -Reply markup for inline keyboards | -
entities | -flags.3?Vector<MessageEntity> | -Message entities for styled text | -
schedule_date | -flags.15?int | -Scheduled message date for scheduled messages | -
Code | -Type | -Description | -
---|---|---|
400 | -BUTTON_DATA_INVALID | -The data of one or more of the buttons you provided is invalid | -
400 | -BUTTON_TYPE_INVALID | -The type of one or more of the buttons you provided is invalid | -
400 | -BUTTON_URL_INVALID | -Button URL invalid | -
400 | -CHANNEL_INVALID | -The provided channel is invalid | -
400 | -CHANNEL_PRIVATE | -You haven't joined this channel/supergroup | -
400 | -CHAT_ADMIN_REQUIRED | -You must be an admin in this chat to do this | -
403 | -CHAT_WRITE_FORBIDDEN | -You can't write in this chat | -
403 | -INLINE_BOT_REQUIRED | -Only the inline bot can edit message | -
400 | -INPUT_USER_DEACTIVATED | -The specified user was deleted | -
400 | -MEDIA_CAPTION_TOO_LONG | -The caption is too long | -
400 | -MEDIA_PREV_INVALID | -Previous media invalid | -
403 | -MESSAGE_AUTHOR_REQUIRED | -Message author required | -
400 | -MESSAGE_EDIT_TIME_EXPIRED | -You can't edit this message anymore, too much time has passed since its creation. | -
400 | -MESSAGE_EMPTY | -The provided message is empty | -
400 | -MESSAGE_ID_INVALID | -The provided message id is invalid | -
400 | -MESSAGE_NOT_MODIFIED | -The message text has not changed | -
400 | -MESSAGE_TOO_LONG | -The provided message is too long | -
400 | -MSG_ID_INVALID | -Invalid message ID provided | -
400 | -PEER_ID_INVALID | -The provided peer id is invalid | -
400 | -REPLY_MARKUP_INVALID | -The provided reply markup is invalid | -
400 | -SCHEDULE_DATE_INVALID | -Invalid schedule date provided | -
400 | -USER_BANNED_IN_CHANNEL | -You're banned from sending messages in supergroups/channels | -
How to create styled text with message entities
-Telegram allows scheduling messages
Export an invite link for a chat
-chatInviteEmpty#69df3769 = ExportedChatInvite;
-chatInviteExported#fc2e05bc link:string = ExportedChatInvite;
----functions---
-messages.exportChatInvite#df7534c peer:InputPeer = ExportedChatInvite;
-Name | -Type | -Description | -
---|---|---|
peer | -InputPeer | -Chat | -
Code | -Type | -Description | -
---|---|---|
400 | -CHANNEL_PRIVATE | -You haven't joined this channel/supergroup | -
400 | -CHAT_ADMIN_REQUIRED | -You must be an admin in this chat to do this | -
400 | -CHAT_ID_INVALID | -The provided chat id is invalid | -
403 | -CHAT_WRITE_FORBIDDEN | -You can't write in this chat | -
400 | -PEER_ID_INVALID | -The provided peer id is invalid | -
Get all installed stickers
-messages.allStickersNotModified#e86602c3 = messages.AllStickers;
-messages.allStickers#edfd405f hash:int sets:Vector<StickerSet> = messages.AllStickers;
----functions---
-messages.getAllStickers#1c9618b1 hash:int = messages.AllStickers;
-Name | -Type | -Description | -
---|---|---|
hash | -int | -Hash for pagination, for more info click here | -
How to fetch results from large lists of objects.
Get folders
----functions---
-messages.getDialogFilters#f19ed96d = Vector<DialogFilter>;
-This constructor does not require any parameters.
-Telegram allows placing chats into folders, based on their type, mute status, or other custom criteria, thanks to folder blacklists and whitelists.
Get dialogs manually marked as unread
----functions---
-messages.getDialogUnreadMarks#22e24e22 = Vector<DialogPeer>;
-This constructor does not require any parameters.
-Get changed emoji keywords
-emojiKeywordsDifference#5cc761bd lang_code:string from_version:int version:int keywords:Vector<EmojiKeyword> = EmojiKeywordsDifference;
----functions---
-messages.getEmojiKeywordsDifference#1508b6af lang_code:string from_version:int = EmojiKeywordsDifference;
-Name | -Type | -Description | -
---|---|---|
lang_code | -string | -Language code | -
from_version | -int | -Previous emoji keyword localization version | -
Returns full chat info according to its ID.
-messages.chatFull#e5d7d19c full_chat:ChatFull chats:Vector<Chat> users:Vector<User> = messages.ChatFull;
----functions---
-messages.getFullChat#3b831c66 chat_id:int = messages.ChatFull;
-Name | -Type | -Description | -
---|---|---|
chat_id | -int | -Chat ID | -
Code | -Type | -Description | -
---|---|---|
400 | -CHAT_ID_INVALID | -The provided chat id is invalid | -
400 | -PEER_ID_INVALID | -The provided peer id is invalid | -
Get highscores of a game
-messages.highScores#9a3bfd99 scores:Vector<HighScore> users:Vector<User> = messages.HighScores;
----functions---
-messages.getGameHighScores#e822649d peer:InputPeer id:int user_id:InputUser = messages.HighScores;
-Name | -Type | -Description | -
---|---|---|
peer | -InputPeer | -Where was the game sent | -
id | -int | -ID of message with game media attachment | -
user_id | -InputUser | -Get high scores made by a certain user | -
Code | -Type | -Description | -
---|---|---|
400 | -MESSAGE_ID_INVALID | -The provided message id is invalid | -
400 | -PEER_ID_INVALID | -The provided peer id is invalid | -
400 | -USER_BOT_REQUIRED | -This method can only be called by a bot | -
Get highscores of a game sent using an inline bot
-messages.highScores#9a3bfd99 scores:Vector<HighScore> users:Vector<User> = messages.HighScores;
----functions---
-messages.getInlineGameHighScores#f635e1b id:InputBotInlineMessageID user_id:InputUser = messages.HighScores;
-Name | -Type | -Description | -
---|---|---|
id | -InputBotInlineMessageID | -ID of inline message | -
user_id | -InputUser | -Get high scores of a certain user | -
Code | -Type | -Description | -
---|---|---|
400 | -MESSAGE_ID_INVALID | -The provided message id is invalid | -
400 | -USER_BOT_REQUIRED | -This method can only be called by a bot | -
Get dialog info of specified peers
-messages.peerDialogs#3371c354 dialogs:Vector<Dialog> messages:Vector<Message> chats:Vector<Chat> users:Vector<User> state:updates.State = messages.PeerDialogs;
----functions---
-messages.getPeerDialogs#e470bcfd peers:Vector<InputDialogPeer> = messages.PeerDialogs;
-Name | -Type | -Description | -
---|---|---|
peers | -Vector<InputDialogPeer> | -Peers | -
Code | -Type | -Description | -
---|---|---|
400 | -CHANNEL_INVALID | -The provided channel is invalid | -
400 | -CHANNEL_PRIVATE | -You haven't joined this channel/supergroup | -
400 | -CONNECTION_DEVICE_MODEL_EMPTY | -Device model empty | -
400 | -MSG_ID_INVALID | -Invalid message ID provided | -
400 | -PEER_ID_INVALID | -The provided peer id is invalid | -
Get messages in a reply thread
-messages.messages#8c718e87 messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
-messages.messagesSlice#3a54685e flags:# inexact:flags.1?true count:int next_rate:flags.0?int offset_id_offset:flags.2?int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
-messages.channelMessages#64479808 flags:# inexact:flags.1?true pts:int count:int offset_id_offset:flags.2?int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
-messages.messagesNotModified#74535f21 count:int = messages.Messages;
----functions---
-messages.getReplies#24b581ba peer:InputPeer msg_id:int offset_id:int offset_date:int add_offset:int limit:int max_id:int min_id:int hash:int = messages.Messages;
-Name | -Type | -Description | -
---|---|---|
peer | -InputPeer | -Peer | -
msg_id | -int | -Message ID | -
offset_id | -int | -Offsets for pagination, for more info click here | -
offset_date | -int | -Offsets for pagination, for more info click here | -
add_offset | -int | -Offsets for pagination, for more info click here | -
limit | -int | -Maximum number of results to return, see pagination | -
max_id | -int | -If a positive value was transferred, the method will return only messages with ID smaller than max_id | -
min_id | -int | -If a positive value was transferred, the method will return only messages with ID bigger than min_id | -
hash | -int | -Hash for pagination, for more info click here | -
How to fetch results from large lists of objects.
Get info about a stickerset
-messages.stickerSet#b60a24a6 set:StickerSet packs:Vector<StickerPack> documents:Vector<Document> = messages.StickerSet;
----functions---
-messages.getStickerSet#2619a90e stickerset:InputStickerSet = messages.StickerSet;
-Name | -Type | -Description | -
---|---|---|
stickerset | -InputStickerSet | -Stickerset | -
Code | -Type | -Description | -
---|---|---|
400 | -STICKERSET_INVALID | -The provided sticker set is invalid | -
Install a stickerset
-messages.stickerSetInstallResultSuccess#38641628 = messages.StickerSetInstallResult;
-messages.stickerSetInstallResultArchive#35e410a8 sets:Vector<StickerSetCovered> = messages.StickerSetInstallResult;
----functions---
-messages.installStickerSet#c78fe460 stickerset:InputStickerSet archived:Bool = messages.StickerSetInstallResult;
-Name | -Type | -Description | -
---|---|---|
stickerset | -InputStickerSet | -Stickerset to install | -
archived | -Bool | -Whether to archive stickerset | -
messages.StickerSetInstallResult
-Code | -Type | -Description | -
---|---|---|
400 | -STICKERSET_INVALID | -The provided sticker set is invalid | -
Mark new featured stickers as read
-boolFalse#bc799737 = Bool;
-boolTrue#997275b5 = Bool;
----functions---
-messages.readFeaturedStickers#5b118126 id:Vector<long> = Bool;
-Name | -Type | -Description | -
---|---|---|
id | -Vector<long> | -IDs of stickersets to mark as read | -
Add GIF to saved gifs list
-boolFalse#bc799737 = Bool;
-boolTrue#997275b5 = Bool;
----functions---
-messages.saveGif#327a30cb id:InputDocument unsave:Bool = Bool;
-Name | -Type | -Description | -
---|---|---|
id | -InputDocument | -GIF to save | -
unsave | -Bool | -Whether to remove GIF from saved gifs list | -
Code | -Type | -Description | -
---|---|---|
400 | -GIF_ID_INVALID | -The provided GIF ID is invalid | -
Search for GIFs
- Method schema is available as of layer 114. Switch »
-Name | -Type | -Description | -
---|---|---|
q | -string | -Text query | -
offset | -int | -Offset for pagination » | -
Code | -Type | -Description | -
---|---|---|
400 | -SEARCH_QUERY_EMPTY | -The search query is empty | -
How to fetch results from large lists of objects.
Sends multiple messages to contacts.
-{scheme}
-Name | -Type | -Description | -
---|---|---|
contacts | -Vector<InputUser> | -List of user ID to whom a message will be sent | -
message | -string | -Message text | -
media | -InputMedia | -Message media-contents | -
Sends a text message to a secret chat.
-messages.sentEncryptedMessage#560f8935 date:int = messages.SentEncryptedMessage;
-messages.sentEncryptedFile#9493ff32 date:int file:EncryptedFile = messages.SentEncryptedMessage;
----functions---
-messages.sendEncrypted#44fa7a15 flags:# silent:flags.0?true peer:InputEncryptedChat random_id:long data:bytes = messages.SentEncryptedMessage;
-Name | -Type | -Description | -
---|---|---|
flags | -# | -Flags, see TL conditional fields | -
silent | -flags.0?true | -Send encrypted message without a notification | -
peer | -InputEncryptedChat | -Secret chat ID | -
random_id | -long | -Unique client message ID, necessary to avoid message resending | -
data | -bytes | -TL-serialization of DecryptedMessage type, encrypted with a key that was created during chat initialization | -
Code | -Type | -Description | -
---|---|---|
400 | -CHAT_ID_INVALID | -The provided chat id is invalid | -
400 | -DATA_INVALID | -Encrypted data invalid | -
400 | -ENCRYPTION_DECLINED | -The secret chat was declined | -
400 | -MSG_WAIT_FAILED | -A waiting call returned an error | -
Object describes the contents of an encrypted message.
Send an album or grouped media
-updatesTooLong#e317af7e = Updates;
-updateShortMessage#2296d2c8 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true id:int user_id:int message:string pts:int pts_count:int date:int fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?int reply_to:flags.3?MessageReplyHeader entities:flags.7?Vector<MessageEntity> = Updates;
-updateShortChatMessage#402d5dbb flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true id:int from_id:int chat_id:int message:string pts:int pts_count:int date:int fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?int reply_to:flags.3?MessageReplyHeader entities:flags.7?Vector<MessageEntity> = Updates;
-updateShort#78d4dec1 update:Update date:int = Updates;
-updatesCombined#725b04c3 updates:Vector<Update> users:Vector<User> chats:Vector<Chat> date:int seq_start:int seq:int = Updates;
-updates#74ae4240 updates:Vector<Update> users:Vector<User> chats:Vector<Chat> date:int seq:int = Updates;
-updateShortSentMessage#11f1331c flags:# out:flags.1?true id:int pts:int pts_count:int date:int media:flags.9?MessageMedia entities:flags.7?Vector<MessageEntity> = Updates;
----functions---
-messages.sendMultiMedia#cc0110cb flags:# silent:flags.5?true background:flags.6?true clear_draft:flags.7?true peer:InputPeer reply_to_msg_id:flags.0?int multi_media:Vector<InputSingleMedia> schedule_date:flags.10?int = Updates;
-Name | -Type | -Description | -
---|---|---|
flags | -# | -Flags, see TL conditional fields | -
silent | -flags.5?true | -Whether to send the album silently (no notification triggered) | -
background | -flags.6?true | -Send in background? | -
clear_draft | -flags.7?true | -Whether to clear drafts | -
peer | -InputPeer | -The destination chat | -
reply_to_msg_id | -flags.0?int | -The message to reply to | -
multi_media | -Vector<InputSingleMedia> | -The medias to send | -
schedule_date | -flags.10?int | -Scheduled message date for scheduled messages | -
Code | -Type | -Description | -
---|---|---|
400 | -CHAT_ADMIN_REQUIRED | -You must be an admin in this chat to do this | -
400 | -MEDIA_EMPTY | -The provided media object is invalid | -
400 | -MEDIA_INVALID | -Media invalid | -
400 | -MULTI_MEDIA_TOO_LONG | -Too many media files for album | -
400 | -PEER_ID_INVALID | -The provided peer id is invalid | -
400 | -RANDOM_ID_EMPTY | -Random ID empty | -
How to handle message drafts
-How to transfer large data batches correctly.
Vote in a poll
-updatesTooLong#e317af7e = Updates;
-updateShortMessage#2296d2c8 flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true id:int user_id:int message:string pts:int pts_count:int date:int fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?int reply_to:flags.3?MessageReplyHeader entities:flags.7?Vector<MessageEntity> = Updates;
-updateShortChatMessage#402d5dbb flags:# out:flags.1?true mentioned:flags.4?true media_unread:flags.5?true silent:flags.13?true id:int from_id:int chat_id:int message:string pts:int pts_count:int date:int fwd_from:flags.2?MessageFwdHeader via_bot_id:flags.11?int reply_to:flags.3?MessageReplyHeader entities:flags.7?Vector<MessageEntity> = Updates;
-updateShort#78d4dec1 update:Update date:int = Updates;
-updatesCombined#725b04c3 updates:Vector<Update> users:Vector<User> chats:Vector<Chat> date:int seq_start:int seq:int = Updates;
-updates#74ae4240 updates:Vector<Update> users:Vector<User> chats:Vector<Chat> date:int seq:int = Updates;
-updateShortSentMessage#11f1331c flags:# out:flags.1?true id:int pts:int pts_count:int date:int media:flags.9?MessageMedia entities:flags.7?Vector<MessageEntity> = Updates;
----functions---
-messages.sendVote#10ea6184 peer:InputPeer msg_id:int options:Vector<bytes> = Updates;
-Name | -Type | -Description | -
---|---|---|
peer | -InputPeer | -The chat where the poll was sent | -
msg_id | -int | -The message ID of the poll | -
options | -Vector<bytes> | -The options that were chosen | -
Code | -Type | -Description | -
---|---|---|
400 | -MESSAGE_ID_INVALID | -The provided message id is invalid | -
400 | -MESSAGE_POLL_CLOSED | -Poll closed | -
400 | -OPTIONS_TOO_MUCH | -Too many options provided | -
400 | -OPTION_INVALID | -Invalid option selected | -
400 | -REVOTE_NOT_ALLOWED | -You cannot change your vote | -
Poll
Uninstall a stickerset
-boolFalse#bc799737 = Bool;
-boolTrue#997275b5 = Bool;
----functions---
-messages.uninstallStickerSet#f96e55de stickerset:InputStickerSet = Bool;
-Name | -Type | -Description | -
---|---|---|
stickerset | -InputStickerSet | -The stickerset to uninstall | -
Code | -Type | -Description | -
---|---|---|
400 | -STICKERSET_INVALID | -The provided sticker set is invalid | -
Reorder folders
-boolFalse#bc799737 = Bool;
-boolTrue#997275b5 = Bool;
----functions---
-messages.updateDialogFiltersOrder#c563c1e4 order:Vector<int> = Bool;
-Name | -Type | -Description | -
---|---|---|
order | -Vector<int> | -New folder order | -
Telegram allows placing chats into folders, based on their type, mute status, or other custom criteria, thanks to folder blacklists and whitelists.
Get info about a credit card
-payments.bankCardData#3e24e573 title:string open_urls:Vector<BankCardOpenUrl> = payments.BankCardData;
----functions---
-payments.getBankCardData#2e79d779 number:string = payments.BankCardData;
-Name | -Type | -Description | -
---|---|---|
number | -string | -Credit card number | -
Send phone call debug data to server
-boolFalse#bc799737 = Bool;
-boolTrue#997275b5 = Bool;
----functions---
-phone.saveCallDebug#277add7e peer:InputPhoneCall debug:DataJSON = Bool;
-Name | -Type | -Description | -
---|---|---|
peer | -InputPhoneCall | -Phone call | -
debug | -DataJSON | -Debug statistics obtained from libtgvoip | -
Code | -Type | -Description | -
---|---|---|
400 | -CALL_PEER_INVALID | -The provided call peer object is invalid | -
400 | -DATA_JSON_INVALID | -The provided JSON data is invalid | -
Deletes profile photos.
----functions---
-photos.deletePhotos#87cf7f2f id:Vector<InputPhoto> = Vector<long>;
-Name | -Type | -Description | -
---|---|---|
id | -Vector<InputPhoto> | -Input photos to delete | -
Method returns a list of successfully deleted photos in Vector<long>
stats.megagroupStats#ef7ff916 period:StatsDateRangeDays members:StatsAbsValueAndPrev messages:StatsAbsValueAndPrev viewers:StatsAbsValueAndPrev posters:StatsAbsValueAndPrev growth_graph:StatsGraph members_graph:StatsGraph new_members_by_source_graph:StatsGraph languages_graph:StatsGraph messages_graph:StatsGraph actions_graph:StatsGraph top_hours_graph:StatsGraph weekdays_graph:StatsGraph top_posters:Vector<StatsGroupTopPoster> top_admins:Vector<StatsGroupTopAdmin> top_inviters:Vector<StatsGroupTopInviter> users:Vector<User> = stats.MegagroupStats;
----functions---
-stats.getMegagroupStats#dcdf8607 flags:# dark:flags.0?true channel:InputChannel = stats.MegagroupStats;
-Name | -Type | -Description | -
---|---|---|
flags | -# | -Flags, see TL conditional fields | -
dark | -flags.0?true | -Whether to enable dark theme for graph colors | -
channel | -InputChannel | -Supergroup ID | -
How to handle channels, supergroups, groups, and what's the difference between them.
-Telegram offers detailed channel statistics for channels and supergroups.
Obtains a list of messages, indicating to which other public channels was a channel message forwarded.
-Will return a list of messages with peer_id
equal to the public channel to which this message was forwarded.
messages.messages#8c718e87 messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
-messages.messagesSlice#3a54685e flags:# inexact:flags.1?true count:int next_rate:flags.0?int offset_id_offset:flags.2?int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
-messages.channelMessages#64479808 flags:# inexact:flags.1?true pts:int count:int offset_id_offset:flags.2?int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
-messages.messagesNotModified#74535f21 count:int = messages.Messages;
----functions---
-stats.getMessagePublicForwards#5630281b channel:InputChannel msg_id:int offset_rate:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages;
-Name | -Type | -Description | -
---|---|---|
channel | -InputChannel | -Source channel | -
msg_id | -int | -Source message ID | -
offset_rate | -int | -Initially 0, then set to the next_rate parameter of messages.messagesSlice |
-
offset_peer | -InputPeer | -Offsets for pagination, for more info click here | -
offset_id | -int | -Offsets for pagination, for more info click here | -
limit | -int | -Maximum number of results to return, see pagination | -
Code | -Type | -Description | -
---|---|---|
400 | -CHANNEL_INVALID | -The provided channel is invalid | -
400 | -MESSAGE_ID_INVALID | -The provided message id is invalid | -
Incomplete list of messages and auxiliary data.
-How to fetch results from large lists of objects.
-A message
Name | -Description | -
---|---|
help.getTermsOfServiceUpdate | -Look for updates of telegram's terms of service | -
help.acceptTermsOfService | -Accept the new terms of service | -
Name | -Description | -
---|---|
account.reportPeer | -Report a peer for violation of telegram's Terms of Service | -
channels.reportSpam | -Reports some messages from a user in a supergroup as spam; requires administrator rights in the supergroup | -
messages.report | -Report a message in a chat for violation of telegram's Terms of Service | -
messages.reportSpam | -Report a new incoming chat for spam, if the peer settings of the chat allow us to do that | -
messages.reportEncryptedSpam | -Report a secret chat for spam | -
Name | -Description | -
---|---|
help.getAppChangelog | -Get changelog of current app. Typically, an updates constructor will be returned, containing one or more updateServiceNotification updates with app-specific changelogs. |
-
help.getAppConfig | -Get app-specific configuration, see client configuration for more info on the result. | -
help.getAppUpdate | -Returns information on update availability for the current application. | -
help.getConfig | -Returns current configuration, including data center configuration. | -
help.getInviteText | -Returns localized text of a text message with an invitation. | -
help.getNearestDc | -Returns info on data centre nearest to the user. | -
help.getSupport | -Returns the support user for the 'ask a question' feature. | -
help.getSupportName | -Get localized name of the telegram support user | -
help.getCountriesList | -Get name, ISO code, localized name and phone codes/patterns of all available countries | -
help.dismissSuggestion | -Dismiss a suggestion | -
Name | -Description | -
---|---|
auth.exportLoginToken | -Generate a login token, for login via QR code. The generated login token should be encoded using base64url, then shown as a tg://login?token=base64encodedtoken URL in the QR code.For more info, see login via QR code. |
-
auth.acceptLoginToken | -Accept QR code login token, logging in the app that generated it. Returns info about the new session. For more info, see login via QR code. |
-
auth.importLoginToken | -Login using a redirected login token, generated in case of DC mismatch during QR code login. For more info, see login via QR code. |
-
Name | -Description | -
---|---|
help.saveAppLog | -Saves logs of application on the server. | -
initConnection | -Initialize connection | -
invokeAfterMsg | -Invokes a query after successfull completion of one of the previous queries. | -
invokeAfterMsgs | -Invokes a query after a successfull completion of previous queries | -
invokeWithLayer | -Invoke the specified query using the specified API layer | -
invokeWithoutUpdates | -Invoke a request without subscribing the used connection for updates (this is enabled by default for file queries). | -
Name | -Description | -
---|---|
auth.bindTempAuthKey | -Binds a temporary authorization key temp_auth_key_id to the permanent authorization key perm_auth_key_id . Each permanent key may only be bound to one temporary key at a time, binding a new temporary key overwrites the previous one.For more information, see Perfect Forward Secrecy. |
-
auth.cancelCode | -Cancel the login verification code | -
auth.checkPassword | -Try logging to an account protected by a 2FA password. | -
auth.dropTempAuthKeys | -Delete all temporary authorization keys except for the ones specified | -
auth.exportAuthorization | -Returns data for copying authorization to another data-centre. | -
auth.importAuthorization | -Logs in a user using a key transmitted from his native data-centre. | -
auth.importBotAuthorization | -Login as a bot | -
auth.logOut | -Logs out the user. | -
auth.recoverPassword | -Reset the 2FA password using the recovery code sent using auth.requestPasswordRecovery. | -
auth.requestPasswordRecovery | -Request recovery code of a 2FA password, only for accounts with a recovery email configured. | -
auth.resendCode | -Resend the login code via another medium, the phone code type is determined by the return value of the previous auth.sendCode/auth.resendCode: see login for more info. | -
auth.resetAuthorizations | -Terminates all user's authorized sessions except for the current one. After calling this method it is necessary to reregister the current device using the method account.registerDevice |
-
auth.sendCode | -Send the verification code for login | -
auth.signIn | -Signs in a user with a validated phone number. | -
auth.signUp | -Registers a validated phone number in the system. | -
Name | -Description | -
---|---|
account.initTakeoutSession | -Intialize account takeout session | -
account.finishTakeoutSession | -Finish account takeout session | -
messages.getSplitRanges | -Get message ranges for saving the user's chat history | -
channels.getLeftChannels | -Get a list of channels/supergroups we left | -
invokeWithMessagesRange | -Invoke with the given message range | -
invokeWithTakeout | -Invoke a method within a takeout session | -
Name | -Description | -
---|---|
messages.getSavedGifs | -Get saved GIFs | -
messages.saveGif | -Add GIF to saved gifs list | -
messages.searchGifs | -Search for GIFs | -
Name | -Description | -
---|---|
help.hidePromoData | -Hide MTProxy/Public Service Announcement information | -
help.getPromoData | -Get MTProxy/Public Service Announcement information | -
Name | -Description | -
---|---|
help.editUserInfo | -Internal use | -
help.getUserInfo | -Internal use | -
Name | -Description | -
---|---|
account.confirmPasswordEmail | -Verify an email to use as 2FA recovery method. | -
account.resendPasswordEmail | -Resend the code to verify an email to use as 2FA recovery method. | -
account.cancelPasswordEmail | -Cancel the code that was sent to verify an email to use as 2FA recovery method. | -
account.getPassword | -Obtain configuration for two-factor authorization with password | -
account.getPasswordSettings | -Get private info associated to the password info (recovery email, telegram passport info & so on) | -
account.updatePasswordSettings | -Set a new 2FA password | -
Name | -Description | -
---|---|
messages.requestUrlAuth | -Get more info about a Seamless Telegram Login authorization request, for more info click here » | -
messages.acceptUrlAuth | -Use this to accept a Seamless Telegram Login authorization request, for more info click here » | -
account.getWebAuthorizations | -Get web login widget authorizations | -
account.resetWebAuthorization | -Log out an active web telegram login session | -
account.resetWebAuthorizations | -Reset all active web telegram login sessions | -
Name | -Description | -
---|---|
phone.acceptCall | -Accept incoming call | -
phone.confirmCall | -Complete phone call E2E encryption key exchange » | -
phone.discardCall | -Refuse or end running call | -
phone.getCallConfig | -Get phone call configuration to be passed to libtgvoip's shared config | -
phone.receivedCall | -Optional: notify the server that the user is currently busy in a call: this will automatically refuse all incoming phone calls until the current phone call is ended. | -
phone.requestCall | -Start a telegram phone call | -
phone.saveCallDebug | -Send phone call debug data to server | -
phone.sendSignalingData | -Send VoIP signaling data | -
phone.setCallRating | -Rate a call | -
Name | -Description | -
---|---|
channels.createChannel | -Create a supergroup/channel. | -
channels.getInactiveChannels | -Get inactive channels and supergroups | -
channels.deleteChannel | -Delete a channel/supergroup | -
channels.deleteHistory | -Delete the history of a supergroup | -
channels.deleteMessages | -Delete messages in a channel/supergroup | -
channels.deleteUserHistory | -Delete all messages sent by a certain user in a supergroup | -
channels.editAdmin | -Modify the admin rights of a user in a supergroup/channel. | -
channels.editBanned | -Ban/unban/kick a user in a supergroup/channel. | -
channels.editCreator | -Transfer channel ownership | -
channels.editLocation | -Edit location of geogroup | -
channels.editPhoto | -Change the photo of a channel/supergroup | -
channels.editTitle | -Edit the name of a channel/supergroup | -
channels.exportMessageLink | -Get link and embed info of a message in a channel/supergroup | -
channels.getAdminLog | -Get the admin log of a channel/supergroup | -
channels.getAdminedPublicChannels | -Get channels/supergroups/geogroups we're admin in. Usually called when the user exceeds the limit for owned public channels/supergroups/geogroups, and the user is given the choice to remove one of his channels/supergroups/geogroups. | -
channels.getChannels | -Get info about channels/supergroups | -
channels.getFullChannel | -Get full info about a channel | -
channels.getGroupsForDiscussion | -Get all groups that can be used as discussion groups. Returned legacy group chats must be first upgraded to supergroups before they can be set as a discussion group. To set a returned supergroup as a discussion group, access to its old messages must be enabled using channels.togglePreHistoryHidden, first. |
-
channels.getMessages | -Get channel/supergroup messages | -
channels.getParticipant | -Get info about a channel/supergroup participant | -
channels.getParticipants | -Get the participants of a supergroup/channel | -
channels.inviteToChannel | -Invite users to a channel/supergroup | -
channels.joinChannel | -Join a channel/supergroup | -
channels.leaveChannel | -Leave a channel/supergroup | -
channels.readHistory | -Mark channel/supergroup history as read | -
channels.readMessageContents | -Mark channel/supergroup message contents as read | -
channels.setDiscussionGroup | -Associate a group to a channel as discussion group for that channel | -
channels.setStickers | -Associate a stickerset to the supergroup | -
channels.togglePreHistoryHidden | -Hide/unhide message history for new channel/supergroup users | -
channels.toggleSignatures | -Enable/disable message signatures in channels | -
channels.toggleSlowMode | -Toggle supergroup slow mode: if enabled, users will only be able to send one message every seconds seconds |
-
messages.getStatsURL | -Returns URL with the chat statistics. Currently this method can be used only for channels | -
Name | -Description | -
---|---|
messages.addChatUser | -Adds a user to a chat and sends a service message on it. | -
messages.checkChatInvite | -Check the validity of a chat invite link and get basic info about it | -
messages.createChat | -Creates a new chat. | -
messages.deleteChatUser | -Deletes a user from a chat and sends a service message on it. | -
messages.editChatAbout | -Edit the description of a group/supergroup/channel. | -
messages.editChatAdmin | -Make a user admin in a legacy group. | -
messages.editChatDefaultBannedRights | -Edit the default banned rights of a channel/supergroup/group. | -
messages.editChatPhoto | -Changes chat photo and sends a service message on it | -
messages.editChatTitle | -Chanages chat name and sends a service message on it. | -
messages.exportChatInvite | -Export an invite link for a chat | -
messages.getAllChats | -Get all chats, channels and supergroups | -
messages.getChats | -Returns chat basic info on their IDs. | -
messages.getCommonChats | -Get chats in common with a user | -
messages.getFullChat | -Returns full chat info according to its ID. | -
messages.importChatInvite | -Import a chat invite and join a private chat/supergroup/channel | -
messages.migrateChat | -Turn a legacy group into a supergroup | -
Name | -Description | -
---|---|
messages.startBot | -Start a conversation with a bot using a deep linking parameter | -
help.getDeepLinkInfo | -Get info about a t.me link |
-
help.getRecentMeUrls | -Get recently used t.me links |
-
Name | -Description | -
---|---|
help.getCdnConfig | -Get configuration for CDN file downloads. | -
upload.getCdnFile | -Download a CDN file. | -
upload.getCdnFileHashes | -Get SHA256 hashes for verifying downloaded CDN files | -
upload.reuploadCdnFile | -Request a reupload of a certain file to a CDN DC. | -
upload.getFile | -Returns content of a whole file or its part. | -
upload.getFileHashes | -Get SHA256 hashes for verifying downloaded files | -
upload.getWebFile | -Returns content of an HTTP file or a part, by proxying the request through telegram. | -
upload.saveBigFilePart | -Saves a part of a large file (over 10Mb in size) to be later passed to one of the methods. | -
upload.saveFilePart | -Saves a part of file for futher sending to one of the methods. | -
messages.uploadEncryptedFile | -Upload encrypted file and associate it to a secret chat | -
messages.uploadMedia | -Upload a file and associate it to a chat (without actually sending it to the chat) | -
messages.getDocumentByHash | -Get a document by its SHA256 hash, mainly used for gifs | -
Name | -Description | -
---|---|
messages.getWebPage | -Get instant view page | -
messages.getWebPagePreview | -Get preview of webpage | -
Name | -Description | -
---|---|
messages.setEncryptedTyping | -Send typing event by the current user to a secret chat. | -
messages.readEncryptedHistory | -Marks message history within a secret chat as read. | -
messages.acceptEncryption | -Confirms creation of a secret chat | -
messages.discardEncryption | -Cancels a request for creation and/or delete info on secret chat. | -
messages.requestEncryption | -Sends a request to start a secret chat to the user. | -
messages.sendEncrypted | -Sends a text message to a secret chat. | -
messages.sendEncryptedFile | -Sends a message with a file attachment to a secret chat | -
messages.sendEncryptedService | -Sends a service message to a secret chat. | -
messages.getDhConfig | -Returns configuration parameters for Diffie-Hellman key generation. Can also return a random sequence of bytes of required length. | -
messages.receivedQueue | -Confirms receipt of messages in a secret chat by client, cancels push notifications. | -
Name | -Description | -
---|---|
account.sendVerifyEmailCode | -Send the verification email code for telegram passport. | -
account.verifyEmail | -Verify an email address for telegram passport. | -
account.sendVerifyPhoneCode | -Send the verification phone code for telegram passport. | -
account.verifyPhone | -Verify a phone number for telegram passport. | -
account.acceptAuthorization | -Sends a Telegram Passport authorization form, effectively sharing data with the service | -
account.getAuthorizationForm | -Returns a Telegram Passport authorization form for sharing data with a service | -
account.getAuthorizations | -Get logged-in sessions | -
account.deleteSecureValue | -Delete stored Telegram Passport documents, for more info see the passport docs » | -
account.getAllSecureValues | -Get all saved Telegram Passport documents, for more info see the passport docs » | -
account.getSecureValue | -Get saved Telegram Passport document, for more info see the passport docs » | -
account.saveSecureValue | -Securely save Telegram Passport document, for more info see the passport docs » | -
help.getPassportConfig | -Get passport configuration | -
users.setSecureValueErrors | -Notify the user that the sent passport data contains some errors The user will not be able to re-submit their Passport data to you until the errors are fixed (the contents of the field for which you returned the error must change). Use this if the data submitted by the user doesn't satisfy the standards your service requires for any reason. For example, if a birthday date seems invalid, a submitted document is blurry, a scan shows evidence of tampering, etc. Supply some details in the error message to make sure the user knows how to correct the issues. |
-
Name | -Description | -
---|---|
updates.getChannelDifference | -Returns the difference between the current state of updates of a certain channel and transmitted. | -
updates.getDifference | -Get new updates. | -
updates.getState | -Returns a current state of updates. | -
Name | -Description | -
---|---|
messages.getInlineBotResults | -Query an inline bot | -
messages.setInlineBotResults | -Answer an inline query, for bots only | -
messages.sendInlineBotResult | -Send a result obtained using messages.getInlineBotResults. | -
messages.getBotCallbackAnswer | -Press an inline callback button and get a callback answer from the bot | -
messages.setBotCallbackAnswer | -Set the callback answer to a user button press (bots only) | -
messages.editInlineBotMessage | -Edit an inline bot message | -
Name | -Description | -
---|---|
bots.setBotCommands | -Set bot command list | -
Name | -Description | -
---|---|
bots.answerWebhookJSONQuery | -Answers a custom query; for bots only | -
bots.sendCustomRequest | -Sends a custom request; for bots only | -
help.setBotUpdatesStatus | -Informs the server about the number of pending bot updates if they haven't been processed for a long time; for bots only | -
Name | -Description | -
---|---|
account.updateTheme | -Update theme | -
account.uploadTheme | -Upload theme | -
account.getThemes | -Get installed themes | -
account.createTheme | -Create a theme | -
account.installTheme | -Install a theme | -
account.saveTheme | -Save a theme | -
account.getTheme | -Get theme information | -
Name | -Description | -
---|---|
account.getContactSignUpNotification | -Whether the user will receive notifications when contacts sign up | -
account.setContactSignUpNotification | -Toggle contact sign up notifications | -
contacts.acceptContact | -If the peer settings of a new user allow us to add him as contact, add that user as contact | -
contacts.addContact | -Add an existing telegram user as contact. Use contacts.importContacts to add contacts by phone number, without knowing their Telegram ID. |
-
contacts.block | -Adds the user to the blacklist. | -
contacts.deleteByPhones | -Delete contacts by phone number | -
contacts.deleteContacts | -Deletes several contacts from the list. | -
contacts.getBlocked | -Returns the list of blocked users. | -
contacts.getContactIDs | -Get contact by telegram IDs | -
contacts.getContacts | -Returns the current user's contact list. | -
contacts.getLocated | -Get contacts near you | -
contacts.getSaved | -Get all contacts | -
contacts.getStatuses | -Returns the list of contact statuses. | -
contacts.getTopPeers | -Get most used peers | -
contacts.importContacts | -Imports contacts: saves a full list on the server, adds already registered contacts to the contact list, returns added contacts and their info. Use contacts.addContact to add Telegram contacts without actually using their phone number. |
-
contacts.resetSaved | -Delete saved contacts | -
contacts.resetTopPeerRating | -Reset rating of top peer | -
contacts.search | -Returns users found by username substring. | -
contacts.toggleTopPeers | -Enable/disable top peers | -
contacts.unblock | -Deletes the user from the blacklist. | -
Name | -Description | -
---|---|
payments.getBankCardData | -Get info about a credit card | -
Name | -Description | -
---|---|
messages.getDialogs | -Returns the current user dialog list. | -
messages.getPeerDialogs | -Get dialog info of specified peers | -
messages.getPinnedDialogs | -Get pinned dialogs | -
messages.toggleDialogPin | -Pin/unpin a dialog | -
messages.reorderPinnedDialogs | -Reorder pinned dialogs | -
messages.getDialogUnreadMarks | -Get dialogs manually marked as unread | -
messages.markDialogUnread | -Manually mark dialog as unread | -
messages.getPeerSettings | -Get peer settings | -
messages.hidePeerSettingsBar | -Should be called after the user hides the report spam/add as contact bar of a new chat, effectively prevents the user from executing the actions specified in the peer's settings. | -
messages.getOnlines | -Get count of online users in a chat | -
messages.sendScreenshotNotification | -Notify the other user in a private chat that a screenshot of the chat was taken | -
messages.setTyping | -Sends a current user typing event (see SendMessageAction for all event types) to a conversation partner or group. | -
Name | -Description | -
---|---|
messages.clearAllDrafts | -Clear all drafts. | -
messages.getAllDrafts | -Save get all message drafts. | -
messages.saveDraft | -Save a message draft associated to a chat. | -
Name | -Description | -
---|---|
messages.getEmojiKeywords | -Get localized emoji keywords | -
messages.getEmojiKeywordsDifference | -Get changed emoji keywords | -
messages.getEmojiKeywordsLanguages | -Get info about an emoji keyword localization | -
messages.getEmojiURL | -Returns an HTTP URL which can be used to automatically log in into translation platform and suggest new emoji replacements. The URL will be valid for 30 seconds after generation | -
Name | -Description | -
---|---|
messages.updateDialogFiltersOrder | -Reorder folders | -
messages.getDialogFilters | -Get folders | -
messages.getSuggestedDialogFilters | -Get suggested folders | -
messages.updateDialogFilter | -Update folder | -
folders.deleteFolder | -Delete a peer folder | -
folders.editPeerFolders | -Edit peers in peer folder | -
Name | -Description | -
---|---|
messages.getGameHighScores | -Get highscores of a game | -
messages.getInlineGameHighScores | -Get highscores of a game sent using an inline bot | -
messages.setGameScore | -Use this method to set the score of the specified user in a game sent as a normal message (bots only). | -
messages.setInlineGameScore | -Use this method to set the score of the specified user in a game sent as an inline message (bots only). | -
Name | -Description | -
---|---|
langpack.getDifference | -Get new strings in languagepack | -
langpack.getLangPack | -Get localization pack strings | -
langpack.getLanguage | -Get information about a language in a localization pack | -
langpack.getLanguages | -Get information about all languages in a localization pack | -
langpack.getStrings | -Get strings from a language pack | -
Name | -Description | -
---|---|
account.getAutoDownloadSettings | -Get media autodownload settings | -
account.saveAutoDownloadSettings | -Change media autodownload settings | -
Name | -Description | -
---|---|
messages.getReplies | -Get messages in a reply thread | -
contacts.blockFromReplies | -Stop getting notifications about thread replies of a certain user in @replies |
-
messages.getDiscussionMessage | -Get discussion message from the associated discussion group of a channel to show it on top of the comment section, without actually joining the group | -
messages.readDiscussion | -Mark a thread as read | -
Name | -Description | -
---|---|
messages.getMessagesReactions | -Get message reactions | -
messages.sendReaction | -Send reaction to message | -
messages.getMessageReactionsList | -Get full message reaction list | -
Name | -Description | -
---|---|
messages.deleteHistory | -Deletes communication history. | -
messages.deleteMessages | -Deletes messages by their identifiers. | -
messages.editMessage | -Edit message | -
messages.forwardMessages | -Forwards messages by their IDs. | -
messages.getHistory | -Gets back the conversation history with one interlocutor / within a chat | -
messages.getMessageEditData | -Find out if a media message's caption can be edited | -
messages.getMessages | -Returns the list of messages by their IDs. | -
messages.getMessagesViews | -Get and increase the view counter of a message sent or forwarded from a channel | -
messages.getRecentLocations | -Get live location history of a certain user | -
messages.getSearchCounters | -Get the number of results that would be found by a messages.search call with the same parameters | -
messages.getUnreadMentions | -Get unread messages where we were mentioned | -
messages.readHistory | -Marks message history as read. | -
messages.readMentions | -Mark mentions as read | -
messages.readMessageContents | -Notifies the sender about the recipient having listened a voice message or watched a video. | -
messages.receivedMessages | -Confirms receipt of messages by a client, cancels PUSH-notification sending. | -
messages.search | -Gets back found messages | -
messages.searchGlobal | -Search for messages and peers globally | -
messages.sendMedia | -Send a media | -
messages.sendMessage | -Sends a message to a chat | -
messages.sendMultiMedia | -Send an album or grouped media | -
messages.updatePinnedMessage | -Pin a message | -
messages.unpinAllMessages | -Unpin all pinned messages | -
Name | -Description | -
---|---|
account.registerDevice | -Register device to receive PUSH notifications | -
account.unregisterDevice | -Deletes a device by its token, stops sending PUSH-notifications to it. | -
account.updateDeviceLocked | -When client-side passcode lock feature is enabled, will not show message texts in incoming PUSH notifications. | -
account.getNotifyExceptions | -Returns list of chats with non-default notification settings | -
account.getNotifySettings | -Gets current notification settings for a given user/group, from all users/all groups. | -
account.updateNotifySettings | -Edits notification settings from a given user/group, from all users/all groups. | -
account.resetNotifySettings | -Resets all notification settings from users and groups. | -
Name | -Description | -
---|---|
users.getFullUser | -Returns extended user info by ID. | -
users.getUsers | -Returns basic user info according to their identifiers. | -
Name | -Description | -
---|---|
payments.getSavedInfo | -Get saved payment information | -
payments.clearSavedInfo | -Clear saved payment information | -
payments.getPaymentForm | -Get a payment form | -
payments.validateRequestedInfo | -Submit requested order information for validation | -
messages.setBotShippingResults | -If you sent an invoice requesting a shipping address and the parameter is_flexible was specified, the bot will receive an updateBotShippingQuery update. Use this method to reply to shipping queries. | -
account.getTmpPassword | -Get temporary payment password | -
payments.sendPaymentForm | -Send compiled payment form | -
messages.setBotPrecheckoutResults | -Once the user has confirmed their payment and shipping details, the bot receives an updateBotPrecheckoutQuery update. Use this method to respond to such pre-checkout queries. Note: Telegram must receive an answer within 10 seconds after the pre-checkout query was sent. |
-
payments.getPaymentReceipt | -Get payment receipt | -
Name | -Description | -
---|---|
messages.getPollResults | -Get poll results | -
messages.getPollVotes | -Get poll results for non-anonymous polls | -
messages.sendVote | -Vote in a poll | -
Name | -Description | -
---|---|
messages.sendScheduledMessages | -Send scheduled messages right away | -
messages.getScheduledHistory | -Get scheduled messages | -
messages.deleteScheduledMessages | -Delete scheduled messages | -
messages.getScheduledMessages | -Get scheduled messages | -
Name | -Description | -
---|---|
account.getContentSettings | -Get sensitive content settings | -
account.setContentSettings | -Set sensitive content settings (for viewing or hiding NSFW content) | -
Name | -Description | -
---|---|
help.getProxyData | -Get promotion info of the currently-used MTProxy | -
Name | -Description | -
---|---|
stats.loadAsyncGraph | -Load channel statistics graph asynchronously | -
stats.getBroadcastStats | -Get channel statistics | -
stats.getMessagePublicForwards | -Obtains a list of messages, indicating to which other public channels was a channel message forwarded. Will return a list of messages with peer_id equal to the public channel to which this message was forwarded. |
-
stats.getMegagroupStats | -Get supergroup statistics | -
stats.getMessageStats | -Get message statistics | -
Name | -Description | -
---|---|
messages.getOldFeaturedStickers | -Method for fetching previously featured stickers | -
messages.toggleStickerSets | -Apply changes to multiple stickersets | -
stickers.setStickerSetThumb | -Set stickerset thumbnail | -
stickers.addStickerToSet | -Add a sticker to a stickerset, bots only. The sticker set must have been created by the bot. | -
stickers.changeStickerPosition | -Changes the absolute position of a sticker in the set to which it belongs; for bots only. The sticker set must have been created by the bot | -
stickers.createStickerSet | -Create a stickerset, bots only. | -
stickers.removeStickerFromSet | -Remove a sticker from the set where it belongs, bots only. The sticker set must have been created by the bot. | -
messages.clearRecentStickers | -Clear recent stickers | -
messages.faveSticker | -Mark a sticker as favorite | -
messages.getAllStickers | -Get all installed stickers | -
messages.getArchivedStickers | -Get all archived stickers | -
messages.getAttachedStickers | -Get stickers attached to a photo or video | -
messages.getFavedStickers | -Get faved stickers | -
messages.getFeaturedStickers | -Get featured stickers | -
messages.getMaskStickers | -Get installed mask stickers | -
messages.getRecentStickers | -Get recent stickers | -
messages.getStickerSet | -Get info about a stickerset | -
messages.getStickers | -Get stickers by emoji | -
messages.saveRecentSticker | -Add/remove sticker from recent stickers list | -
messages.installStickerSet | -Install a stickerset | -
messages.readFeaturedStickers | -Mark new featured stickers as read | -
messages.reorderStickerSets | -Reorder installed stickersets | -
messages.searchStickerSets | -Search for stickersets | -
messages.uninstallStickerSet | -Uninstall a stickerset | -
Name | -Description | -
---|---|
account.changePhone | -Change the phone number of the current account | -
account.confirmPhone | -Confirm a phone number to cancel account deletion, for more info click here » | -
account.deleteAccount | -Delete the user's account from the telegram servers. Can be used, for example, to delete the account of a user that provided the login code, but forgot the 2FA password and no recovery method is configured. | -
account.getAccountTTL | -Get days to live of account | -
account.getPrivacy | -Get privacy settings of current account | -
account.resetAuthorization | -Log out an active authorized session by its hash | -
account.sendChangePhoneCode | -Verify a new phone number to associate to the current account | -
account.sendConfirmPhoneCode | -Send confirmation code to cancel account deletion, for more info click here » | -
account.setAccountTTL | -Set account self-destruction period | -
account.setPrivacy | -Change privacy settings of current account | -
account.setGlobalPrivacySettings | -Set global privacy settings | -
account.getGlobalPrivacySettings | -Get global privacy settings | -
account.updateProfile | -Updates user profile. | -
account.updateStatus | -Updates online user status. | -
Name | -Description | -
---|---|
photos.deletePhotos | -Deletes profile photos. | -
photos.getUserPhotos | -Returns the list of user photos. | -
photos.updateProfilePhoto | -Installs a previously uploaded photo as a profile photo. | -
photos.uploadProfilePhoto | -Updates current user profile photo. | -
Name | -Description | -
---|---|
channels.checkUsername | -Check if a username is free and can be assigned to a channel/supergroup | -
channels.updateUsername | -Change the username of a supergroup/channel | -
account.updateUsername | -Changes username for the current user. | -
account.checkUsername | -Validates a username and checks availability. | -
contacts.resolveUsername | -Resolve a @username to get peer info | -
Name | -Description | -
---|---|
account.getMultiWallPapers | -Get info about multiple wallpapers | -
account.getWallPaper | -Get info about a certain wallpaper | -
account.getWallPapers | -Returns a list of available wallpapers. | -
account.installWallPaper | -Install wallpaper | -
account.resetWallPapers | -Delete installed wallpapers | -
account.saveWallPaper | -Install/uninstall wallpaper | -
account.uploadWallPaper | -Create and upload a new wallpaper | -
See Polymorphism in TL and TL Language.
-It remains to describe how types, e.g. values of type Type, are transmitted (serialized). In general, there is nothing unexpected going on here: we have type constructors of various arities (for example, List is an arity-1 constructor, but IntList is a 0-arity constructor); and if we know that a 32-bit “name” is assigned to each type constructor, there are no further questions -- values of type Type are serialized exactly like values of any other recursive type with a defined set of constructors of differing arity.
-How can a 32-bit “name” be assigned to a type (a type constructor, to be more exact) such as List or IntList? -It is proposed to use the sum of the names of all of its constructors, plus the CRC32 of the string with the designation of the type's name and all of its parameters such as “IntList = Type” or “List X:Type = Type”. This way, the List constructor’s “name” is the sum of the CRC32s of the three strings "List X:Type = Type", "cons X:Type hd:X tl:List X = List X", and "nil X:Type = List X". -For “bare” types (which, formally speaking, are subtypes of the corresponding “boxed” type), the situation is somewhat more complicated; the logical negation of the corresponding constructor’s name is used. For built-in bareand boxed types (for example, int and Int), a pseudo-declaration is used (for example, int ? = Int").
-!
modifier has not been explained.*--This document describes MTProto v1.0, its status is DEPRECATED.
-
For information on encryption used in up-to-date Telegram clients, kindly see this document.
This page deals with the basic layer of MTProto encryption used for Cloud chats (server-client encryption). See also:
- -The protocol is designed for access to a server API from applications running on mobile devices. It must be emphasized that a web browser is not such an application.
-The protocol is subdivided into three virtually independent components:
---Got questions about this setup? — Check out the Advanced FAQ!
-
Each plaintext message to be encrypted in MTProto always contains the following data to be checked upon decryption in order to make the system robust against known problems with the components:
-See additional comments on our use of IGE, SHA-1 and message authentication.
-Telegram's End-to-end encrypted Secret Chats are using an additional layer of encryption on top of the described above. See Secret Chats, End-to-End encryption for details.
-From the standpoint of the high-level component, the client and the server exchange messages inside a session. The session is attached to the client device (the application, to be more exact) rather than a specific http/https/tcp connection. In addition, each session is attached to a user key ID by which authorization is actually accomplished.
-Several connections to a server may be open; messages may be sent in either direction through any of the connections (a response to a query is not necessarily returned through the same connection that carried the original query, although most often, that is the case; however, in no case can a message be returned through a connection belonging to a different session). When the UDP protocol is used, a response might be returned by a different IP address than the one to which the query had been sent.
-There are several types of messages:
-From the standpoint of lower level protocols, a message is a binary data stream aligned along a 4 or 16-byte boundary. The first several fields in the message are fixed and are used by the cryptographic/authorization system.
-Each message, either individual or inside a container, consists of a message identifier (64 bits, see below), a message sequence number within a session (32 bits), the length (of the message body in bytes; 32 bits), and a body (any size which is a multiple of 4 bytes). In addition, when a container or a single message is sent, an internal header is added at the top (see below), then the entire message is encrypted, and an external header is placed at the top of the message (a 64-bit key identifier and a 128-bit message key).
-A message body normally consists of a 32-bit message type followed by type-dependent parameters. In particular, each RPC function has a corresponding message type. For more detail, see Binary Data Serialization, Mobile Protocol: Service Messages.
-All numbers are written as little endian. However, very large numbers (2048-bit) used in RSA and DH are written in the big endian format because that is what the OpenSSL library does.
-Prior to a message (or a multipart message) being transmitted over a network using a transport protocol, it is encrypted in a certain way, and an external header is added at the top of the message which is: a 64-bit key identifier (that uniquely identifies an authorization key for the server as well as the user) and a 128-bit message key. A user key together with the message key defines an actual 256-bit key which is what encrypts the message using AES-256 encryption. Note that the initial part of the message to be encrypted contains variable data (session, message ID, sequence number, server salt) that obviously influences the message key (and thus the AES key and iv). The message key is defined as the 128 lower-order bits of the SHA1 of the message body (including session, message ID, etc.). Multipart messages are encrypted as a single message.
-For a technical specification, see Mobile Protocol: Detailed Description
The first thing a client application must do is create an authorization key which is normally generated when it is first run and almost never changes.
The protocol’s principal drawback is that an intruder passively intercepting messages and then somehow appropriating the authorization key (for example, by stealing a device) will be able to decrypt all the intercepted messages post factum. This probably is not too much of a problem (by stealing a device, one could also gain access to all the information cached on the device without decrypting anything); however, the following steps could be taken to overcome this weakness:
-If client time diverges widely from server time, a server may start ignoring client messages, or vice versa, because of an invalid message identifier (which is closely related to creation time). Under these circumstances, the server will send the client a special message containing the correct time and a certain 128-bit salt (either explicitly provided by the client in a special RPC synchronization request or equal to the key of the latest message received from the client during the current session). This message could be the first one in a container that includes other messages (if the time discrepancy is significant but does not as yet result in the client’s messages being ignored).
-Having received such a message or a container holding it, the client first performs a time synchronization (in effect, simply storing the difference between the server’s time and its own to be able to compute the “correct” time in the future) and then verifies that the message identifiers for correctness.
-Where a correction has been neglected, the client will have to generate a new session to assure the monotonicity of message identifiers.
-Enables the delivery of encrypted containers together with the external header (hereinafter, Payload) from client to server and back. There are three types of transport:
-We shall examine the first two types.
-Implemented over HTTP/1.1 (with keepalive) running over the traditional TCP Port 80. HTTPS is not used; the above encryption method is used instead.
-An HTTP connection is attached to a session (or rather, to session + key identifier) specified in the most recent user query received; normally, the session is the same in all queries, but crafty HTTP proxies may corrupt that. A server may not return a message into an HTTP connection unless it belongs to the same session, and unless it is the server’s turn (an HTTP request had been received from the client to which a response has not been sent yet).
-The overall arrangement is as follows. The client opens one or more keepalive HTTP connections to the server. If one or more messages need to be sent, they are made into a payload which is followed by a POST request to the URL/api to which the payload is transmitted as data. In addition, Content-Length
, Keepalive
, and Host
are valid HTTP headers.
Having received the query, the server may either wait a little while (if the query requires a response following a short timeout) or immediately return a dummy response (only acknowledging the receipt of the container). In any case, the response may contain any number of messages. The server may at the same time send out any other messages it might be holding for the session.
-In addition, there exists a special long poll RPC query (valid for HTTP connections only) which transmits maximum timeout T. If the server has messages for the session, they are returned immediately; otherwise, a wait state is entered until such time as the server has a message for the client or T seconds have elapsed. If no events occur in the span of T seconds, a dummy response is returned (special message).
-If a server needs to send a message to a client, it checks for an HTTP connection that belongs to the required session and is in the “answering an HTTP request” state (including long poll) whereupon the message is added to the response container for the connection and sent to the user. In a typical case, there is some additional wait time (50 milliseconds) against the eventuality that the server will soon have more messages for the session.
-If no suitable HTTP connection is available, the messages are placed in the current session’s send queue. However, they find their way there anyway until receipt is explicitly or indirectly confirmed by the client. For the HTTP protocol, sending the next query into the same HTTP connection is regarded as an implicit acknowledgment (not any more, the HTTP protocol also requires that explicit acknowledgments be sent); in other cases, the client must return an explicit acknowledgment within a reasonable time (it can be added to a container for the following request).
-Important: if the acknowledgment fails to arrive on time, the message can be resent (possibly, in a different container). The parties must autonomously be ready for this and must store the identifiers of the most recent messages received (and ignore such duplicates rather than repeat actions). In order not to have the identifiers stored forever, there exist special garbage collection messages that take advantage of message identifier monotonicity.
-If the send queue overflows or if messages stay in the queue for over 10 minutes, the server forgets them (or sends them to swap, no genius required). This may happen even faster, if the server is running out of buffer space (for example, because of serious network issues resulting in a large number of connections becoming severed).
-This is very similar to the HTTP transport. May also be implemented over Port 80 (to penetrate all firewalls) and even use the same server IP addresses. In this situation, the server understands whether HTTP or TCP protocol must be used for the connection, based on the first four incoming bytes (for HTTP, it is POST).
-When a TCP connection is created, it is assigned to the session (and the authorization key) transmitted in the first user message, and subsequently used exclusively for this session (multiplexing arrangements are not allowed).
-If a payload (packet) needs to be transmitted from server to client or from client to server, it is encapsulated as follows: 4 length bytes are added at the front (to include the length, the sequence number, and CRC32; always divisible by 4) and 4 bytes with the packet sequence number within this TCP connection (the first packet sent is numbered 0, the next one 1, etc.), and 4 CRC32 bytes at the end (length, sequence number, and payload together).
-There is an abridged version of the same protocol: if the client sends 0xef
as the first byte (important: only prior to the very first data packet), then packet length is encoded by a single byte (0x01..0x7e
= data length divided by 4; or 0x7f
followed by 3 length bytes (little endian) divided by 4) followed by the data themselves (sequence number and CRC32 not added). In this case, server responses look the same (the server does not send 0xef
as the first byte).
In case 4-byte data alignment is needed, an intermediate version of the original protocol may be used: if the client sends 0xeeeeeeee
as the first int (four bytes), then packet length is encoded always by four bytes as in the original version, but the sequence number and CRC32 are omitted, thus decreasing total packet size by 8 bytes.
The full, the intermediate and the abridged versions of the protocol have support for quick acknowledgment. In this case, the client sets the highest-order length bit in the query packet, and the server responds with a special 4 bytes as a separate packet. They are the 32 higher-order SHA1 bits of the encrypted portion of the packet with the most significant bit set to make clear that this is not the length of a regular server response packet; if the abridged version is used, bswap is applied to these four bytes.
-There are no implicit acknowledgments for the TCP transport: all messages must be acknowledged explicitly. Most frequently, acknowledgments are placed in a container with the next query or response if it is transmitted in short order. For example, this is almost always the case for client messages containing RPC queries: the acknowledgment normally arrives with the RPC response.
-In the event of an error, the server may send a packet whose payload consists of 4 bytes as the error code. For example, Error Code 403 corresponds to situations where the corresponding HTTP error would have been returned by the HTTP protocol.
-Telegram Passport is a unified authorization method for services that require personal identification. Users can upload their documents once, then instantly share their data with services that require real-world ID (finance, ICOs, etc.). Telegram doesn't have access to the users' personal information thanks to end-to-end encryption.
-From the perspective of a service that requires real-world ID, the process looks like this:
-Check out this example to see Telegram Passport in action.
---To learn more about Telegram Passport from the perspective of a user, please see this blog post and the technical MTProto documentation. -See this page if you're interested in encryption algorithms used on Telegram's side.
-
Telegram Passport 1.1 (blog post)
-To integrate Telegram Passport into your login or verification flow, you need a working Telegram bot (see this page for information on how to get one).
-To request data from Telegram Passport users, your bot will need to generate a pair of encryption keys.
-First, use a console to generate a private key:
-openssl genrsa 2048 > private.key
-WARNING: Keep your private key SECRET!
-Then use the console to print the corresponding public key:
-openssl rsa -in private.key -pubout
-Use the /setpublickey command with @BotFather to connect this public key with your bot.
-Add a link to your Privacy Policy by using the /setprivacypolicy command. Users will see this link when offered to authorize you to access their data.
-To request information stored in a Telegram Passport, use one of these SDKs:
- -Use the following parameters to request information with the SDK:
-Parameters | -Type | -Required | -
bot_id | -Integer | -Yes | -
scope | -PassportScope | -Yes | -
public_key | -String | -Yes | -
nonce | -String | -Yes | -
This object represents the data to be requested.
-Field | -Type | -Description | -
data | -Array of PassportScopeElement | -List of requested elements, each type may be used only once in the entire array of PassportScopeElement objects | -
v | -Integer | -Scope version, must be 1 | -
This object represents a requested element, should be one of:
-This object represents several elements one of which must be provided.
-Field | -Type | -Description | -
one_of | -Array of PassportScopeElementOne | -List of elements one of which must be provided; must contain either several of “passport”, “driver_license”, “identity_card”, “internal_passport” or several of “utility_bill”, “bank_statement”, “rental_agreement”, “passport_registration”, “temporary_registration” | -
selfie | -Boolean | -Optional. Use this parameter if you want to request a selfie with the document from this list that the user chooses to upload. | -
translation | -Boolean | -Optional. Use this parameter if you want to request a translation of the document from this list that the user chooses to upload. Note: We suggest to only request translations after you have received a valid document that requires one. | -
This object represents one particular element that must be provided. If no options are needed, String can be used instead of this object to specify the type of the element.
-Field | -Type | -Description | -
type | -String | -Element type. One of "personal_details", "passport", "driver_license", "identity_card", "internal_passport", "address", "utility_bill", "bank_statement", "rental_agreement", "passport_registration", "temporary_registration", "phone_number", "email" | -
selfie | -Boolean | -Optional. Use this parameter if you want to request a selfie with the document as well. Available for "passport", "driver_license", "identity_card" and "internal_passport" | -
translation | -Boolean | -Optional. Use this parameter if you want to request a translation of the document as well. Available for "passport", "driver_license", "identity_card", "internal_passport", "utility_bill", "bank_statement", "rental_agreement", "passport_registration" and "temporary_registration". Note: We suggest to only request translations after you have received a valid document that requires one. | -
native_names | -Boolean | -Optional. Use this parameter to request the first, last and middle name of the user in the language of the user's country of residence. Available for "personal_details" | -
You can also use the special type "id_document" as an alias for one of "passport", "driver_license", "identity_card" and the special type "address_document" as an alias for one of "utility_bill", "bank_statement", "rental_agreement".
-So {"type":"id_document",selfie:true}
is equal to {"one_of":["passport","driver_license","identity_card"],selfie:true}
.
Your bot can request personal details, one or several types of identity document, residential address, one or several types of proof of address document, a phone number, or an email address. You can also request optional selfies with the document and certified English translations of the document. -This is just a list of data types that can be requested, and the encrypted objects that will contain such data.
---Note: We suggest to only request English translations after you have received a valid document that requires one.
-
Name | Key | Type | Description |
---|---|---|---|
personal_details | data | PersonalDetails | Personal Details |
passport | data | IdDocumentData | Passport |
front_side | PassportFile | ||
selfie | Optional. PassportFile | ||
translation | Optional. Array of PassportFile | ||
internal_passport | data | IdDocumentData | Internal Passport |
front_side | PassportFile | ||
selfie | Optional. PassportFile | ||
translation | Optional. Array of PassportFile | ||
driver_license | data | IdDocumentData | Driver License |
front_side | PassportFile | ||
reverse_side | PassportFile | ||
selfie | Optional. PassportFile | ||
translation | Optional. Array of PassportFile | ||
identity_card | data | IdDocumentData | Identity Card |
front_side | PassportFile | ||
reverse_side | PassportFile | ||
selfie | Optional. PassportFile | ||
translation | Optional. Array of PassportFile | ||
address | data | ResidentialAddress | Address |
utility_bill | files | Array of PassportFile | Utility Bill |
translation | Optional. Array of PassportFile | ||
bank_statement | files | Array of PassportFile | Bank Statement |
translation | Optional. Array of PassportFile | ||
rental_agreement | files | Array of PassportFile | Rental Agreement |
translation | Optional. Array of PassportFile | ||
passport_registration | files | Array of PassportFile | Registration Page in the Internal Passport |
translation | Optional. Array of PassportFile | ||
temporary_registration | files | Array of PassportFile | Temporary Registration |
translation | Optional. Array of PassportFile | ||
phone_number | String | Phone number | |
String |
This object represents personal details.
-Field | -Type | -Description | -
first_name | -String | -First Name | -
last_name | -String | -Last Name | -
middle_name | -String | -Optional. Middle Name | -
birth_date | -String | -Date of birth in DD.MM.YYYY format | -
gender | -String | -Gender, male or female | -
country_code | -String | -Citizenship (ISO 3166-1 alpha-2 country code) | -
residence_country_code | -String | -Country of residence (ISO 3166-1 alpha-2 country code) | -
first_name_native | -String | -First Name in the language of the user's country of residence | -
last_name_native | -String | -Last Name in the language of the user's country of residence | -
middle_name_native | -String | -Optional. Middle Name in the language of the user's country of residence | -
This object represents a residential address.
-Field | -Type | -Description | -
street_line1 | -String | -First line for the address | -
street_line2 | -String | -Optional. Second line for the address | -
city | -String | -City | -
state | -String | -Optional. State | -
country_code | -String | -ISO 3166-1 alpha-2 country code | -
post_code | -String | -Address post code | -
This object represents the data of an identity document.
-Field | -Type | -Description | -
document_no | -String | -Document number | -
expiry_date | -String | -Optional. Date of expiry, in DD.MM.YYYY format | -
This object represents a PassportFile related to a document. The file is up to 10MB in size and in the .jpg format.
-When the user confirms your request by pressing the 'Authorize' button, the Bot API sends an Update with the field passport_data to the bot that contains encrypted Telegram Passport data.
---Note that all base64-encoded fields should be decoded before use.
-
To decrypt the received data, first, decrypt the credentials contained in EncryptedCredentials.
-Decrypt the credentials secret ( secret field in EncryptedCredentials) using your private key (set OAEP padding option, e.g. OPENSSL_PKCS1_OAEP_PADDING
in PHP)
Use this secret and the credentials hash ( hash field in EncryptedCredentials) to calculate credentials_key and credentials_iv as described below:
- credentials_secret_hash = SHA512( credentials_secret + credentials_hash )
- credentials_key = slice( credentials_secret_hash, 0, 32 )
- credentials_iv = slice( credentials_secret_hash, 32, 16 )
-Decrypt the credentials data ( data field in EncryptedCredentials) by AES256-CBC using these credentials_key and credentials_iv. IMPORTANT: At this step, make sure that the credentials hash is equal to SHA256( credentials_data )
Credentials data is padded with 32 to 255 random padding bytes to make its length divisible by 16 bytes. The first byte contains the length of this padding (including this byte). Remove the padding to get the data.
---Note that all hashes represent as raw binary data, not hexits
-
Credentials is a JSON-serialized object.
-Field | -Type | -Description | -
secure_data | -SecureData | -Credentials for encrypted data | -
nonce | -String | -Bot-specified nonce | -
IMPORTANT: Make sure that the nonce is the same as was passed in the request.
-This object represents the credentials required to decrypt encrypted data. All fields are optional and depend on fields that were requested.
-Field | -Type | -Description | -
personal_details | -SecureValue | -Optional. Credentials for encrypted personal details | -
passport | -SecureValue | -Optional. Credentials for encrypted passport | -
internal_passport | -SecureValue | -Optional. Credentials for encrypted internal passport | -
driver_license | -SecureValue | -Optional. Credentials for encrypted driver license | -
identity_card | -SecureValue | -Optional. Credentials for encrypted ID card | -
address | -SecureValue | -Optional. Credentials for encrypted residential address | -
utility_bill | -SecureValue | -Optional. Credentials for encrypted utility bill | -
bank_statement | -SecureValue | -Optional. Credentials for encrypted bank statement | -
rental_agreement | -SecureValue | -Optional. Credentials for encrypted rental agreement | -
passport_registration | -SecureValue | -Optional. Credentials for encrypted registration from internal passport | -
temporary_registration | -SecureValue | -Optional. Credentials for encrypted temporary registration | -
This object represents the credentials required to decrypt encrypted values. All fields are optional and depend on the type of fields that were requested.
-Field | -Type | -Description | -
data | -DataCredentials | -Optional. Credentials for encrypted Telegram Passport data. Available for "personal_details", "passport", "driver_license", "identity_card", "internal_passport" and "address" types. | -
front_side | -FileCredentials | -Optional. Credentials for an encrypted document's front side. Available for "passport", "driver_license", "identity_card" and "internal_passport". | -
reverse_side | -FileCredentials | -Optional. Credentials for an encrypted document's reverse side. Available for "driver_license" and "identity_card". | -
selfie | -FileCredentials | -Optional. Credentials for an encrypted selfie of the user with a document. Available for "passport", "driver_license", "identity_card" and "internal_passport". | -
translation | -Array of FileCredentials | -Optional. Credentials for an encrypted translation of the document. Available for "passport", "driver_license", "identity_card", "internal_passport", "utility_bill", "bank_statement", "rental_agreement", "passport_registration" and "temporary_registration". | -
files | -Array of FileCredentials | -Optional. Credentials for encrypted files. Available for "utility_bill", "bank_statement", "rental_agreement", "passport_registration" and "temporary_registration" types. | -
These credentials can be used to decrypt encrypted data from the data field in EncryptedPassportElement.
-Field | -Type | -Description | -
data_hash | -String | -Checksum of encrypted data | -
secret | -String | -Secret of encrypted data | -
To decrypt data, use the corresponding secret and data_hash from DataCredentials as described below:
- data_secret_hash = SHA512( data_secret + data_hash )
- data_key = slice( data_secret_hash, 0, 32 )
- data_iv = slice( data_secret_hash, 32, 16 )
-Use AES256-CBC with this data_key and data_iv to decrypt the data (the data field in EncryptedPassportElement). IMPORTANT: At this step, make sure that data_hash from the credentials is equal to SHA256( data )
.
The data is padded with 32 to 255 random padding bytes to make its length divisible by 16 bytes. The first byte contains the length of the padding (including this byte). Remove padding to get the data.
-The data is a JSON-serialized object of one of the following types: PersonalDetails, IdDocumentData, ResidentialAddress, depending on type.
-These credentials can be used to decrypt encrypted files from the front_side, reverse_side, selfie, files and translation fields in EncryptedPassportElement.
-Field | -Type | -Description | -
file_hash | -String | -Checksum of encrypted file | -
secret | -String | -Secret of encrypted file | -
To decrypt the file, use the corresponding secret and file_hash from FileCredentials as described below:
- file_secret_hash = SHA512( file_secret + file_hash )
- file_key = slice( file_secret_hash, 0, 32 )
- file_iv = slice( file_secret_hash, 32, 16 )
-Download the encrypted file using the getFile method.
-Use AES256-CBC with this file_key and file_iv to decrypt the content of the file. IMPORTANT: At this step, make sure that file_hash from the credentials is equal to SHA256( file_content )
.
The content of the file is padded with 32 to 255 random padding bytes to make its length divisible by 16 bytes. The first byte contains the length of the padding (including that byte). Remove padding to get the file content.
-If the data you received contains errors, the bot can use the setPassportDataErrors method to inform the user and request information again. The user will not be able to resend the data, until all errors are fixed.
The Android SDK helps you easily integrate Telegram Passport requests into your Android-based apps. Check out our GitHub repository to see samples using this SDK.
-Telegram Passport SDK is available from the Maven repository. -Add this line to the dependencies section in your build.gradle:
-compile 'org.telegram:passport:1.1'
-and sync your project.
-Download the library, unzip it and copy the library project to the root of your project directory (the one with settings.gradle and gradle.properties). Then, make the following changes to your Gradle scripts.
-In settings.gradle, add ':telegrampassport'
to includes:
include ':app', ':telegrampassport'
-In the build.gradle file for your app, add this line to the dependencies section:
-compile ':telegrampassport'
-and sync your project.
-The SDK provides the "Log in with Telegram" button which we recommend using for a consistent user experience across different apps. You can either add it from your Java code:
-TelegramLoginButton telegramButton;
-// ...
-telegramButton=new TelegramLoginButton(this);
-// Optionally you can change the roundness of the button corners
-// to better fit your design.
-telegramButton.setCornerRoundness(1f);
-viewGroupOfSomeSort.addView(telegramButton, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
-Or from XML:
- <org.telegram.passport.TelegramLoginButton
- android:layout_width="wrap_content"
- android:layout_height="wrap_content"
- app:cornerRoundness="0.5"/>
-The button doesn't do anything by itself; you need to set an OnClickListener on it to start the authorization flow (replace the comments with actual parameters):
-private static final int TG_PASSPORT_RESULT=352; // this can be any integer less than 0xFFFF
-// ...
-telegramButton.setOnClickListener(new View.OnClickListener(){
-@Override
-public void onClick(View view){
- TelegramPassport.AuthRequest req=new TelegramPassport.AuthRequest();
- req.botID=/* your bot ID here */;
- req.publicKey=/* your bot public key here */;
- req.nonce=/* a unique nonce to pass to the bot server */;
- // Request either a passport or an ID card with selfie, a driver license, personal details with
- // name as it appears in the documents, address with any address document, and a phone number.
- // You could also pass a raw JSON object here if that's what works better for you
- // (for example, if you already get it from your server in the correct format).
- req.scope=new PassportScope(
- new PassportScopeElementOneOfSeveral(PassportScope.PASSPORT, PassportScope.IDENTITY_CARD).withSelfie(),
- new PassportScopeElementOne(PassportScope.PERSONAL_DETAILS).withNativeNames(),
- PassportScope.DRIVER_LICENSE,
- PassportScope.ADDRESS,
- PassportScope.ADDRESS_DOCUMENT,
- PassportScope.PHONE_NUMBER
- );
- TelegramPassport.request(MyActivity.this, req, TG_PASSPORT_RESULT);
-}});
-If you need more control over the process, the TelegramPassport
class contains several more methods:
getAuthIntent(AuthParams)
returns an Intent
for you to use in startActivityForResult
if you need to do that in some special way. Be sure to check that an app is present that can handle this intent before starting it by using PackageManager
or intent.resolveActivity
.showAppInstallAlert(Activity)
shows an alert that the user needs to install Telegram in order to continue. This is intended to be used together with the previous method for the cases when the app isn't installed.The result is delivered via the onActivityResult
method in your activity with the request code you passed to TelegramPassport.request
. Currently, the only meaningful parameter is resultCode
, which is RESULT_OK
if the authorization was successful and RESULT_CANCELED
otherwise.
TDLib (Telegram Database Library) is a cross-platform, fully functional Telegram client. We designed it to help third-party developers create their own custom apps using the Telegram platform.
-- --
- --
TDLib is fully open source, all code is available on GitHub.
-See also:
- -Public key to use only during handshakes to CDN DCs.
-cdnPublicKey#c982eaba dc_id:int public_key:string = CdnPublicKey;
-Constructor | -Description | -
---|---|
cdnPublicKey | -Public key to use only during handshakes to CDN DCs. | -
Chat invite
-chatInviteAlready#5a686d7c chat:Chat = ChatInvite;
-chatInvite#dfc2f58e flags:# channel:flags.0?true broadcast:flags.1?true public:flags.2?true megagroup:flags.3?true title:string photo:Photo participants_count:int participants:flags.4?Vector<User> = ChatInvite;
-chatInvitePeek#61695cb0 chat:Chat expires:int = ChatInvite;
-
----functions---
-
-messages.checkChatInvite#3eadb1bb hash:string = ChatInvite;
-Constructor | -Description | -
---|---|
chatInviteAlready | -The user has already joined this chat | -
chatInvite | -Chat invite info | -
chatInvitePeek | -A chat invitation that also allows peeking into the group to read messages without joining it. | -
Method | -Description | -
---|---|
messages.checkChatInvite | -Check the validity of a chat invite link and get basic info about it | -
Information for connection to data centre.
-dcOption#18b7a10d flags:# ipv6:flags.0?true media_only:flags.1?true tcpo_only:flags.2?true cdn:flags.3?true static:flags.4?true id:int ip_address:string port:int secret:flags.10?bytes = DcOption;
-Constructor | -Description | -
---|---|
dcOption | -Data centre | -
Object describes the contents of an encrypted message.
-===8===
-decryptedMessage#1f814f1f random_id:long random_bytes:bytes message:string media:DecryptedMessageMedia = DecryptedMessage;
-decryptedMessageService#aa48327d random_id:long random_bytes:bytes action:DecryptedMessageAction = DecryptedMessage;
-
-===17===
-decryptedMessage#204d3878 random_id:long ttl:int message:string media:DecryptedMessageMedia = DecryptedMessage;
-decryptedMessageService#73164160 random_id:long action:DecryptedMessageAction = DecryptedMessage;
-
-===45===
-decryptedMessage#36b091de flags:# random_id:long ttl:int message:string media:flags.9?DecryptedMessageMedia entities:flags.7?Vector<MessageEntity> via_bot_name:flags.11?string reply_to_random_id:flags.3?long = DecryptedMessage;
-
-===73===
-decryptedMessage#91cc4674 flags:# no_webpage:flags.1?true silent:flags.5?true random_id:long ttl:int message:string media:flags.9?DecryptedMessageMedia entities:flags.7?Vector<MessageEntity> via_bot_name:flags.11?string reply_to_random_id:flags.3?long grouped_id:flags.17?long = DecryptedMessage;
Object describes media contents of an encrypted message.
-===8===
-decryptedMessageMediaEmpty#89f5c4a = DecryptedMessageMedia;
-decryptedMessageMediaPhoto#32798a8c thumb:bytes thumb_w:int thumb_h:int w:int h:int size:int key:bytes iv:bytes = DecryptedMessageMedia;
-decryptedMessageMediaVideo#4cee6ef3 thumb:bytes thumb_w:int thumb_h:int duration:int w:int h:int size:int key:bytes iv:bytes = DecryptedMessageMedia;
-decryptedMessageMediaGeoPoint#35480a59 lat:double long:double = DecryptedMessageMedia;
-decryptedMessageMediaContact#588a0a97 phone_number:string first_name:string last_name:string user_id:int = DecryptedMessageMedia;
-decryptedMessageMediaDocument#b095434b thumb:bytes thumb_w:int thumb_h:int file_name:string mime_type:string size:int key:bytes iv:bytes = DecryptedMessageMedia;
-decryptedMessageMediaAudio#6080758f duration:int size:int key:bytes iv:bytes = DecryptedMessageMedia;
-
-===17===
-decryptedMessageMediaVideo#524a415d thumb:bytes thumb_w:int thumb_h:int duration:int mime_type:string w:int h:int size:int key:bytes iv:bytes = DecryptedMessageMedia;
-decryptedMessageMediaAudio#57e0a9cb duration:int mime_type:string size:int key:bytes iv:bytes = DecryptedMessageMedia;
-
-===23===
-decryptedMessageMediaExternalDocument#fa95b0dd id:long access_hash:long date:int mime_type:string size:int thumb:PhotoSize dc_id:int attributes:Vector<DocumentAttribute> = DecryptedMessageMedia;
-
-===45===
-decryptedMessageMediaPhoto#f1fa8d78 thumb:bytes thumb_w:int thumb_h:int w:int h:int size:int key:bytes iv:bytes caption:string = DecryptedMessageMedia;
-decryptedMessageMediaVideo#970c8c0e thumb:bytes thumb_w:int thumb_h:int duration:int mime_type:string w:int h:int size:int key:bytes iv:bytes caption:string = DecryptedMessageMedia;
-decryptedMessageMediaDocument#7afe8ae2 thumb:bytes thumb_w:int thumb_h:int mime_type:string size:int key:bytes iv:bytes attributes:Vector<DocumentAttribute> caption:string = DecryptedMessageMedia;
-decryptedMessageMediaVenue#8a0df56f lat:double long:double title:string address:string provider:string venue_id:string = DecryptedMessageMedia;
-decryptedMessageMediaWebPage#e50511d8 url:string = DecryptedMessageMedia;
Object sets encrypted file for attachment
-inputEncryptedFileEmpty#1837c364 = InputEncryptedFile;
-inputEncryptedFileUploaded#64bd0306 id:long parts:int md5_checksum:string key_fingerprint:int = InputEncryptedFile;
-inputEncryptedFile#5a17b5e5 id:long access_hash:long = InputEncryptedFile;
-inputEncryptedFileBigUploaded#2dc173c8 id:long parts:int key_fingerprint:int = InputEncryptedFile;
-Constructor | -Description | -
---|---|
inputEncryptedFileEmpty | -Empty constructor. | -
inputEncryptedFileUploaded | -Sets new encrypted file saved by parts using upload.saveFilePart method. | -
inputEncryptedFile | -Sets forwarded encrypted file for attachment. | -
inputEncryptedFileBigUploaded | -Assigns a new big encrypted file (over 10Mb in size), saved in parts using the method upload.saveBigFilePart. | -
Phone call
-inputPhoneCall#1e36fded id:long access_hash:long = InputPhoneCall;
-Constructor | -Description | -
---|---|
inputPhoneCall | -Phone call | -
Wallpaper
-inputWallPaper#e630b979 id:long access_hash:long = InputWallPaper;
-inputWallPaperSlug#72091c80 slug:string = InputWallPaper;
-inputWallPaperNoFile#8427bbac = InputWallPaper;
-Constructor | -Description | -
---|---|
inputWallPaper | -Wallpaper | -
inputWallPaperSlug | -Wallpaper by slug (a unique ID) | -
inputWallPaperNoFile | -Wallpaper with no file | -
Labeled pricetag
-labeledPrice#cb296bf8 label:string amount:long = LabeledPrice;
-Constructor | -Description | -
---|---|
labeledPrice | -This object represents a portion of the price for goods or services. | -
Language pack changes
-langPackDifference#f385c1f6 lang_code:string from_version:int version:int strings:Vector<LangPackString> = LangPackDifference;
-
----functions---
-
-langpack.getLangPack#f2f2330a lang_pack:string lang_code:string = LangPackDifference;
-langpack.getDifference#cd984aa5 lang_pack:string lang_code:string from_version:int = LangPackDifference;
-Constructor | -Description | -
---|---|
langPackDifference | -Changes to the app's localization pack | -
Method | -Description | -
---|---|
langpack.getLangPack | -Get localization pack strings | -
langpack.getDifference | -Get new strings in languagepack | -
Message entities, representing styled text in a message
-messageEntityUnknown#bb92ba95 offset:int length:int = MessageEntity;
-messageEntityMention#fa04579d offset:int length:int = MessageEntity;
-messageEntityHashtag#6f635b0d offset:int length:int = MessageEntity;
-messageEntityBotCommand#6cef8ac7 offset:int length:int = MessageEntity;
-messageEntityUrl#6ed02538 offset:int length:int = MessageEntity;
-messageEntityEmail#64e475c2 offset:int length:int = MessageEntity;
-messageEntityBold#bd610bc9 offset:int length:int = MessageEntity;
-messageEntityItalic#826f8b60 offset:int length:int = MessageEntity;
-messageEntityCode#28a20571 offset:int length:int = MessageEntity;
-messageEntityPre#73924be0 offset:int length:int language:string = MessageEntity;
-messageEntityTextUrl#76a6d327 offset:int length:int url:string = MessageEntity;
-messageEntityMentionName#352dca58 offset:int length:int user_id:int = MessageEntity;
-inputMessageEntityMentionName#208e68c9 offset:int length:int user_id:InputUser = MessageEntity;
-messageEntityPhone#9b69e34b offset:int length:int = MessageEntity;
-messageEntityCashtag#4c4e743f offset:int length:int = MessageEntity;
-messageEntityUnderline#9c4e7e8b offset:int length:int = MessageEntity;
-messageEntityStrike#bf0693d4 offset:int length:int = MessageEntity;
-messageEntityBlockquote#20df5d0 offset:int length:int = MessageEntity;
-messageEntityBankCard#761e6af4 offset:int length:int = MessageEntity;
-Constructor | -Description | -
---|---|
messageEntityUnknown | -Unknown message entity | -
messageEntityMention | -Message entity mentioning the current user | -
messageEntityHashtag | -#hashtag message entity | -
messageEntityBotCommand | -Message entity representing a bot /command | -
messageEntityUrl | -Message entity representing an in-text url: https://google.com; for text urls, use messageEntityTextUrl. | -
messageEntityEmail | -Message entity representing an email@example.com. | -
messageEntityBold | -Message entity representing bold text. | -
messageEntityItalic | -Message entity representing italic text. | -
messageEntityCode | -Message entity representing a codeblock . |
-
messageEntityPre | -Message entity representing a preformatted codeblock , allowing the user to specify a programming language for the codeblock. |
-
messageEntityTextUrl | -Message entity representing a text url: for in-text urls like https://google.com use messageEntityUrl. | -
messageEntityMentionName | -Message entity representing a user mention: for creating a mention use inputMessageEntityMentionName. | -
inputMessageEntityMentionName | -Message entity that can be used to create a user user mention: received mentions use the messageEntityMentionName constructor, instead. | -
messageEntityPhone | -Message entity representing a phone number. | -
messageEntityCashtag | -Message entity representing a $cashtag. | -
messageEntityUnderline | -Message entity representing underlined text. | -
messageEntityStrike | -Message entity representing |
-
messageEntityBlockquote | -Message entity representing a block quote. | -
messageEntityBankCard | -Indicates a credit card number | -
Message interaction counters
-messageInteractionCounters#ad4fc9bd msg_id:int views:int forwards:int = MessageInteractionCounters;
-Constructor | -Description | -
---|---|
messageInteractionCounters | -Message interaction counters | -
Media
-messageMediaEmpty#3ded6320 = MessageMedia;
-messageMediaPhoto#695150d7 flags:# photo:flags.0?Photo ttl_seconds:flags.2?int = MessageMedia;
-messageMediaGeo#56e0d474 geo:GeoPoint = MessageMedia;
-messageMediaContact#cbf24940 phone_number:string first_name:string last_name:string vcard:string user_id:int = MessageMedia;
-messageMediaUnsupported#9f84f49e = MessageMedia;
-messageMediaDocument#9cb070d7 flags:# document:flags.0?Document ttl_seconds:flags.2?int = MessageMedia;
-messageMediaWebPage#a32dd600 webpage:WebPage = MessageMedia;
-messageMediaVenue#2ec0533f geo:GeoPoint title:string address:string provider:string venue_id:string venue_type:string = MessageMedia;
-messageMediaGame#fdb19008 game:Game = MessageMedia;
-messageMediaInvoice#84551347 flags:# shipping_address_requested:flags.1?true test:flags.3?true title:string description:string photo:flags.0?WebDocument receipt_msg_id:flags.2?int currency:string total_amount:long start_param:string = MessageMedia;
-messageMediaGeoLive#b940c666 flags:# geo:GeoPoint heading:flags.0?int period:int proximity_notification_radius:flags.1?int = MessageMedia;
-messageMediaPoll#4bd6e798 poll:Poll results:PollResults = MessageMedia;
-messageMediaDice#3f7ee58b value:int emoticon:string = MessageMedia;
-
----functions---
-
-messages.getWebPagePreview#8b68b0cc flags:# message:string entities:flags.3?Vector<MessageEntity> = MessageMedia;
-messages.uploadMedia#519bc2b1 peer:InputPeer media:InputMedia = MessageMedia;
-Constructor | -Description | -
---|---|
messageMediaEmpty | -Empty constructor. | -
messageMediaPhoto | -Attached photo. | -
messageMediaGeo | -Attached map. | -
messageMediaContact | -Attached contact. | -
messageMediaUnsupported | -Current version of the client does not support this media type. | -
messageMediaDocument | -Document (video, audio, voice, sticker, any media type except photo) | -
messageMediaWebPage | -Preview of webpage | -
messageMediaVenue | -Venue | -
messageMediaGame | -Telegram game | -
messageMediaInvoice | -Invoice | -
messageMediaGeoLive | -Indicates a live geolocation | -
messageMediaPoll | -Poll | -
messageMediaDice | -Dice | -
Method | -Description | -
---|---|
messages.getWebPagePreview | -Get preview of webpage | -
messages.uploadMedia | -Upload a file and associate it to a chat (without actually sending it to the chat) | -
Instant view page
-page#98657f0d flags:# part:flags.0?true rtl:flags.1?true v2:flags.2?true url:string blocks:Vector<PageBlock> photos:Vector<Photo> documents:Vector<Document> views:flags.3?int = Page;
-Constructor | -Description | -
---|---|
page | -Instant view page | -
Chat partner or group.
-peerUser#9db1bc6d user_id:int = Peer;
-peerChat#bad0e5bb chat_id:int = Peer;
-peerChannel#bddde532 channel_id:int = Peer;
-Constructor | -Description | -
---|---|
peerUser | -Chat partner | -
peerChat | -Group. | -
peerChannel | -Channel/supergroup | -
Phone call
-phoneCallEmpty#5366c915 id:long = PhoneCall;
-phoneCallWaiting#1b8f4ad1 flags:# video:flags.6?true id:long access_hash:long date:int admin_id:int participant_id:int protocol:PhoneCallProtocol receive_date:flags.0?int = PhoneCall;
-phoneCallRequested#87eabb53 flags:# video:flags.6?true id:long access_hash:long date:int admin_id:int participant_id:int g_a_hash:bytes protocol:PhoneCallProtocol = PhoneCall;
-phoneCallAccepted#997c454a flags:# video:flags.6?true id:long access_hash:long date:int admin_id:int participant_id:int g_b:bytes protocol:PhoneCallProtocol = PhoneCall;
-phoneCall#8742ae7f flags:# p2p_allowed:flags.5?true video:flags.6?true id:long access_hash:long date:int admin_id:int participant_id:int g_a_or_b:bytes key_fingerprint:long protocol:PhoneCallProtocol connections:Vector<PhoneConnection> start_date:int = PhoneCall;
-phoneCallDiscarded#50ca4de1 flags:# need_rating:flags.2?true need_debug:flags.3?true video:flags.6?true id:long reason:flags.0?PhoneCallDiscardReason duration:flags.1?int = PhoneCall;
-Constructor | -Description | -
---|---|
phoneCallEmpty | -Empty constructor | -
phoneCallWaiting | -Incoming phone call | -
phoneCallRequested | -Requested phone call | -
phoneCallAccepted | -An accepted phone call | -
phoneCall | -Phone call | -
phoneCallDiscarded | -Indicates a discarded phone call | -
Location of a certain size of a picture
-photoSizeEmpty#e17e23c type:string = PhotoSize;
-photoSize#77bfb61b type:string location:FileLocation w:int h:int size:int = PhotoSize;
-photoCachedSize#e9a734fa type:string location:FileLocation w:int h:int bytes:bytes = PhotoSize;
-photoStrippedSize#e0b0bc2e type:string bytes:bytes = PhotoSize;
-photoSizeProgressive#5aa86a51 type:string location:FileLocation w:int h:int sizes:Vector<int> = PhotoSize;
-photoPathSize#d8214d41 type:string bytes:bytes = PhotoSize;
-Constructor | -Description | -
---|---|
photoSizeEmpty | -Empty constructor. Image with this thumbnail is unavailable. | -
photoSize | -Image description. | -
photoCachedSize | -Description of an image and its content. | -
photoStrippedSize | -Just the image's content | -
photoSizeProgressive | -Progressively encoded photosize | -
photoPathSize | -Messages with animated stickers can have a compressed svg (< 300 bytes) to show the outline of the sticker before fetching the actual lottie animation. | -
User actions. Use this to provide users with detailed info about their chat partners' actions: typing or sending attachments of all kinds.
-sendMessageTypingAction#16bf744e = SendMessageAction;
-sendMessageCancelAction#fd5ec8f5 = SendMessageAction;
-sendMessageRecordVideoAction#a187d66f = SendMessageAction;
-sendMessageUploadVideoAction#e9763aec progress:int = SendMessageAction;
-sendMessageRecordAudioAction#d52f73f7 = SendMessageAction;
-sendMessageUploadAudioAction#f351d7ab progress:int = SendMessageAction;
-sendMessageUploadPhotoAction#d1d34a26 progress:int = SendMessageAction;
-sendMessageUploadDocumentAction#aa0cd9e4 progress:int = SendMessageAction;
-sendMessageGeoLocationAction#176f8ba1 = SendMessageAction;
-sendMessageChooseContactAction#628cbc6f = SendMessageAction;
-sendMessageGamePlayAction#dd6a8f48 = SendMessageAction;
-sendMessageRecordRoundAction#88f27fbc = SendMessageAction;
-sendMessageUploadRoundAction#243e1c66 progress:int = SendMessageAction;
-Constructor | -Description | -
---|---|
sendMessageTypingAction | -User is typing. | -
sendMessageCancelAction | -Invalidate all previous action updates. E.g. when user deletes entered text or aborts a video upload. | -
sendMessageRecordVideoAction | -User is recording a video. | -
sendMessageUploadVideoAction | -User is uploading a video. | -
sendMessageRecordAudioAction | -User is recording a voice message. | -
sendMessageUploadAudioAction | -User is uploading a voice message. | -
sendMessageUploadPhotoAction | -User is uploading a photo. | -
sendMessageUploadDocumentAction | -User is uploading a file. | -
sendMessageGeoLocationAction | -User is selecting a location to share. | -
sendMessageChooseContactAction | -User is selecting a contact to share. | -
sendMessageGamePlayAction | -User is playing a game | -
sendMessageRecordRoundAction | -User is recording a round video to share | -
sendMessageUploadRoundAction | -User is uploading a round video | -
Configuration for two-factor authorization
-account.password#ad2641f8 flags:# has_recovery:flags.0?true has_secure_values:flags.1?true has_password:flags.2?true current_algo:flags.2?PasswordKdfAlgo srp_B:flags.2?bytes srp_id:flags.2?long hint:flags.3?string email_unconfirmed_pattern:flags.4?string new_algo:PasswordKdfAlgo new_secure_algo:SecurePasswordKdfAlgo secure_random:bytes = account.Password;
-
----functions---
-
-account.getPassword#548a30f5 = account.Password;
-Constructor | -Description | -
---|---|
account.password | -Configuration for two-factor authorization | -
Method | -Description | -
---|---|
account.getPassword | -Obtain configuration for two-factor authorization with password | -
Temporary password
-account.tmpPassword#db64fd34 tmp_password:bytes valid_until:int = account.TmpPassword;
-
----functions---
-
-account.getTmpPassword#449e0b51 password:InputCheckPasswordSRP period:int = account.TmpPassword;
-Constructor | -Description | -
---|---|
account.tmpPassword | -Temporary payment password | -
Method | -Description | -
---|---|
account.getTmpPassword | -Get temporary payment password | -
Info about pinned MTProxy or Public Service Announcement peers.
-help.promoDataEmpty#98f6ac75 expires:int = help.PromoData;
-help.promoData#8c39793f flags:# proxy:flags.0?true expires:int peer:Peer chats:Vector<Chat> users:Vector<User> psa_type:flags.1?string psa_message:flags.2?string = help.PromoData;
-
----functions---
-
-help.getPromoData#c0977421 = help.PromoData;
-Constructor | -Description | -
---|---|
help.promoDataEmpty | -No PSA/MTProxy info is available | -
help.promoData | -MTProxy/Public Service Announcement information | -
Method | -Description | -
---|---|
help.getPromoData | -Get MTProxy/Public Service Announcement information | -
A basic bare type, the values of which correspond to single-element sequences, i.e. numbers from -2^31 to 2^31-1 which in this case represent themselves.
- -Object contains extended info on chat with auxiliary data.
-messages.chatFull#e5d7d19c full_chat:ChatFull chats:Vector<Chat> users:Vector<User> = messages.ChatFull;
-
----functions---
-
-messages.getFullChat#3b831c66 chat_id:int = messages.ChatFull;
-
-channels.getFullChannel#8736a09 channel:InputChannel = messages.ChatFull;
-Constructor | -Description | -
---|---|
messages.chatFull | -Extended info on chat and auxiliary data. | -
Method | -Description | -
---|---|
messages.getFullChat | -Returns full chat info according to its ID. | -
channels.getFullChannel | -Get full info about a channel | -
Favorited stickers
-messages.favedStickersNotModified#9e8fa6d3 = messages.FavedStickers;
-messages.favedStickers#f37f2f16 hash:int packs:Vector<StickerPack> stickers:Vector<Document> = messages.FavedStickers;
-
----functions---
-
-messages.getFavedStickers#21ce0b0e hash:int = messages.FavedStickers;
-Constructor | -Description | -
---|---|
messages.favedStickersNotModified | -No new favorited stickers were found | -
messages.favedStickers | -Favorited stickers | -
Method | -Description | -
---|---|
messages.getFavedStickers | -Get faved stickers | -
Found stickersets
-messages.foundStickerSetsNotModified#d54b65d = messages.FoundStickerSets;
-messages.foundStickerSets#5108d648 hash:int sets:Vector<StickerSetCovered> = messages.FoundStickerSets;
-
----functions---
-
-messages.searchStickerSets#c2b7d08b flags:# exclude_featured:flags.0?true q:string hash:int = messages.FoundStickerSets;
-Constructor | -Description | -
---|---|
messages.foundStickerSetsNotModified | -No further results were found | -
messages.foundStickerSets | -Found stickersets | -
Method | -Description | -
---|---|
messages.searchStickerSets | -Search for stickersets | -
Object contains infor on list of messages with auxiliary data.
-messages.messages#8c718e87 messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
-messages.messagesSlice#3a54685e flags:# inexact:flags.1?true count:int next_rate:flags.0?int offset_id_offset:flags.2?int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
-messages.channelMessages#64479808 flags:# inexact:flags.1?true pts:int count:int offset_id_offset:flags.2?int messages:Vector<Message> chats:Vector<Chat> users:Vector<User> = messages.Messages;
-messages.messagesNotModified#74535f21 count:int = messages.Messages;
-
----functions---
-
-messages.getMessages#63c66506 id:Vector<InputMessage> = messages.Messages;
-messages.getHistory#dcbb8260 peer:InputPeer offset_id:int offset_date:int add_offset:int limit:int max_id:int min_id:int hash:int = messages.Messages;
-messages.search#c352eec flags:# peer:InputPeer q:string from_id:flags.0?InputPeer top_msg_id:flags.1?int filter:MessagesFilter min_date:int max_date:int offset_id:int add_offset:int limit:int max_id:int min_id:int hash:int = messages.Messages;
-messages.searchGlobal#4bc6589a flags:# folder_id:flags.0?int q:string filter:MessagesFilter min_date:int max_date:int offset_rate:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages;
-messages.getUnreadMentions#46578472 peer:InputPeer offset_id:int add_offset:int limit:int max_id:int min_id:int = messages.Messages;
-messages.getRecentLocations#bbc45b09 peer:InputPeer limit:int hash:int = messages.Messages;
-messages.getScheduledHistory#e2c2685b peer:InputPeer hash:int = messages.Messages;
-messages.getScheduledMessages#bdbb0464 peer:InputPeer id:Vector<int> = messages.Messages;
-messages.getReplies#24b581ba peer:InputPeer msg_id:int offset_id:int offset_date:int add_offset:int limit:int max_id:int min_id:int hash:int = messages.Messages;
-
-channels.getMessages#ad8c9a23 channel:InputChannel id:Vector<InputMessage> = messages.Messages;
-
-stats.getMessagePublicForwards#5630281b channel:InputChannel msg_id:int offset_rate:int offset_peer:InputPeer offset_id:int limit:int = messages.Messages;
-Constructor | -Description | -
---|---|
messages.messages | -Full list of messages with auxilary data. | -
messages.messagesSlice | -Incomplete list of messages and auxiliary data. | -
messages.channelMessages | -Channel messages | -
messages.messagesNotModified | -No new messages matching the query were found | -
Method | -Description | -
---|---|
messages.getMessages | -Returns the list of messages by their IDs. | -
messages.getHistory | -Gets back the conversation history with one interlocutor / within a chat | -
messages.search | -Gets back found messages | -
channels.getMessages | -Get channel/supergroup messages | -
messages.searchGlobal | -Search for messages and peers globally | -
messages.getUnreadMentions | -Get unread messages where we were mentioned | -
messages.getRecentLocations | -Get live location history of a certain user | -
messages.getScheduledHistory | -Get scheduled messages | -
messages.getScheduledMessages | -Get scheduled messages | -
messages.getReplies | -Get messages in a reply thread | -
stats.getMessagePublicForwards | -Obtains a list of messages, indicating to which other public channels was a channel message forwarded. | -
List of dialogs
-messages.peerDialogs#3371c354 dialogs:Vector<Dialog> messages:Vector<Message> chats:Vector<Chat> users:Vector<User> state:updates.State = messages.PeerDialogs;
-
----functions---
-
-messages.getPeerDialogs#e470bcfd peers:Vector<InputDialogPeer> = messages.PeerDialogs;
-messages.getPinnedDialogs#d6b94df2 folder_id:int = messages.PeerDialogs;
-Constructor | -Description | -
---|---|
messages.peerDialogs | -Dialog info of multiple peers | -
Method | -Description | -
---|---|
messages.getPeerDialogs | -Get dialog info of specified peers | -
messages.getPinnedDialogs | -Get pinned dialogs | -
How users voted in a poll
-messages.votesList#823f649 flags:# count:int votes:Vector<MessageUserVote> users:Vector<User> next_offset:flags.0?string = messages.VotesList;
-
----functions---
-
-messages.getPollVotes#b86e380e flags:# peer:InputPeer id:int option:flags.0?bytes offset:flags.1?string limit:int = messages.VotesList;
-Constructor | -Description | -
---|---|
messages.votesList | -How users voted in a poll | -
Method | -Description | -
---|---|
messages.getPollVotes | -Get poll results for non-anonymous polls | -
Saved payment info
-payments.savedInfo#fb8fe43c flags:# has_saved_credentials:flags.1?true saved_info:flags.0?PaymentRequestedInfo = payments.SavedInfo;
-
----functions---
-
-payments.getSavedInfo#227d824b = payments.SavedInfo;
-Constructor | -Description | -
---|---|
payments.savedInfo | -Saved server-side order information | -
Method | -Description | -
---|---|
payments.getSavedInfo | -Get saved payment information | -
A basic bare type. Values of type string
look differently depending on the length L
of the string being serialized:
L <= 253
, the serialization contains one byte with the value of L
, then L
bytes of the string followed by 0 to 3 characters containing 0, such that the overall length of the value be divisible by 4, whereupon all of this is interpreted as a sequence of int(L/4)+1
32-bit little-endian integers.L >= 254
, the serialization contains byte 254, followed by 3 bytes with the string length L
in little-endian order, followed by L
bytes of the string, further followed by 0 to 3 null padding bytes.All strings passed to the API must be encoded in UTF-8. When arbitrary byte sequences have to be serialized, bytes alias is to be used.
-Further details on basic types»
-Basic bare type. It is an alias of the string type, with the difference that the value may contain arbitrary byte sequences, including invalid UTF-8 sequences.
-When computing crc32 for a constructor or method it is necessary to replace all byte types with string types.
-Represents the download status of a CDN file
-upload.cdnFileReuploadNeeded#eea8e46e request_token:bytes = upload.CdnFile;
-upload.cdnFile#a99fca4f bytes:bytes = upload.CdnFile;
-
----functions---
-
-upload.getCdnFile#2000bcc3 file_token:bytes offset:int limit:int = upload.CdnFile;
-Constructor | -Description | -
---|---|
upload.cdnFileReuploadNeeded | -The file was cleared from the temporary RAM cache of the CDN and has to be reuploaded. | -
upload.cdnFile | -Represent a chunk of a CDN file. | -
Method | -Description | -
---|---|
upload.getCdnFile | -Download a CDN file. | -
Farewell to typos! Starting today, you can edit the text of your messages after sending them. This works across all Telegram chats, including groups and one-on-one conversations.
- - -Simply tap and hold on a message, then press ‘Edit’. If you're on desktop, press the up arrow button to edit your last message. The messages will display a small ‘edited’ label so that it's easy to tell which were altered.
-Mentioning other people in groups is handy since it sends them a notification about your message even if they muted the group. Starting today, you can mention any members in a group – even if they don't have a username. Just type the @
symbol and select whoever you would like to address. Easy!
Speaking of addressing people, you can now get to your recent chats much faster using the new People list in Search.
- - - -We've also made it easier for you to access your favorite inline bots. Simply scroll down the attachment menu – and there they are. The more you use them, the higher they will climb.
- - -Naturally, you will only see inline bots in the attachment menu if you used them at least once. Try @youtube, @gif or @imdb if you don't know where to start. Check out this post for more info on how to use inline bots.
-We‘ve added quick sharing buttons to forwarded messages from bots, channels, and public groups. Notifications about messages with stickers will now show the relevant emoji so that you’ll know the general idea at first glance.
- - -Last but not least, if you're on iOS, your app now remembers the scroll position in chats when switching to a different chat and back. And scrolling up in a chat summons a new button that will send you back to the bottom in one tap. This button also displays a handy unread message counter if new ones are waiting for you there.
-And that's it for today. Stay tuned for more updates coming soon!
-May 15, 2016
The Telegram Team
Bots became an integral part of Telegram for many users, but communication with them wasn't always easy. You had to send them messages in separate chats or add them to your groups. Today we are introducing a quicker way to contact bots.
-With the new inline mode, bots become omnipresent and can be used as a tool in any of your chats, groups or channels – it doesn't matter, whether the bot is a member or not. Inline bots can help you with dozens of different tasks, like quickly sending relevant GIFs, pictures from the Web, YouTube videos, Wikipedia articles, etc.
-We've created several sample bots for you to try out: @gif, @vid, @pic, @bing, @wiki, @imdb and @bold. To see them in action, simply type one of their @usernames in the message field in any chat, then type some keywords. The bot will offer you relevant content.
-Tap on an item to instantly send it to the chat. This way you can share stuff from bots without any hassle. Inline bots don't see any messages in your chats – they only receive what you type after their username in the input field.
-Tap on ‘via @username’ to send a new request to the bot. Recently used inline bots will also show up in the suggestion box when you type @
in the input field in any chat.
Like pretty much everything else at Telegram, inline bots are part of an open platform, available for free to every developer in the world starting today. Hundreds of new inline bots are sure to arrive once developers start supporting the new mode.
-If you are a developer, take a look at our Introduction to Inline Bots. Also, feel free to subscribe to our official @BotNews channel to stay up to date on platform news.
-The Telegram Team,
January 4, 2016
Since we first added polls for groups and channels, they've been used for everything from deciding where to have lunch to organizing leaderless protests. Today we're expanding the range of possibilities with three new kinds of Telegram polls.
-Previously, all polls on Telegram were anonymous. With this update, you can create polls that allow everyone in the group to see who voted for what. Now you will know exactly which friends you disagree with on the matter of pineapple and pizza.
- - -Naturally, you can still create anonymous polls to make sure nobody finds out it was you who voted for broccoli instead of cookies.
-One of the best ways to settle the score is with polls that allow people to select multiple answers. Scheduling events, or choosing a playlist of songs for a party – sometimes you need more than one choice.
- - -Our aunt who has a knack for statistics and exploring bizarre correlations kept asking for this feature – and we just couldn't say no. (33% of developers who didn't refuse this request were also found to be addicted to cheese.)
-For the game show guru and “Who Wants To Be A Millionaire” contestant in all of us, polls now have Quiz Mode. Such polls have one correct answer and can power anything from trivia games to public service exams.
- - -As if guessing right wasn't sweet enough, correct answers will trigger a shower of confetti.
-Polls can be created in groups or channels (they feel lonely in one-on-one chats). Simply choose the “Poll” option in the attachment menu. Type in your question, add answer options, choose the settings that fit your purpose best – and you're ready to go:
-All the new poll types are supported in today's update to our Bot API, so bot developers can build on this new functionality.
-As an example, we've created a Quiz Bot that lets you create multi-question quizzes and share them with others. It also lets you add text or media before questions to help create exam-style prompts with graphs and tables – or better yet, your own Know Your Meme tests.
-Once your quiz is ready, you can share it to a group or channel – or invite users to answer questions privately, in a chat with the bot. To see how this works, try our demo quiz: Who is Who in the 'Great Minds' sticker pack.
- - -The bot will keep tabs on how many questions users got right and how much time it took them to complete the quiz. It also keeps a global leaderboard for each quiz you create.
-In addition to the new polls, our apps just got a new visual setting. If you find your Telegram messages too hip to be square (or round, depending on your platform), you can tweak the appearance of message bubbles in Settings:
-Just like on iOS, Android users can now see exact progress counters when downloading or uploading files – if they're in the mood to count bits and bytes.
- - -And that's it for today. Here's to a good new year full of updates. Stay tuned!
-January 23, 2020
The Telegram Team
--This FAQ provides answers to basic questions about Telegram.
-
Check out our Advanced FAQ for more technical information.
Contact Telegram Support
Follow Us on Twitter
Facebook
Advanced FAQ
Telegram is a messaging app with a focus on speed and security, it’s super-fast, simple and free. You can use Telegram on all your devices at the same time — your messages sync seamlessly across any number of your phones, tablets or computers. Telegram has over 500 million monthly active users and is one of the 10 most downloaded apps in the world.
-With Telegram, you can send messages, photos, videos and files of any type (doc, zip, mp3, etc), as well as create groups for up to 200,000 people or channels for broadcasting to unlimited audiences. You can write to your phone contacts and find people by their usernames. As a result, Telegram is like SMS and email combined — and can take care of all your personal or business messaging needs. In addition to this, we support end-to-end encrypted voice and video calls, as well as voice chats in groups for thousands of participants.
---Follow our Tips Channel to learn more about Telegram features.
-
Telegram is for everyone who wants fast and reliable messaging and calls. Business users and small teams may like the large groups, usernames, desktop apps and powerful file sharing options.
-Since Telegram groups can have up to 200,000 members, we support replies, mentions and hashtags that help maintain order and keep communication in large communities efficient. You can appoint admins with advanced tools to help these communities prosper in peace. Public groups can be joined by anyone and are powerful platforms for discussions and collecting feedback.
-In case you're more into pictures, Telegram has animated gif search, a state of the art photo editor, and an open sticker platform (find some cool stickers here or here). What's more, there is no need to worry about disk space on your device. With Telegram's cloud support and cache management options, Telegram can take up nearly zero space on your phone.
-Those looking for extra privacy should check out our advanced settings and rather revolutionary policy. And if you want secrecy, try our device-specific Secret Chats with self-destructing messages, photos, and videos — and lock your app with an additional passcode.
---We keep evolving — check out our Brief History of Telegram and follow us on twitter and Telegram to stay in touch.
-
Unlike WhatsApp, Telegram is a cloud-based messenger with seamless sync. As a result, you can access your messages from several devices at once, including tablets and computers, and share an unlimited number of photos, videos and files (doc, zip, mp3, etc.) of up to 2 GB each.
-Telegram needs less than 100 MB on your device – you can keep all your media in the cloud without deleting things – simply clear your cache to free up space.
-Thanks to Telegram's multi-data center infrastructure and encryption, is faster and way more secure. On top of that, private messaging on Telegram is free and will stay free — no ads, no subscription fees, forever.
-Telegram's API and code is open, and developers are welcome to create their own Telegram apps. We also have a Bot API, a platform for developers that allows anyone to easily build specialized tools for Telegram, integrate any services, and even accept payments from users around the world.
-And that's just the tip of the iceberg.
---Follow our Tips Channel to learn more about Telegram features.
-
Telegram for iOS was launched on August 14, 2013. The alpha version of Telegram for Android officially launched on October 20, 2013. More and more Telegram clients appear, built by independent developers using Telegram's open platform.
-You can use Telegram on smartphones, tablets, and even computers. We have apps for iOS (9.0 and above), Android (4.1 and up), a native macOS app and a universal desktop app for Windows, macOS, and Linux. Telegram Web can also help to quickly do something on the go.
---You can log in to Telegram from as many of your devices as you like — all at the same time. Just use your main mobile phone number to log in everywhere, your cloud chats will sync instantly.
-
The Telegram API is open for developers, should you want to build your own applications for other platforms.
-Telegram is supported by Pavel Durov and his brother Nikolai. Pavel supports Telegram financially and ideologically while Nikolai's input is technological. To make Telegram possible, Nikolai developed a unique custom data protocol, which is open, secure and optimized for work with multiple data-centers. As a result, Telegram combines security, reliability and speed on any network.
---See also: articles about Telegram
-
The Telegram development team is based in Dubai.
-Most of the developers behind Telegram originally come from St. Petersburg, the city famous for its unprecedented number of highly skilled engineers. The Telegram team had to leave Russia due to local IT regulations and has tried a number of locations as its base, including Berlin, London and Singapore. We’re currently happy with Dubai, although are ready to relocate again if local regulations change.
-No. See this post for details.
-We believe in fast and secure messaging that is also 100% free.
-Our founder and CEO Pavel Durov, who financed Telegram throughout most of its history, has outlined a strategy to make Telegram sustainable in this post.
-While Telegram will introduce monetization in 2021 to pay for the infrastructure and developer salaries, making profits will never be an end-goal for us.
-We think that the two most important components of Internet privacy should be:
-Telegram's aim is to create a truly free messenger, with a revolutionary privacy policy.
-The General Data Protection Regulation (GDPR) came into force in Europe on May 25, 2018. Since taking back our right to privacy was the reason we made Telegram, there wasn't much we had to change. We don’t use your data for ad targeting, we don’t sell it to others, and we're not part of any mafia family “family of companies.”
Telegram only keeps the information it needs to function as a feature-rich cloud service. For example, your cloud chats – so that you can access them from any devices without using third-party backups, or your contacts – so that you can rely on your existing social graph when messaging people on Telegram. Please see our Privacy Policy for more information.
-You can use @GDPRbot to:
-All Telegram chats and group chats are private amongst their participants. We do not process any requests related to them.
-But sticker sets, channels, and bots on Telegram are publicly available. If you find sticker sets or bots on Telegram that you think are illegal, please ping us at abuse@telegram.org.
-You can also use the 'report' buttons right inside our apps, see this post on our official @ISISwatch channel for details.
---Note: If a scammer is pretending to be you, contact @NoToScam
-
All Telegram chats and group chats are private amongst their participants. We do not process any requests related to them. But sticker sets, channels, and bots on Telegram are publicly available.
-If you see a bot, channel, or sticker set that is infringing on your copyright, kindly submit a complaint to dmca@telegram.org. Please note that such requests should only be submitted by the copyright owner or an agent authorized to act on the owner’s behalf.
-Our mission is to provide a secure means of communication that works everywhere on the planet. To do this in the places where it is most needed (and to continue distributing Telegram through the App Store and Google Play), we have to process legitimate requests to take down illegal public content (e.g., sticker sets, bots, and channels) within the app. For example, we can take down sticker sets that violate intellectual property rights or porn bots.
-User-uploaded stickers sets, channels, and bots by third-party developers are not part of the core Telegram UI. Whenever we receive a complaint at abuse@telegram.org or dmca@telegram.org regarding the legality of public content, we perform the necessary legal checks and take it down when deemed appropriate.
-Please note that this does not apply to local restrictions on freedom of speech. For example, if criticizing the government is illegal in some country, Telegram won't be a part of such politically motivated censorship. This goes against our founders' principles. While we do block terrorist (e.g. ISIS-related) bots and channels, we will not block anybody who peacefully expresses alternative opinions.
-If you think we banned your bot, channel, or sticker set for no apparent reasons, drop us a line at abuse@telegram.org.
-Secret chats use end-to-end encryption, thanks to which we don't have any data to disclose.
-To protect the data that is not covered by end-to-end encryption, Telegram uses a distributed infrastructure. Cloud chat data is stored in multiple data centers around the globe that are controlled by different legal entities spread across different jurisdictions. The relevant decryption keys are split into parts and are never kept in the same place as the data they protect. As a result, several court orders from different jurisdictions are required to force us to give up any data.
-Thanks to this structure, we can ensure that no single government or block of like-minded countries can intrude on people's privacy and freedom of expression. Telegram can be forced to give up data only if an issue is grave and universal enough to pass the scrutiny of several different legal systems around the world.
-To this day, we have disclosed 0 bytes of user data to third parties, including governments.
---Follow our Tips Channel to learn more about Telegram features.
-
You can write to people who are in your phone contacts and have Telegram. Another way of contacting people is to type their Telegram username into the search field – you don't need to know their phone number to do this.
-People can contact you on Telegram if they know your phone number or if you message them first.
-If they don't know your phone number, they can find you in these cases:
-Your contacts, who have Telegram, are shown at the top of your Contacts. They also have pictures.
-iOS: The basic invitations are simple SMS messages. They will be charged as standard outgoing SMS by your carrier (unless sent via iMessage). Naturally, you have other options to bring your friends here. Try sending them a download link via any other messaging service: email, Facebook, WhatsApp, an actual telegram — you name it. The link: https://telegram.org/dl/
-Android: Open the app menu (swipe right in chat list) > Invite Friends. Then choose an application via which you would like to send out invitations.
---You can give your friends a t.me link with your username so that they can easily find you on Telegram even if they don't have your phone number.
-
One check — message delivered to the Telegram cloud and your friend has been notified if he allows notifications.
Two checks — message read (your friend opened Telegram and opened the conversation with the message).
We don't have a 'delivered to device' status for messages because Telegram can run on as many devices as you want. So which particular one would that check mean?
-You can choose who sees this info in Privacy and Security settings.
-Remember that you won't see Last Seen timestamps for people with whom you don't share your own. You will, however, see an approximate last seen value. This keeps stalkers away but makes it possible to understand whether a person is reachable over Telegram. There are four possible approximate values:
-The last seen rules apply to your online status as well. People can only see you online if you're sharing your last seen status with them.
-There are some exceptions because sometimes it is obvious that you are online. Regardless of the last seen settings, people will see you online for a brief period (~30 seconds) if you do the following:
-If you're not sharing your last seen timestamp with someone and don't do anything of the above, they'll never see you online. Another way of achieving this is to block that person.
-People Nearby is an optional feature that allows Telegram users to explore local groups, find friends to chat with in their area, or quickly exchange contacts with people who are close.
-You can find it in Contacts > Find People Nearby, as well as directly in the side menu on Android.
-While you have the People Nearby section open on your screen, people who are very close will be able to see you there. If you don't open the section, others will never see you in 'People Nearby'.
-You can also choose to permanently add your profile to the list of nearby people by tapping Make Myself Visible. After becoming visible, you can remove your profile from the list at any time by tapping Stop Showing Me.
---Note: People Nearby is never turned on by default – users must manually enable it. If you are receiving messages from someone you don't know, see Q: Who can contact me?
-
Yes. You can always delete any messages you sent or received for both sides in any one-on-one conversation (in groups, it's still your own messages only). You can also clear the entire chat history on both ends. On Telegram, deleted messages do not leave a mark in the chat.
-Together with privacy settings for forwarded messages, this makes exchanging Telegram messages similar to talking face to face (without a tape recorder). As a result, users no longer need to worry about the data accumulating in their chats over the years. Both parties in a conversation have full control over what does and what doesn't belong to their online identity.
-Yes! You can make end-to-end encrypted Voice Calls and Video Calls.
-If you want more participants, try starting a Voice Chat in one of the groups you created. Voice Chats add a live layer of ephemeral talk to the group. They can be used as virtual office spaces for teams or informal lounges for any community. While Voice Chats are not group calls, they can achieve similar goals.
-Type one word in your input field to get relevant emoji suggestions. You can also type “:” followed by any keyword to open emoji search – like :heart.
-You can suggest missing keywords for emoji in your language using this interface (this will open suggestions for English, don't forget to change to your language in the left menu).
-Telegram groups can have up to 200,000 members each and are extremely powerful communication tools. Here are a few key features that make them stand out in the messaging world:
-Unified history
Edit your messages after posting, delete them so that they disappear for everyone.
Cross-platform availability
Access your messages anytime, from any number of your mobile or desktop devices.
Instant search
Find the message you're looking for, even among millions. Filter by sender to make searching easier.
Replies, mentions, hashtags
Easily trace a conversation and keep communication efficient, no matter the group size.
Smart notifications
Mute the group to get notifications only when people mention you or reply to your messages.
Pinned messages
You can pin any message to be displayed at the top of the chat screen. All members will get a notification — even if they muted ordinary messages from your group.
Moderation tools
Appoint administrators that can mass-delete messages, control membership, and pin important messages. Define their admin privileges with granular precision.
Group permissions
Set default permissions to restrict all members from posting specific kinds of content. Or even restrict members from sending messages altogether – and let the admins chat amongst themselves while everybody else is watching.
File sharing
Send and receive files of any type, up to 2 GB in size each, access them instantly on your other devices.
Public groups
Get a short link for your group and make it public, like t.me/publictestgroup. This way, anybody can view the group's entire chat history and join to post messages.
Customization via bots
Create custom tools for any specific needs using our Bot API and Inline Bots.
Telegram groups are ideal for sharing stuff with friends and family or collaboration in small teams. But groups can also grow very large and support communities of up to 200,000 members. You can make any group public, toggle persistent history to control whether or not new members have access to earlier messages and appoint administrators with granular privileges. You can also pin important messages to the top of the screen so that all members can see them, including those who have just joined.
-Channels are a tool for broadcasting messages to large audiences. In fact, a channel can have an unlimited number of subscribers. When you post in a channel, the message is signed with the channel's name and photo and not your own. Each message in a channel has a view counter that gets updated when the message is viewed, including its forwarded copies.
-- --
iOS: Start a new message (tap the icon in the top right corner in Chats) > 'New Group'.
Android: Tap the circular pencil icon in the chat list > 'New Group'.
Telegram Desktop: Click the menu button in the top left corner > 'New Group'.
You can add administrators to help you manage your group and define their privileges with granular precision.
-iOS: Go to Group Info (tap the photo in the top right corner on the group‘s chat screen) > Edit > Administrators.
Android: Go to Group Info (tap the name in the header) > the pencil icon (in the top right corner) > Administrators.
Telegram Desktop: When in the group, click '…' in the top right corner > Manage group > Administrators.
You can add your contacts, or using search by username.
-It is easy to migrate existing groups to Telegram by sending people an invite link. To create an invite link, go to Group Info > Add Member > Invite to Group via Link.
-Anyone who has Telegram installed will be able to join your group by following this link. If you choose to revoke the link, it will stop working immediately.
-- --
You can set up a public username on Telegram. It then becomes possible for other users to find you by that username — you will appear in contacts search under 'global results'. Please note that people who find you will be able to send you messages, even if they don't know your number. If you are not comfortable with this, we advise against setting up a username in Telegram.
-You can set up a username in Settings and use the universal search box in the chat list to search for chats, messages, and usernames.
-Once you've set up a username, you can give people a t.me/username link. Opening that link on their phone will automatically fire up their Telegram app and open a chat with you. You can share username links with friends, write them on business cards or put them up on your website.
-This way people can contact you on Telegram without knowing your phone number.
-You can use a-z, 0-9 and underscores. Usernames are case-insensitive, but Telegram will store your capitalization preferences (e.g. Telegram and TeleGram is the same user). The username must be at least five characters long.
-You don't have to get one. Remember that Telegram usernames are public and choosing a username on Telegram makes it possible for people to find you in global search and send you messages even if they don't have your number. If you are not comfortable with this, we advise against setting up a username.
-No. Neither party will see another's phone number (unless this is permitted by your privacy settings). This is similar to the case when you message a person who you've met in a Telegram group.
-Go to Settings and save an empty username. This will remove your username; people will no longer be able to find you via search. This will not affect existing conversations.
-Telegram usernames are distributed on a first come — first serve basis.
-We understand that certain usernames are part of an online identity for some of us. If your desired username is already taken, we will be happy to help you acquire it for your account or channel, provided that you have that same username on at least two of these services: Facebook, Twitter, Instagram.
-Due to the fact that one account can register multiple bot and channel usernames, we reserve the right to recall usernames assigned to unused bots and channels, as well as openly squatted usernames.
-To request a username, contact @Username_bot.
-If a scammer is pretending to be you, please contact @NoToScam.
---If you are an advanced user, you may find our FAQ for the Technically Inclined useful as well.
-
Telegram is more secure than mass market messengers like WhatsApp and Line. We are based on the MTProto protocol (see description and advanced FAQ), built upon time-tested algorithms to make security compatible with high-speed delivery and reliability on weak connections. We are continuously working with the community to improve the security of our protocol and clients.
-We've got you covered. Telegram’s special secret chats use end-to-end encryption, leave no trace on our servers, support self-destructing messages and don’t allow forwarding. On top of this, secret chats are not part of the Telegram cloud and can only be accessed on their devices of origin.
-We support two layers of secure encryption. Server-client encryption is used in Cloud Chats (private and group chats), Secret Chats use an additional layer of client-client encryption. All data, regardless of type, is encrypted in the same way — be it text, media or files.
-Our encryption is based on 256-bit symmetric AES encryption, 2048-bit RSA encryption, and Diffie–Hellman secure key exchange. You can find more info in the Advanced FAQ.
---See also: Do you process data requests?
-
Telegram is open, anyone can check our source code, protocol and API, see how everything works and make an informed decision. Telegram supports verifiable builds, which allow experts to independently verify that our code published on GitHub is the exact same code that is used to build the apps you download from App Store or Google Play.
-We welcome security experts to audit our system and appreciate any feedback at security@telegram.org.
-On top of that, Telegram's primary focus is not to bring a profit, so commercial interests will never interfere with our mission.
---See also: articles about Telegram
-
When it comes to secret chats, you don't — just make sure that the visualized key of your secret chat matches the one in your friend's secret chat settings. More about this below.
-Anyone who claims that Telegram messages can be deciphered is welcome to prove that claim in our competition and win $300,000. You can check out the Cracking Contest Description to learn more.
-Any comments on Telegram's security are welcome at security@telegram.org. All submissions which result in a change of code or configuration are eligible for bounties, ranging from $100 to $100,000 or more, depending on the severity of the issue. Please note that we can not offer bounties for issues that are disclosed to the public before they are fixed.
-Telegram can help when it comes to data transfer and secure communication. This means that all data (including media and files) that you send and receive via Telegram cannot be deciphered when intercepted by your internet service provider, owners of Wi-Fi routers you connect to, or other third parties.
-But please remember that we cannot protect you from your own mother if she takes your unlocked phone without a passcode. Or from your IT-department if they access your computer at work. Or from any other people that get physical or root access to your phones or computers running Telegram.
-If you have reasons to worry about your personal security, we strongly recommend using only Secret Chats in official or at least verifiable open-source apps for sensitive information, preferably with a self-destruct timer. We also recommend enabling 2-Step Verification and setting up a strong passcode to lock your app, you will find both options in Settings > Privacy and Security.
-Logging in with an SMS code is an industry standard in messaging, but if you're looking for more security or have reasons to doubt your mobile carrier or government, we recommend protecting your cloud chats with an additional password.
-You can do this in Settings > Privacy and Security > 2-Step Verification. Once enabled, you will need both an SMS code and a password to log in. You can also set up a recovery email address that will help regain access, should you forget your password. If you do so, please remember that it's important that the recovery email account is also protected with a strong password and 2-Step Verification when possible.
-Check this out for tips on creating a strong password that is easy to remember.
-Using a rooted or jailbroken device makes it easier for a potential attacker to gain full administrative control over your device — root access.
-A user with root access can easily bypass security features built into the operating system, read process memory or access restricted areas, such as the internal storage. Once an attacker has root access, any efforts to mitigate threats become futile. No application can be called safe under these circumstances, no matter how strong the encryption.
-Secret chats are meant for people who want more secrecy than the average fella. All messages in secret chats use end-to-end encryption. This means only you and the recipient can read those messages — nobody else can decipher them, including us here at Telegram (more on this here). On top of this, Messages cannot be forwarded from secret chats. And when you delete messages on your side of the conversation, the app on the other side of the secret chat will be ordered to delete them as well.
-You can order your messages, photos, videos and files to self-destruct in a set amount of time after they have been read or opened by the recipient. The message will then disappear from both your and your friend's devices.
-All secret chats in Telegram are device-specific and are not part of the Telegram cloud. This means you can only access messages in a secret chat from their device of origin. They are safe for as long as your device is safe in your pocket.
-Open the profile of the user you want to contact. Tap on ‘…’, then ‘Start Secret Chat’.
-Remember that Telegram secret chats are device-specific. If you start a secret chat with a friend on one of your devices, this chat will only be available on that device. If you log out, you will lose all your secret chats. You can create as many different secret chats with the same contact as you like.
-The Self-Destruct Timer is available for all messages in Secret Chats and for media in private cloud chats.
-To set the timer, simply tap the clock icon (in the input field on iOS, top bar on Android), and then choose the desired time limit. The clock starts ticking the moment the message is displayed on the recipient's screen (gets two check marks). As soon as the time runs out, the message disappears from both devices. We will try to send a notification if a screenshot is taken.
-Please note that the timer in Secret Chats only applies to messages that were sent after the timer was set. It has no effect on earlier messages.
-Unfortunately, there is no bulletproof way of detecting screenshots on certain systems (most notably, some Android and Windows Phone devices). We will make every effort to alert you about screenshots taken in your Secret Chats, but it may still be possible to bypass such notifications and take screenshots silently. We advise to share sensitive information only with people you trust. After all, nobody can stop a person from taking a picture of their screen with a different device or an old school camera.
-When a secret chat is created, the participating devices exchange encryption keys using the so-called Diffie-Hellman key exchange. After the secure end-to-end connection has been established, we generate a picture that visualizes the encryption key for your chat. You can then compare this image with the one your friend has — if the two images are the same, you can be sure that the secret chat is secure, and no man-in-the-middle attack can succeed.
-Newer versions of Telegram apps will show a larger picture along with a textual representation of the key (this is not the key itself, of course!) when both participants are using an updated app.
-Always compare visualizations using a channel that is known to be secure — it's safest if you do this in person, in an offline meeting with the conversation partner.
-All Telegram messages are always securely encrypted. Messages in Secret Chats use client-client encryption, while Cloud Chats use client-server/server-client encryption and are stored encrypted in the Telegram Cloud (more here). This enables your cloud messages to be both secure and immediately accessible from any of your devices – even if you lose your device altogether.
-The problem of restoring access to your chat history on a newly connected device (e.g. when you lose your phone) does not have an elegant solution in the end-to-end encryption paradigm. At the same time, reliable backups are an essential feature for any mass-market messenger. To solve this problem, some applications (like Whatsapp and Viber) allow decryptable backups that put their users' privacy at risk – even if they do not enable backups themselves. Other apps ignore the need for backups altogether and leave their users vulnerable to data loss.
-We opted for a third approach by offering two distinct types of chats. Telegram disables default system backups and provides all users with an integrated security-focused backup solution in the form of Cloud Chats. Meanwhile, the separate entity of Secret Chats gives you full control over the data you do not want to be stored.
-This allows Telegram to be widely adopted in broad circles, not just by activists and dissidents, so that the simple fact of using Telegram does not mark users as targets for heightened surveillance in certain countries. We are convinced that the separation of conversations into Cloud and Secret chats represents the most secure solution currently possible for a massively popular messaging application.
---See also: Why Telegram isn't End-to-End Encrypted “by Default”
-
On Telegram, you can send messages in private chats and groups without making your phone number visible. By default, your number is only visible to people who you've added to your address book as contacts. You can further modify this in Settings > Privacy and Security > Phone Number.
---Note that people will always see your number if they know it already and saved it in their address book.
-
Each phone number is a separate account on Telegram. You have several options if you are using multiple phone numbers:
-Most users don't need to log out of Telegram:
-If you do want to log out for some reason, here's how you do that:
-iOS: Go to Settings > Edit > Log out.
Android, Telegram Desktop: Go to Settings > … (in the top right corner) > Log out.
If you log out, you will keep all your cloud messages. However, you will lose all your Secret Chats and all messages inside those secret chats when you log out.
---Note that logging out does not trigger remote deletion of your secret chat messages on your partner's device — to do that, choose 'Clear History' first.
-
You can change your number in Telegram and keep everything, including all your contacts, messages, and media from the Telegram cloud, as well as all your Secret Chats on all devices.
-To change your number, go to Settings, then tap on your phone number (just above the username), then 'Change Number'. If you already have a different Telegram account on the target number, you'll need to delete that account first.
-If you would like to delete your account, you can do this on the deactivation page. Deleting your account permanently removes all your messages and contacts. All groups and channels that you've created are orphaned and left without a creator but admins retain their rights.
-This action must be confirmed via your Telegram account and cannot be undone.
---We recommend using a non-mobile browser for this process.
-
Note that you'll receive the code via Telegram, not SMS.
As was just mentioned above, all your data will be flushed from our system: all messages, groups, and contacts associated with your account will be deleted. That said, your contacts will still be able to chat in the groups that you have created, and they will still have their copy of the messages you sent them. So if you want to send messages that can vanish without a trace, try using our self-destruct timer instead.
-Termination of a Telegram account is irreversible. If you sign up again, you will appear as a new user and will not get your history, contacts or groups back. People, who have your phone number in their contacts, will be notified. The new user will be displayed as a separate conversation in their messages list and their conversation history with this new user will be empty.
-Telegram is not a commercial organization, and we value our disk space greatly. If you stop using Telegram and don't come online for at least six months, your account will be deleted along with all messages, media, contacts and every other piece of data you store in the Telegram cloud. You can change the exact period after which your inactive account will self-destruct in Settings.
-First of all, sorry about your phone. Unfortunately, the phone number is the only way for us to identify a Telegram user at the moment. We don't collect additional information about you, so whoever has the number, has the account. This means we can't help you unless you have access either to the phone number or to Telegram itself on any of your devices.
-Common thieves usually throw out the SIM card immediately (the phone is harder to locate this way), then wipe the devices and sell them, so there isn't much risk for the data in case of regular petty theft. But if you have reasons to worry about the data on the device and are unable to log out the other device, it is best that you wipe it remotely. You can read more about it here: Apple iOS, Android. Unfortunately, this requires you to have prepared in advance for this scenario.
-You can delete your Telegram account if you are logged in on at least one of your other devices (mobile or desktop). Note that inactive Telegram accounts self-destruct automatically after a period of time — 6 months being the default setting.
---If you're a developer, you may find our Bots FAQ more useful.
-
Bots are like small programs that run right inside Telegram. They are made by third-party developers using the Telegram Bot API.
-Creating Telegram bots is super-easy, but you will need at least some skills in computer programming. If you're sure you're up to it, our Introduction for Developers is a good place to start.
-Unfortunately, there are no out-of-the-box ways to create a working bot if you are not a developer. But we're sure you'll soon find plenty of bots created by other people to play with.
-If you don't want a bot to send you messages, feel free to block it – same as you would block a human user. Some Telegram clients have a 'Stop Bot' button right in the bot's profile.
-That said, most bot developers offer commands that silence the bot, check its /help for clues.
-Yes. Bots are no different from human users that you meet in groups for example. They can see your public name, username, and profile pictures, and they can see messages you send to them, that's it. They can't access your last seen status and don't see your phone number (unless you decide to give it to them yourself).
-Naturally, any bot should be treated as a stranger — don't give them your passwords, Telegram codes or bank account numbers, even if they ask nicely. Also, be careful when opening files sent by bots, same as you would deal with ordinary humans. Example: If a bot sent us a file called OpenMe.exe, we probably wouldn't open it.
-Bots can work in two modes when you add them to groups. By default, bots only see messages that are meant for them. In this case, you'll see 'has no access to messages' in the group members list next to the bot.
-Some bots need more information to work, so developers may disable the privacy mode. In this case, the bot will see all messages sent to the group, and you will see 'has access to messages' in the members list next to the bot.
-Learn more about privacy mode for bots »
-If your group contains very sensitive information, maybe it's better to avoid adding bots you don't trust 100%.
-No. While we have some official bots for specific purposes (like @gif or @GDPRbot), we don't usually make bots. Bots are made by third-party developers using the Telegram Bot API and platform.
-There is no official store at the moment, so you'll have to ask your friends or search the web for now. We're pretty sure you'll find some bots to play with.
-All Telegram client apps are fully open source. We offer verifiable builds both for iOS and Android – this technology allows to independently verify that the application you download from the app stores was built using the exact same code that we publish.
-By contrast, publishing the server code doesn’t provide security guarantees neither for Secret Chats nor for Cloud Chats. This is because – unlike with the client-side code – there’s no way to verify that the same code is run on the servers.
-As for Secret Chats, you don’t need the server-side code to check their integrity – the point of end-to-end encryption is that it must be solid regardless of how the servers function.
---In a post on his channel, Pavel Durov explained why Telegram hasn't published the server code, even as a publicity stunt.
-
The encryption and API used on Telegram's servers are fully documented and open for review by security experts. We welcome any comments at security@telegram.org
-Our architecture does not support federation yet. Telegram is a unified cloud service, so creating forks where two users might end up on two different Telegram clouds is unacceptable. To enable you to run your own Telegram server while retaining both speed and security is a task in itself. At the moment, we are undecided on whether or not Telegram should go in this direction.
-Yes. Developers for all platforms are welcome to use our protocol, API and even source code. Check out the Getting started section of the docs.
---Don't forget about our Bot API that lets you build cool stuff on our platform.
-
Sure. Check this out.
-Apple created privacy sheets to inform users about what data apps may collect, but information there is vague and can be misleading. You can see a detailed explanation of Telegram's sheet here.
-One is our app for macOS, the other is Telegram Lite, the macOS version of our multi-platform client. Both apps are official. Both started out as unofficial applications by two different developers and vary in design and functionality.
-Telegram for macOS supports many platform-specific features, such as the MacBook Pro Touch Bar, gesture navigation, integration with the Mac's Share menu and more. It has every feature from the iOS version of the app including Secret Chats.
-Telegram Lite is a lightning-fast app, optimized for work-related tasks and handling large communities. It offers a three-column interface, perfect for multitasking and quick access to media, files and links shared in your chats. This app can also be used to export your Telegram data and chats.
-Telegram is officially available in English, Spanish, German, Dutch, Italian, French, Arabic, Portuguese, Korean, Malay, Russian and Ukrainian on most platforms, and we are gradually expanding the list of languages built into the apps.
-If you don’t like how a specific element in Telegram's interface is translated in your language, or would like to help us maintain the translation, check out our localization platform. Everyone can suggest translations and vote for the best ones, making Telegram localization a community-driven effort.
-If you're looking to go beyond suggestions for individual phrases and would like to help us maintain the official translation to your language on a continuous basis, you can contact @TelegramAuditions. Please include a hashtag with the English name of your language (e.g. #Albanian) and a few links to phrases on this platform with your translation suggestions or comments. Be sure to read the Style Guide carefully before you apply.
-Yes, we are always looking for volunteers to help us with user support. If you would be interested in answering questions about Telegram to users from your country, contact our auditions account.
-Before you apply, please check out the Telegram Support Initiative.
-Telegram Passport is a unified authorization method for services that require personal identification. With Telegram Passport, you can upload your documents once, then instantly share your data with services that require real-world ID (finance, ICOs, etc.).
-Your identity documents and personal data will be stored in the Telegram cloud using End-to-End Encryption. To Telegram, this data is just random gibberish, and we have no access to the information you store in your Telegram Passport. When you share data, it goes directly to the recipient.
---You can find more information about Telegram Passport on our blog.
-
If you're a developer or owner of a service that requires real-life ID, kindly take a look at this manual. You can also try requesting Telegram Passport data using this page.
-Please make sure you are entering your mobile phone number in the international format.
I.e.: +(country code)(city or carrier code)(your number)
If you are having registration or login problems, please contact us using this form.
-For security reasons, login codes dictated via a phone call are only available for accounts that have two-step verification enabled (Settings > Privacy & Security > Two-Step Verification).
-Please also note that Telegram accounts can only be connected to a mobile number. We currently don't support landline numbers.
-If you have recently used one of our apps on another device (it could also be a different app on the same device), we may send the login code via Telegram instead of SMS.
-To receive such a code, just check Telegram from any of your connected devices. You will find it in the chat with Telegram, a verified profile with a blue check:
- - -WARNING! Please note that getting codes via Telegram should not be considered an alternative to using an up-to-date phone number. In case of a change in numbers, always make sure Telegram is connected to a phone number you control, otherwise you risk losing access to your account forever.
---If the tips below don't help, check out this detailed guide on Troubleshooting Notification Issues.
-
ANDROID
---NOTE: Huawei and Xiaomi devices have evil task killer services that interfere with the Telegram notification service. For our notifications to work, you need to add Telegram to allowed apps in those devices' security settings. Huawei: Phone Manager App > Protected Apps > Add Telegram to the list. Xiaomi: Services > Security > Permissions > Autostart, find Telegram and enable autostart.
-
iOS
-If you know your friends have Telegram, but you can't see them — or they appear as numbers instead of names.
-Android:
-iOS:
-To delete a contact, open a chat with the person, tap the title in the top area of the chat screen to open their profile, then tap on (⋮) in the top right corner > 'Delete contact'.
-If you want to delete the contact completely, make sure you also delete them from your phone contacts. Telegram stays in sync and will add the contact back if you don't.
-Secret Chats are established between the two devices they were created on. This means that all those messages are not available in the cloud and cannot be accessed on other devices.
-Moreover, Secret Chats are also tied to your current login session on the device. If you log out and in again, you will lose all your Secret Chats.
-When users report unwanted messages from a Telegram account, we apply a limit: Reported accounts can only send messages to people who have their number saved as a contact.
-This means that if you randomly contact people you don't know and send them annoying messages, you may lose the ability to do so in the future.
-If you think that this limit was applied to your account wrongly, please visit this page.
-Telegram can use the microphone in the background if you minimize the app when making a call, recording a video, or recording a voice/video message.
-Permission monitors on Samsung and Xiaomi can inadvertently flag and notify you that Telegram requested access to camera in the background. This happens when the app requests info about the camera — it isn’t using the camera. Unfortunately it may look the same to the Samsung and Xiaomi permission monitors.
-Camera info is requested by the app when you tap on the attachment button, or start recording a video or a video message. If you do this and quickly close the app, the already initiated request may try to run asynchronously when the app is already in the background, or be sent when the system wakes up the app to show a notification about a new message. In any case, these requests are only for the camera info, the app never uses the camera itself in the background.
-Anyone can check Telegram’s open source code and confirm that the app is not doing anything behind their back. We also offer reproducible builds that can help you prove that the version you downloaded from App Store or Google Play is built from the exact same source code we publish.
-If you have any other questions, please contact Telegram Support (in Telegram go to Settings — Ask a question). Note that we rely on volunteers for support.
-If you can't log in to your account, please use this form.
---For media requests, please contact @PressBot on Telegram.
-
Yep. Follow us! @telegram
Our twitter account in Spanish: @telegram_es
In Italian: @telegram_it
In Korean: @Telegram_kr
In German: @de_telegram
For users from Brazil: @Telegram_br
Our Arabic-speaking users may find @telegram_arabic more interesting.
We have a special account that can help you with login problems, @smstelegram. This account is official. Don't be afraid to DM it the number you use for Telegram, we need this info to investigate issues.
-Be careful, we don't have any other support accounts on any social media platforms.
-If anyone on Facebook or any other platform is telling you they're us, they are not.
- ---This FAQ is for people whose accounts were limited after being reported for spam.
-
Back to the main FAQ »
When users press the ‘Report spam’ button in a chat, they forward these messages to our team of moderators for review. If the moderators decide that the messages deserved this, the account becomes limited temporarily.
-This means that if you have been sending unwanted messages to random strangers or posting spam in groups, you lose the ability to do so.
-No, it's not that bad. Limited accounts can send messages to people who have their number saved as a contact. You can also always reply to anyone who messages you first.
-Telegram‘s username search is not a tool for making new friends. People usually don’t like it when strangers contact them — so they will report you if they find your messages annoying. Please only contact people if you're sure that they are expecting messages from you. The same applies to adding people to unwanted groups and channels. In addition to this, group admins can also report users who post spam in their groups.
-Naturally, all such reports are also checked by human moderators. If the messages contain spam, the account will be temporarily limited.
-For private messages, it really doesn‘t matter what you send, as long as the receivers find it unwelcome. It could have been a photo, an invite link or a simple ’hello‘. Please only send messages when you are sure people won’t mind getting them.
-As a general rule, people do mind getting unsolicited advertisements, links, invite links to groups or channels, random photos and, above all, anything related to commerce or online popularity. If you send them something like this, you will be blocked — and everybody else will be happy.
-Moderators are more lenient when it comes to messages in groups, but anyone who sends spam or unsolicited advertisments will be limited.
-If this happened to you for the first time (and you are not an industrial scale spammer), most likely your account will be limited for a few days or so. Please wait and consider that people want a peaceful time using our messenger.
-Repeated offences will result in longer periods of being blocked. If you keep writing unwanted messages to strangers, you may lose the ability to do so forever.
-If you are sure that the limit was wrongfully applied to your account, please contact our @SpamBot.
-Please forgive us for the inconvenience — even the best systems, algorithms and well-trained people can make mistakes sometimes.
-We're sorry, but this is impossible. We value the inner peace of Telegram users too much.
-Some numbers may trigger an overly harsh response from our system, either due to their previous owners‘ activities or due to them being certain virtual/VOIP numbers. We’re sorry if this resulted in your account being limited for no reason.
-If you think this is your case, please contact @SpamBot and tell it your story.
-