skip to Main Content

How can I get channel messages from telegram channels with TLSharp?

The following links haven’t helped me:

3

Answers


  1. 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

    Login or Signup to reply.
  2. 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;
                        }
                    }
                }
            }
        }
    
    Login or Signup to reply.
  3. 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;
        }
    }
    

    }

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search