* Changed public API overview generator behaviour, now working only in DEBUG builds
* Fixed wrong LeveldDebug method calls after moving logic from providers to router * Added independent "IndentFlags" property to inner debugger class * Fixed debug logging in few places * Removed "ICollectingOptions" and merged it with new options abstract "ITelegratorOptions" * Added WebHook version of hosting class
This commit is contained in:
@@ -0,0 +1,25 @@
|
|||||||
|
using Telegrator.Hosting;
|
||||||
|
using Telegrator.Hosting.Web;
|
||||||
|
|
||||||
|
namespace Telegrator.ConsoleHost.Web
|
||||||
|
{
|
||||||
|
public class Program
|
||||||
|
{
|
||||||
|
public static void Main(string[] args)
|
||||||
|
{
|
||||||
|
TelegramBotWebHostBuilder builder = TelegramBotWebHost.CreateBuilder(new TelegramBotWebOptions()
|
||||||
|
{
|
||||||
|
Args = args,
|
||||||
|
WebhookUri = "https://telegrator-hooker.cloudpub.ru/bot",
|
||||||
|
DescendDescriptorIndex = false,
|
||||||
|
ExceptIntersectingCommandAliases = true,
|
||||||
|
});
|
||||||
|
|
||||||
|
builder.Handlers.CollectHandlersAssemblyWide();
|
||||||
|
|
||||||
|
TelegramBotWebHost telegramBot = builder.Build();
|
||||||
|
telegramBot.SetBotCommands();
|
||||||
|
telegramBot.Run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
{
|
||||||
|
"profiles": {
|
||||||
|
"http": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
},
|
||||||
|
"dotnetRunMessages": true,
|
||||||
|
"applicationUrl": "http://localhost:5284"
|
||||||
|
},
|
||||||
|
"https": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
},
|
||||||
|
"dotnetRunMessages": true,
|
||||||
|
"applicationUrl": "https://localhost:8080"
|
||||||
|
},
|
||||||
|
"IIS Express": {
|
||||||
|
"commandName": "IISExpress",
|
||||||
|
"launchBrowser": true,
|
||||||
|
"environmentVariables": {
|
||||||
|
"ASPNETCORE_ENVIRONMENT": "Development"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"$schema": "http://json.schemastore.org/launchsettings.json",
|
||||||
|
"iisSettings": {
|
||||||
|
"windowsAuthentication": false,
|
||||||
|
"anonymousAuthentication": true,
|
||||||
|
"iisExpress": {
|
||||||
|
"applicationUrl": "http://localhost:12266",
|
||||||
|
"sslPort": 44308
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,13 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\Telegrator.Hosting.Web\Telegrator.Hosting.Web.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,28 @@
|
|||||||
|
{
|
||||||
|
"Logging": {
|
||||||
|
"LogLevel": {
|
||||||
|
"Default": "Information",
|
||||||
|
"Microsoft.AspNetCore": "Warning"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
"TelegramBotClientOptions": {
|
||||||
|
"Token": "7625502724:AAE5QPuX5P_lk2HwV4kdE6guoM6nsFQbe-c"
|
||||||
|
},
|
||||||
|
|
||||||
|
"TelegramBotOptions": {
|
||||||
|
"ExecuteOnlyFirstFoundHanlder": true,
|
||||||
|
"MaximumParallelWorkingHandlers": null
|
||||||
|
},
|
||||||
|
|
||||||
|
"HostOptions": {
|
||||||
|
"ShutdownTimeout": 10,
|
||||||
|
"BackgroundServiceExceptionBehavior": "StopHost"
|
||||||
|
},
|
||||||
|
|
||||||
|
"Shapes": {
|
||||||
|
"Token": "AX5IHZHSZMGQVEC6TILCOFLALPQRDDUWEBT8UYPH0OW"
|
||||||
|
},
|
||||||
|
|
||||||
|
"AllowedHosts": "*"
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ using System.Collections.Immutable;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Xml.Linq;
|
using System.Xml.Linq;
|
||||||
|
|
||||||
|
#pragma warning disable CS0162
|
||||||
namespace Telegrator.Generators
|
namespace Telegrator.Generators
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -14,6 +15,11 @@ namespace Telegrator.Generators
|
|||||||
{
|
{
|
||||||
public void Initialize(IncrementalGeneratorInitializationContext context)
|
public void Initialize(IncrementalGeneratorInitializationContext context)
|
||||||
{
|
{
|
||||||
|
#if RELEASE
|
||||||
|
// DEBUG ONLY GENERATOR
|
||||||
|
return;
|
||||||
|
#endif
|
||||||
|
|
||||||
IncrementalValueProvider<ImmutableArray<BaseTypeDeclarationSyntax>> typeDeclarations = context.SyntaxProvider
|
IncrementalValueProvider<ImmutableArray<BaseTypeDeclarationSyntax>> typeDeclarations = context.SyntaxProvider
|
||||||
.CreateSyntaxProvider(
|
.CreateSyntaxProvider(
|
||||||
predicate: (node, _) => node is ClassDeclarationSyntax || node is InterfaceDeclarationSyntax || node is StructDeclarationSyntax || node is EnumDeclarationSyntax,
|
predicate: (node, _) => node is ClassDeclarationSyntax || node is InterfaceDeclarationSyntax || node is StructDeclarationSyntax || node is EnumDeclarationSyntax,
|
||||||
|
|||||||
@@ -1,8 +1,14 @@
|
|||||||
using Telegrator.Hosting.Components;
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.AspNetCore.Routing;
|
||||||
|
using Telegrator.Hosting.Components;
|
||||||
|
|
||||||
namespace Telegrator.Hosting.Web.Components
|
namespace Telegrator.Hosting.Web.Components
|
||||||
{
|
{
|
||||||
public interface ITelegramBotWebHost : ITelegramBotHost//, IEndpointRouteBuilder
|
/// <summary>
|
||||||
|
/// Interface for Telegram bot hosts with Webhook update receiving.
|
||||||
|
/// Combines wbe application capabilities with reactive Telegram bot functionality.
|
||||||
|
/// </summary>
|
||||||
|
public interface ITelegramBotWebHost : ITelegramBotHost, IEndpointRouteBuilder, IApplicationBuilder, IAsyncDisposable
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
// This file is used by Code Analysis to maintain SuppressMessage
|
||||||
|
// attributes that are applied to this project.
|
||||||
|
// Project-level suppressions either have no target or are given
|
||||||
|
// a specific target and scoped to a namespace, type, member, etc.
|
||||||
|
|
||||||
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
|
||||||
|
[assembly: SuppressMessage("Style", "IDE0290")]
|
||||||
|
[assembly: SuppressMessage("Style", "IDE0090")]
|
||||||
|
[assembly: SuppressMessage("Usage", "CA2254")]
|
||||||
@@ -1,49 +1,93 @@
|
|||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
|
using Microsoft.Extensions.Primitives;
|
||||||
|
using System.Text.Json;
|
||||||
using Telegram.Bot;
|
using Telegram.Bot;
|
||||||
|
using Telegram.Bot.Types;
|
||||||
using Telegrator.Hosting.Web.Components;
|
using Telegrator.Hosting.Web.Components;
|
||||||
using Telegrator.MadiatorCore;
|
using Telegrator.MadiatorCore;
|
||||||
|
|
||||||
namespace Telegrator.Hosting.Web.Polling
|
namespace Telegrator.Hosting.Web.Polling
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Service for receiving updates for Hosted telegram bots via Webhooks
|
||||||
|
/// </summary>
|
||||||
public class HostedUpdateWebhooker : IHostedService
|
public class HostedUpdateWebhooker : IHostedService
|
||||||
{
|
{
|
||||||
|
private const string SecretTokenHeader = "X-Telegram-Bot-Api-Secret-Token";
|
||||||
|
|
||||||
private readonly ITelegramBotWebHost _botHost;
|
private readonly ITelegramBotWebHost _botHost;
|
||||||
private readonly ITelegramBotClient _botClient;
|
private readonly ITelegramBotClient _botClient;
|
||||||
private readonly IUpdateRouter _updateRouter;
|
private readonly IUpdateRouter _updateRouter;
|
||||||
private readonly TelegramBotWebOptions _options;
|
private readonly TelegramBotWebOptions _options;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Initiallizes new instance of <see cref="HostedUpdateWebhooker"/>
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="botHost"></param>
|
||||||
|
/// <param name="botClient"></param>
|
||||||
|
/// <param name="updateRouter"></param>
|
||||||
|
/// <param name="options"></param>
|
||||||
|
/// <exception cref="ArgumentNullException"></exception>
|
||||||
public HostedUpdateWebhooker(ITelegramBotWebHost botHost, ITelegramBotClient botClient, IUpdateRouter updateRouter, IOptions<TelegramBotWebOptions> options)
|
public HostedUpdateWebhooker(ITelegramBotWebHost botHost, ITelegramBotClient botClient, IUpdateRouter updateRouter, IOptions<TelegramBotWebOptions> options)
|
||||||
{
|
{
|
||||||
if (string.IsNullOrEmpty(options.Value.WebhookUri))
|
if (string.IsNullOrEmpty(options.Value.WebhookUri))
|
||||||
throw new ArgumentNullException(nameof(options), "Option \"WebhookUrl\" must be set to subscribe for update recieving");
|
throw new ArgumentNullException(nameof(options), "Option \"WebhookUrl\" must be set to subscribe for update recieving");
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(options.Value.WebhookPattern))
|
|
||||||
throw new ArgumentNullException(nameof(options), "Option \"WebhookPattern\" must be set to subscribe for update recieving");
|
|
||||||
|
|
||||||
_botHost = botHost;
|
_botHost = botHost;
|
||||||
_botClient = botClient;
|
_botClient = botClient;
|
||||||
_updateRouter = updateRouter;
|
_updateRouter = updateRouter;
|
||||||
_options = options.Value;
|
_options = options.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
public Task StartAsync(CancellationToken cancellationToken)
|
public Task StartAsync(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
|
string pattern = new UriBuilder(_options.WebhookUri).Path;
|
||||||
|
_botHost.MapPost(pattern, (Delegate)ReceiveUpdate);
|
||||||
|
|
||||||
_botClient.SetWebhook(
|
_botClient.SetWebhook(
|
||||||
url: _options.WebhookUri,
|
url: _options.WebhookUri,
|
||||||
maxConnections: _options.MaxConnections,
|
maxConnections: _options.MaxConnections,
|
||||||
allowedUpdates: _botHost.UpdateRouter.HandlersProvider.AllowedTypes,
|
allowedUpdates: _botHost.UpdateRouter.HandlersProvider.AllowedTypes,
|
||||||
dropPendingUpdates: _options.DropPendingUpdates,
|
dropPendingUpdates: _options.DropPendingUpdates,
|
||||||
cancellationToken: cancellationToken);
|
cancellationToken: cancellationToken)
|
||||||
|
.Wait(cancellationToken);
|
||||||
|
|
||||||
//botHost.MapGet(_options.WebhookPattern, async (Update update) => await _updateRouter.HandleUpdateAsync(_botClient, update, cancellationToken));
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
public Task StopAsync(CancellationToken cancellationToken)
|
public Task StopAsync(CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
_botClient.DeleteWebhook(_options.DropPendingUpdates, cancellationToken);
|
_botClient.DeleteWebhook(_options.DropPendingUpdates, cancellationToken);
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async Task<IResult> ReceiveUpdate(HttpContext ctx)
|
||||||
|
{
|
||||||
|
if (_options.SecretToken != null)
|
||||||
|
{
|
||||||
|
if (!ctx.Request.Headers.TryGetValue(SecretTokenHeader, out StringValues strings))
|
||||||
|
return Results.BadRequest();
|
||||||
|
|
||||||
|
string? secret = strings.SingleOrDefault();
|
||||||
|
if (secret == null)
|
||||||
|
return Results.BadRequest();
|
||||||
|
|
||||||
|
if (_options.SecretToken != secret)
|
||||||
|
return Results.StatusCode(401);
|
||||||
|
}
|
||||||
|
|
||||||
|
Update? update = await JsonSerializer.DeserializeAsync<Update>(ctx.Request.Body, JsonBotAPI.Options, ctx.RequestAborted);
|
||||||
|
if (update is not { Id: > 0 })
|
||||||
|
return Results.BadRequest();
|
||||||
|
|
||||||
|
await _updateRouter.HandleUpdateAsync(_botClient, update, ctx.RequestAborted);
|
||||||
|
return Results.Ok();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,84 @@
|
|||||||
|
# Telegrator.Hosting.Web
|
||||||
|
|
||||||
|
**Telegrator.Hosting.Web** is an extension for the Telegrator framework that enables seamless integration with ASP.NET Core and webhook-based Telegram bots. It is designed for scalable, production-ready web applications.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Features
|
||||||
|
- ASP.NET Core integration for webhook-based bots
|
||||||
|
- Automatic handler discovery and registration
|
||||||
|
- Strongly-typed configuration via `appsettings.json` and environment variables
|
||||||
|
- Dependency injection and middleware support
|
||||||
|
- Graceful startup/shutdown and lifecycle management
|
||||||
|
- Advanced error handling and logging
|
||||||
|
- Supports all Telegrator handler/filter/state features
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- .NET 8.0 or later
|
||||||
|
- ASP.NET Core
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```shell
|
||||||
|
dotnet add package Telegrator.Hosting.Web
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Quick Start Example
|
||||||
|
|
||||||
|
**Program.cs (ASP.NET Core):**
|
||||||
|
```csharp
|
||||||
|
using Telegrator.Hosting;
|
||||||
|
using Telegrator.Hosting.Web;
|
||||||
|
|
||||||
|
// Creating builder
|
||||||
|
TelegramBotWebHostBuilder builder = TelegramBotWebHost.CreateBuilder(new TelegramBotWebOptions()
|
||||||
|
{
|
||||||
|
Args = args,
|
||||||
|
WebhookUri = "https://you-public-host.ru/bot"
|
||||||
|
ExceptIntersectingCommandAliases = true
|
||||||
|
});
|
||||||
|
|
||||||
|
// Register handlers
|
||||||
|
builder.Handlers.CollectHandlersAssemblyWide();
|
||||||
|
builder.Services.AddHandlersFromAssembly(typeof(Program).Assembly);
|
||||||
|
|
||||||
|
// Register your services
|
||||||
|
builder.Services.AddSingleton<IMyService, MyService>();
|
||||||
|
|
||||||
|
// Building and running application
|
||||||
|
TelegramBotWebHost telegramBot = builder.Build();
|
||||||
|
telegramBot.SetBotCommands();
|
||||||
|
telegramBot.Run();
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Configuration (appsettings.json)
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"TelegramBotClientOptions": {
|
||||||
|
"Token": "YOUR_BOT_TOKEN"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- `TelegramBotClientOptions`: Bot token and client settings
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
- [Telegrator Main Docs](https://github.com/Rikitav/Telegrator)
|
||||||
|
- [Getting Started Guide](https://github.com/Rikitav/Telegrator/wiki/Getting-started)
|
||||||
|
- [Annotation Overview](https://github.com/Rikitav/Telegrator/wiki/Annotation-overview)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## License
|
||||||
|
GPLv3
|
||||||
@@ -1,10 +1,196 @@
|
|||||||
using Telegrator.Hosting.Components;
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Microsoft.AspNetCore.Http.Features;
|
||||||
using Microsoft.AspNetCore.Routing;
|
using Microsoft.AspNetCore.Routing;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using System.Text;
|
||||||
|
using Telegram.Bot.Types.Enums;
|
||||||
|
using Telegrator.Hosting.Components;
|
||||||
|
using Telegrator.Hosting.Providers;
|
||||||
|
using Telegrator.Hosting.Web.Components;
|
||||||
|
using Telegrator.MadiatorCore;
|
||||||
|
using Telegrator.MadiatorCore.Descriptors;
|
||||||
|
|
||||||
namespace Telegrator.Hosting.Web
|
namespace Telegrator.Hosting.Web
|
||||||
{
|
{
|
||||||
public class TelegramBotWebHost //: ITelegramBotWebHost
|
/// <summary>
|
||||||
|
/// Represents a web hosted telegram bot
|
||||||
|
/// </summary>
|
||||||
|
public class TelegramBotWebHost : ITelegramBotWebHost
|
||||||
{
|
{
|
||||||
|
private readonly WebApplication _innerApp;
|
||||||
|
private readonly IUpdateRouter _updateRouter;
|
||||||
|
private readonly ILogger<TelegramBotHost> _logger;
|
||||||
|
|
||||||
|
private bool _disposed;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public IServiceProvider Services => _innerApp.Services;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public IUpdateRouter UpdateRouter => _updateRouter;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public ICollection<EndpointDataSource> DataSources => ((IEndpointRouteBuilder)_innerApp).DataSources;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Allows consumers to be notified of application lifetime events.
|
||||||
|
/// </summary>
|
||||||
|
public IHostApplicationLifetime Lifetime => _innerApp.Lifetime;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// This application's logger
|
||||||
|
/// </summary>
|
||||||
|
public ILogger<TelegramBotHost> Logger => _logger;
|
||||||
|
|
||||||
|
// Private interface fields
|
||||||
|
IServiceProvider IEndpointRouteBuilder.ServiceProvider => Services;
|
||||||
|
IServiceProvider IApplicationBuilder.ApplicationServices { get => Services; set => throw new NotImplementedException(); }
|
||||||
|
IFeatureCollection IApplicationBuilder.ServerFeatures => ((IApplicationBuilder)_innerApp).ServerFeatures;
|
||||||
|
IDictionary<string, object?> IApplicationBuilder.Properties => ((IApplicationBuilder)_innerApp).Properties;
|
||||||
|
|
||||||
|
internal TelegramBotWebHost(WebApplicationBuilder webApplicationBuilder, HostHandlersCollection handlers)
|
||||||
|
{
|
||||||
|
RegisterHostServices(webApplicationBuilder, handlers);
|
||||||
|
_innerApp = webApplicationBuilder.Build();
|
||||||
|
|
||||||
|
_updateRouter = Services.GetRequiredService<IUpdateRouter>();
|
||||||
|
_logger = Services.GetRequiredService<ILogger<TelegramBotHost>>();
|
||||||
|
|
||||||
|
LogHandlers(handlers);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates new <see cref="TelegramBotHostBuilder"/> with default services and webhook update receiving scheme
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static TelegramBotWebHostBuilder CreateBuilder(TelegramBotWebOptions settings)
|
||||||
|
{
|
||||||
|
ArgumentNullException.ThrowIfNull(settings, nameof(settings));
|
||||||
|
WebApplicationBuilder innerApp = WebApplication.CreateBuilder(settings.ToWebApplicationOptions());
|
||||||
|
TelegramBotWebHostBuilder builder = new TelegramBotWebHostBuilder(innerApp, settings);
|
||||||
|
builder.Services.AddTelegramBotHostDefaults();
|
||||||
|
builder.Services.AddTelegramWebhook();
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates new SLIM <see cref="TelegramBotHostBuilder"/> with default services and webhook update receiving scheme
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static TelegramBotWebHostBuilder CreateSlimBuilder(TelegramBotWebOptions settings)
|
||||||
|
{
|
||||||
|
ArgumentNullException.ThrowIfNull(settings, nameof(settings));
|
||||||
|
WebApplicationBuilder innerApp = WebApplication.CreateSlimBuilder(settings.ToWebApplicationOptions());
|
||||||
|
TelegramBotWebHostBuilder builder = new TelegramBotWebHostBuilder(innerApp, settings);
|
||||||
|
builder.Services.AddTelegramBotHostDefaults();
|
||||||
|
builder.Services.AddTelegramWebhook();
|
||||||
|
return builder;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Creates new EMPTY <see cref="TelegramBotHostBuilder"/> WITHOUT any services or update receiving schemes
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static TelegramBotWebHostBuilder CreateEmptyBuilder(TelegramBotWebOptions settings)
|
||||||
|
{
|
||||||
|
ArgumentNullException.ThrowIfNull(settings, nameof(settings));
|
||||||
|
WebApplicationBuilder innerApp = WebApplication.CreateEmptyBuilder(settings.ToWebApplicationOptions());
|
||||||
|
return new TelegramBotWebHostBuilder(innerApp, settings);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public async Task StartAsync(CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
await _innerApp.StartAsync(cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public async Task StopAsync(CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
|
await _innerApp.StopAsync(cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public IApplicationBuilder CreateApplicationBuilder()
|
||||||
|
=> ((IEndpointRouteBuilder)_innerApp).CreateApplicationBuilder();
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public IApplicationBuilder Use(Func<RequestDelegate, RequestDelegate> middleware)
|
||||||
|
=> _innerApp.Use(middleware);
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public IApplicationBuilder New()
|
||||||
|
=> ((IApplicationBuilder)_innerApp).New();
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public RequestDelegate Build()
|
||||||
|
=> ((IApplicationBuilder)_innerApp).Build();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Disposes the host.
|
||||||
|
/// </summary>
|
||||||
|
public async ValueTask DisposeAsync()
|
||||||
|
{
|
||||||
|
if (_disposed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
await _innerApp.DisposeAsync();
|
||||||
|
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
_disposed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Disposes the host.
|
||||||
|
/// </summary>
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
if (_disposed)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Sorry for this, i really dont know how to handle such cases
|
||||||
|
ValueTask disposeTask = _innerApp.DisposeAsync();
|
||||||
|
while (!disposeTask.IsCompleted)
|
||||||
|
Thread.Sleep(100);
|
||||||
|
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
_disposed = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void LogHandlers(HostHandlersCollection handlers)
|
||||||
|
{
|
||||||
|
StringBuilder logBuilder = new StringBuilder("Registered handlers : ");
|
||||||
|
if (!handlers.Keys.Any())
|
||||||
|
throw new Exception();
|
||||||
|
|
||||||
|
foreach (UpdateType updateType in handlers.Keys)
|
||||||
|
{
|
||||||
|
HandlerDescriptorList descriptors = handlers[updateType];
|
||||||
|
logBuilder.Append("\n\tUpdateType." + updateType + " :");
|
||||||
|
|
||||||
|
foreach (HandlerDescriptor descriptor in descriptors.Reverse())
|
||||||
|
{
|
||||||
|
logBuilder.AppendFormat("\n\t* {0} - {1}",
|
||||||
|
descriptor.Indexer.ToString(),
|
||||||
|
descriptor.ToString());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Logger.LogInformation(logBuilder.ToString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RegisterHostServices(WebApplicationBuilder hostApplicationBuilder, HostHandlersCollection handlers)
|
||||||
|
{
|
||||||
|
//hostApplicationBuilder.Services.RemoveAll<IHost>();
|
||||||
|
//hostApplicationBuilder.Services.AddSingleton<IHost>(this);
|
||||||
|
|
||||||
|
hostApplicationBuilder.Services.AddSingleton<ITelegramBotHost>(this);
|
||||||
|
hostApplicationBuilder.Services.AddSingleton<ITelegramBotWebHost>(this);
|
||||||
|
hostApplicationBuilder.Services.AddSingleton<ITelegratorBot>(this);
|
||||||
|
hostApplicationBuilder.Services.AddSingleton<IHandlersCollection>(handlers);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,73 @@
|
|||||||
using Telegrator.Hosting.Components;
|
using Microsoft.AspNetCore.Builder;
|
||||||
using Telegrator.Hosting.Web.Components;
|
using Microsoft.Extensions.Configuration;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
using Microsoft.Extensions.Logging;
|
||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using Telegram.Bot;
|
||||||
|
using Telegram.Bot.Polling;
|
||||||
|
using Telegrator.Hosting.Components;
|
||||||
|
using Telegrator.Hosting.Configuration;
|
||||||
|
using Telegrator.Hosting.Providers;
|
||||||
|
using Telegrator.MadiatorCore;
|
||||||
|
|
||||||
|
#pragma warning disable IDE0001
|
||||||
namespace Telegrator.Hosting.Web
|
namespace Telegrator.Hosting.Web
|
||||||
{
|
{
|
||||||
public class TelegramBotWebHostBuilder //: ITelegramBotHostBuilder
|
/// <summary>
|
||||||
|
/// Represents a web hosted telegram bots and services builder that helps manage configuration, logging, lifetime, and more.
|
||||||
|
/// </summary>
|
||||||
|
public class TelegramBotWebHostBuilder : ITelegramBotHostBuilder
|
||||||
{
|
{
|
||||||
|
private readonly WebApplicationBuilder _innerBuilder;
|
||||||
|
private readonly TelegramBotWebOptions _settings;
|
||||||
|
private readonly HostHandlersCollection _handlers;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public IHandlersCollection Handlers => _handlers;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public IConfigurationManager Configuration => _innerBuilder.Configuration;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public ILoggingBuilder Logging => _innerBuilder.Logging;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public IServiceCollection Services => _innerBuilder.Services;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public IHostEnvironment Environment => _innerBuilder.Environment;
|
||||||
|
|
||||||
|
internal TelegramBotWebHostBuilder(WebApplicationBuilder webApplicationBuilder, TelegramBotWebOptions settings)
|
||||||
|
{
|
||||||
|
_innerBuilder = webApplicationBuilder;
|
||||||
|
_settings = settings ?? throw new ArgumentNullException(nameof(settings));
|
||||||
|
_handlers = new HostHandlersCollection(Services, _settings);
|
||||||
|
|
||||||
|
Services.AddSingleton<IOptions<TelegramBotWebOptions>>(Options.Create(settings));
|
||||||
|
Services.Configure<TelegratorOptions>(Configuration.GetSection(nameof(TelegratorOptions)));
|
||||||
|
Services.Configure<TelegramBotClientOptions>(Configuration.GetSection(nameof(TelegramBotClientOptions)), new TelegramBotClientOptionsProxy());
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Builds the host.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
public TelegramBotWebHost Build()
|
||||||
|
{
|
||||||
|
foreach (PreBuildingRoutine preBuildRoutine in _handlers.PreBuilderRoutines)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
preBuildRoutine.Invoke(this);
|
||||||
|
}
|
||||||
|
catch (NotImplementedException)
|
||||||
|
{
|
||||||
|
_ = 0xBAD + 0xC0DE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new TelegramBotWebHost(_innerBuilder, _handlers);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,58 @@
|
|||||||
using Telegrator.Configuration;
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
|
||||||
namespace Telegrator.Hosting.Web
|
namespace Telegrator.Hosting.Web
|
||||||
{
|
{
|
||||||
public class TelegramBotWebOptions : TelegramBotOptions
|
/// <summary>
|
||||||
|
/// Configuration options for Telegram bot behavior and execution settings.
|
||||||
|
/// Controls various aspects of bot operation including concurrency, routing, webhook receiving, and execution policies.
|
||||||
|
/// </summary>
|
||||||
|
public class TelegramBotWebOptions : TelegratorOptions
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets uri for webhook update receiving
|
/// Gets or sets HTTPS URL to send updates to. Use an empty string to remove webhook integration
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public required string WebhookUri { get; set; }
|
public required string WebhookUri { get; set; }
|
||||||
|
|
||||||
public required string WebhookPattern { get; set; }
|
/// <summary>
|
||||||
|
/// A secret token to be sent in a header “X-Telegram-Bot-Api-Secret-Token” in every webhook request, 1-256 characters.
|
||||||
|
/// Only characters A-Z, a-z, 0-9, _ and - are allowed.
|
||||||
|
/// The header is useful to ensure that the request comes from a webhook set by you.
|
||||||
|
/// </summary>
|
||||||
|
public string? SecretToken { get; set; }
|
||||||
|
|
||||||
public int MaxConnections { get; set; }
|
/// <summary>
|
||||||
|
/// The maximum allowed number of simultaneous HTTPS connections to the webhook for update delivery, 1-100. Defaults to 40.
|
||||||
|
/// Use lower values to limit the load on your bot's server, and higher values to increase your bot's throughput.
|
||||||
|
/// </summary>
|
||||||
|
public int MaxConnections { get; set; } = 40;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Pass true to drop all pending updates
|
||||||
|
/// </summary>
|
||||||
public bool DropPendingUpdates { get; set; }
|
public bool DropPendingUpdates { get; set; }
|
||||||
|
|
||||||
|
/// <inheritdoc cref="WebApplicationOptions.Args"/>
|
||||||
|
public string[]? Args { get; init; }
|
||||||
|
|
||||||
|
/// <inheritdoc cref="WebApplicationOptions.EnvironmentName"/>
|
||||||
|
public string? EnvironmentName { get; init; }
|
||||||
|
|
||||||
|
/// <inheritdoc cref="WebApplicationOptions.ApplicationName"/>
|
||||||
|
public string? ApplicationName { get; init; }
|
||||||
|
|
||||||
|
/// <inheritdoc cref="WebApplicationOptions.ContentRootPath"/>
|
||||||
|
public string? ContentRootPath { get; init; }
|
||||||
|
|
||||||
|
/// <inheritdoc cref="WebApplicationOptions.WebRootPath"/>
|
||||||
|
public string? WebRootPath { get; init; }
|
||||||
|
|
||||||
|
internal WebApplicationOptions ToWebApplicationOptions() => new WebApplicationOptions()
|
||||||
|
{
|
||||||
|
ApplicationName = ApplicationName,
|
||||||
|
Args = Args,
|
||||||
|
ContentRootPath = ContentRootPath,
|
||||||
|
EnvironmentName = EnvironmentName,
|
||||||
|
WebRootPath = WebRootPath
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,18 @@
|
|||||||
<TargetFramework>net8.0</TargetFramework>
|
<TargetFramework>net8.0</TargetFramework>
|
||||||
<ImplicitUsings>enable</ImplicitUsings>
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
|
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
||||||
|
<GenerateDocumentationFile>True</GenerateDocumentationFile>
|
||||||
|
<PackageProjectUrl></PackageProjectUrl>
|
||||||
|
<Title>Telegrator : Telegram.Bot mediator framework</Title>
|
||||||
|
<PackageIcon>telegrator_nuget.png</PackageIcon>
|
||||||
|
<RepositoryUrl>https://github.com/Rikitav/Telegrator</RepositoryUrl>
|
||||||
|
<PackageTags>telegram;bot;mediator;attributes;aspect;hosting;host;framework;easy;simple;handlers</PackageTags>
|
||||||
|
<EnableNETAnalyzers>True</EnableNETAnalyzers>
|
||||||
|
<EnforceCodeStyleInBuild>True</EnforceCodeStyleInBuild>
|
||||||
|
<PackageLicenseFile>LICENSE</PackageLicenseFile>
|
||||||
|
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||||
|
<Version>1.0.7</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -11,6 +23,25 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="Microsoft.AspNetCore.Routing" Version="2.3.0" />
|
<None Include="..\LICENSE">
|
||||||
|
<Pack>True</Pack>
|
||||||
|
<PackagePath>\</PackagePath>
|
||||||
|
</None>
|
||||||
|
<None Include="..\resources\telegrator_nuget.png">
|
||||||
|
<Pack>True</Pack>
|
||||||
|
<PackagePath>\</PackagePath>
|
||||||
|
</None>
|
||||||
|
<None Update="README.md">
|
||||||
|
<Pack>True</Pack>
|
||||||
|
<PackagePath>\</PackagePath>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<FrameworkReference Include="Microsoft.AspNetCore.App" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="Telegram.Bot.AspNetCore" Version="22.5.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -1,12 +1,22 @@
|
|||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Telegram.Bot;
|
using Telegram.Bot;
|
||||||
|
using Telegrator.Hosting.Web.Components;
|
||||||
using Telegrator.Hosting.Web.Polling;
|
using Telegrator.Hosting.Web.Polling;
|
||||||
|
|
||||||
namespace Telegrator.Hosting.Web
|
namespace Telegrator.Hosting.Web
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Contains extensions for <see cref="IServiceCollection"/>
|
||||||
|
/// Provides method to configure <see cref="ITelegramBotWebHost"/>
|
||||||
|
/// </summary>
|
||||||
public static class ServicesCollectionExtensions
|
public static class ServicesCollectionExtensions
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Registers <see cref="ITelegramBotClient"/> service with <see cref="HostedUpdateWebhooker"/> to receive updates using webhook
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="services"></param>
|
||||||
|
/// <returns></returns>
|
||||||
public static IServiceCollection AddTelegramWebhook(this IServiceCollection services)
|
public static IServiceCollection AddTelegramWebhook(this IServiceCollection services)
|
||||||
{
|
{
|
||||||
services.AddHttpClient<ITelegramBotClient>("tgwebhook").RemoveAllLoggers().AddTypedClient(TypedTelegramBotClientFactory);
|
services.AddHttpClient<ITelegramBotClient>("tgwebhook").RemoveAllLoggers().AddTypedClient(TypedTelegramBotClientFactory);
|
||||||
|
|||||||
@@ -10,6 +10,6 @@
|
|||||||
/// Executes the pre-building routine on the specified host builder.
|
/// Executes the pre-building routine on the specified host builder.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="hostBuilder">The host builder to configure.</param>
|
/// <param name="hostBuilder">The host builder to configure.</param>
|
||||||
public static abstract void PreBuildingRoutine(TelegramBotHostBuilder hostBuilder);
|
public static abstract void PreBuildingRoutine(ITelegramBotHostBuilder hostBuilder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Telegrator.MadiatorCore;
|
using Telegrator.MadiatorCore;
|
||||||
|
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ namespace Telegrator.Hosting.Configuration
|
|||||||
/// Internal proxy class for configuring Telegram bot client options from configuration.
|
/// Internal proxy class for configuring Telegram bot client options from configuration.
|
||||||
/// Extends ConfigureOptionsProxy to provide specific configuration for Telegram bot client options.
|
/// Extends ConfigureOptionsProxy to provide specific configuration for Telegram bot client options.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal class TelegramBotClientOptionsProxy : ConfigureOptionsProxy<TelegramBotClientOptions>
|
public class TelegramBotClientOptionsProxy : ConfigureOptionsProxy<TelegramBotClientOptions>
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets the bot token.
|
/// Gets or sets the bot token.
|
||||||
|
|||||||
@@ -7,3 +7,4 @@ using System.Diagnostics.CodeAnalysis;
|
|||||||
|
|
||||||
[assembly: SuppressMessage("Style", "IDE0290")]
|
[assembly: SuppressMessage("Style", "IDE0290")]
|
||||||
[assembly: SuppressMessage("Style", "IDE0090")]
|
[assembly: SuppressMessage("Style", "IDE0090")]
|
||||||
|
[assembly: SuppressMessage("Usage", "CA2254")]
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Telegrator.Configuration;
|
|
||||||
using Telegrator.MadiatorCore.Descriptors;
|
using Telegrator.MadiatorCore.Descriptors;
|
||||||
using Telegrator.Polling;
|
using Telegrator.Polling;
|
||||||
|
|
||||||
namespace Telegrator.Hosting.Polling
|
namespace Telegrator.Hosting.Polling
|
||||||
{
|
{
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public class HostUpdateHandlersPool(IOptions<TelegramBotOptions> options, ILogger<HostUpdateHandlersPool> logger) : UpdateHandlersPool(options.Value, options.Value.GlobalCancellationToken)
|
public class HostUpdateHandlersPool(IOptions<TelegratorOptions> options, ILogger<HostUpdateHandlersPool> logger) : UpdateHandlersPool(options.Value, options.Value.GlobalCancellationToken)
|
||||||
{
|
{
|
||||||
private readonly ILogger<HostUpdateHandlersPool> _logger = logger;
|
private readonly ILogger<HostUpdateHandlersPool> _logger = logger;
|
||||||
|
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ namespace Telegrator.Hosting.Polling
|
|||||||
public HostUpdateRouter(
|
public HostUpdateRouter(
|
||||||
IHandlersProvider handlersProvider,
|
IHandlersProvider handlersProvider,
|
||||||
IAwaitingProvider awaitingProvider,
|
IAwaitingProvider awaitingProvider,
|
||||||
IOptions<TelegramBotOptions> options,
|
IOptions<TelegratorOptions> options,
|
||||||
IUpdateHandlersPool handlersPool,
|
IUpdateHandlersPool handlersPool,
|
||||||
ITelegramBotInfo botInfo,
|
ITelegramBotInfo botInfo,
|
||||||
ILogger<HostUpdateRouter> logger) : base(handlersProvider, awaitingProvider, options.Value, handlersPool, botInfo)
|
ILogger<HostUpdateRouter> logger) : base(handlersProvider, awaitingProvider, options.Value, handlersPool, botInfo)
|
||||||
@@ -33,7 +33,7 @@ namespace Telegrator.Hosting.Polling
|
|||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public override Task HandleUpdateAsync(ITelegramBotClient botClient, Update update, CancellationToken cancellationToken)
|
public override Task HandleUpdateAsync(ITelegramBotClient botClient, Update update, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
//Logger.LogInformation("Received update of type \"{type}\"", update.Type);
|
Logger.LogInformation("Received update of type \"{type}\"", update.Type);
|
||||||
return base.HandleUpdateAsync(botClient, update, cancellationToken);
|
return base.HandleUpdateAsync(botClient, update, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Telegrator.Configuration;
|
|
||||||
using Telegrator.Providers;
|
using Telegrator.Providers;
|
||||||
|
|
||||||
namespace Telegrator.Hosting.Providers
|
namespace Telegrator.Hosting.Providers
|
||||||
{
|
{
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public class HostAwaitingProvider(IOptions<TelegramBotOptions> options, ILogger<HostAwaitingProvider> logger) : AwaitingProvider(options.Value)
|
public class HostAwaitingProvider(IOptions<TelegratorOptions> options, ILogger<HostAwaitingProvider> logger) : AwaitingProvider(options.Value)
|
||||||
{
|
{
|
||||||
private readonly ILogger<HostAwaitingProvider> _logger = logger;
|
private readonly ILogger<HostAwaitingProvider> _logger = logger;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,10 +12,10 @@ namespace Telegrator.Hosting.Providers
|
|||||||
/// Pre host building task
|
/// Pre host building task
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="builder"></param>
|
/// <param name="builder"></param>
|
||||||
public delegate void PreBuildingRoutine(TelegramBotHostBuilder builder);
|
public delegate void PreBuildingRoutine(ITelegramBotHostBuilder builder);
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public class HostHandlersCollection(IServiceCollection hostServiceColletion, IHandlersCollectingOptions options) : HandlersCollection(options)
|
public class HostHandlersCollection(IServiceCollection hostServiceColletion, ITelegratorOptions options) : HandlersCollection(options)
|
||||||
{
|
{
|
||||||
private readonly IServiceCollection Services = hostServiceColletion;
|
private readonly IServiceCollection Services = hostServiceColletion;
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using Microsoft.Extensions.DependencyInjection;
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using Telegrator.Configuration;
|
|
||||||
using Telegrator.Handlers.Components;
|
using Telegrator.Handlers.Components;
|
||||||
using Telegrator.MadiatorCore;
|
using Telegrator.MadiatorCore;
|
||||||
using Telegrator.MadiatorCore.Descriptors;
|
using Telegrator.MadiatorCore.Descriptors;
|
||||||
@@ -18,7 +17,7 @@ namespace Telegrator.Hosting.Providers
|
|||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public HostHandlersProvider(
|
public HostHandlersProvider(
|
||||||
IHandlersCollection handlers,
|
IHandlersCollection handlers,
|
||||||
IOptions<TelegramBotOptions> options,
|
IOptions<TelegratorOptions> options,
|
||||||
IServiceProvider serviceProvider,
|
IServiceProvider serviceProvider,
|
||||||
ILogger<HostHandlersProvider> logger) : base(handlers, options.Value)
|
ILogger<HostHandlersProvider> logger) : base(handlers, options.Value)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -0,0 +1,93 @@
|
|||||||
|
# Telegrator.Hosting
|
||||||
|
|
||||||
|
**Telegrator.Hosting** is an extension for the Telegrator framework that provides seamless integration with the .NET Generic Host, enabling production-ready, scalable, and maintainable Telegram bot applications.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Features
|
||||||
|
- Integration with `Microsoft.Extensions.Hosting` (background services, DI, configuration, logging)
|
||||||
|
- Automatic handler discovery and registration
|
||||||
|
- Strongly-typed configuration via `appsettings.json` and environment variables
|
||||||
|
- Graceful startup/shutdown and lifecycle management
|
||||||
|
- Advanced error handling and logging
|
||||||
|
- Supports all Telegrator handler/filter/state features
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
- .NET 8.0 or later
|
||||||
|
- [Telegrator](https://github.com/Rikitav/Telegrator)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
```shell
|
||||||
|
dotnet add package Telegrator.Hosting
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Quick Start Example
|
||||||
|
|
||||||
|
**Program.cs:**
|
||||||
|
```csharp
|
||||||
|
using Telegrator.Hosting;
|
||||||
|
|
||||||
|
// Creating builder
|
||||||
|
TelegramBotHostBuilder builder = TelegramBotHost.CreateBuilder(new TelegramBotHostBuilderSettings()
|
||||||
|
{
|
||||||
|
Args = args,
|
||||||
|
DescendDescriptorIndex = false,
|
||||||
|
ExceptIntersectingCommandAliases = true
|
||||||
|
});
|
||||||
|
|
||||||
|
// Registerring handlers
|
||||||
|
builder.Handlers.CollectHandlersAssemblyWide();
|
||||||
|
|
||||||
|
// Register your services
|
||||||
|
builder.Services.AddSingleton<IMyService, MyService>();
|
||||||
|
|
||||||
|
// Building and running application
|
||||||
|
TelegramBotHost telegramBot = builder.Build();
|
||||||
|
telegramBot.SetBotCommands();
|
||||||
|
telegramBot.Run();
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Configuration (appsettings.json)
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"TelegramBotClientOptions": {
|
||||||
|
"Token": "YOUR_BOT_TOKEN"
|
||||||
|
},
|
||||||
|
|
||||||
|
"HostOptions": {
|
||||||
|
"ShutdownTimeout": 10,
|
||||||
|
"BackgroundServiceExceptionBehavior": "StopHost"
|
||||||
|
},
|
||||||
|
|
||||||
|
"ReceiverOptions": {
|
||||||
|
"DropPendingUpdates": true,
|
||||||
|
"Limit": 10
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
- `TelegramBotClientOptions`: Bot token and client settings
|
||||||
|
- `HostOptions`: Host lifecycle and shutdown behavior
|
||||||
|
- `ReceiverOptions`: Long-polling configuration
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Documentation
|
||||||
|
- [Telegrator Main Docs](https://github.com/Rikitav/Telegrator)
|
||||||
|
- [Getting Started Guide](https://github.com/Rikitav/Telegrator/wiki/Getting-started)
|
||||||
|
- [Annotation Overview](https://github.com/Rikitav/Telegrator/wiki/Annotation-overview)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## License
|
||||||
|
GPLv3
|
||||||
@@ -114,6 +114,8 @@ namespace Telegrator.Hosting
|
|||||||
if (_disposed)
|
if (_disposed)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
_innerHost.Dispose();
|
||||||
|
|
||||||
GC.SuppressFinalize(this);
|
GC.SuppressFinalize(this);
|
||||||
_disposed = true;
|
_disposed = true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,10 +4,9 @@ using Microsoft.Extensions.Hosting;
|
|||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
using Telegram.Bot;
|
using Telegram.Bot;
|
||||||
using Telegram.Bot.Polling;
|
using Telegram.Bot.Polling;
|
||||||
using Telegrator.Hosting.Configuration;
|
|
||||||
using Telegrator.Configuration;
|
|
||||||
using Telegrator.Hosting;
|
using Telegrator.Hosting;
|
||||||
using Telegrator.Hosting.Components;
|
using Telegrator.Hosting.Components;
|
||||||
|
using Telegrator.Hosting.Configuration;
|
||||||
using Telegrator.Hosting.Providers;
|
using Telegrator.Hosting.Providers;
|
||||||
using Telegrator.MadiatorCore;
|
using Telegrator.MadiatorCore;
|
||||||
|
|
||||||
@@ -51,7 +50,7 @@ namespace Telegrator.Hosting
|
|||||||
|
|
||||||
_innerBuilder.Logging.ClearProviders();
|
_innerBuilder.Logging.ClearProviders();
|
||||||
|
|
||||||
Services.Configure<TelegramBotOptions>(Configuration.GetSection(nameof(TelegramBotOptions)));
|
Services.Configure<TelegratorOptions>(Configuration.GetSection(nameof(TelegratorOptions)));
|
||||||
Services.Configure<ReceiverOptions>(Configuration.GetSection(nameof(ReceiverOptions)));
|
Services.Configure<ReceiverOptions>(Configuration.GetSection(nameof(ReceiverOptions)));
|
||||||
Services.Configure<TelegramBotClientOptions>(Configuration.GetSection(nameof(TelegramBotClientOptions)), new TelegramBotClientOptionsProxy());
|
Services.Configure<TelegramBotClientOptions>(Configuration.GetSection(nameof(TelegramBotClientOptions)), new TelegramBotClientOptionsProxy());
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using Microsoft.Extensions.Hosting;
|
using Microsoft.Extensions.Hosting;
|
||||||
using Telegrator.Configuration;
|
|
||||||
|
|
||||||
namespace Telegrator.Hosting
|
namespace Telegrator.Hosting
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Settings os hosted Telegram bot
|
/// Settings os hosted Telegram bot
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class TelegramBotHostBuilderSettings() : IHandlersCollectingOptions
|
public class TelegramBotHostBuilderSettings() : TelegratorOptions
|
||||||
{
|
{
|
||||||
/// <inheritdoc cref="HostApplicationBuilderSettings.DisableDefaults"/>
|
/// <inheritdoc cref="HostApplicationBuilderSettings.DisableDefaults"/>
|
||||||
public bool DisableDefaults { get; set; }
|
public bool DisableDefaults { get; set; }
|
||||||
@@ -27,12 +26,6 @@ namespace Telegrator.Hosting
|
|||||||
/// <inheritdoc cref="HostApplicationBuilderSettings.ContentRootPath"/>
|
/// <inheritdoc cref="HostApplicationBuilderSettings.ContentRootPath"/>
|
||||||
public string? ContentRootPath { get; set; }
|
public string? ContentRootPath { get; set; }
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
public bool DescendDescriptorIndex { get; set; } = true;
|
|
||||||
|
|
||||||
/// <inheritdoc/>
|
|
||||||
public bool ExceptIntersectingCommandAliases { get; set; } = true;
|
|
||||||
|
|
||||||
internal HostApplicationBuilderSettings ToApplicationBuilderSettings() => new HostApplicationBuilderSettings()
|
internal HostApplicationBuilderSettings ToApplicationBuilderSettings() => new HostApplicationBuilderSettings()
|
||||||
{
|
{
|
||||||
DisableDefaults = DisableDefaults,
|
DisableDefaults = DisableDefaults,
|
||||||
|
|||||||
@@ -15,7 +15,8 @@
|
|||||||
<EnableNETAnalyzers>True</EnableNETAnalyzers>
|
<EnableNETAnalyzers>True</EnableNETAnalyzers>
|
||||||
<EnforceCodeStyleInBuild>True</EnforceCodeStyleInBuild>
|
<EnforceCodeStyleInBuild>True</EnforceCodeStyleInBuild>
|
||||||
<PackageLicenseFile>LICENSE</PackageLicenseFile>
|
<PackageLicenseFile>LICENSE</PackageLicenseFile>
|
||||||
<Version>1.0.6</Version>
|
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||||
|
<Version>1.0.7</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -38,4 +39,11 @@
|
|||||||
<ProjectReference Include="..\Telegrator\Telegrator.csproj" />
|
<ProjectReference Include="..\Telegrator\Telegrator.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<None Update="README.md">
|
||||||
|
<Pack>True</Pack>
|
||||||
|
<PackagePath>\</PackagePath>
|
||||||
|
</None>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ using Microsoft.Extensions.Logging;
|
|||||||
using Microsoft.Extensions.Options;
|
using Microsoft.Extensions.Options;
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using Telegram.Bot;
|
using Telegram.Bot;
|
||||||
using Telegram.Bot.Types;
|
using Telegram.Bot.Types;
|
||||||
using Telegrator.Configuration;
|
using Telegrator.Configuration;
|
||||||
|
|||||||
@@ -20,6 +20,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Telegrator.Analyzers", "Tel
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Telegrator.ConsoleHost", "..\Telegram.Reactive.TestApps\Telegrator.ConsoleHost\Telegrator.ConsoleHost.csproj", "{78691EF7-6009-3BB1-C90D-1D1D95442041}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Telegrator.ConsoleHost", "..\Telegram.Reactive.TestApps\Telegrator.ConsoleHost\Telegrator.ConsoleHost.csproj", "{78691EF7-6009-3BB1-C90D-1D1D95442041}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Telegrator.Hosting.Web", "Telegrator.Hosting.Web\Telegrator.Hosting.Web.csproj", "{98AB490F-6A36-CCFF-F6E6-B029D1665965}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Telegrator.ConsoleHost.Web", "Telegrator.ConsoleHost.Web\Telegrator.ConsoleHost.Web.csproj", "{C18E1844-64A7-4FF8-BDB9-24F8FBFC5CF6}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
AnalyzersDebug|Any CPU = AnalyzersDebug|Any CPU
|
AnalyzersDebug|Any CPU = AnalyzersDebug|Any CPU
|
||||||
@@ -63,6 +67,18 @@ Global
|
|||||||
{78691EF7-6009-3BB1-C90D-1D1D95442041}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{78691EF7-6009-3BB1-C90D-1D1D95442041}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{78691EF7-6009-3BB1-C90D-1D1D95442041}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{78691EF7-6009-3BB1-C90D-1D1D95442041}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{78691EF7-6009-3BB1-C90D-1D1D95442041}.Release|Any CPU.Build.0 = Release|Any CPU
|
{78691EF7-6009-3BB1-C90D-1D1D95442041}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{98AB490F-6A36-CCFF-F6E6-B029D1665965}.AnalyzersDebug|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{98AB490F-6A36-CCFF-F6E6-B029D1665965}.AnalyzersDebug|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{98AB490F-6A36-CCFF-F6E6-B029D1665965}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{98AB490F-6A36-CCFF-F6E6-B029D1665965}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{98AB490F-6A36-CCFF-F6E6-B029D1665965}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{98AB490F-6A36-CCFF-F6E6-B029D1665965}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{C18E1844-64A7-4FF8-BDB9-24F8FBFC5CF6}.AnalyzersDebug|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{C18E1844-64A7-4FF8-BDB9-24F8FBFC5CF6}.AnalyzersDebug|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{C18E1844-64A7-4FF8-BDB9-24F8FBFC5CF6}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{C18E1844-64A7-4FF8-BDB9-24F8FBFC5CF6}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{C18E1844-64A7-4FF8-BDB9-24F8FBFC5CF6}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{C18E1844-64A7-4FF8-BDB9-24F8FBFC5CF6}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|||||||
@@ -64,36 +64,6 @@ namespace Telegrator.Attributes
|
|||||||
SpecialState = specialState;
|
SpecialState = specialState;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes the attribute with a custom state keeper, a specific state, and a custom key resolver.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="keeper">The state keeper instance</param>
|
|
||||||
/// <param name="myState">The state value to associate</param>
|
|
||||||
/// <param name="keyResolver">The key resolver for state keeping</param>
|
|
||||||
protected StateKeeperAttribute(TKeeper keeper, TState myState, IStateKeyResolver<TKey> keyResolver) : base(typeof(TKeeper))
|
|
||||||
{
|
|
||||||
StateKeeper ??= keeper;
|
|
||||||
StateKeeper.KeyResolver = keyResolver;
|
|
||||||
MyState = myState;
|
|
||||||
SpecialState = SpecialState.None;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Initializes the attribute with a custom state keeper, a special state, and a custom key resolver.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="keeper">The state keeper instance</param>
|
|
||||||
/// <param name="specialState">The special state mode</param>
|
|
||||||
/// <param name="keyResolver">The key resolver for state keeping</param>
|
|
||||||
protected StateKeeperAttribute(TKeeper keeper, SpecialState specialState, IStateKeyResolver<TKey> keyResolver) : base(typeof(TKeeper))
|
|
||||||
{
|
|
||||||
StateKeeper ??= keeper;
|
|
||||||
StateKeeper.KeyResolver = keyResolver;
|
|
||||||
MyState = StateKeeper.DefaultState;
|
|
||||||
SpecialState = specialState;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Determines whether the current update context passes the state filter.
|
/// Determines whether the current update context passes the state filter.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -1,19 +0,0 @@
|
|||||||
namespace Telegrator.Configuration
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Interface for configuring handler collection behavior.
|
|
||||||
/// Defines options that control how handlers are collected and processed during initialization.
|
|
||||||
/// </summary>
|
|
||||||
public interface IHandlersCollectingOptions
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating whether to descend the indexr of handler's index on register. ('false' by default)
|
|
||||||
/// </summary>
|
|
||||||
public bool DescendDescriptorIndex { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Gets or sets a value indicating whether to exclude intersecting command aliases.
|
|
||||||
/// </summary>
|
|
||||||
public bool ExceptIntersectingCommandAliases { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+13
-3
@@ -1,10 +1,10 @@
|
|||||||
namespace Telegrator.Configuration
|
namespace Telegrator.Configuration
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Configuration options for Telegram bot behavior and execution settings.
|
/// Interface for configuring Telegram bot behavior and execution settings.
|
||||||
/// Controls various aspects of bot operation including concurrency, routing, and execution policies.
|
/// Controls various aspects of bot operation including concurrency, routing, collecting, and execution policies.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class TelegramBotOptions
|
public interface ITelegratorOptions
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets or sets a value indicating whether only the first found handler should be executed for each update.
|
/// Gets or sets a value indicating whether only the first found handler should be executed for each update.
|
||||||
@@ -25,5 +25,15 @@
|
|||||||
/// Gets or sets the global cancellation token for all bot operations.
|
/// Gets or sets the global cancellation token for all bot operations.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public CancellationToken GlobalCancellationToken { get; set; }
|
public CancellationToken GlobalCancellationToken { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a value indicating whether to descend the indexr of handler's index on register. ('false' by default)
|
||||||
|
/// </summary>
|
||||||
|
public bool DescendDescriptorIndex { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets a value indicating whether to exclude intersecting command aliases.
|
||||||
|
/// </summary>
|
||||||
|
public bool ExceptIntersectingCommandAliases { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -76,6 +76,11 @@
|
|||||||
[Flags]
|
[Flags]
|
||||||
public enum DebugLevel
|
public enum DebugLevel
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// None to write
|
||||||
|
/// </summary>
|
||||||
|
None = 0x0,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Write debug messages from filters execution
|
/// Write debug messages from filters execution
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using Telegram.Bot.Types.Enums;
|
|
||||||
|
|
||||||
namespace Telegrator
|
namespace Telegrator
|
||||||
{
|
{
|
||||||
@@ -8,13 +7,18 @@ namespace Telegrator
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public static class LeveledDebug
|
public static class LeveledDebug
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Gets or sets flags of what debug messages to write
|
||||||
|
/// </summary>
|
||||||
|
public static DebugLevel IndentFlags { get; set; } = DebugLevel.None;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Writes debug message if Indent level has Router flag
|
/// Writes debug message if Indent level has Router flag
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="message"></param>
|
/// <param name="message"></param>
|
||||||
public static void RouterWriteLine(string message)
|
public static void RouterWriteLine(string message)
|
||||||
{
|
{
|
||||||
if (Debug.IndentLevel.HasFlag(DebugLevel.Router))
|
if (IndentFlags.HasFlag(DebugLevel.Router))
|
||||||
Debug.WriteLine(message);
|
Debug.WriteLine(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,7 +29,7 @@ namespace Telegrator
|
|||||||
/// <param name="args"></param>
|
/// <param name="args"></param>
|
||||||
public static void RouterWriteLine(string message, params object[] args)
|
public static void RouterWriteLine(string message, params object[] args)
|
||||||
{
|
{
|
||||||
if (Debug.IndentLevel.HasFlag(DebugLevel.Router))
|
if (IndentFlags.HasFlag(DebugLevel.Router))
|
||||||
Debug.WriteLine(message, args);
|
Debug.WriteLine(message, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -35,7 +39,7 @@ namespace Telegrator
|
|||||||
/// <param name="message"></param>
|
/// <param name="message"></param>
|
||||||
public static void ProviderWriteLine(string message)
|
public static void ProviderWriteLine(string message)
|
||||||
{
|
{
|
||||||
if (Debug.IndentLevel.HasFlag(DebugLevel.Providers))
|
if (IndentFlags.HasFlag(DebugLevel.Providers))
|
||||||
Debug.WriteLine(message);
|
Debug.WriteLine(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -46,7 +50,7 @@ namespace Telegrator
|
|||||||
/// <param name="args"></param>
|
/// <param name="args"></param>
|
||||||
public static void ProviderWriteLine(string message, params object[] args)
|
public static void ProviderWriteLine(string message, params object[] args)
|
||||||
{
|
{
|
||||||
if (Debug.IndentLevel.HasFlag(DebugLevel.Providers))
|
if (IndentFlags.HasFlag(DebugLevel.Providers))
|
||||||
Debug.WriteLine(message, args);
|
Debug.WriteLine(message, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -56,7 +60,7 @@ namespace Telegrator
|
|||||||
/// <param name="message"></param>
|
/// <param name="message"></param>
|
||||||
public static void FilterWriteLine(string message)
|
public static void FilterWriteLine(string message)
|
||||||
{
|
{
|
||||||
if (Debug.IndentLevel.HasFlag(DebugLevel.Filters))
|
if (IndentFlags.HasFlag(DebugLevel.Filters))
|
||||||
Debug.WriteLine(message);
|
Debug.WriteLine(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -67,7 +71,7 @@ namespace Telegrator
|
|||||||
/// <param name="args"></param>
|
/// <param name="args"></param>
|
||||||
public static void FilterWriteLine(string message, params object[] args)
|
public static void FilterWriteLine(string message, params object[] args)
|
||||||
{
|
{
|
||||||
if (Debug.IndentLevel.HasFlag(DebugLevel.Filters))
|
if (IndentFlags.HasFlag(DebugLevel.Filters))
|
||||||
Debug.WriteLine(message, args);
|
Debug.WriteLine(message, args);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -77,7 +81,7 @@ namespace Telegrator
|
|||||||
/// <param name="message"></param>
|
/// <param name="message"></param>
|
||||||
public static void PoolWriteLine(string message)
|
public static void PoolWriteLine(string message)
|
||||||
{
|
{
|
||||||
if (Debug.IndentLevel.HasFlag(DebugLevel.HandlersPool))
|
if (IndentFlags.HasFlag(DebugLevel.HandlersPool))
|
||||||
Debug.WriteLine(message);
|
Debug.WriteLine(message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,7 +92,7 @@ namespace Telegrator
|
|||||||
/// <param name="args"></param>
|
/// <param name="args"></param>
|
||||||
public static void PoolWriteLine(string message, params object[] args)
|
public static void PoolWriteLine(string message, params object[] args)
|
||||||
{
|
{
|
||||||
if (Debug.IndentLevel.HasFlag(DebugLevel.HandlersPool))
|
if (IndentFlags.HasFlag(DebugLevel.HandlersPool))
|
||||||
Debug.WriteLine(message, args);
|
Debug.WriteLine(message, args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ namespace Telegrator.MadiatorCore.Descriptors
|
|||||||
{
|
{
|
||||||
if (!UpdateValidator.CanPass(filterContext))
|
if (!UpdateValidator.CanPass(filterContext))
|
||||||
{
|
{
|
||||||
LeveledDebug.FilterWriteLine("(E) UpdateValidator filter of {0} for Update ({2}) didnt pass!", filterContext.Data["handler_name"]);
|
LeveledDebug.FilterWriteLine("(E) UpdateValidator filter of {0} for Update ({1}) didnt pass!", filterContext.Data["handler_name"], filterContext.Update.Id);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,7 +59,7 @@ namespace Telegrator.MadiatorCore.Descriptors
|
|||||||
{
|
{
|
||||||
if (!StateKeeperValidator.CanPass(filterContext))
|
if (!StateKeeperValidator.CanPass(filterContext))
|
||||||
{
|
{
|
||||||
LeveledDebug.FilterWriteLine("(E) StateKeeperValidator filter of {0} for Update ({2}) didnt pass!", filterContext.Data["handler_name"]);
|
LeveledDebug.FilterWriteLine("(E) StateKeeperValidator filter of {0} for Update ({1}) didnt pass!", filterContext.Data["handler_name"], filterContext.Update.Id);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,7 +74,7 @@ namespace Telegrator.MadiatorCore.Descriptors
|
|||||||
if (!filter.CanPass(filterContext))
|
if (!filter.CanPass(filterContext))
|
||||||
{
|
{
|
||||||
if (filter is not AnonymousCompiledFilter && filter is not AnonymousTypeFilter)
|
if (filter is not AnonymousCompiledFilter && filter is not AnonymousTypeFilter)
|
||||||
LeveledDebug.FilterWriteLine("(E) {0} filter of {1} didnt pass!", filter.GetType().Name, filterContext.Data["handler_name"]);
|
LeveledDebug.FilterWriteLine("(E) {0} filter of {1} for Update ({2}) didnt pass!", filter.GetType().Name, filterContext.Data["handler_name"], filterContext.Update.Id);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ namespace Telegrator.MadiatorCore.Descriptors
|
|||||||
{
|
{
|
||||||
private readonly object _lock = new object();
|
private readonly object _lock = new object();
|
||||||
private readonly SortedList<DescriptorIndexer, HandlerDescriptor> _innerCollection;
|
private readonly SortedList<DescriptorIndexer, HandlerDescriptor> _innerCollection;
|
||||||
private readonly IHandlersCollectingOptions? _options;
|
private readonly ITelegratorOptions? _options;
|
||||||
private readonly UpdateType _handlingType;
|
private readonly UpdateType _handlingType;
|
||||||
|
|
||||||
private int count;
|
private int count;
|
||||||
@@ -54,7 +54,7 @@ namespace Telegrator.MadiatorCore.Descriptors
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="updateType">The update type for the handlers.</param>
|
/// <param name="updateType">The update type for the handlers.</param>
|
||||||
/// <param name="options">The collecting options.</param>
|
/// <param name="options">The collecting options.</param>
|
||||||
public HandlerDescriptorList(UpdateType updateType, IHandlersCollectingOptions? options)
|
public HandlerDescriptorList(UpdateType updateType, ITelegratorOptions? options)
|
||||||
{
|
{
|
||||||
_innerCollection = [];
|
_innerCollection = [];
|
||||||
_handlingType = updateType;
|
_handlingType = updateType;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using Telegram.Bot.Polling;
|
using Telegram.Bot.Polling;
|
||||||
using Telegrator.Configuration;
|
|
||||||
using Telegrator.Handlers.Components;
|
using Telegrator.Handlers.Components;
|
||||||
|
|
||||||
namespace Telegrator.MadiatorCore
|
namespace Telegrator.MadiatorCore
|
||||||
@@ -11,9 +10,9 @@ namespace Telegrator.MadiatorCore
|
|||||||
public interface IUpdateRouter : IUpdateHandler, IPollingProvider
|
public interface IUpdateRouter : IUpdateHandler, IPollingProvider
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the <see cref="TelegramBotOptions"/> for the router.
|
/// Gets the <see cref="TelegratorOptions"/> for the router.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public TelegramBotOptions Options { get; }
|
public TelegratorOptions Options { get; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets the <see cref="IUpdateHandlersPool"/> that manages handler execution.
|
/// Gets the <see cref="IUpdateHandlersPool"/> that manages handler execution.
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System.Collections.Concurrent;
|
using System.Collections.Concurrent;
|
||||||
using Telegrator.Configuration;
|
|
||||||
using Telegrator.MadiatorCore;
|
using Telegrator.MadiatorCore;
|
||||||
using Telegrator.MadiatorCore.Descriptors;
|
using Telegrator.MadiatorCore.Descriptors;
|
||||||
|
|
||||||
@@ -39,7 +38,7 @@ namespace Telegrator.Polling
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// The bot configuration options.
|
/// The bot configuration options.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected readonly TelegramBotOptions Options;
|
protected readonly TelegratorOptions Options;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The global cancellation token for stopping all operations.
|
/// The global cancellation token for stopping all operations.
|
||||||
@@ -62,7 +61,7 @@ namespace Telegrator.Polling
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="options">The bot configuration options.</param>
|
/// <param name="options">The bot configuration options.</param>
|
||||||
/// <param name="globalCancellationToken">The global cancellation token.</param>
|
/// <param name="globalCancellationToken">The global cancellation token.</param>
|
||||||
public UpdateHandlersPool(TelegramBotOptions options, CancellationToken globalCancellationToken)
|
public UpdateHandlersPool(TelegratorOptions options, CancellationToken globalCancellationToken)
|
||||||
{
|
{
|
||||||
Options = options;
|
Options = options;
|
||||||
GlobalCancellationToken = globalCancellationToken;
|
GlobalCancellationToken = globalCancellationToken;
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ namespace Telegrator.Polling
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class UpdateRouter : IUpdateRouter
|
public class UpdateRouter : IUpdateRouter
|
||||||
{
|
{
|
||||||
private readonly TelegramBotOptions _options;
|
private readonly TelegratorOptions _options;
|
||||||
private readonly IHandlersProvider _handlersProvider;
|
private readonly IHandlersProvider _handlersProvider;
|
||||||
private readonly IAwaitingProvider _awaitingProvider;
|
private readonly IAwaitingProvider _awaitingProvider;
|
||||||
private readonly IUpdateHandlersPool _HandlersPool;
|
private readonly IUpdateHandlersPool _HandlersPool;
|
||||||
@@ -30,7 +30,7 @@ namespace Telegrator.Polling
|
|||||||
public IAwaitingProvider AwaitingProvider => _awaitingProvider;
|
public IAwaitingProvider AwaitingProvider => _awaitingProvider;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public TelegramBotOptions Options => _options;
|
public TelegratorOptions Options => _options;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public IUpdateHandlersPool HandlersPool => _HandlersPool;
|
public IUpdateHandlersPool HandlersPool => _HandlersPool;
|
||||||
@@ -48,7 +48,7 @@ namespace Telegrator.Polling
|
|||||||
/// <param name="awaitingProvider">The provider for awaiting handlers.</param>
|
/// <param name="awaitingProvider">The provider for awaiting handlers.</param>
|
||||||
/// <param name="options">The bot configuration options.</param>
|
/// <param name="options">The bot configuration options.</param>
|
||||||
/// <param name="botInfo"></param>
|
/// <param name="botInfo"></param>
|
||||||
public UpdateRouter(IHandlersProvider handlersProvider, IAwaitingProvider awaitingProvider, TelegramBotOptions options, ITelegramBotInfo botInfo)
|
public UpdateRouter(IHandlersProvider handlersProvider, IAwaitingProvider awaitingProvider, TelegratorOptions options, ITelegramBotInfo botInfo)
|
||||||
{
|
{
|
||||||
_options = options;
|
_options = options;
|
||||||
_handlersProvider = handlersProvider;
|
_handlersProvider = handlersProvider;
|
||||||
@@ -65,7 +65,7 @@ namespace Telegrator.Polling
|
|||||||
/// <param name="options">The bot configuration options.</param>
|
/// <param name="options">The bot configuration options.</param>
|
||||||
/// <param name="handlersPool">The custom handlers pool to use.</param>
|
/// <param name="handlersPool">The custom handlers pool to use.</param>
|
||||||
/// <param name="botInfo"></param>
|
/// <param name="botInfo"></param>
|
||||||
public UpdateRouter(IHandlersProvider handlersProvider, IAwaitingProvider awaitingProvider, TelegramBotOptions options, IUpdateHandlersPool handlersPool, ITelegramBotInfo botInfo)
|
public UpdateRouter(IHandlersProvider handlersProvider, IAwaitingProvider awaitingProvider, TelegratorOptions options, IUpdateHandlersPool handlersPool, ITelegramBotInfo botInfo)
|
||||||
{
|
{
|
||||||
_options = options;
|
_options = options;
|
||||||
_handlersProvider = handlersProvider;
|
_handlersProvider = handlersProvider;
|
||||||
@@ -149,22 +149,22 @@ namespace Telegrator.Polling
|
|||||||
/// <returns>A collection of described handler information for the update</returns>
|
/// <returns>A collection of described handler information for the update</returns>
|
||||||
protected virtual IEnumerable<DescribedHandlerInfo> GetHandlers(IHandlersProvider provider, IUpdateRouter updateRouter, ITelegramBotClient client, Update update, CancellationToken cancellationToken = default)
|
protected virtual IEnumerable<DescribedHandlerInfo> GetHandlers(IHandlersProvider provider, IUpdateRouter updateRouter, ITelegramBotClient client, Update update, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
LeveledDebug.ProviderWriteLine("Requested handlers for UpdateType.{0}", update.Type);
|
LeveledDebug.RouterWriteLine("Requested handlers for UpdateType.{0}", update.Type);
|
||||||
if (!provider.TryGetDescriptorList(update.Type, out HandlerDescriptorList? descriptors))
|
if (!provider.TryGetDescriptorList(update.Type, out HandlerDescriptorList? descriptors))
|
||||||
{
|
{
|
||||||
LeveledDebug.ProviderWriteLine("No registered, providing Any");
|
LeveledDebug.RouterWriteLine("No registered, providing Any");
|
||||||
provider.TryGetDescriptorList(UpdateType.Unknown, out descriptors);
|
provider.TryGetDescriptorList(UpdateType.Unknown, out descriptors);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (descriptors == null || descriptors.Count == 0)
|
if (descriptors == null || descriptors.Count == 0)
|
||||||
{
|
{
|
||||||
LeveledDebug.ProviderWriteLine("No handlers provided");
|
LeveledDebug.RouterWriteLine("No handlers provided");
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
|
|
||||||
IEnumerable<DescribedHandlerInfo> described = DescribeDescriptors(provider, descriptors, updateRouter, client, update, cancellationToken);
|
IEnumerable<DescribedHandlerInfo> described = DescribeDescriptors(provider, descriptors, updateRouter, client, update, cancellationToken);
|
||||||
LeveledDebug.ProviderWriteLine("Described total of {0} handlers for Update ({1}) from {2} provider", described.Count(), update.Id, provider.GetType().Name);
|
LeveledDebug.RouterWriteLine("Described total of {0} handlers for Update ({1}) from {2} provider", described.Count(), update.Id, provider.GetType().Name);
|
||||||
LeveledDebug.ProviderWriteLine("Described handlers : {0}", string.Join(", ", described));
|
LeveledDebug.RouterWriteLine("Described handlers : {0}", string.Join(", ", described));
|
||||||
return described;
|
return described;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,7 +183,7 @@ namespace Telegrator.Polling
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
LeveledDebug.ProviderWriteLine("Describing descriptors of descriptorsList.HandlingType.{0} for Update ({1})", descriptors.HandlingType, update.Id);
|
LeveledDebug.RouterWriteLine("Describing descriptors of descriptorsList.HandlingType.{0} for Update ({1})", descriptors.HandlingType, update.Id);
|
||||||
foreach (HandlerDescriptor descriptor in descriptors.Reverse())
|
foreach (HandlerDescriptor descriptor in descriptors.Reverse())
|
||||||
{
|
{
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
@@ -198,7 +198,7 @@ namespace Telegrator.Polling
|
|||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
LeveledDebug.ProviderWriteLine("Describing for Update ({0}) finished", update.Id);
|
LeveledDebug.RouterWriteLine("Describing for Update ({0}) finished", update.Id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -247,7 +247,25 @@ namespace Telegrator.Polling
|
|||||||
sb.AppendFormat(" from {0} ({1})", msg.From.Username, msg.From.Id);
|
sb.AppendFormat(" from {0} ({1})", msg.From.Username, msg.From.Id);
|
||||||
|
|
||||||
if (msg.Text != null)
|
if (msg.Text != null)
|
||||||
sb.AppendFormat("'{0}'", msg.Text);
|
sb.AppendFormat(" with text '{0}'", msg.Text);
|
||||||
|
|
||||||
|
if (msg.Sticker != null)
|
||||||
|
sb.AppendFormat(" with sticker '{0}'", msg.Sticker.Emoji);
|
||||||
|
|
||||||
|
LeveledDebug.RouterWriteLine(sb.ToString());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case UpdateType.CallbackQuery:
|
||||||
|
{
|
||||||
|
CallbackQuery cq = update.CallbackQuery ?? throw new NullReferenceException();
|
||||||
|
StringBuilder sb = new StringBuilder("Update.CallbackQuery");
|
||||||
|
|
||||||
|
if (cq.From != null)
|
||||||
|
sb.AppendFormat(" from {0} ({1})", cq.From.Username, cq.From.Id);
|
||||||
|
|
||||||
|
if (cq.From != null)
|
||||||
|
sb.AppendFormat(" with data '{0}'", cq.Data);
|
||||||
|
|
||||||
LeveledDebug.RouterWriteLine(sb.ToString());
|
LeveledDebug.RouterWriteLine(sb.ToString());
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using Telegram.Bot.Types.Enums;
|
using Telegram.Bot.Types.Enums;
|
||||||
using Telegrator.Configuration;
|
|
||||||
using Telegrator.MadiatorCore;
|
using Telegrator.MadiatorCore;
|
||||||
using Telegrator.MadiatorCore.Descriptors;
|
using Telegrator.MadiatorCore.Descriptors;
|
||||||
|
|
||||||
@@ -10,7 +9,7 @@ namespace Telegrator.Providers
|
|||||||
/// Extends HandlersProvider to provide functionality for creating and managing awaiter handlers.
|
/// Extends HandlersProvider to provide functionality for creating and managing awaiter handlers.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="options">The bot configuration options.</param>
|
/// <param name="options">The bot configuration options.</param>
|
||||||
public class AwaitingProvider(TelegramBotOptions options) : HandlersProvider([], options), IAwaitingProvider
|
public class AwaitingProvider(TelegratorOptions options) : HandlersProvider([], options), IAwaitingProvider
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// List of handler descriptors for awaiting handlers.
|
/// List of handler descriptors for awaiting handlers.
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ namespace Telegrator.Providers
|
|||||||
/// Provides functionality for collecting, adding, and organizing handlers.
|
/// Provides functionality for collecting, adding, and organizing handlers.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="options">Optional configuration options for handler collecting.</param>
|
/// <param name="options">Optional configuration options for handler collecting.</param>
|
||||||
public class HandlersCollection(IHandlersCollectingOptions? options) : IHandlersCollection
|
public class HandlersCollection(ITelegratorOptions? options) : IHandlersCollection
|
||||||
{
|
{
|
||||||
private readonly List<UpdateType> _allowedTypes = [];
|
private readonly List<UpdateType> _allowedTypes = [];
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ namespace Telegrator.Providers
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Configuration options for handler collecting.
|
/// Configuration options for handler collecting.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected readonly IHandlersCollectingOptions? Options = options;
|
protected readonly ITelegratorOptions? Options = options;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets whether handlers must have a parameterless constructor.
|
/// Gets whether handlers must have a parameterless constructor.
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using Telegram.Bot.Types;
|
using Telegram.Bot.Types;
|
||||||
using Telegram.Bot.Types.Enums;
|
using Telegram.Bot.Types.Enums;
|
||||||
using Telegrator.Configuration;
|
|
||||||
using Telegrator.Handlers.Components;
|
using Telegrator.Handlers.Components;
|
||||||
using Telegrator.MadiatorCore;
|
using Telegrator.MadiatorCore;
|
||||||
using Telegrator.MadiatorCore.Descriptors;
|
using Telegrator.MadiatorCore.Descriptors;
|
||||||
@@ -28,7 +27,7 @@ namespace Telegrator.Providers
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Configuration options for the bot and handler execution behavior.
|
/// Configuration options for the bot and handler execution behavior.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected readonly TelegramBotOptions Options;
|
protected readonly TelegratorOptions Options;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of <see cref="HandlersProvider"/> with the specified handler collections and configuration.
|
/// Initializes a new instance of <see cref="HandlersProvider"/> with the specified handler collections and configuration.
|
||||||
@@ -36,11 +35,12 @@ namespace Telegrator.Providers
|
|||||||
/// <param name="handlers">Collection of handler descriptor lists organized by update type</param>
|
/// <param name="handlers">Collection of handler descriptor lists organized by update type</param>
|
||||||
/// <param name="options">Configuration options for the bot and handler execution</param>
|
/// <param name="options">Configuration options for the bot and handler execution</param>
|
||||||
/// <exception cref="ArgumentNullException">Thrown when options or botInfo is null</exception>
|
/// <exception cref="ArgumentNullException">Thrown when options or botInfo is null</exception>
|
||||||
public HandlersProvider(IHandlersCollection handlers, TelegramBotOptions options)
|
public HandlersProvider(IHandlersCollection handlers, TelegratorOptions options)
|
||||||
{
|
{
|
||||||
AllowedTypes = handlers.AllowedTypes;
|
AllowedTypes = handlers.AllowedTypes;
|
||||||
HandlersDictionary = handlers.Values.ForEach(list => list.Freeze()).ToReadOnlyDictionary(list => list.HandlingType);
|
HandlersDictionary = handlers.Values.ForEach(list => list.Freeze()).ToReadOnlyDictionary(list => list.HandlingType);
|
||||||
Options = options ?? throw new ArgumentNullException(nameof(options));
|
Options = options ?? throw new ArgumentNullException(nameof(options));
|
||||||
|
LeveledDebug.ProviderWriteLine("{0} created!", GetType().Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@@ -49,27 +49,36 @@ namespace Telegrator.Providers
|
|||||||
/// <param name="handlers">Collection of handler descriptor lists organized by update type</param>
|
/// <param name="handlers">Collection of handler descriptor lists organized by update type</param>
|
||||||
/// <param name="options">Configuration options for the bot and handler execution</param>
|
/// <param name="options">Configuration options for the bot and handler execution</param>
|
||||||
/// <exception cref="ArgumentNullException">Thrown when options or botInfo is null</exception>
|
/// <exception cref="ArgumentNullException">Thrown when options or botInfo is null</exception>
|
||||||
public HandlersProvider(IEnumerable<HandlerDescriptorList> handlers, TelegramBotOptions options)
|
public HandlersProvider(IEnumerable<HandlerDescriptorList> handlers, TelegratorOptions options)
|
||||||
{
|
{
|
||||||
AllowedTypes = Update.AllTypes;
|
AllowedTypes = Update.AllTypes;
|
||||||
HandlersDictionary = handlers.ForEach(list => list.Freeze()).ToReadOnlyDictionary(list => list.HandlingType);
|
HandlersDictionary = handlers.ForEach(list => list.Freeze()).ToReadOnlyDictionary(list => list.HandlingType);
|
||||||
Options = options ?? throw new ArgumentNullException(nameof(options));
|
Options = options ?? throw new ArgumentNullException(nameof(options));
|
||||||
|
LeveledDebug.ProviderWriteLine("{0} created!", GetType().Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
/// <exception cref="Exception">Thrown when the descriptor type is not recognized</exception>
|
/// <exception cref="Exception">Thrown when the descriptor type is not recognized</exception>
|
||||||
public virtual UpdateHandlerBase GetHandlerInstance(HandlerDescriptor descriptor, CancellationToken cancellationToken = default)
|
public virtual UpdateHandlerBase GetHandlerInstance(HandlerDescriptor descriptor, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
try
|
||||||
bool useSingleton = UseSingleton(descriptor);
|
{
|
||||||
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
bool useSingleton = UseSingleton(descriptor);
|
||||||
|
|
||||||
if (useSingleton && descriptor.SingletonInstance != null)
|
if (useSingleton && descriptor.SingletonInstance != null)
|
||||||
return descriptor.SingletonInstance;
|
return descriptor.SingletonInstance;
|
||||||
|
|
||||||
UpdateHandlerBase instance = GetHandlerInstanceInternal(descriptor);
|
UpdateHandlerBase instance = GetHandlerInstanceInternal(descriptor);
|
||||||
descriptor.SingletonInstance = useSingleton ? instance : null;
|
descriptor.SingletonInstance = useSingleton ? instance : null;
|
||||||
descriptor.LazyInitialization?.Invoke(instance);
|
descriptor.LazyInitialization?.Invoke(instance);
|
||||||
return instance;
|
return instance;
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
LeveledDebug.ProviderWriteLine("Failed to create instance of {0}", descriptor.ToString());
|
||||||
|
throw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static UpdateHandlerBase GetHandlerInstanceInternal(HandlerDescriptor descriptor)
|
private static UpdateHandlerBase GetHandlerInstanceInternal(HandlerDescriptor descriptor)
|
||||||
@@ -84,7 +93,7 @@ namespace Telegrator.Providers
|
|||||||
{
|
{
|
||||||
DescriptorType.General or DescriptorType.Keyed => false,
|
DescriptorType.General or DescriptorType.Keyed => false,
|
||||||
DescriptorType.Implicit or DescriptorType.Singleton => true,
|
DescriptorType.Implicit or DescriptorType.Singleton => true,
|
||||||
_ => throw new Exception()
|
_ => throw new Exception("Unknown decriptor type")
|
||||||
};
|
};
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
<EnableNETAnalyzers>True</EnableNETAnalyzers>
|
<EnableNETAnalyzers>True</EnableNETAnalyzers>
|
||||||
<EnforceCodeStyleInBuild>True</EnforceCodeStyleInBuild>
|
<EnforceCodeStyleInBuild>True</EnforceCodeStyleInBuild>
|
||||||
<PackageLicenseFile>LICENSE</PackageLicenseFile>
|
<PackageLicenseFile>LICENSE</PackageLicenseFile>
|
||||||
<Version>1.0.6</Version>
|
<Version>1.0.7</Version>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ namespace Telegrator
|
|||||||
private IUpdateRouter? updateRouter = null;
|
private IUpdateRouter? updateRouter = null;
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public TelegramBotOptions Options { get; private set; }
|
public TelegratorOptions Options { get; private set; }
|
||||||
|
|
||||||
/// <inheritdoc/>
|
/// <inheritdoc/>
|
||||||
public IHandlersCollection Handlers { get; private set; }
|
public IHandlersCollection Handlers { get; private set; }
|
||||||
@@ -47,7 +47,7 @@ namespace Telegrator
|
|||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
public TelegratorClient(TelegramBotClientOptions options, HttpClient? httpClient = null, CancellationToken cancellationToken = default) : base(options, httpClient, cancellationToken)
|
public TelegratorClient(TelegramBotClientOptions options, HttpClient? httpClient = null, CancellationToken cancellationToken = default) : base(options, httpClient, cancellationToken)
|
||||||
{
|
{
|
||||||
Options = new TelegramBotOptions();
|
Options = new TelegratorOptions();
|
||||||
Handlers = new HandlersCollection(default);
|
Handlers = new HandlersCollection(default);
|
||||||
BotInfo = new TelegramBotInfo(this.GetMe(cancellationToken).Result);
|
BotInfo = new TelegramBotInfo(this.GetMe(cancellationToken).Result);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
using Telegrator.Configuration;
|
||||||
|
|
||||||
|
namespace Telegrator
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Configuration options for Telegram bot behavior and execution settings.
|
||||||
|
/// Controls various aspects of bot operation including concurrency, routing, and execution policies.
|
||||||
|
/// </summary>
|
||||||
|
public class TelegratorOptions : ITelegratorOptions
|
||||||
|
{
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool ExecuteOnlyFirstFoundHanlder { get; set; }
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public int? MaximumParallelWorkingHandlers { get; set; }
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool ExclusiveAwaitingHandlerRouting { get; set; }
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public CancellationToken GlobalCancellationToken { get; set; }
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool DescendDescriptorIndex { get; set; } = true;
|
||||||
|
|
||||||
|
/// <inheritdoc/>
|
||||||
|
public bool ExceptIntersectingCommandAliases { get; set; } = true;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user