mirror of
https://github.com/sochix/TLSharp.git
synced 2025-12-06 08:02:00 +01:00
Merge branch 'master' of https://github.com/sochix/TLSharp into netstandard
This commit is contained in:
commit
b343c51723
49
README.md
49
README.md
|
|
@ -1,12 +1,13 @@
|
|||
TLSharp
|
||||
-------------------------------
|
||||
|
||||
[](https://gitter.im/TLSharp/Lobby?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
[](https://ci.appveyor.com/project/sochix/tlsharp)
|
||||
[](https://badge.fury.io/nu/TLSharp)
|
||||
|
||||
_Unofficial_ Telegram (http://telegram.org) client library implemented in C#. Latest TL scheme supported, thanks to Afshin Arani
|
||||
|
||||
🚩 Check out [TeleJS](https://github.com/RD17/TeleJS) - a pure JavaScript implementation of Telegram MTP protocol
|
||||
|
||||
It's a perfect fit for any developer who would like to send data directly to Telegram users or write own custom Telegram client.
|
||||
|
||||
:star2: If you :heart: library, please star it! :star2:
|
||||
|
|
@ -20,9 +21,10 @@ It's a perfect fit for any developer who would like to send data directly to Tel
|
|||
- [First requests](#first-requests)
|
||||
- [Working with files](#working-with-files)
|
||||
- [Available Methods](#available-methods)
|
||||
- [Contributing](#contributing)
|
||||
- [Contributors](#contributors)
|
||||
- [FAQ](#faq)
|
||||
- [Donations](#donations)
|
||||
- [Support](#support)
|
||||
- [License](#license)
|
||||
|
||||
# How do I add this to my project?
|
||||
|
|
@ -81,13 +83,13 @@ You can call any method on authenticated user. For example, let's send message t
|
|||
var result = await client.GetContactsAsync();
|
||||
|
||||
//find recipient in contacts
|
||||
var user = result.Users.lists
|
||||
var user = result.Users
|
||||
.Where(x => x.GetType() == typeof (TLUser))
|
||||
.Cast<TLUser>()
|
||||
.FirstOrDefault(x => x.phone == "<recipient_phone>");
|
||||
.FirstOrDefault(x => x.Phone == "<recipient_phone>");
|
||||
|
||||
//send message
|
||||
await client.SendMessageAsync(new TLInputPeerUser() {user_id = user.id}, "OUR_MESSAGE");
|
||||
await client.SendMessageAsync(new TLInputPeerUser() {UserId = user.Id}, "OUR_MESSAGE");
|
||||
```
|
||||
|
||||
Full code you can see at [SendMessage test](https://github.com/sochix/TLSharp/blob/master/TLSharp.Tests/TLSharpTests.cs#L87)
|
||||
|
|
@ -95,16 +97,16 @@ Full code you can see at [SendMessage test](https://github.com/sochix/TLSharp/bl
|
|||
To send message to channel you could use the following code:
|
||||
```csharp
|
||||
//get user dialogs
|
||||
var dialogs = await client.GetUserDialogsAsync();
|
||||
var dialogs = (TLDialogsSlice) await client.GetUserDialogsAsync();
|
||||
|
||||
//find channel by title
|
||||
var chat = dialogs.chats.lists
|
||||
var chat = dialogs.Chats
|
||||
.Where(c => c.GetType() == typeof(TLChannel))
|
||||
.Cast<TLChannel>()
|
||||
.FirstOrDefault(c => c.title == "<channel_title>");
|
||||
.FirstOrDefault(c => c.Title == "<channel_title>");
|
||||
|
||||
//send message
|
||||
await client.SendMessageAsync(new TLInputPeerChannel() { channel_id = chat.id, access_hash = chat.access_hash.Value }, "OUR_MESSAGE");
|
||||
await client.SendMessageAsync(new TLInputPeerChannel() { ChannelId = chat.Id, AccessHash = chat.AccessHash.Value }, "OUR_MESSAGE");
|
||||
```
|
||||
Full code you can see at [SendMessageToChannel test](https://github.com/sochix/TLSharp/blob/master/TLSharp.Tests/TLSharpTests.cs#L107)
|
||||
## Working with files
|
||||
|
|
@ -117,9 +119,9 @@ Telegram separate files to two categories -> big file and small file. File is Bi
|
|||
TLSharp provides two wrappers for sending photo and document
|
||||
|
||||
```csharp
|
||||
await client.SendUploadedPhoto(new TLInputPeerUser() { user_id = user.id }, fileResult, "kitty");
|
||||
await client.SendUploadedPhoto(new TLInputPeerUser() { UserId = user.Id }, fileResult, "kitty");
|
||||
await client.SendUploadedDocument(
|
||||
new TLInputPeerUser() { user_id = user.id },
|
||||
new TLInputPeerUser() { UserId = user.Id },
|
||||
fileResult,
|
||||
"some zips", //caption
|
||||
"application/zip", //mime-type
|
||||
|
|
@ -132,11 +134,11 @@ To download file you should call **GetFile** method
|
|||
await client.GetFile(
|
||||
new TLInputDocumentFileLocation()
|
||||
{
|
||||
access_hash = document.access_hash,
|
||||
id = document.id,
|
||||
version = document.version
|
||||
AccessHash = document.AccessHash,
|
||||
Id = document.Id,
|
||||
Version = document.Version
|
||||
},
|
||||
document.size); //size of fileChunk you want to retrieve
|
||||
document.Size); //size of fileChunk you want to retrieve
|
||||
```
|
||||
|
||||
Full code you can see at [DownloadFileFromContactTest](https://github.com/sochix/TLSharp/blob/master/TLSharp.Tests/TLSharpTests.cs#L167)
|
||||
|
|
@ -169,12 +171,12 @@ Don't panic. You can call any method with help of `SendRequestAsync` function. F
|
|||
//Create request
|
||||
var req = new TLRequestSetTyping()
|
||||
{
|
||||
action = new TLSendMessageTypingAction(),
|
||||
peer = peer
|
||||
Action = new TLSendMessageTypingAction(),
|
||||
Peer = new TLInputPeerUser() { UserId = user.Id }
|
||||
};
|
||||
|
||||
//run request, and deserialize response to Boolean
|
||||
return await SendRequestAsync<Boolean>(req);
|
||||
return await client.SendRequestAsync<Boolean>(req);
|
||||
```
|
||||
|
||||
**Where you can find a list of requests and its params?**
|
||||
|
|
@ -211,10 +213,10 @@ It's likely [Telegram restrictions](https://core.telegram.org/api/errors#420-flo
|
|||
|
||||
#### Why does TLSharp lacks feature XXXX?
|
||||
|
||||
Now TLSharp is basic realization of Telegram protocol, you can be a contributor or a sponsor to speed-up developemnt of any feature.
|
||||
TLSharp only covers basic functionality of the Telegram protocol, you can be a contributor or a sponsor to speed-up developemnt of any more new features.
|
||||
|
||||
#### Nothing helps
|
||||
Ask your question at gitter or create an issue in project bug tracker.
|
||||
#### Where else to ask for help?
|
||||
If you think you have found a bug in TLSharp, create a github issue. But if you just have questions about how to use TLSharp, use our gitter channel (https://gitter.im/TLSharp/Lobby) or our Telegram channel (https://t.me/joinchat/AgtDiBEqG1i-qPqttNFLbA).
|
||||
|
||||
**Attach following information**:
|
||||
|
||||
|
|
@ -231,6 +233,11 @@ Thanks for donations! It's highly appreciated.
|
|||
List of donators:
|
||||
* [mtbitcoin](https://github.com/mtbitcoin)
|
||||
|
||||
# Support
|
||||
If you have troubles while using TLSharp, I can help you for an additional fee.
|
||||
|
||||
My pricing is **219$/hour**. I accept PayPal. To request a paid support write me at Telegram @sochix, start your message with phrase [PAID SUPPORT].
|
||||
|
||||
# Contributors
|
||||
* [Afshin Arani](http://aarani.ir) - TLGenerator, and a lot of other usefull things
|
||||
* [Knocte](https://github.com/knocte)
|
||||
|
|
|
|||
|
|
@ -18,10 +18,10 @@ namespace TLSharp.Core.Network
|
|||
{
|
||||
//private ulong sessionId = GenerateRandomUlong();
|
||||
|
||||
private TcpTransport _transport;
|
||||
private Session _session;
|
||||
private readonly TcpTransport _transport;
|
||||
private readonly Session _session;
|
||||
|
||||
public List<ulong> needConfirmation = new List<ulong>();
|
||||
public readonly List<ulong> needConfirmation = new List<ulong>();
|
||||
|
||||
public MtProtoSender(TcpTransport transport, Session session)
|
||||
{
|
||||
|
|
@ -29,11 +29,6 @@ namespace TLSharp.Core.Network
|
|||
_session = session;
|
||||
}
|
||||
|
||||
public void ChangeTransport(TcpTransport transport)
|
||||
{
|
||||
_transport = transport;
|
||||
}
|
||||
|
||||
private int GenerateSequence(bool confirmed)
|
||||
{
|
||||
return confirmed ? _session.Sequence++ * 2 + 1 : _session.Sequence * 2;
|
||||
|
|
|
|||
|
|
@ -84,21 +84,21 @@ namespace TLSharp.Core.Network
|
|||
}
|
||||
|
||||
return new TcpMessage(seq, body);
|
||||
}
|
||||
|
||||
public bool IsConnected
|
||||
{
|
||||
get
|
||||
{
|
||||
return this._tcpClient.Connected;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public bool IsConnected
|
||||
{
|
||||
get
|
||||
{
|
||||
return this._tcpClient.Connected;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_tcpClient.Connected)
|
||||
_tcpClient.Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,7 +41,6 @@ namespace TLSharp.Core
|
|||
if (store == null)
|
||||
store = new FileSessionStore();
|
||||
|
||||
TLContext.Init();
|
||||
_apiHash = apiHash;
|
||||
_apiId = apiId;
|
||||
_handler = handler;
|
||||
|
|
@ -50,7 +49,7 @@ namespace TLSharp.Core
|
|||
_transport = new TcpTransport(_session.ServerAddress, _session.Port, _handler);
|
||||
}
|
||||
|
||||
public async Task<bool> ConnectAsync(bool reconnect = false)
|
||||
public async Task ConnectAsync(bool reconnect = false)
|
||||
{
|
||||
if (_session.AuthKey == null || reconnect)
|
||||
{
|
||||
|
|
@ -77,21 +76,19 @@ namespace TLSharp.Core
|
|||
await _sender.Receive(invokewithLayer);
|
||||
|
||||
dcOptions = ((TLConfig)invokewithLayer.Response).DcOptions.ToList();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private async Task ReconnectToDcAsync(int dcId)
|
||||
{
|
||||
if (dcOptions == null || !dcOptions.Any())
|
||||
throw new InvalidOperationException($"Can't reconnect. Establish initial connection first.");
|
||||
|
||||
TLExportedAuthorization exported = null;
|
||||
if (_session.TLUser != null)
|
||||
{
|
||||
TLRequestExportAuthorization exportAuthorization = new TLRequestExportAuthorization() { DcId = dcId };
|
||||
exported = await SendRequestAsync<TLExportedAuthorization>(exportAuthorization);
|
||||
}
|
||||
|
||||
TLExportedAuthorization exported = null;
|
||||
if (_session.TLUser != null)
|
||||
{
|
||||
TLRequestExportAuthorization exportAuthorization = new TLRequestExportAuthorization() { DcId = dcId };
|
||||
exported = await SendRequestAsync<TLExportedAuthorization>(exportAuthorization);
|
||||
}
|
||||
|
||||
var dc = dcOptions.First(d => d.Id == dcId);
|
||||
|
||||
|
|
@ -99,18 +96,21 @@ namespace TLSharp.Core
|
|||
_session.ServerAddress = dc.IpAddress;
|
||||
_session.Port = dc.Port;
|
||||
|
||||
await ConnectAsync(true);
|
||||
|
||||
if (_session.TLUser != null)
|
||||
{
|
||||
TLRequestImportAuthorization importAuthorization = new TLRequestImportAuthorization() { Id = exported.Id, Bytes = exported.Bytes };
|
||||
var imported = await SendRequestAsync<TLAuthorization>(importAuthorization);
|
||||
OnUserAuthenticated(((TLUser)imported.User));
|
||||
await ConnectAsync(true);
|
||||
|
||||
if (_session.TLUser != null)
|
||||
{
|
||||
TLRequestImportAuthorization importAuthorization = new TLRequestImportAuthorization() { Id = exported.Id, Bytes = exported.Bytes };
|
||||
var imported = await SendRequestAsync<TLAuthorization>(importAuthorization);
|
||||
OnUserAuthenticated(((TLUser)imported.User));
|
||||
}
|
||||
}
|
||||
|
||||
private async Task RequestWithDcMigration(TLMethod request)
|
||||
{
|
||||
private async Task RequestWithDcMigration(TLMethod request)
|
||||
{
|
||||
if (_sender == null)
|
||||
throw new InvalidOperationException("Not connected!");
|
||||
|
||||
var completed = false;
|
||||
while(!completed)
|
||||
{
|
||||
|
|
@ -126,7 +126,7 @@ namespace TLSharp.Core
|
|||
// prepare the request for another try
|
||||
request.ConfirmReceived = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsUserAuthorized()
|
||||
|
|
@ -139,9 +139,6 @@ namespace TLSharp.Core
|
|||
if (String.IsNullOrWhiteSpace(phoneNumber))
|
||||
throw new ArgumentNullException(nameof(phoneNumber));
|
||||
|
||||
if (_sender == null)
|
||||
throw new InvalidOperationException("Not connected!");
|
||||
|
||||
var authCheckPhoneRequest = new TLRequestCheckPhone() { PhoneNumber = phoneNumber };
|
||||
|
||||
await RequestWithDcMigration(authCheckPhoneRequest);
|
||||
|
|
@ -172,8 +169,8 @@ namespace TLSharp.Core
|
|||
if (String.IsNullOrWhiteSpace(code))
|
||||
throw new ArgumentNullException(nameof(code));
|
||||
|
||||
var request = new TLRequestSignIn() { PhoneNumber = phoneNumber, PhoneCodeHash = phoneCodeHash, PhoneCode = code };
|
||||
|
||||
var request = new TLRequestSignIn() { PhoneNumber = phoneNumber, PhoneCodeHash = phoneCodeHash, PhoneCode = code };
|
||||
|
||||
await RequestWithDcMigration(request);
|
||||
|
||||
OnUserAuthenticated(((TLUser)request.Response.User));
|
||||
|
|
@ -314,21 +311,21 @@ namespace TLSharp.Core
|
|||
public async Task SendPingAsync()
|
||||
{
|
||||
await _sender.SendPingAsync();
|
||||
}
|
||||
|
||||
public async Task<TLAbsMessages> GetHistoryAsync(TLAbsInputPeer peer, int offset, int max_id, int limit)
|
||||
{
|
||||
if (!IsUserAuthorized())
|
||||
throw new InvalidOperationException("Authorize user first!");
|
||||
|
||||
var req = new TLRequestGetHistory()
|
||||
{
|
||||
Peer = peer,
|
||||
AddOffset = offset,
|
||||
MaxId = max_id,
|
||||
Limit = limit
|
||||
};
|
||||
return await SendRequestAsync<TLAbsMessages>(req);
|
||||
}
|
||||
|
||||
public async Task<TLAbsMessages> GetHistoryAsync(TLAbsInputPeer peer, int offset, int max_id, int limit)
|
||||
{
|
||||
if (!IsUserAuthorized())
|
||||
throw new InvalidOperationException("Authorize user first!");
|
||||
|
||||
var req = new TLRequestGetHistory()
|
||||
{
|
||||
Peer = peer,
|
||||
AddOffset = offset,
|
||||
MaxId = max_id,
|
||||
Limit = limit
|
||||
};
|
||||
return await SendRequestAsync<TLAbsMessages>(req);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -354,18 +351,18 @@ namespace TLSharp.Core
|
|||
_session.SessionExpires = int.MaxValue;
|
||||
|
||||
_session.Save();
|
||||
}
|
||||
|
||||
public bool IsConnected
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_transport == null)
|
||||
return false;
|
||||
return _transport.IsConnected;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public bool IsConnected
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_transport == null)
|
||||
return false;
|
||||
return _transport.IsConnected;
|
||||
}
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_transport != null)
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ namespace TeleSharp.TL
|
|||
{
|
||||
private static Dictionary<int, Type> Types;
|
||||
|
||||
public static void Init()
|
||||
static TLContext()
|
||||
{
|
||||
Types = new Dictionary<int, Type>();
|
||||
Types = (from t in Assembly.GetExecutingAssembly().GetTypes()
|
||||
|
|
@ -22,6 +22,7 @@ namespace TeleSharp.TL
|
|||
select t).ToDictionary(x => ((TLObjectAttribute)x.GetCustomAttribute(typeof(TLObjectAttribute))).Constructor, x => x);
|
||||
Types[481674261] = typeof(TLVector<>);
|
||||
}
|
||||
|
||||
public static Type getType(int Constructor)
|
||||
{
|
||||
return Types[Constructor];
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ namespace TeleSharp.TL
|
|||
Serialize(bw);
|
||||
bw.Close();
|
||||
m.Close();
|
||||
return m.GetBuffer();
|
||||
return m.ToArray();
|
||||
}
|
||||
}
|
||||
public void Serialize(BinaryWriter writer)
|
||||
|
|
|
|||
Loading…
Reference in a new issue