-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
GitOrigin-RevId: ab6991abd7c7dccbdd3821c41c85eb3e96c0e8a8
- Loading branch information
Showing
9 changed files
with
420 additions
and
7 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
.vs/ | ||
bin/ | ||
obj/ | ||
project.lock.json | ||
TdExample.csproj.user |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# TDLib C# example | ||
|
||
This is an example of building TDLib with `C++/CLI` support and an example of TDLib usage from C#. | ||
|
||
## Building TDLib | ||
|
||
* Download and install Microsoft Visual Studio 2015 or later. | ||
* Download and install [CMake](https://cmake.org/download/). | ||
* Install [vcpkg](https://github.com/Microsoft/vcpkg#quick-start) or update it to the latest version using `vcpkg update` and following received instructions. | ||
* Install `zlib` and `openssl` for using `vcpkg`: | ||
``` | ||
C:\src\vcpkg> .\vcpkg.exe install openssl:x64-windows openssl:x86-windows zlib:x64-windows zlib:x86-windows | ||
``` | ||
* Download and install [gperf](https://sourceforge.net/projects/gnuwin32/files/gperf/3.0.1/). Add the path to gperf.exe to the PATH environment variable. | ||
* Build `TDLib` with CMake enabling .NET support and specifying correct path to `vcpkg` toolchain file: | ||
``` | ||
cd <path to TDLib sources>/example/csharp | ||
mkdir build | ||
cd build | ||
cmake -DTD_ENABLE_DOTNET=ON -DCMAKE_TOOLCHAIN_FILE=C:\src\vcpkg\scripts\buildsystems\vcpkg.cmake ../../.. | ||
cmake --build . --config Release | ||
cmake --build . --config Debug | ||
``` | ||
|
||
## Example of usage | ||
|
||
After `TDLib` is built you can open and run TdExample project. | ||
It contains a simple console C# application with implementation of authorization and message sending. | ||
Just open it with Visual Studio 2015 or 2017 and run. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,264 @@ | ||
// | ||
// Copyright Aliaksei Levin ([email protected]), Arseny Smirnov ([email protected]) 2014-2018 | ||
// | ||
// Distributed under the Boost Software License, Version 1.0. (See accompanying | ||
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) | ||
// | ||
|
||
using Td = Telegram.Td; | ||
using TdApi = Telegram.Td.Api; | ||
|
||
using System; | ||
using System.Threading; | ||
|
||
/** | ||
* Example class for TDLib usage from C#. | ||
*/ | ||
namespace TdExample | ||
{ | ||
class Example | ||
{ | ||
private static Td.Client _client = null; | ||
private readonly static Td.ClientResultHandler _defaultHandler = new DefaultHandler(); | ||
|
||
private static TdApi.AuthorizationState _authorizationState = null; | ||
private static volatile bool _haveAuthorization = false; | ||
private static volatile bool _quiting = false; | ||
|
||
private static volatile AutoResetEvent _gotAuthorization = new AutoResetEvent(false); | ||
|
||
private static readonly string _newLine = Environment.NewLine; | ||
private static readonly string _commandsLine = "Enter command (gc <chatId> - GetChat, me - GetMe, sm <chatId> <message> - SendMessage, lo - LogOut, q - Quit): "; | ||
|
||
private static Td.Client CreateTdClient() | ||
{ | ||
Td.Client result = Td.Client.Create(new UpdatesHandler()); | ||
new Thread(() => | ||
{ | ||
Thread.CurrentThread.IsBackground = true; | ||
result.Run(); | ||
}).Start(); | ||
return result; | ||
} | ||
|
||
private static void Print(string str) | ||
{ | ||
Console.WriteLine(); | ||
Console.WriteLine(str); | ||
if (_haveAuthorization) | ||
{ | ||
Console.Write(_commandsLine); | ||
} | ||
} | ||
|
||
private static string ReadLine(string str) | ||
{ | ||
Console.WriteLine(); | ||
Console.Write(str); | ||
return Console.ReadLine(); | ||
} | ||
|
||
private static void OnAuthorizationStateUpdated(TdApi.AuthorizationState authorizationState) | ||
{ | ||
if (authorizationState != null) | ||
{ | ||
_authorizationState = authorizationState; | ||
} | ||
if (_authorizationState is TdApi.AuthorizationStateWaitTdlibParameters) | ||
{ | ||
TdApi.TdlibParameters parameters = new TdApi.TdlibParameters(); | ||
parameters.DatabaseDirectory = "tdlib"; | ||
parameters.UseMessageDatabase = true; | ||
parameters.UseSecretChats = true; | ||
parameters.ApiId = 94575; | ||
parameters.ApiHash = "a3406de8d171bb422bb6ddf3bbd800e2"; | ||
parameters.SystemLanguageCode = "en"; | ||
parameters.DeviceModel = "Desktop"; | ||
parameters.SystemVersion = "Unknown"; | ||
parameters.ApplicationVersion = "1.0"; | ||
parameters.EnableStorageOptimizer = true; | ||
|
||
_client.Send(new TdApi.SetTdlibParameters(parameters), new AuthorizationRequestHandler()); | ||
} | ||
else if (_authorizationState is TdApi.AuthorizationStateWaitEncryptionKey) | ||
{ | ||
_client.Send(new TdApi.CheckDatabaseEncryptionKey(), new AuthorizationRequestHandler()); | ||
} | ||
else if (_authorizationState is TdApi.AuthorizationStateWaitPhoneNumber) | ||
{ | ||
string phoneNumber = ReadLine("Please enter phone number: "); | ||
_client.Send(new TdApi.SetAuthenticationPhoneNumber(phoneNumber, false, false), new AuthorizationRequestHandler()); | ||
} | ||
else if (_authorizationState is TdApi.AuthorizationStateWaitCode) | ||
{ | ||
string code = ReadLine("Please enter authentication code: "); | ||
_client.Send(new TdApi.CheckAuthenticationCode(code, "", ""), new AuthorizationRequestHandler()); | ||
} | ||
else if (_authorizationState is TdApi.AuthorizationStateWaitPassword) | ||
{ | ||
string password = ReadLine("Please enter password: "); | ||
_client.Send(new TdApi.CheckAuthenticationPassword(password), new AuthorizationRequestHandler()); | ||
} | ||
else if (_authorizationState is TdApi.AuthorizationStateReady) | ||
{ | ||
_haveAuthorization = true; | ||
_gotAuthorization.Set(); | ||
} | ||
else if (_authorizationState is TdApi.AuthorizationStateLoggingOut) | ||
{ | ||
_haveAuthorization = false; | ||
Print("Logging out"); | ||
} | ||
else if (_authorizationState is TdApi.AuthorizationStateClosing) | ||
{ | ||
_haveAuthorization = false; | ||
Print("Closing"); | ||
} | ||
else if (_authorizationState is TdApi.AuthorizationStateClosed) | ||
{ | ||
Print("Closed"); | ||
if (!_quiting) | ||
{ | ||
_client = CreateTdClient(); // recreate _client after previous has closed | ||
} | ||
} | ||
else | ||
{ | ||
Print("Unsupported authorization state:" + _newLine + _authorizationState); | ||
} | ||
} | ||
|
||
private static long GetChatId(string arg) | ||
{ | ||
long chatId = 0; | ||
try | ||
{ | ||
chatId = Convert.ToInt64(arg); | ||
} | ||
catch (FormatException) | ||
{ | ||
} | ||
catch (OverflowException) | ||
{ | ||
} | ||
return chatId; | ||
} | ||
|
||
private static void GetCommand() | ||
{ | ||
string command = ReadLine(_commandsLine); | ||
string[] commands = command.Split(new char[] { ' ' }, 2); | ||
try | ||
{ | ||
switch (commands[0]) | ||
{ | ||
case "gc": | ||
_client.Send(new TdApi.GetChat(GetChatId(commands[1])), _defaultHandler); | ||
break; | ||
case "me": | ||
_client.Send(new TdApi.GetMe(), _defaultHandler); | ||
break; | ||
case "sm": | ||
string[] args = commands[1].Split(new char[] { ' ' }, 2); | ||
sendMessage(GetChatId(args[0]), args[1]); | ||
break; | ||
case "lo": | ||
_haveAuthorization = false; | ||
_client.Send(new TdApi.LogOut(), _defaultHandler); | ||
break; | ||
case "q": | ||
_quiting = true; | ||
_haveAuthorization = false; | ||
_client.Send(new TdApi.Close(), _defaultHandler); | ||
break; | ||
default: | ||
Print("Unsupported command: " + command); | ||
break; | ||
} | ||
} | ||
catch (IndexOutOfRangeException) | ||
{ | ||
Print("Not enough arguments"); | ||
} | ||
} | ||
|
||
private static void sendMessage(long chatId, string message) | ||
{ | ||
// initialize reply markup just for testing | ||
TdApi.InlineKeyboardButton[] row = { new TdApi.InlineKeyboardButton("https://telegram.org?1", new TdApi.InlineKeyboardButtonTypeUrl()), new TdApi.InlineKeyboardButton("https://telegram.org?2", new TdApi.InlineKeyboardButtonTypeUrl()), new TdApi.InlineKeyboardButton("https://telegram.org?3", new TdApi.InlineKeyboardButtonTypeUrl()) }; | ||
TdApi.ReplyMarkup replyMarkup = new TdApi.ReplyMarkupInlineKeyboard(new TdApi.InlineKeyboardButton[][] { row, row, row }); | ||
|
||
TdApi.InputMessageContent content = new TdApi.InputMessageText(new TdApi.FormattedText(message, null), false, true); | ||
_client.Send(new TdApi.SendMessage(chatId, 0, false, false, replyMarkup, content), _defaultHandler); | ||
} | ||
|
||
static void Main() | ||
{ | ||
// disable TDLib log | ||
Td.Log.SetVerbosityLevel(0); | ||
if (!Td.Log.SetFilePath("tdlib.log")) | ||
{ | ||
throw new System.IO.IOException("Write access to the current directory is required"); | ||
} | ||
|
||
// create Td.Client | ||
_client = CreateTdClient(); | ||
|
||
// test Client.Execute | ||
_defaultHandler.OnResult(_client.Execute(new TdApi.GetTextEntities("@telegram /test_command https://telegram.org telegram.me @gif @test"))); | ||
|
||
// main loop | ||
while (!_quiting) | ||
{ | ||
// await authorization | ||
_gotAuthorization.Reset(); | ||
_gotAuthorization.WaitOne(); | ||
|
||
_client.Send(new TdApi.GetChats(Int64.MaxValue, 0, 100), _defaultHandler); // preload chat list | ||
while (_haveAuthorization) | ||
{ | ||
GetCommand(); | ||
} | ||
} | ||
} | ||
|
||
private class DefaultHandler : Td.ClientResultHandler | ||
{ | ||
void Td.ClientResultHandler.OnResult(TdApi.BaseObject @object) | ||
{ | ||
Print(@object.ToString()); | ||
} | ||
} | ||
|
||
private class UpdatesHandler : Td.ClientResultHandler | ||
{ | ||
void Td.ClientResultHandler.OnResult(TdApi.BaseObject @object) | ||
{ | ||
if (@object is TdApi.UpdateAuthorizationState) | ||
{ | ||
OnAuthorizationStateUpdated((@object as TdApi.UpdateAuthorizationState).AuthorizationState); | ||
} | ||
else | ||
{ | ||
// Print("Unsupported update: " + @object); | ||
} | ||
} | ||
} | ||
|
||
private class AuthorizationRequestHandler : Td.ClientResultHandler | ||
{ | ||
void Td.ClientResultHandler.OnResult(TdApi.BaseObject @object) | ||
{ | ||
if (@object is TdApi.Error) | ||
{ | ||
Print("Receive an error:" + _newLine + @object); | ||
OnAuthorizationStateUpdated(null); // repeat last action | ||
} | ||
else | ||
{ | ||
// ok result is already received through UpdateAuthorizationState, nothing to do | ||
} | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.