summaryrefslogtreecommitdiff
path: root/libs/tdlib/td/example/csharp
diff options
context:
space:
mode:
Diffstat (limited to 'libs/tdlib/td/example/csharp')
-rw-r--r--libs/tdlib/td/example/csharp/.gitignore5
-rw-r--r--libs/tdlib/td/example/csharp/README.md32
-rw-r--r--libs/tdlib/td/example/csharp/TdExample.cs270
-rw-r--r--libs/tdlib/td/example/csharp/TdExample.csproj85
4 files changed, 392 insertions, 0 deletions
diff --git a/libs/tdlib/td/example/csharp/.gitignore b/libs/tdlib/td/example/csharp/.gitignore
new file mode 100644
index 0000000000..5266ecccc9
--- /dev/null
+++ b/libs/tdlib/td/example/csharp/.gitignore
@@ -0,0 +1,5 @@
+.vs/
+bin/
+obj/
+project.lock.json
+TdExample.csproj.user
diff --git a/libs/tdlib/td/example/csharp/README.md b/libs/tdlib/td/example/csharp/README.md
new file mode 100644
index 0000000000..2faa15e12e
--- /dev/null
+++ b/libs/tdlib/td/example/csharp/README.md
@@ -0,0 +1,32 @@
+# 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
+```
+* (Optional. For XML documentation generation.) Download [PHP](https://windows.php.net/download#php-7.2). Add the path to php.exe to the PATH environment variable.
+* 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.
+
+Also see TdExample.csproj for example of including TDLib in C# project with all native shared library dependencies.
diff --git a/libs/tdlib/td/example/csharp/TdExample.cs b/libs/tdlib/td/example/csharp/TdExample.cs
new file mode 100644
index 0000000000..be98e1a758
--- /dev/null
+++ b/libs/tdlib/td/example/csharp/TdExample.cs
@@ -0,0 +1,270 @@
+//
+// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 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;
+
+namespace TdExample
+{
+ /// <summary>
+ /// Example class for TDLib usage from C#.
+ /// </summary>
+ 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 volatile string _currentPrompt = null;
+
+ 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)
+ {
+ if (_currentPrompt != null)
+ {
+ Console.WriteLine();
+ }
+ Console.WriteLine(str);
+ if (_currentPrompt != null)
+ {
+ Console.Write(_currentPrompt);
+ }
+ }
+
+ private static string ReadLine(string str)
+ {
+ Console.Write(str);
+ _currentPrompt = str;
+ var result = Console.ReadLine();
+ _currentPrompt = null;
+ return result;
+ }
+
+ 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
+ {
+ // result is already received through UpdateAuthorizationState, nothing to do
+ }
+ }
+ }
+ }
+}
diff --git a/libs/tdlib/td/example/csharp/TdExample.csproj b/libs/tdlib/td/example/csharp/TdExample.csproj
new file mode 100644
index 0000000000..ea2ad56532
--- /dev/null
+++ b/libs/tdlib/td/example/csharp/TdExample.csproj
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+ <PropertyGroup>
+ <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+ <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
+ <ProjectGuid>{3F9A93EA-DC26-4F8B-ACE0-131B33B00CA7}</ProjectGuid>
+ <OutputType>Exe</OutputType>
+ <NoStandardLibraries>false</NoStandardLibraries>
+ <AssemblyName>ConsoleApplication</AssemblyName>
+ <TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
+ <TargetFrameworkProfile>Client</TargetFrameworkProfile>
+ <FileAlignment>512</FileAlignment>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+ <DebugSymbols>true</DebugSymbols>
+ <DebugType>full</DebugType>
+ <Optimize>false</Optimize>
+ <OutputPath>bin\Debug\</OutputPath>
+ <DefineConstants>DEBUG;TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <PlatformTarget>x86</PlatformTarget>
+ </PropertyGroup>
+ <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+ <DebugType>pdbonly</DebugType>
+ <Optimize>true</Optimize>
+ <OutputPath>bin\Release\</OutputPath>
+ <DefineConstants>TRACE</DefineConstants>
+ <ErrorReport>prompt</ErrorReport>
+ <WarningLevel>4</WarningLevel>
+ <PlatformTarget>x86</PlatformTarget>
+ </PropertyGroup>
+ <PropertyGroup>
+ <RootNamespace>TdExample</RootNamespace>
+ </PropertyGroup>
+ <ItemGroup>
+ <Reference Include="Microsoft.CSharp" />
+ <Reference Include="System" />
+ <Reference Include="System.Core" />
+ <Reference Include="System.Data" />
+ <Reference Include="System.Data.DataSetExtensions" />
+ <Reference Include="System.Xml" />
+ <Reference Include="System.Xml.Linq" />
+ <Reference Include="Telegram.Td, Version=0.0.0.0, Culture=neutral, processorArchitecture=AMD64">
+ <SpecificVersion>False</SpecificVersion>
+ <HintPath Condition=" '$(Configuration)' == 'Debug' ">build\Debug\Telegram.Td.dll</HintPath>
+ <HintPath Condition=" '$(Configuration)' == 'Release' ">build\Release\Telegram.Td.dll</HintPath>
+ </Reference>
+ </ItemGroup>
+ <ItemGroup>
+ <Compile Include="TdExample.cs" />
+ </ItemGroup>
+ <ItemGroup Condition=" '$(Configuration)' == 'Debug' ">
+ <Content Include="build\Debug\LIBEAY32.dll">
+ <Link>LIBEAY32.dll</Link>
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="build\Debug\SSLEAY32.dll">
+ <Link>SSLEAY32.dll</Link>
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="build\Debug\zlibd1.dll">
+ <Link>zlibd1.dll</Link>
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ </ItemGroup>
+ <ItemGroup Condition=" '$(Configuration)' == 'Release' ">
+ <Content Include="build\Release\LIBEAY32.dll">
+ <Link>LIBEAY32.dll</Link>
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="build\Release\SSLEAY32.dll">
+ <Link>SSLEAY32.dll</Link>
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ <Content Include="build\Release\zlib1.dll">
+ <Link>zlib1.dll</Link>
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
+ </ItemGroup>
+ <Import Project="$(MSBuildToolsPath)\Microsoft.CSHARP.Targets" />
+ <ProjectExtensions>
+ <VisualStudio AllowExistingFolder="true" />
+ </ProjectExtensions>
+</Project> \ No newline at end of file