I'm using WTelegramClient C# API under VB.NET in .NET 4.8. I would like to implement an helper function that will retrieve the forum topics of the specified channel (group).
I think this could be done via the Channels_GetForumTopics
function that takes a InputChannelBase
object as argument, and my biggest problem I think it is not understanding how to obtain the required access hash value of a specific ChatBase
object to create an instance of the InputChannel
type (which inherits from InputChannelBase
).
...Or how to directly convert a ChatBase
object to InputChannel
to pass it to the Channels_GetForumTopics
function.
The FAQ of WTelegramClient API does not help me to understand it.
This what I've achieved for now:
Private Async Sub Test()
Dim clientConfig As New TelegramClientConfig With {
.ApiId = "###",
.ApiHash = "###",
.FirstName = "###",
.LastName = "###",
.Password = "###",
.PhoneNumber = "###",
.VerificationCode = "###"
}
Dim client As WTelegram.Client = WTelegramHelper.CreateClient(clientConfig)
Dim myUser As TL.User = Await client.LoginUserIfNeeded()
Dim myUserId As Long = WTelegramHelper.GetIdPropertyValue(myUser)
Console.WriteLine($"We are logged-in as user: {myUser.MainUsername}, id: {myUserId}")
Dim sourceGroup As TL.ChatBase =
(Await WTelegramHelper.GetChannelsByTitleAsync(client, title:="Aliens Rar ")
).Single()
Dim sourceGroupId As Long = sourceGroup.ID
Dim sourceGroupTopics As ReadOnlyCollection(Of TL.ForumTopicBase) =
Await WTelegramHelper.GetGroupTopicsAsync(sourceGroup)
End Sub
And for the helper function that should retrieve the forum topics of a specific channel (group):
Public Shared Async Function GetChannelTopicsAsync(client As WTelegram.Client, channel As TL.ChatBase) _
As Task(Of ReadOnlyCollection(Of TL.ForumTopic))
Dim access_hash As Long = ????
Dim inputChannel As New InputChannel(channel.ID, access_hash)
Dim msgs_ForumTopics As Messages_ForumTopics =
Await client.Channels_GetForumTopics(inputChannel)
Dim topicsBase As TL.ForumTopicBase() = msgs_ForumTopics.topics
Dim topics As List(Of TL.ForumTopic) =
Array.ConvertAll(topicsBase, Function(topicBase) DirectCast(topicBase, ForumTopic)).ToList()
' Suggestion to implement custom ordering here.
topics.Sort(Comparer(Of TL.ForumTopic).Default)
Return topics.AsReadOnly()
End Function
Note: I'm not sure if I should rely on TL.ForumTopicBase
class, or TL.ForumTopic
class, my subsequent intention is to enumerate the messages (from all users) that belongs to a specific topic from the retrieved ones... so I would like to get a collection of the proper class that fits my needs.
Additional (own) helper code used:
Public Class TelegramClientConfig
Public Property ApiId As String
Public Property ApiHash As String
Public Property PhoneNumber As String
Public Property VerificationCode As String
Public Property FirstName As String
Public Property LastName As String
Public Property Password As String
End Class
Public NotInheritable Class WTelegramHelper
''' <summary>
''' Prevents a default instance of the <see cref="WTelegramHelper"/> class from being created.
''' </summary>
<DebuggerNonUserCode>
Private Sub New()
End Sub
''' <summary>
''' Creates an instance of the <see cref="WTelegram.Client"/> class using the
''' configuration specified in the provided <see cref="TelegramClientConfig"/> object.
''' </summary>
'''
''' <param name="clientConfig">
''' A <see cref="TelegramClientConfig"/> object containing the
''' client configuration settings.
''' </param>
'''
''' <returns>
''' An instance of the <see cref="WTelegram.Client"/> object configured
''' based on the provided <see cref="TelegramClientConfig"/> object.
''' </returns>
<DebuggerStepThrough>
Public Shared Function CreateClient(clientConfig As TelegramClientConfig) As WTelegram.Client
Dim configProvider As Func(Of String, String) =
Function(key As String) As String
Select Case key.ToLower()
Case "api_id"
Return clientConfig.ApiId
Case "api_hash"
Return clientConfig.ApiHash
Case "phone_number"
Return clientConfig.PhoneNumber
Case "verification_code"
Return clientConfig.VerificationCode
Case "first_name"
Return clientConfig.FirstName ' If sign-up is required.
Case "last_name"
Return clientConfig.LastName ' If sign-up is required.
Case "password"
Return clientConfig.Password ' If user has enabled 2FA.
Case Else
Return Nothing ' Let WTelegramClient decide the default config.
End Select
End Function
Dim client As New WTelegram.Client(configProvider)
Return client
End Function
''' <summary>
''' Retrieves the value of the "ID" property (uppercase) from an object's type that
''' implements the <see cref="IPeerInfo"/> interface (e.g., <see cref="TL.User"/>).
''' <para></para>
''' This method accommodates the non-VB.NET compliant member naming convention
''' used in the WTelegramClient API, originally written in C#.
''' </summary>
'''
''' <param name="sourceObject">
''' The source object implementing the <see cref="IPeerInfo"/> interface.
''' </param>
'''
''' <returns>
''' The value of the <see cref="IPeerInfo.ID"/> property from the source object.
''' </returns>
<DebuggerStepThrough>
Public Shared Function GetIdPropertyValue(sourceObject As IPeerInfo) As Long
Dim propInfo As PropertyInfo =
GetType(IPeerInfo).
GetProperty("ID", BindingFlags.Instance Or BindingFlags.Public,
Type.DefaultBinder, GetType(Long), Type.EmptyTypes,
Array.Empty(Of ParameterModifier))
Dim value As Long = CLng(propInfo.GetValue(sourceObject))
Return value
End Function
''' <summary>
''' Asynchronously retrieves the <see cref="TL.ChatBase"/> instances
''' that match the specified channel or group title (case-insensitive).
''' </summary>
'''
''' <param name="client">
''' The source <see cref="WTelegram.Client"/> object used to retrieve channels.
''' </param>
'''
''' <param name="title">
''' The title of the channel or group to search for.
''' </param>
'''
''' <returns>
''' An asynchronous operation that yields a <see cref="ReadOnlyCollection(Of TL.ChatBase)"/>
''' containing the matching channels or groups.
''' </returns>
<DebuggerStepThrough>
Public Shared Async Function GetChannelsByTitleAsync(client As WTelegram.Client,
title As String) As Task(Of ReadOnlyCollection(Of TL.ChatBase))
Dim allChannels As Messages_Chats = Await client.Messages_GetAllChats()
Dim retChannels As New List(Of TL.ChatBase)
For Each channel As ChatBase In allChannels.chats.Values
If String.Compare(channel.Title, title, StringComparison.OrdinalIgnoreCase) = 0 Then
retChannels.Add(channel)
End If
Next channel
' Suggestion to implement custom ordering here.
retChannels.Sort(Comparer(Of TL.ChatBase).Default)
Return retChannels.AsReadOnly()
End Function
End Class
I figured out that
ChatBase
can be casted toChannel
type, so these are the main changes I did to the previous code that I posted:At this point I have a compatible
Channel
object, so the rest is easy to adapt:UPDATE: I noticed that the
Channels_GetForumTopics
has an offset parameter. I suppose this should be used if there are many topics to return per request, so the code above will need little modifications in those cases.