From 12e2b93ac9fed151beb14edecbc3f0c70500f479 Mon Sep 17 00:00:00 2001 From: Andrew Camilleri Date: Mon, 22 Jun 2020 09:32:51 +0200 Subject: [PATCH] Add invoice notifications (#1674) * Add invoice notifications * fixeth le order * comment-to-code auto commit * reduce notifications --- BTCPayServer/HostedServices/InvoiceWatcher.cs | 15 ++++- BTCPayServer/Hosting/BTCPayServerServices.cs | 1 + .../Blobs/InvoiceEventNotification.cs | 65 +++++++++++++++++++ .../NotificationsNavItem.cshtml | 2 +- 4 files changed, 80 insertions(+), 3 deletions(-) create mode 100644 BTCPayServer/Services/Notifications/Blobs/InvoiceEventNotification.cs diff --git a/BTCPayServer/HostedServices/InvoiceWatcher.cs b/BTCPayServer/HostedServices/InvoiceWatcher.cs index 105daf63e..e37593c6c 100644 --- a/BTCPayServer/HostedServices/InvoiceWatcher.cs +++ b/BTCPayServer/HostedServices/InvoiceWatcher.cs @@ -12,6 +12,9 @@ using System.Collections.Concurrent; using BTCPayServer.Events; using BTCPayServer.Services.Invoices; using System.Threading.Channels; +using BTCPayServer.Services.Notifications; +using BTCPayServer.Services.Notifications.Blobs; +using NBitpayClient; namespace BTCPayServer.HostedServices { @@ -38,15 +41,18 @@ namespace BTCPayServer.HostedServices InvoiceRepository _InvoiceRepository; EventAggregator _EventAggregator; ExplorerClientProvider _ExplorerClientProvider; + private readonly NotificationSender _notificationSender; public InvoiceWatcher( InvoiceRepository invoiceRepository, EventAggregator eventAggregator, - ExplorerClientProvider explorerClientProvider) + ExplorerClientProvider explorerClientProvider, + NotificationSender notificationSender) { _InvoiceRepository = invoiceRepository ?? throw new ArgumentNullException(nameof(invoiceRepository)); _EventAggregator = eventAggregator ?? throw new ArgumentNullException(nameof(eventAggregator)); _ExplorerClientProvider = explorerClientProvider; + _notificationSender = notificationSender; } CompositeDisposable leases = new CompositeDisposable(); @@ -228,8 +234,13 @@ namespace BTCPayServer.HostedServices { Watch(b.InvoiceId); })); - leases.Add(_EventAggregator.Subscribe(b => + leases.Add(_EventAggregator.Subscribe(async b => { + if (InvoiceEventNotification.HandlesEvent(b.Name)) + { + await _notificationSender.SendNotification(new StoreScope(b.Invoice.StoreId), + new InvoiceEventNotification(b.Invoice.Id, b.Name)); + } if (b.Name == InvoiceEvent.Created) { Watch(b.Invoice.Id); diff --git a/BTCPayServer/Hosting/BTCPayServerServices.cs b/BTCPayServer/Hosting/BTCPayServerServices.cs index 892395f16..2e4a05c61 100644 --- a/BTCPayServer/Hosting/BTCPayServerServices.cs +++ b/BTCPayServer/Hosting/BTCPayServerServices.cs @@ -222,6 +222,7 @@ namespace BTCPayServer.Hosting services.AddScoped(); services.AddScoped(); services.AddSingleton(); + services.AddSingleton(); services.TryAddSingleton(); services.TryAddSingleton(o => diff --git a/BTCPayServer/Services/Notifications/Blobs/InvoiceEventNotification.cs b/BTCPayServer/Services/Notifications/Blobs/InvoiceEventNotification.cs new file mode 100644 index 000000000..648b37e9b --- /dev/null +++ b/BTCPayServer/Services/Notifications/Blobs/InvoiceEventNotification.cs @@ -0,0 +1,65 @@ +using System.Collections.Generic; +using System.Linq; +using BTCPayServer.Configuration; +using BTCPayServer.Controllers; +using BTCPayServer.Events; +using BTCPayServer.Models.NotificationViewModels; +using Microsoft.AspNetCore.Routing; + +namespace BTCPayServer.Services.Notifications.Blobs +{ + internal class InvoiceEventNotification + { + internal class Handler : NotificationHandler + { + private readonly LinkGenerator _linkGenerator; + private readonly BTCPayServerOptions _options; + + public Handler(LinkGenerator linkGenerator, BTCPayServerOptions options) + { + _linkGenerator = linkGenerator; + _options = options; + } + + public override string NotificationType => "invoicestate"; + + internal static Dictionary TextMapping = new Dictionary() + { + // {InvoiceEvent.PaidInFull, "was fully paid."}, + {InvoiceEvent.PaidAfterExpiration, "was paid after expiration."}, + {InvoiceEvent.ExpiredPaidPartial, "expired with partial payments."}, + {InvoiceEvent.FailedToConfirm, "has payments that failed to confirm on time."}, + // {InvoiceEvent.ReceivedPayment, "received a payment."}, + {InvoiceEvent.Confirmed, "was confirmed paid."} + }; + + protected override void FillViewModel(InvoiceEventNotification notification, + NotificationViewModel vm) + { + var baseStr = $"Invoice {notification.InvoiceId.Substring(0, 5)}.."; + vm.Body = $"{baseStr} {TextMapping[notification.Event]}"; + vm.ActionLink = _linkGenerator.GetPathByAction(nameof(InvoiceController.Invoice), + "Invoice", + new {invoiceId = notification.InvoiceId}, _options.RootPath); + } + } + + public InvoiceEventNotification() + { + } + + public InvoiceEventNotification(string invoiceId, string invoiceEvent) + { + InvoiceId = invoiceId; + Event = invoiceEvent; + } + + public static bool HandlesEvent(string invoiceEvent) + { + return Handler.TextMapping.Keys.Any(s => s == invoiceEvent); + } + + public string InvoiceId { get; set; } + public string Event { get; set; } + } +} diff --git a/BTCPayServer/Views/Shared/LayoutPartials/NotificationsNavItem.cshtml b/BTCPayServer/Views/Shared/LayoutPartials/NotificationsNavItem.cshtml index a563fb255..a479f9cea 100644 --- a/BTCPayServer/Views/Shared/LayoutPartials/NotificationsNavItem.cshtml +++ b/BTCPayServer/Views/Shared/LayoutPartials/NotificationsNavItem.cshtml @@ -19,7 +19,7 @@ @notif.Body
- @notif.Created.ToBrowserDate() + @notif.Created.ToTimeAgo()
}