diff --git a/BTCPayServer/Controllers/GreenField/GreenfieldInvoiceController.cs b/BTCPayServer/Controllers/GreenField/GreenfieldInvoiceController.cs index d1fea5093..119c3ef74 100644 --- a/BTCPayServer/Controllers/GreenField/GreenfieldInvoiceController.cs +++ b/BTCPayServer/Controllers/GreenField/GreenfieldInvoiceController.cs @@ -12,6 +12,7 @@ using BTCPayServer.Services; using BTCPayServer.Services.Invoices; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Cors; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Routing; using NBitcoin; @@ -389,7 +390,13 @@ namespace BTCPayServer.Controllers.Greenfield ReceivedDate = paymentEntity.ReceivedTime.DateTime }; } + private InvoiceData ToModel(InvoiceEntity entity) + { + return ToModel(entity, _linkGenerator, Request); + } + + public static InvoiceData ToModel(InvoiceEntity entity, LinkGenerator linkGenerator, HttpRequest? request) { var statuses = new List(); var state = entity.GetInvoiceState(); @@ -411,7 +418,7 @@ namespace BTCPayServer.Controllers.Greenfield Amount = entity.Price, Type = entity.Type, Id = entity.Id, - CheckoutLink = _linkGenerator.CheckoutLink(entity.Id, Request.Scheme, Request.Host, Request.PathBase), + CheckoutLink = request is null? null: linkGenerator.CheckoutLink(entity.Id, request.Scheme, request.Host, request.PathBase), Status = entity.Status.ToModernStatus(), AdditionalStatus = entity.ExceptionStatus, Currency = entity.Currency, diff --git a/BTCPayServer/HostedServices/StoreEmailRuleProcessorSender.cs b/BTCPayServer/HostedServices/StoreEmailRuleProcessorSender.cs index 82cb2d1ef..e0ac040e1 100644 --- a/BTCPayServer/HostedServices/StoreEmailRuleProcessorSender.cs +++ b/BTCPayServer/HostedServices/StoreEmailRuleProcessorSender.cs @@ -1,14 +1,18 @@ using System; +using System.Globalization; using System.Linq; using System.Threading; using System.Threading.Tasks; using BTCPayServer.Controllers; using BTCPayServer.Data; +using BTCPayServer.Controllers.Greenfield; using BTCPayServer.Events; +using BTCPayServer.Services; using BTCPayServer.Services.Mails; using BTCPayServer.Services.Stores; +using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.Logging; -using MimeKit; +using InvoiceData = BTCPayServer.Client.Models.InvoiceData; namespace BTCPayServer.HostedServices; @@ -16,14 +20,19 @@ public class StoreEmailRuleProcessorSender : EventHostedServiceBase { private readonly StoreRepository _storeRepository; private readonly EmailSenderFactory _emailSenderFactory; + private readonly LinkGenerator _linkGenerator; + private readonly BTCPayServerEnvironment _environment; public StoreEmailRuleProcessorSender(StoreRepository storeRepository, EventAggregator eventAggregator, ILogger logger, - EmailSenderFactory emailSenderFactory) : base( + EmailSenderFactory emailSenderFactory, + LinkGenerator linkGenerator, BTCPayServerEnvironment environment) : base( eventAggregator, logger) { _storeRepository = storeRepository; _emailSenderFactory = emailSenderFactory; + _linkGenerator = linkGenerator; + _environment = environment; } protected override void SubscribeToEvents() @@ -54,17 +63,35 @@ public class StoreEmailRuleProcessorSender : EventHostedServiceBase foreach (UIStoresController.StoreEmailRule actionableRule in actionableRules) { var recipients = (actionableRule.To?.Split(",", StringSplitOptions.RemoveEmptyEntries)??Array.Empty()) - .Select(o => { MailboxAddressValidator.TryParse(o, out var mb); return mb; }) + .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)) + if (actionableRule.CustomerEmail && + MailboxAddressValidator.TryParse(invoiceEvent.Invoice.Metadata.BuyerEmail, out var bmb)) { recipients.Add(bmb); } - sender.SendEmail(recipients.ToArray(), null, null, actionableRule.Subject, actionableRule.Body); + var i = GreenfieldInvoiceController.ToModel(invoiceEvent.Invoice, _linkGenerator, null); + sender.SendEmail(recipients.ToArray(), null, null, Interpolator(actionableRule.Subject, i), + Interpolator(actionableRule.Body, i)); } } } } } + + 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}", i.Amount.ToString(CultureInfo.InvariantCulture)) + .Replace("{Invoice.Currency}", i.Currency) + .Replace("{Invoice.Status}", i.Status.ToString()) + .Replace("{Invoice.AdditionalStatus}", i.AdditionalStatus.ToString()); + } } diff --git a/BTCPayServer/Views/UIStores/StoreEmails.cshtml b/BTCPayServer/Views/UIStores/StoreEmails.cshtml index d5337a3e2..aac1fd76e 100644 --- a/BTCPayServer/Views/UIStores/StoreEmails.cshtml +++ b/BTCPayServer/Views/UIStores/StoreEmails.cshtml @@ -74,7 +74,6 @@ } - @section PageFootContent { } diff --git a/BTCPayServer/wwwroot/main/site.js b/BTCPayServer/wwwroot/main/site.js index bd47aa77c..92dd58ee5 100644 --- a/BTCPayServer/wwwroot/main/site.js +++ b/BTCPayServer/wwwroot/main/site.js @@ -58,7 +58,6 @@ document.addEventListener("DOMContentLoaded", function () { })); } }); - // rich text editor if ($.summernote) { $('.richtext').summernote({