-
Notifications
You must be signed in to change notification settings - Fork 380
GetFullChat + GetAllChats + MakeAuthBotAsync + Other methods #926
base: master
Are you sure you want to change the base?
Changes from all commits
80d16fe
e067688
92ca5a9
406a73b
54781b2
2d4aa3e
00fb3ae
65ff8cc
3721e8c
c28a41c
7dedf2a
45be5f5
9623f9d
ce93c76
27d680f
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -8,6 +8,7 @@ | |
using TeleSharp.TL; | ||
using TeleSharp.TL.Account; | ||
using TeleSharp.TL.Auth; | ||
using TeleSharp.TL.Channels; | ||
using TeleSharp.TL.Contacts; | ||
using TeleSharp.TL.Help; | ||
using TeleSharp.TL.Messages; | ||
|
@@ -17,13 +18,20 @@ | |
using TLSharp.Core.MTProto.Crypto; | ||
using TLSharp.Core.Network; | ||
using TLSharp.Core.Network.Exceptions; | ||
using TLSharp.Core.Types; | ||
using TLSharp.Core.Utils; | ||
using TLAuthorization = TeleSharp.TL.Auth.TLAuthorization; | ||
using TLRequestUpdateUsername = TeleSharp.TL.Account.TLRequestUpdateUsername; | ||
|
||
namespace TLSharp.Core | ||
{ | ||
public class TelegramClient : IDisposable | ||
{ | ||
/// <summary> | ||
/// When pagination is needed, this is the default page size | ||
/// </summary> | ||
public const int DEFAULT_PAGE_SIZE = 200; | ||
|
||
private MtProtoSender sender; | ||
private TcpTransport transport; | ||
private string apiHash = String.Empty; | ||
|
@@ -262,7 +270,7 @@ public bool IsUserAuthorized() | |
|
||
public async Task<bool> CheckUsernameAsync(string username, CancellationToken token = default(CancellationToken)) | ||
{ | ||
var req = new TLRequestCheckUsername { Username = username }; | ||
var req = new TeleSharp.TL.Account.TLRequestCheckUsername { Username = username }; | ||
|
||
return await SendAuthenticatedRequestAsync<bool>(req, token) | ||
.ConfigureAwait(false); | ||
|
@@ -406,6 +414,239 @@ await sender.SendPingAsync(token) | |
.ConfigureAwait(false); | ||
} | ||
|
||
/// <summary> | ||
/// Authenticates a Bot | ||
/// </summary> | ||
/// <param name="botAuthToken">The token of the bot to authenticate</param> | ||
/// <param name="token"></param> | ||
/// <returns>The TLUser descriptor</returns> | ||
public async Task<TLUser> MakeAuthBotAsync(string botAuthToken, CancellationToken token = default(CancellationToken)) | ||
{ | ||
if (String.IsNullOrWhiteSpace(botAuthToken)) | ||
{ | ||
throw new ArgumentNullException(nameof(botAuthToken)); | ||
} | ||
|
||
var request = new TLRequestImportBotAuthorization() { BotAuthToken = botAuthToken, ApiId = apiId, ApiHash = apiHash }; | ||
|
||
await RequestWithDcMigration(request, token).ConfigureAwait(false); | ||
|
||
OnUserAuthenticated(((TLUser)request.Response.User)); | ||
|
||
return ((TLUser)request.Response.User); | ||
} | ||
|
||
/// <summary> | ||
/// Gets the full information of a specified chat | ||
/// </summary> | ||
/// <param name="chatId">The ID of the chat we want the info of</param> | ||
/// <param name="token"></param> | ||
/// <returns></returns> | ||
public async Task<TeleSharp.TL.Messages.TLChatFull> GetFullChat(int chatId, CancellationToken token = default(CancellationToken)) | ||
{ | ||
var req = new TLRequestGetFullChat() { ChatId = chatId }; | ||
var fchat = await SendRequestAsync<TeleSharp.TL.Messages.TLChatFull>(req, token).ConfigureAwait(false); | ||
|
||
return fchat; | ||
} | ||
|
||
/// <summary> | ||
/// Gets the list of chats and channels opened by the authenticated user. | ||
/// Throws an exception if the authenticated user is a bot. | ||
/// </summary> | ||
/// <param name="token"></param> | ||
/// <returns>The list of chats opened by the authenticated user</returns> | ||
public async Task<TLChats> GetAllChats(CancellationToken token = default(CancellationToken)) | ||
{ | ||
return await GetAllChats(null, token); | ||
} | ||
|
||
/// <summary> | ||
/// Gets the list of chats and channels opened by the authenticated user except the passed ones. | ||
/// Throws an exception if the authenticated user is a bot. | ||
/// </summary> | ||
/// <param name="ids">The IDs of the chats to be returned</param> | ||
/// <param name="token"></param> | ||
/// <returns>The list of chats opened by the authenticated user</returns> | ||
public async Task<TLChats> GetAllChats(int[] exceptdIds, CancellationToken token = default(CancellationToken)) | ||
{ | ||
var ichats = new TeleSharp.TL.TLVector<int>(); // we can't pass a null argument to the TLRequestGetChats | ||
if (exceptdIds != null) | ||
Array.ForEach(exceptdIds, x => ichats.Add(x)); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not a fan of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. // there is a handy constructor // if (exceptdIds != null) |
||
var chats = await SendRequestAsync<TLChats>(new TLRequestGetAllChats() { ExceptIds = ichats }, token).ConfigureAwait(false); | ||
return chats; | ||
} | ||
|
||
/// <summary> | ||
/// Gets the information about a channel | ||
/// </summary> | ||
/// <param name="channel">The channel to get the info of</param> | ||
/// <param name="token"></param> | ||
/// <returns></returns> | ||
public async Task<TeleSharp.TL.Messages.TLChatFull> GetFullChannel(TLChannel channel, CancellationToken token = default(CancellationToken)) | ||
{ | ||
if (channel == null) return null; | ||
return await GetFullChannel(channel.Id, (long)channel.AccessHash, token).ConfigureAwait(false); | ||
} | ||
|
||
/// <summary> | ||
/// Gets the information about a channel | ||
/// </summary> | ||
/// <param name="channelId">The ID of the channel</param> | ||
/// <param name="token"></param> | ||
/// <returns></returns> | ||
public async Task<TeleSharp.TL.Messages.TLChatFull> GetFullChannel(int channelId, long accessHash, CancellationToken token = default(CancellationToken)) | ||
{ | ||
var req = new TLRequestGetFullChannel() { Channel = new TLInputChannel() { ChannelId = channelId, AccessHash = accessHash } }; | ||
var fchat = await SendRequestAsync<TeleSharp.TL.Messages.TLChatFull>(req, token).ConfigureAwait(false); | ||
|
||
return fchat; | ||
} | ||
|
||
/// <summary> | ||
/// Gets the channels having the supplied IDs | ||
/// </summary> | ||
/// <param name="channelIds">The IDs of the channels to be retrieved</param> | ||
/// <param name="token"></param> | ||
/// <returns></returns> | ||
public async Task<TeleSharp.TL.Messages.TLChats> GetChannels(int[] channelIds, CancellationToken token = default(CancellationToken)) | ||
{ | ||
var channels = new TLVector<TeleSharp.TL.TLAbsInputChannel>(); // we can't pass a null argument to the TLRequestGetChats | ||
if (channelIds != null) | ||
Array.ForEach(channelIds, x => channels.Add(new TLInputChannel() { ChannelId = x })); | ||
var req = new TLRequestGetChannels() { Id = channels }; | ||
var fchat = await SendRequestAsync<TeleSharp.TL.Messages.TLChats>(req, token).ConfigureAwait(false); | ||
|
||
return fchat; | ||
} | ||
|
||
/// <summary> | ||
/// Gets the participants of the channel having the supplied type. | ||
/// The method will auto-paginate results and return all the participants | ||
/// </summary> | ||
/// <param name="channel">The TLChannel whose participants are requested</param> | ||
/// <param name="stIdx">The index to start fetching from. -1 will automatically fetch all the results</param> | ||
/// <param name="pageSize">How many results to be fetch on each iteration. | ||
/// Values smaller than 0 are ignored. If stIdx is set, a number of results smaller than pageSize might be returned by Telegram.</param> | ||
/// <param name="partType">The type of the participants to get. Choose Recents not to filter</param> | ||
/// <param name="token"></param> | ||
/// <returns></returns> | ||
public async Task<TLChannelParticipants> GetParticipants(TLChannel channel, int stIdx = -1, int pageSize = -1, ParticipantFilterTypes partType = ParticipantFilterTypes.Recents, CancellationToken token = default(CancellationToken)) | ||
{ | ||
if (channel == null) return null; | ||
return await GetParticipants(channel.Id, (long)channel.AccessHash, stIdx, pageSize, partType, token).ConfigureAwait(false); | ||
} | ||
|
||
/// <summary> | ||
/// Gets the participants of the channel having the supplied type. | ||
/// The method will auto-paginate results and return all the participants | ||
/// </summary> | ||
/// <param name="channelId">The id of the channel whose participants are requested</param> | ||
/// <param name="accessHash">The access hash of the channel whose participants are requested</param> | ||
/// <param name="stIdx">The index to start fetching from. -1 will automatically fetch all the results</param> | ||
/// <param name="pageSize">How many results to be fetch on each iteration. | ||
/// Values smaller than 0 are ignored. If stIdx is set, a number of results smaller than pageSize might be returned by Telegram.</param> | ||
/// <param name="partType">The type of the participants to get. Choose Recents not to filter</param> | ||
/// <param name="token"></param> | ||
/// <returns></returns> | ||
public async Task<TLChannelParticipants> GetParticipants(int channelId, long accessHash, int stIdx = -1, int pageSize = -1, ParticipantFilterTypes partType = ParticipantFilterTypes.Recents, CancellationToken token = default(CancellationToken)) | ||
{ | ||
TLAbsChannelParticipantsFilter filter; | ||
switch (partType) | ||
{ | ||
case ParticipantFilterTypes.Admins: | ||
filter = new TLChannelParticipantsAdmins(); | ||
break; | ||
|
||
case ParticipantFilterTypes.Kicked: | ||
filter = new TLChannelParticipantsKicked(); | ||
break; | ||
|
||
case ParticipantFilterTypes.Bots: | ||
filter = new TLChannelParticipantsBots(); | ||
break; | ||
|
||
case ParticipantFilterTypes.Recents: | ||
filter = new TLChannelParticipantsRecent(); | ||
break; | ||
|
||
case ParticipantFilterTypes.Banned: | ||
case ParticipantFilterTypes.Restricted: | ||
case ParticipantFilterTypes.Contacts: | ||
case ParticipantFilterTypes.Search: | ||
default: | ||
throw new NotImplementedException($"{partType} not implemented yet"); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If it's not gonna be implemented please remove them from your enum as the only purpose of enum is for this filter There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it's gonna be implemented as soon as the new Classes are added to the TL framework There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should i drop them anyways or leave them? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. are they present in the new layers? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes, see here: https://core.telegram.org/type/ChannelParticipantsFilter There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I vote, then, for only merging this PR after we have updated the layer |
||
} | ||
|
||
int total = 0; | ||
int found = stIdx < 0 ? 0 : stIdx; | ||
pageSize = pageSize < 0 ? DEFAULT_PAGE_SIZE : pageSize; | ||
|
||
TLChannelParticipants ret = new TLChannelParticipants(); | ||
ret.Participants = new TLVector<TLAbsChannelParticipant>(); | ||
ret.Users = new TLVector<TLAbsUser>(); | ||
|
||
do | ||
{ | ||
var req = new TLRequestGetParticipants() | ||
{ | ||
Channel = new TLInputChannel() | ||
{ | ||
ChannelId = channelId, | ||
AccessHash = accessHash | ||
}, | ||
Filter = filter, | ||
Offset = found, | ||
Limit = pageSize | ||
}; | ||
var fchat = await SendRequestAsync<TLChannelParticipants>(req, token).ConfigureAwait(false); | ||
total = fchat.Count; | ||
found += fchat.Participants.Count; | ||
foreach (var p in fchat.Participants) | ||
ret.Participants.Add(p); | ||
foreach (var u in fchat.Users) | ||
ret.Users.Add(u); | ||
} while (found < total && stIdx == -1); | ||
ret.Count = ret.Participants.Count; | ||
return ret; | ||
} | ||
|
||
/// <summary> | ||
/// Invites the passed users to the specified channel | ||
/// </summary> | ||
/// <param name="channel">The descriptor of the channel to invite the users to</param> | ||
/// <param name="users"></param> | ||
/// <returns></returns> | ||
public async Task<TLUpdates> InviteToChannel(TLChannel channel, int[] users, CancellationToken token = default(CancellationToken)) | ||
{ | ||
return await InviteToChannel(channel.Id, (long)channel.AccessHash, users, token); | ||
} | ||
solarin marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
/// <summary> | ||
/// Invites the passed users to the specified channel | ||
/// </summary> | ||
/// <param name="channelId">The id of the channel to invite the users to</param> | ||
/// <param name="accessHash">The access hash of the channel to invite the users to</param> | ||
/// <param name="users"></param> | ||
/// <returns></returns> | ||
public async Task<TLUpdates> InviteToChannel(int channelId, long accessHash, int[] users, CancellationToken token = default(CancellationToken)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe use TLChannel or TLInputChannel as parameter here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I create an overload as for the other methods, ok? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sure nice There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This function is not working, always return UserId_Invalid exception There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @jamesjsc do you mind porting this PR to TgSharp? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @knocte ok There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @knocte What is the different between TLSharp and TgSharp? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. TL Layer update, Tg is the future, TL will just receive bug fixes, no new features. |
||
{ | ||
TLVector<TLAbsInputUser> absUsers = new TLVector<TLAbsInputUser>(); | ||
Array.ForEach(users, u => absUsers.Add(new TLInputUser() { UserId = u })); | ||
var req = new TLRequestInviteToChannel() | ||
{ | ||
Channel = new TLInputChannel() | ||
{ | ||
ChannelId = channelId, | ||
AccessHash = accessHash | ||
}, | ||
Users = absUsers | ||
}; | ||
var updates = await SendRequestAsync<TLUpdates>(req, token).ConfigureAwait(false); | ||
|
||
return updates; | ||
} | ||
|
||
/// <summary> | ||
/// Serch user or chat. API: contacts.search#11f812d8 q:string limit:int = contacts.Found; | ||
/// </summary> | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
namespace TLSharp.Core.Types | ||
{ | ||
public enum ParticipantFilterTypes | ||
{ | ||
Recents, | ||
Restricted, | ||
Admins, | ||
Bots, | ||
Search, | ||
Contacts, | ||
Kicked, | ||
Banned | ||
} | ||
|
||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what's the reason behind this? just use it directly inside the code. there is hundreds of request used in this file. no need to add alias for just one use
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
actually TLRequestUpdateUsername is ambigous with as it's already present in TL.Channels. i can double check and report exactly where.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'TLRequestUpdateUsername' is an ambiguous reference between 'TeleSharp.TL.Account.TLRequestUpdateUsername' and 'TeleSharp.TL.Channels.TLRequestUpdateUsername'
'TLAuthorization' is an ambiguous reference between 'TeleSharp.TL.Auth.TLAuthorization' and 'TeleSharp.TL.TLAuthorization' TLSharp.Core
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
that's fair enough