I want to implement multiple authorization using PHP for interaction with Telegram REST API.
What task am I trying to solve? Well, it’s simple: several dozens of users (all of them have a carma like here (+10, -2, +1000 etc.) with relevant group taxonomy: web-masters and customers) have a user profile on my website. After they reach a certain amount of carma and since they are authorized in their profile they are joined to private chats based on Telegram generated for them automatically.
After some research, I found that it’s very complicated because:
- I’ve never had an experience of API implementation for hardware-binded social networks.
-
I took a look at https://core.telegram.org/api/auth, but it’s completely unobvious how to implement these functions (for example auth.sendCode), using PHP or any other language. If these commands should be sent as JSON to server, then it doesn’t look like JSON:
auth.sentCode#efed51d9 phone_registered:Bool phone_code_hash:string send_call_timeout:int is_password:Bool = auth.SentCode;
What is it? In which language is it written?
UPD: It’s written in TL (Type Language): https://core.telegram.org/mtproto/TL
-
I’ve explored the source code of several clients (Webogram, Telegram-cli (tg), tdesktop), and I found several implementations of https://core.telegram.org/mtproto
Unfortunately, none of them support multiple authorization on their side, and after a little bit of research, I have no idea where to dig deeper to find out more information.
Also, these implementations look bulky and compound (for example, https://github.com/vysheng/tg):
There I see bunch of servers (./tg/tgl/tgl.h):
#define TG_SERVER_1 "149.154.175.50"
#define TG_SERVER_2 "149.154.167.51"
#define TG_SERVER_3 "149.154.175.100"
#define TG_SERVER_4 "149.154.167.91"
#define TG_SERVER_5 "149.154.171.5"
I found several possibly appropriate functions (./tg/tgl/queries.c):
void empty_auth_file (void) {
if (TLS->test_mode) {
bl_do_dc_option (TLS, 1, "", 0, TG_SERVER_TEST_1, strlen (TG_SERVER_TEST_1), 443);
bl_do_dc_option (TLS, 2, "", 0, TG_SERVER_TEST_2, strlen (TG_SERVER_TEST_2), 443);
bl_do_dc_option (TLS, 3, "", 0, TG_SERVER_TEST_3, strlen (TG_SERVER_TEST_3), 443);
bl_do_set_working_dc (TLS, TG_SERVER_TEST_DEFAULT);
} else {
bl_do_dc_option (TLS, 1, "", 0, TG_SERVER_1, strlen (TG_SERVER_1), 443);
bl_do_dc_option (TLS, 2, "", 0, TG_SERVER_2, strlen (TG_SERVER_2), 443);
bl_do_dc_option (TLS, 3, "", 0, TG_SERVER_3, strlen (TG_SERVER_3), 443);
bl_do_dc_option (TLS, 4, "", 0, TG_SERVER_4, strlen (TG_SERVER_4), 443);
bl_do_dc_option (TLS, 5, "", 0, TG_SERVER_5, strlen (TG_SERVER_5), 443);
bl_do_set_working_dc (TLS, TG_SERVER_DEFAULT);
}
}
void bl_do_dc_option (struct tgl_state *TLS, int id, const char *name, int l1, const char *ip, int l2, int port) {
struct tgl_dc *DC = TLS->DC_list[id];
if (DC && !strncmp (ip, DC->ip, l2)) { return; }
clear_packet ();
out_int (CODE_binlog_dc_option);
out_int (id);
out_cstring (name, l1);
out_cstring (ip, l2);
out_int (port);
add_log_event (TLS, packet_buffer, 4 * (packet_ptr - packet_buffer));
}
etc.
What files should I transfer to PHP for multiple user auth implementation?
Could you please help me to know where to start from and how to make it easier than it currently is?
Thank you in advance!
4
Answers
So far I have been able to implement the telegram authorization completely, but not in your requested language – PHP, I used vb.Net. However, I believe the same logic should apply.
Creating a Telegram Authorization Key
Telegram API is no walk in the park. Studying existing src code could be quite daunting (IMHO). Hence my approach was to study the online API documentation and implement the sample-auth_key outlined in the links below.
https://core.telegram.org/mtproto/auth_key
https://core.telegram.org/mtproto/samples-auth_key
What this approach will give you is a better understanding and introduction to the primitives used throughout Telegram API, and possibly help you start organizing your own set of functions and routines to handle which you will need for the next steps – implementing other features of the API, since generating an AuthKey is just the beginning.
Step 1
All Communication is via TCP – Once you have obtained a unique api_id (https://core.telegram.org/api/obtaining_api_id#obtaining-api-id) you will find the following IP advertised for use in testing: 149.154.167.40:433 The api_id is not required at this point for generating an AuthKey
Setup your preferred method of Send/Receive TCP processing Loop
what I have is a private SendData that simply sends a bytes to a live socket connected to the give IP address above
Finally for this step, we need a TcpPack() method which helps us pad our data in the format Telegram expects – see code below with comments
STEP 2
With the basic TCP send/receive routines setup, we can start preparing data packets to send to telegram and have sub routines for handling the specific responses received – ProcessResponse(data)
What we need to understand next is the fact that Telegram handles 2 broad categories of messages –
Unencrypted – https://core.telegram.org/mtproto/description#unencrypted-message
These are plain text messages with their
auth_key_id =0
generating an AuthKey uses this type of message throughoutEncrypted – https://core.telegram.org/mtproto/description#encrypted-message-encrypted-data
All further communication with Telegram Servers will be via encrypted messages
I choose to have two classes to encapsulate both message types. I can then have two Send(m) methods that handles each type
For now only UnencryptedMessage is required
STEP 3
Now we follow he series of steps outlined in https://core.telegram.org/mtproto/auth_key
My approach for this is very simple:
In a Class called MTProto I implement a set of shared functions as required by each step of the exchange. Each method is simply building up an Encrypted data structure which will be sent as above where required
We start with: req_pq
Public Const ZERO_TICK = 621355968000000000 — i.e. 1970-01-01T00:00:00Z (January 1, 1970, at 12:00 AM UTC)
Now our process response method from Step 1
Great so far, each response received has a message_type code.
we can switch on that and determine how each is handled. We need to process resPQ right now.
What i have done is to create a a set of classes that each handles a specific response type
Each is based on this simple object
Building on this, we tackle steps 3 & 4
This is initiated here
RequestDHKeyExchange(New resPQ(r.message_data))
in myProcessResponse
routine aboveYou can use your own implementation of Prime-Decomposition to replace this line
Dim pp = New PrimeProduct(r.pq)
Here is an example of how I learnt do it using PollardBrent (Pollard Rho Brent Integer Factorization) https://stackoverflow.com/a/31978350/44080
Okay if you can follow up to this point you have a general idea of how i’m decomposing the AuthKey implementation step by step.
You should be able to run through the remaining steps 5-9. It’s a lot for me to type…
If this answer so far is of any help to anyone, then i’ll take out time to organize and post the remaining part.
I believe that the routines and knowledge you build up along the way should give you the tools you need to both understand and implement your own independent Telegram API code from scratch.
Completed Interaction Dump
….
Regards.
As a follow up to my original post, once you are done with the auth_key steps the following will be useful to quickly get you up to speed with how the rest of telegram works.
1) Download and study the source code for Webogram, it is all basically JavaScript.
2) run a local copy of Webogram modified with console.logs to clearly show you step by step the interactions that are taking place between “a working telegram client” and the telegram servers. This will give you a work-flow of how telegram clients and Telegram really work.
3) Use whatever development language you are most comfortable with to build your own implementation of a Protocol Parser for converting binary streams into TL types and vice-versa
It’s actually quite fun to code this step. I’ve just built a simple Protocol Parser in Elixir
4) Here is a sample log from a modified copy of Webogram.
It shows what steps to take after successfully generated your Auth_key
You even get to see where it has to generate a new Auth_key in-flight as it switches the validated your to the proper DataCenter, recreating his session, new server_salts etc (not shown)
Regards.
I have written a PHP implementation of mtproto, and so far I have managed to implement TL serialization/deserialization, tcp abridged/intermediate/full connections, http/https connections.
I have implemented OOP wrappers for all mtproto methods, a prime generation module based on Python/wolfram alpha/php, HTML/Markdown parsing with support for mentions, bot API file id support, update handling with callbacks or getupdates, bot API <-> MTProto object conversion, upload/download wrappers, login wrappers for bots/users (2FA is supported), simple error handling, internal peer management (you can provide a simple bot API chat id, a username or a peer id in tg-cli format to send a message or to call other mtproto methods) and I am currently working on a nice Lua wrapper to allow usage of td-cli/tg-cli bots w/ MadelineProto.
I have also written a class to generate documentation for all mtproto methods/constructors/types (available at https://daniil.it/MadelineProto/API_docs).
MadelineProto can be serialized to a file to allow easy session storage.
If anyone is interested, or wants to contribute, here is the link to the github repo: https://github.com/danog/MadelineProto
As of February’2018 you can use an official Telegram Login Widget on your website.