【问题标题】:Telegram API (NOT Telegram Bot API!) - how to get all messages in entire chat/channel?Telegram API(不是 Telegram Bot API!) - 如何获取整个聊天/频道中的所有消息?
【发布时间】:2021-04-03 16:52:36
【问题描述】:
  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");
     }
    

【问题讨论】:

    标签: c# telegram telegram-api


    【解决方案1】:

    您可以尝试在 Thead.Sleep(22000) 之前刷新您的文本框吗?

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

    执行此操作的其他方式可能是使用 BackgroundWorker,其方式与用于管理 ProgressBar 的方式相同。

    【讨论】:

      【解决方案2】:

      现在有 WTelegramClient 库,使用最新的 Telegram Client API 协议(以用户身份连接,而不是机器人)。

      该库非常完整,但使用起来也非常简单。关注README on 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;
      }
      

      【讨论】:

        猜你喜欢
        • 2018-01-28
        • 2016-04-04
        • 2017-02-25
        • 2021-10-23
        • 1970-01-01
        • 1970-01-01
        • 2016-02-23
        • 2021-04-01
        • 2022-01-24
        相关资源
        最近更新 更多