diff --git a/README.md b/README.md
index 8cdba23..54691f8 100644
--- a/README.md
+++ b/README.md
@@ -1,19 +1,21 @@
#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
-**Consider donation to speed up development process.**
-
-Bitcoin wallet: **3K1ocweFgaHnAibJ3n6hX7RNZWFTFcJjUe**
-
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:
+If you have difficulties with library usage, I can support you ( 75$/hour ). Contact me at @sochix.
+
+If you have difficulties with console or writing code, you can try [Telegram Tools](https://github.com/sochix/telegram-tools). It's a GUI for TLSharp.
+
# Table of contents?
- [How do I add this to my project?](#how-do-i-add-this-to-my-project)
@@ -161,6 +163,7 @@ For your convenience TLSharp have wrappers for several Telegram API methods. You
1. GetFile
1. UploadFile
1. SendPingAsync
+1. GetHistoryAsync
**What if you can't find needed method at the list?**
@@ -186,7 +189,7 @@ Latest scheme in JSON format you can find [here](https://gist.github.com/aarani/
# Contributing
-Contributing is highly appreciated!
+Contributing is highly appreciated! Donations required
## What things can I Implement (Project Roadmap)?
@@ -232,7 +235,7 @@ Without information listen above your issue will be closed.
# Donations
Thanks for donations! It's highly appreciated.
-Bitcoin wallet: **3K1ocweFgaHnAibJ3n6hX7RNZWFTFcJjUe**
+
List of donators:
* [mtbitcoin](https://github.com/mtbitcoin)
diff --git a/TLSharp.Core/Network/TcpTransport.cs b/TLSharp.Core/Network/TcpTransport.cs
index 9092828..254153e 100644
--- a/TLSharp.Core/Network/TcpTransport.cs
+++ b/TLSharp.Core/Network/TcpTransport.cs
@@ -1,22 +1,28 @@
using System;
-using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Threading.Tasks;
namespace TLSharp.Core.Network
{
+ public delegate TcpClient TcpClientConnectionHandler(string address, int port);
+
public class TcpTransport : IDisposable
{
private readonly TcpClient _tcpClient;
private int sendCounter = 0;
- public TcpTransport(string address, int port)
+ public TcpTransport(string address, int port, TcpClientConnectionHandler handler = null)
{
- _tcpClient = new TcpClient();
+ if (handler == null)
+ {
+ _tcpClient = new TcpClient();
- var ipAddress = IPAddress.Parse(address);
- _tcpClient.Connect(ipAddress, port);
+ var ipAddress = IPAddress.Parse(address);
+ _tcpClient.Connect(ipAddress, port);
+ }
+ else
+ _tcpClient = handler(address, port);
}
public async Task Send(byte[] packet)
@@ -84,6 +90,6 @@ namespace TLSharp.Core.Network
{
if (_tcpClient.Connected)
_tcpClient.Close();
- }
+ }
}
}
diff --git a/TLSharp.Core/TelegramClient.cs b/TLSharp.Core/TelegramClient.cs
index 7cf7e5d..a4fa06a 100644
--- a/TLSharp.Core/TelegramClient.cs
+++ b/TLSharp.Core/TelegramClient.cs
@@ -4,7 +4,6 @@ using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
-using System.Web;
using TeleSharp.TL;
using TeleSharp.TL.Account;
using TeleSharp.TL.Auth;
@@ -15,7 +14,6 @@ using TeleSharp.TL.Upload;
using TLSharp.Core.Auth;
using TLSharp.Core.MTProto.Crypto;
using TLSharp.Core.Network;
-using TLSharp.Core.Requests;
using TLSharp.Core.Utils;
using TLAuthorization = TeleSharp.TL.Auth.TLAuthorization;
@@ -30,8 +28,10 @@ namespace TLSharp.Core
private int _apiId = 0;
private Session _session;
private List dcOptions;
+ private TcpClientConnectionHandler _handler;
- public TelegramClient(int apiId, string apiHash, ISessionStore store = null, string sessionUserId = "session")
+ public TelegramClient(int apiId, string apiHash,
+ ISessionStore store = null, string sessionUserId = "session", TcpClientConnectionHandler handler = null)
{
if (apiId == default(int))
throw new MissingApiConfigurationException("API_ID");
@@ -44,9 +44,10 @@ namespace TLSharp.Core
TLContext.Init();
_apiHash = apiHash;
_apiId = apiId;
+ _handler = handler;
_session = Session.TryLoadOrCreateNew(store, sessionUserId);
- _transport = new TcpTransport(_session.ServerAddress, _session.Port);
+ _transport = new TcpTransport(_session.ServerAddress, _session.Port, _handler);
}
public async Task ConnectAsync(bool reconnect = false)
@@ -87,7 +88,7 @@ namespace TLSharp.Core
var dc = dcOptions.First(d => d.id == dcId);
- _transport = new TcpTransport(dc.ip_address, dc.port);
+ _transport = new TcpTransport(dc.ip_address, dc.port, _handler);
_session.ServerAddress = dc.ip_address;
_session.Port = dc.port;
@@ -292,7 +293,7 @@ namespace TLSharp.Core
});
}
- public async Task GetFile(TLAbsInputFileLocation location, int filePartSize)
+ public async Task GetFile(TLAbsInputFileLocation location, int filePartSize, int offset = 0)
{
TLFile result = null;
try
@@ -300,7 +301,8 @@ namespace TLSharp.Core
result = await SendRequestAsync(new TLRequestGetFile()
{
location = location,
- limit = filePartSize
+ limit = filePartSize,
+ offset = offset
});
}
catch (FileMigrationException ex)
@@ -318,7 +320,7 @@ namespace TLSharp.Core
bytes = exportedAuth.bytes,
id = exportedAuth.id
});
- result = await GetFile(location, filePartSize);
+ result = await GetFile(location, filePartSize, offset);
_session.AuthKey = authKey;
_session.TimeOffset = timeOffset;
@@ -335,6 +337,38 @@ namespace TLSharp.Core
public async Task SendPingAsync()
{
await _sender.SendPingAsync();
+ }
+
+ public async Task GetHistoryAsync(TLAbsInputPeer peer, int offset, int max_id, int limit)
+ {
+ if (!IsUserAuthorized())
+ throw new InvalidOperationException("Authorize user first!");
+
+ var req = new TLRequestGetHistory()
+ {
+ peer = peer,
+ add_offset = offset,
+ max_id = max_id,
+ limit = limit
+ };
+ return await SendRequestAsync(req);
+ }
+
+ ///
+ /// Serch user or chat. API: contacts.search#11f812d8 q:string limit:int = contacts.Found;
+ ///
+ /// User or chat name
+ /// Max result count
+ ///
+ public async Task SearchUserAsync(string q, int limit = 10)
+ {
+ var r = new TeleSharp.TL.Contacts.TLRequestSearch
+ {
+ q = q,
+ limit = limit
+ };
+
+ return await SendRequestAsync(r);
}
private void OnUserAuthenticated(TLUser TLUser)
diff --git a/TLSharp.Tests.NUnit/Test.cs b/TLSharp.Tests.NUnit/Test.cs
index 7c390db..40e54ac 100644
--- a/TLSharp.Tests.NUnit/Test.cs
+++ b/TLSharp.Tests.NUnit/Test.cs
@@ -75,5 +75,11 @@ namespace TLSharp.Tests
{
await base.FloodExceptionShouldNotCauseCannotReadPackageLengthError();
}
+
+ [Test]
+ public override async Task SendMessageByUserNameTest()
+ {
+ await base.SendMessageByUserNameTest();
+ }
}
}
diff --git a/TLSharp.Tests.VS/TLSharpTestsVs.cs b/TLSharp.Tests.VS/TLSharpTestsVs.cs
index fff25b6..8f6c58d 100644
--- a/TLSharp.Tests.VS/TLSharpTestsVs.cs
+++ b/TLSharp.Tests.VS/TLSharpTestsVs.cs
@@ -73,5 +73,11 @@ namespace TLSharp.Tests
{
await base.FloodExceptionShouldNotCauseCannotReadPackageLengthError();
}
+
+ [TestMethod]
+ public override async Task SendMessageByUserNameTest()
+ {
+ await base.SendMessageByUserNameTest();
+ }
}
}
diff --git a/TLSharp.Tests/TLSharpTests.cs b/TLSharp.Tests/TLSharpTests.cs
index 6166067..487b535 100644
--- a/TLSharp.Tests/TLSharpTests.cs
+++ b/TLSharp.Tests/TLSharpTests.cs
@@ -323,6 +323,7 @@ namespace TLSharp.Tests
var result = await client.IsPhoneRegisteredAsync(NumberToAuthenticate);
Assert.IsTrue(result);
}
+
public virtual async Task FloodExceptionShouldNotCauseCannotReadPackageLengthError()
{
for (int i = 0; i < 50; i++)
@@ -338,5 +339,42 @@ namespace TLSharp.Tests
}
}
}
+
+ public virtual async Task SendMessageByUserNameTest()
+ {
+ UserNameToSendMessage = ConfigurationManager.AppSettings[nameof(UserNameToSendMessage)];
+ if (string.IsNullOrWhiteSpace(UserNameToSendMessage))
+ throw new Exception($"Please fill the '{nameof(UserNameToSendMessage)}' setting in app.config file first");
+
+ var client = NewClient();
+
+ await client.ConnectAsync();
+
+ var result = await client.SearchUserAsync(UserNameToSendMessage);
+
+ var user = result.users.lists
+ .Where(x => x.GetType() == typeof(TLUser))
+ .OfType()
+ .FirstOrDefault(x => x.username == UserNameToSendMessage.TrimStart('@'));
+
+ if (user == null)
+ {
+ var contacts = await client.GetContactsAsync();
+
+ user = contacts.users.lists
+ .Where(x => x.GetType() == typeof(TLUser))
+ .OfType()
+ .FirstOrDefault(x => x.username == UserNameToSendMessage.TrimStart('@'));
+ }
+
+ if (user == null)
+ {
+ throw new System.Exception("Username was not found: " + UserNameToSendMessage);
+ }
+
+ await client.SendTypingAsync(new TLInputPeerUser() { user_id = user.id });
+ Thread.Sleep(3000);
+ await client.SendMessageAsync(new TLInputPeerUser() { user_id = user.id }, "TEST");
+ }
}
}