mirror of
https://github.com/aljazceru/btcpayserver.git
synced 2025-12-18 06:24:24 +01:00
Refactoring of Webhooks and Email Rules (#6954)
This commit is contained in:
@@ -0,0 +1,76 @@
|
||||
#nullable enable
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
using BTCPayServer.Data;
|
||||
using BTCPayServer.HostedServices;
|
||||
using BTCPayServer.Plugins.Emails;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using StoreData = BTCPayServer.Data.StoreData;
|
||||
|
||||
namespace BTCPayServer.Plugins.Webhooks.HostedServices;
|
||||
|
||||
/// <summary>
|
||||
/// This class listen to <typeparamref name="T"/> events and create webhook notifications and trigger event from it.
|
||||
/// </summary>
|
||||
public class WebhookProviderHostedService(
|
||||
EventAggregator eventAggregator,
|
||||
ApplicationDbContextFactory dbContextFactory,
|
||||
IEnumerable<WebhookTriggerProvider> webhookTriggerProviders,
|
||||
WebhookSender webhookSender,
|
||||
ILogger<WebhookProviderHostedService> logger)
|
||||
: EventHostedServiceBase(eventAggregator, logger)
|
||||
{
|
||||
class WebhookTriggerOwner(WebhookTriggerProvider provider, WebhookTriggerContext ctx) : ITriggerOwner
|
||||
{
|
||||
public Task BeforeSending(EmailRuleMatchContext context)
|
||||
=> provider.BeforeSending(context, ctx);
|
||||
}
|
||||
|
||||
protected override void SubscribeToEvents()
|
||||
{
|
||||
SubscribeAny<object>();
|
||||
}
|
||||
|
||||
protected override async Task ProcessEvent(object evt, CancellationToken cancellationToken)
|
||||
{
|
||||
var (provider, webhookEvent) = webhookTriggerProviders
|
||||
.Select(o => (o, o.GetWebhookEvent(evt)))
|
||||
.FirstOrDefault(o => o.Item2 is not null);
|
||||
if (webhookEvent is null || provider is null)
|
||||
return;
|
||||
|
||||
var webhooks = await webhookSender.GetWebhooks(webhookEvent.StoreId, webhookEvent.Type);
|
||||
foreach (var webhook in webhooks)
|
||||
{
|
||||
var ev = Clone(webhookEvent);
|
||||
ev.WebhookId = webhook.Id;
|
||||
var delivery = Data.WebhookDeliveryData.Create(webhook.Id);
|
||||
ev.DeliveryId = delivery.Id;
|
||||
ev.OriginalDeliveryId = delivery.Id;
|
||||
ev.Timestamp = delivery.Timestamp;
|
||||
ev.IsRedelivery = false;
|
||||
webhookSender.EnqueueDelivery(new(webhook.Id, ev, delivery, webhook.GetBlob()));
|
||||
}
|
||||
|
||||
if (await GetStore(webhookEvent) is {} store)
|
||||
{
|
||||
var ctx = provider.CreateWebhookTriggerContext(store, evt, webhookEvent);
|
||||
var triggerEvent = new TriggerEvent(webhookEvent.StoreId, EmailRuleData.GetWebhookTriggerName(webhookEvent.Type),
|
||||
await provider.GetEmailModel(ctx), new WebhookTriggerOwner(provider, ctx));
|
||||
EventAggregator.Publish(triggerEvent);
|
||||
}
|
||||
}
|
||||
|
||||
private StoreWebhookEvent Clone(StoreWebhookEvent webhookEvent)
|
||||
=> (StoreWebhookEvent)JsonConvert.DeserializeObject(JsonConvert.SerializeObject(webhookEvent), webhookEvent.GetType(), WebhookSender.DefaultSerializerSettings)!;
|
||||
|
||||
private async Task<StoreData?> GetStore(StoreWebhookEvent webhookEvent)
|
||||
{
|
||||
await using var ctx = dbContextFactory.CreateContext();
|
||||
return await ctx.Stores.FindAsync(webhookEvent.StoreId);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user