diff --git a/README.md b/README.md index af3885a..d7d606b 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,7 @@ ## How to use -:warning: This library relies on asynchronous C# programming (`async/await`) so make sure you are familiar with this before proceeding. +âš ī¸ This library relies on asynchronous C# programming (`async/await`) so make sure you are familiar with this before proceeding. After installing WTelegramClient through Nuget, your first Console program will be as simple as: ```csharp @@ -55,18 +55,14 @@ static string Config(string what) ... using var client = new WTelegram.Client(Config); ``` -There are other configuration items that are queried to your method but returning `null` let WTelegramClient choose a default adequate value. - -The configuration items shown above are the only ones that have no default values and are required to be provided by your method. - -The constructor also takes another optional delegate parameter that will be called for any other Update or other information/status/service messages that Telegram sends unsollicited, independently of your API requests. +There are other configuration items that are queried to your method but returning `null` let WTelegramClient choose a default adequate value. Those shown above are the only ones that have no default values and are required to be provided by your method. Finally, if you want to redirect the library logs to your logger instead of the Console, you can install a delegate in the `WTelegram.Helpers.Log` static property. Its `int` argument is the log severity, compatible with the classic [LogLevel enum](https://docs.microsoft.com/en-us/dotnet/api/microsoft.extensions.logging.loglevel) # Example of API call -:information_source: The Telegram API makes extensive usage of base and derived classes, so be ready to use the various syntaxes C# offer to check/cast base classes into the more useful derived classes (`is`, `as`, `case DerivedType` ) +â„šī¸ The Telegram API makes extensive usage of base and derived classes, so be ready to use the various syntaxes C# offer to check/cast base classes into the more useful derived classes (`is`, `as`, `case DerivedType` ) To find which derived classes are available for a given base class, the fastest is to check our [TL.Schema.cs](src/TL.Schema.cs) source file as they are listed in groups. Intellisense tooltips on API structures/methods will also display a web link to the adequate Telegram documentation page. @@ -101,7 +97,9 @@ await client.SendMessageAsync(target, "Hello, World"); # Other things to know -An invalid API request can result in a RpcException being raised, reflecting the [error code and status text](https://core.telegram.org/api/errors) of the problem. +The Client class also offers an `Update` event that is triggered when Telegram servers sends unsollicited Updates or notifications/information/status/service messages, independently of your API requests. + +An invalid API request can result in a `RpcException` being raised, reflecting the [error code and status text](https://core.telegram.org/api/errors) of the problem. The other configuration items that you can override include: **session_pathname, server_address, device_model, system_version, app_version, system_lang_code, lang_pack, lang_code, user_id** diff --git a/src/Client.cs b/src/Client.cs index 534a9f0..015ffa9 100644 --- a/src/Client.cs +++ b/src/Client.cs @@ -19,9 +19,9 @@ namespace WTelegram { public sealed partial class Client : IDisposable { + public event Func Update; public Config TLConfig { get; private set; } private readonly Func _config; - private readonly Func _updateHandler; private readonly int _apiId; private readonly string _apiHash; private readonly Session _session; @@ -41,16 +41,16 @@ namespace WTelegram /// Welcome to WTelegramClient! 😀 /// Config callback, is queried for: api_id, api_hash, session_pathname - /// Handler for Telegram updates messages that are not replies to RPC API calls - public Client(Func configProvider = null, Func updateHandler = null) + public Client(Func configProvider = null) { _config = configProvider ?? DefaultConfigOrAsk; - _updateHandler = updateHandler; _apiId = int.Parse(Config("api_id")); _apiHash = Config("api_hash"); _session = Session.LoadOrCreate(Config("session_pathname"), Convert.FromHexString(_apiHash)); } + private Task OnUpdate(ITLObject obj) => Update?.Invoke(obj) ?? Task.CompletedTask; + public string Config(string config) => _config(config) ?? DefaultConfig(config) ?? throw new ApplicationException("You must provide a config value for " + config); @@ -615,8 +615,8 @@ namespace WTelegram if (_bareRequest == badMsgNotification.bad_msg_id) _bareRequest = 0; _ = Task.Run(() => tcs.SetException(new ApplicationException($"BadMsgNotification {badMsgNotification.error_code}"))); } - else if (_updateHandler != null) - await _updateHandler.Invoke(obj); + else + await OnUpdate(obj); } break; default: @@ -629,8 +629,7 @@ namespace WTelegram _ = Task.Run(() => tcs.SetResult(obj)); } } - if (_updateHandler != null) - await _updateHandler.Invoke(obj); + await OnUpdate(obj); break; } @@ -639,8 +638,8 @@ namespace WTelegram var (type, tcs) = PullPendingRequest(msgId); if (tcs != null) _ = Task.Run(() => tcs.SetResult(result)); - else if (_updateHandler != null) - await _updateHandler.Invoke(obj); + else + await OnUpdate(obj); } } @@ -721,8 +720,8 @@ namespace WTelegram if (authorization is Auth_AuthorizationSignUpRequired signUpRequired) { var waitUntil = DateTime.UtcNow.AddSeconds(3); - if (signUpRequired.terms_of_service != null && _updateHandler != null) - await _updateHandler.Invoke(signUpRequired.terms_of_service); // give caller the possibility to read and accept TOS + if (signUpRequired.terms_of_service != null) + await OnUpdate(signUpRequired.terms_of_service); // give caller the possibility to read and accept TOS var first_name = Config("first_name"); var last_name = Config("last_name"); var wait = waitUntil - DateTime.UtcNow;