From 31e52887ba14b01bcfa278044f24f37288551fbd Mon Sep 17 00:00:00 2001 From: FlorianDahn Date: Fri, 26 Nov 2021 17:57:49 +0100 Subject: [PATCH] V17 - Big Update - Adding a message loop interface to build custom message loops - extracting default message loop from BotBase into seperate class - updates to BotBaseBuilder for integration of custom message loops - updating all result classes for using the new Update object of V17 - improving MessageResult and UpdateResult classes - BotBase has been prepared for cleanup (a lot of comments) - Comment cleanup at the next build - updating Readme --- README.md | 5 + TelegramBotBase/Base/DataResult.cs | 56 ++- TelegramBotBase/Base/MessageClient.cs | 252 ++++++---- TelegramBotBase/Base/MessageResult.cs | 75 +-- TelegramBotBase/Base/ResultBase.cs | 3 +- TelegramBotBase/Base/UpdateResult.cs | 59 +++ TelegramBotBase/BotBase.cs | 440 ++++++++++-------- TelegramBotBase/Builder/BotBaseBuilder.cs | 50 +- .../Interfaces/IAPIKeySelectionStage.cs | 2 +- .../Interfaces/IMessageLoopSelectionStage.cs | 36 ++ .../Interfaces/INetworkingSelectionStage.cs | 2 + .../MessageLoops/FormBaseMessageLoop.cs | 131 ++++++ TelegramBotBase/Form/ButtonBase.cs | 4 +- TelegramBotBase/Form/GroupForm.cs | 4 +- .../Interfaces/IMessageLoopFactory.cs | 21 + TelegramBotBase/Sessions/DeviceSession.cs | 14 +- 16 files changed, 824 insertions(+), 330 deletions(-) create mode 100644 TelegramBotBase/Base/UpdateResult.cs create mode 100644 TelegramBotBase/Builder/Interfaces/IMessageLoopSelectionStage.cs create mode 100644 TelegramBotBase/Factories/MessageLoops/FormBaseMessageLoop.cs create mode 100644 TelegramBotBase/Interfaces/IMessageLoopFactory.cs diff --git a/README.md b/README.md index 01efc4a..b1fdcdf 100644 --- a/README.md +++ b/README.md @@ -147,6 +147,7 @@ It needs to be a subclass of "FormBase" you will find in Namespace TelegramBotBa var bb = BotBaseBuilder .Create() .WithAPIKey("{YOUR API KEY}") + .DefaultMessageLoop() .WithStartForm() .NoProxy() .CustomCommands(a => @@ -263,6 +264,7 @@ Below we have 4 options. var bb = BotBaseBuilder .Create() .WithAPIKey("{YOUR API KEY}") + .DefaultMessageLoop() .WithStartForm() .NoProxy() .CustomCommands(a => @@ -984,6 +986,7 @@ In general you didn't need to do more then, to keep the actual form: var bb = BotBaseBuilder .Create() .WithAPIKey("{YOUR API KEY}") + .DefaultMessageLoop() .WithStartForm() .NoProxy() .CustomCommands(a => @@ -1007,6 +1010,7 @@ In general you didn't need to do more then, to keep the actual form: var bb = BotBaseBuilder .Create() .WithAPIKey("{YOUR API KEY}") + .DefaultMessageLoop() .WithStartForm() .NoProxy() .CustomCommands(a => @@ -1031,6 +1035,7 @@ In general you didn't need to do more then, to keep the actual form: var bb = BotBaseBuilder .Create() .WithAPIKey("{YOUR API KEY}") + .DefaultMessageLoop() .WithStartForm() .NoProxy() .CustomCommands(a => diff --git a/TelegramBotBase/Base/DataResult.cs b/TelegramBotBase/Base/DataResult.cs index c3f2a21..55ff7b2 100644 --- a/TelegramBotBase/Base/DataResult.cs +++ b/TelegramBotBase/Base/DataResult.cs @@ -4,6 +4,7 @@ using System.IO; using System.Linq; using System.Text; using System.Threading.Tasks; +using Telegram.Bot; using Telegram.Bot.Types; using Telegram.Bot.Types.InputFiles; @@ -14,7 +15,11 @@ namespace TelegramBotBase.Base /// public class DataResult : ResultBase { - public Telegram.Bot.Args.MessageEventArgs RawMessageData { get; set; } + + //public Telegram.Bot.Args.MessageEventArgs RawMessageData { get; set; } + + public UpdateResult Update { get; set; } + public Contact Contact { @@ -64,11 +69,21 @@ namespace TelegramBotBase.Base } } + + //public Telegram.Bot.Types.Enums.MessageType Type + //{ + // get + // { + // return this.RawMessageData?.Message?.Type ?? Telegram.Bot.Types.Enums.MessageType.Unknown; + // } + //} + + public Telegram.Bot.Types.Enums.MessageType Type { get { - return this.RawMessageData?.Message?.Type ?? Telegram.Bot.Types.Enums.MessageType.Unknown; + return this.Message?.Type ?? Telegram.Bot.Types.Enums.MessageType.Unknown; } } @@ -87,23 +102,30 @@ namespace TelegramBotBase.Base } - public DataResult(Telegram.Bot.Args.MessageEventArgs rawdata) + //public DataResult(Telegram.Bot.Args.MessageEventArgs rawdata) + //{ + // this.RawMessageData = rawdata; + // this.Message = rawdata.Message; + //} + + //public DataResult(MessageResult message) + //{ + // this.RawMessageData = message.RawMessageData; + // this.Message = message.Message; + + // this.Client = message.Client; + //} + + + public DataResult(UpdateResult update) { - this.RawMessageData = rawdata; - this.Message = rawdata.Message; + this.Update = update; } - public DataResult(MessageResult message) - { - this.RawMessageData = message.RawMessageData; - this.Message = message.Message; - - this.Client = message.Client; - } public async Task DownloadDocument() { - var encryptedContent = new System.IO.MemoryStream(this.Document.FileSize); + var encryptedContent = new System.IO.MemoryStream(this.Document.FileSize.Value); var file = await this.Client.TelegramClient.GetInfoAndDownloadFileAsync(this.Document.FileId, encryptedContent); return new InputOnlineFile(encryptedContent, this.Document.FileName); @@ -156,13 +178,13 @@ namespace TelegramBotBase.Base ms.Position = 0; var sr = new StreamReader(ms, encoding); - + return sr.ReadToEnd(); } public async Task DownloadVideo() { - var encryptedContent = new System.IO.MemoryStream(this.Video.FileSize); + var encryptedContent = new System.IO.MemoryStream(this.Video.FileSize.Value); var file = await this.Client.TelegramClient.GetInfoAndDownloadFileAsync(this.Video.FileId, encryptedContent); return new InputOnlineFile(encryptedContent, ""); @@ -179,7 +201,7 @@ namespace TelegramBotBase.Base public async Task DownloadAudio() { - var encryptedContent = new System.IO.MemoryStream(this.Audio.FileSize); + var encryptedContent = new System.IO.MemoryStream(this.Audio.FileSize.Value); var file = await this.Client.TelegramClient.GetInfoAndDownloadFileAsync(this.Audio.FileId, encryptedContent); return new InputOnlineFile(encryptedContent, ""); @@ -197,7 +219,7 @@ namespace TelegramBotBase.Base public async Task DownloadPhoto(int index) { var photo = this.Photos[index]; - var encryptedContent = new System.IO.MemoryStream(photo.FileSize); + var encryptedContent = new System.IO.MemoryStream(photo.FileSize.Value); var file = await this.Client.TelegramClient.GetInfoAndDownloadFileAsync(photo.FileId, encryptedContent); return new InputOnlineFile(encryptedContent, ""); diff --git a/TelegramBotBase/Base/MessageClient.cs b/TelegramBotBase/Base/MessageClient.cs index 22a71fe..80327fb 100644 --- a/TelegramBotBase/Base/MessageClient.cs +++ b/TelegramBotBase/Base/MessageClient.cs @@ -5,8 +5,13 @@ using System.Linq; using System.Net; using System.Net.Http; using System.Text; +using System.Threading; using System.Threading.Tasks; +using Telegram.Bot.Exceptions; +using Telegram.Bot; using Telegram.Bot.Types; +using Telegram.Bot.Types.Enums; +using Telegram.Bot.Extensions.Polling; namespace TelegramBotBase.Base { @@ -19,16 +24,20 @@ namespace TelegramBotBase.Base public String APIKey { get; set; } - public Telegram.Bot.TelegramBotClient TelegramClient { get; set; } + public ITelegramBotClient TelegramClient { get; set; } private EventHandlerList __Events { get; set; } = new EventHandlerList(); + private static object __evOnMessageLoop = new object(); + private static object __evOnMessage = new object(); private static object __evOnMessageEdit = new object(); private static object __evCallbackQuery = new object(); + CancellationTokenSource __cancellationTokenSource; + public MessageClient(String APIKey) { @@ -47,13 +56,22 @@ namespace TelegramBotBase.Base Prepare(); } - public MessageClient(String APIKey, Uri proxyUrl) + + + public MessageClient(String APIKey, Uri proxyUrl, NetworkCredential credential = null) { this.APIKey = APIKey; - var proxy = new WebProxy(proxyUrl); + var proxy = new WebProxy(proxyUrl) + { + Credentials = credential + }; - this.TelegramClient = new Telegram.Bot.TelegramBotClient(APIKey, proxy); + var httpClient = new HttpClient( + new HttpClientHandler { Proxy = proxy, UseProxy = true } + ); + + this.TelegramClient = new Telegram.Bot.TelegramBotClient(APIKey, httpClient); Prepare(); } @@ -70,11 +88,17 @@ namespace TelegramBotBase.Base var proxy = new WebProxy(proxyHost, proxyPort); - this.TelegramClient = new Telegram.Bot.TelegramBotClient(APIKey, proxy); + var httpClient = new HttpClient( + new HttpClientHandler { Proxy = proxy, UseProxy = true } + ); + + this.TelegramClient = new Telegram.Bot.TelegramBotClient(APIKey, httpClient); Prepare(); } + + public MessageClient(String APIKey, Telegram.Bot.TelegramBotClient Client) { this.APIKey = APIKey; @@ -88,62 +112,106 @@ namespace TelegramBotBase.Base { this.TelegramClient.Timeout = new TimeSpan(0, 0, 30); - this.TelegramClient.OnMessage += TelegramClient_OnMessage; - this.TelegramClient.OnMessageEdited += TelegramClient_OnMessageEdited; - this.TelegramClient.OnCallbackQuery += TelegramClient_OnCallbackQuery; + + //this.TelegramClient.OnMessage += TelegramClient_OnMessage; + //this.TelegramClient.OnMessageEdited += TelegramClient_OnMessageEdited; + //this.TelegramClient.OnCallbackQuery += TelegramClient_OnCallbackQuery; + } - private async void TelegramClient_OnMessage(object sender, Telegram.Bot.Args.MessageEventArgs e) + + + public void StartReceiving() { - //Skip empty messages by default - if (e.Message == null) - return; + __cancellationTokenSource = new CancellationTokenSource(); - try - { - var mr = new MessageResult(e); - mr.Client = this; - OnMessage(mr); - } - catch + var receiverOptions = new ReceiverOptions { + AllowedUpdates = { } // receive all update types + }; - } + this.TelegramClient.StartReceiving(HandleUpdateAsync, HandleErrorAsync, receiverOptions, __cancellationTokenSource.Token); } - - private async void TelegramClient_OnMessageEdited(object sender, Telegram.Bot.Args.MessageEventArgs e) + public void StopReceiving() { - //Skip empty messages by default - if (e.Message == null) - return; - - try - { - var mr = new MessageResult(e); - mr.Client = this; - OnMessageEdit(mr); - } - catch - { - - } + __cancellationTokenSource.Cancel(); } - private async void TelegramClient_OnCallbackQuery(object sender, Telegram.Bot.Args.CallbackQueryEventArgs e) + + //private async void TelegramClient_OnMessage(object sender, Telegram.Bot.Args.MessageEventArgs e) + //{ + // //Skip empty messages by default + // if (e.Message == null) + // return; + + // try + // { + // var mr = new MessageResult(e); + // mr.Client = this; + // OnMessage(mr); + // } + // catch + // { + + // } + //} + + + //private async void TelegramClient_OnMessageEdited(object sender, Telegram.Bot.Args.MessageEventArgs e) + //{ + // //Skip empty messages by default + // if (e.Message == null) + // return; + + // try + // { + // var mr = new MessageResult(e); + // mr.Client = this; + // OnMessageEdit(mr); + // } + // catch + // { + + // } + //} + + //private async void TelegramClient_OnCallbackQuery(object sender, Telegram.Bot.Args.CallbackQueryEventArgs e) + //{ + // try + // { + // var ar = new MessageResult(e); + // ar.Client = this; + // OnAction(ar); + // } + // catch + // { + + // } + //} + + + public Task HandleUpdateAsync(ITelegramBotClient botClient, Update update, CancellationToken cancellationToken) { - try - { - var ar = new MessageResult(e); - ar.Client = this; - OnAction(ar); - } - catch - { + OnMessageLoop(new UpdateResult(update, null)); - } + return Task.CompletedTask; } + public Task HandleErrorAsync(ITelegramBotClient botClient, Exception exception, CancellationToken cancellationToken) + { + if (exception is ApiRequestException exAPI) + { + Console.WriteLine($"Telegram API Error:\n[{exAPI.ErrorCode}]\n{exAPI.Message}"); + } + else + { + Console.WriteLine(exception.ToString()); + } + return Task.CompletedTask; + } + + /// /// This will return the current list of bot commands. /// @@ -168,56 +236,78 @@ namespace TelegramBotBase.Base #region "Events" - public event EventHandler Message + + + public event Async.AsyncEventHandler MessageLoop { add { - this.__Events.AddHandler(__evOnMessage, value); + this.__Events.AddHandler(__evOnMessageLoop, value); } remove { - this.__Events.RemoveHandler(__evOnMessage, value); + this.__Events.RemoveHandler(__evOnMessageLoop, value); } } - public void OnMessage(MessageResult result) + public void OnMessageLoop(UpdateResult update) { - (this.__Events[__evOnMessage] as EventHandler)?.Invoke(this, result); + (this.__Events[__evOnMessageLoop] as Async.AsyncEventHandler)?.Invoke(this, update); } - public event EventHandler MessageEdit - { - add - { - this.__Events.AddHandler(__evOnMessageEdit, value); - } - remove - { - this.__Events.RemoveHandler(__evOnMessageEdit, value); - } - } - public void OnMessageEdit(MessageResult result) - { - (this.__Events[__evOnMessageEdit] as EventHandler)?.Invoke(this, result); - } + //public event EventHandler Message + //{ + // add + // { + // this.__Events.AddHandler(__evOnMessage, value); + // } + // remove + // { + // this.__Events.RemoveHandler(__evOnMessage, value); + // } + //} - public event EventHandler Action - { - add - { - this.__Events.AddHandler(__evCallbackQuery, value); - } - remove - { - this.__Events.RemoveHandler(__evCallbackQuery, value); - } - } + //public void OnMessage(MessageResult result) + //{ + // (this.__Events[__evOnMessage] as EventHandler)?.Invoke(this, result); + //} - public void OnAction(MessageResult result) - { - (this.__Events[__evCallbackQuery] as EventHandler)?.Invoke(this, result); - } + + + //public event EventHandler MessageEdit + //{ + // add + // { + // this.__Events.AddHandler(__evOnMessageEdit, value); + // } + // remove + // { + // this.__Events.RemoveHandler(__evOnMessageEdit, value); + // } + //} + + //public void OnMessageEdit(MessageResult result) + //{ + // (this.__Events[__evOnMessageEdit] as EventHandler)?.Invoke(this, result); + //} + + //public event EventHandler Action + //{ + // add + // { + // this.__Events.AddHandler(__evCallbackQuery, value); + // } + // remove + // { + // this.__Events.RemoveHandler(__evCallbackQuery, value); + // } + //} + + //public void OnAction(MessageResult result) + //{ + // (this.__Events[__evCallbackQuery] as EventHandler)?.Invoke(this, result); + //} #endregion diff --git a/TelegramBotBase/Base/MessageResult.cs b/TelegramBotBase/Base/MessageResult.cs index 7da2bdd..8ecf3fd 100644 --- a/TelegramBotBase/Base/MessageResult.cs +++ b/TelegramBotBase/Base/MessageResult.cs @@ -3,15 +3,21 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Telegram.Bot; +using Telegram.Bot.Types; using TelegramBotBase.Sessions; namespace TelegramBotBase.Base { public class MessageResult : ResultBase { - public Telegram.Bot.Args.MessageEventArgs RawMessageData { get; set; } - public Telegram.Bot.Args.CallbackQueryEventArgs RawCallbackData { get; set; } + //public Telegram.Bot.Args.MessageEventArgs RawMessageData { get; set; } + + //public Telegram.Bot.Args.CallbackQueryEventArgs RawCallbackData { get; set; } + + + public Telegram.Bot.Types.Update UpdateData { get; set; } /// /// Returns the Device/ChatId @@ -20,8 +26,9 @@ namespace TelegramBotBase.Base { get { - return this.RawMessageData?.Message?.Chat.Id - ?? this.RawCallbackData?.CallbackQuery.Message?.Chat.Id + return this.UpdateData?.Message?.Chat?.Id + ?? this.UpdateData?.EditedMessage?.Chat.Id + ?? this.UpdateData?.CallbackQuery.Message?.Chat.Id ?? Device?.DeviceId ?? 0; } @@ -40,8 +47,9 @@ namespace TelegramBotBase.Base { get { - return this.Message?.MessageId - ?? this.RawCallbackData?.CallbackQuery?.Message?.MessageId + return this.UpdateData?.Message?.MessageId + ?? this.Message?.MessageId + ?? this.UpdateData?.CallbackQuery?.Message?.MessageId ?? 0; } } @@ -50,7 +58,7 @@ namespace TelegramBotBase.Base { get { - return this.RawMessageData?.Message?.Text ?? ""; + return this.UpdateData?.Message?.Text ?? ""; } } @@ -58,7 +66,7 @@ namespace TelegramBotBase.Base { get { - return this.RawMessageData?.Message?.Text ?? ""; + return this.UpdateData?.Message?.Text ?? ""; } } @@ -66,8 +74,19 @@ namespace TelegramBotBase.Base { get { - return this.RawMessageData?.Message?.Type - ?? Telegram.Bot.Types.Enums.MessageType.Unknown; + return Message?.Type ?? Telegram.Bot.Types.Enums.MessageType.Unknown; + } + } + + public Message Message + { + get + { + return this.UpdateData?.Message + ?? this.UpdateData?.EditedMessage + ?? this.UpdateData?.ChannelPost + ?? this.UpdateData?.EditedChannelPost + ?? this.UpdateData?.CallbackQuery?.Message; } } @@ -78,7 +97,7 @@ namespace TelegramBotBase.Base { get { - return (this.RawCallbackData != null); + return (this.UpdateData.CallbackQuery != null); } } @@ -133,7 +152,7 @@ namespace TelegramBotBase.Base { get { - return this.RawCallbackData?.CallbackQuery?.Data; + return this.UpdateData?.CallbackQuery?.Data; } } @@ -162,14 +181,7 @@ namespace TelegramBotBase.Base /// public async Task ConfirmAction(String message = "", bool showAlert = false, String urlToOpen = null) { - try - { - await this.Client.TelegramClient.AnswerCallbackQueryAsync(this.RawCallbackData.CallbackQuery.Id, message, showAlert, urlToOpen); - } - catch - { - - } + await this.Device.ConfirmAction(this.UpdateData.CallbackQuery.Id, message, showAlert, urlToOpen); } public override async Task DeleteMessage() @@ -189,17 +201,24 @@ namespace TelegramBotBase.Base } - public MessageResult(Telegram.Bot.Args.MessageEventArgs rawdata) + public MessageResult(Telegram.Bot.Types.Update update) { - this.RawMessageData = rawdata; - this.Message = rawdata.Message; + this.UpdateData = update; + } - public MessageResult(Telegram.Bot.Args.CallbackQueryEventArgs callback) - { - this.RawCallbackData = callback; - this.Message = callback.CallbackQuery.Message; - } + + //public MessageResult(Telegram.Bot.Args.MessageEventArgs rawdata) + //{ + // this.RawMessageData = rawdata; + // this.Message = rawdata.Message; + //} + + //public MessageResult(Telegram.Bot.Args.CallbackQueryEventArgs callback) + //{ + // this.RawCallbackData = callback; + // this.Message = callback.CallbackQuery.Message; + //} } } diff --git a/TelegramBotBase/Base/ResultBase.cs b/TelegramBotBase/Base/ResultBase.cs index e351860..e5d37e8 100644 --- a/TelegramBotBase/Base/ResultBase.cs +++ b/TelegramBotBase/Base/ResultBase.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Telegram.Bot; namespace TelegramBotBase.Base { @@ -20,7 +21,7 @@ namespace TelegramBotBase.Base } } - public Telegram.Bot.Types.Message Message { get; set; } + public virtual Telegram.Bot.Types.Message Message { get; set; } /// /// Deletes the current message diff --git a/TelegramBotBase/Base/UpdateResult.cs b/TelegramBotBase/Base/UpdateResult.cs new file mode 100644 index 0000000..f2341dd --- /dev/null +++ b/TelegramBotBase/Base/UpdateResult.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using Telegram.Bot.Types; +using TelegramBotBase.Sessions; + +namespace TelegramBotBase.Base +{ + public class UpdateResult : ResultBase + { + public UpdateResult(Update rawData, DeviceSession device) + { + RawData = rawData; + Device = device; + + + } + + /// + /// Returns the Device/ChatId + /// + public override long DeviceId + { + get + { + return this.RawData?.Message?.Chat?.Id + ?? this.RawData?.CallbackQuery?.Message?.Chat?.Id + ?? Device?.DeviceId + ?? 0; + } + } + + public Update RawData { get; set; } + + public override Message Message + { + get + { + return RawData?.Message + ?? RawData?.EditedMessage + ?? RawData?.ChannelPost + ?? RawData?.EditedChannelPost + ?? RawData?.CallbackQuery?.Message; + } + } + + + + public DeviceSession Device + { + get; + set; + } + + + } + +} diff --git a/TelegramBotBase/BotBase.cs b/TelegramBotBase/BotBase.cs index 9361281..e5a6d93 100644 --- a/TelegramBotBase/BotBase.cs +++ b/TelegramBotBase/BotBase.cs @@ -3,13 +3,17 @@ using System.Collections.Generic; using System.ComponentModel; using System.Linq; using System.Text; +using System.Threading; using System.Threading.Tasks; using Telegram.Bot; +using Telegram.Bot.Exceptions; using Telegram.Bot.Types; +using Telegram.Bot.Types.Enums; using TelegramBotBase.Args; using TelegramBotBase.Attributes; using TelegramBotBase.Base; using TelegramBotBase.Enums; +using TelegramBotBase.Factories.MessageLoops; using TelegramBotBase.Form; using TelegramBotBase.Interfaces; using TelegramBotBase.Sessions; @@ -69,6 +73,8 @@ namespace TelegramBotBase /// public IStartFormFactory StartFormFactory { get; set; } + public IMessageLoopFactory MessageLoopFactory { get; set; } + public Dictionary SystemSettings { get; private set; } @@ -88,6 +94,8 @@ namespace TelegramBotBase this.Sessions.BotBase = this; } + + /// /// Start your Bot /// @@ -96,9 +104,12 @@ namespace TelegramBotBase if (this.Client == null) return; - this.Client.Message += Client_Message; - this.Client.MessageEdit += Client_MessageEdit; - this.Client.Action += Client_Action; + this.Client.MessageLoop += Client_MessageLoop; + + //this.Client.Message += Client_Message; + //this.Client.MessageEdit += Client_MessageEdit; + //this.Client.Action += Client_Action; + if (this.StateMachine != null) { @@ -116,7 +127,39 @@ namespace TelegramBotBase DeviceSession.MaxNumberOfRetries = this.GetSetting(eSettings.MaxNumberOfRetries, 5); - this.Client.TelegramClient.StartReceiving(); + this.Client.StartReceiving(); + } + + + private async Task Client_MessageLoop(object sender, UpdateResult e) + { + DeviceSession ds = this.Sessions.GetSession(e.DeviceId); + if (ds == null) + { + ds = this.Sessions.StartSession(e.DeviceId).GetAwaiter().GetResult(); + e.Device = ds; + ds.LastMessage = e.RawData.Message; + + OnSessionBegins(new SessionBeginEventArgs(e.DeviceId, ds)); + } + + var mr = new MessageResult(e.RawData); + + int i = 0; + + //Should formulars get navigated (allow maximum of 10, to dont get loops) + do + { + i++; + + //Reset navigation + ds.FormSwitched = false; + + await MessageLoopFactory.MessageLoop(this, ds, e, mr); + + mr.IsFirstHandler = false; + + } while (ds.FormSwitched && i < this.GetSetting(eSettings.NavigationMaximum, 10)); } @@ -128,10 +171,14 @@ namespace TelegramBotBase if (this.Client == null) return; - this.Client.Message -= Client_Message; - this.Client.Action -= Client_Action; + this.Client.MessageLoop -= Client_MessageLoop; - this.Client.TelegramClient.StopReceiving(); + //this.Client.Message -= Client_Message; + //this.Client.MessageEdit -= Client_MessageEdit; + //this.Client.Action -= Client_Action; + + + this.Client.StopReceiving(); this.Sessions.SaveSessionStates(); } @@ -152,35 +199,37 @@ namespace TelegramBotBase } } - private async void Client_Message(object sender, MessageResult e) - { - if (this.GetSetting(eSettings.SkipAllMessages, false)) - return; - try - { - DeviceSession ds = this.Sessions.GetSession(e.DeviceId); - e.Device = ds; - if (this.GetSetting(eSettings.LogAllMessages, false)) - { - OnMessage(new MessageIncomeEventArgs(e.DeviceId, ds, e)); - } + //private async void Client_Message(object sender, MessageResult e) + //{ + // if (this.GetSetting(eSettings.SkipAllMessages, false)) + // return; - ds?.OnMessageReceived(new MessageReceivedEventArgs(e.Message)); + // try + // { + // DeviceSession ds = this.Sessions.GetSession(e.DeviceId); + // e.Device = ds; - await Client_Loop(sender, e); - } - catch (Telegram.Bot.Exceptions.ApiRequestException ex) - { + // if (this.GetSetting(eSettings.LogAllMessages, false)) + // { + // OnMessage(new MessageIncomeEventArgs(e.DeviceId, ds, e)); + // } - } - catch (Exception ex) - { - DeviceSession ds = this.Sessions.GetSession(e.DeviceId); - OnException(new SystemExceptionEventArgs(e.Message.Text, ds?.DeviceId ?? -1, ds, ex)); - } - } + // ds?.OnMessageReceived(new MessageReceivedEventArgs(e.Message)); + + // await Client_Loop(sender, e); + // } + // catch (Telegram.Bot.Exceptions.ApiRequestException ex) + // { + + // } + // catch (Exception ex) + // { + // DeviceSession ds = this.Sessions.GetSession(e.DeviceId); + // OnException(new SystemExceptionEventArgs(e.Message.Text, ds?.DeviceId ?? -1, ds, ex)); + // } + //} @@ -255,101 +304,107 @@ namespace TelegramBotBase //} - private async Task Client_Loop(object sender, MessageResult e) - { - DeviceSession ds = e.Device; - if (ds == null) - { - ds = await this.Sessions.StartSession(e.DeviceId); - e.Device = ds; - ds.LastMessage = e.Message; - OnSessionBegins(new SessionBeginEventArgs(e.DeviceId, ds)); - } + //private async Task Client_Loop(object sender, MessageResult e) + //{ + // DeviceSession ds = e.Device; + // if (ds == null) + // { + // ds = await this.Sessions.StartSession(e.DeviceId); + // e.Device = ds; + // ds.LastMessage = e.Message; - ds.LastAction = DateTime.Now; - ds.LastMessage = e.Message; + // OnSessionBegins(new SessionBeginEventArgs(e.DeviceId, ds)); + // } - //Is this a bot command ? - if (e.IsBotCommand && this.BotCommands.Count(a => "/" + a.Command == e.BotCommand) > 0) - { - var sce = new BotCommandEventArgs(e.BotCommand, e.BotCommandParameters, e.Message, ds.DeviceId, ds); - await OnBotCommand(sce); + // ds.LastAction = DateTime.Now; + // ds.LastMessage = e.Message; - if (sce.Handled) - return; - } + // //Is this a bot command ? + // if (e.IsBotCommand && this.BotCommands.Count(a => "/" + a.Command == e.BotCommand) > 0) + // { + // var sce = new BotCommandEventArgs(e.BotCommand, e.BotCommandParameters, e.Message, ds.DeviceId, ds); + // await OnBotCommand(sce); - FormBase activeForm = null; + // if (sce.Handled) + // return; + // } - int i = 0; + // FormBase activeForm = null; - //Should formulars get navigated (allow maximum of 10, to dont get loops) - do - { - i++; + // int i = 0; - //Reset navigation - ds.FormSwitched = false; - - activeForm = ds.ActiveForm; - - //Pre Loading Event - await activeForm.PreLoad(e); - - //Send Load event to controls - await activeForm.LoadControls(e); - - //Loading Event - await activeForm.Load(e); - - //Is Attachment ? (Photo, Audio, Video, Contact, Location, Document) - if (e.MessageType == Telegram.Bot.Types.Enums.MessageType.Contact | e.MessageType == Telegram.Bot.Types.Enums.MessageType.Document | e.MessageType == Telegram.Bot.Types.Enums.MessageType.Location | - e.MessageType == Telegram.Bot.Types.Enums.MessageType.Photo | e.MessageType == Telegram.Bot.Types.Enums.MessageType.Video | e.MessageType == Telegram.Bot.Types.Enums.MessageType.Audio) - { - await activeForm.SentData(new DataResult(e)); - } - - //Action Event - if (!ds.FormSwitched && e.IsAction) - { - //Send Action event to controls - await activeForm.ActionControls(e); - - //Send Action event to form itself - await activeForm.Action(e); - - if (!e.Handled) - { - var uhc = new UnhandledCallEventArgs(e.Message.Text, e.RawData, ds.DeviceId, e.MessageId, e.Message, ds); - OnUnhandledCall(uhc); - - if (uhc.Handled) - { - e.Handled = true; - if (!ds.FormSwitched) - { - break; - } - } - } - - } - - if (!ds.FormSwitched) - { - //Render Event - await activeForm.RenderControls(e); - - await activeForm.Render(e); - } - - e.IsFirstHandler = false; - - } while (ds.FormSwitched && i < this.GetSetting(eSettings.NavigationMaximum, 10)); + // //Should formulars get navigated (allow maximum of 10, to dont get loops) + // do + // { + // i++; - } + + // //Reset navigation + // ds.FormSwitched = false; + + // activeForm = ds.ActiveForm; + + + + // //Pre Loading Event + // await activeForm.PreLoad(e); + + // //Send Load event to controls + // await activeForm.LoadControls(e); + + // //Loading Event + // await activeForm.Load(e); + + // //Is Attachment ? (Photo, Audio, Video, Contact, Location, Document) + // if (e.MessageType == Telegram.Bot.Types.Enums.MessageType.Contact | e.MessageType == Telegram.Bot.Types.Enums.MessageType.Document | e.MessageType == Telegram.Bot.Types.Enums.MessageType.Location | + // e.MessageType == Telegram.Bot.Types.Enums.MessageType.Photo | e.MessageType == Telegram.Bot.Types.Enums.MessageType.Video | e.MessageType == Telegram.Bot.Types.Enums.MessageType.Audio) + // { + // await activeForm.SentData(new DataResult(e)); + // } + + // //Action Event + // if (!ds.FormSwitched && e.IsAction) + // { + // //Send Action event to controls + // await activeForm.ActionControls(e); + + // //Send Action event to form itself + // await activeForm.Action(e); + + // if (!e.Handled) + // { + // var uhc = new UnhandledCallEventArgs(e.Message.Text, e.RawData, ds.DeviceId, e.MessageId, e.Message, ds); + // OnUnhandledCall(uhc); + + // if (uhc.Handled) + // { + // e.Handled = true; + // if (!ds.FormSwitched) + // { + // break; + // } + // } + // } + + // } + + // if (!ds.FormSwitched) + // { + // //Render Event + // await activeForm.RenderControls(e); + + // await activeForm.Render(e); + // } + + // e.IsFirstHandler = false; + + // } while (ds.FormSwitched && i < this.GetSetting(eSettings.NavigationMaximum, 10)); + + + //} + /// /// This will invoke the full message loop for the device even when no "userevent" like message or action has been raised. @@ -374,7 +429,8 @@ namespace TelegramBotBase DeviceSession ds = this.Sessions.GetSession(DeviceId); e.Device = ds; - await Client_Loop(this, e); + await MessageLoopFactory.MessageLoop(this, ds, new UpdateResult(e.UpdateData, ds), e); + //await Client_Loop(this, e); } catch (Exception ex) { @@ -383,79 +439,85 @@ namespace TelegramBotBase } } - private async void Client_MessageEdit(object sender, MessageResult e) + + //private async void Client_MessageEdit(object sender, MessageResult e) + //{ + // if (this.GetSetting(eSettings.SkipAllMessages, false)) + // return; + + // try + // { + // DeviceSession ds = this.Sessions.GetSession(e.DeviceId); + // e.Device = ds; + + // if (this.GetSetting(eSettings.LogAllMessages, false)) + // { + // OnMessage(new MessageIncomeEventArgs(e.DeviceId, ds, e)); + // } + + // //Call same, to handle received liked edited + // ds?.OnMessageReceived(new MessageReceivedEventArgs(e.Message)); + + // await Client_TryMessageEdit(sender, e); + // } + // catch (Telegram.Bot.Exceptions.ApiRequestException ex) + // { + + // } + // catch (Exception ex) + // { + // DeviceSession ds = this.Sessions.GetSession(e.DeviceId); + // OnException(new SystemExceptionEventArgs(e.Message.Text, ds?.DeviceId ?? -1, ds, ex)); + // } + //} + + //private async Task Client_TryMessageEdit(object sender, MessageResult e) + //{ + // DeviceSession ds = e.Device; + // if (ds == null) + // { + // ds = await this.Sessions.StartSession(e.DeviceId); + // e.Device = ds; + // } + + // ds.LastAction = DateTime.Now; + // ds.LastMessage = e.Message; + + // //Pre Loading Event + // await ds.ActiveForm.Edited(e); + + // //When form has been switched due navigation within the edit method, reopen Client_Message + // if (ds.FormSwitched) + // { + // await Client_Loop(sender, e); + // } + + //} + + //private async void Client_Action(object sender, MessageResult e) + //{ + // try + // { + // DeviceSession ds = this.Sessions.GetSession(e.DeviceId); + // e.Device = ds; + + // if (this.GetSetting(eSettings.LogAllMessages, false)) + // { + // OnMessage(new MessageIncomeEventArgs(e.DeviceId, ds, e)); + // } + + // await Client_Loop(sender, e); + // } + // catch (Exception ex) + // { + // DeviceSession ds = this.Sessions.GetSession(e.DeviceId); + // OnException(new SystemExceptionEventArgs(e.Message.Text, ds?.DeviceId ?? -1, ds, ex)); + // } + //} + + public void MessageLoopFactory_UnhandledCall(object sender, UnhandledCallEventArgs e) { - if (this.GetSetting(eSettings.SkipAllMessages, false)) - return; - - try - { - DeviceSession ds = this.Sessions.GetSession(e.DeviceId); - e.Device = ds; - - if (this.GetSetting(eSettings.LogAllMessages, false)) - { - OnMessage(new MessageIncomeEventArgs(e.DeviceId, ds, e)); - } - - //Call same, to handle received liked edited - ds?.OnMessageReceived(new MessageReceivedEventArgs(e.Message)); - - await Client_TryMessageEdit(sender, e); - } - catch (Telegram.Bot.Exceptions.ApiRequestException ex) - { - - } - catch (Exception ex) - { - DeviceSession ds = this.Sessions.GetSession(e.DeviceId); - OnException(new SystemExceptionEventArgs(e.Message.Text, ds?.DeviceId ?? -1, ds, ex)); - } - } - - private async Task Client_TryMessageEdit(object sender, MessageResult e) - { - DeviceSession ds = e.Device; - if (ds == null) - { - ds = await this.Sessions.StartSession(e.DeviceId); - e.Device = ds; - } - - ds.LastAction = DateTime.Now; - ds.LastMessage = e.Message; - - //Pre Loading Event - await ds.ActiveForm.Edited(e); - - //When form has been switched due navigation within the edit method, reopen Client_Message - if (ds.FormSwitched) - { - await Client_Loop(sender, e); - } - - } - - private async void Client_Action(object sender, MessageResult e) - { - try - { - DeviceSession ds = this.Sessions.GetSession(e.DeviceId); - e.Device = ds; - - if (this.GetSetting(eSettings.LogAllMessages, false)) - { - OnMessage(new MessageIncomeEventArgs(e.DeviceId, ds, e)); - } - - await Client_Loop(sender, e); - } - catch (Exception ex) - { - DeviceSession ds = this.Sessions.GetSession(e.DeviceId); - OnException(new SystemExceptionEventArgs(e.Message.Text, ds?.DeviceId ?? -1, ds, ex)); - } + OnUnhandledCall(e); } //private async void Client_TryAction(object sender, MessageResult e) diff --git a/TelegramBotBase/Builder/BotBaseBuilder.cs b/TelegramBotBase/Builder/BotBaseBuilder.cs index 9bc8794..dc4eb33 100644 --- a/TelegramBotBase/Builder/BotBaseBuilder.cs +++ b/TelegramBotBase/Builder/BotBaseBuilder.cs @@ -12,7 +12,7 @@ using TelegramBotBase.Interfaces; namespace TelegramBotBase.Builder { - public class BotBaseBuilder : IAPIKeySelectionStage, IStartFormSelectionStage, IBuildingStage, INetworkingSelectionStage, IBotCommandsStage, ISessionSerializationStage + public class BotBaseBuilder : IAPIKeySelectionStage, IMessageLoopSelectionStage, IStartFormSelectionStage, IBuildingStage, INetworkingSelectionStage, IBotCommandsStage, ISessionSerializationStage { String _apiKey = null; @@ -25,17 +25,55 @@ namespace TelegramBotBase.Builder IStateMachine _statemachine = null; + IMessageLoopFactory _messageloopfactory = null; + public static IAPIKeySelectionStage Create() { return new BotBaseBuilder(); } - public IStartFormSelectionStage WithAPIKey(string apiKey) + #region "Step 1" + + public IMessageLoopSelectionStage WithAPIKey(string apiKey) { this._apiKey = apiKey; return this; } + #endregion + + + #region "Step 2" + + public IStartFormSelectionStage DefaultMessageLoop() + { + _messageloopfactory = new Factories.MessageLoops.FormBaseMessageLoop(); + + return this; + } + + public IStartFormSelectionStage CustomMessageLoop(Type messageLoopClass) + { + if (messageLoopClass.IsSubclassOf(typeof(IMessageLoopFactory))) + throw new ArgumentException($"Not a subclass of {nameof(IMessageLoopFactory)}"); + + _messageloopfactory = messageLoopClass.GetConstructor(new Type[] { })?.Invoke(new object[] { }) as IMessageLoopFactory; + + return this; + } + + public IStartFormSelectionStage CustomMessageLoop() + where T : class, new() + { + _messageloopfactory = typeof(T).GetConstructor(new Type[] { })?.Invoke(new object[] { }) as IMessageLoopFactory; + + return this; + } + + #endregion + + #region "Step 3" + public INetworkingSelectionStage WithStartForm(Type startFormClass) { this._factory = new Factories.DefaultStartFormFactory(startFormClass); @@ -55,6 +93,8 @@ namespace TelegramBotBase.Builder return this; } + #endregion + public IBotCommandsStage WithProxy(string proxyAddress) { @@ -64,6 +104,7 @@ namespace TelegramBotBase.Builder return this; } + public IBotCommandsStage NoProxy() { _client = new MessageClient(_apiKey); @@ -79,6 +120,7 @@ namespace TelegramBotBase.Builder return this; } + public IBotCommandsStage WithHostAndPort(string proxyHost, int proxyPort) { _client = new MessageClient(_apiKey, proxyHost, proxyPort); @@ -139,6 +181,10 @@ namespace TelegramBotBase.Builder bb.StateMachine = _statemachine; + bb.MessageLoopFactory = _messageloopfactory; + + bb.MessageLoopFactory.UnhandledCall += bb.MessageLoopFactory_UnhandledCall; + return bb; } diff --git a/TelegramBotBase/Builder/Interfaces/IAPIKeySelectionStage.cs b/TelegramBotBase/Builder/Interfaces/IAPIKeySelectionStage.cs index 0d4c112..cfa6131 100644 --- a/TelegramBotBase/Builder/Interfaces/IAPIKeySelectionStage.cs +++ b/TelegramBotBase/Builder/Interfaces/IAPIKeySelectionStage.cs @@ -11,7 +11,7 @@ namespace TelegramBotBase.Builder.Interfaces /// /// /// - IStartFormSelectionStage WithAPIKey(String apiKey); + IMessageLoopSelectionStage WithAPIKey(String apiKey); } } diff --git a/TelegramBotBase/Builder/Interfaces/IMessageLoopSelectionStage.cs b/TelegramBotBase/Builder/Interfaces/IMessageLoopSelectionStage.cs new file mode 100644 index 0000000..125945e --- /dev/null +++ b/TelegramBotBase/Builder/Interfaces/IMessageLoopSelectionStage.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Text; +using TelegramBotBase.Form; +using TelegramBotBase.Interfaces; + +namespace TelegramBotBase.Builder.Interfaces +{ + public interface IMessageLoopSelectionStage + { + + /// + /// Chooses a default message loop. + /// + /// + /// + IStartFormSelectionStage DefaultMessageLoop(); + + /// + /// Chooses a custom message loop. + /// + /// + /// + IStartFormSelectionStage CustomMessageLoop(Type startFormClass); + + + /// + /// Chooses a custom message loop. + /// + /// + /// + IStartFormSelectionStage CustomMessageLoop() where T : class, new(); + + + } +} diff --git a/TelegramBotBase/Builder/Interfaces/INetworkingSelectionStage.cs b/TelegramBotBase/Builder/Interfaces/INetworkingSelectionStage.cs index 5456877..4b5bcce 100644 --- a/TelegramBotBase/Builder/Interfaces/INetworkingSelectionStage.cs +++ b/TelegramBotBase/Builder/Interfaces/INetworkingSelectionStage.cs @@ -8,6 +8,7 @@ namespace TelegramBotBase.Builder.Interfaces { public interface INetworkingSelectionStage { + /// /// Chooses a proxy as network configuration. /// @@ -29,6 +30,7 @@ namespace TelegramBotBase.Builder.Interfaces /// IBotCommandsStage WithBotClient(TelegramBotClient client); + /// /// Sets the custom proxy host and port. /// diff --git a/TelegramBotBase/Factories/MessageLoops/FormBaseMessageLoop.cs b/TelegramBotBase/Factories/MessageLoops/FormBaseMessageLoop.cs new file mode 100644 index 0000000..a902fe0 --- /dev/null +++ b/TelegramBotBase/Factories/MessageLoops/FormBaseMessageLoop.cs @@ -0,0 +1,131 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Telegram.Bot.Types; +using TelegramBotBase.Args; +using TelegramBotBase.Base; +using TelegramBotBase.Enums; +using TelegramBotBase.Interfaces; +using TelegramBotBase.Sessions; + +namespace TelegramBotBase.Factories.MessageLoops +{ + public class FormBaseMessageLoop : IMessageLoopFactory + { + private static object __evUnhandledCall = new object(); + + private EventHandlerList __Events = new EventHandlerList(); + + public FormBaseMessageLoop() + { + + } + + public async Task MessageLoop(BotBase Bot, DeviceSession session, UpdateResult ur, MessageResult mr) + { + var update = ur.RawData; + + + if (update.Type != Telegram.Bot.Types.Enums.UpdateType.Message + && update.Type != Telegram.Bot.Types.Enums.UpdateType.EditedMessage + && update.Type != Telegram.Bot.Types.Enums.UpdateType.CallbackQuery) + { + return; + } + + //Is this a bot command ? + if (mr.IsFirstHandler && mr.IsBotCommand && Bot.BotCommands.Count(a => "/" + a.Command == mr.BotCommand) > 0) + { + var sce = new BotCommandEventArgs(mr.BotCommand, mr.BotCommandParameters, mr.Message, session.DeviceId, session); + await Bot.OnBotCommand(sce); + + if (sce.Handled) + return; + } + + //var mr = new MessageResult(update); + + mr.Device = session; + + + //var message = update.Message ?? update.EditedMessage; + + var activeForm = session.ActiveForm; + + //Pre Loading Event + await activeForm.PreLoad(mr); + + //Send Load event to controls + await activeForm.LoadControls(mr); + + //Loading Event + await activeForm.Load(mr); + + //Is Attachment ? (Photo, Audio, Video, Contact, Location, Document) + if (mr.MessageType == Telegram.Bot.Types.Enums.MessageType.Contact | mr.MessageType == Telegram.Bot.Types.Enums.MessageType.Document | mr.MessageType == Telegram.Bot.Types.Enums.MessageType.Location | + mr.MessageType == Telegram.Bot.Types.Enums.MessageType.Photo | mr.MessageType == Telegram.Bot.Types.Enums.MessageType.Video | mr.MessageType == Telegram.Bot.Types.Enums.MessageType.Audio) + { + await activeForm.SentData(new DataResult(ur)); + } + + //Action Event + if (!session.FormSwitched && mr.IsAction) + { + //Send Action event to controls + await activeForm.ActionControls(mr); + + //Send Action event to form itself + await activeForm.Action(mr); + + if (!mr.Handled) + { + var uhc = new UnhandledCallEventArgs(ur.Message.Text, mr.RawData, session.DeviceId, mr.MessageId, ur.Message, session); + OnUnhandledCall(uhc); + + if (uhc.Handled) + { + mr.Handled = true; + if (!session.FormSwitched) + { + return; + } + } + } + + } + + if (!session.FormSwitched) + { + //Render Event + await activeForm.RenderControls(mr); + + await activeForm.Render(mr); + } + + } + + /// + /// Will be called if no form handeled this call + /// + public event EventHandler UnhandledCall + { + add + { + this.__Events.AddHandler(__evUnhandledCall, value); + } + remove + { + this.__Events.RemoveHandler(__evUnhandledCall, value); + } + } + + public void OnUnhandledCall(UnhandledCallEventArgs e) + { + (this.__Events[__evUnhandledCall] as EventHandler)?.Invoke(this, e); + + } + } +} diff --git a/TelegramBotBase/Form/ButtonBase.cs b/TelegramBotBase/Form/ButtonBase.cs index 54ffefe..efb4466 100644 --- a/TelegramBotBase/Form/ButtonBase.cs +++ b/TelegramBotBase/Form/ButtonBase.cs @@ -46,9 +46,9 @@ namespace TelegramBotBase.Form return InlineKeyboardButton.WithCallbackData(this.Text, id + this.Value); } - var ikb = new InlineKeyboardButton(); + var ikb = new InlineKeyboardButton(this.Text); - ikb.Text = this.Text; + //ikb.Text = this.Text; ikb.Url = this.Url; return ikb; diff --git a/TelegramBotBase/Form/GroupForm.cs b/TelegramBotBase/Form/GroupForm.cs index 6b460cf..ecdc01f 100644 --- a/TelegramBotBase/Form/GroupForm.cs +++ b/TelegramBotBase/Form/GroupForm.cs @@ -24,12 +24,12 @@ namespace TelegramBotBase.Form { case Telegram.Bot.Types.Enums.MessageType.ChatMembersAdded: - await OnMemberChanges(new MemberChangeEventArgs(Telegram.Bot.Types.Enums.MessageType.ChatMembersAdded, message, message.RawMessageData.Message.NewChatMembers)); + await OnMemberChanges(new MemberChangeEventArgs(Telegram.Bot.Types.Enums.MessageType.ChatMembersAdded, message, message.Message.NewChatMembers)); break; case Telegram.Bot.Types.Enums.MessageType.ChatMemberLeft: - await OnMemberChanges(new MemberChangeEventArgs(Telegram.Bot.Types.Enums.MessageType.ChatMemberLeft, message, message.RawMessageData.Message.LeftChatMember)); + await OnMemberChanges(new MemberChangeEventArgs(Telegram.Bot.Types.Enums.MessageType.ChatMemberLeft, message, message.Message.LeftChatMember)); break; diff --git a/TelegramBotBase/Interfaces/IMessageLoopFactory.cs b/TelegramBotBase/Interfaces/IMessageLoopFactory.cs new file mode 100644 index 0000000..fec857f --- /dev/null +++ b/TelegramBotBase/Interfaces/IMessageLoopFactory.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Threading.Tasks; +using Telegram.Bot.Types; +using TelegramBotBase.Args; +using TelegramBotBase.Base; +using TelegramBotBase.Sessions; + +namespace TelegramBotBase.Interfaces +{ + public interface IMessageLoopFactory + { + + Task MessageLoop(BotBase Bot, DeviceSession session, UpdateResult ur, MessageResult e); + + event EventHandler UnhandledCall; + + + } +} diff --git a/TelegramBotBase/Sessions/DeviceSession.cs b/TelegramBotBase/Sessions/DeviceSession.cs index fceac78..1238c66 100644 --- a/TelegramBotBase/Sessions/DeviceSession.cs +++ b/TelegramBotBase/Sessions/DeviceSession.cs @@ -769,7 +769,7 @@ namespace TelegramBotBase.Sessions /// /// /// - public T RAW(Func call) + public T RAW(Func call) { return call(this.Client.TelegramClient); } @@ -780,7 +780,7 @@ namespace TelegramBotBase.Sessions /// /// /// - public async Task API(Func> call) + public async Task API(Func> call) { var numberOfTries = 0; while (numberOfTries < DeviceSession.MaxNumberOfRetries) @@ -794,8 +794,8 @@ namespace TelegramBotBase.Sessions if (ex.ErrorCode != 429) throw; - if (ex.Parameters != null) - await Task.Delay(ex.Parameters.RetryAfter * 1000); + if (ex.Parameters != null && ex.Parameters.RetryAfter != null) + await Task.Delay(ex.Parameters.RetryAfter.Value * 1000); numberOfTries++; } @@ -808,7 +808,7 @@ namespace TelegramBotBase.Sessions /// /// /// - public async Task API(Func call) + public async Task API(Func call) { var numberOfTries = 0; while (numberOfTries < DeviceSession.MaxNumberOfRetries) @@ -823,8 +823,8 @@ namespace TelegramBotBase.Sessions if (ex.ErrorCode != 429) throw; - if (ex.Parameters != null) - await Task.Delay(ex.Parameters.RetryAfter * 1000); + if (ex.Parameters != null && ex.Parameters.RetryAfter != null) + await Task.Delay(ex.Parameters.RetryAfter.Value * 1000); numberOfTries++; }