From a017c8f54fd1cbed65d2b8c7669c7501445b5054 Mon Sep 17 00:00:00 2001 From: Roei Erez Date: Mon, 15 Jan 2024 17:19:20 +0200 Subject: [PATCH 1/3] Add app_data to the webhook query params --- breezsdk/init.go | 3 +++ http/router.go | 11 ++++++++--- http/router_test.go | 6 +++++- notify/notify.go | 1 + 4 files changed, 17 insertions(+), 4 deletions(-) diff --git a/breezsdk/init.go b/breezsdk/init.go index 38b3cf0..e351042 100644 --- a/breezsdk/init.go +++ b/breezsdk/init.go @@ -34,6 +34,9 @@ func createMessageFactory() services.FCMMessageBuilder { func createPush(notification *notify.Notification) (*messaging.Message, error) { data := notification.Data data["notification_type"] = notification.Template + if notification.AppData != nil { + data["app_data"] = *notification.AppData + } return &messaging.Message{ Token: notification.TargetIdentifier, Data: data, diff --git a/http/router.go b/http/router.go index eddbd9f..d8b039f 100644 --- a/http/router.go +++ b/http/router.go @@ -14,8 +14,9 @@ import ( ) type MobilePushWebHookQuery struct { - Platform string `form:"platform" binding:"required,oneof=ios android"` - Token string `form:"token" binding:"required"` + Platform string `form:"platform" binding:"required,oneof=ios android"` + Token string `form:"token" binding:"required"` + AppData *string `form:"app_data"` } type NotificationConvertible interface { @@ -37,6 +38,7 @@ func (p *WebhookCallbackMessagePayload) ToNotification(query *MobilePushWebHookQ DisplayMessage: p.GenerateDisplayMessage(), Type: query.Platform, TargetIdentifier: query.Token, + AppData: query.AppData, Data: map[string]string{ "callback_url": p.Data.CallbackURL, "message_payload": p.Data.MessagePayload, @@ -46,7 +48,7 @@ func (p *WebhookCallbackMessagePayload) ToNotification(query *MobilePushWebHookQ func (p *WebhookCallbackMessagePayload) GenerateDisplayMessage() string { switch p.MessageType { - case "lnulrpay_info": + case "lnurlpay_info": return "Receiving payment" case "lnurlpay_invoice": return "Invoice requested" @@ -67,6 +69,7 @@ func (p *PaymentReceivedPayload) ToNotification(query *MobilePushWebHookQuery) * DisplayMessage: "Incoming payment", Type: query.Platform, TargetIdentifier: query.Token, + AppData: query.AppData, Data: map[string]string{"payment_hash": p.Data.PaymentHash}, } } @@ -84,6 +87,7 @@ func (p *TxConfirmedPayload) ToNotification(query *MobilePushWebHookQuery) *noti DisplayMessage: "Transaction confirmed", Type: query.Platform, TargetIdentifier: query.Token, + AppData: query.AppData, Data: map[string]string{"tx_id": p.Data.TxID}, } } @@ -101,6 +105,7 @@ func (p *AddressTxsChangedPayload) ToNotification(query *MobilePushWebHookQuery) DisplayMessage: "Address transactions changed", Type: query.Platform, TargetIdentifier: query.Token, + AppData: query.AppData, Data: map[string]string{"address": p.Data.Address}, } } diff --git a/http/router_test.go b/http/router_test.go index 660e9ff..86dbbc7 100644 --- a/http/router_test.go +++ b/http/router_test.go @@ -14,10 +14,13 @@ import ( ) func TestPaymentReceivedHook(t *testing.T) { + testAppData := "testdata" query := MobilePushWebHookQuery{ Platform: "android", Token: "1234", + AppData: &testAppData, } + paymentReceivedPayload := PaymentReceivedPayload{ Template: notify.NOTIFICATION_PAYMENT_RECEIVED, Data: struct { @@ -26,12 +29,13 @@ func TestPaymentReceivedHook(t *testing.T) { PaymentHash: "1234", }, } + body, err := json.Marshal(paymentReceivedPayload) if err != nil { t.Fatalf("failed to marshal notification %v", err) } expected := paymentReceivedPayload.ToNotification(&query) - testValidNotification(t, "/api/v1/notify?platform=android&token=1234", body, expected) + testValidNotification(t, "/api/v1/notify?platform=android&token=1234&app_data=testdata", body, expected) } func TestTxConfirmedHook(t *testing.T) { diff --git a/notify/notify.go b/notify/notify.go index 399ce15..4ff225f 100644 --- a/notify/notify.go +++ b/notify/notify.go @@ -25,6 +25,7 @@ type Notification struct { DisplayMessage string Type string TargetIdentifier string + AppData *string Data map[string]string } From b38cb79ecf2e91dc5e673846e676523c87fefb06 Mon Sep 17 00:00:00 2001 From: Roei Erez Date: Tue, 16 Jan 2024 12:35:34 +0200 Subject: [PATCH 2/3] simplify notification payload structure --- breezsdk/init.go | 15 +++++++++++++-- http/router.go | 47 +++++++++++++++++++++++++++++------------------ notify/notify.go | 3 ++- 3 files changed, 44 insertions(+), 21 deletions(-) diff --git a/breezsdk/init.go b/breezsdk/init.go index e351042..f953efa 100644 --- a/breezsdk/init.go +++ b/breezsdk/init.go @@ -1,6 +1,9 @@ package breezsdk import ( + "encoding/json" + "fmt" + "firebase.google.com/go/messaging" "github.com/breez/notify/config" "github.com/breez/notify/notify" @@ -22,7 +25,8 @@ func createMessageFactory() services.FCMMessageBuilder { case notify.NOTIFICATION_PAYMENT_RECEIVED, notify.NOTIFICATION_TX_CONFIRMED, notify.NOTIFICATION_ADDRESS_TXS_CHANGED, - notify.NOTIFICATION_WEBHOOK_CALLBACK: + notify.NOTIFICATION_LNURLPAY_INFO, + notify.NOTIFICATION_LNURLPAY_INVOICE: return createPush(notification) } @@ -32,11 +36,18 @@ func createMessageFactory() services.FCMMessageBuilder { } func createPush(notification *notify.Notification) (*messaging.Message, error) { - data := notification.Data + data := make(map[string]string) + data["notification_type"] = notification.Template if notification.AppData != nil { data["app_data"] = *notification.AppData } + payload, err := json.Marshal(notification.Data) + if err != nil { + return nil, fmt.Errorf("failed to marshal notification data %v", err) + } + data["notification_payload"] = string(payload) + return &messaging.Message{ Token: notification.TargetIdentifier, Data: data, diff --git a/http/router.go b/http/router.go index d8b039f..da3eb99 100644 --- a/http/router.go +++ b/http/router.go @@ -23,37 +23,48 @@ type NotificationConvertible interface { ToNotification(query *MobilePushWebHookQuery) *notify.Notification } -type WebhookCallbackMessagePayload struct { - Template string `json:"template" binding:"required,eq=webhook_callback_message"` - MessageType string `json:"message_type" binding:"required"` - Data struct { - CallbackURL string `json:"callback_url" binding:"required"` - MessagePayload string `json:"message_payload"` +type LnurlPayInfoPayload struct { + Template string `json:"template" binding:"required,eq=lnurlpay_info"` + Data struct { + CallbackURL string `json:"callback_url" binding:"required"` + ReplyURL string `json:"reply_url" binding:"required"` } `json:"data"` } -func (p *WebhookCallbackMessagePayload) ToNotification(query *MobilePushWebHookQuery) *notify.Notification { +func (p *LnurlPayInfoPayload) ToNotification(query *MobilePushWebHookQuery) *notify.Notification { return ¬ify.Notification{ Template: p.Template, - DisplayMessage: p.GenerateDisplayMessage(), + DisplayMessage: "Receiving payment", Type: query.Platform, TargetIdentifier: query.Token, AppData: query.AppData, Data: map[string]string{ - "callback_url": p.Data.CallbackURL, - "message_payload": p.Data.MessagePayload, + "callback_url": p.Data.CallbackURL, + "reply_url": p.Data.ReplyURL, }, } } -func (p *WebhookCallbackMessagePayload) GenerateDisplayMessage() string { - switch p.MessageType { - case "lnurlpay_info": - return "Receiving payment" - case "lnurlpay_invoice": - return "Invoice requested" +type LnurlPayInvoicePayload struct { + Template string `json:"template" binding:"required,eq=lnurlpay_info"` + Data struct { + Amount string `json:"amount" binding:"required"` + ServerReplyURL string `json:"reply_url" binding:"required"` + } `json:"data"` +} + +func (p *LnurlPayInvoicePayload) ToNotification(query *MobilePushWebHookQuery) *notify.Notification { + return ¬ify.Notification{ + Template: p.Template, + DisplayMessage: "Invoice requested", + Type: query.Platform, + TargetIdentifier: query.Token, + AppData: query.AppData, + Data: map[string]string{ + "amount": p.Data.Amount, + "reply_url": p.Data.ServerReplyURL, + }, } - return "" } type PaymentReceivedPayload struct { @@ -137,7 +148,7 @@ func addWebHookRouter(r *gin.RouterGroup, notifier *notify.Notifier) { } // Find a matching notification payload - payloads := []NotificationConvertible{&PaymentReceivedPayload{}, &TxConfirmedPayload{}, &AddressTxsChangedPayload{}, &WebhookCallbackMessagePayload{}} + payloads := []NotificationConvertible{&PaymentReceivedPayload{}, &TxConfirmedPayload{}, &AddressTxsChangedPayload{}, &LnurlPayInfoPayload{}, &LnurlPayInvoicePayload{}} var validPayload NotificationConvertible for _, p := range payloads { if err := c.ShouldBindBodyWith(p, binding.JSON); err != nil { diff --git a/notify/notify.go b/notify/notify.go index 4ff225f..348aa3c 100644 --- a/notify/notify.go +++ b/notify/notify.go @@ -13,7 +13,8 @@ const ( NOTIFICATION_PAYMENT_RECEIVED = "payment_received" NOTIFICATION_TX_CONFIRMED = "tx_confirmed" NOTIFICATION_ADDRESS_TXS_CHANGED = "address_txs_changed" - NOTIFICATION_WEBHOOK_CALLBACK = "webhook_callback_message" + NOTIFICATION_LNURLPAY_INFO = "lnurlpay_info" + NOTIFICATION_LNURLPAY_INVOICE = "lnurlpay_invoice" ) var ( From 501859f38afb84dc0974b3e05f16f43e1cc82df9 Mon Sep 17 00:00:00 2001 From: Roei Erez Date: Tue, 16 Jan 2024 19:20:28 +0200 Subject: [PATCH 3/3] fix some namings --- http/router.go | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/http/router.go b/http/router.go index da3eb99..6a4535f 100644 --- a/http/router.go +++ b/http/router.go @@ -46,10 +46,10 @@ func (p *LnurlPayInfoPayload) ToNotification(query *MobilePushWebHookQuery) *not } type LnurlPayInvoicePayload struct { - Template string `json:"template" binding:"required,eq=lnurlpay_info"` + Template string `json:"template" binding:"required,eq=lnurlpay_invoice"` Data struct { - Amount string `json:"amount" binding:"required"` - ServerReplyURL string `json:"reply_url" binding:"required"` + Amount string `json:"amount" binding:"required"` + ReplyURL string `json:"reply_url" binding:"required"` } `json:"data"` } @@ -62,7 +62,7 @@ func (p *LnurlPayInvoicePayload) ToNotification(query *MobilePushWebHookQuery) * AppData: query.AppData, Data: map[string]string{ "amount": p.Data.Amount, - "reply_url": p.Data.ServerReplyURL, + "reply_url": p.Data.ReplyURL, }, } }