2018-03-12 00:38:07 +01:00
|
|
|
//
|
2020-01-01 02:23:48 +01:00
|
|
|
// Copyright Aliaksei Levin (levlam@telegram.org), Arseny Smirnov (arseny30@gmail.com) 2014-2020
|
2018-03-12 00:38:07 +01:00
|
|
|
//
|
|
|
|
// 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
|
|
|
|
{
|
2018-03-16 22:26:27 +01:00
|
|
|
/// <summary>
|
|
|
|
/// Example class for TDLib usage from C#.
|
|
|
|
/// </summary>
|
2018-03-12 00:38:07 +01:00
|
|
|
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;
|
2020-10-11 10:48:42 +02:00
|
|
|
private static volatile bool _needQuit = false;
|
|
|
|
private static volatile bool _canQuit = false;
|
2018-03-12 00:38:07 +01:00
|
|
|
|
|
|
|
private static volatile AutoResetEvent _gotAuthorization = new AutoResetEvent(false);
|
|
|
|
|
|
|
|
private static readonly string _newLine = Environment.NewLine;
|
2018-07-27 09:03:25 +02:00
|
|
|
private static readonly string _commandsLine = "Enter command (gc <chatId> - GetChat, me - GetMe, sm <chatId> <message> - SendMessage, lo - LogOut, r - Restart, q - Quit): ";
|
2018-03-20 16:54:50 +01:00
|
|
|
private static volatile string _currentPrompt = null;
|
2018-03-12 00:38:07 +01:00
|
|
|
|
|
|
|
private static Td.Client CreateTdClient()
|
|
|
|
{
|
2020-10-05 19:13:15 +02:00
|
|
|
Td.Client result = Td.Client.Create(new UpdateHandler());
|
2018-03-12 00:38:07 +01:00
|
|
|
new Thread(() =>
|
|
|
|
{
|
|
|
|
Thread.CurrentThread.IsBackground = true;
|
|
|
|
result.Run();
|
|
|
|
}).Start();
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
private static void Print(string str)
|
|
|
|
{
|
2018-03-20 16:54:50 +01:00
|
|
|
if (_currentPrompt != null)
|
|
|
|
{
|
|
|
|
Console.WriteLine();
|
|
|
|
}
|
2018-03-12 00:38:07 +01:00
|
|
|
Console.WriteLine(str);
|
2018-03-20 16:54:50 +01:00
|
|
|
if (_currentPrompt != null)
|
2018-03-12 00:38:07 +01:00
|
|
|
{
|
2018-03-20 16:54:50 +01:00
|
|
|
Console.Write(_currentPrompt);
|
2018-03-12 00:38:07 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private static string ReadLine(string str)
|
|
|
|
{
|
|
|
|
Console.Write(str);
|
2018-03-20 16:54:50 +01:00
|
|
|
_currentPrompt = str;
|
|
|
|
var result = Console.ReadLine();
|
|
|
|
_currentPrompt = null;
|
|
|
|
return result;
|
2018-03-12 00:38:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
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.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: ");
|
2019-05-03 04:44:59 +02:00
|
|
|
_client.Send(new TdApi.SetAuthenticationPhoneNumber(phoneNumber, null), new AuthorizationRequestHandler());
|
2018-03-12 00:38:07 +01:00
|
|
|
}
|
2019-12-18 17:23:14 +01:00
|
|
|
else if (_authorizationState is TdApi.AuthorizationStateWaitOtherDeviceConfirmation state)
|
|
|
|
{
|
|
|
|
Console.WriteLine("Please confirm this login link on another device: " + state.Link);
|
|
|
|
}
|
2018-03-12 00:38:07 +01:00
|
|
|
else if (_authorizationState is TdApi.AuthorizationStateWaitCode)
|
|
|
|
{
|
|
|
|
string code = ReadLine("Please enter authentication code: ");
|
2019-07-16 21:08:34 +02:00
|
|
|
_client.Send(new TdApi.CheckAuthenticationCode(code), new AuthorizationRequestHandler());
|
|
|
|
}
|
|
|
|
else if (_authorizationState is TdApi.AuthorizationStateWaitRegistration)
|
|
|
|
{
|
|
|
|
string firstName = ReadLine("Please enter your first name: ");
|
|
|
|
string lastName = ReadLine("Please enter your last name: ");
|
|
|
|
_client.Send(new TdApi.RegisterUser(firstName, lastName), new AuthorizationRequestHandler());
|
2018-03-12 00:38:07 +01:00
|
|
|
}
|
|
|
|
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");
|
2018-07-27 09:03:25 +02:00
|
|
|
_client.Dispose(); // _client is closed and native resources can be disposed now
|
2020-10-11 10:48:42 +02:00
|
|
|
if (!_needQuit)
|
2018-03-12 00:38:07 +01:00
|
|
|
{
|
|
|
|
_client = CreateTdClient(); // recreate _client after previous has closed
|
2020-10-11 10:48:42 +02:00
|
|
|
} else {
|
|
|
|
_canQuit = true;
|
2018-03-12 00:38:07 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
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;
|
2018-07-27 09:03:25 +02:00
|
|
|
case "r":
|
|
|
|
_haveAuthorization = false;
|
|
|
|
_client.Send(new TdApi.Close(), _defaultHandler);
|
|
|
|
break;
|
2018-03-12 00:38:07 +01:00
|
|
|
case "q":
|
2020-10-11 10:48:42 +02:00
|
|
|
_needQuit = true;
|
2018-03-12 00:38:07 +01:00
|
|
|
_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);
|
2020-09-23 00:52:16 +02:00
|
|
|
_client.Send(new TdApi.SendMessage(chatId, 0, 0, null, replyMarkup, content), _defaultHandler);
|
2018-03-12 00:38:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
static void Main()
|
|
|
|
{
|
|
|
|
// disable TDLib log
|
2019-02-24 17:17:36 +01:00
|
|
|
Td.Client.Execute(new TdApi.SetLogVerbosityLevel(0));
|
2020-10-03 21:05:55 +02:00
|
|
|
if (Td.Client.Execute(new TdApi.SetLogStream(new TdApi.LogStreamFile("tdlib.log", 1 << 27, false))) is TdApi.Error)
|
2018-03-12 00:38:07 +01:00
|
|
|
{
|
|
|
|
throw new System.IO.IOException("Write access to the current directory is required");
|
|
|
|
}
|
|
|
|
|
|
|
|
// create Td.Client
|
|
|
|
_client = CreateTdClient();
|
|
|
|
|
|
|
|
// test Client.Execute
|
2018-10-24 19:23:47 +02:00
|
|
|
_defaultHandler.OnResult(Td.Client.Execute(new TdApi.GetTextEntities("@telegram /test_command https://telegram.org telegram.me @gif @test")));
|
2018-03-12 00:38:07 +01:00
|
|
|
|
|
|
|
// main loop
|
2020-10-11 10:48:42 +02:00
|
|
|
while (!_needQuit)
|
2018-03-12 00:38:07 +01:00
|
|
|
{
|
|
|
|
// await authorization
|
|
|
|
_gotAuthorization.Reset();
|
|
|
|
_gotAuthorization.WaitOne();
|
|
|
|
|
2019-08-22 17:24:02 +02:00
|
|
|
_client.Send(new TdApi.GetChats(null, Int64.MaxValue, 0, 100), _defaultHandler); // preload main chat list
|
2018-03-12 00:38:07 +01:00
|
|
|
while (_haveAuthorization)
|
|
|
|
{
|
|
|
|
GetCommand();
|
|
|
|
}
|
|
|
|
}
|
2020-10-11 10:48:42 +02:00
|
|
|
while (!_canQuit) {
|
|
|
|
Thread.Sleep(1);
|
|
|
|
}
|
2018-03-12 00:38:07 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
private class DefaultHandler : Td.ClientResultHandler
|
|
|
|
{
|
|
|
|
void Td.ClientResultHandler.OnResult(TdApi.BaseObject @object)
|
|
|
|
{
|
|
|
|
Print(@object.ToString());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-10-05 19:13:15 +02:00
|
|
|
private class UpdateHandler : Td.ClientResultHandler
|
2018-03-12 00:38:07 +01:00
|
|
|
{
|
|
|
|
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
|
|
|
|
{
|
2018-03-16 22:26:27 +01:00
|
|
|
// result is already received through UpdateAuthorizationState, nothing to do
|
2018-03-12 00:38:07 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|