mirror of
https://github.com/aljazceru/btcpayserver.git
synced 2025-12-18 22:44:29 +01:00
Pluginize Webhooks and support Payouts (#5421)
Co-authored-by: d11n <mail@dennisreimann.de>
This commit is contained in:
@@ -1,20 +1,14 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using BTCPayServer.Client.Models;
|
||||
using BTCPayServer.Controllers;
|
||||
using BTCPayServer.Controllers.Greenfield;
|
||||
using BTCPayServer.Data;
|
||||
using BTCPayServer.Events;
|
||||
using BTCPayServer.Services;
|
||||
using BTCPayServer.Services.Invoices;
|
||||
using BTCPayServer.HostedServices.Webhooks;
|
||||
using BTCPayServer.Services.Mails;
|
||||
using BTCPayServer.Services.Rates;
|
||||
using BTCPayServer.Services.Stores;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using InvoiceData = BTCPayServer.Client.Models.InvoiceData;
|
||||
|
||||
namespace BTCPayServer.HostedServices;
|
||||
|
||||
@@ -22,82 +16,75 @@ public class StoreEmailRuleProcessorSender : EventHostedServiceBase
|
||||
{
|
||||
private readonly StoreRepository _storeRepository;
|
||||
private readonly EmailSenderFactory _emailSenderFactory;
|
||||
private readonly LinkGenerator _linkGenerator;
|
||||
private readonly CurrencyNameTable _currencyNameTable;
|
||||
|
||||
public StoreEmailRuleProcessorSender(StoreRepository storeRepository, EventAggregator eventAggregator,
|
||||
ILogger<InvoiceEventSaverService> logger,
|
||||
EmailSenderFactory emailSenderFactory,
|
||||
LinkGenerator linkGenerator,
|
||||
CurrencyNameTable currencyNameTable) : base(
|
||||
EmailSenderFactory emailSenderFactory) : base(
|
||||
eventAggregator, logger)
|
||||
{
|
||||
_storeRepository = storeRepository;
|
||||
_emailSenderFactory = emailSenderFactory;
|
||||
_linkGenerator = linkGenerator;
|
||||
_currencyNameTable = currencyNameTable;
|
||||
}
|
||||
|
||||
protected override void SubscribeToEvents()
|
||||
{
|
||||
Subscribe<InvoiceEvent>();
|
||||
Subscribe<WebhookSender.WebhookDeliveryRequest>();
|
||||
}
|
||||
|
||||
protected override async Task ProcessEvent(object evt, CancellationToken cancellationToken)
|
||||
{
|
||||
if (evt is InvoiceEvent invoiceEvent)
|
||||
if (evt is WebhookSender.WebhookDeliveryRequest webhookDeliveryRequest)
|
||||
{
|
||||
var type = WebhookSender.GetWebhookEvent(invoiceEvent);
|
||||
var type = webhookDeliveryRequest.WebhookEvent.Type;
|
||||
if (type is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var store = await _storeRepository.FindStore(invoiceEvent.Invoice.StoreId);
|
||||
|
||||
if (webhookDeliveryRequest.WebhookEvent is not StoreWebhookEvent storeWebhookEvent || storeWebhookEvent.StoreId is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
var store = await _storeRepository.FindStore(storeWebhookEvent.StoreId);
|
||||
if (store is null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var blob = store.GetStoreBlob();
|
||||
if (blob.EmailRules?.Any() is true)
|
||||
{
|
||||
var actionableRules = blob.EmailRules.Where(rule => rule.Trigger == type.Type).ToList();
|
||||
var actionableRules = blob.EmailRules.Where(rule => rule.Trigger == type).ToList();
|
||||
if (actionableRules.Any())
|
||||
{
|
||||
var sender = await _emailSenderFactory.GetEmailSender(invoiceEvent.Invoice.StoreId);
|
||||
var sender = await _emailSenderFactory.GetEmailSender(storeWebhookEvent.StoreId);
|
||||
foreach (UIStoresController.StoreEmailRule actionableRule in actionableRules)
|
||||
{
|
||||
var recipients = (actionableRule.To?.Split(",", StringSplitOptions.RemoveEmptyEntries) ?? Array.Empty<string>())
|
||||
|
||||
|
||||
var request = new SendEmailRequest()
|
||||
{
|
||||
Subject = actionableRule.Subject, Body = actionableRule.Body, Email = actionableRule.To
|
||||
};
|
||||
request = await webhookDeliveryRequest.Interpolate(request, actionableRule);
|
||||
|
||||
|
||||
var recipients = (request?.Email?.Split(",", StringSplitOptions.RemoveEmptyEntries) ?? Array.Empty<string>())
|
||||
.Select(o =>
|
||||
{
|
||||
MailboxAddressValidator.TryParse(o, out var mb);
|
||||
return mb;
|
||||
})
|
||||
.Where(o => o != null)
|
||||
.ToList();
|
||||
if (actionableRule.CustomerEmail &&
|
||||
MailboxAddressValidator.TryParse(invoiceEvent.Invoice.Metadata.BuyerEmail, out var bmb))
|
||||
{
|
||||
recipients.Add(bmb);
|
||||
}
|
||||
var i = GreenfieldInvoiceController.ToModel(invoiceEvent.Invoice, _linkGenerator, null);
|
||||
sender.SendEmail(recipients.ToArray(), null, null, Interpolator(actionableRule.Subject, i),
|
||||
Interpolator(actionableRule.Body, i));
|
||||
.ToArray();
|
||||
|
||||
if(recipients.Length == 0)
|
||||
continue;
|
||||
|
||||
sender.SendEmail(recipients.ToArray(), null, null, request.Subject, request.Body);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private string Interpolator(string str, InvoiceData i)
|
||||
{
|
||||
//TODO: we should switch to https://dotnetfiddle.net/MoqJFk later
|
||||
return str.Replace("{Invoice.Id}", i.Id)
|
||||
.Replace("{Invoice.StoreId}", i.StoreId)
|
||||
.Replace("{Invoice.Price}",
|
||||
decimal.Round(i.Amount, _currencyNameTable.GetCurrencyData(i.Currency, true).Divisibility,
|
||||
MidpointRounding.ToEven).ToString(CultureInfo.InvariantCulture))
|
||||
.Replace("{Invoice.Currency}", i.Currency)
|
||||
.Replace("{Invoice.Status}", i.Status.ToString())
|
||||
.Replace("{Invoice.AdditionalStatus}", i.AdditionalStatus.ToString())
|
||||
.Replace("{Invoice.OrderId}", i.Metadata.ToObject<InvoiceMetadata>().OrderId);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user