In this article, you will learn about Telegram Messenger, why use Telegram Cloud in your own applications, TDLib Library, using OpenSSL for security and encryption, developing your own Telegram in Windows app development software, and much more.
Table of Contents
What is Telegram Messenger?
Telegram Messenger is a popular cloud instant messaging application. This application offers multiple services including instant text messaging and video calls which are end to end encrypted. Telegram also allows for secure file sharing and many other powerful features which would be hard to do independently in your own code.
Telegram Messenger is famous for the level of security it offers for users. Furthermore, Telegram Messenger offers a free and open Telegram API that allows anyone to create their own messaging apps operating in the Telegram cloud. To ease Telegram API integration, a cross-platform library completely free is provided too. This library is known as TDLib library.
Why use the Telegram cloud in your own application ?
Telegram Messenger is more than an instant messaging application; it’s a real social network with the capabilities and features we’ve come to expect. For example, if you need a notification feature in your application, integrating with the Telegram cloud allows you to get this feature very quickly and be in touch with all Telegram users.
A brief look at TDLib library.
The advantage of using the TDLib component library are :
- Cross platform capability (Windows,Android,iOS,MacOS,Linux)
- High-performance. it can be red in the documentation that each TDLib instance can manage around 20000 bots.
- Consistent: The TDLib checks that all incoming messages and answers are dispatched in the correct temporal order.
- Reliable : TDLib can work on slow and unstable internet connections.
- Secure: All local data are encrypted.
- Asynchronous : Each call to TDLib doesnt block main thread.
We use OpenSSL to provide security and encryption
This library has also some dependency with OpenSSL. It also needs to use the Zlib compression library. This will mean we need to download those packages and include . or link the following third party binaries from them as you can see below:
- tdjson.dll
- libcrypto-1_1.dll
- libssl-1_1.dll
- zlib1.dll
The Windows version of TDLib needs Visual C++ runtime that can be found at : https://www.microsoft.com/en-us/download/details.aspx?id=52685
How can I develop my own Telegram client in Delphi?
The TDLib libray has a lot of exposed methods and despite the detailed documentation, it’s not so easy to deal with it directly. However the components suite of ESEGECE company does a lot of the hard work for you and provides the main methods to develop your own customized Telegram client. We’ve talked before about ESEGECE on the blog. Their components have a pretty wide range of uses and are definitely worth checking out.
Is there a Telegram messenger component for use in Delphi?
The first step will be to download the Websockets components suite of ESEGECE here in order to use their TsgcTDLib_Telegram component.
Declare a new Telegram application
To be allowed to connect to the Telegram Messenger cloud, you will need an API ID and API Hash Key. To get them, you will need to
- Sign up for Telegram cloud with any Telegram client.
- Log in to the site : https://my.telegram.org
- Go to API development tools and fill out the form and you will get api_id and api_hash parameters required for user authorization.
Use TsgcTDLib_Telegram component
Start a new VCL or FireMonkey FMX project with Delphi and drag drop the TsgcTDLib_Telegram component. You are ready to create your own Telegram client.
How does a messenger app work?
As for any client-server architecture, a client needs to be connected to the server before it can send or receive any data. To keep things secure there is an authentication system. Let’s have a look how the authorization mechanism works.
Telegram App Authorization steps
Developer must fill some mandatory parameters to be able to connect to Telegram cloud. You can go to my.telegram.org to get the API authorization keys which can be found in the the Telegram.API property group. If developer wants to be declared as a user a phone number must be set. If he/she wants to be declared as a bot then a bot token must be set.
See below for an example of initialization of an instance of the TsgcTDLib_Telegram class.
1 2 3 4 5 6 7 8 9 10 |
//sgcTelegram was drag dropped on a form no need to create sgcTelegram.Telegram.API.ApiHash := apiHash; sgcTelegram.Telegram.API.ApiId := apiID; sgcTelegram.Telegram.PhoneNumber := ''+0155512345678'; sgcTelegram.ApplicationVersion := '1.0'; sgcTelegram.DeviceModel := 'Desktop'; sgcTelegram.LanguageCode := 'en'; sgcTelegram.SystemVersion := 'Windows'; //here Active = True means the connection is queried sgcTelegram.Active := true; |
As soon as the Active property is set to True, some events are fired to finalize the authorization procedure.
The OnConnectionStatus event
This event is fired each time the connection status changes. Some values of Status are:
- connectionStateConnecting
- connectionStateUpdating
- connectionStateReady
The OnAuthenticationCode event
The phone number is registered on the Telegram cloud and a grant code is sent through Telegram application.If the phone number is not registered to the Telegram cloud the grant code is sent through SMS.
Just implement in the a simple InputBox to enter the receieved code to complete the authorization process.
1 2 3 4 5 |
procedure TFormTelegram.sgcTelegramAuthenticationCode(Sender: TObject; var Code: string); begin Code := InputBox('Telegram', 'Introduce Telegram Code', ''); end; |
OnRegisterUser events allow us to sign up new users to Telegram and our messenger app
In the case of the used phone number was not registered on the Telegram system, the sign up process is started automatically . This sign up process needs the first name and the last name of the user. To get them an event OnRegisterUser is fired . See below a very simple implementation of this event :
1 2 3 4 5 6 |
procedure TFormTelegram.sgcTelegramRegisterUser(Sender: TObject; var FirstName, LastName: string); begin FirstName := InputBox('Telegram', 'Your FirstName', ''); LastName := InputBox('Telegram', 'Your LastName', ''); end; |
OnAuthorizationStatus events and what they do
During all these authorizations steps, an event OnAuthorizationStatus is fired to describe which step is achieved in this process. Most values of the status are:
- authorizationStateWaitTdlibParameters
- authorizationStateWaitEncryptionKey
- authorizationStateWaitPhoneNumber
- authorizationStateWaitCode
- authorizationStateLoggingOut
- authorizationStateClosed
- authorizationStateReady
Once the authorization is granted, the application is ready to send and receive messages with other Telegram users.
How to exchange messages on the Telegram cloud
With our use of the Telegram API instant messaging applications are built around a chat room and users subscribed to that room. Literally, users join in a chat room and exchange messages. To send a public message for several users in the same chat room, only the identifier of the chat room is needed. The Telegram cloud will dispatch the message to all users associated to this chat room. Ultimately, the goal of a chat application is to receive and send messages publicly to the group and privately. Let’s check how it works with the TsgcTDLib_Telegram component.
How do I receive messages from Telegram users in my Delphi Windows and Mobile apps?
It’s the simplest part. Just implement the event OnMessageText(Sender: TObject; MessageText: TsgcTelegramMessageText); When another user of Telegram sends a message to you, this event will be fired in your application. The class TsgcTelegramMessageText owns properties ChatID and SenderUserID that allow to identify in which chat room and which user sent the message. The content of the message is set in the property Text of this class.
How can we send messages to Telegram users from our app?
The method of the TsgcTDLib_Telegram class used to send a message is SendTextMessage(aChatID:integer;aMessageText:string); It means we must know the ChatID of the chat room where to send the message. In this case all the members of this chat room will receive the message. If the chat room is already opened and the exchange of messages is already started, the ChatID is already known through the event OnMessageText. But, if the user of the application wants to start the chat, the problem is a bit more tricky to solve. To create a chat room and get its ChatID , we can use the method CreateNewBasicGroupChat(aUserIds array of Int64;const aTitle:string); to create a group chat or CreatePrivateChat(userId:integer); to create a chat with a single user.
The list of user identifiers (aUserIds) is passed with the title of the room chat This list symbolizes the list of participants in the chat. The ChatID will be returned in the event OnNewChat(Sender: TObject; Chat:TsgcTelegramChat);
The Chat identifier (ChatId) is reachable through the property ChatId of TsgcTelegramChat class. To create a chat room and to be able to send message to other users we need to know the user identifiers (UserID) of the message target.
How do I get a Telegram user identifier from a phone number?
The UserID is a number only known by Telegram cloud. The phone number, however,. is the public identifier in the real world for any user.
The TDLib exposes a method to get the UserID of an user from his phone number in the case he is registered on the Telegram cloud. The list of Telegram APIs can be read here.
To use directly the APIs in Json format , we must use the method TDLibSend. It sends a command to the TDLib library and the result of this command is seen through the event OnEvent(Sender: TObject; const Event,Text: string); The parameter Event as a string allows to categoryze the event type and the parameter Text is the whole data in JSon format. The number of API exposed in TDLib is really huge but lets have a look at the one used to get an UserID from a phone number. The TDLib API to get the UserID from a phone number is importContacts. The documentation is as below :
The type is a function that return importedContacts structure. The input parameter of importContacts function is an array of contact structure. Then have a look at the contact structure.
How to programmatically define a contact in Telegram using only the phone number
It means you can describe a contact by his phone number, first name, last name, vcard and user_id. Lets define the contact with the phone number only. The ‘importContacts‘ method call in JSon will write like.
1 |
sgcTelegram.TDLibSend('{"@type": "importContacts", "contacts": [{"phone_number": "+01555678945"}]); |
The documentation show that the result is importedContacts like :
It will be received through the OnEvent event .
Here is an example of a JSON string received : {“@type”:”importedContacts”,”user_ids”:[15138448729],”importer_count”:[0]}
In this example the owner of the phone number +01555678945 is registred to the Telegram cloud and has UserID : 15138448729. If the phone number is not registred the user_id in the importedContacts callback is 0. It’s highly recommended to log all received events to have a better idea how to interpret it . Then the procedure to parse the UserIds from a list of phone number is as below :
1 2 3 4 5 6 7 |
procedure TFRMTelegramFMX.sgcTelegramEvent(Sender: TObject; const Event, Text: string); begin if Event ='importedContacts' then begin FUserIDList := ParseImportedContacts(Text); end; end; |
with the method ParseImportedContacts to parse the importedContacts JSon structure.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
function TFRMTelegramFMX.ParseImportedContacts(aText: string):TStringList; var aJson:TJsonValue; userIdArray:TJsonArray; iter:integer; begin Result := TStringList.Create; aJson := TJSONObject.ParseJSONValue(aText); userIdArray := aJson.P['user_ids'] as TJsonArray; for iter := 0 to userIdArray.Count-1 do begin Result.Add(userIdArray.Items[iter].ToJSON); end; aJson.Free; end; |
Avoiding spammers and scammers
The method GetUser of the TsgcTDLib_Telegram class allows the user to retrieve the civility of the target user using the same way to parse the Json string receive through the OnEvent event. See below Json string received after a call of GetUser method
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
{ "@type":"user", "id":15138448729, "first_name":"John", "last_name":"", "username":"", "phone_number":"01555678945", "status":{ "@type":"userStatusOffline", "was_online":1626193501 }, "is_contact":true, "is_mutual_contact":true, "is_verified":false, "is_support":false, "restriction_reason":"", "is_scam":false, "have_access":true, "type":{ "@type":"userTypeRegular" }, "language_code":"" } |
With such method you can copy the official Telegram behaviour if user wants to initiate a chat when he knows only the phone number of the target user. Please note that after authorization granting, Telegram sends to the application through the OnEvent event all already known contacts in Telegram of the owner of the phone number .
Would you like to download a working demo of an instant messenger app with full source code?
A demo with source code is available at https://github.com/checkdigits/TelegramDemo
Try it yourself!
Download the trial version of the Websocket component suite of ESEGECE and have fun on the Telegram cloud using Rad Studio, our favorite development tool of course.
Design. Code. Compile. Deploy.
Start Free Trial Upgrade Today
Free Delphi Community Edition Free C++Builder Community Edition
Awesome 👍 thank you for sharing good material to us to learn more🙏
Hi, sorry for the late reply but 1000 thank you. It’s warm to read such comment. Regards
How can we send messages to Bot ?
I’m not sure I understand your question. The article does suggest some further reading but you can also download the demo’s source code and try it for yourself: https://github.com/checkdigits/TelegramDemo
I am using Delphi 10.3.
From the page https://www.esegece.com/websockets/download
I downloaded the “Delphi WebSockets Components Trial” installer for Delphi 10_3 (file sgcWebSockets_D10_3.zip), installed it, accordingly opened the demo project “\sgcWebSockets\Demos\50.Other \01.Telegram_Client\sgcTelegramFMX.dproj”.
But when trying to compile the project with Target Platforms = Androide 32
it doesn’t compile and throws an error
“[DCC Error] FTelegramFMX.pas(21): E2003 Undeclared identifier: ‘TsgcTDLib_Telegram'”
on the source code line “sgcTelegram: TsgcTDLib_Telegram;”
although with Target Platforms = Windows 32 the program compiles
You can force the search path of unit source code for the Android32 profile, maybe it will resolve your problem …