From b129e655f8182d4b39b59939aeffa5adbe618dd5 Mon Sep 17 00:00:00 2001 From: "Andres G. Aragoneses" Date: Fri, 21 Oct 2016 23:43:53 +0800 Subject: [PATCH 01/15] build: switch to lower framework version (4.5.2 -> 4.5) This change is good because: a) It's better to target a lower target framework version if the project doesn't necessarily depend on the new features of the newer versions (so, bigger target audience). b) It lets compile the project with implementations of the .NET Framework that are not compatible with 4.5.2. For example, after this change I can successfully build TLSharp with the Mono v4.2.1 that comes in my Ubuntu Linux 16.04.1. --- README.md | 2 +- TLSharp.Core/TLSharp.Core.csproj | 2 +- TeleSharp.Generator/TeleSharp.Generator.csproj | 2 +- TeleSharp.TL/TeleSharp.TL.csproj | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 4b68f9f..b47b54d 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ Library _almost_ ready for production usage. We need contributors to make 1.0.0 To use TLSharp follow next steps: 1. Clone TLSharp from GitHub -1. Compile source with VS2015 +1. Compile source with VS2015 or MonoDevelop 1. Add reference to ```TLSharp.Core.dll``` to your awesome project. # Dependencies diff --git a/TLSharp.Core/TLSharp.Core.csproj b/TLSharp.Core/TLSharp.Core.csproj index de604d1..792a7bb 100644 --- a/TLSharp.Core/TLSharp.Core.csproj +++ b/TLSharp.Core/TLSharp.Core.csproj @@ -9,7 +9,7 @@ Properties TLSharp.Core TLSharp.Core - v4.5.2 + v4.5 512 diff --git a/TeleSharp.Generator/TeleSharp.Generator.csproj b/TeleSharp.Generator/TeleSharp.Generator.csproj index c386fa6..94f3e9b 100644 --- a/TeleSharp.Generator/TeleSharp.Generator.csproj +++ b/TeleSharp.Generator/TeleSharp.Generator.csproj @@ -9,7 +9,7 @@ Properties TeleSharp.Generator TeleSharp.Generator - v4.5.2 + v4.5 512 true diff --git a/TeleSharp.TL/TeleSharp.TL.csproj b/TeleSharp.TL/TeleSharp.TL.csproj index 46e2a18..a6da831 100644 --- a/TeleSharp.TL/TeleSharp.TL.csproj +++ b/TeleSharp.TL/TeleSharp.TL.csproj @@ -9,7 +9,7 @@ Properties TeleSharp.TL TeleSharp.TL - v4.5.2 + v4.5 512 From 77867b44e626aedfba58cf9729100e3cc1a808a8 Mon Sep 17 00:00:00 2001 From: "Andres G. Aragoneses" Date: Sat, 22 Oct 2016 22:00:15 +0800 Subject: [PATCH 02/15] Use better exception handling Parsing the message of an exception to decide what to do next is a bad practice, because it's easy that the message might be changed by mistake in the future. To enforce the coupling in a stronger way it's better to use exceptions of different type depending on the kind of error, so that we rely on the compiler enforcing the behaviour when doing changes in this error handling areas in the future. This also makes the code a bit more simple and readable. --- TLSharp.Core/Network/MtProtoSender.cs | 15 ++++++++++++--- TLSharp.Core/TelegramClient.cs | 11 ++--------- 2 files changed, 14 insertions(+), 12 deletions(-) diff --git a/TLSharp.Core/Network/MtProtoSender.cs b/TLSharp.Core/Network/MtProtoSender.cs index f7c4ef2..2d8babf 100644 --- a/TLSharp.Core/Network/MtProtoSender.cs +++ b/TLSharp.Core/Network/MtProtoSender.cs @@ -279,9 +279,7 @@ namespace TLSharp.Core.Network { var resultString = Regex.Match(errorMessage, @"\d+").Value; var dcIdx = int.Parse(resultString); - var exception = new InvalidOperationException($"Your phone number registered to {dcIdx} dc. Please update settings. See https://github.com/sochix/TLSharp#i-get-an-error-migrate_x for details."); - exception.Data.Add("dcId", dcIdx); - throw exception; + throw new MigrationNeededException(dcIdx); } else { @@ -484,4 +482,15 @@ namespace TLSharp.Core.Network return new MemoryStream(new byte[len], 0, len, true, true); } } + + internal class MigrationNeededException : Exception + { + internal int DC { get; private set; } + + internal MigrationNeededException(int dc) + : base ("$Your phone number is registered to a different dc: {dc}. Please migrate.") + { + DC = dc; + } + } } \ No newline at end of file diff --git a/TLSharp.Core/TelegramClient.cs b/TLSharp.Core/TelegramClient.cs index 75d0466..40eefaf 100644 --- a/TLSharp.Core/TelegramClient.cs +++ b/TLSharp.Core/TelegramClient.cs @@ -110,16 +110,9 @@ namespace TLSharp.Core completed = true; } - catch (InvalidOperationException ex) + catch (MigrationNeededException ex) { - if (ex.Message.StartsWith("Your phone number registered to") && ex.Data["dcId"] != null) - { - await ReconnectToDcAsync((int)ex.Data["dcId"]); - } - else - { - throw; - } + await ReconnectToDcAsync(ex.DC); } } From 6c541647261fa396e0313ce4e34260b74309e519 Mon Sep 17 00:00:00 2001 From: Ilya Pirozhenko Date: Sun, 23 Oct 2016 10:59:20 +0300 Subject: [PATCH 03/15] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 9f255c2..8afdbc7 100644 --- a/README.md +++ b/README.md @@ -194,6 +194,7 @@ List of donators: # Contributors * [Afshin Arani](http://aarani.ir) - TLGenerator, and a lot of other usefull things +* [Knocte](https://github.com/knocte) # License From 7fd0413c7ea37d43bf85ee107cd7fcdbfdb3891f Mon Sep 17 00:00:00 2001 From: Ilya P Date: Sun, 23 Oct 2016 11:17:59 +0300 Subject: [PATCH 04/15] - removed non-generic TLVector - write length of Vector during Serialization --- TLSharp.Core/Network/MtProtoSender.cs | 4 +-- TeleSharp.TL/TL/TLVector.cs | 39 --------------------------- TeleSharp.TL/TLVector.cs | 2 ++ TeleSharp.TL/TeleSharp.TL.csproj | 1 - 4 files changed, 4 insertions(+), 42 deletions(-) delete mode 100644 TeleSharp.TL/TL/TLVector.cs diff --git a/TLSharp.Core/Network/MtProtoSender.cs b/TLSharp.Core/Network/MtProtoSender.cs index 2d8babf..4cf59a8 100644 --- a/TLSharp.Core/Network/MtProtoSender.cs +++ b/TLSharp.Core/Network/MtProtoSender.cs @@ -336,9 +336,9 @@ namespace TLSharp.Core.Network switch (errorCode) { case 16: - throw new InvalidOperationException(" msg_id too low (most likely, client time is wrong; it would be worthwhile to synchronize it using msg_id notifications and re-send the original message with the “correct” msg_id or wrap it in a container with a new msg_id if the original message had waited too long on the client to be transmitted)"); + throw new InvalidOperationException("msg_id too low (most likely, client time is wrong; it would be worthwhile to synchronize it using msg_id notifications and re-send the original message with the “correct” msg_id or wrap it in a container with a new msg_id if the original message had waited too long on the client to be transmitted)"); case 17: - throw new InvalidOperationException(" msg_id too high (similar to the previous case, the client time has to be synchronized, and the message re-sent with the correct msg_id)"); + throw new InvalidOperationException("msg_id too high (similar to the previous case, the client time has to be synchronized, and the message re-sent with the correct msg_id)"); case 18: throw new InvalidOperationException("incorrect two lower order msg_id bits (the server expects client message msg_id to be divisible by 4)"); case 19: diff --git a/TeleSharp.TL/TL/TLVector.cs b/TeleSharp.TL/TL/TLVector.cs deleted file mode 100644 index 562ceb0..0000000 --- a/TeleSharp.TL/TL/TLVector.cs +++ /dev/null @@ -1,39 +0,0 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using TeleSharp.TL; -namespace TeleSharp.TL -{ - [TLObject(481674261)] - public class TLVector : TLObject - { - public override int Constructor - { - get - { - return 481674261; - } - } - - - - public void ComputeFlags() - { - - } - - public override void DeserializeBody(BinaryReader br) - { - - } - - public override void SerializeBody(BinaryWriter bw) - { - bw.Write(Constructor); - - } - } -} diff --git a/TeleSharp.TL/TLVector.cs b/TeleSharp.TL/TLVector.cs index 6c34270..8f35b7d 100644 --- a/TeleSharp.TL/TLVector.cs +++ b/TeleSharp.TL/TLVector.cs @@ -54,6 +54,8 @@ namespace TeleSharp.TL public override void SerializeBody(BinaryWriter bw) { bw.Write(Constructor); + bw.Write(lists.Count()); + foreach (var item in lists.Cast()) { item.SerializeBody(bw); diff --git a/TeleSharp.TL/TeleSharp.TL.csproj b/TeleSharp.TL/TeleSharp.TL.csproj index 446410d..65252c2 100644 --- a/TeleSharp.TL/TeleSharp.TL.csproj +++ b/TeleSharp.TL/TeleSharp.TL.csproj @@ -758,7 +758,6 @@ - From d96daec6d177f0108808eae4600333cd88b8f192 Mon Sep 17 00:00:00 2001 From: "Andres G. Aragoneses" Date: Sun, 23 Oct 2016 17:00:52 +0800 Subject: [PATCH 05/15] Tests: remove unneeded usings --- TLSharp.Tests/TLSharpTests.cs | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/TLSharp.Tests/TLSharpTests.cs b/TLSharp.Tests/TLSharpTests.cs index 59607e4..4d02beb 100644 --- a/TLSharp.Tests/TLSharpTests.cs +++ b/TLSharp.Tests/TLSharpTests.cs @@ -1,20 +1,14 @@ -using System; -using System.Collections.Generic; + using System.Configuration; using System.Diagnostics; -using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; + using Microsoft.VisualStudio.TestTools.UnitTesting; + using TeleSharp.TL; -using TeleSharp.TL.Channels; -using TeleSharp.TL.Contacts; -using TeleSharp.TL.Messages; using TLSharp.Core; -using TLSharp.Core.Auth; -using TLSharp.Core.MTProto; -using TLSharp.Core.Network; namespace TLSharp.Tests { From 1d6035aeb7ba7060ece2a14a5aa524fa69715160 Mon Sep 17 00:00:00 2001 From: Ilya P Date: Sun, 23 Oct 2016 13:02:44 +0300 Subject: [PATCH 06/15] - fix file Uploader - refactor file uploader - added test for file uploading --- TLSharp.Core/Requests/UploadHelper.cs | 214 ++++++++++++++------------ TLSharp.Core/TelegramClient.cs | 48 +++++- TLSharp.Tests/TLSharp.Tests.csproj | 7 +- TLSharp.Tests/TLSharpTests.cs | 50 +++++- 4 files changed, 213 insertions(+), 106 deletions(-) diff --git a/TLSharp.Core/Requests/UploadHelper.cs b/TLSharp.Core/Requests/UploadHelper.cs index 5397e67..f7d14fe 100644 --- a/TLSharp.Core/Requests/UploadHelper.cs +++ b/TLSharp.Core/Requests/UploadHelper.cs @@ -7,112 +7,130 @@ using System.Text; using System.Threading.Tasks; using TeleSharp.TL; using TeleSharp.TL.Upload; +using TLSharp.Core.Utils; + namespace TLSharp.Core.Requests { - public class UploadHelper + public static class UploadHelper { - public static async Task Uploader(string name,StreamReader reader,TelegramClient client) + private static string GetFileHash(byte[] data) { - if (reader.BaseStream.Length < 10 * 1024 * 1024) - return await SmallFileUpload(name, reader, client); + string md5_checksum; + using (var md5 = MD5.Create()) + { + var hash = md5.ComputeHash(data); + var hashResult = new StringBuilder(hash.Length * 2); + + foreach (byte t in hash) + hashResult.Append(t.ToString("x2")); + + md5_checksum = hashResult.ToString(); + } + + return md5_checksum; + } + + public static async Task UploadFile(this TelegramClient client, string name, StreamReader reader) + { + const long tenMb = 10 * 1024 * 1024; + return await UploadFile(name, reader, client, reader.BaseStream.Length >= tenMb); + } + + private static byte[] GetFile(StreamReader reader) + { + var file = new byte[reader.BaseStream.Length]; + + using (reader) + { + reader.BaseStream.Read(file, 0, (int)reader.BaseStream.Length); + } + + return file; + } + + private static Queue GetFileParts(byte[] file) + { + var fileParts = new Queue(); + + const int maxFilePart = 512 * 1024; + + using (var stream = new MemoryStream(file)) + { + while (stream.Position != stream.Length) + { + if ((stream.Length - stream.Position) > maxFilePart) + { + var temp = new byte[maxFilePart]; + stream.Read(temp, 0, maxFilePart); + fileParts.Enqueue(temp); + } + else + { + var length = stream.Length - stream.Position; + var temp = new byte[length]; + stream.Read(temp, 0, (int)(length)); + fileParts.Enqueue(temp); + } + } + } + + return fileParts; + } + + private static async Task UploadFile(string name, StreamReader reader, + TelegramClient client, bool isBigFileUpload) + { + var file = GetFile(reader); + var fileParts = GetFileParts(file); + + int partNumber = 0; + int partsCount = fileParts.Count; + long file_id = BitConverter.ToInt64(Helpers.GenerateRandomBytes(8), 0); + while (fileParts.Count != 0) + { + var part = fileParts.Dequeue(); + + if (isBigFileUpload) + { + await client.SendRequestAsync(new TLRequestSaveBigFilePart + { + file_id = file_id, + file_part = partNumber, + bytes = part, + file_total_parts = partsCount + }); + } + else + { + await client.SendRequestAsync(new TLRequestSaveFilePart + { + file_id = file_id, + file_part = partNumber, + bytes = part + }); + } + partNumber++; + } + + if (isBigFileUpload) + { + return new TLInputFileBig + { + id = file_id, + name = name, + parts = partsCount + }; + } else - return await BigFileUpload(name, reader, client); - } - private static async Task SmallFileUpload(string name, StreamReader reader, TelegramClient client) - { - var file = new byte[reader.BaseStream.Length]; - reader.BaseStream.Read(file, 0, (int)reader.BaseStream.Length); - string hash; - using (MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider()) { - hash = Convert.ToBase64String(md5.ComputeHash(file)); - } - reader = null; - var stream = new MemoryStream(file); - Queue parts = new Queue(); - while (!(stream.Position == stream.Length)) - { - if ((stream.Length - stream.Position) > 512 *1024) + return new TLInputFile { - byte[] temp = new byte[512]; - stream.Read(temp, 0, 512 * 1024); - parts.Enqueue(temp); - } - else - { - byte[] temp = new byte[512]; - stream.Read(temp, 0, (int)(stream.Length - stream.Position)); - parts.Enqueue(temp); - } + id = file_id, + name = name, + parts = partsCount, + md5_checksum = GetFileHash(file) + }; } - stream = null; - int partnumber = 0; - long file_id = BitConverter.ToInt64(RandomByteArray(8), 0); - while (parts.Count != 0) - { - var part = parts.Dequeue(); - TLRequestSaveFilePart save = new TLRequestSaveFilePart(); - save.file_id = file_id; - save.file_part = partnumber; - save.bytes = part; - await client.SendRequestAsync(save); - partnumber++; - } - TLInputFile returnFile = new TLInputFile(); - returnFile.id = file_id; - returnFile.name = name; - returnFile.parts = parts.Count; - returnFile.md5_checksum = hash; - return returnFile; - } - private static async Task BigFileUpload(string name, StreamReader reader, TelegramClient client) - { - var file = new byte[reader.BaseStream.Length]; - reader.BaseStream.Read(file, 0, (int)reader.BaseStream.Length); - reader = null; - var stream = new MemoryStream(file); - Queue parts = new Queue(); - while (!(stream.Position == stream.Length)) - { - if ((stream.Length - stream.Position) > 512 * 1024) - { - byte[] temp = new byte[512]; - stream.Read(temp, 0, 512 * 1024); - parts.Enqueue(temp); - } - else - { - byte[] temp = new byte[512]; - stream.Read(temp, 0, (int)(stream.Length - stream.Position)); - parts.Enqueue(temp); - } - } - stream = null; - int partnumber = 0; - long file_id = BitConverter.ToInt64(RandomByteArray(8), 0); - while (parts.Count != 0) - { - var part = parts.Dequeue(); - TLRequestSaveBigFilePart save = new TLRequestSaveBigFilePart(); - save.file_id = file_id; - save.file_part = partnumber; - save.bytes = part; - save.file_total_parts = parts.Count; - await client.SendRequestAsync(save); - partnumber++; - } - TLInputFileBig returnFile = new TLInputFileBig(); - returnFile.id = file_id; - returnFile.name = name; - returnFile.parts = parts.Count; - return returnFile; - } - private static byte[] RandomByteArray(int count) - { - var temp = new byte[count]; - Random random = new Random(); - random.NextBytes(temp); - return temp; } } } diff --git a/TLSharp.Core/TelegramClient.cs b/TLSharp.Core/TelegramClient.cs index 40eefaf..587c679 100644 --- a/TLSharp.Core/TelegramClient.cs +++ b/TLSharp.Core/TelegramClient.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; +using System.Web; using TeleSharp.TL; using TeleSharp.TL.Auth; using TeleSharp.TL.Contacts; @@ -10,6 +11,8 @@ using TeleSharp.TL.Messages; using TLSharp.Core.Auth; using TLSharp.Core.MTProto.Crypto; using TLSharp.Core.Network; +using TLSharp.Core.Requests; +using TLSharp.Core.Utils; namespace TLSharp.Core { @@ -53,7 +56,15 @@ namespace TLSharp.Core //set-up layer var config = new TLRequestGetConfig(); - var request = new TLRequestInitConnection() { api_id = _apiId, app_version = "1.0.0", device_model = "PC", lang_code = "en", query = config, system_version = "Win 10.0" }; + var request = new TLRequestInitConnection() + { + api_id = _apiId, + app_version = "1.0.0", + device_model = "PC", + lang_code = "en", + query = config, + system_version = "Win 10.0" + }; var invokewithLayer = new TLRequestInvokeWithLayer() { layer = 57, query = request }; await _sender.Send(invokewithLayer); await _sender.Receive(invokewithLayer); @@ -165,14 +176,12 @@ namespace TLSharp.Core if (!IsUserAuthorized()) throw new InvalidOperationException("Authorize user first!"); - long uniqueId = Convert.ToInt64((DateTime.UtcNow - new DateTime(1970, 1, 1)).TotalMilliseconds); - return await SendRequestAsync( new TLRequestSendMessage() { peer = peer, message = message, - random_id = uniqueId + random_id = Helpers.GenerateRandomLong() }); } @@ -193,6 +202,37 @@ namespace TLSharp.Core new TLRequestGetDialogs() { offset_date = 0, offset_peer = peer, limit = 100 }); } + public async Task SendUploadedPhoto(TLAbsInputPeer peer, TLAbsInputFile file, string caption) + { + return await SendRequestAsync(new TLRequestSendMedia() + { + random_id = Helpers.GenerateRandomLong(), + background = false, + clear_draft = false, + media = new TLInputMediaUploadedPhoto() { file = file, caption = caption }, + peer = peer + }); + } + + public async Task SendUploadedDocument( + TLAbsInputPeer peer, TLAbsInputFile file, string caption, string mimeType, TLVector attributes) + { + return await SendRequestAsync(new TLRequestSendMedia() + { + random_id = Helpers.GenerateRandomLong(), + background = false, + clear_draft = false, + media = new TLInputMediaUploadedDocument() + { + file = file, + caption = caption, + mime_type = mimeType, + attributes = attributes + }, + peer = peer + }); + } + private void OnUserAuthenticated(TLUser TLUser) { _session.TLUser = TLUser; diff --git a/TLSharp.Tests/TLSharp.Tests.csproj b/TLSharp.Tests/TLSharp.Tests.csproj index a30c84a..f215a0c 100644 --- a/TLSharp.Tests/TLSharp.Tests.csproj +++ b/TLSharp.Tests/TLSharp.Tests.csproj @@ -1,4 +1,4 @@ - + Debug @@ -68,6 +68,11 @@ TLSharp.Core + + + Always + + diff --git a/TLSharp.Tests/TLSharpTests.cs b/TLSharp.Tests/TLSharpTests.cs index 59607e4..00f1cc7 100644 --- a/TLSharp.Tests/TLSharpTests.cs +++ b/TLSharp.Tests/TLSharpTests.cs @@ -6,6 +6,7 @@ using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; +using System.Web; using Microsoft.VisualStudio.TestTools.UnitTesting; using TeleSharp.TL; using TeleSharp.TL.Channels; @@ -15,6 +16,8 @@ using TLSharp.Core; using TLSharp.Core.Auth; using TLSharp.Core.MTProto; using TLSharp.Core.Network; +using TLSharp.Core.Requests; +using TLSharp.Core.Utils; namespace TLSharp.Tests { @@ -37,7 +40,7 @@ namespace TLSharp.Tests private int apiId = 0; - [TestInitialize] + [TestInitialize] public void Init() { // Setup your phone numbers in app.config @@ -117,7 +120,49 @@ namespace TLSharp.Tests await client.SendMessageAsync(new TLInputPeerChannel() { channel_id = chat.id, access_hash = chat.access_hash.Value }, "TEST MSG"); } - [TestMethod] + [TestMethod] + public async Task SendPhotoToContactTest() + { + var client = new TelegramClient(apiId, apiHash); + + await client.ConnectAsync(); + + var result = await client.GetContactsAsync(); + + var user = result.users.lists + .Where(x => x.GetType() == typeof(TLUser)) + .Cast() + .FirstOrDefault(x => x.phone == NumberToSendMessage); + + var fileResult = (TLInputFile)await client.UploadFile("cat.jpg", new StreamReader("data/cat.jpg")); + await client.SendUploadedPhoto(new TLInputPeerUser() {user_id = user.id}, fileResult, "kitty"); + } + + [TestMethod] + public async Task SendBigFileToContactTest() + { + var client = new TelegramClient(apiId, apiHash); + + await client.ConnectAsync(); + + var result = await client.GetContactsAsync(); + + var user = result.users.lists + .Where(x => x.GetType() == typeof(TLUser)) + .Cast() + .FirstOrDefault(x => x.phone == NumberToSendMessage); + + var fileResult = (TLInputFileBig)await client.UploadFile("some.zip", new StreamReader("C:\\PetProjects\\TelegramBotSample.zip")); + + await client.SendUploadedDocument( + new TLInputPeerUser() {user_id = user.id}, + fileResult, + "some zips", + "application/zip", + new TLVector()); + } + + [TestMethod] public async Task SignUpNewUser() { var client = new TelegramClient(apiId, apiHash); @@ -143,6 +188,5 @@ namespace TLSharp.Tests var result = await client.IsPhoneRegisteredAsync(NumberToAuthenticate); Assert.IsTrue(result); } - } } From bbc84f074806a34d7f164eec672442d253b77dc4 Mon Sep 17 00:00:00 2001 From: "Andres G. Aragoneses" Date: Sun, 23 Oct 2016 18:11:26 +0800 Subject: [PATCH 07/15] Tests: put API settings also in app.config For these tests to pass you not only needed to change the app.config file but the .cs file as well with your API settings (Hash & ID). So let's put everything of them in the app.config so it's easier to discover. --- TLSharp.Tests/TLSharpTests.cs | 26 ++++++++++++++++++-------- TLSharp.Tests/app.config | 2 ++ 2 files changed, 20 insertions(+), 8 deletions(-) diff --git a/TLSharp.Tests/TLSharpTests.cs b/TLSharp.Tests/TLSharpTests.cs index 4d02beb..6c1d8d5 100644 --- a/TLSharp.Tests/TLSharpTests.cs +++ b/TLSharp.Tests/TLSharpTests.cs @@ -27,14 +27,24 @@ namespace TLSharp.Tests private string NumberToAddToChat { get; set; } - private string apiHash = null; + private string ApiHash { get; set; } - private int apiId = 0; + private int ApiId { get; set; } [TestInitialize] public void Init() { - // Setup your phone numbers in app.config + // Setup your API settings and phone numbers in app.config + + ApiHash = ConfigurationManager.AppSettings[nameof(ApiHash)]; + if (string.IsNullOrEmpty(ApiHash)) + Debug.WriteLine("ApiHash not configured in app.config! Some tests may fail."); + + var apiId = ConfigurationManager.AppSettings[nameof(ApiId)]; + if (string.IsNullOrEmpty(apiId)) + Debug.WriteLine("ApiId not configured in app.config! Some tests may fail."); + ApiId = int.Parse(apiId); + NumberToAuthenticate = ConfigurationManager.AppSettings[nameof(NumberToAuthenticate)]; if (string.IsNullOrEmpty(NumberToAuthenticate)) Debug.WriteLine("NumberToAuthenticate not configured in app.config! Some tests may fail."); @@ -63,7 +73,7 @@ namespace TLSharp.Tests [TestMethod] public async Task AuthUser() { - var client = new TelegramClient(apiId, apiHash); + var client = new TelegramClient(ApiId, ApiHash); await client.ConnectAsync(); @@ -79,7 +89,7 @@ namespace TLSharp.Tests [TestMethod] public async Task SendMessageTest() { - var client = new TelegramClient(apiId, apiHash); + var client = new TelegramClient(ApiId, ApiHash); await client.ConnectAsync(); @@ -98,7 +108,7 @@ namespace TLSharp.Tests [TestMethod] public async Task SendMessageToChannelTest() { - var client = new TelegramClient(apiId, apiHash); + var client = new TelegramClient(ApiId, ApiHash); await client.ConnectAsync(); @@ -114,7 +124,7 @@ namespace TLSharp.Tests [TestMethod] public async Task SignUpNewUser() { - var client = new TelegramClient(apiId, apiHash); + var client = new TelegramClient(ApiId, ApiHash); await client.ConnectAsync(); var hash = await client.SendCodeRequestAsync(NotRegisteredNumberToSignUp); @@ -131,7 +141,7 @@ namespace TLSharp.Tests [TestMethod] public async Task CheckPhones() { - var client = new TelegramClient(apiId, apiHash); + var client = new TelegramClient(ApiId, ApiHash); await client.ConnectAsync(); var result = await client.IsPhoneRegisteredAsync(NumberToAuthenticate); diff --git a/TLSharp.Tests/app.config b/TLSharp.Tests/app.config index 62aae65..6fc79b3 100644 --- a/TLSharp.Tests/app.config +++ b/TLSharp.Tests/app.config @@ -1,6 +1,8 @@  + + From f6ad50ce94e949d237f97ce0021df2de67f800cd Mon Sep 17 00:00:00 2001 From: Ilya P Date: Sun, 23 Oct 2016 13:29:18 +0300 Subject: [PATCH 08/15] - added getFile method --- TLSharp.Core/TelegramClient.cs | 10 ++++ TLSharp.Tests/TLSharpTests.cs | 104 +++++++++++++++++++++++---------- 2 files changed, 82 insertions(+), 32 deletions(-) diff --git a/TLSharp.Core/TelegramClient.cs b/TLSharp.Core/TelegramClient.cs index 587c679..c4aab25 100644 --- a/TLSharp.Core/TelegramClient.cs +++ b/TLSharp.Core/TelegramClient.cs @@ -8,6 +8,7 @@ using TeleSharp.TL.Auth; using TeleSharp.TL.Contacts; using TeleSharp.TL.Help; using TeleSharp.TL.Messages; +using TeleSharp.TL.Upload; using TLSharp.Core.Auth; using TLSharp.Core.MTProto.Crypto; using TLSharp.Core.Network; @@ -233,6 +234,15 @@ namespace TLSharp.Core }); } + public async Task GetFile(TLAbsInputFileLocation location, int filePartSize) + { + return await SendRequestAsync(new TLRequestGetFile() + { + location = location, + limit = filePartSize + }); + } + private void OnUserAuthenticated(TLUser TLUser) { _session.TLUser = TLUser; diff --git a/TLSharp.Tests/TLSharpTests.cs b/TLSharp.Tests/TLSharpTests.cs index 00f1cc7..c65ba68 100644 --- a/TLSharp.Tests/TLSharpTests.cs +++ b/TLSharp.Tests/TLSharpTests.cs @@ -12,6 +12,7 @@ using TeleSharp.TL; using TeleSharp.TL.Channels; using TeleSharp.TL.Contacts; using TeleSharp.TL.Messages; +using TeleSharp.TL.Upload; using TLSharp.Core; using TLSharp.Core.Auth; using TLSharp.Core.MTProto; @@ -40,7 +41,7 @@ namespace TLSharp.Tests private int apiId = 0; - [TestInitialize] + [TestInitialize] public void Init() { // Setup your phone numbers in app.config @@ -85,40 +86,40 @@ namespace TLSharp.Tests Assert.IsTrue(client.IsUserAuthorized()); } - [TestMethod] - public async Task SendMessageTest() - { - var client = new TelegramClient(apiId, apiHash); + [TestMethod] + public async Task SendMessageTest() + { + var client = new TelegramClient(apiId, apiHash); - await client.ConnectAsync(); + await client.ConnectAsync(); - var result = await client.GetContactsAsync(); + var result = await client.GetContactsAsync(); - var user = result.users.lists - .Where(x => x.GetType() == typeof (TLUser)) - .Cast() - .FirstOrDefault(x => x.phone == NumberToSendMessage); - await client.SendTypingAsync(new TLInputPeerUser() {user_id = user.id}); - Thread.Sleep(3000); - await client.SendMessageAsync(new TLInputPeerUser() {user_id = user.id}, "TEST"); - - } + var user = result.users.lists + .Where(x => x.GetType() == typeof(TLUser)) + .Cast() + .FirstOrDefault(x => x.phone == NumberToSendMessage); + await client.SendTypingAsync(new TLInputPeerUser() { user_id = user.id }); + Thread.Sleep(3000); + await client.SendMessageAsync(new TLInputPeerUser() { user_id = user.id }, "TEST"); - [TestMethod] - public async Task SendMessageToChannelTest() - { - var client = new TelegramClient(apiId, apiHash); + } - await client.ConnectAsync(); + [TestMethod] + public async Task SendMessageToChannelTest() + { + var client = new TelegramClient(apiId, apiHash); - var dialogs = await client.GetUserDialogsAsync(); - var chat = dialogs.chats.lists - .Where(c => c.GetType() == typeof(TLChannel)) - .Cast() - .FirstOrDefault(c => c.title == "TestGroup"); + await client.ConnectAsync(); - await client.SendMessageAsync(new TLInputPeerChannel() { channel_id = chat.id, access_hash = chat.access_hash.Value }, "TEST MSG"); - } + var dialogs = await client.GetUserDialogsAsync(); + var chat = dialogs.chats.lists + .Where(c => c.GetType() == typeof(TLChannel)) + .Cast() + .FirstOrDefault(c => c.title == "TestGroup"); + + await client.SendMessageAsync(new TLInputPeerChannel() { channel_id = chat.id, access_hash = chat.access_hash.Value }, "TEST MSG"); + } [TestMethod] public async Task SendPhotoToContactTest() @@ -135,7 +136,7 @@ namespace TLSharp.Tests .FirstOrDefault(x => x.phone == NumberToSendMessage); var fileResult = (TLInputFile)await client.UploadFile("cat.jpg", new StreamReader("data/cat.jpg")); - await client.SendUploadedPhoto(new TLInputPeerUser() {user_id = user.id}, fileResult, "kitty"); + await client.SendUploadedPhoto(new TLInputPeerUser() { user_id = user.id }, fileResult, "kitty"); } [TestMethod] @@ -152,14 +153,53 @@ namespace TLSharp.Tests .Cast() .FirstOrDefault(x => x.phone == NumberToSendMessage); - var fileResult = (TLInputFileBig)await client.UploadFile("some.zip", new StreamReader("C:\\PetProjects\\TelegramBotSample.zip")); + var fileResult = (TLInputFileBig)await client.UploadFile("some.zip", new StreamReader("")); await client.SendUploadedDocument( - new TLInputPeerUser() {user_id = user.id}, + new TLInputPeerUser() { user_id = user.id }, fileResult, "some zips", "application/zip", - new TLVector()); + new TLVector()); + } + + [TestMethod] + public async Task DownloadFileFromContactTest() + { + var client = new TelegramClient(apiId, apiHash); + + await client.ConnectAsync(); + + var result = await client.GetContactsAsync(); + + var user = result.users.lists + .Where(x => x.GetType() == typeof(TLUser)) + .Cast() + .FirstOrDefault(x => x.phone == NumberToSendMessage); + + var inputPeer = new TLInputPeerUser() { user_id = user.id }; + var res = await client.SendRequestAsync(new TLRequestGetHistory() { peer = inputPeer }); + var document = res.messages.lists + .Where(m => m.GetType() == typeof(TLMessage)) + .Cast() + .Where(m => m.media != null && m.media.GetType() == typeof(TLMessageMediaDocument)) + .Select(m => m.media) + .Cast() + .Where(md => md.document.GetType() == typeof(TLDocument)) + .Select(md => md.document) + .Cast() + .First(); + + var resFile = await client.GetFile( + new TLInputDocumentFileLocation() + { + access_hash = document.access_hash, + id = document.id, + version = document.version + }, + document.size); + + Assert.IsTrue(resFile.bytes.Length > 0); } [TestMethod] From 1719fd9f19f80a2f267abd68d70d102e7d58bf44 Mon Sep 17 00:00:00 2001 From: "Andres G. Aragoneses" Date: Sun, 23 Oct 2016 18:44:37 +0800 Subject: [PATCH 09/15] Tests: avoid NullReferenceException Instead of throwing cryptic NullReferenceException when this test fails, let's give more information about what is going on, to the developer. --- TLSharp.Tests/TLSharpTests.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/TLSharp.Tests/TLSharpTests.cs b/TLSharp.Tests/TLSharpTests.cs index c65ba68..ed03a6c 100644 --- a/TLSharp.Tests/TLSharpTests.cs +++ b/TLSharp.Tests/TLSharpTests.cs @@ -99,6 +99,12 @@ namespace TLSharp.Tests .Where(x => x.GetType() == typeof(TLUser)) .Cast() .FirstOrDefault(x => x.phone == NumberToSendMessage); + + if (user == null) + { + throw new System.Exception("Number was not found in Contacts List of user: " + NumberToSendMessage); + } + await client.SendTypingAsync(new TLInputPeerUser() { user_id = user.id }); Thread.Sleep(3000); await client.SendMessageAsync(new TLInputPeerUser() { user_id = user.id }, "TEST"); From b7f3da175665085bbf4b67c96e647187cf96c6aa Mon Sep 17 00:00:00 2001 From: Ilya Pirozhenko Date: Sun, 23 Oct 2016 13:46:28 +0300 Subject: [PATCH 10/15] Update README.md --- README.md | 49 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 8afdbc7..bc3ff4c 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,7 @@ It's a perfect fit for any developer who would like to send data directly to Tel - [Starter Guide](#starter-guide) - [Quick configuration](#quick-configuration) - [First requests](#first-requests) + - [Working with files](#working-with-files) - [Available Methods](#available-methods) - [Contributing](#contributing) - [FAQ](#faq) @@ -104,8 +105,41 @@ To send message to channel you could use the following code: await client.SendMessageAsync(new TLInputPeerChannel() { channel_id = chat.id, access_hash = chat.access_hash.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 +Telegram separate files to two categories -> big file and small file. File is Big if its size more than 10 Mb. TLSharp tries to hide this complexity from you, thats why we provide one method to upload files **UploadFile**. -## Available Methods +```csharp + var fileResult = await client.UploadFile("cat.jpg", new StreamReader("data/cat.jpg")); +``` + +TLSharp provides two wrappers for sending photo and document + +```csharp + await client.SendUploadedPhoto(new TLInputPeerUser() { user_id = user.id }, fileResult, "kitty"); + await client.SendUploadedDocument( + new TLInputPeerUser() { user_id = user.id }, + fileResult, + "some zips", //caption + "application/zip", //mime-type + new TLVector()); //document attributes, such as file name +``` +Full code you can see at [SendPhotoToContactTest](https://github.com/sochix/TLSharp/blob/master/TLSharp.Tests/TLSharpTests.cs#L125) and [SendBigFileToContactTest](https://github.com/sochix/TLSharp/blob/master/TLSharp.Tests/TLSharpTests.cs#L143) + +To download file you should call **GetFile** method +```csharp + await client.GetFile( + new TLInputDocumentFileLocation() + { + access_hash = document.access_hash, + id = document.id, + version = document.version + }, + 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) + +# Available Methods For your convenience TLSharp have wrappers for several Telegram API methods. You could add your own, see details below. @@ -117,6 +151,10 @@ For your convenience TLSharp have wrappers for several Telegram API methods. You 1. SendMessageAsync 1. SendTypingAsync 1. GetUserDialogsAsync +1. SendUploadedPhoto +1. SendUploadedDocument +1. GetFile +1. UploadFile **What if you can't find needed method at the list?** @@ -140,18 +178,19 @@ Don't panic. You can call any method with help of `SendRequestAsync` function. F The only way is [Telegram API docs](https://core.telegram.org/methods). Yes, it's outdated. But there is no other source. Latest scheme in JSON format you can find [here](https://gist.github.com/aarani/b22b7cda024973dff68e1672794b0298) -## Contributing +# Contributing Contributing is highly appreciated! -### What things can I Implement (Project Roadmap)? +## What things can I Implement (Project Roadmap)? -#### Release 1.0.0 +### Release 1.0.0 * [DONE] Add PHONE_MIGRATE handling +* Add FILE_MIGRATE handling * Add Updates handling * Add NuGet package -* [WIP] Add wrappers for media uploading +* [DONE] Add wrappers for media uploading and downloading * Store user session as JSON # FAQ From 6d106b4425c5c383eb5f8863f09e5fd120bf2545 Mon Sep 17 00:00:00 2001 From: Ilya P Date: Sun, 23 Oct 2016 14:10:54 +0300 Subject: [PATCH 11/15] Merge fix --- TLSharp.Tests/TLSharpTests.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/TLSharp.Tests/TLSharpTests.cs b/TLSharp.Tests/TLSharpTests.cs index fe88804..7ce34f7 100644 --- a/TLSharp.Tests/TLSharpTests.cs +++ b/TLSharp.Tests/TLSharpTests.cs @@ -1,6 +1,7 @@  using System.Configuration; using System.Diagnostics; +using System.IO; using System.Linq; using System.Threading; using System.Threading.Tasks; @@ -8,10 +9,9 @@ using System.Threading.Tasks; using Microsoft.VisualStudio.TestTools.UnitTesting; using TeleSharp.TL; -using TeleSharp.TL.Upload; +using TeleSharp.TL.Messages; using TLSharp.Core; using TLSharp.Core.Requests; -using TLSharp.Core.Utils; namespace TLSharp.Tests { @@ -127,7 +127,7 @@ namespace TLSharp.Tests [TestMethod] public async Task SendPhotoToContactTest() { - var client = new TelegramClient(apiId, apiHash); + var client = new TelegramClient(ApiId, ApiHash); await client.ConnectAsync(); @@ -145,7 +145,7 @@ namespace TLSharp.Tests [TestMethod] public async Task SendBigFileToContactTest() { - var client = new TelegramClient(apiId, apiHash); + var client = new TelegramClient(ApiId, ApiHash); await client.ConnectAsync(); @@ -169,7 +169,7 @@ namespace TLSharp.Tests [TestMethod] public async Task DownloadFileFromContactTest() { - var client = new TelegramClient(apiId, apiHash); + var client = new TelegramClient(ApiId, ApiHash); await client.ConnectAsync(); From b823c340781eacba25b91cb7d75540c851a4ac6d Mon Sep 17 00:00:00 2001 From: Ilya P Date: Sun, 23 Oct 2016 14:12:34 +0300 Subject: [PATCH 12/15] Move upload helper to helpers --- TLSharp.Core/TLSharp.Core.csproj | 2 +- .../{Requests => Utils}/UploadHelper.cs | 271 +++++++++--------- TLSharp.Tests/TLSharpTests.cs | 1 + 3 files changed, 137 insertions(+), 137 deletions(-) rename TLSharp.Core/{Requests => Utils}/UploadHelper.cs (95%) diff --git a/TLSharp.Core/TLSharp.Core.csproj b/TLSharp.Core/TLSharp.Core.csproj index 31fee3a..0b8ac8d 100644 --- a/TLSharp.Core/TLSharp.Core.csproj +++ b/TLSharp.Core/TLSharp.Core.csproj @@ -63,7 +63,7 @@ - + diff --git a/TLSharp.Core/Requests/UploadHelper.cs b/TLSharp.Core/Utils/UploadHelper.cs similarity index 95% rename from TLSharp.Core/Requests/UploadHelper.cs rename to TLSharp.Core/Utils/UploadHelper.cs index f7d14fe..68fc176 100644 --- a/TLSharp.Core/Requests/UploadHelper.cs +++ b/TLSharp.Core/Utils/UploadHelper.cs @@ -1,136 +1,135 @@ -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Security.Cryptography; -using System.Text; -using System.Threading.Tasks; -using TeleSharp.TL; -using TeleSharp.TL.Upload; -using TLSharp.Core.Utils; - -namespace TLSharp.Core.Requests -{ - public static class UploadHelper - { - private static string GetFileHash(byte[] data) - { - string md5_checksum; - using (var md5 = MD5.Create()) - { - var hash = md5.ComputeHash(data); - var hashResult = new StringBuilder(hash.Length * 2); - - foreach (byte t in hash) - hashResult.Append(t.ToString("x2")); - - md5_checksum = hashResult.ToString(); - } - - return md5_checksum; - } - - public static async Task UploadFile(this TelegramClient client, string name, StreamReader reader) - { - const long tenMb = 10 * 1024 * 1024; - return await UploadFile(name, reader, client, reader.BaseStream.Length >= tenMb); - } - - private static byte[] GetFile(StreamReader reader) - { - var file = new byte[reader.BaseStream.Length]; - - using (reader) - { - reader.BaseStream.Read(file, 0, (int)reader.BaseStream.Length); - } - - return file; - } - - private static Queue GetFileParts(byte[] file) - { - var fileParts = new Queue(); - - const int maxFilePart = 512 * 1024; - - using (var stream = new MemoryStream(file)) - { - while (stream.Position != stream.Length) - { - if ((stream.Length - stream.Position) > maxFilePart) - { - var temp = new byte[maxFilePart]; - stream.Read(temp, 0, maxFilePart); - fileParts.Enqueue(temp); - } - else - { - var length = stream.Length - stream.Position; - var temp = new byte[length]; - stream.Read(temp, 0, (int)(length)); - fileParts.Enqueue(temp); - } - } - } - - return fileParts; - } - - private static async Task UploadFile(string name, StreamReader reader, - TelegramClient client, bool isBigFileUpload) - { - var file = GetFile(reader); - var fileParts = GetFileParts(file); - - int partNumber = 0; - int partsCount = fileParts.Count; - long file_id = BitConverter.ToInt64(Helpers.GenerateRandomBytes(8), 0); - while (fileParts.Count != 0) - { - var part = fileParts.Dequeue(); - - if (isBigFileUpload) - { - await client.SendRequestAsync(new TLRequestSaveBigFilePart - { - file_id = file_id, - file_part = partNumber, - bytes = part, - file_total_parts = partsCount - }); - } - else - { - await client.SendRequestAsync(new TLRequestSaveFilePart - { - file_id = file_id, - file_part = partNumber, - bytes = part - }); - } - partNumber++; - } - - if (isBigFileUpload) - { - return new TLInputFileBig - { - id = file_id, - name = name, - parts = partsCount - }; - } - else - { - return new TLInputFile - { - id = file_id, - name = name, - parts = partsCount, - md5_checksum = GetFileHash(file) - }; - } - } - } -} +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Security.Cryptography; +using System.Text; +using System.Threading.Tasks; +using TeleSharp.TL; +using TeleSharp.TL.Upload; + +namespace TLSharp.Core.Utils +{ + public static class UploadHelper + { + private static string GetFileHash(byte[] data) + { + string md5_checksum; + using (var md5 = MD5.Create()) + { + var hash = md5.ComputeHash(data); + var hashResult = new StringBuilder(hash.Length * 2); + + foreach (byte t in hash) + hashResult.Append(t.ToString("x2")); + + md5_checksum = hashResult.ToString(); + } + + return md5_checksum; + } + + public static async Task UploadFile(this TelegramClient client, string name, StreamReader reader) + { + const long tenMb = 10 * 1024 * 1024; + return await UploadFile(name, reader, client, reader.BaseStream.Length >= tenMb); + } + + private static byte[] GetFile(StreamReader reader) + { + var file = new byte[reader.BaseStream.Length]; + + using (reader) + { + reader.BaseStream.Read(file, 0, (int)reader.BaseStream.Length); + } + + return file; + } + + private static Queue GetFileParts(byte[] file) + { + var fileParts = new Queue(); + + const int maxFilePart = 512 * 1024; + + using (var stream = new MemoryStream(file)) + { + while (stream.Position != stream.Length) + { + if ((stream.Length - stream.Position) > maxFilePart) + { + var temp = new byte[maxFilePart]; + stream.Read(temp, 0, maxFilePart); + fileParts.Enqueue(temp); + } + else + { + var length = stream.Length - stream.Position; + var temp = new byte[length]; + stream.Read(temp, 0, (int)(length)); + fileParts.Enqueue(temp); + } + } + } + + return fileParts; + } + + private static async Task UploadFile(string name, StreamReader reader, + TelegramClient client, bool isBigFileUpload) + { + var file = GetFile(reader); + var fileParts = GetFileParts(file); + + int partNumber = 0; + int partsCount = fileParts.Count; + long file_id = BitConverter.ToInt64(Helpers.GenerateRandomBytes(8), 0); + while (fileParts.Count != 0) + { + var part = fileParts.Dequeue(); + + if (isBigFileUpload) + { + await client.SendRequestAsync(new TLRequestSaveBigFilePart + { + file_id = file_id, + file_part = partNumber, + bytes = part, + file_total_parts = partsCount + }); + } + else + { + await client.SendRequestAsync(new TLRequestSaveFilePart + { + file_id = file_id, + file_part = partNumber, + bytes = part + }); + } + partNumber++; + } + + if (isBigFileUpload) + { + return new TLInputFileBig + { + id = file_id, + name = name, + parts = partsCount + }; + } + else + { + return new TLInputFile + { + id = file_id, + name = name, + parts = partsCount, + md5_checksum = GetFileHash(file) + }; + } + } + } +} diff --git a/TLSharp.Tests/TLSharpTests.cs b/TLSharp.Tests/TLSharpTests.cs index 7ce34f7..05965d3 100644 --- a/TLSharp.Tests/TLSharpTests.cs +++ b/TLSharp.Tests/TLSharpTests.cs @@ -12,6 +12,7 @@ using TeleSharp.TL; using TeleSharp.TL.Messages; using TLSharp.Core; using TLSharp.Core.Requests; +using TLSharp.Core.Utils; namespace TLSharp.Tests { From 0e32291d112f5df08423c381c842b496b867286a Mon Sep 17 00:00:00 2001 From: "Andres G. Aragoneses" Date: Sun, 23 Oct 2016 23:23:10 +0800 Subject: [PATCH 13/15] Tests: show a more meaningful exception when running for 1st time Instead of throwing a System.FormatException, capture the URL thrown by the library itself so that the developer configures the API_ID and API_HASH and places them in the app.config file. --- TLSharp.Core/TelegramClient.cs | 17 ++++++++++++---- TLSharp.Tests/TLSharpTests.cs | 36 +++++++++++++++++++++++++--------- 2 files changed, 40 insertions(+), 13 deletions(-) diff --git a/TLSharp.Core/TelegramClient.cs b/TLSharp.Core/TelegramClient.cs index c4aab25..eeb72b5 100644 --- a/TLSharp.Core/TelegramClient.cs +++ b/TLSharp.Core/TelegramClient.cs @@ -35,11 +35,11 @@ namespace TLSharp.Core TLContext.Init(); _apiHash = apiHash; _apiId = apiId; - if (_apiId == 0) - throw new InvalidOperationException("Your API_ID is invalid. Do a configuration first https://github.com/sochix/TLSharp#quick-configuration"); - + if (_apiId == default(int)) + throw new MissingApiConfigurationException("API_ID"); if (string.IsNullOrEmpty(_apiHash)) - throw new InvalidOperationException("Your API_ID is invalid. Do a configuration first https://github.com/sochix/TLSharp#quick-configuration"); + throw new MissingApiConfigurationException("API_HASH"); + _session = Session.TryLoadOrCreateNew(store, sessionUserId); _transport = new TcpTransport(_session.ServerAddress, _session.Port); } @@ -250,6 +250,15 @@ namespace TLSharp.Core _session.Save(); } + } + public class MissingApiConfigurationException : Exception + { + public const string InfoUrl = "https://github.com/sochix/TLSharp#quick-configuration"; + + internal MissingApiConfigurationException(string invalidParamName): + base($"Your {invalidParamName} setting is missing. Adjust the configuration first, see {InfoUrl}") + { + } } } diff --git a/TLSharp.Tests/TLSharpTests.cs b/TLSharp.Tests/TLSharpTests.cs index 6f7bd4b..97deaa6 100644 --- a/TLSharp.Tests/TLSharpTests.cs +++ b/TLSharp.Tests/TLSharpTests.cs @@ -1,4 +1,5 @@  +using System; using System.Configuration; using System.Diagnostics; using System.IO; @@ -39,7 +40,23 @@ namespace TLSharp.Tests public void Init() { // Setup your API settings and phone numbers in app.config + GatherTestConfiguration(); + } + private TelegramClient NewClient() + { + try + { + return new TelegramClient(ApiId, ApiHash); + } + catch (MissingApiConfigurationException) + { + throw new Exception($"Please add your API settings to the `app.config` file. (More info: {MissingApiConfigurationException.InfoUrl})"); + } + } + + private void GatherTestConfiguration() + { ApiHash = ConfigurationManager.AppSettings[nameof(ApiHash)]; if (string.IsNullOrEmpty(ApiHash)) Debug.WriteLine("ApiHash not configured in app.config! Some tests may fail."); @@ -47,7 +64,8 @@ namespace TLSharp.Tests var apiId = ConfigurationManager.AppSettings[nameof(ApiId)]; if (string.IsNullOrEmpty(apiId)) Debug.WriteLine("ApiId not configured in app.config! Some tests may fail."); - ApiId = int.Parse(apiId); + else + ApiId = int.Parse(apiId); NumberToAuthenticate = ConfigurationManager.AppSettings[nameof(NumberToAuthenticate)]; if (string.IsNullOrEmpty(NumberToAuthenticate)) @@ -77,7 +95,7 @@ namespace TLSharp.Tests [TestMethod] public async Task AuthUser() { - var client = new TelegramClient(ApiId, ApiHash); + var client = NewClient(); await client.ConnectAsync(); @@ -93,7 +111,7 @@ namespace TLSharp.Tests [TestMethod] public async Task SendMessageTest() { - var client = new TelegramClient(ApiId, ApiHash); + var client = NewClient(); await client.ConnectAsync(); @@ -118,7 +136,7 @@ namespace TLSharp.Tests [TestMethod] public async Task SendMessageToChannelTest() { - var client = new TelegramClient(ApiId, ApiHash); + var client = NewClient(); await client.ConnectAsync(); @@ -134,7 +152,7 @@ namespace TLSharp.Tests [TestMethod] public async Task SendPhotoToContactTest() { - var client = new TelegramClient(ApiId, ApiHash); + var client = NewClient(); await client.ConnectAsync(); @@ -152,7 +170,7 @@ namespace TLSharp.Tests [TestMethod] public async Task SendBigFileToContactTest() { - var client = new TelegramClient(ApiId, ApiHash); + var client = NewClient(); await client.ConnectAsync(); @@ -176,7 +194,7 @@ namespace TLSharp.Tests [TestMethod] public async Task DownloadFileFromContactTest() { - var client = new TelegramClient(ApiId, ApiHash); + var client = NewClient(); await client.ConnectAsync(); @@ -215,7 +233,7 @@ namespace TLSharp.Tests [TestMethod] public async Task SignUpNewUser() { - var client = new TelegramClient(ApiId, ApiHash); + var client = NewClient(); await client.ConnectAsync(); var hash = await client.SendCodeRequestAsync(NotRegisteredNumberToSignUp); @@ -232,7 +250,7 @@ namespace TLSharp.Tests [TestMethod] public async Task CheckPhones() { - var client = new TelegramClient(ApiId, ApiHash); + var client = NewClient(); await client.ConnectAsync(); var result = await client.IsPhoneRegisteredAsync(NumberToAuthenticate); From c644bac4e4f221e1bf79f1f1ff7ee5f82d890a5d Mon Sep 17 00:00:00 2001 From: "Andres G. Aragoneses" Date: Mon, 24 Oct 2016 14:57:04 +0800 Subject: [PATCH 14/15] Fix typo in string of exception message This was meant to start with $, not including the $ char inside the string, otherwise the compiler string interpolation doesn't work. --- TLSharp.Core/Network/MtProtoSender.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/TLSharp.Core/Network/MtProtoSender.cs b/TLSharp.Core/Network/MtProtoSender.cs index 4cf59a8..a8fd1ed 100644 --- a/TLSharp.Core/Network/MtProtoSender.cs +++ b/TLSharp.Core/Network/MtProtoSender.cs @@ -488,7 +488,7 @@ namespace TLSharp.Core.Network internal int DC { get; private set; } internal MigrationNeededException(int dc) - : base ("$Your phone number is registered to a different dc: {dc}. Please migrate.") + : base ($"Your phone number is registered to a different DC: {dc}. Please migrate.") { DC = dc; } From 3639ae3e8895d2bd45700b3c7275cd8fbbe43151 Mon Sep 17 00:00:00 2001 From: "Andres G. Aragoneses" Date: Mon, 24 Oct 2016 14:58:04 +0800 Subject: [PATCH 15/15] Always include an innerException when re-throwing Hiding the previous thrown exception is a bad practice. --- TLSharp.Tests/TLSharpTests.cs | 5 +++-- TeleSharp.TL/ObjectDeserializer.cs | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/TLSharp.Tests/TLSharpTests.cs b/TLSharp.Tests/TLSharpTests.cs index 97deaa6..ccd88f1 100644 --- a/TLSharp.Tests/TLSharpTests.cs +++ b/TLSharp.Tests/TLSharpTests.cs @@ -49,9 +49,10 @@ namespace TLSharp.Tests { return new TelegramClient(ApiId, ApiHash); } - catch (MissingApiConfigurationException) + catch (MissingApiConfigurationException ex) { - throw new Exception($"Please add your API settings to the `app.config` file. (More info: {MissingApiConfigurationException.InfoUrl})"); + throw new Exception($"Please add your API settings to the `app.config` file. (More info: {MissingApiConfigurationException.InfoUrl})", + ex); } } diff --git a/TeleSharp.TL/ObjectDeserializer.cs b/TeleSharp.TL/ObjectDeserializer.cs index f6e256c..3c695ab 100644 --- a/TeleSharp.TL/ObjectDeserializer.cs +++ b/TeleSharp.TL/ObjectDeserializer.cs @@ -21,7 +21,7 @@ namespace TeleSharp.TL } catch(Exception ex) { - throw new InvalidDataException("Constructor Invalid Or Context.Init Not Called !"); + throw new InvalidDataException("Constructor Invalid Or Context.Init Not Called !", ex); } if (t.IsSubclassOf(typeof(TLMethod))) {