Мне нужно захватить все сообщения в чате. Я использую C# и библиотеку TLSharp.
Я авторизовался, получил токен и т.д. успешно.
Но когда я пытаюсь получить сообщения в цикле, я получаю бесконечный цикл.
Таким образом, текст с результатами никогда не появляется в текстовом поле. Я хотел бы знать, что я делаю неправильно и как это исправить. Спасибо.
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");
}
Не могли бы вы попробовать обновить текстовое поле перед 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;
}