この記事は、Thierry Grassia氏のブログの抄訳です
Table of Contents
Telegram Messengerとは?
Telegram Messengerは、人気の高いクラウドインスタントメッセージングアプリケーションです。 このアプリケーションは、エンドツーエンドで暗号化されたインスタントテキストメッセージングやビデオ通話など、複数のサービスを提供しています。またTelegramでは、安全なファイル共有や独自のコードで個別に実行するのが難しい多くの強力な機能も可能にします。
Telegram Messengerは、ユーザーに提供するセキュリティレベルが高いことで有名です。さらにTelegram Messengerは、Telegramのクラウド上で動作する独自のメッセージングアプリを誰でも作成可能な無料でオープンなTelegram APIを提供しています。またTelegram APIの統合を容易にするために、完全に無料のクロスプラットフォームライブラリも提供されています。このライブラリはTDLibライブラリとして知られています。
アプリケーションでTelegramクラウドを使用する理由は?
Telegram Messengerは、単なるインスタントメッセージングアプリケーションではなく、私たちが期待する機能や特徴を備えた真のソーシャルネットワークです。例えば、アプリケーションに通知機能が必要な場合、Telegramクラウドと統合することで、とても迅速にこの機能を取得して、すべてのTelegramユーザーと連絡を取ることができます。
TDLibライブラリについて
TDLibコンポーネントライブラリを使用する利点は、以下の通りです。
- クロスプラットフォーム対応: Windows、Android、iOS、MacOS、Linux等の様々なプラットホームをサポート
- 高性能: ドキュメントによると、TDLibの各インスタンスは約20000のボットの管理が可能
- 一貫性: TDLibは、すべての着信メッセージと応答が正しい時間順序でディスパッチされていることを確認
- 信頼性: TDLibは、低速で不安定なインターネット接続でも動作
- 安全性: すべてのローカルデータは暗号化される
- 非同期: TDLibを呼び出す度に、メインスレッドがブロックされない
セキュリティと暗号化のためにOpenSSLを使用
このライブラリは、OpenSSLに依存しており、Zlib圧縮ライブラリも使用する必要があります。このため、これらのパッケージをダウンロードして、以下で示すサードパーティのバイナリをインクルードまたはリンクする必要があります。
- tdjson.dll
- libcrypto-1_1.dll
- libssl-1_1.dll
- zlib1.dll
またWindows向けのTDLibでは、Visual C++ランタイムライブラリも必要です。
https://www.microsoft.com/ja-jp/download/details.aspx?id=52685
Delphiで独自のTelegramクライアントを開発するには?
TDLibライブラリには多くの公開されたメソッドがあり、詳細なドキュメントがあるにもかかわらず、直接処理するのはそれほど簡単ではありません。しかし、ESEGECE社のコンポーネントスイートは、多くの困難な作業を代行し、独自にカスタマイズしたTelegramクライアントを開発するための主要なメソッドを提供しています。
以前、エンバカデロのブログでもESEGECE社のWebsocketsを紹介したことがあります。併せてこちらもチェックしてください。
Delphiで使用可能なTelegram Messengerコンポーネントは?
最初のステップは、ESEGECE社のWebsocketsコンポーネントスイートをこちらからダウンロードして、TsgcTDLib_Telegramコンポーネントを使用することです。(トライアル版も利用できます)
新しいTelegramアプリケーションを作成
Telegram Messengerのクラウドへの接続を許可するには、、PI IDとAPI Hash Keyが必要となります。以下の手順で取得できます。
- TelegramクライアントでTelegramクラウドにサインアップする
- https://my.telegram.orgのサイトにログインする
- API開発ツールにアクセスし、フォームに必要事項を入力すると、ユーザー認証に必要なapi_idとapi_hashのパラメータが得られます。
TsgcTDLib_Telegramコンポーネントの使用
Delphiで新しいVCLまたはFireMonkey FMXプロジェクトを作成し、TsgcTDLib_Telegramコンポーネントをドラッグアンドドロップします。これで、独自のTelegramクライアントを作成する準備が整いました。
Messengerアプリの動作の仕組みは?
他のクライアント/サーバーアーキテクチャの場合と同様に、クライアントはデータを送受信する前にサーバーに接続する必要があり、安全性を保つために認証システムがあります。ここでは、認証メカニズムがどのように機能するかを見てみましょう。
Telegramアプリの認証手順
開発者は、Telegramクラウドに接続できるようにするために、いくつかの必須パラメータを入力する必要があります。my.telegram.orgにアクセスして、Telegram.APIプロパティグループにあるAPI認証キーを取得できます。 開発者がユーザーとして宣言したい場合は、電話番号を設定する必要があります。ボットとして宣言されたい場合は、ボットトークンを設定する必要があります。
TsgcTDLib_Telegramクラスのインスタンスを初期化するコード例は以下の通りです。
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; |
Active プロパティが True に設定されるとすぐに、認証手順を完了するためにいくつかのイベントが発生します。
OnConnectionStatusイベント
このイベントは、接続ステータスが変更されるたびに発生します。 接続ステータスは、以下の通りです。
- connectionStateConnecting
- connectionStateUpdating
- connectionStateReady
OnAuthenticationCodeイベント
電話番号がTelegramクラウドに登録されている場合は、Telegramアプリケーションを介して認証コードが送信されます。電話番号がTelegramクラウドに登録されていない場合は、SMSを介して認証コードが送信されます。
シンプルなInputBoxを実装して、受信したコードを入力するだけで、認証プロセスを完了できます。
1 2 3 4 5 |
procedure TFormTelegram.sgcTelegramAuthenticationCode(Sender: TObject; var Code: string); begin Code := InputBox('Telegram', 'Introduce Telegram Code', ''); end; |
Telegram Messagerアプリは、OnRegisterUserイベントによって新規ユーザーを登録
使用した電話番号がTelegramシステムに登録されていない場合は、自動的にサインアッププロセスが開始されます。このサインアッププロセスでは、ユーザーの姓と名が必要です。それらを取得するために、イベントOnRegisterUserが発生します。このイベントの非常にシンプルな実装コード例は、以下の通りです。
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イベント
これらの認証ステップ中に、OnAuthorizationStatusイベントが発生し、このプロセスでどのステップに達しているか確認できます。そのステータスの種類は、以下の通りです。
- authorizationStateWaitTdlibParameters
- authorizationStateWaitEncryptionKey
- authorizationStateWaitPhoneNumber
- authorizationStateWaitCode
- authorizationStateLoggingOut
- authorizationStateClosed
- authorizationStateReady
認証が完了すると、アプリケーションは他のTelegramユーザーとメッセージを送受信できるようになります。
Telegramクラウドでのメッセージ交換方法
Telegram APIを使用したインスタントメッセージングアプリケーションは、チャットルームを中心に構築され、ユーザーはそのチャットルームに登録します。文字通り、ユーザーはチャットルームに参加し、メッセージを交換します。同じチャットルームにいる複数のユーザーに公開メッセージを送信するには、チャットルームの識別子のみが必要です。Telegramクラウドは、このチャットルームに関連付けられたすべてのユーザーにメッセージを発信します。最終的に、このチャットアプリケーションの目的は、メッセージをグループに対して公開および非公開で送受信することです。それでは、TsgcTDLib_Telegramコンポーネントを使用して、その仕組みを確認してみましょう。
DelphiのWindowsおよびモバイルアプリでTelegramユーザーからのメッセージを受信するには?
一番シンプルな部分です。イベント OnMessageText(Sender: TObject; MessageText: TsgcTelegramMessageText); を実装するだけで、Telegramの他のユーザーがあなたにメッセージを送信すると、このイベントがあなたのアプリケーションで発生します。TsgcTelegramMessageTextクラスは、どのチャットルームでどのユーザーがメッセージを送信したかを識別できるChatIDとSenderUserIDというプロパティを持っています。メッセージの内容は、このクラスのTextプロパティに設定されています。
アプリからTelegramユーザーにメッセージを送信するには?
メッセージの送信に使用されるTsgcTDLib_Telegramクラスのメソッドは、SendTextMessage(aChatID:integer; aMessageText:string);です。 つまり、メッセージの送信先であるチャットルームのChatIDを知っている必要があります。
この場合、このチャットルームのすべてのメンバーがメッセージを受信します。チャットルームがすでに開かれていて、メッセージの交換がすでに開始されている場合、ChatIDはイベントOnMessageTextを通じて既にに認識されています。ただし、アプリケーションのユーザーがチャットを開始したい場合、この問題はもう少し厄介なものになります。チャットルームを作成し、そのChatIDを取得するには、CreateNewBasicGroupChat(aUserIds array of Int64;const aTitle:string)というメソッドを使用します。
グループチャットを作成する場合は、CreatePrivateChat(userId:integer);によって作成します。
ユーザー識別子(aUserIds)のリストは、ルームチャットのタイトルと共に渡されます このリストは、チャットの参加者のリストを表します。 ChatIDは、OnNewChat(Sender:TObject; Chat:TsgcTelegramChat);イベントで返されます。
チャットの識別子(ChatId)は、TsgcTelegramChatクラスのプロパティChatIdから取得できます。チャットルームを作成し、他のユーザーにメッセージを送信するためには、メッセージ対象のユーザー識別子(UserID)を知る必要があります。
電話番号からTelegramのユーザーIDを取得するには?
UserIDは、Telegramクラウドでのみ認識される番号ですが、電話番号は、あらゆるユーザーの現実の世界での公開識別子です。
TDLibでは、ユーザーがTelegramクラウドに登録している場合に、電話番号からユーザーのUserIDを取得するメソッドを公開しています。Telegram APIのリストはこちらをご覧ください。
Json形式のAPIを直接使用するには、TDLibSendメソッドを使用する必要があります。このメソッドはTDLibライブラリにコマンドを送信し、このコマンドの結果は、OnEvent(Sender: TObject; const Event,Text: string);イベントを通じて確認できます。 文字列としてのパラメータEventはイベントタイプをカテゴリ化することができ、パラメータTextはJSON形式の全データです。TDLibで公開されているAPIの数は非常に多いのですが、ここでは電話番号からユーザーIDを取得するためのAPIを見てみましょう。電話番号からUserIDを取得するためのTDLib APIは、importContactsです。ドキュメントは以下の通りです。
typeは importedContacts構造体を返す関数です。importContacts関数の入力パラメータは、contact構造の配列です。それでは、contact構造を見てみましょう。
電話番号のみを使用してTelegramで連絡先をプログラムで定義する方法
これは連絡先を電話番号、名前、姓、vcard、user_idで記述できることを意味します。 ここでは、電話番号のみで連絡先を定義してみましょう。JSONの’importContacts’メソッドを呼び出すコード例は、以下の通りです。
1 |
sgcTelegram.TDLibSend('{"@type": "importContacts", "contacts": [{"phone_number": "+01555678945"}]); |
ドキュメントによると、結果は以下のようなimportedContactsになります。
OnEventイベントで受信されます。
受信したJSON文字列の例は、以下の通りです。
{“@type”: “importedContacts”, “user_ids”:[15138448729], “importer_count”:[0]}
この例では、電話番号+01555678945の所有者はTelegramクラウドに登録されており、UserID : 15138448729を持っています。電話番号が登録されていない場合、importedContactsコールバックのuser_idは0です。受信したイベントをすべてログに記録して、どのように解釈すべきかを把握しておくことを強くお勧めします。次に、電話番号のリストからUserIDを解析する手順は以下の通りです。
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; |
ParseImportedContactsメソッドを使用して importedContactsのJSON構造を解析します。
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; |
スパムやスキャマーを回避するには
TsgcTDLib_TelegramクラスのメソッドGetUserを使用すると、ユーザーは、OnEventイベントで受け取ったJSON文字列を解析するのと同じ方法で、対象ユーザーのcivilityを取得することができます。 GetUserメソッドの呼び出し後に受信したJSON文字列は、以下の通りです。
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":"" } |
この方法では、ユーザーが対象ユーザーの電話番号しか知らないときにチャットを開始したい場合、公式のTelegramの動作をコピーすることができます。承認された後、TelegramはOnEventイベントを介して、電話番号の所有者のTelegram内のすべての既知の連絡先をアプリケーションに送信することに注意してください。
Messagerアプリのデモプログラムについて
このブログで紹介したデモプログラムは、こちらからダウンロードできます。
Design. Code. Compile. Deploy.
Start Free Trial Upgrade Today
Free Delphi Community Edition Free C++Builder Community Edition