diff --git a/TelegramBotBase/MessageLoops/Extensions/MiddlewareBaseMessageLoopExtensions.cs b/TelegramBotBase/MessageLoops/Extensions/MiddlewareBaseMessageLoopExtensions.cs new file mode 100644 index 0000000..e6cf105 --- /dev/null +++ b/TelegramBotBase/MessageLoops/Extensions/MiddlewareBaseMessageLoopExtensions.cs @@ -0,0 +1,310 @@ +using System; +using System.Linq; +using System.Threading.Tasks; +using Telegram.Bot.Types; +using Telegram.Bot.Types.Enums; +using TelegramBotBase.Args; +using TelegramBotBase.Base; +using static System.Collections.Specialized.BitVector32; + +namespace TelegramBotBase.MessageLoops.Extensions; + +public static class MiddlewareBaseMessageLoopExtensions +{ + /// + /// Adds middleware to the message loop then returns the message loop + /// + public static MiddlewareBaseMessageLoop Use(this MiddlewareBaseMessageLoop messageLoop, Func, Task> middleware) + { + messageLoop.AddMiddleware(middleware); + + return messageLoop; + } + + /// + /// Adds update type validator middleware to the message loop then returns message loop + /// + public static MiddlewareBaseMessageLoop UseValidUpdateTypes(this MiddlewareBaseMessageLoop messageLoop, params UpdateType[] updateTypes) + { + messageLoop.Use(async (container, next) => + { + var updateType = container.UpdateResult.RawData.Type; + + if (updateTypes.Contains(updateType)) + { + await next(); + } + }); + + return messageLoop; + } + + /// + /// Adds bot commands handler middleware to the message loop then returns message loop + /// + public static MiddlewareBaseMessageLoop UseBotCommands(this MiddlewareBaseMessageLoop messageLoop) + { + messageLoop.Use(async (container, next) => + { + var botBase = container.BotBase; + var messageResult = container.MessageResult; + + if (messageResult.IsFirstHandler && + messageResult.IsBotCommand && + botBase.IsKnownBotCommand(messageResult.BotCommand)) + { + var deviceSession = container.DeviceSession; + + var sce = + new BotCommandEventArgs(messageResult.BotCommand, + messageResult.BotCommandParameters, + messageResult.Message, + deviceSession.DeviceId, + deviceSession); + + await botBase.OnBotCommand(sce); + + if (sce.Handled) + { + return; + } + } + + await next(); + }); + + return messageLoop; + } + + /// + /// Adds forms handler middleware to the message loop then returns message loop + /// + public static MiddlewareBaseMessageLoop UseForms(this MiddlewareBaseMessageLoop messageLoop) + { + messageLoop.Use(async (container, next) => + { + var activeForm = container.DeviceSession.ActiveForm; + var messageResult = container.MessageResult; + + //Pre Loading Event + await activeForm.PreLoad(messageResult); + + //Send Load event to controls + await activeForm.LoadControls(messageResult); + + //Loading Event + await activeForm.Load(messageResult); + + var updateType = container.UpdateResult.RawData.Type; + + //Is Attachment ? (Photo, Audio, Video, Contact, Location, Document) (Ignore Callback Queries) + if (updateType == UpdateType.Message) + { + if ((messageResult.MessageType == MessageType.Contact) + | (messageResult.MessageType == MessageType.Document) + | (messageResult.MessageType == MessageType.Location) + | (messageResult.MessageType == MessageType.Photo) + | (messageResult.MessageType == MessageType.Video) + | (messageResult.MessageType == MessageType.Audio)) + { + var updateResult = container.UpdateResult; + + await activeForm.SentData(new DataResult(updateResult)); + } + } + + var deviceSession = container.DeviceSession; + + //Action Event + if (!deviceSession.FormSwitched && messageResult.IsAction) + { + //Send Action event to controls + await activeForm.ActionControls(messageResult); + + //Send Action event to form itself + await activeForm.Action(messageResult); + + if (!messageResult.Handled) + { + messageResult.Handled = true; + return; + } + } + + if (!deviceSession.FormSwitched) + { + //Render Event + await activeForm.RenderControls(messageResult); + + await activeForm.Render(messageResult); + } + + await next(); + }); + + return messageLoop; + } + + /// + /// Adds forms pre loads handler middleware to the message loop then returns message loop + /// + public static MiddlewareBaseMessageLoop UsePreLoad(this MiddlewareBaseMessageLoop messageLoop) + { + messageLoop.Use(async (container, next) => + { + var activeForm = container.DeviceSession.ActiveForm; + var messageResult = container.MessageResult; + + await activeForm.PreLoad(messageResult); + + await next(); + }); + + return messageLoop; + } + + /// + /// Adds forms loads handler middleware to the message loop then returns message loop + /// + public static MiddlewareBaseMessageLoop UseLoad(this MiddlewareBaseMessageLoop messageLoop) + { + messageLoop.Use(async (container, next) => + { + var activeForm = container.DeviceSession.ActiveForm; + var messageResult = container.MessageResult; + + await activeForm.LoadControls(messageResult); + await activeForm.Load(messageResult); + + await next(); + }); + + return messageLoop; + } + + /// + /// Adds forms custom attachments handler middleware to the message loop then returns message loop + /// + public static MiddlewareBaseMessageLoop UseAttachments(this MiddlewareBaseMessageLoop messageLoop, params MessageType[] validAttachments) + { + messageLoop.Use(async (container, next) => + { + var activeForm = container.DeviceSession.ActiveForm; + var messageResult = container.MessageResult; + var updateType = container.UpdateResult.RawData.Type; + + //Is Attachment ? (Photo, Audio, Video, Contact, Location, Document) (Ignore Callback Queries) + if (updateType == UpdateType.Message) + { + if ((messageResult.MessageType == MessageType.Contact) + | (messageResult.MessageType == MessageType.Document) + | (messageResult.MessageType == MessageType.Location) + | (messageResult.MessageType == MessageType.Photo) + | (messageResult.MessageType == MessageType.Video) + | (messageResult.MessageType == MessageType.Audio)) + { + if (validAttachments.Contains(messageResult.MessageType)) + { + var updateResult = container.UpdateResult; + + await activeForm.SentData(new DataResult(updateResult)); + } + } + } + + await next(); + }); + + return messageLoop; + } + + /// + /// Adds forms all attachments handler middleware to the message loop then returns message loop + /// + public static MiddlewareBaseMessageLoop UseAllAttachments(this MiddlewareBaseMessageLoop messageLoop) + { + messageLoop.Use(async (container, next) => + { + var activeForm = container.DeviceSession.ActiveForm; + var messageResult = container.MessageResult; + var updateType = container.UpdateResult.RawData.Type; + + //Is Attachment ? (Photo, Audio, Video, Contact, Location, Document) (Ignore Callback Queries) + if (updateType == UpdateType.Message) + { + if ((messageResult.MessageType == MessageType.Contact) + | (messageResult.MessageType == MessageType.Document) + | (messageResult.MessageType == MessageType.Location) + | (messageResult.MessageType == MessageType.Photo) + | (messageResult.MessageType == MessageType.Video) + | (messageResult.MessageType == MessageType.Audio)) + { + var updateResult = container.UpdateResult; + + await activeForm.SentData(new DataResult(updateResult)); + } + } + + await next(); + }); + + return messageLoop; + } + + /// + /// Adds forms actions handler middleware to the message loop then returns message loop + /// + public static MiddlewareBaseMessageLoop UseActions(this MiddlewareBaseMessageLoop messageLoop) + { + messageLoop.Use(async (container, next) => + { + var messageResult = container.MessageResult; + var deviceSession = container.DeviceSession; + var activeForm = deviceSession.ActiveForm; + + //Action Event + if (!deviceSession.FormSwitched && messageResult.IsAction) + { + //Send Action event to controls + await activeForm.ActionControls(messageResult); + + //Send Action event to form itself + await activeForm.Action(messageResult); + + if (!messageResult.Handled) + { + messageResult.Handled = true; + return; + } + } + + await next(); + }); + + return messageLoop; + } + + /// + /// Adds forms renders handler middleware to the message loop then returns message loop + /// + public static MiddlewareBaseMessageLoop UseRender(this MiddlewareBaseMessageLoop messageLoop) + { + messageLoop.Use(async (container, next) => + { + var messageResult = container.MessageResult; + var deviceSession = container.DeviceSession; + var activeForm = deviceSession.ActiveForm; + + if (!deviceSession.FormSwitched) + { + await activeForm.RenderControls(messageResult); + + await activeForm.Render(messageResult); + } + + await next(); + }); + + return messageLoop; + } +}