Initial webhook support

This commit is contained in:
2024-01-28 18:51:18 +03:00
parent aaf27a9a06
commit 1088037e58
4 changed files with 125 additions and 2 deletions
+75
View File
@@ -0,0 +1,75 @@
using BotFramework.Abstractions.UpdateProvider;
using BotFramework.Config;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Newtonsoft.Json;
using System.Threading.Tasks;
using Telegram.Bot;
using Telegram.Bot.Types;
namespace Kruzya.TelegramBot.Core.Controllers
{
[Route("/Telegram")]
public class Telegram : Controller
{
private const string SecretTokenHeader = "X-Telegram-Bot-Api-Secret-Token";
private readonly ILogger<Telegram> _logger;
private readonly ITelegramBotClient _client;
private readonly IUpdateTarget _updateTarget;
private readonly string _secretToken;
public Telegram(ILogger<Telegram> logger, ITelegramBotClient client, IUpdateTarget updateTarget, IOptions<BotConfig> config)
{
_logger = logger;
_client = client;
_updateTarget = updateTarget;
_secretToken = config.Value.Webhook.SecretToken;
if (string.IsNullOrEmpty(_secretToken))
{
_secretToken = null;
}
}
[Route("/WebHook")]
[HttpPost]
public IActionResult Index()
{
if (_secretToken != null && !Request.Headers.ContainsKey(SecretTokenHeader))
{
_logger.LogWarning("Someone tried push update without secret key in headers");
return BadRequest();
}
var ok = (_secretToken == null || Request.Headers[SecretTokenHeader] == _secretToken);
if (!ok)
{
_logger.LogWarning("Someone tried push update with wrong secret key in headers");
return BadRequest();
}
LaunchHandle();
return Ok();
}
private void LaunchHandle()
{
try
{
var update = JsonConvert.DeserializeObject<Update>(Request.Body.ToString());
if (update == null)
{
throw new System.Exception("Invalid request body");
}
_updateTarget.Push(update);
}
catch (System.Exception e)
{
_logger.LogError($"Error occured when handling a new update: {e}");
}
}
}
}
+1 -1
View File
@@ -8,7 +8,7 @@
<PropertyGroup Condition=" '$(RunConfiguration)' == 'Core' " />
<ItemGroup>
<PackageReference Include="AleXr64.BotFramework" Version="2.0.7-g4bee468724" />
<PackageReference Include="AleXr64.BotFramework" Version="2.0.8-gf720999661" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="7.0.1">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
+9 -1
View File
@@ -13,6 +13,7 @@ using Microsoft.Extensions.Logging;
using System.Collections.Concurrent;
using Kruzya.TelegramBot.Core.Options;
using Telegram.Bot.Types;
using BotFramework.Abstractions.UpdateProvider;
namespace Kruzya.TelegramBot.Core;
@@ -49,7 +50,8 @@ public class Startup
services.AddSingleton<IAntiFlood, MemoryAntiFloodService>();
services.AddSingleton<ThreadSafeRandom>();
services.AddSingleton<IWebhookProvider, WebhookAspNetProvider>();
services.AddControllersWithViews();
services.AddSingleton<ConcurrentBag<DeleteRequest>>();
services.AddHostedService<DeleteService>();
@@ -64,6 +66,12 @@ public class Startup
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseRouting();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
_core.Modules.Configure(app, env);
}
}
+40
View File
@@ -0,0 +1,40 @@
#nullable enable
using BotFramework.Abstractions.UpdateProvider;
using BotFramework.Config;
using Microsoft.Extensions.Options;
using System.Threading;
using System.Threading.Tasks;
using Telegram.Bot;
namespace Kruzya.TelegramBot.Core
{
public class WebhookAspNetProvider : IWebhookProvider
{
private readonly ITelegramBotClient _client;
private readonly BotConfig _config;
private readonly string? _secretToken;
public WebhookAspNetProvider(ITelegramBotClient client, IOptions<BotConfig> config)
{
_client = client;
_config = config.Value;
_secretToken = _config.Webhook.SecretToken;
if (string.IsNullOrWhiteSpace(_secretToken))
{
_secretToken = null;
}
}
public async Task StartAsync(CancellationToken token)
{
await _client.SetWebhookAsync(_config.Webhook.Url, secretToken: _secretToken, cancellationToken: token);
}
public async Task StopAsync(CancellationToken token)
{
await _client.DeleteWebhookAsync(cancellationToken: token);
}
}
}