如何使用TLSharp从电报频道获取频道消息?

时间:2016-05-12 14:26:43

标签: telegram

如何使用TLSharp从电报频道获取频道消息?

以下链接无法帮助我:

3 个答案:

答案 0 :(得分:2)

您可以使用此代码

        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;
                    }
                }
            }
        }
    }

答案 1 :(得分:1)

要获取频道消息,您只需接收频道更新即可。

与TL-schema-52一样,您可以请求:

channels.getDialogs#a9d3d249 offset:int limit:int = messages.Dialogs; 

然而,这已经在TL-schema-53中被删除。

我猜你可以试试其他channel.*函数之一

我还没有尝试过TL-schema-53

您的TLSharp使用的是什么版本的TL架构?

如果尚未在TLSharp版本中实现相关功能,则可以简单地实现相关功能

答案 2 :(得分:1)

不确定这是否 100% 有效而不会丢失任何消息,但这是我在我的一个项目中使用的:

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;
    }
}

}