* Added integration addon wit WTelegramBot (WIP)
* Added some extensions methods * Refactored Result behaviour * Added missing exception messages * Removed telegrator-specific host builder (obsolete) * Code cleanup and bug fixes
This commit is contained in:
@@ -4,6 +4,7 @@
|
||||
<Project Path="src/Telegrator.Analyzers/Telegrator.Analyzers.csproj" />
|
||||
<Project Path="src/Telegrator.Hosting.Web/Telegrator.Hosting.Web.csproj" />
|
||||
<Project Path="src/Telegrator.Hosting/Telegrator.Hosting.csproj" />
|
||||
<Project Path="src/Telegrator.Hosting.WideBot/Telegrator.Hosting.WideBot.csproj" />
|
||||
<Project Path="src/Telegrator.Localized/Telegrator.Localized.csproj" />
|
||||
<Project Path="src/Telegrator/Telegrator.csproj" />
|
||||
<Project Path="tests/Telegrator.Tests/Telegrator.Tests.csproj" />
|
||||
|
||||
@@ -6,3 +6,4 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
|
||||
[assembly: SuppressMessage("Style", "IDE0090")]
|
||||
[assembly: SuppressMessage("Roslynator", "RCS1037")]
|
||||
|
||||
@@ -112,7 +112,7 @@ public class ImplicitHandlerBuilderExtensionsGenerator : IIncrementalGenerator
|
||||
{
|
||||
try
|
||||
{
|
||||
PrimaryConstructorBaseTypeSyntax primaryConstructor = (PrimaryConstructorBaseTypeSyntax)classDeclaration.BaseList.Types.ElementAt(0);
|
||||
PrimaryConstructorBaseTypeSyntax primaryConstructor = (PrimaryConstructorBaseTypeSyntax)classDeclaration.BaseList.Types[0];
|
||||
MethodDeclarationSyntax genExtension = GeneratedExtensionsMethod(classDeclaration, classDeclaration.ParameterList, primaryConstructor.ArgumentList, targeter);
|
||||
extensions.Add(genExtension);
|
||||
}
|
||||
@@ -239,7 +239,7 @@ public class ImplicitHandlerBuilderExtensionsGenerator : IIncrementalGenerator
|
||||
if (targeters.TryGetValue(classDeclaration.Identifier.ValueText, out MethodDeclarationSyntax targeter))
|
||||
return targeter;
|
||||
|
||||
if (classDeclaration.BaseList != null && targeters.TryGetValue(classDeclaration.BaseList.Types.ElementAt(0).Type.ToString(), out targeter))
|
||||
if (classDeclaration.BaseList != null && targeters.TryGetValue(classDeclaration.BaseList.Types[0].Type.ToString(), out targeter))
|
||||
return targeter;
|
||||
|
||||
return null;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
namespace Telegrator.RoslynGenerators.RoslynExtensions
|
||||
{
|
||||
namespace Telegrator.RoslynGenerators.RoslynExtensions;
|
||||
|
||||
public static class CollectionsExtensions
|
||||
{
|
||||
public static IEnumerable<TSource> Combine<TSource>(params IEnumerable<TSource>[] collections)
|
||||
@@ -61,4 +61,3 @@
|
||||
public static IEnumerable<T> Repeat<T>(this T item, int times)
|
||||
=> Enumerable.Range(0, times).Select(_ => item);
|
||||
}
|
||||
}
|
||||
|
||||
+11
-144
@@ -4,131 +4,6 @@
|
||||
<name>Telegrator.Hosting.Web</name>
|
||||
</assembly>
|
||||
<members>
|
||||
<member name="T:Telegrator.Hosting.Web.TelegramBotWebHost">
|
||||
<summary>
|
||||
Represents a web hosted telegram bot
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Telegrator.Hosting.Web.TelegramBotWebHost.Services">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="P:Telegrator.Hosting.Web.TelegramBotWebHost.UpdateRouter">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="P:Telegrator.Hosting.Web.TelegramBotWebHost.DataSources">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="P:Telegrator.Hosting.Web.TelegramBotWebHost.Lifetime">
|
||||
<summary>
|
||||
Allows consumers to be notified of application lifetime events.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Telegrator.Hosting.Web.TelegramBotWebHost.Logger">
|
||||
<summary>
|
||||
This application's logger
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Telegrator.Hosting.Web.TelegramBotWebHost.Properties">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:Telegrator.Hosting.Web.TelegramBotWebHost.#ctor(Microsoft.AspNetCore.Builder.WebApplicationBuilder)">
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:Microsoft.AspNetCore.Builder.WebApplicationBuilder"/> class.
|
||||
</summary>
|
||||
<param name="webApplicationBuilder">The proxied instance of host builder.</param>
|
||||
</member>
|
||||
<member name="M:Telegrator.Hosting.Web.TelegramBotWebHost.CreateBuilder(Microsoft.AspNetCore.Builder.WebApplicationOptions)">
|
||||
<summary>
|
||||
Creates new <see cref="T:Telegrator.Hosting.TelegramBotHostBuilder"/> with default services and webhook update receiving scheme
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:Telegrator.Hosting.Web.TelegramBotWebHost.CreateSlimBuilder(Microsoft.AspNetCore.Builder.WebApplicationOptions)">
|
||||
<summary>
|
||||
Creates new SLIM <see cref="T:Telegrator.Hosting.TelegramBotHostBuilder"/> with default services and webhook update receiving scheme
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:Telegrator.Hosting.Web.TelegramBotWebHost.CreateEmptyBuilder(Microsoft.AspNetCore.Builder.WebApplicationOptions)">
|
||||
<summary>
|
||||
Creates new EMPTY <see cref="T:Telegrator.Hosting.TelegramBotHostBuilder"/> WITHOUT any services or update receiving schemes
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:Telegrator.Hosting.Web.TelegramBotWebHost.StartAsync(System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:Telegrator.Hosting.Web.TelegramBotWebHost.StopAsync(System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:Telegrator.Hosting.Web.TelegramBotWebHost.CreateApplicationBuilder">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:Telegrator.Hosting.Web.TelegramBotWebHost.Use(System.Func{Microsoft.AspNetCore.Http.RequestDelegate,Microsoft.AspNetCore.Http.RequestDelegate})">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:Telegrator.Hosting.Web.TelegramBotWebHost.New">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:Telegrator.Hosting.Web.TelegramBotWebHost.Build">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:Telegrator.Hosting.Web.TelegramBotWebHost.DisposeAsync">
|
||||
<summary>
|
||||
Disposes the host.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Telegrator.Hosting.Web.TelegramBotWebHost.Dispose">
|
||||
<summary>
|
||||
Disposes the host.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:Telegrator.Hosting.Web.TelegramBotWebHostBuilder">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="P:Telegrator.Hosting.Web.TelegramBotWebHostBuilder.Handlers">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="P:Telegrator.Hosting.Web.TelegramBotWebHostBuilder.Configuration">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="P:Telegrator.Hosting.Web.TelegramBotWebHostBuilder.Logging">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="P:Telegrator.Hosting.Web.TelegramBotWebHostBuilder.Services">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="P:Telegrator.Hosting.Web.TelegramBotWebHostBuilder.Environment">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="P:Telegrator.Hosting.Web.TelegramBotWebHostBuilder.Properties">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="P:Telegrator.Hosting.Web.TelegramBotWebHostBuilder.Metrics">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:Telegrator.Hosting.Web.TelegramBotWebHostBuilder.#ctor(Microsoft.AspNetCore.Builder.WebApplicationBuilder)">
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:Telegrator.Hosting.Web.TelegramBotWebHostBuilder"/> class.
|
||||
</summary>
|
||||
<param name="webApplicationBuilder"></param>
|
||||
</member>
|
||||
<member name="M:Telegrator.Hosting.Web.TelegramBotWebHostBuilder.#ctor(Microsoft.AspNetCore.Builder.WebApplicationBuilder,Telegrator.Core.IHandlersCollection)">
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:Telegrator.Hosting.Web.TelegramBotWebHostBuilder"/> class.
|
||||
</summary>
|
||||
<param name="webApplicationBuilder"></param>
|
||||
<param name="handlers"></param>
|
||||
</member>
|
||||
<member name="M:Telegrator.Hosting.Web.TelegramBotWebHostBuilder.Build">
|
||||
<summary>
|
||||
Builds the host.
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:Telegrator.Hosting.Web.TelegramBotWebHostBuilder.ConfigureContainer``1(Microsoft.Extensions.DependencyInjection.IServiceProviderFactory{``0},System.Action{``0})">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="T:Telegrator.Hosting.Web.WebhookerOptions">
|
||||
<summary>
|
||||
Configuration options for Telegram bot behavior and execution settings.
|
||||
@@ -200,20 +75,12 @@
|
||||
Provides method to configure Telegram Bot WebHost
|
||||
</summary>
|
||||
</member>
|
||||
<member name="F:Telegrator.ServicesCollectionExtensions.HandlersCollectionPropertyKey">
|
||||
<summary>
|
||||
The key used to store the <see cref="T:Telegrator.Core.IHandlersCollection"/> in the builder properties.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Telegrator.ServicesCollectionExtensions.get_Handlers(Microsoft.AspNetCore.Builder.WebApplicationBuilder)">
|
||||
<inheritdoc cref="P:Telegrator.ServicesCollectionExtensions.<G>$41F16C2D39AF52899E745C9C9F42FF83.Handlers"/>
|
||||
</member>
|
||||
<member name="M:Telegrator.ServicesCollectionExtensions.AddTelegratorWeb(Telegrator.Hosting.ITelegramBotHostBuilder,Telegrator.TelegratorOptions,Telegrator.Core.IHandlersCollection,System.Action{Telegrator.Hosting.ITelegramBotHostBuilder})">
|
||||
<member name="M:Telegrator.ServicesCollectionExtensions.AddTelegratorWeb(Microsoft.Extensions.Hosting.IHostApplicationBuilder,Telegrator.TelegratorOptions,Telegrator.Core.IHandlersCollection)">
|
||||
<summary>
|
||||
Replaces TelegramBotWebHostBuilder. Configures DI, options, and handlers.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Telegrator.ServicesCollectionExtensions.AddTelegratorWeb(Microsoft.AspNetCore.Builder.WebApplicationBuilder,Telegrator.TelegratorOptions,Telegrator.Core.IHandlersCollection,System.Action{Telegrator.Hosting.ITelegramBotHostBuilder})">
|
||||
<member name="M:Telegrator.ServicesCollectionExtensions.AddTelegratorWeb(Microsoft.Extensions.Hosting.IHostApplicationBuilder,Telegrator.TelegratorOptions,Telegrator.Core.IHandlersCollection,System.Action{Telegrator.Hosting.ITelegramBotHostBuilder})">
|
||||
<summary>
|
||||
Replaces TelegramBotWebHostBuilder. Configures DI, options, and handlers.
|
||||
</summary>
|
||||
@@ -223,7 +90,12 @@
|
||||
Replaces TelegramBotWebHostBuilder. Configures DI, options, and handlers.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Telegrator.ServicesCollectionExtensions.TryFindWebhooker(System.IServiceProvider,Telegrator.Mediation.HostedUpdateWebhooker@)">
|
||||
<member name="T:Telegrator.TelegramBotHostExtensions">
|
||||
<summary>
|
||||
Provides useful methods to adjust Telegram bot Host
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Telegrator.TelegramBotHostExtensions.TryFindWebhooker(System.IServiceProvider,Telegrator.Mediation.HostedUpdateWebhooker@)">
|
||||
<summary>
|
||||
Searchs for <see cref="T:Telegrator.Mediation.HostedUpdateWebhooker"/> hosted service inside hosts services
|
||||
</summary>
|
||||
@@ -231,13 +103,13 @@
|
||||
<param name="webhooker"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:Telegrator.ServicesCollectionExtensions.UseTelegratorWeb``1(``0,System.Boolean)">
|
||||
<member name="M:Telegrator.TelegramBotHostExtensions.UseTelegratorWeb``1(``0,System.Boolean)">
|
||||
<summary>
|
||||
Replaces the initialization logic from TelegramBotWebHost constructor.
|
||||
Initializes the bot and logs handlers on application startup.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Telegrator.ServicesCollectionExtensions.RemapWebhook``1(``0,System.String)">
|
||||
<member name="M:Telegrator.TelegramBotHostExtensions.RemapWebhook``1(``0,System.String)">
|
||||
<summary>
|
||||
Allows to remap receiving webhook endpoint and map new route to webhost.
|
||||
</summary>
|
||||
@@ -246,17 +118,12 @@
|
||||
<returns></returns>
|
||||
<exception cref="T:System.ArgumentException"></exception>
|
||||
</member>
|
||||
<member name="M:Telegrator.ServicesCollectionExtensions.AddTelegramWebhook(Microsoft.Extensions.DependencyInjection.IServiceCollection)">
|
||||
<member name="M:Telegrator.TelegramBotHostExtensions.AddTelegramWebhook(Microsoft.Extensions.DependencyInjection.IServiceCollection)">
|
||||
<summary>
|
||||
Registers <see cref="T:Telegram.Bot.ITelegramBotClient"/> service with <see cref="T:Telegrator.Mediation.HostedUpdateWebhooker"/> to receive updates using webhook
|
||||
</summary>
|
||||
<param name="services"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="P:Telegrator.ServicesCollectionExtensions.<G>$41F16C2D39AF52899E745C9C9F42FF83.Handlers">
|
||||
<summary>
|
||||
Gets the <see cref="T:Telegrator.Core.IHandlersCollection"/> from the builder properties.
|
||||
</summary>
|
||||
</member>
|
||||
</members>
|
||||
</doc>
|
||||
|
||||
+18
-81
@@ -40,63 +40,6 @@
|
||||
Represents a hosted telegram bots and services builder that helps manage configuration, logging, lifetime, and more.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:Telegrator.Hosting.TelegramBotHost">
|
||||
<summary>
|
||||
Represents a hosted telegram bot
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Telegrator.Hosting.TelegramBotHost.Services">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="P:Telegrator.Hosting.TelegramBotHost.UpdateRouter">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="P:Telegrator.Hosting.TelegramBotHost.Logger">
|
||||
<summary>
|
||||
This application's logger
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Telegrator.Hosting.TelegramBotHost.#ctor(Microsoft.Extensions.Hosting.HostApplicationBuilder)">
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:Telegrator.Hosting.TelegramBotHost"/> class.
|
||||
</summary>
|
||||
<param name="hostApplicationBuilder">The proxied instance of host builder.</param>
|
||||
</member>
|
||||
<member name="M:Telegrator.Hosting.TelegramBotHost.CreateBuilder">
|
||||
<summary>
|
||||
Creates new <see cref="T:Telegrator.Hosting.TelegramBotHostBuilder"/> with default configuration, services and long-polling update receiving scheme
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:Telegrator.Hosting.TelegramBotHost.CreateBuilder(Microsoft.Extensions.Hosting.HostApplicationBuilderSettings)">
|
||||
<summary>
|
||||
Creates new <see cref="T:Telegrator.Hosting.TelegramBotHostBuilder"/> with default services and long-polling update receiving scheme
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:Telegrator.Hosting.TelegramBotHost.CreateEmptyBuilder">
|
||||
<summary>
|
||||
Creates new EMPTY <see cref="T:Telegrator.Hosting.TelegramBotHostBuilder"/> WITHOUT any services or update receiving schemes
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:Telegrator.Hosting.TelegramBotHost.CreateEmptyBuilder(Microsoft.Extensions.Hosting.HostApplicationBuilderSettings)">
|
||||
<summary>
|
||||
Creates new EMPTY <see cref="T:Telegrator.Hosting.TelegramBotHostBuilder"/> WITHOUT any services or update receiving schemes
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:Telegrator.Hosting.TelegramBotHost.StartAsync(System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:Telegrator.Hosting.TelegramBotHost.StopAsync(System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:Telegrator.Hosting.TelegramBotHost.Dispose">
|
||||
<summary>
|
||||
Disposes the host.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="T:Telegrator.Hosting.TelegramBotHostBuilder">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
@@ -121,25 +64,19 @@
|
||||
<member name="P:Telegrator.Hosting.TelegramBotHostBuilder.Metrics">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:Telegrator.Hosting.TelegramBotHostBuilder.#ctor(Microsoft.Extensions.Hosting.HostApplicationBuilder)">
|
||||
<member name="M:Telegrator.Hosting.TelegramBotHostBuilder.#ctor(Microsoft.Extensions.Hosting.IHostApplicationBuilder)">
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:Telegrator.Hosting.TelegramBotHostBuilder"/> class.
|
||||
</summary>
|
||||
<param name="hostApplicationBuilder"></param>
|
||||
</member>
|
||||
<member name="M:Telegrator.Hosting.TelegramBotHostBuilder.#ctor(Microsoft.Extensions.Hosting.HostApplicationBuilder,Telegrator.Core.IHandlersCollection)">
|
||||
<member name="M:Telegrator.Hosting.TelegramBotHostBuilder.#ctor(Microsoft.Extensions.Hosting.IHostApplicationBuilder,Telegrator.Core.IHandlersCollection)">
|
||||
<summary>
|
||||
Initializes a new instance of the <see cref="T:Telegrator.Hosting.TelegramBotHostBuilder"/> class.
|
||||
</summary>
|
||||
<param name="hostApplicationBuilder"></param>
|
||||
<param name="handlers"></param>
|
||||
</member>
|
||||
<member name="M:Telegrator.Hosting.TelegramBotHostBuilder.Build">
|
||||
<summary>
|
||||
Builds the host.
|
||||
</summary>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:Telegrator.Hosting.TelegramBotHostBuilder.ConfigureContainer``1(Microsoft.Extensions.DependencyInjection.IServiceProviderFactory{``0},System.Action{``0})">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
@@ -158,7 +95,7 @@
|
||||
<member name="M:Telegrator.Logging.MicrosoftLoggingAdapter.Log(Telegrator.Logging.LogLevel,System.String,System.Exception)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="T:Telegrator.Polling.HostedUpdateReceiver">
|
||||
<member name="T:Telegrator.Mediation.HostedUpdateReceiver">
|
||||
<summary>
|
||||
Service for receiving updates for Hosted telegram bots
|
||||
</summary>
|
||||
@@ -167,7 +104,7 @@
|
||||
<param name="options"></param>
|
||||
<param name="logger"></param>
|
||||
</member>
|
||||
<member name="M:Telegrator.Polling.HostedUpdateReceiver.#ctor(Telegram.Bot.ITelegramBotClient,Telegrator.Core.IUpdateRouter,Microsoft.Extensions.Options.IOptions{Telegram.Bot.Polling.ReceiverOptions},Microsoft.Extensions.Logging.ILogger{Telegrator.Polling.HostedUpdateReceiver})">
|
||||
<member name="M:Telegrator.Mediation.HostedUpdateReceiver.#ctor(Telegram.Bot.ITelegramBotClient,Telegrator.Core.IUpdateRouter,Microsoft.Extensions.Options.IOptions{Telegram.Bot.Polling.ReceiverOptions},Microsoft.Extensions.Logging.ILogger{Telegrator.Mediation.HostedUpdateReceiver})">
|
||||
<summary>
|
||||
Service for receiving updates for Hosted telegram bots
|
||||
</summary>
|
||||
@@ -176,24 +113,24 @@
|
||||
<param name="options"></param>
|
||||
<param name="logger"></param>
|
||||
</member>
|
||||
<member name="M:Telegrator.Polling.HostedUpdateReceiver.ExecuteAsync(System.Threading.CancellationToken)">
|
||||
<member name="M:Telegrator.Mediation.HostedUpdateReceiver.ExecuteAsync(System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="T:Telegrator.Polling.HostUpdateRouter">
|
||||
<member name="T:Telegrator.Mediation.HostUpdateRouter">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="F:Telegrator.Polling.HostUpdateRouter.Logger">
|
||||
<member name="F:Telegrator.Mediation.HostUpdateRouter.Logger">
|
||||
<summary>
|
||||
<see cref="T:Microsoft.Extensions.Logging.ILogger"/> of this router
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Telegrator.Polling.HostUpdateRouter.#ctor(Telegrator.Core.IHandlersProvider,Telegrator.Core.IAwaitingProvider,Telegrator.Core.States.IStateStorage,Microsoft.Extensions.Options.IOptions{Telegrator.TelegratorOptions},Telegrator.Core.ITelegramBotInfo,Microsoft.Extensions.Logging.ILogger{Telegrator.Polling.HostUpdateRouter})">
|
||||
<member name="M:Telegrator.Mediation.HostUpdateRouter.#ctor(Telegrator.Core.IHandlersProvider,Telegrator.Core.IAwaitingProvider,Telegrator.Core.States.IStateStorage,Microsoft.Extensions.Options.IOptions{Telegrator.TelegratorOptions},Telegrator.Core.ITelegramBotInfo,Microsoft.Extensions.Logging.ILogger{Telegrator.Mediation.HostUpdateRouter})">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:Telegrator.Polling.HostUpdateRouter.HandleUpdateAsync(Telegram.Bot.ITelegramBotClient,Telegram.Bot.Types.Update,System.Threading.CancellationToken)">
|
||||
<member name="M:Telegrator.Mediation.HostUpdateRouter.HandleUpdateAsync(Telegram.Bot.ITelegramBotClient,Telegram.Bot.Types.Update,System.Threading.CancellationToken)">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="M:Telegrator.Polling.HostUpdateRouter.HandleException(Telegram.Bot.ITelegramBotClient,System.Exception,Telegram.Bot.Polling.HandleErrorSource,System.Threading.CancellationToken)">
|
||||
<member name="M:Telegrator.Mediation.HostUpdateRouter.HandleException(Telegram.Bot.ITelegramBotClient,System.Exception,Telegram.Bot.Polling.HandleErrorSource,System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
Default exception handler of this router
|
||||
</summary>
|
||||
@@ -239,12 +176,7 @@
|
||||
The key used to store the <see cref="T:Telegrator.Core.IHandlersCollection"/> in the builder properties.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Telegrator.HostBuilderExtensions.AddTelegrator(Telegrator.Hosting.ITelegramBotHostBuilder,Telegrator.TelegratorOptions,Telegrator.Core.IHandlersCollection,System.Action{Telegrator.Hosting.ITelegramBotHostBuilder})">
|
||||
<summary>
|
||||
Replaces TelegramBotHostBuilder. Configures DI, options, and handlers.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Telegrator.HostBuilderExtensions.AddTelegrator(Microsoft.Extensions.Hosting.HostApplicationBuilder,Telegrator.TelegratorOptions,Telegrator.Core.IHandlersCollection,System.Action{Telegrator.Hosting.ITelegramBotHostBuilder})">
|
||||
<member name="M:Telegrator.HostBuilderExtensions.AddTelegrator(Microsoft.Extensions.Hosting.IHostApplicationBuilder,Telegrator.TelegratorOptions,Telegrator.Core.IHandlersCollection,System.Action{Telegrator.Hosting.ITelegramBotHostBuilder})">
|
||||
<summary>
|
||||
Replaces TelegramBotHostBuilder. Configures DI, options, and handlers.
|
||||
</summary>
|
||||
@@ -259,6 +191,11 @@
|
||||
Replaces TelegramBotHostBuilder. Configures DI, options, and handlers.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Telegrator.HostBuilderExtensions.AddTelegrator(Microsoft.Extensions.Hosting.IHostBuilder,Telegrator.TelegratorOptions,Telegrator.Core.IHandlersCollection,System.Action{Telegrator.Core.IHandlersCollection})">
|
||||
<summary>
|
||||
Replaces TelegramBotHostBuilder. Configures DI, options, and handlers.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Telegrator.HostBuilderExtensions.AddTelegratorInternal(Microsoft.Extensions.DependencyInjection.IServiceCollection,Microsoft.Extensions.Configuration.IConfiguration,System.Collections.Generic.IDictionary{System.Object,System.Object},Telegrator.Core.IHandlersCollection@,Telegrator.TelegratorOptions)">
|
||||
<summary>
|
||||
Replaces TelegramBotHostBuilder. Configures DI, options, and handlers.
|
||||
@@ -280,14 +217,14 @@
|
||||
</member>
|
||||
<member name="M:Telegrator.ServicesCollectionExtensions.AddTelegramBotHostDefaults(Microsoft.Extensions.DependencyInjection.IServiceCollection)">
|
||||
<summary>
|
||||
Registers <see cref="T:Telegrator.Hosting.TelegramBotHost"/> default services
|
||||
Registers <see cref="N:Telegrator"/> default services
|
||||
</summary>
|
||||
<param name="services"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:Telegrator.ServicesCollectionExtensions.AddTelegramReceiver(Microsoft.Extensions.DependencyInjection.IServiceCollection)">
|
||||
<summary>
|
||||
Registers <see cref="T:Telegram.Bot.ITelegramBotClient"/> service with <see cref="T:Telegrator.Polling.HostedUpdateReceiver"/> to receive updates using long polling
|
||||
Registers <see cref="T:Telegram.Bot.ITelegramBotClient"/> service with <see cref="T:Telegrator.Mediation.HostedUpdateReceiver"/> to receive updates using long polling
|
||||
</summary>
|
||||
<param name="services"></param>
|
||||
<returns></returns>
|
||||
|
||||
+23
-12
@@ -6027,6 +6027,9 @@
|
||||
Manages the distribution of updates between regular handlers and awaiting handlers.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Telegrator.Mediation.UpdateRouter.Options">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="P:Telegrator.Mediation.UpdateRouter.HandlersProvider">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
@@ -6036,9 +6039,6 @@
|
||||
<member name="P:Telegrator.Mediation.UpdateRouter.StateStorage">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="P:Telegrator.Mediation.UpdateRouter.Options">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
<member name="P:Telegrator.Mediation.UpdateRouter.HandlersPool">
|
||||
<inheritdoc/>
|
||||
</member>
|
||||
@@ -6377,14 +6377,9 @@
|
||||
Represents handler results, allowing to communicate with router and control aspect execution
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Telegrator.Result.Positive">
|
||||
<member name="P:Telegrator.Result.InterruptRouter">
|
||||
<summary>
|
||||
Is result positive
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Telegrator.Result.RouteNext">
|
||||
<summary>
|
||||
Should router search for next matching handler
|
||||
Tell router to stop describing
|
||||
</summary>
|
||||
</member>
|
||||
<member name="P:Telegrator.Result.NextType">
|
||||
@@ -6449,6 +6444,14 @@
|
||||
<param name="keySelector"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:Telegrator.ColletionsExtensions.Squeeze``1(System.Collections.Generic.IEnumerable{``0})">
|
||||
<summary>
|
||||
Remove all <see langword="null"/> values and returns collection without nullable type.
|
||||
</summary>
|
||||
<typeparam name="T"></typeparam>
|
||||
<param name="source"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:Telegrator.ColletionsExtensions.ForEach``1(System.Collections.Generic.IEnumerable{``0},System.Action{``0})">
|
||||
<summary>
|
||||
Enumerates objects in a <paramref name="source"/> and executes an <paramref name="action"/> on each one
|
||||
@@ -6558,7 +6561,7 @@
|
||||
<param name="type"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:Telegrator.ReflectionExtensions.IsHandlerRealization(System.Type)">
|
||||
<member name="M:Telegrator.ReflectionExtensions.IsHandlerImplementation(System.Type)">
|
||||
<summary>
|
||||
Checks if <paramref name="type"/> is an implementation of <see cref="T:Telegrator.Core.Handlers.UpdateHandlerBase"/> class or its descendants
|
||||
</summary>
|
||||
@@ -6802,7 +6805,7 @@
|
||||
Initializes the update router and begins polling for updates.
|
||||
</summary>
|
||||
<param name="receiverOptions">Optional receiver options for configuring update polling.</param>
|
||||
<param name="cancellationToken">The cancellation token to stop receiving updates.</param>
|
||||
<param name="globalCancellationToken">The cancellation token to stop receiving updates.</param>
|
||||
</member>
|
||||
<member name="M:Telegrator.TelegratorClient.StartReceivingInternal(Telegram.Bot.Polling.ReceiverOptions,System.Threading.CancellationToken)">
|
||||
<summary>
|
||||
@@ -7113,6 +7116,14 @@
|
||||
Provides convenient methods for creating implicit handlers.
|
||||
</summary>
|
||||
</member>
|
||||
<member name="M:Telegrator.HandlersCollectionExtensions.CollectHandlers(Telegrator.Core.IHandlersCollection)">
|
||||
<summary>
|
||||
Collects all handlers from current app domain.
|
||||
Scans for handlers exported by analyzer into class `Telegrator.Analyzers.AnalyzerExport` in each assembly and registers them to the collection.
|
||||
</summary>
|
||||
<param name="handlers"></param>
|
||||
<returns></returns>
|
||||
</member>
|
||||
<member name="M:Telegrator.HandlersCollectionExtensions.CollectHandlersDomainWide(Telegrator.Core.IHandlersCollection)">
|
||||
<summary>
|
||||
Collects all public handlers from the current app domain.
|
||||
|
||||
@@ -10,6 +10,8 @@ namespace Telegrator.Analyzers;
|
||||
[Generator(LanguageNames.CSharp)]
|
||||
public class DeveloperHelperAnalyzer : IIncrementalGenerator
|
||||
{
|
||||
internal record class HandlerDeclarationModel(string ClassName, string NamespaceName, string? AttributeName, string? BaseClassName, Location Location);
|
||||
|
||||
private static readonly DiagnosticDescriptor MissingBaseClassWarning = new(
|
||||
id: "TLG101",
|
||||
title: "Missing handlers base class",
|
||||
@@ -131,9 +133,8 @@ public class DeveloperHelperAnalyzer : IIncrementalGenerator
|
||||
|
||||
private static FieldDeclarationSyntax GenerateTypeField(HandlerDeclarationModel handler)
|
||||
{
|
||||
string fullTypeName = handler.Namespace == "Global"
|
||||
? handler.ClassName
|
||||
: $"{handler.Namespace}.{handler.ClassName}";
|
||||
string fullTypeName = handler.NamespaceName == "Global"
|
||||
? handler.ClassName : $"{handler.NamespaceName}.{handler.ClassName}";
|
||||
|
||||
TypeOfExpressionSyntax typeofExpression = SyntaxFactory.TypeOfExpression(SyntaxFactory.ParseTypeName(fullTypeName));
|
||||
VariableDeclaratorSyntax variableDeclarator = SyntaxFactory.VariableDeclarator(SyntaxFactory.Identifier($"{handler.ClassName}Type"))
|
||||
@@ -149,15 +150,6 @@ public class DeveloperHelperAnalyzer : IIncrementalGenerator
|
||||
}
|
||||
}
|
||||
|
||||
internal class HandlerDeclarationModel(string className, string namespaceName, string? attributeName, string? baseClassName, Location location)
|
||||
{
|
||||
public readonly string ClassName = className;
|
||||
public readonly string Namespace = namespaceName;
|
||||
public readonly string? AttributeName = attributeName;
|
||||
public readonly string? BaseClassName = baseClassName;
|
||||
public readonly Location Location = location;
|
||||
}
|
||||
|
||||
internal static class DeveloperHelperAnalyzerExtensions
|
||||
{
|
||||
private static readonly string[] HandlersNames =
|
||||
|
||||
+5
-27
@@ -8,8 +8,12 @@ using System.Text;
|
||||
namespace Telegrator.Analyzers;
|
||||
|
||||
[Generator(LanguageNames.CSharp)]
|
||||
public class GeneratedKeyboardMarkupGenerator : IIncrementalGenerator
|
||||
public class KeyboardMarkupGenerator : IIncrementalGenerator
|
||||
{
|
||||
// Records
|
||||
private record class GeneratedMarkupMethodModel(MethodDeclarationSyntax OriginalMethod, FieldDeclarationSyntax GeneratedField, MethodDeclarationSyntax GeneratedMethod);
|
||||
private record class GeneratedMarkupPropertyModel(PropertyDeclarationSyntax OriginalProperty, PropertyDeclarationSyntax GeneratedProperty);
|
||||
|
||||
// Return types
|
||||
private const string InlineReturnType = "InlineKeyboardMarkup";
|
||||
private const string ReplyReturnType = "ReplyKeyboardMarkup";
|
||||
@@ -459,30 +463,4 @@ public class GeneratedKeyboardMarkupGenerator : IIncrementalGenerator
|
||||
SyntaxFactory.IdentifierName(className),
|
||||
SyntaxFactory.IdentifierName(methodName));
|
||||
}
|
||||
|
||||
private class GeneratedMarkupMethodModel
|
||||
{
|
||||
public MethodDeclarationSyntax OriginalMethod { get; }
|
||||
public FieldDeclarationSyntax GeneratedField { get; }
|
||||
public MethodDeclarationSyntax GeneratedMethod { get; }
|
||||
|
||||
public GeneratedMarkupMethodModel(MethodDeclarationSyntax originalMethod, FieldDeclarationSyntax generatedField, MethodDeclarationSyntax generatedMethod)
|
||||
{
|
||||
OriginalMethod = originalMethod;
|
||||
GeneratedField = generatedField;
|
||||
GeneratedMethod = generatedMethod;
|
||||
}
|
||||
}
|
||||
|
||||
private class GeneratedMarkupPropertyModel
|
||||
{
|
||||
public PropertyDeclarationSyntax OriginalProperty { get; }
|
||||
public PropertyDeclarationSyntax GeneratedProperty { get; }
|
||||
|
||||
public GeneratedMarkupPropertyModel(PropertyDeclarationSyntax originalProperty, PropertyDeclarationSyntax generatedProperty)
|
||||
{
|
||||
OriginalProperty = originalProperty;
|
||||
GeneratedProperty = generatedProperty;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
namespace Telegrator.Analyzers.RoslynExtensions;
|
||||
|
||||
public class TargteterNotFoundException() : Exception() { }
|
||||
|
||||
public class BaseClassTypeNotFoundException() : Exception() { }
|
||||
|
||||
public class AncestorNotFoundException : Exception { }
|
||||
#pragma warning disable RCS1194 // Implement exception constructors
|
||||
public class TargteterNotFoundException() : Exception();
|
||||
public class BaseClassTypeNotFoundException() : Exception();
|
||||
public class AncestorNotFoundException() : Exception();
|
||||
#pragma warning restore RCS1194 // Implement exception constructors
|
||||
|
||||
@@ -10,3 +10,5 @@ using System.Diagnostics.CodeAnalysis;
|
||||
[assembly: SuppressMessage("Usage", "CA2254")]
|
||||
[assembly: SuppressMessage("Maintainability", "CA1510")]
|
||||
[assembly: SuppressMessage("Style", "IDE0270")]
|
||||
[assembly: SuppressMessage("Roslynator", "RCS1037")]
|
||||
[assembly: SuppressMessage("Roslynator", "RCS1224")]
|
||||
|
||||
@@ -1,159 +0,0 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.AspNetCore.Http.Features;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Telegrator.Core;
|
||||
|
||||
namespace Telegrator.Hosting.Web;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a web hosted telegram bot
|
||||
/// </summary>
|
||||
public class TelegramBotWebHost : IHost, IApplicationBuilder, IEndpointRouteBuilder, IAsyncDisposable
|
||||
{
|
||||
private readonly WebApplication _innerApp;
|
||||
private readonly IUpdateRouter _updateRouter;
|
||||
private readonly ILogger<TelegramBotWebHost> _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<TelegramBotWebHost> Logger => _logger;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IDictionary<string, object?> Properties => ((IApplicationBuilder)_innerApp).Properties;
|
||||
|
||||
// Private interface fields
|
||||
IServiceProvider IEndpointRouteBuilder.ServiceProvider => Services;
|
||||
IServiceProvider IApplicationBuilder.ApplicationServices { get => Services; set => throw new NotImplementedException(); }
|
||||
IFeatureCollection IApplicationBuilder.ServerFeatures => ((IApplicationBuilder)_innerApp).ServerFeatures;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="WebApplicationBuilder"/> class.
|
||||
/// </summary>
|
||||
/// <param name="webApplicationBuilder">The proxied instance of host builder.</param>
|
||||
public TelegramBotWebHost(WebApplicationBuilder webApplicationBuilder)
|
||||
{
|
||||
// Building proxy application
|
||||
_innerApp = webApplicationBuilder.Build();
|
||||
|
||||
// Reruesting services for this host
|
||||
_updateRouter = Services.GetRequiredService<IUpdateRouter>();
|
||||
_logger = Services.GetRequiredService<ILogger<TelegramBotWebHost>>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates new <see cref="TelegramBotHostBuilder"/> with default services and webhook update receiving scheme
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static TelegramBotWebHostBuilder CreateBuilder(WebApplicationOptions? settings)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(settings, nameof(settings));
|
||||
WebApplicationBuilder innerApp = WebApplication.CreateBuilder(settings);
|
||||
TelegramBotWebHostBuilder builder = new TelegramBotWebHostBuilder(innerApp);
|
||||
builder.AddTelegratorWeb();
|
||||
return builder;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates new SLIM <see cref="TelegramBotHostBuilder"/> with default services and webhook update receiving scheme
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static TelegramBotWebHostBuilder CreateSlimBuilder(WebApplicationOptions? settings)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(settings, nameof(settings));
|
||||
WebApplicationBuilder innerApp = WebApplication.CreateSlimBuilder(settings);
|
||||
TelegramBotWebHostBuilder builder = new TelegramBotWebHostBuilder(innerApp);
|
||||
builder.AddTelegratorWeb();
|
||||
return builder;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates new EMPTY <see cref="TelegramBotHostBuilder"/> WITHOUT any services or update receiving schemes
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static TelegramBotWebHostBuilder CreateEmptyBuilder(WebApplicationOptions? settings)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(settings, nameof(settings));
|
||||
WebApplicationBuilder innerApp = WebApplication.CreateEmptyBuilder(settings);
|
||||
TelegramBotWebHostBuilder builder = new TelegramBotWebHostBuilder(innerApp);
|
||||
builder.AddTelegratorWeb();
|
||||
return builder;
|
||||
}
|
||||
|
||||
/// <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;
|
||||
|
||||
ValueTask disposeTask = _innerApp.DisposeAsync();
|
||||
disposeTask.AsTask().Wait();
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
_disposed = true;
|
||||
}
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Diagnostics.Metrics;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Telegrator.Core;
|
||||
|
||||
#pragma warning disable IDE0001
|
||||
namespace Telegrator.Hosting.Web;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public class TelegramBotWebHostBuilder : ITelegramBotHostBuilder
|
||||
{
|
||||
private readonly WebApplicationBuilder _innerBuilder;
|
||||
internal IHandlersCollection _handlers = null!;
|
||||
|
||||
/// <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;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IDictionary<object, object> Properties => ((IHostApplicationBuilder)_innerBuilder).Properties;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IMetricsBuilder Metrics => _innerBuilder.Metrics;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="TelegramBotWebHostBuilder"/> class.
|
||||
/// </summary>
|
||||
/// <param name="webApplicationBuilder"></param>
|
||||
public TelegramBotWebHostBuilder(WebApplicationBuilder webApplicationBuilder)
|
||||
{
|
||||
_innerBuilder = webApplicationBuilder ?? throw new ArgumentNullException(nameof(webApplicationBuilder));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="TelegramBotWebHostBuilder"/> class.
|
||||
/// </summary>
|
||||
/// <param name="webApplicationBuilder"></param>
|
||||
/// <param name="handlers"></param>
|
||||
public TelegramBotWebHostBuilder(WebApplicationBuilder webApplicationBuilder, IHandlersCollection handlers)
|
||||
{
|
||||
_innerBuilder = webApplicationBuilder ?? throw new ArgumentNullException(nameof(webApplicationBuilder));
|
||||
_handlers = handlers ?? throw new ArgumentNullException(nameof(handlers));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Builds the host.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public TelegramBotWebHost Build()
|
||||
{
|
||||
TelegramBotWebHost host = new TelegramBotWebHost(_innerBuilder);
|
||||
host.UseTelegratorWeb();
|
||||
return host;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void ConfigureContainer<TContainerBuilder>(IServiceProviderFactory<TContainerBuilder> factory, Action<TContainerBuilder>? configure = null) where TContainerBuilder : notnull
|
||||
{
|
||||
((IHostApplicationBuilder)_innerBuilder).ConfigureContainer(factory, configure);
|
||||
}
|
||||
}
|
||||
@@ -6,25 +6,8 @@ using Telegrator.Hosting.Web;
|
||||
|
||||
namespace Telegrator;
|
||||
|
||||
internal class Program
|
||||
internal static class Program
|
||||
{
|
||||
public static void TelegramBotWebHostBuilder_Example(string[] args)
|
||||
{
|
||||
TelegramBotWebHostBuilder builder = TelegramBotWebHost.CreateBuilder(new WebApplicationOptions()
|
||||
{
|
||||
Args = args,
|
||||
ApplicationName = "TelegramBotWebHost example",
|
||||
});
|
||||
|
||||
builder.Handlers
|
||||
.CollectHandlersAssemblyWide();
|
||||
|
||||
builder.Build()
|
||||
.AddLoggingAdapter()
|
||||
.SetBotCommands()
|
||||
.Run();
|
||||
}
|
||||
|
||||
public static void WebApplicationBuilder_Example(string[] args)
|
||||
{
|
||||
WebApplicationBuilder builder = WebApplication.CreateBuilder(new WebApplicationOptions()
|
||||
@@ -38,28 +21,7 @@ internal class Program
|
||||
|
||||
builder.Build()
|
||||
.UseTelegratorWeb(dontMap: true)
|
||||
.RemapWebhook("https://awesome-butt-sex.cloudpub.ru/")
|
||||
.AddLoggingAdapter()
|
||||
.SetBotCommands()
|
||||
.Run();
|
||||
}
|
||||
|
||||
public static void TelegramBotHostBuilder_Example(string[] args)
|
||||
{
|
||||
ConfigurationManager configuration = new ConfigurationManager();
|
||||
configuration.AddJsonFile("appsettings.json");
|
||||
|
||||
TelegramBotHostBuilder builder = TelegramBotHost.CreateBuilder(new HostApplicationBuilderSettings()
|
||||
{
|
||||
Args = args,
|
||||
ApplicationName = "TelegramBotHost example",
|
||||
Configuration = configuration
|
||||
});
|
||||
|
||||
builder.Handlers
|
||||
.CollectHandlersAssemblyWide();
|
||||
|
||||
builder.Build()
|
||||
.RemapWebhook("https://amazing-butt-sex.cloudpub.ru/")
|
||||
.AddLoggingAdapter()
|
||||
.SetBotCommands()
|
||||
.Run();
|
||||
|
||||
@@ -8,45 +8,43 @@ using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Telegram.Bot;
|
||||
using Telegram.Bot.Polling;
|
||||
using Telegrator.Core;
|
||||
using Telegrator.Hosting;
|
||||
using Telegrator.Hosting.Web;
|
||||
using Telegrator.Mediation;
|
||||
using Telegrator.Providers;
|
||||
|
||||
namespace Telegrator
|
||||
{
|
||||
namespace Telegrator;
|
||||
|
||||
/// <summary>
|
||||
/// Contains extensions for <see cref="IServiceCollection"/>
|
||||
/// Provides method to configure Telegram Bot WebHost
|
||||
/// </summary>
|
||||
public static class ServicesCollectionExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// The key used to store the <see cref="IHandlersCollection"/> in the builder properties.
|
||||
/// </summary>
|
||||
public const string HandlersCollectionPropertyKey = nameof(IHandlersCollection);
|
||||
public static IServiceCollection ConfigureWebhooker(this IServiceCollection services, WebhookerOptions options)
|
||||
{
|
||||
services.AddSingleton(Options.Create(options));
|
||||
return services;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Replaces TelegramBotWebHostBuilder. Configures DI, options, and handlers.
|
||||
/// </summary>
|
||||
public static ITelegramBotHostBuilder AddTelegratorWeb(this ITelegramBotHostBuilder builder, TelegratorOptions? options = null, IHandlersCollection? handlers = null, Action<ITelegramBotHostBuilder>? action = null)
|
||||
public static IHostApplicationBuilder AddTelegratorWeb(this IHostApplicationBuilder builder, TelegratorOptions? options = null, IHandlersCollection? handlers = null)
|
||||
{
|
||||
AddTelegratorWebInternal(builder.Services, builder.Configuration, builder.Properties, ref handlers, options);
|
||||
if (builder is TelegramBotWebHostBuilder telegramBotHostBuilder)
|
||||
telegramBotHostBuilder._handlers = handlers;
|
||||
|
||||
action?.Invoke(builder);
|
||||
return builder;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Replaces TelegramBotWebHostBuilder. Configures DI, options, and handlers.
|
||||
/// </summary>
|
||||
public static IHostApplicationBuilder AddTelegratorWeb(this WebApplicationBuilder builder, TelegratorOptions? options = null, IHandlersCollection? handlers = null, Action<ITelegramBotHostBuilder>? action = null)
|
||||
public static IHostApplicationBuilder AddTelegratorWeb(this IHostApplicationBuilder builder, TelegratorOptions? options = null, IHandlersCollection? handlers = null, Action<ITelegramBotHostBuilder>? action = null)
|
||||
{
|
||||
AddTelegratorWebInternal(builder.Services, builder.Configuration, ((IHostApplicationBuilder)builder).Properties, ref handlers, options);
|
||||
action?.Invoke(new TelegramBotWebHostBuilder(builder, handlers));
|
||||
AddTelegratorWebInternal(builder.Services, builder.Configuration, builder.Properties, ref handlers, options);
|
||||
action?.Invoke(new TelegramBotHostBuilder(builder, handlers));
|
||||
return builder;
|
||||
}
|
||||
|
||||
@@ -55,11 +53,14 @@ namespace Telegrator
|
||||
/// </summary>
|
||||
internal static void AddTelegratorWebInternal(IServiceCollection services, IConfiguration configuration, IDictionary<object, object> properties, [NotNull] ref IHandlersCollection? handlers, TelegratorOptions? options = null)
|
||||
{
|
||||
if (options == null)
|
||||
if (services.Any(srvc => srvc.ServiceType == typeof(HostedUpdateReceiver)))
|
||||
throw new InvalidOperationException("`HostedUpdateReceiver` found in services. WebHost extension is not compatible with long-polling receiving. Please, remove `AddTelegrator` invocation from your WebApp configuration.");
|
||||
|
||||
if (options is null)
|
||||
{
|
||||
options = configuration.GetSection(nameof(TelegratorOptions)).Get<TelegratorOptions>();
|
||||
if (options == null)
|
||||
throw new MissingMemberException("Auto configuration disabled, yet no options of type 'TelegratorOptions' wasn't registered. This configuration is runtime required!");
|
||||
if (options is null)
|
||||
throw new MissingMemberException("Auto configuration disabled, yet no options of type 'TelegratorOptions' was registered. This configuration is runtime required!");
|
||||
}
|
||||
|
||||
CancellationTokenSource globallCancell = new CancellationTokenSource();
|
||||
@@ -67,25 +68,22 @@ namespace Telegrator
|
||||
services.AddSingleton(Options.Create(options));
|
||||
services.AddKeyedSingleton("cancell", globallCancell);
|
||||
|
||||
if (handlers != null)
|
||||
{
|
||||
if (handlers is IHandlersManager manager)
|
||||
if (handlers is not null && handlers is IHandlersManager manager)
|
||||
{
|
||||
ServiceDescriptor descriptor = new ServiceDescriptor(typeof(IHandlersProvider), manager);
|
||||
services.Replace(descriptor);
|
||||
services.AddSingleton(manager);
|
||||
}
|
||||
}
|
||||
|
||||
handlers ??= new HostHandlersCollection(services, options);
|
||||
services.AddSingleton(handlers);
|
||||
properties.Add(HandlersCollectionPropertyKey, handlers);
|
||||
properties.Add(HostBuilderExtensions.HandlersCollectionPropertyKey, handlers);
|
||||
|
||||
if (!services.Any(srvc => srvc.ImplementationType == typeof(IOptions<WebhookerOptions>)))
|
||||
if (!services.Any(srvc => srvc.ServiceType == typeof(IOptions<WebhookerOptions>)))
|
||||
{
|
||||
WebhookerOptions? webhookerOptions = configuration.GetSection(nameof(WebhookerOptions)).Get<WebhookerOptions>();
|
||||
if (webhookerOptions == null)
|
||||
throw new MissingMemberException("Auto configuration disabled, yet no options of type 'WebhookerOptions' wasn't registered. This configuration is runtime required!");
|
||||
throw new MissingMemberException("Auto configuration disabled, yet no options of type 'WebhookerOptions' was registered. This configuration is runtime required!");
|
||||
|
||||
services.AddSingleton(Options.Create(webhookerOptions));
|
||||
}
|
||||
@@ -102,7 +100,13 @@ namespace Telegrator
|
||||
services.AddTelegramBotHostDefaults();
|
||||
services.AddTelegramWebhook();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Provides useful methods to adjust Telegram bot Host
|
||||
/// </summary>
|
||||
public static class TelegramBotHostExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Searchs for <see cref="HostedUpdateWebhooker"/> hosted service inside hosts services
|
||||
/// </summary>
|
||||
@@ -119,27 +123,30 @@ namespace Telegrator
|
||||
/// Replaces the initialization logic from TelegramBotWebHost constructor.
|
||||
/// Initializes the bot and logs handlers on application startup.
|
||||
/// </summary>
|
||||
public static T UseTelegratorWeb<T>(this T app, bool dontMap = false) where T : IEndpointRouteBuilder, IHost
|
||||
public static T UseTelegratorWeb<T>(this T botHost, bool dontMap = false) where T : IEndpointRouteBuilder, IHost
|
||||
{
|
||||
if (!app.ServiceProvider.TryFindWebhooker(out HostedUpdateWebhooker? webhooker))
|
||||
if (!botHost.ServiceProvider.TryFindWebhooker(out HostedUpdateWebhooker? webhooker))
|
||||
throw new InvalidOperationException("No service for type 'Telegrator.Mediation.HostedUpdateWebhooker' has been registered.");
|
||||
|
||||
ITelegramBotInfo info = app.ServiceProvider.GetRequiredService<ITelegramBotInfo>();
|
||||
IHandlersCollection handlers = app.ServiceProvider.GetRequiredService<IHandlersCollection>();
|
||||
ILoggerFactory loggerFactory = app.ServiceProvider.GetRequiredService<ILoggerFactory>();
|
||||
ITelegramBotInfo info = botHost.ServiceProvider.GetRequiredService<ITelegramBotInfo>();
|
||||
IHandlersCollection handlers = botHost.ServiceProvider.GetRequiredService<IHandlersCollection>();
|
||||
ILoggerFactory loggerFactory = botHost.ServiceProvider.GetRequiredService<ILoggerFactory>();
|
||||
ILogger logger = loggerFactory.CreateLogger("Telegrator.Hosting.Web.TelegratorHost");
|
||||
|
||||
if (logger.IsEnabled(LogLevel.Information))
|
||||
{
|
||||
logger.LogInformation("Telegrator Bot ASP.NET WebHost started");
|
||||
logger.LogInformation("Telegrator Bot Host started (ASP.NET WebHost)");
|
||||
logger.LogInformation("Receiving mode : WEB-HOOKING");
|
||||
logger.LogInformation("Telegram Bot : {firstname}, @{usrname}, id:{id},", info.User.FirstName ?? "[NULL]", info.User.Username ?? "[NULL]", info.User.Id);
|
||||
logger.LogHandlers(handlers);
|
||||
}
|
||||
|
||||
if (!dontMap)
|
||||
webhooker.MapWebhook(app);
|
||||
webhooker.MapWebhook(botHost);
|
||||
|
||||
return app;
|
||||
botHost.AddLoggingAdapter();
|
||||
botHost.SetBotCommands();
|
||||
return botHost;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -173,4 +180,3 @@ namespace Telegrator
|
||||
private static ITelegramBotClient TypedTelegramBotClientFactory(HttpClient httpClient, IServiceProvider provider)
|
||||
=> new TelegramBotClient(provider.GetRequiredService<IOptions<TelegramBotClientOptions>>().Value, httpClient);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
// 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("Roslynator", "RCS1037")]
|
||||
@@ -0,0 +1,35 @@
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Telegram.Bot;
|
||||
using Telegram.Bot.Polling;
|
||||
using Telegrator.Core;
|
||||
|
||||
namespace Telegrator.Mediation;
|
||||
|
||||
//Hosting.WideBot
|
||||
public class HostedWideBotUpdateReceiver(ILogger<HostedWideBotUpdateReceiver> logger, ITelegramBotClient botClient, IUpdateRouter updateRouter, IOptions<ReceiverOptions>? options) : BackgroundService
|
||||
{
|
||||
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
|
||||
{
|
||||
if (botClient is not WTelegramBotClient wideBotClient)
|
||||
throw new Exception("Registered ITelegramBotClient was not a wide client (WTelegramBotClient)! Please, use `AddWideTelegrator` instead.");
|
||||
|
||||
if (options?.Value.DropPendingUpdates is true)
|
||||
await wideBotClient.DropPendingUpdates();
|
||||
|
||||
logger.LogInformation("Starting receiving updates via MTProto");
|
||||
|
||||
// UIP (understanding in progress)
|
||||
//_receiverOptions.AllowedUpdates = updateRouter.HandlersProvider.AllowedTypes.ToArray();
|
||||
|
||||
botClient.DeleteWebhook(options?.Value.DropPendingUpdates ?? false, cancellationToken: stoppingToken)
|
||||
.ConfigureAwait(false).GetAwaiter().GetResult();
|
||||
|
||||
WideUpdateReceiver updateReceiver = new WideUpdateReceiver(wideBotClient);
|
||||
await updateReceiver.ReceiveAsync(updateRouter, stoppingToken).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Telegram.Bot;
|
||||
using Telegram.Bot.Polling;
|
||||
using Telegrator.Core;
|
||||
using WUpdate = WTelegram.Types.Update;
|
||||
|
||||
namespace Telegrator.Mediation;
|
||||
|
||||
public class WideUpdateReceiver(WTelegramBotClient client) : IUpdateReceiver
|
||||
{
|
||||
private readonly WTelegramBotClient _client = client;
|
||||
private IUpdateHandler? _updateHandler = null;
|
||||
private CancellationToken _cancellation = default;
|
||||
|
||||
public async Task ReceiveAsync(IUpdateHandler updateHandler, CancellationToken cancellationToken = default)
|
||||
{
|
||||
_updateHandler = updateHandler;
|
||||
_cancellation = cancellationToken;
|
||||
|
||||
TaskCompletionSource<object> tcs = new TaskCompletionSource<object>(TaskCreationOptions.RunContinuationsAsynchronously);
|
||||
await using CancellationTokenRegistration registration = cancellationToken.Register(() => tcs.TrySetResult(null!));
|
||||
|
||||
try
|
||||
{
|
||||
_client.OnUpdate += OnUpdate;
|
||||
await tcs.Task.ConfigureAwait(false);
|
||||
}
|
||||
finally
|
||||
{
|
||||
_client.OnUpdate -= OnUpdate;
|
||||
}
|
||||
}
|
||||
|
||||
private async Task OnUpdate(WUpdate update)
|
||||
{
|
||||
if (_updateHandler == null)
|
||||
throw new Exception("Router not initialized (got null)");
|
||||
|
||||
try
|
||||
{
|
||||
await _updateHandler.HandleUpdateAsync(_client, update, _cancellation).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
await _updateHandler.HandleErrorAsync(_client, ex, HandleErrorSource.HandleUpdateError, _cancellation).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net10.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<RootNamespace>Telegrator</RootNamespace>
|
||||
<LangVersion>latest</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="WTelegramBot" Version="9.5.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\..\src\Telegrator.Hosting\Telegrator.Hosting.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,76 @@
|
||||
// Maybe later...
|
||||
|
||||
/*
|
||||
using System;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using Telegram.Bot;
|
||||
using Telegram.Bot.Polling;
|
||||
using Telegrator.Core;
|
||||
using Telegrator.Logging;
|
||||
using Telegrator.Mediation;
|
||||
using Telegrator.Providers;
|
||||
using Telegrator.States;
|
||||
|
||||
namespace Telegrator;
|
||||
|
||||
public class TelegratorWClient : WTelegramBotClient, ITelegratorBot, ICollectingProvider
|
||||
{
|
||||
private IUpdateRouter? _updateRouter = null;
|
||||
|
||||
public TelegratorOptions Options { get; }
|
||||
|
||||
public IHandlersCollection Handlers { get; }
|
||||
|
||||
public ITelegramBotInfo BotInfo { get; }
|
||||
|
||||
public IUpdateRouter UpdateRouter => _updateRouter ?? throw new InvalidOperationException("Router's not created yet. Invoke `StartReceiving` to initialize this property.");
|
||||
|
||||
public TelegratorWClient(WTelegramBotClientOptions wOptions, TelegratorOptions? telegratorOptions = null, HttpClient? httpClient = null, CancellationToken cancellationToken = default)
|
||||
: base(wOptions, httpClient, cancellationToken)
|
||||
{
|
||||
Options = telegratorOptions ?? new TelegratorOptions();
|
||||
Handlers = new HandlersCollection(default);
|
||||
BotInfo = new TelegramBotInfo(GetMe(cancellationToken).Result);
|
||||
}
|
||||
|
||||
public void StartReceiving(CancellationToken cancellationToken = default)
|
||||
{
|
||||
if (Options.GlobalCancellationToken == CancellationToken.None)
|
||||
Options.GlobalCancellationToken = cancellationToken;
|
||||
|
||||
HandlersProvider handlerProvider = new HandlersProvider(Handlers, Options);
|
||||
AwaitingProvider awaitingProvider = new AwaitingProvider(Options);
|
||||
DefaultStateStorage stateStorage = new DefaultStateStorage();
|
||||
|
||||
_updateRouter = new UpdateRouter(handlerProvider, awaitingProvider, stateStorage, Options, BotInfo);
|
||||
TelegratorLogging.LogInformation($"TelegratorW bot starting up - BotId: {BotInfo.User.Id}, Username: {BotInfo.User.Username}");
|
||||
|
||||
StartReceivingInternal(Options.GlobalCancellationToken);
|
||||
}
|
||||
|
||||
private async void StartReceivingInternal(CancellationToken cancellationToken)
|
||||
{
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
await new HostedWideBotUpdateReceiver(this)
|
||||
.ReceiveAsync(UpdateRouter, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception exception)
|
||||
{
|
||||
await UpdateRouter
|
||||
.HandleErrorAsync(this, exception, HandleErrorSource.FatalError, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
catch (OperationCanceledException)
|
||||
{
|
||||
// Cancelled
|
||||
TelegratorLogging.LogInformation("Telegrator bot stopped (cancelled)");
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
@@ -0,0 +1,181 @@
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.DependencyInjection.Extensions;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading;
|
||||
using Telegram.Bot;
|
||||
using Telegram.Bot.Types;
|
||||
using Telegrator.Core;
|
||||
using Telegrator.Core.Handlers;
|
||||
using Telegrator.Hosting;
|
||||
using Telegrator.Mediation;
|
||||
using Telegrator.Providers;
|
||||
|
||||
using TLUpdate = TL.Update;
|
||||
using WUpdate = WTelegram.Types.Update;
|
||||
|
||||
namespace Telegrator;
|
||||
|
||||
public static class HandlersExtensions
|
||||
{
|
||||
extension<TUpdate>(AbstractUpdateHandler<TUpdate> handler) where TUpdate : class
|
||||
{
|
||||
public WUpdate WUpdate
|
||||
{
|
||||
get
|
||||
{
|
||||
object? update = typeof(AbstractUpdateHandler<TUpdate>).GetField("HandlingUpdate")?.GetValue(handler);
|
||||
if (update is not WUpdate wUpdate)
|
||||
throw new InvalidCastException();
|
||||
|
||||
return wUpdate;
|
||||
}
|
||||
}
|
||||
|
||||
public TLUpdate? TLUpdate
|
||||
{
|
||||
get => handler.WUpdate.TLUpdate;
|
||||
}
|
||||
}
|
||||
|
||||
public static WUpdate AsWUpdate(this Update update)
|
||||
{
|
||||
return update as WUpdate
|
||||
?? throw new InvalidCastException("Update is not assignable to `WTelegram.Types.Update`");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Provides extension methods for <see cref="IHostApplicationBuilder"/> to configure Telegrator.
|
||||
/// </summary>
|
||||
public static class ServiceCollectionExtensions
|
||||
{
|
||||
public static IServiceCollection ConfigureWideTelegram(this IServiceCollection services, WTelegramBotClientOptions options)
|
||||
{
|
||||
services.AddSingleton(Options.Create(options));
|
||||
return services;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Replaces TelegramBotHostBuilder. Configures DI, options, and handlers.
|
||||
/// </summary>
|
||||
public static IHostApplicationBuilder AddWideTelegrator(this IHostApplicationBuilder builder, TelegratorOptions? options = null, IHandlersCollection? handlers = null, Action<ITelegramBotHostBuilder>? action = null)
|
||||
{
|
||||
AddTelegratorInternal(builder.Services, builder.Configuration, builder.Properties, ref handlers, options);
|
||||
action?.Invoke(new TelegramBotHostBuilder(builder, handlers));
|
||||
return builder;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Replaces TelegramBotHostBuilder. Configures DI, options, and handlers.
|
||||
/// </summary>
|
||||
public static IHostApplicationBuilder AddWideTelegrator(this IHostApplicationBuilder builder, TelegratorOptions? options = null, IHandlersCollection? handlers = null)
|
||||
{
|
||||
AddTelegratorInternal(builder.Services, builder.Configuration, builder.Properties, ref handlers, options);
|
||||
return builder;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Replaces TelegramBotHostBuilder. Configures DI, options, and handlers.
|
||||
/// </summary>
|
||||
internal static void AddTelegratorInternal(IServiceCollection services, IConfiguration configuration, IDictionary<object, object> properties, [NotNull] ref IHandlersCollection? handlers, TelegratorOptions? options = null)
|
||||
{
|
||||
if (services.Any(srvc => srvc.ServiceType == typeof(HostedUpdateReceiver)))
|
||||
throw new InvalidOperationException("`HostedUpdateReceiver` found in services. WideHost extension is not compatible with long-polling receiving. Please, remove `AddTelegrator` invocation from your WebApp configuration.");
|
||||
|
||||
if (options == null)
|
||||
{
|
||||
options = configuration.GetSection(nameof(TelegratorOptions)).Get<TelegratorOptions>();
|
||||
if (options == null)
|
||||
throw new MissingMemberException("Auto configuration disabled, yet no options of type 'TelegratorOptions' was registered. This configuration is runtime required!");
|
||||
}
|
||||
|
||||
CancellationTokenSource globallCancell = new CancellationTokenSource();
|
||||
options.GlobalCancellationToken = globallCancell.Token;
|
||||
services.AddSingleton(Options.Create(options));
|
||||
services.AddKeyedSingleton("cancell", globallCancell);
|
||||
|
||||
if (handlers != null)
|
||||
{
|
||||
if (handlers is IHandlersManager manager)
|
||||
{
|
||||
ServiceDescriptor descriptor = new ServiceDescriptor(typeof(IHandlersProvider), manager);
|
||||
services.Replace(descriptor);
|
||||
services.AddSingleton(manager);
|
||||
}
|
||||
}
|
||||
|
||||
handlers ??= new HostHandlersCollection(services, options);
|
||||
services.AddSingleton(handlers);
|
||||
properties.Add(HostBuilderExtensions.HandlersCollectionPropertyKey, handlers);
|
||||
|
||||
if (!services.Any(srvc => srvc.ImplementationType == typeof(IOptions<WTelegramBotClientOptions>)))
|
||||
{
|
||||
// For now, there's no way to configure this from IConfiguration, use `ConfigureWideTelegram` instead
|
||||
throw new MissingMemberException("No options of type 'WTelegramBotClientOptions' was registered. This configuration is runtime required! Use `ConfigureWideTelegram` to register options.");
|
||||
|
||||
/*
|
||||
services.AddSingleton(Options.Create(new WTelegramBotClientOptions(options.Token, options.BaseUrl, options.UseTestEnvironment)
|
||||
{
|
||||
RetryCount = options.RetryCount,
|
||||
RetryThreshold = options.RetryThreshold
|
||||
}));
|
||||
*/
|
||||
}
|
||||
|
||||
services.AddTelegramBotHostDefaults();
|
||||
services.AddMTProtoUpdateReceiver();
|
||||
}
|
||||
|
||||
public static IServiceCollection AddMTProtoUpdateReceiver(this IServiceCollection services)
|
||||
{
|
||||
services.AddHttpClient<WTelegramBotClient>("tgmtproto").RemoveAllLoggers().AddTypedClient(TypedTelegramBotClientFactory);
|
||||
services.AddSingleton<ITelegramBotClient>(sp => sp.GetRequiredService<WTelegramBotClient>());
|
||||
services.AddHostedService<HostedWideBotUpdateReceiver>();
|
||||
return services;
|
||||
}
|
||||
|
||||
private static WTelegramBotClient TypedTelegramBotClientFactory(HttpClient httpClient, IServiceProvider provider)
|
||||
=> new WTelegramBotClient(provider.GetRequiredService<IOptions<WTelegramBotClientOptions>>().Value, httpClient);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Provides useful methods to adjust Telegram bot Host
|
||||
/// </summary>
|
||||
public static class TelegramBotHostExtensions
|
||||
{
|
||||
public static IHost UseWideTelegrator(this IHost botHost)
|
||||
{
|
||||
if (!botHost.Services.TryFindWTelegramBotClient())
|
||||
throw new InvalidOperationException("No service for type 'Telegram.Bot.WTelegramBotClient' has been registered. Invoke `AddWideTelegrator`");
|
||||
|
||||
ITelegramBotInfo info = botHost.Services.GetRequiredService<ITelegramBotInfo>();
|
||||
IHandlersCollection handlers = botHost.Services.GetRequiredService<IHandlersCollection>();
|
||||
ILoggerFactory loggerFactory = botHost.Services.GetRequiredService<ILoggerFactory>();
|
||||
ILogger logger = loggerFactory.CreateLogger("Telegrator.Hosting.Web.TelegratorHost");
|
||||
|
||||
if (logger.IsEnabled(LogLevel.Information))
|
||||
{
|
||||
logger.LogInformation("Telegrator WIDE Bot Host started (Generic Host)");
|
||||
logger.LogInformation("Receiving mode : MTProto");
|
||||
logger.LogInformation("Telegram Bot : {firstname}, @{usrname}, id:{id},", info.User.FirstName ?? "[NULL]", info.User.Username ?? "[NULL]", info.User.Id);
|
||||
logger.LogHandlers(handlers);
|
||||
}
|
||||
|
||||
botHost.AddLoggingAdapter();
|
||||
botHost.SetBotCommands();
|
||||
return botHost;
|
||||
}
|
||||
|
||||
private static bool TryFindWTelegramBotClient(this IServiceProvider services)
|
||||
{
|
||||
return services.GetServices<IHostedService>().Any(s => s is HostedWideBotUpdateReceiver);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
|
||||
namespace Telegrator;
|
||||
|
||||
public class WideReceiverOptions
|
||||
{
|
||||
}
|
||||
@@ -10,3 +10,4 @@ using System.Diagnostics.CodeAnalysis;
|
||||
[assembly: SuppressMessage("Usage", "CA2254")]
|
||||
[assembly: SuppressMessage("Maintainability", "CA1510")]
|
||||
[assembly: SuppressMessage("Style", "IDE0270")]
|
||||
[assembly: SuppressMessage("Roslynator", "RCS1037")]
|
||||
|
||||
@@ -6,7 +6,4 @@ namespace Telegrator.Hosting;
|
||||
/// <summary>
|
||||
/// Represents a hosted telegram bots and services builder that helps manage configuration, logging, lifetime, and more.
|
||||
/// </summary>
|
||||
public interface ITelegramBotHostBuilder : IHostApplicationBuilder, ICollectingProvider
|
||||
{
|
||||
|
||||
}
|
||||
public interface ITelegramBotHostBuilder : IHostApplicationBuilder, ICollectingProvider;
|
||||
|
||||
@@ -1,114 +0,0 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Telegrator.Core;
|
||||
|
||||
namespace Telegrator.Hosting;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a hosted telegram bot
|
||||
/// </summary>
|
||||
public class TelegramBotHost : IHost, ITelegratorBot
|
||||
{
|
||||
private readonly IHost _innerHost;
|
||||
private readonly IUpdateRouter _updateRouter;
|
||||
private readonly ILogger<TelegramBotHost> _logger;
|
||||
|
||||
private bool _disposed;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IServiceProvider Services => _innerHost.Services;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IUpdateRouter UpdateRouter => _updateRouter;
|
||||
|
||||
/// <summary>
|
||||
/// This application's logger
|
||||
/// </summary>
|
||||
public ILogger<TelegramBotHost> Logger => _logger;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="TelegramBotHost"/> class.
|
||||
/// </summary>
|
||||
/// <param name="hostApplicationBuilder">The proxied instance of host builder.</param>
|
||||
public TelegramBotHost(HostApplicationBuilder hostApplicationBuilder)
|
||||
{
|
||||
// Registering this host in services for easy access
|
||||
hostApplicationBuilder.Services.AddSingleton<ITelegratorBot>(this);
|
||||
|
||||
// Building proxy hoster
|
||||
_innerHost = hostApplicationBuilder.Build();
|
||||
|
||||
// Reruesting services for this host
|
||||
_updateRouter = Services.GetRequiredService<IUpdateRouter>();
|
||||
_logger = Services.GetRequiredService<ILogger<TelegramBotHost>>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates new <see cref="TelegramBotHostBuilder"/> with default configuration, services and long-polling update receiving scheme
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static TelegramBotHostBuilder CreateBuilder()
|
||||
{
|
||||
HostApplicationBuilder innerBuilder = new HostApplicationBuilder(settings: null);
|
||||
TelegramBotHostBuilder builder = new TelegramBotHostBuilder(innerBuilder);
|
||||
return builder;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates new <see cref="TelegramBotHostBuilder"/> with default services and long-polling update receiving scheme
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static TelegramBotHostBuilder CreateBuilder(HostApplicationBuilderSettings? settings)
|
||||
{
|
||||
HostApplicationBuilder innerBuilder = new HostApplicationBuilder(settings);
|
||||
TelegramBotHostBuilder builder = new TelegramBotHostBuilder(innerBuilder);
|
||||
return builder;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates new EMPTY <see cref="TelegramBotHostBuilder"/> WITHOUT any services or update receiving schemes
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static TelegramBotHostBuilder CreateEmptyBuilder()
|
||||
{
|
||||
HostApplicationBuilder innerBuilder = Host.CreateEmptyApplicationBuilder(null);
|
||||
return new TelegramBotHostBuilder(innerBuilder);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates new EMPTY <see cref="TelegramBotHostBuilder"/> WITHOUT any services or update receiving schemes
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static TelegramBotHostBuilder CreateEmptyBuilder(HostApplicationBuilderSettings? settings)
|
||||
{
|
||||
HostApplicationBuilder innerBuilder = Host.CreateEmptyApplicationBuilder(settings);
|
||||
return new TelegramBotHostBuilder(innerBuilder);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task StartAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
await _innerHost.StartAsync(cancellationToken);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public async Task StopAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
await _innerHost.StopAsync(cancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disposes the host.
|
||||
/// </summary>
|
||||
public void Dispose()
|
||||
{
|
||||
if (_disposed)
|
||||
return;
|
||||
|
||||
_innerHost.Dispose();
|
||||
|
||||
GC.SuppressFinalize(this);
|
||||
_disposed = true;
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ namespace Telegrator.Hosting;
|
||||
/// <inheritdoc/>
|
||||
public class TelegramBotHostBuilder : ITelegramBotHostBuilder
|
||||
{
|
||||
private readonly HostApplicationBuilder _innerBuilder;
|
||||
private readonly IHostApplicationBuilder _innerBuilder;
|
||||
internal IHandlersCollection _handlers = null!;
|
||||
|
||||
/// <inheritdoc/>
|
||||
@@ -30,7 +30,7 @@ public class TelegramBotHostBuilder : ITelegramBotHostBuilder
|
||||
public IHostEnvironment Environment => _innerBuilder.Environment;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IDictionary<object, object> Properties => ((IHostApplicationBuilder)_innerBuilder).Properties;
|
||||
public IDictionary<object, object> Properties => _innerBuilder.Properties;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IMetricsBuilder Metrics => _innerBuilder.Metrics;
|
||||
@@ -39,7 +39,7 @@ public class TelegramBotHostBuilder : ITelegramBotHostBuilder
|
||||
/// Initializes a new instance of the <see cref="TelegramBotHostBuilder"/> class.
|
||||
/// </summary>
|
||||
/// <param name="hostApplicationBuilder"></param>
|
||||
public TelegramBotHostBuilder(HostApplicationBuilder hostApplicationBuilder)
|
||||
public TelegramBotHostBuilder(IHostApplicationBuilder hostApplicationBuilder)
|
||||
{
|
||||
_innerBuilder = hostApplicationBuilder ?? throw new ArgumentNullException(nameof(hostApplicationBuilder));
|
||||
}
|
||||
@@ -49,23 +49,12 @@ public class TelegramBotHostBuilder : ITelegramBotHostBuilder
|
||||
/// </summary>
|
||||
/// <param name="hostApplicationBuilder"></param>
|
||||
/// <param name="handlers"></param>
|
||||
public TelegramBotHostBuilder(HostApplicationBuilder hostApplicationBuilder, IHandlersCollection handlers)
|
||||
public TelegramBotHostBuilder(IHostApplicationBuilder hostApplicationBuilder, IHandlersCollection handlers)
|
||||
{
|
||||
_innerBuilder = hostApplicationBuilder ?? throw new ArgumentNullException(nameof(hostApplicationBuilder));
|
||||
_handlers = handlers ?? throw new ArgumentNullException(nameof(handlers));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Builds the host.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public TelegramBotHost Build()
|
||||
{
|
||||
TelegramBotHost host = new TelegramBotHost(_innerBuilder);
|
||||
host.UseTelegrator();
|
||||
return host;
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public void ConfigureContainer<TContainerBuilder>(IServiceProviderFactory<TContainerBuilder> factory, Action<TContainerBuilder>? configure = null) where TContainerBuilder : notnull
|
||||
{
|
||||
|
||||
+1
-2
@@ -5,9 +5,8 @@ using Telegram.Bot.Polling;
|
||||
using Telegram.Bot.Types;
|
||||
using Telegrator.Core;
|
||||
using Telegrator.Core.States;
|
||||
using Telegrator.Mediation;
|
||||
|
||||
namespace Telegrator.Polling;
|
||||
namespace Telegrator.Mediation;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public class HostUpdateRouter : UpdateRouter
|
||||
+3
-3
@@ -4,9 +4,8 @@ using Microsoft.Extensions.Options;
|
||||
using Telegram.Bot;
|
||||
using Telegram.Bot.Polling;
|
||||
using Telegrator.Core;
|
||||
using Telegrator.Mediation;
|
||||
|
||||
namespace Telegrator.Polling;
|
||||
namespace Telegrator.Mediation;
|
||||
|
||||
/// <summary>
|
||||
/// Service for receiving updates for Hosted telegram bots
|
||||
@@ -26,7 +25,8 @@ public class HostedUpdateReceiver(ITelegramBotClient botClient, IUpdateRouter up
|
||||
logger.LogInformation("Starting receiving updates via long-polling");
|
||||
_receiverOptions.AllowedUpdates = _updateRouter.HandlersProvider.AllowedTypes.ToArray();
|
||||
|
||||
botClient.DeleteWebhook(options.Value.DropPendingUpdates).Wait();
|
||||
botClient.DeleteWebhook(options.Value.DropPendingUpdates, cancellationToken: stoppingToken)
|
||||
.ConfigureAwait(false).GetAwaiter().GetResult();
|
||||
|
||||
DefaultUpdateReceiver updateReceiver = new DefaultUpdateReceiver(botClient, _receiverOptions);
|
||||
await updateReceiver.ReceiveAsync(_updateRouter, stoppingToken).ConfigureAwait(false);
|
||||
@@ -17,41 +17,60 @@ public class HostHandlersCollection(IServiceCollection hostServiceColletion, Tel
|
||||
{
|
||||
switch (descriptor.Type)
|
||||
{
|
||||
default:
|
||||
throw new Exception("Unknown descriptor type");
|
||||
|
||||
case DescriptorType.General:
|
||||
{
|
||||
if (descriptor.InstanceFactory != null)
|
||||
{
|
||||
Services.AddScoped(descriptor.HandlerType, _ => descriptor.InstanceFactory.Invoke());
|
||||
else
|
||||
Services.AddScoped(descriptor.HandlerType);
|
||||
break;
|
||||
}
|
||||
|
||||
Services.AddScoped(descriptor.HandlerType);
|
||||
break;
|
||||
}
|
||||
|
||||
case DescriptorType.Keyed:
|
||||
{
|
||||
if (descriptor.InstanceFactory != null)
|
||||
{
|
||||
Services.AddKeyedScoped(descriptor.HandlerType, descriptor.ServiceKey, (_, _) => descriptor.InstanceFactory.Invoke());
|
||||
else
|
||||
Services.AddKeyedScoped(descriptor.HandlerType, descriptor.ServiceKey);
|
||||
break;
|
||||
}
|
||||
|
||||
Services.AddKeyedScoped(descriptor.HandlerType, descriptor.ServiceKey);
|
||||
break;
|
||||
}
|
||||
|
||||
case DescriptorType.Singleton:
|
||||
{
|
||||
Services.AddSingleton(descriptor.HandlerType, descriptor.SingletonInstance ?? (descriptor.InstanceFactory != null
|
||||
? descriptor.InstanceFactory.Invoke()
|
||||
: throw new Exception()));
|
||||
if (descriptor.SingletonInstance != null)
|
||||
{
|
||||
Services.AddSingleton(descriptor.HandlerType, descriptor.SingletonInstance);
|
||||
break;
|
||||
}
|
||||
|
||||
if (descriptor.InstanceFactory == null)
|
||||
throw new InvalidOperationException("Singleton handler descriptor without singleton instance should implement `InstanceFactory`");
|
||||
|
||||
Services.AddSingleton(descriptor.HandlerType, descriptor.InstanceFactory.Invoke());
|
||||
break;
|
||||
}
|
||||
|
||||
case DescriptorType.Implicit:
|
||||
{
|
||||
Services.AddKeyedSingleton(descriptor.HandlerType, descriptor.ServiceKey, descriptor.SingletonInstance ?? (descriptor.InstanceFactory != null
|
||||
? descriptor.InstanceFactory.Invoke()
|
||||
: throw new Exception()));
|
||||
if (descriptor.SingletonInstance != null)
|
||||
{
|
||||
Services.AddKeyedSingleton(descriptor.HandlerType, descriptor.ServiceKey, descriptor.SingletonInstance);
|
||||
break;
|
||||
}
|
||||
|
||||
if (descriptor.InstanceFactory == null)
|
||||
throw new InvalidOperationException("Implicit handler descriptor without singleton instance should implement `InstanceFactory`");
|
||||
|
||||
Services.AddKeyedSingleton(descriptor.HandlerType, descriptor.ServiceKey, descriptor.InstanceFactory.Invoke());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ using Telegrator.Core.Descriptors;
|
||||
using Telegrator.Core.States;
|
||||
using Telegrator.Hosting;
|
||||
using Telegrator.Logging;
|
||||
using Telegrator.Polling;
|
||||
using Telegrator.Mediation;
|
||||
using Telegrator.Providers;
|
||||
using Telegrator.States;
|
||||
|
||||
@@ -34,20 +34,7 @@ public static class HostBuilderExtensions
|
||||
/// <summary>
|
||||
/// Replaces TelegramBotHostBuilder. Configures DI, options, and handlers.
|
||||
/// </summary>
|
||||
public static ITelegramBotHostBuilder AddTelegrator(this ITelegramBotHostBuilder builder, TelegratorOptions? options = null, IHandlersCollection? handlers = null, Action<ITelegramBotHostBuilder>? action = null)
|
||||
{
|
||||
AddTelegratorInternal(builder.Services, builder.Configuration, builder.Properties, ref handlers, options);
|
||||
if (builder is TelegramBotHostBuilder telegramBotHostBuilder)
|
||||
telegramBotHostBuilder._handlers = handlers;
|
||||
|
||||
action?.Invoke(builder);
|
||||
return builder;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Replaces TelegramBotHostBuilder. Configures DI, options, and handlers.
|
||||
/// </summary>
|
||||
public static IHostApplicationBuilder AddTelegrator(this HostApplicationBuilder builder, TelegratorOptions? options = null, IHandlersCollection? handlers = null, Action<ITelegramBotHostBuilder>? action = null)
|
||||
public static IHostApplicationBuilder AddTelegrator(this IHostApplicationBuilder builder, TelegratorOptions? options = null, IHandlersCollection? handlers = null, Action<ITelegramBotHostBuilder>? action = null)
|
||||
{
|
||||
AddTelegratorInternal(builder.Services, builder.Configuration, ((IHostApplicationBuilder)builder).Properties, ref handlers, options);
|
||||
action?.Invoke(new TelegramBotHostBuilder(builder, handlers));
|
||||
@@ -72,6 +59,16 @@ public static class HostBuilderExtensions
|
||||
return builder;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Replaces TelegramBotHostBuilder. Configures DI, options, and handlers.
|
||||
/// </summary>
|
||||
public static IHostBuilder AddTelegrator(this IHostBuilder builder, TelegratorOptions? options = null, IHandlersCollection? handlers = null, Action<IHandlersCollection>? action = null)
|
||||
{
|
||||
builder.ConfigureServices((ctx, sp) => AddTelegratorInternal(sp, ctx.Configuration, builder.Properties, ref handlers, options));
|
||||
action?.Invoke(handlers!); // AddTelegratorInternal initializes `handlers`
|
||||
return builder;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Replaces TelegramBotHostBuilder. Configures DI, options, and handlers.
|
||||
/// </summary>
|
||||
@@ -81,7 +78,7 @@ public static class HostBuilderExtensions
|
||||
{
|
||||
options = configuration.GetSection(nameof(TelegratorOptions)).Get<TelegratorOptions>();
|
||||
if (options == null)
|
||||
throw new MissingMemberException("Auto configuration disabled, yet no options of type 'TelegratorOptions' wasn't registered. This configuration is runtime required!");
|
||||
throw new MissingMemberException("Auto configuration disabled, yet no options of type 'TelegratorOptions' was registered. This configuration is runtime required!");
|
||||
}
|
||||
|
||||
CancellationTokenSource globallCancell = new CancellationTokenSource();
|
||||
@@ -103,11 +100,11 @@ public static class HostBuilderExtensions
|
||||
services.AddSingleton(handlers);
|
||||
properties.Add(HandlersCollectionPropertyKey, handlers);
|
||||
|
||||
if (!services.Any(srvc => srvc.ImplementationType == typeof(IOptions<ReceiverOptions>)))
|
||||
if (!services.Any(srvc => srvc.ServiceType == typeof(IOptions<ReceiverOptions>)))
|
||||
{
|
||||
ReceiverOptions? receiverOptions = configuration.GetSection(nameof(ReceiverOptions)).Get<ReceiverOptions>();
|
||||
if (receiverOptions == null)
|
||||
throw new MissingMemberException("Auto configuration disabled, yet no options of type 'ReceiverOptions' wasn't registered. This configuration is runtime required!");
|
||||
throw new MissingMemberException("Auto configuration disabled, yet no options of type 'ReceiverOptions' was registered. This configuration is runtime required!");
|
||||
|
||||
services.AddSingleton(Options.Create(receiverOptions));
|
||||
}
|
||||
@@ -132,6 +129,18 @@ public static class HostBuilderExtensions
|
||||
/// </summary>
|
||||
public static class ServicesCollectionExtensions
|
||||
{
|
||||
public static IServiceCollection ConfigureTelegram(this IServiceCollection services, TelegramBotClientOptions options)
|
||||
{
|
||||
services.AddSingleton(Options.Create(options));
|
||||
return services;
|
||||
}
|
||||
|
||||
public static IServiceCollection ConfigureReceiver(this IServiceCollection services, ReceiverOptions options)
|
||||
{
|
||||
services.AddSingleton(Options.Create(options));
|
||||
return services;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers <see cref="IStateStorage"/> service
|
||||
/// </summary>
|
||||
@@ -145,7 +154,7 @@ public static class ServicesCollectionExtensions
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers <see cref="TelegramBotHost"/> default services
|
||||
/// Registers <see cref="Telegrator"/> default services
|
||||
/// </summary>
|
||||
/// <param name="services"></param>
|
||||
/// <returns></returns>
|
||||
@@ -200,11 +209,14 @@ public static class TelegramBotHostExtensions
|
||||
|
||||
if (logger.IsEnabled(Microsoft.Extensions.Logging.LogLevel.Information))
|
||||
{
|
||||
logger.LogInformation("Telegrator Bot .NET Host started");
|
||||
logger.LogInformation("Telegrator Bot Host started (Generic Host)");
|
||||
logger.LogInformation("Receiving mode : LONG-POLLING");
|
||||
logger.LogInformation("Telegram Bot : {firstname}, @{usrname}, id:{id},", info.User.FirstName ?? "[NULL]", info.User.Username ?? "[NULL]", info.User.Id);
|
||||
logger.LogHandlers(handlers);
|
||||
}
|
||||
|
||||
botHost.AddLoggingAdapter();
|
||||
botHost.SetBotCommands();
|
||||
return botHost;
|
||||
}
|
||||
|
||||
@@ -219,7 +231,12 @@ public static class TelegramBotHostExtensions
|
||||
IUpdateRouter router = botHost.Services.GetRequiredService<IUpdateRouter>();
|
||||
|
||||
IEnumerable<BotCommand> aliases = router.HandlersProvider.GetBotCommands();
|
||||
client.SetMyCommands(aliases).Wait();
|
||||
if (aliases.Any())
|
||||
{
|
||||
client.SetMyCommands(aliases)
|
||||
.ConfigureAwait(false).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
return botHost;
|
||||
}
|
||||
|
||||
@@ -255,7 +272,7 @@ public static class LoggerExtensions
|
||||
|
||||
StringBuilder logBuilder = new StringBuilder("Registered handlers : ");
|
||||
if (!handlers.Keys.Any())
|
||||
throw new Exception();
|
||||
throw new Exception("No update types were registered");
|
||||
|
||||
foreach (UpdateType updateType in handlers.Keys)
|
||||
{
|
||||
|
||||
@@ -56,7 +56,7 @@ public abstract class UpdateHandlerBase(UpdateType handlingUpdateType) : IUpdate
|
||||
.ExecutePre(this, container, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (!preResult.Positive)
|
||||
if (!preResult.InterruptRouter)
|
||||
return preResult;
|
||||
}
|
||||
catch (NotImplementedException)
|
||||
@@ -69,7 +69,7 @@ public abstract class UpdateHandlerBase(UpdateType handlingUpdateType) : IUpdate
|
||||
{
|
||||
// Executing handler
|
||||
Result execResult = await ExecuteInternal(container, cancellationToken).ConfigureAwait(false);
|
||||
if (!execResult.Positive)
|
||||
if (!execResult.InterruptRouter)
|
||||
return execResult;
|
||||
}
|
||||
catch (NotImplementedException)
|
||||
@@ -86,7 +86,7 @@ public abstract class UpdateHandlerBase(UpdateType handlingUpdateType) : IUpdate
|
||||
.ExecutePost(this, container, cancellationToken)
|
||||
.ConfigureAwait(false);
|
||||
|
||||
if (!postResult.Positive)
|
||||
if (!postResult.InterruptRouter)
|
||||
return postResult;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,27 +19,22 @@ namespace Telegrator.Mediation;
|
||||
/// </summary>
|
||||
public class UpdateRouter : IUpdateRouter
|
||||
{
|
||||
private readonly TelegratorOptions _options;
|
||||
private readonly IHandlersProvider _handlersProvider;
|
||||
private readonly IAwaitingProvider _awaitingProvider;
|
||||
private readonly IStateStorage _stateStorage;
|
||||
private readonly IUpdateHandlersPool _HandlersPool;
|
||||
private readonly ITelegramBotInfo _botInfo;
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IHandlersProvider HandlersProvider => _handlersProvider;
|
||||
public TelegratorOptions Options { get; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IAwaitingProvider AwaitingProvider => _awaitingProvider;
|
||||
public IHandlersProvider HandlersProvider { get; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IStateStorage StateStorage => _stateStorage;
|
||||
public IAwaitingProvider AwaitingProvider { get; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public TelegratorOptions Options => _options;
|
||||
public IStateStorage StateStorage { get; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IUpdateHandlersPool HandlersPool => _HandlersPool;
|
||||
public IUpdateHandlersPool HandlersPool { get; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IRouterExceptionHandler? ExceptionHandler { get; set; }
|
||||
@@ -57,11 +52,11 @@ public class UpdateRouter : IUpdateRouter
|
||||
/// <param name="botInfo"></param>
|
||||
public UpdateRouter(IHandlersProvider handlersProvider, IAwaitingProvider awaitingProvider, IStateStorage stateStorage, TelegratorOptions options, ITelegramBotInfo botInfo)
|
||||
{
|
||||
_options = options;
|
||||
_handlersProvider = handlersProvider;
|
||||
_awaitingProvider = awaitingProvider;
|
||||
_stateStorage = stateStorage;
|
||||
_HandlersPool = new UpdateHandlersPool(this, _options, _options.GlobalCancellationToken);
|
||||
Options = options;
|
||||
HandlersProvider = handlersProvider;
|
||||
AwaitingProvider = awaitingProvider;
|
||||
StateStorage = stateStorage;
|
||||
HandlersPool = new UpdateHandlersPool(this, Options, Options.GlobalCancellationToken);
|
||||
_botInfo = botInfo;
|
||||
}
|
||||
|
||||
@@ -116,7 +111,7 @@ public class UpdateRouter : IUpdateRouter
|
||||
if (lastResult == null)
|
||||
break; // Smth went horribly wrong, better to stop routing
|
||||
|
||||
if (lastResult != null && !lastResult.RouteNext)
|
||||
if (lastResult.InterruptRouter)
|
||||
break;
|
||||
|
||||
TelegratorLogging.LogTrace("Handler '{0}' requested route continuation (Update {1})", handlerInfo.DisplayString, handlerInfo.HandlingUpdate.Id);
|
||||
@@ -146,7 +141,7 @@ public class UpdateRouter : IUpdateRouter
|
||||
if (lastResult == null)
|
||||
break; // Smth went horribly wrong, better to stop routing
|
||||
|
||||
if (lastResult != null && !lastResult.RouteNext)
|
||||
if (lastResult.InterruptRouter)
|
||||
break;
|
||||
|
||||
TelegratorLogging.LogTrace("Handler '{0}' requested route continuation (Update {1})", handlerInfo.DisplayString, handlerInfo.HandlingUpdate.Id);
|
||||
@@ -249,17 +244,13 @@ public class UpdateRouter : IUpdateRouter
|
||||
FiltersFallbackReport report = new FiltersFallbackReport(descriptor, filterContext);
|
||||
Result filtersResult = descriptor.Filters.Validate(filterContext, descriptor.FormReport, ref report);
|
||||
|
||||
if (filtersResult.RouteNext)
|
||||
{
|
||||
if (filtersResult.InterruptRouter)
|
||||
return null;
|
||||
|
||||
Result fallbackResult = handlerInstance.FiltersFallback(report, client, cancellationToken).Result;
|
||||
breakRouting = !fallbackResult.RouteNext;
|
||||
breakRouting = fallbackResult.InterruptRouter;
|
||||
return null;
|
||||
}
|
||||
else if (!filtersResult.Positive)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
return new DescribedHandlerDescriptor(descriptor, this, AwaitingProvider, StateStorage, client, handlerInstance, filterContext, descriptor.DisplayString);
|
||||
}
|
||||
@@ -307,6 +298,4 @@ public class UpdateRouter : IUpdateRouter
|
||||
|
||||
TelegratorLogging.LogTrace(sb.ToString());
|
||||
}
|
||||
|
||||
private class BreakDescribingException : Exception { }
|
||||
}
|
||||
|
||||
@@ -10,29 +10,23 @@ namespace Telegrator;
|
||||
/// </summary>
|
||||
public sealed class Result
|
||||
{
|
||||
private static readonly Result ok = new Result(true, false, null);
|
||||
private static readonly Result fault = new Result(false, false, null);
|
||||
private static readonly Result next = new Result(true, true, null);
|
||||
private static readonly Result ok = new Result(true, null);
|
||||
private static readonly Result fault = new Result(true, null);
|
||||
private static readonly Result next = new Result(false, null);
|
||||
|
||||
/// <summary>
|
||||
/// Is result positive
|
||||
/// Tell router to stop describing
|
||||
/// </summary>
|
||||
public bool Positive { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Should router search for next matching handler
|
||||
/// </summary>
|
||||
public bool RouteNext { get; }
|
||||
public bool InterruptRouter { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Exact type that router should search
|
||||
/// </summary>
|
||||
public Type? NextType { get; }
|
||||
|
||||
internal Result(bool positive, bool routeNext, Type? nextType)
|
||||
internal Result(bool interruptRouter, Type? nextType)
|
||||
{
|
||||
Positive = positive;
|
||||
RouteNext = routeNext;
|
||||
InterruptRouter = interruptRouter;
|
||||
NextType = nextType;
|
||||
}
|
||||
|
||||
@@ -79,5 +73,5 @@ public sealed class Result
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
public static Result Next<T>()
|
||||
=> new Result(true, true, typeof(T));
|
||||
=> new Result(false, typeof(T));
|
||||
}
|
||||
|
||||
@@ -26,6 +26,21 @@ public static partial class ColletionsExtensions
|
||||
return new ReadOnlyDictionary<TKey, TValue>(dictionary);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Remove all <see langword="null"/> values and returns collection without nullable type.
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <param name="source"></param>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<T> Squeeze<T>(this IEnumerable<T?> source)
|
||||
{
|
||||
foreach (T? item in source)
|
||||
{
|
||||
if (item is not null)
|
||||
yield return item;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Enumerates objects in a <paramref name="source"/> and executes an <paramref name="action"/> on each one
|
||||
/// </summary>
|
||||
@@ -188,7 +203,7 @@ public static partial class ReflectionExtensions
|
||||
/// </summary>
|
||||
/// <param name="type"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsHandlerRealization(this Type type)
|
||||
public static bool IsHandlerImplementation(this Type type)
|
||||
=> !type.IsAbstract && type != typeof(UpdateHandlerBase) && typeof(UpdateHandlerBase).IsAssignableFrom(type);
|
||||
|
||||
/// <summary>
|
||||
@@ -260,6 +275,7 @@ public static partial class StringExtensions
|
||||
{
|
||||
char[] chars = target.ToCharArray();
|
||||
int index = chars.IndexOf(char.IsLetter);
|
||||
|
||||
chars[index] = char.ToUpper(chars[index]);
|
||||
return new string(chars);
|
||||
}
|
||||
@@ -273,6 +289,7 @@ public static partial class StringExtensions
|
||||
{
|
||||
char[] chars = target.ToCharArray();
|
||||
int index = chars.IndexOf(char.IsLetter);
|
||||
|
||||
chars[index] = char.ToLower(chars[index]);
|
||||
return new string(chars);
|
||||
}
|
||||
|
||||
@@ -29,7 +29,7 @@ public class TelegratorClient : TelegramBotClient, ITelegratorBot, ICollectingPr
|
||||
public ITelegramBotInfo BotInfo { get; private set; }
|
||||
|
||||
/// <inheritdoc/>
|
||||
public IUpdateRouter UpdateRouter { get => updateRouter ?? throw new Exception(); }
|
||||
public IUpdateRouter UpdateRouter => updateRouter ?? throw new InvalidOperationException("Router's not created yet. Invoke `StartReceiving` to initialize this property.");
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="TelegratorClient"/> class with a bot token.
|
||||
@@ -68,11 +68,11 @@ public class TelegratorClient : TelegramBotClient, ITelegratorBot, ICollectingPr
|
||||
/// Initializes the update router and begins polling for updates.
|
||||
/// </summary>
|
||||
/// <param name="receiverOptions">Optional receiver options for configuring update polling.</param>
|
||||
/// <param name="cancellationToken">The cancellation token to stop receiving updates.</param>
|
||||
public void StartReceiving(ReceiverOptions? receiverOptions = null, CancellationToken cancellationToken = default)
|
||||
/// <param name="globalCancellationToken">The cancellation token to stop receiving updates.</param>
|
||||
public void StartReceiving(ReceiverOptions? receiverOptions = null, CancellationToken globalCancellationToken = default)
|
||||
{
|
||||
if (Options.GlobalCancellationToken == CancellationToken.None)
|
||||
Options.GlobalCancellationToken = cancellationToken;
|
||||
Options.GlobalCancellationToken = globalCancellationToken;
|
||||
|
||||
HandlersProvider handlerProvider = new HandlersProvider(Handlers, Options);
|
||||
AwaitingProvider awaitingProvider = new AwaitingProvider(Options);
|
||||
@@ -82,8 +82,7 @@ public class TelegratorClient : TelegramBotClient, ITelegratorBot, ICollectingPr
|
||||
|
||||
// Log startup
|
||||
TelegratorLogging.LogInformation($"Telegrator bot starting up - BotId: {BotInfo.User.Id}, Username: {BotInfo.User.Username}, MaxParallelHandlers: {Options.MaximumParallelWorkingHandlers ?? -1}");
|
||||
|
||||
StartReceivingInternal(receiverOptions, cancellationToken);
|
||||
StartReceivingInternal(receiverOptions, globalCancellationToken);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -115,6 +114,4 @@ public class TelegratorClient : TelegramBotClient, ITelegratorBot, ICollectingPr
|
||||
TelegratorLogging.LogInformation("Telegrator bot stopped (cancelled)");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -412,6 +412,26 @@ public static partial class HandlersCollectionExtensions
|
||||
"Ocelot", "BouncyCastle", "IdentityModel", "Telegrator"
|
||||
];
|
||||
|
||||
/// <summary>
|
||||
/// Collects all handlers from current app domain.
|
||||
/// Scans for handlers exported by analyzer into class `Telegrator.Analyzers.AnalyzerExport` in each assembly and registers them to the collection.
|
||||
/// </summary>
|
||||
/// <param name="handlers"></param>
|
||||
/// <returns></returns>
|
||||
public static IHandlersCollection CollectHandlers(this IHandlersCollection handlers)
|
||||
{
|
||||
const string exportClassName = "Telegrator.Analyzers.AnalyzerExport";
|
||||
AppDomain.CurrentDomain.GetAssemblies()
|
||||
.Select(ass => ass.GetType(exportClassName))
|
||||
.Squeeze()
|
||||
.SelectMany(t => t.GetFields())
|
||||
.Select(f => f.GetValue(null) as Type)
|
||||
.Squeeze()
|
||||
.ForEach(v => handlers.AddHandler(v));
|
||||
|
||||
return handlers;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Collects all public handlers from the current app domain.
|
||||
/// Scans for types that implement handlers and adds them to the collection.
|
||||
@@ -438,7 +458,7 @@ public static partial class HandlersCollectionExtensions
|
||||
{
|
||||
(collectingTarget ?? Assembly.GetCallingAssembly())
|
||||
.GetExportedTypes()
|
||||
.Where(type => type.GetCustomAttribute<DontCollectAttribute>() == null && type.IsHandlerRealization())
|
||||
.Where(type => type.GetCustomAttribute<DontCollectAttribute>() == null && type.IsHandlerImplementation())
|
||||
.ForEach(type => handlers.AddHandler(type));
|
||||
|
||||
return handlers;
|
||||
@@ -496,7 +516,7 @@ public static partial class HandlersCollectionExtensions
|
||||
/// <exception cref="Exception">Thrown when the type is not a valid handler implementation.</exception>
|
||||
public static IHandlersCollection AddHandler(this IHandlersCollection handlers, Type handlerType)
|
||||
{
|
||||
if (!handlerType.IsHandlerRealization())
|
||||
if (!handlerType.IsHandlerImplementation())
|
||||
throw new Exception();
|
||||
|
||||
if (handlerType.IsCustomDescriptorsProvider())
|
||||
|
||||
Reference in New Issue
Block a user