How can I get channel messages from telegram channels with TLSharp?
The following links haven't helped me:
How can I get channel messages from telegram channels with TLSharp?
The following links haven't helped me:
You can use this code
public async Task GatherChannelHistory(string channelName, int offset = 0, int maxId = -1, int limit = 50)
{
_resultMessages.Clear();
await _client.ConnectAsync();
var dialogs = (TLDialogsSlice)await _client.GetUserDialogsAsync();
var chat = dialogs.Chats.ToList()
.OfType<TLChannel>()
.FirstOrDefault(c => c.Title == channelName);
if (chat.AccessHash != null)
{
var tlAbsMessages =
await _client.GetHistoryAsync(
new TLInputPeerChannel {ChannelId= chat.Id, AccessHash = chat.AccessHash.Value}, offset,
maxId, limit);
var tlChannelMessages = (TLChannelMessages) tlAbsMessages;
for (var index = 0; index < tlChannelMessages.Messages.Count-1; index++)
{
var tlAbsMessage = tlChannelMessages.Messages.ToList()[index];
var message = (TLMessage) tlAbsMessage;
//Now you have the message and you can do what you need with it
//the code below is an example of messages classification
if (message.media == null)
{
_resultMessages.Add(new ChannelMessage()
{
Id = message.id,
ChannelId = chat.id,
Content = message.message,
Type = EnChannelMessage.Message,
Views = message.views,
});
}
else
{
switch (message.media.GetType().ToString())
{
case "TeleSharp.TL.TLMessageMediaPhoto":
var tLMessageMediaPhoto = (TLMessageMediaPhoto)message.media;
_resultMessages.Add(new ChannelMessage()
{
Id = message.id,
ChannelId = chat.id,
Content = tLMessageMediaPhoto.caption,
Type = EnChannelMessage.MediaPhoto,
Views = message.views ?? 0,
});
break;
case "TeleSharp.TL.TLMessageMediaDocument":
var tLMessageMediaDocument = (TLMessageMediaDocument)message.media;
_resultMessages.Add(new ChannelMessage()
{
Id = message.id,
ChannelId = chat.id,
Content = tLMessageMediaDocument.caption,
Type = EnChannelMessage.MediaDocument,
Views = message.views ?? 0,
});
break;
case "TeleSharp.TL.TLMessageMediaWebPage":
var tLMessageMediaWebPage = (TLMessageMediaWebPage)message.media;
string url = string.Empty;
if (tLMessageMediaWebPage.webpage.GetType().ToString() != "TeleSharp.TL.TLWebPageEmpty")
{
var webPage = (TLWebPage) tLMessageMediaWebPage.webpage;
url = webPage.url;
}
_resultMessages.Add(new ChannelMessage
{
Id = message.id,
ChannelId = chat.id,
Content = message.message + @" : " + url,
Type = EnChannelMessage.WebPage,
Views = message.views ?? 0,
});
break;
}
}
}
}
}
_resultMessages
? Is it part of a longer code? please advice. –
Cushiony To get channel messages you simply need to be receiving channel updates.
As at TL-schema-52 you could request:
channels.getDialogs#a9d3d249 offset:int limit:int = messages.Dialogs;
however this has been dropped in TL-schema-53.
I'm guessing you can try one of the other channel.*
functions,
I have not tried yet on TL-schema-53
What version of the TL-schema is your TLSharp using?
You could simply implement the relevant functions if they are not yet implemented in your TLSharp version
Not sure if this works 100% without missing any messages, but this is what I have used in one of my projects:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TeleSharp.TL;
using TeleSharp.TL.Channels;
using TeleSharp.TL.Messages;
using TLSharp.Core;
using TLSharp.Core.Utils;
namespace NewsArchive.Telegram
{
/// <summary>
/// Created to be used as a workaround of ref/out since they cannot be used in an async method => GetMessagesInternal
/// </summary>
public class RequestOffset
{
/// <summary>
/// Value of the offset
/// </summary>
public int Id { get; set; }
}
public class TelegramNewsClient
{
#region Properties
private TelegramClient _client;
private int _apiId;
private string _apiHash;
private static readonly int RESULT_MAX = 100;
#endregion
/// <summary>
/// Ctor
/// </summary>
/// <param name="apiId"></param>
/// <param name="apiHash"></param>
public TelegramNewsClient(int apiId, string apiHash)
{
_apiId = apiId;
_apiHash = apiHash;
_client = new TelegramClient(_apiId, _apiHash);
_client.ConnectAsync().Wait();
}
/// <summary>
/// Authenticates the user with the phone number
/// </summary>
/// <param name="phone"></param>
/// <returns></returns>
public async Task Authenticate(string phone)
{
var hash = await _client.SendCodeRequestAsync(phone);
var code = "<code_from_telegram>"; // you can change code in debugger
var user = await _client.MakeAuthAsync(phone, hash, code);
}
/// <summary>
/// Gets all messages from a channel
/// </summary>
/// <param name="channelName"></param>
/// <returns></returns>
public async Task<IEnumerable<TLMessage>> GetChannelMessages(string channelName)
{
var messages = new List<TLMessage>();
var channel = await GetChannel(channelName);
if(channel == null)
throw new Exception($"The channel {channelName} was not found!");
var offset = new RequestOffset(){Id = 1};
var internalMessages = new List<TLMessage>();
internalMessages = await GetMessagesInternal(channel.Id, channel.AccessHash.Value, offset);
messages = messages.Concat(internalMessages)
.OrderBy(m => m.Id)
.ToList();
while (internalMessages.Count > 0)
{
/*When you reach the last message, the API will keep returning the same last message over and over again,
that's why we stop making requests and return the result*/
if ((internalMessages.Count == 1 && internalMessages.First().Id == messages.Max(m => m.Id)))
break;
internalMessages = await GetMessagesInternal(channel.Id, channel.AccessHash.Value, offset);
messages = messages.Concat(internalMessages)
.OrderBy(m =>m.Id)
.ToList();
/*if you make too many requests you will be locked out of the API*/
await Task.Delay(TimeSpan.FromSeconds(1));
}
return messages;
}
private async Task<List<TLMessage>> GetMessagesInternal(int channelId, long accessHash, RequestOffset offset)
{
/*Refer to https://core.telegram.org/api/offsets for more info on how to use the offsets.
Here we basically get the last RESULT_MAX (100 in this case) messages newer than the offset.Id aka offsetId*/
var history = await _client.GetHistoryAsync(new TLInputPeerChannel
{
ChannelId = channelId,
AccessHash = accessHash
}, offset.Id, 0, -RESULT_MAX, RESULT_MAX, 0, 0) as TLChannelMessages;
/*Some messages are service messages with no useful content, and if cast to TLMessage it will throw an exception*/
var messages = history.Messages
.Where(m => m is TLMessage)
.Cast<TLMessage>()
.ToList();
/*Get the ID of the last message so it can be used in the next API call*/
offset.Id = messages.Max(m => m.Id);
return messages;
}
private async Task<TLChannel> GetChannel(string channelName)
{
var offset = new RequestOffset() { Id = RESULT_MAX };
var channels = (await _client.GetUserDialogsAsync(0, offset.Id, null, RESULT_MAX) as TLDialogs)
?.Chats
?.Cast<TLChannel>()
?.ToList();
var channel = channels?.FirstOrDefault(c => c.Username.Equals(channelName, StringComparison.OrdinalIgnoreCase));
offset.Id += RESULT_MAX - 1;
while (channels.Count > 0 && channel == null)
{
channels = (await _client.GetUserDialogsAsync(0, offset.Id, null, RESULT_MAX) as TLDialogs)
?.Chats
?.Cast<TLChannel>()
?.ToList();
channel = channels?.FirstOrDefault(c => c.Username.Equals(channelName, StringComparison.OrdinalIgnoreCase));
offset.Id += RESULT_MAX - 1;
/*if you make too many requests you will be locked out of the API*/
await Task.Delay(TimeSpan.FromSeconds(1));
}
return channel;
}
}
}
© 2022 - 2024 — McMap. All rights reserved.