- Fix Messages_GetAllDialogs (MessageEmpty)

- Fix AnalyzeInviteLink (public channel with join request)
- Added Contacts_ResolvedPeer.Channel property
closes #166
This commit is contained in:
Wizou 2023-06-27 16:00:55 +02:00
parent a31bcc3df6
commit d50ac0ba51
6 changed files with 28 additions and 17 deletions

View file

@ -17,7 +17,7 @@ jobs:
support-label: 'telegram api' support-label: 'telegram api'
issue-comment: > issue-comment: >
**Github Issues** should be used only for problems with the library itself. **Github Issues** should be used only for problems with the library itself.
For questions about Telegram API usage, you can search the [API official documentation](https://core.telegram.org/api#getting-started) For questions about Telegram API usage, you can search the [API official documentation](https://core.telegram.org/api#getting-started)
or [click here to ask your question on **StackOverflow**](https://stackoverflow.com/questions/ask?tags=c%23+wtelegramclient+telegram-api) so the whole community can help and benefit. or [click here to ask your question on **StackOverflow**](https://stackoverflow.com/questions/ask?tags=c%23+wtelegramclient+telegram-api) so the whole community can help and benefit.
close-issue: true close-issue: true

2
FAQ.md
View file

@ -203,7 +203,7 @@ If Telegram servers decide to shutdown this secondary connection, it's not an is
This should be transparent and pending API calls should automatically be resent upon reconnection. This should be transparent and pending API calls should automatically be resent upon reconnection.
You can choose to increase `MaxAutoReconnects` if it happens too often because your Internet connection is unstable. You can choose to increase `MaxAutoReconnects` if it happens too often because your Internet connection is unstable.
3) If you reach `MaxAutoReconnects` disconnections, then the **OnOther** event handler will receive a `ReactorError` object to notify you of the problem, 3) If you reach `MaxAutoReconnects` disconnections or a reconnection fails, then the **OnOther** event handler will receive a `ReactorError` object to notify you of the problem,
and pending API calls throw the network IOException. and pending API calls throw the network IOException.
In this case, the recommended action would be to dispose the client and recreate one (see example [Program_ReactorError.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_ReactorError.cs)) In this case, the recommended action would be to dispose the client and recreate one (see example [Program_ReactorError.cs](https://github.com/wiz0u/WTelegramClient/blob/master/Examples/Program_ReactorError.cs))

View file

@ -1,6 +1,6 @@
[![API Layer](https://img.shields.io/badge/API_Layer-158-blueviolet)](https://corefork.telegram.org/methods) [![API Layer](https://img.shields.io/badge/API_Layer-158-blueviolet)](https://corefork.telegram.org/methods)
[![NuGet version](https://img.shields.io/nuget/v/WTelegramClient?color=00508F)](https://www.nuget.org/packages/WTelegramClient/) [![NuGet version](https://img.shields.io/nuget/v/WTelegramClient?color=00508F)](https://www.nuget.org/packages/WTelegramClient/)
[![NuGet prerelease](https://img.shields.io/nuget/vpre/WTelegramClient?color=C09030&label=dev+nuget)](https://www.nuget.org/packages/WTelegramClient/) [![NuGet prerelease](https://img.shields.io/nuget/vpre/WTelegramClient?color=C09030&label=dev+nuget)](https://www.nuget.org/packages/WTelegramClient/absoluteLatest)
[![Donate](https://img.shields.io/badge/Help_this_project:-Donate-ff4444)](https://www.buymeacoffee.com/wizou) [![Donate](https://img.shields.io/badge/Help_this_project:-Donate-ff4444)](https://www.buymeacoffee.com/wizou)
## _Telegram Client API library written 100% in C# and .NET_ ## _Telegram Client API library written 100% in C# and .NET_
@ -91,6 +91,8 @@ Since version 3.0.0, a new approach to login/configuration has been added. Some
```csharp ```csharp
WTelegram.Client client = new WTelegram.Client(YOUR_API_ID, "YOUR_API_HASH"); // this constructor doesn't need a Config method WTelegram.Client client = new WTelegram.Client(YOUR_API_ID, "YOUR_API_HASH"); // this constructor doesn't need a Config method
await DoLogin("+12025550156"); // initial call with user's phone_number await DoLogin("+12025550156"); // initial call with user's phone_number
...
//client.Dispose(); // the client must be disposed when you're done running your userbot.
async Task DoLogin(string loginInfo) // (add this method to your code) async Task DoLogin(string loginInfo) // (add this method to your code)
{ {

View file

@ -473,10 +473,15 @@ namespace WTelegram
{ {
dialogList.AddRange(dialogs.Dialogs); dialogList.AddRange(dialogs.Dialogs);
messageList.AddRange(dialogs.Messages); messageList.AddRange(dialogs.Messages);
var lastDialog = dialogs.Dialogs[^1]; int last = dialogs.Dialogs.Length - 1;
var lastMsg = dialogs.Messages.LastOrDefault(m => m.Peer.ID == lastDialog.Peer.ID && m.ID == lastDialog.TopMessage); var lastDialog = dialogs.Dialogs[last];
var offsetPeer = dialogs.UserOrChat(lastDialog).ToInputPeer(); var lastPeer = dialogs.UserOrChat(lastDialog).ToInputPeer();
dialogs = await this.Messages_GetDialogs(lastMsg?.Date ?? default, lastDialog.TopMessage, offsetPeer, folder_id: folder_id); var lastMsgId = lastDialog.TopMessage;
retryDate:
var lastDate = dialogs.Messages.LastOrDefault(m => m.Peer.ID == lastDialog.Peer.ID && m.ID == lastDialog.TopMessage)?.Date ?? default;
if (lastDate == default)
if (--last < 0) break; else { lastDialog = dialogs.Dialogs[last]; goto retryDate; }
dialogs = await this.Messages_GetDialogs(lastDate, lastMsgId, lastPeer, folder_id: folder_id);
if (dialogs is not Messages_Dialogs md) break; if (dialogs is not Messages_Dialogs md) break;
foreach (var (key, value) in md.chats) mds.chats[key] = value; foreach (var (key, value) in md.chats) mds.chats[key] = value;
foreach (var (key, value) in md.users) mds.users[key] = value; foreach (var (key, value) in md.users) mds.users[key] = value;
@ -682,8 +687,8 @@ namespace WTelegram
private static readonly char[] UrlSeparator = new[] { '?', '#', '/' }; private static readonly char[] UrlSeparator = new[] { '?', '#', '/' };
/// <summary>Return information about a chat/channel based on Invite Link</summary> /// <summary>Return information about a chat/channel based on Invite Link or Public Link</summary>
/// <param name="url">Public link or Invite link, like https://t.me/+InviteHash, https://t.me/joinchat/InviteHash or https://t.me/channelname<br/>Also work without https:// prefix</param> /// <param name="url">Public link or Invite link, like https://t.me/+InviteHash, https://t.me/joinchat/InviteHash or https://t.me/channelname<br/>Works also without https:// prefix</param>
/// <param name="join"><see langword="true"/> to also join the chat/channel</param> /// <param name="join"><see langword="true"/> to also join the chat/channel</param>
/// <param name="chats">previously collected chats, to prevent unnecessary ResolveUsername</param> /// <param name="chats">previously collected chats, to prevent unnecessary ResolveUsername</param>
/// <returns>a Chat or Channel, possibly partial Channel information only (with flag <see cref="Channel.Flags.min"/>)</returns> /// <returns>a Chat or Channel, possibly partial Channel information only (with flag <see cref="Channel.Flags.min"/>)</returns>
@ -703,10 +708,12 @@ namespace WTelegram
{ {
var chat = await CachedOrResolveUsername(url[start..end], chats); var chat = await CachedOrResolveUsername(url[start..end], chats);
if (join && chat is Channel channel) if (join && chat is Channel channel)
{ try
var res = await this.Channels_JoinChannel(channel); {
chat = res.Chats[chat.ID]; var res = await this.Channels_JoinChannel(channel);
} chat = res.Chats[channel.id];
}
catch (RpcException ex) when (ex.Code == 400 && ex.Message == "INVITE_REQUEST_SENT") { }
return chat; return chat;
} }
var chatInvite = await this.Messages_CheckChatInvite(hash); var chatInvite = await this.Messages_CheckChatInvite(hash);
@ -748,11 +755,11 @@ namespace WTelegram
return null; return null;
} }
/// <summary>Return chat and message details based on a message URL</summary> /// <summary>Return chat and message details based on a Message Link (URL)</summary>
/// <param name="url">Message Link, like https://t.me/c/1234567890/1234 or https://t.me/channelname/1234</param> /// <param name="url">Message Link, like https://t.me/c/1234567890/1234 or https://t.me/channelname/1234</param>
/// <param name="chats">previously collected chats, to prevent unnecessary ResolveUsername</param> /// <param name="chats">previously collected chats, to prevent unnecessary ResolveUsername</param>
/// <returns>Structure containing the message, chat and user details</returns> /// <returns>Structure containing the message, chat and user details</returns>
/// <remarks>If link is for private group (<c>t.me/c/..</c>), user must have joined the group</remarks> /// <remarks>If link is for private group (<c>t.me/c/..</c>), user must have joined that group</remarks>
public async Task<Messages_ChannelMessages> GetMessageByLink(string url, IDictionary<long, ChatBase> chats = null) public async Task<Messages_ChannelMessages> GetMessageByLink(string url, IDictionary<long, ChatBase> chats = null)
{ {
int start = url.IndexOf("//"); int start = url.IndexOf("//");

View file

@ -543,8 +543,10 @@ namespace TL
public static implicit operator InputPeer(Contacts_ResolvedPeer resolved) => resolved?.UserOrChat.ToInputPeer(); public static implicit operator InputPeer(Contacts_ResolvedPeer resolved) => resolved?.UserOrChat.ToInputPeer();
/// <returns>A <see cref="TL.User"/>, or <see langword="null"/> if the username was for a channel</returns> /// <returns>A <see cref="TL.User"/>, or <see langword="null"/> if the username was for a channel</returns>
public User User => peer is PeerUser pu ? users[pu.user_id] : null; public User User => peer is PeerUser pu ? users[pu.user_id] : null;
/// <returns>A <see cref="Channel"/> or <see cref="ChannelForbidden"/>, or <see langword="null"/> if the username was for a user</returns> /// <returns>A <see cref="TL.Channel"/> or <see cref="TL.ChannelForbidden"/>, or <see langword="null"/> if the username was for a user</returns>
public ChatBase Chat => peer is PeerChannel or PeerChat ? chats[peer.ID] : null; public ChatBase Chat => peer is PeerChannel or PeerChat ? chats[peer.ID] : null;
/// <returns>A <see cref="TL.Channel"/>, or <see langword="null"/> if the username was for a user or for a forbidden channel</returns>
public Channel Channel => peer is PeerChannel pc ? chats[pc.channel_id] as Channel : null;
} }
partial class Updates_ChannelDifferenceBase partial class Updates_ChannelDifferenceBase

View file

@ -23,7 +23,7 @@
<RepositoryType>git</RepositoryType> <RepositoryType>git</RepositoryType>
<PackageTags>Telegram;MTProto;Client;Api;UserBot;TLSharp</PackageTags> <PackageTags>Telegram;MTProto;Client;Api;UserBot;TLSharp</PackageTags>
<PackageReadmeFile>README.md</PackageReadmeFile> <PackageReadmeFile>README.md</PackageReadmeFile>
<PackageReleaseNotes>$(ReleaseNotes.Replace("|", "%0D%0A").Replace(" - ","%0D%0A- ").Replace(" ", "%0D%0A%0D%0A"))</PackageReleaseNotes> <PackageReleaseNotes>$(ReleaseNotes.Replace("\"", "%22").Replace("|", "%0D%0A").Replace(" - ","%0D%0A- ").Replace(" ", "%0D%0A%0D%0A"))</PackageReleaseNotes>
<NoWarn>0419;1573;1591;NETSDK1138</NoWarn> <NoWarn>0419;1573;1591;NETSDK1138</NoWarn>
<DefineConstants>TRACE;OBFUSCATION</DefineConstants> <DefineConstants>TRACE;OBFUSCATION</DefineConstants>
</PropertyGroup> </PropertyGroup>