Протухает авторизация телеграм

155
22 июля 2019, 23:20

Попробовал отправлять сообщения в телеграм при помощи TLSharp (хабр, гитхаб).

Ну, вариант рабочий. Однако есть следующая проблема: после коннекта к серверу нужно пройти аутентификацию, используя hash и code - и этот code приходит на телефон.

Этот code достаточно быстро протухает (в api точно не указано (раз, два), но где-то меньше часа кажется прошло) и если я даже сохраню этот код, то со временем всё равно получу исключение:

InvalidOperationException: PHONE_CODE_EXPIRED

А это значит, нужно снова лезть (руками!) в телефон и в отладчике менять на лету значение переменной. Да-да, автор так и советует:

var hash = await client.SendCodeRequestAsync("<user_number>");
var code = "<code_from_telegram>"; // you can change code in debugger
var user = await client.MakeAuthAsync("<user_number>", hash, code);

Только вот это совсем не production ready. :(

Кто может порекомендовать хороший способ автоматизировать этот процесс?

На ум приходит только вариант получения какого-то долгоиграющего (судя по api самого телеграмма - этот code можно получить либо в СМС на телефон, либо в приложение телеграмма) кода (на месяц хотя бы), но я не нашёл в api варианта получить такой токен (да и сомневаюсь, что по соображениям безопасности они будут выдаваться).

Answer 1

Моё предположение в комментариях оказалось верным. Проходить авторизацию нужно только при первом подключении. В дальнейшем TLSharp сохраняет все нужные данные в файл session.dat и использует его при последующих подключениях. Повторная авторизация может потребоваться в двух случаях:

  • Файл session.dat был удалён/повреждён
  • Пользователь закрыл сессию (причем, мог сделать это воспользовавшись другим клиентом)

Ниже приведу работающий пример кода:

using System;
using System.Threading.Tasks;
using TeleSharp.TL;
using TLSharp.Core;
namespace ConsoleApp1
{
    internal static class Program
    {
        private static async Task Main()
        {
            // Следующие два значения нужно получить на https://my.telegram.org/apps
            var apiId = 123456;
            var apiHash = "foo";
            // Номер телефона пользователя
            var phoneNum = "+75551234567";
            var client = new TelegramClient(apiId, apiHash);
            await client.ConnectAsync();
            var isAuth = client.IsUserAuthorized();
            Console.WriteLine($"Файл авторизации существует: {isAuth}");
            if (!isAuth) // Если не найден файл session.dat, то пытаемся авторизоваться
            {
                TLUser user;
                try
                {
                    var hash = await client.SendCodeRequestAsync(phoneNum);
                    Console.WriteLine("Введите код из SMS:");
                    var code = Console.ReadLine();
                    try
                    {
                        user = await client.MakeAuthAsync(phoneNum, hash, code);
                    }
                    catch (CloudPasswordNeededException)
                    {
                        // На данном аккаунте включена двухфакторная авторизация
                        var passwordSettings = await client.GetPasswordSetting();
                        Console.WriteLine("Введите пароль:");
                        var passwordStr = Console.ReadLine();
                        user = await client.MakeAuthWithPasswordAsync(passwordSettings, passwordStr);
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                    return;
                }
                Console.WriteLine($"Пользователь '{user?.FirstName}' авторизован");
                isAuth = client.IsUserAuthorized();
                Console.WriteLine($"Файл авторизации существует: {isAuth}");
            }
            try
            {
                // В качестве демонстрации работы узнаем количество контактов у пользователя
                var contacts = await client.GetContactsAsync();
                Console.WriteLine($"У вас {contacts.Users.Count} контактов");
            }
            catch (InvalidOperationException ex) when (ex.Message == "AUTH_KEY_UNREGISTERED")
            {
                // Файл session.dat существует, но для сервера эта сессия уже мертва
                Console.WriteLine("Пользователь воспользовался другим устройством чтобы закрыть текущую сессию.");
                Console.WriteLine("Удалите файл session.dat и повторите попытку.");
            }
        }
    }
}
READ ALSO
Передача данных по udp на клиент под NAT (C# winforms)

Передача данных по udp на клиент под NAT (C# winforms)

Подскажите пожалуйста, есть ли возмлжность передать данные на клиент, который находится под NAT

145
Что значит в generic where T : unmanaged?

Что значит в generic where T : unmanaged?

Сидел пробовал написать Generic метод для получения значения типа из указателя, и вот случайно написал where T : unmanaged и этот код был успешно откомпилирован!

174
iOS и Windows читают .xml файлы по-разному C#

iOS и Windows читают .xml файлы по-разному C#

Есть проект XamarinForms, внутри есть три приложения (iOS, Android, UWP), один общий проект с общим кодом Portable Class Library

195
Поиск в txt файле

Поиск в txt файле

Имеетсяtxt файл, в котором записан текст

152