Merge 9b3e3de55df176ea66f953d92a330c4d2ce25ed7 into 26152ee348bafaf898583217217d60de0cb75c60
This commit is contained in:
commit
28ff3ed5ce
47
Examples/MiddlewareBaseBot/Forms/StartForm.cs
Normal file
47
Examples/MiddlewareBaseBot/Forms/StartForm.cs
Normal file
@ -0,0 +1,47 @@
|
||||
using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Form;
|
||||
|
||||
internal sealed class StartForm : FormBase
|
||||
{
|
||||
public override async Task PreLoad(MessageResult message)
|
||||
{
|
||||
await this.Device.Send("PreLoad");
|
||||
|
||||
await Task.Delay(200);
|
||||
}
|
||||
|
||||
public override async Task Load(MessageResult message)
|
||||
{
|
||||
await this.Device.Send("Load");
|
||||
|
||||
await Task.Delay(200);
|
||||
}
|
||||
|
||||
public override async Task Edited(MessageResult message)
|
||||
{
|
||||
await this.Device.Send("Edited");
|
||||
|
||||
await Task.Delay(200);
|
||||
}
|
||||
|
||||
public override async Task Action(MessageResult message)
|
||||
{
|
||||
await this.Device.Send("Action");
|
||||
|
||||
await Task.Delay(200);
|
||||
}
|
||||
|
||||
public override async Task SentData(DataResult data)
|
||||
{
|
||||
await this.Device.Send("SentData");
|
||||
|
||||
await Task.Delay(200);
|
||||
}
|
||||
|
||||
public override async Task Render(MessageResult message)
|
||||
{
|
||||
await this.Device.Send("Render");
|
||||
|
||||
await Task.Delay(200);
|
||||
}
|
||||
}
|
||||
14
Examples/MiddlewareBaseBot/MiddlewareBaseBot.csproj
Normal file
14
Examples/MiddlewareBaseBot/MiddlewareBaseBot.csproj
Normal file
@ -0,0 +1,14 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\TelegramBotBase\TelegramBotBase.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
195
Examples/MiddlewareBaseBot/Program.cs
Normal file
195
Examples/MiddlewareBaseBot/Program.cs
Normal file
@ -0,0 +1,195 @@
|
||||
using Telegram.Bot.Types.Enums;
|
||||
using TelegramBotBase;
|
||||
using TelegramBotBase.Builder;
|
||||
using TelegramBotBase.MessageLoops.Extensions;
|
||||
|
||||
public class Program
|
||||
{
|
||||
private static async Task Main(string[] args)
|
||||
{
|
||||
var bot = GetPhotoBot();
|
||||
|
||||
await bot.Start();
|
||||
|
||||
Console.WriteLine("Bot started :)");
|
||||
|
||||
Console.ReadLine();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a bot with middleware message loop and authentication for admin user
|
||||
/// </summary>
|
||||
private static BotBase GetAdminBot()
|
||||
{
|
||||
var bot = BotBaseBuilder
|
||||
.Create()
|
||||
.WithAPIKey(Environment.GetEnvironmentVariable("API_KEY") ?? throw new Exception("API_KEY is not set"))
|
||||
.MiddlewareMessageLoop(
|
||||
messageLoop =>
|
||||
messageLoop
|
||||
.Use(async (container, next) =>
|
||||
{
|
||||
var updateResult = container.UpdateResult;
|
||||
if (updateResult.Message is not null)
|
||||
{
|
||||
if (updateResult.Message.From is not null)
|
||||
{
|
||||
var fromId = updateResult.Message.From.Id;
|
||||
|
||||
if (fromId == 1)
|
||||
{
|
||||
await next();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return;
|
||||
})
|
||||
.UseValidUpdateTypes(
|
||||
UpdateType.Message,
|
||||
UpdateType.EditedMessage,
|
||||
UpdateType.CallbackQuery)
|
||||
.UseBotCommands()
|
||||
.UseForms())
|
||||
.WithStartForm<StartForm>()
|
||||
.NoProxy()
|
||||
.DefaultCommands()
|
||||
.NoSerialization()
|
||||
.UsePersian()
|
||||
.Build();
|
||||
|
||||
return bot;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a bot with middleware message loop for handle inline queries
|
||||
/// </summary>
|
||||
private static BotBase GetInlineQueryBot()
|
||||
{
|
||||
var bot = BotBaseBuilder
|
||||
.Create()
|
||||
.WithAPIKey(Environment.GetEnvironmentVariable("API_KEY") ?? throw new Exception("API_KEY is not set"))
|
||||
.MiddlewareMessageLoop(
|
||||
messageLoop =>
|
||||
messageLoop
|
||||
.UseValidUpdateTypes(UpdateType.InlineQuery)
|
||||
.Use(async (container, next) =>
|
||||
{
|
||||
var query = container.UpdateResult.RawData.InlineQuery.Query;
|
||||
|
||||
if (!string.IsNullOrWhiteSpace(query))
|
||||
{
|
||||
// logic
|
||||
|
||||
await next();
|
||||
}
|
||||
|
||||
return;
|
||||
}))
|
||||
.WithStartForm<StartForm>()
|
||||
.NoProxy()
|
||||
.DefaultCommands()
|
||||
.NoSerialization()
|
||||
.UsePersian()
|
||||
.Build();
|
||||
|
||||
return bot;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a bot with middleware message loop like form base message loop
|
||||
/// </summary>
|
||||
private static BotBase GetFormBaseBot()
|
||||
{
|
||||
var bot = BotBaseBuilder
|
||||
.Create()
|
||||
.WithAPIKey(Environment.GetEnvironmentVariable("API_KEY") ?? throw new Exception("API_KEY is not set"))
|
||||
.MiddlewareMessageLoop(
|
||||
messageLoop =>
|
||||
messageLoop
|
||||
.UseValidUpdateTypes(
|
||||
UpdateType.Message,
|
||||
UpdateType.EditedMessage,
|
||||
UpdateType.CallbackQuery)
|
||||
.UseBotCommands()
|
||||
.UseForms())
|
||||
// OR instead of UseForms
|
||||
// .UsePreLoad()
|
||||
// .UseLoad()
|
||||
// .UseAllAttachments()
|
||||
// .UseActions()
|
||||
// .UseRender()
|
||||
.WithStartForm<StartForm>()
|
||||
.NoProxy()
|
||||
.DefaultCommands()
|
||||
.NoSerialization()
|
||||
.UsePersian()
|
||||
.Build();
|
||||
|
||||
return bot;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a bot with middleware message loop like form base message loop
|
||||
/// </summary>
|
||||
private static BotBase GetFullBot()
|
||||
{
|
||||
var bot = BotBaseBuilder
|
||||
.Create()
|
||||
.WithAPIKey(Environment.GetEnvironmentVariable("API_KEY") ?? throw new Exception("API_KEY is not set"))
|
||||
.MiddlewareMessageLoop(
|
||||
messageLoop =>
|
||||
messageLoop
|
||||
.UseBotCommands()
|
||||
.UseForms())
|
||||
.WithStartForm<StartForm>()
|
||||
.NoProxy()
|
||||
.DefaultCommands()
|
||||
.NoSerialization()
|
||||
.UsePersian()
|
||||
.Build();
|
||||
|
||||
return bot;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a bot with middleware message loop like minimal message loop
|
||||
/// </summary>
|
||||
private static BotBase GetMinimalBot()
|
||||
{
|
||||
var bot = BotBaseBuilder
|
||||
.Create()
|
||||
.WithAPIKey(Environment.GetEnvironmentVariable("API_KEY") ?? throw new Exception("API_KEY is not set"))
|
||||
.MiddlewareMessageLoop(
|
||||
messageLoop =>
|
||||
messageLoop
|
||||
.UseLoad())
|
||||
.WithStartForm<StartForm>()
|
||||
.NoProxy()
|
||||
.DefaultCommands()
|
||||
.NoSerialization()
|
||||
.UsePersian()
|
||||
.Build();
|
||||
|
||||
return bot;
|
||||
}
|
||||
|
||||
private static BotBase GetPhotoBot()
|
||||
{
|
||||
var bot = BotBaseBuilder
|
||||
.Create()
|
||||
.WithAPIKey(Environment.GetEnvironmentVariable("API_KEY") ?? throw new Exception("API_KEY is not set"))
|
||||
.MiddlewareMessageLoop(
|
||||
messageLoop =>
|
||||
messageLoop
|
||||
.UseAttachments(MessageType.Photo))
|
||||
.WithStartForm<StartForm>()
|
||||
.NoProxy()
|
||||
.DefaultCommands()
|
||||
.NoSerialization()
|
||||
.UsePersian()
|
||||
.Build();
|
||||
|
||||
return bot;
|
||||
}
|
||||
}
|
||||
@ -146,6 +146,12 @@ public class BotBaseBuilder : IAPIKeySelectionStage, IMessageLoopSelectionStage,
|
||||
return this;
|
||||
}
|
||||
|
||||
public IStartFormSelectionStage MiddlewareMessageLoop(Func<MiddlewareBaseMessageLoop, MiddlewareBaseMessageLoop> messageLoopConfiguration)
|
||||
{
|
||||
_messageLoopFactory = messageLoopConfiguration(new MiddlewareBaseMessageLoop());
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
public IStartFormSelectionStage MinimalMessageLoop()
|
||||
{
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
using TelegramBotBase.Interfaces;
|
||||
using System;
|
||||
using TelegramBotBase.Interfaces;
|
||||
using TelegramBotBase.MessageLoops;
|
||||
|
||||
namespace TelegramBotBase.Builder.Interfaces;
|
||||
|
||||
@ -12,6 +14,12 @@ public interface IMessageLoopSelectionStage
|
||||
IStartFormSelectionStage DefaultMessageLoop();
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Choses a fully customizable middleware-based message loop.
|
||||
/// </summary>
|
||||
IStartFormSelectionStage MiddlewareMessageLoop(Func<MiddlewareBaseMessageLoop, MiddlewareBaseMessageLoop> messageLoopConfiguration);
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Chooses a minimalistic message loop, which catches all update types and only calls the Load function.
|
||||
/// </summary>
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
namespace TelegramBotBase.Localizations
|
||||
namespace TelegramBotBase.Localizations;
|
||||
|
||||
public sealed class Persian : Localization
|
||||
{
|
||||
public sealed class Persian : Localization
|
||||
{
|
||||
public Persian()
|
||||
{
|
||||
Values["Language"] = "فارسی";
|
||||
@ -33,5 +33,4 @@
|
||||
Values["ButtonGrid_SearchIcon"] = "🔍";
|
||||
Values["ButtonGrid_TagIcon"] = "📁";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -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
|
||||
{
|
||||
/// <summary>
|
||||
/// Adds middleware to the message loop then returns the message loop
|
||||
/// </summary>
|
||||
public static MiddlewareBaseMessageLoop Use(this MiddlewareBaseMessageLoop messageLoop, Func<MessageContainer, Func<Task>, Task> middleware)
|
||||
{
|
||||
messageLoop.AddMiddleware(middleware);
|
||||
|
||||
return messageLoop;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds update type validator middleware to the message loop then returns message loop
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds bot commands handler middleware to the message loop then returns message loop
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds forms handler middleware to the message loop then returns message loop
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds forms pre loads handler middleware to the message loop then returns message loop
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds forms loads handler middleware to the message loop then returns message loop
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds forms custom attachments handler middleware to the message loop then returns message loop
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds forms all attachments handler middleware to the message loop then returns message loop
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds forms actions handler middleware to the message loop then returns message loop
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds forms renders handler middleware to the message loop then returns message loop
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
}
|
||||
@ -12,7 +12,7 @@ namespace TelegramBotBase.MessageLoops;
|
||||
/// <summary>
|
||||
/// Thats the default message loop which reacts to Message, EditMessage and CallbackQuery.
|
||||
/// </summary>
|
||||
public class FormBaseMessageLoop : IMessageLoopFactory
|
||||
public sealed class FormBaseMessageLoop : IMessageLoopFactory
|
||||
{
|
||||
private static readonly object EvUnhandledCall = new();
|
||||
|
||||
@ -22,7 +22,6 @@ public class FormBaseMessageLoop : IMessageLoopFactory
|
||||
{
|
||||
var update = ur.RawData;
|
||||
|
||||
|
||||
if (update.Type != UpdateType.Message
|
||||
&& update.Type != UpdateType.EditedMessage
|
||||
&& update.Type != UpdateType.CallbackQuery)
|
||||
|
||||
@ -12,7 +12,7 @@ namespace TelegramBotBase.MessageLoops;
|
||||
/// <summary>
|
||||
/// This message loop reacts to all update types.
|
||||
/// </summary>
|
||||
public class FullMessageLoop : IMessageLoopFactory
|
||||
public sealed class FullMessageLoop : IMessageLoopFactory
|
||||
{
|
||||
private static readonly object EvUnhandledCall = new();
|
||||
|
||||
@ -20,9 +20,6 @@ public class FullMessageLoop : IMessageLoopFactory
|
||||
|
||||
public async Task MessageLoop(BotBase bot, DeviceSession session, UpdateResult ur, MessageResult mr)
|
||||
{
|
||||
var update = ur.RawData;
|
||||
|
||||
|
||||
//Is this a bot command ?
|
||||
if (mr.IsFirstHandler && mr.IsBotCommand && bot.IsKnownBotCommand(mr.BotCommand))
|
||||
{
|
||||
@ -50,6 +47,7 @@ public class FullMessageLoop : IMessageLoopFactory
|
||||
//Loading Event
|
||||
await activeForm.Load(mr);
|
||||
|
||||
var update = ur.RawData;
|
||||
|
||||
//Is Attachment ? (Photo, Audio, Video, Contact, Location, Document) (Ignore Callback Queries)
|
||||
if (update.Type == UpdateType.Message)
|
||||
|
||||
77
TelegramBotBase/MessageLoops/MiddlewareBaseMessageLoop.cs
Normal file
77
TelegramBotBase/MessageLoops/MiddlewareBaseMessageLoop.cs
Normal file
@ -0,0 +1,77 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using TelegramBotBase.Args;
|
||||
using TelegramBotBase.Base;
|
||||
using TelegramBotBase.Interfaces;
|
||||
using TelegramBotBase.Sessions;
|
||||
|
||||
namespace TelegramBotBase.MessageLoops;
|
||||
|
||||
/// <summary>
|
||||
/// This message loop based on middleware pattern
|
||||
/// </summary>
|
||||
public sealed class MiddlewareBaseMessageLoop : IMessageLoopFactory
|
||||
{
|
||||
private List<Func<MessageContainer, Func<Task>, Task>> Middlewares = new();
|
||||
|
||||
public event EventHandler<UnhandledCallEventArgs> UnhandledCall;
|
||||
|
||||
public async Task MessageLoop(BotBase bot, DeviceSession session, UpdateResult ur, MessageResult mr)
|
||||
{
|
||||
ur.Device = session;
|
||||
mr.Device = session;
|
||||
|
||||
var messageContainer = new MessageContainer(bot, session, ur, mr);
|
||||
|
||||
if (Middlewares.Any())
|
||||
{
|
||||
int middlewareIndex = 0;
|
||||
|
||||
await InvokeMiddleware(messageContainer, middlewareIndex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Invokes middleware with index
|
||||
/// </summary>
|
||||
private async Task InvokeMiddleware(MessageContainer messageContainer, int middlewareIndex)
|
||||
{
|
||||
await Middlewares[middlewareIndex]
|
||||
.Invoke(messageContainer, async () =>
|
||||
{
|
||||
int nextMiddlewareIndex = middlewareIndex + 1;
|
||||
if (nextMiddlewareIndex < Middlewares.Count)
|
||||
{
|
||||
await InvokeMiddleware(messageContainer, nextMiddlewareIndex);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds a new middleware
|
||||
/// </summary>
|
||||
public void AddMiddleware(Func<MessageContainer, Func<Task>, Task> middleware)
|
||||
{
|
||||
Middlewares.Add(middleware);
|
||||
}
|
||||
}
|
||||
|
||||
public struct MessageContainer
|
||||
{
|
||||
public BotBase BotBase { get; private set; }
|
||||
public DeviceSession DeviceSession { get; private set; }
|
||||
public UpdateResult UpdateResult { get; private set; }
|
||||
public MessageResult MessageResult { get; private set; }
|
||||
|
||||
public MessageContainer(BotBase botBase, DeviceSession deviceSession, UpdateResult updateResult, MessageResult messageResult)
|
||||
{
|
||||
BotBase = botBase;
|
||||
DeviceSession = deviceSession;
|
||||
UpdateResult = updateResult;
|
||||
MessageResult = messageResult;
|
||||
}
|
||||
}
|
||||
@ -11,7 +11,7 @@ namespace TelegramBotBase.MessageLoops;
|
||||
/// <summary>
|
||||
/// This is a minimal message loop which will react to all update types and just calling the Load method.
|
||||
/// </summary>
|
||||
public class MinimalMessageLoop : IMessageLoopFactory
|
||||
public sealed class MinimalMessageLoop : IMessageLoopFactory
|
||||
{
|
||||
private static readonly object EvUnhandledCall = new();
|
||||
|
||||
@ -19,9 +19,6 @@ public class MinimalMessageLoop : IMessageLoopFactory
|
||||
|
||||
public async Task MessageLoop(BotBase bot, DeviceSession session, UpdateResult ur, MessageResult mr)
|
||||
{
|
||||
var update = ur.RawData;
|
||||
|
||||
|
||||
mr.Device = session;
|
||||
|
||||
var activeForm = session.ActiveForm;
|
||||
|
||||
@ -32,6 +32,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BotAndWebApplication", "Exa
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InlineAndReplyCombination", "Examples\InlineAndReplyCombination\InlineAndReplyCombination.csproj", "{067E8EBE-F90A-4AFF-A0FF-20578216486E}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MiddlewareBaseBot", "Examples\MiddlewareBaseBot\MiddlewareBaseBot.csproj", "{8D053824-966C-4F82-B184-4840DB36D5F2}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "DependencyInjection", "Examples\DependencyInjection\DependencyInjection.csproj", "{689B16BC-200E-4C68-BB2E-8B209070849B}"
|
||||
EndProject
|
||||
Global
|
||||
@ -80,6 +82,10 @@ Global
|
||||
{067E8EBE-F90A-4AFF-A0FF-20578216486E}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{067E8EBE-F90A-4AFF-A0FF-20578216486E}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{067E8EBE-F90A-4AFF-A0FF-20578216486E}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{8D053824-966C-4F82-B184-4840DB36D5F2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{8D053824-966C-4F82-B184-4840DB36D5F2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{8D053824-966C-4F82-B184-4840DB36D5F2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{8D053824-966C-4F82-B184-4840DB36D5F2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{689B16BC-200E-4C68-BB2E-8B209070849B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{689B16BC-200E-4C68-BB2E-8B209070849B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{689B16BC-200E-4C68-BB2E-8B209070849B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
@ -97,6 +103,7 @@ Global
|
||||
{261BED47-0404-4A9A-86FC-047DE42A7D25} = {BFA71E3F-31C0-4FC1-A320-4DCF704768C5}
|
||||
{52EA3201-02E8-46F5-87C4-B4752C8A815C} = {BFA71E3F-31C0-4FC1-A320-4DCF704768C5}
|
||||
{067E8EBE-F90A-4AFF-A0FF-20578216486E} = {BFA71E3F-31C0-4FC1-A320-4DCF704768C5}
|
||||
{8D053824-966C-4F82-B184-4840DB36D5F2} = {BFA71E3F-31C0-4FC1-A320-4DCF704768C5}
|
||||
{689B16BC-200E-4C68-BB2E-8B209070849B} = {BFA71E3F-31C0-4FC1-A320-4DCF704768C5}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user