Telegram API (НЕ Telegram Bot API!) - как получить все сообщения во всем чате/канале?

  1. Мне нужно захватить все сообщения в чате. Я использую C# и библиотеку TLSharp.

  2. Я авторизовался, получил токен и т.д. успешно.

  3. Но когда я пытаюсь получить сообщения в цикле, я получаю бесконечный цикл.

  4. Таким образом, текст с результатами никогда не появляется в текстовом поле. Я хотел бы знать, что я делаю неправильно и как это исправить. Спасибо.

    using TeleSharp.TL;
    using TeleSharp.TL.Messages;
    using TLSharp.Core;
    //using other standard...
    
    //code for authorization etc. is skipped
    
     int VKFID = 1175259547; //ID of the chat
     int offset = 0;
     int n = 1;
     StringBuilder sb = new StringBuilder();
     TelegramClient client = new TelegramClient(<key>, <hash>);
     TLUser user;
    
     private DateTime ConvertFromUnixTimestamp(double timestamp)
     {
         DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0);
         return origin.AddSeconds(timestamp);
     }
    
     private async void button3_Click(object sender, EventArgs e)
     {
         sb.Append("#\tDate\tTime\tMID\tTUID\tText" + Environment.NewLine);
         TLDialogsSlice dialogs = (TLDialogsSlice)await client.GetUserDialogsAsync();
         TLChannel chat = dialogs.Chats.Where(c => c.GetType() == typeof(TLChannel)).Cast<TLChannel>().FirstOrDefault(c => c.Id == VKFID);
         TLInputPeerChannel inputPeer = new TLInputPeerChannel() { ChannelId = chat.Id, AccessHash = (long)chat.AccessHash };
         while (true)
         {
             try
             {
                 TLChannelMessages res = await client.SendRequestAsync<TLChannelMessages>
                 (new TLRequestGetHistory() { Peer = inputPeer, Limit = 1000, AddOffset = offset, OffsetId = 0 });
                 var msgs = res.Messages;
                 if (res.Count > offset)
                 {
                     offset += msgs.Count;
                     foreach (TLAbsMessage msg in msgs)
                     {
                         if (msg is TLMessage)
                         {
                             TLMessage message = msg as TLMessage;
                             sb.Append(n.ToString() + "\t" +
                                 ConvertFromUnixTimestamp(message.Date).ToLocalTime().ToString("dd'.'MM'.'yyyy") + "\t" +
                                 ConvertFromUnixTimestamp(message.Date).ToLocalTime().ToString("HH':'mm':'ss") + "\t" +
                                 message.Id + "\t" + message.FromId + "\t" + message.Message + Environment.NewLine);
                         }
                         if (msg is TLMessageService)
                             continue;
                         n++;
                     }
                     Thread.Sleep(22000); //to avoid TelegramFloodException
                 }
                 else
                     break;
             }
             catch (Exception ex)
             {
                 MessageBox.Show(ex.Message);
                 break;
             }
             finally
             {
                 await Task.Delay(22000); //to avoid TelegramFloodException
             }
         }
         textBox2.Text = sb.ToString();
         MessageBox.Show("Done");
     }
    
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
0
1 929
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Не могли бы вы попробовать обновить текстовое поле перед Thead.Sleep(22000)?

    textBox2.Text += sb.ToString();
    Application.DoEvents();
    Thread.Sleep(22000);

Другой способ сделать это — использовать BackgroundWorker так же, как он используется для управления ProgressBar.

Ответ принят как подходящий

Теперь есть библиотека WTelegramClient, использующая новейший протокол Telegram Client API (подключение от имени пользователя, а не бота).

Библиотека очень полная, но и очень простая в использовании. Следуйте README на GitHub для простого ознакомления.

Подключиться, найти свой чат и получить все сообщения можно следующим образом:

using TL;
using System.Linq;

const int TargetChatId = 1175259547;

using var client = new WTelegram.Client(); // or Client(Environment.GetEnvironmentVariable)
await client.LoginUserIfNeeded();
var chats = await client.Messages_GetAllChats(null);
InputPeer peer = chats.chats.First(chat => chat.ID == TargetChatId);
for (int offset = 0; ;)
{
    var messagesBase = await client.Messages_GetHistory(peer, 0, default, offset, 1000, 0, 0, 0);
    if (messagesBase is not Messages_ChannelMessages channelMessages) break;
    foreach (var msgBase in channelMessages.messages)
        if (msgBase is Message msg)
        {
            // process the message
        }
    offset += channelMessages.messages.Length;
    if (offset >= channelMessages.count) break;
}

Другие вопросы по теме