From 8fc78f16285d391f37f628fc9a35374f5d40138d Mon Sep 17 00:00:00 2001 From: im-adithya Date: Fri, 8 Nov 2024 01:13:04 +0530 Subject: [PATCH 1/7] feat: add endpoint for registering alby go 'notifications --- cmd/server/main.go | 1 + go.mod | 1 + go.sum | 2 + internal/nostr/expo.go | 126 ++++++++++++++++++ internal/nostr/models.go | 8 ++ internal/nostr/nostr.go | 16 ++- ...1071013_add_push_token_to_subscriptions.go | 23 ++++ migrations/migrate.go | 1 + 8 files changed, 177 insertions(+), 1 deletion(-) create mode 100644 internal/nostr/expo.go create mode 100644 migrations/202411071013_add_push_token_to_subscriptions.go diff --git a/cmd/server/main.go b/cmd/server/main.go index 408a7cb..9b6d7b8 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -50,6 +50,7 @@ func main() { e.POST("/nip47", svc.NIP47Handler) e.POST("/nip47/webhook", svc.NIP47WebhookHandler) e.POST("/nip47/notifications", svc.NIP47NotificationHandler) + e.POST("/nip47/notifications/go", svc.NIP47ExpoNotificationHandler) e.POST("/publish", svc.PublishHandler) e.POST("/subscriptions", svc.SubscriptionHandler) e.DELETE("/subscriptions/:id", svc.StopSubscriptionHandler) diff --git a/go.mod b/go.mod index fc02c56..41b1a49 100644 --- a/go.mod +++ b/go.mod @@ -28,6 +28,7 @@ require ( github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/oliveroneill/exponent-server-sdk-golang v0.0.0-20210823140141-d050598be512 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/puzpuzpuz/xsync/v3 v3.1.0 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect diff --git a/go.sum b/go.sum index 47a5267..42b726b 100644 --- a/go.sum +++ b/go.sum @@ -148,6 +148,8 @@ github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyua github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/nbd-wtf/go-nostr v0.31.4 h1:Qq+PHyKixRZR6Tn+omF7LykK/IR6qcdmThNY132pKsA= github.com/nbd-wtf/go-nostr v0.31.4/go.mod h1:vHKtHyLXDXzYBN0fi/9Y/Q5AD0p+hk8TQVKlldAi0gI= +github.com/oliveroneill/exponent-server-sdk-golang v0.0.0-20210823140141-d050598be512 h1:/ZSmjwl1inqsiHMhn+sPlEtSHdVTf+TH3LNGGdMQ/vA= +github.com/oliveroneill/exponent-server-sdk-golang v0.0.0-20210823140141-d050598be512/go.mod h1:Isv/48UnAjtxS8FD80Bito3ZJqZRyIMxKARIEITfW4k= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/outcaste-io/ristretto v0.2.3 h1:AK4zt/fJ76kjlYObOeNwh4T3asEuaCmp26pOvUOL9w0= diff --git a/internal/nostr/expo.go b/internal/nostr/expo.go new file mode 100644 index 0000000..e2f5e1f --- /dev/null +++ b/internal/nostr/expo.go @@ -0,0 +1,126 @@ +package nostr + +import ( + "net/http" + "time" + + "github.com/labstack/echo/v4" + "github.com/nbd-wtf/go-nostr" + expo "github.com/oliveroneill/exponent-server-sdk-golang/sdk" + "github.com/sirupsen/logrus" +) + +func (svc *Service) NIP47ExpoNotificationHandler(c echo.Context) error { + var requestData NIP47ExpoNotificationRequest + // send in a pubkey and authenticate by signing + if err := c.Bind(&requestData); err != nil { + return c.JSON(http.StatusBadRequest, ErrorResponse{ + Message: "Error decoding notification request", + Error: err.Error(), + }) + } + + if (requestData.PushToken == "") { + return c.JSON(http.StatusBadRequest, ErrorResponse{ + Message: "push token is empty", + Error: "no push token in request data", + }) + } + + _, err := expo.NewExponentPushToken(requestData.PushToken) + if err != nil { + return c.JSON(http.StatusBadRequest, ErrorResponse{ + Message: "invalid push token", + Error: "invalid push token in request data", + }) + } + + if (requestData.WalletPubkey == "") { + return c.JSON(http.StatusBadRequest, ErrorResponse{ + Message: "wallet pubkey is empty", + Error: "no wallet pubkey in request data", + }) + } + + if (requestData.ConnPubkey == "") { + return c.JSON(http.StatusBadRequest, ErrorResponse{ + Message: "connection pubkey is empty", + Error: "no connection pubkey in request data", + }) + } + + svc.Logger.WithFields(logrus.Fields{ + "wallet_pubkey": requestData.WalletPubkey, + "relay_url": requestData.RelayUrl, + "push_token": requestData.PushToken, + }).Debug("Subscribing to send push notifications") + + subscription := Subscription{ + RelayUrl: requestData.RelayUrl, + PushToken: requestData.PushToken, + Open: true, + Since: time.Now(), + Authors: &[]string{requestData.WalletPubkey}, + Kinds: &[]int{NIP_47_NOTIFICATION_KIND}, + } + + tags := make(nostr.TagMap) + (tags)["p"] = []string{requestData.ConnPubkey} + + subscription.Tags = &tags + + err = svc.db.Create(&subscription).Error + + if err != nil { + svc.Logger.WithError(err).WithFields(logrus.Fields{ + "wallet_pubkey": requestData.WalletPubkey, + "relay_url": requestData.RelayUrl, + "push_token": requestData.PushToken, + }).Error("Failed to store subscription") + return c.JSON(http.StatusBadRequest, ErrorResponse{ + Message: "Failed to store subscription", + Error: err.Error(), + }) + } + + go svc.startSubscription(svc.Ctx, &subscription, nil, svc.handleSubscribedExpoNotification) + + return c.NoContent(http.StatusOK) +} + +func (svc *Service) handleSubscribedExpoNotification(event *nostr.Event, subscription *Subscription) { + svc.Logger.WithFields(logrus.Fields{ + "event_id": event.ID, + "event_kind": event.Kind, + "subscription_id": subscription.ID, + "relay_url": subscription.RelayUrl, + }).Debug("Received subscribed notification") + + pushToken, _ := expo.NewExponentPushToken(subscription.PushToken) + + response, err := svc.client.Publish( + &expo.PushMessage{ + To: []expo.ExponentPushToken{pushToken}, + Title: "New event", + Body: "", + Data: map[string]string{ + "content": event.Content, + "appPubkey": event.Tags.GetFirst([]string{"p", ""}).Value(), + }, + Priority: expo.DefaultPriority, + }, + ) + + someerr := response.ValidateResponse() + if err != nil || someerr != nil { + svc.Logger.WithFields(logrus.Fields{ + "push_token": subscription.PushToken, + }).Error("Failed to send expo notification") + return + } + + svc.Logger.WithFields(logrus.Fields{ + "event_id": event.ID, + "push_token": subscription.PushToken, + }).Debug("Push notification sent successfully") +} diff --git a/internal/nostr/models.go b/internal/nostr/models.go index 89e1f28..ae42993 100644 --- a/internal/nostr/models.go +++ b/internal/nostr/models.go @@ -28,6 +28,7 @@ type Subscription struct { ID uint RelayUrl string WebhookUrl string + PushToken string Open bool Ids *[]string `gorm:"-"` Kinds *[]int `gorm:"-"` @@ -185,6 +186,13 @@ type NIP47NotificationRequest struct { ConnPubkey string `json:"connectionPubkey"` } +type NIP47ExpoNotificationRequest struct { + RelayUrl string `json:"relayUrl"` + PushToken string `json:"pushToken"` + WalletPubkey string `json:"walletPubkey"` + ConnPubkey string `json:"connectionPubkey"` +} + type NIP47Response struct { Event *nostr.Event `json:"event,omitempty"` State string `json:"state"` diff --git a/internal/nostr/nostr.go b/internal/nostr/nostr.go index 301af7c..0f7b801 100644 --- a/internal/nostr/nostr.go +++ b/internal/nostr/nostr.go @@ -23,6 +23,7 @@ import ( "gorm.io/gorm" "github.com/jackc/pgx/v5/stdlib" + expo "github.com/oliveroneill/exponent-server-sdk-golang/sdk" sqltrace "gopkg.in/DataDog/dd-trace-go.v1/contrib/database/sql" gormtrace "gopkg.in/DataDog/dd-trace-go.v1/contrib/gorm.io/gorm.v1" ) @@ -49,6 +50,7 @@ type Service struct { subscriptions map[string]*nostr.Subscription subscriptionsMutex sync.Mutex relayMutex sync.Mutex + client *expo.PushClient } func NewService(ctx context.Context) (*Service, error) { @@ -116,6 +118,12 @@ func NewService(ctx context.Context) (*Service, error) { subscriptions := make(map[string]*nostr.Subscription) + // TODO: Check limits + client := expo.NewPushClient(&expo.ClientConfig{ + Host: "https://api.expo.dev", + APIURL: "/v2", + }) + var wg sync.WaitGroup svc := &Service{ Cfg: cfg, @@ -125,6 +133,7 @@ func NewService(ctx context.Context) (*Service, error) { Logger: logger, Relay: relay, subscriptions: subscriptions, + client: client, } logger.Info("Starting all open subscriptions...") @@ -139,7 +148,11 @@ func NewService(ctx context.Context) (*Service, error) { // Create a copy of the loop variable to // avoid passing address of the same variable subscription := sub - go svc.startSubscription(svc.Ctx, &subscription, nil, svc.handleSubscribedEvent) + handleEvent := svc.handleSubscribedEvent + if sub.PushToken != "" { + handleEvent = svc.handleSubscribedExpoNotification + } + go svc.startSubscription(svc.Ctx, &subscription, nil, handleEvent) } return svc, nil @@ -928,6 +941,7 @@ func (svc *Service) postEventToWebhook(event *nostr.Event, webhookURL string) { "event_kind": event.Kind, "webhook_url": webhookURL, }).Error("Failed to post event to webhook") + return } svc.Logger.WithFields(logrus.Fields{ diff --git a/migrations/202411071013_add_push_token_to_subscriptions.go b/migrations/202411071013_add_push_token_to_subscriptions.go new file mode 100644 index 0000000..2c54710 --- /dev/null +++ b/migrations/202411071013_add_push_token_to_subscriptions.go @@ -0,0 +1,23 @@ +package migrations + +import ( + "github.com/go-gormigrate/gormigrate/v2" + "gorm.io/gorm" +) + +// Add push_token column to subscriptions table +var _202411071013_add_push_token_to_subscriptions = &gormigrate.Migration{ + ID: "202411071013_add_push_token_to_subscriptions", + Migrate: func(tx *gorm.DB) error { + if err := tx.Exec("ALTER TABLE subscriptions ADD COLUMN push_token TEXT").Error; err != nil { + return err + } + return nil + }, + Rollback: func(tx *gorm.DB) error { + if err := tx.Exec("ALTER TABLE subscriptions DROP COLUMN push_token").Error; err != nil { + return err + } + return nil + }, +} \ No newline at end of file diff --git a/migrations/migrate.go b/migrations/migrate.go index 444adee..6fc528f 100644 --- a/migrations/migrate.go +++ b/migrations/migrate.go @@ -12,6 +12,7 @@ func Migrate(db *gorm.DB) error { _202404021628_add_uuid_to_subscriptions, _202404031539_add_indexes, _202407171220_add_response_received_at_to_request_events, + _202411071013_add_push_token_to_subscriptions, }) return m.Migrate() From 8b183597fc2eb7ae8a1dc198f4f8f648c84a5584 Mon Sep 17 00:00:00 2001 From: im-adithya Date: Fri, 8 Nov 2024 01:20:24 +0530 Subject: [PATCH 2/7] chore: minor spacing fixes --- internal/nostr/expo.go | 1 - internal/nostr/models.go | 4 ++-- migrations/202404021628_add_uuid_to_subscriptions.go | 2 +- migrations/202404031539_add_indexes.go | 2 +- migrations/202411071013_add_push_token_to_subscriptions.go | 2 +- migrations/migrate.go | 2 +- 6 files changed, 6 insertions(+), 7 deletions(-) diff --git a/internal/nostr/expo.go b/internal/nostr/expo.go index e2f5e1f..a4b1650 100644 --- a/internal/nostr/expo.go +++ b/internal/nostr/expo.go @@ -12,7 +12,6 @@ import ( func (svc *Service) NIP47ExpoNotificationHandler(c echo.Context) error { var requestData NIP47ExpoNotificationRequest - // send in a pubkey and authenticate by signing if err := c.Bind(&requestData); err != nil { return c.JSON(http.StatusBadRequest, ErrorResponse{ Message: "Error decoding notification request", diff --git a/internal/nostr/models.go b/internal/nostr/models.go index ae42993..ff16e26 100644 --- a/internal/nostr/models.go +++ b/internal/nostr/models.go @@ -28,7 +28,7 @@ type Subscription struct { ID uint RelayUrl string WebhookUrl string - PushToken string + PushToken string Open bool Ids *[]string `gorm:"-"` Kinds *[]int `gorm:"-"` @@ -190,7 +190,7 @@ type NIP47ExpoNotificationRequest struct { RelayUrl string `json:"relayUrl"` PushToken string `json:"pushToken"` WalletPubkey string `json:"walletPubkey"` - ConnPubkey string `json:"connectionPubkey"` + ConnPubkey string `json:"connectionPubkey"` } type NIP47Response struct { diff --git a/migrations/202404021628_add_uuid_to_subscriptions.go b/migrations/202404021628_add_uuid_to_subscriptions.go index 8e09c78..af515c3 100644 --- a/migrations/202404021628_add_uuid_to_subscriptions.go +++ b/migrations/202404021628_add_uuid_to_subscriptions.go @@ -20,4 +20,4 @@ var _202404021628_add_uuid_to_subscriptions = &gormigrate.Migration{ } return tx.Exec("ALTER TABLE subscriptions DROP COLUMN IF EXISTS uuid").Error }, -} \ No newline at end of file +} diff --git a/migrations/202404031539_add_indexes.go b/migrations/202404031539_add_indexes.go index 8475cd3..1b8b81b 100644 --- a/migrations/202404031539_add_indexes.go +++ b/migrations/202404031539_add_indexes.go @@ -28,4 +28,4 @@ var _202404031539_add_indexes = &gormigrate.Migration{ } return nil }, -} \ No newline at end of file +} diff --git a/migrations/202411071013_add_push_token_to_subscriptions.go b/migrations/202411071013_add_push_token_to_subscriptions.go index 2c54710..617e60f 100644 --- a/migrations/202411071013_add_push_token_to_subscriptions.go +++ b/migrations/202411071013_add_push_token_to_subscriptions.go @@ -20,4 +20,4 @@ var _202411071013_add_push_token_to_subscriptions = &gormigrate.Migration{ } return nil }, -} \ No newline at end of file +} diff --git a/migrations/migrate.go b/migrations/migrate.go index 6fc528f..058cc72 100644 --- a/migrations/migrate.go +++ b/migrations/migrate.go @@ -16,4 +16,4 @@ func Migrate(db *gorm.DB) error { }) return m.Migrate() -} \ No newline at end of file +} From a275855cbfec49233ae382b4a7fbe3f812af9d23 Mon Sep 17 00:00:00 2001 From: im-adithya Date: Fri, 8 Nov 2024 10:22:45 +0530 Subject: [PATCH 3/7] chore: handle errors --- internal/nostr/expo.go | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/internal/nostr/expo.go b/internal/nostr/expo.go index a4b1650..d0de760 100644 --- a/internal/nostr/expo.go +++ b/internal/nostr/expo.go @@ -109,15 +109,21 @@ func (svc *Service) handleSubscribedExpoNotification(event *nostr.Event, subscri Priority: expo.DefaultPriority, }, ) - - someerr := response.ValidateResponse() - if err != nil || someerr != nil { - svc.Logger.WithFields(logrus.Fields{ + if err != nil { + svc.Logger.WithError(err).WithFields(logrus.Fields{ "push_token": subscription.PushToken, }).Error("Failed to send expo notification") return } + err = response.ValidateResponse() + if err != nil { + svc.Logger.WithError(err).WithFields(logrus.Fields{ + "push_token": subscription.PushToken, + }).Error("Failed to valid expo publish response") + return + } + svc.Logger.WithFields(logrus.Fields{ "event_id": event.ID, "push_token": subscription.PushToken, From b99700a9548961d245e12b332a3bc337475a389a Mon Sep 17 00:00:00 2001 From: im-adithya Date: Fri, 8 Nov 2024 14:46:58 +0530 Subject: [PATCH 4/7] chore: add index and check for existing subscriptions --- internal/nostr/expo.go | 41 +++++++++++++++++-- internal/nostr/models.go | 9 +++- ...1071013_add_push_token_to_subscriptions.go | 6 +++ 3 files changed, 51 insertions(+), 5 deletions(-) diff --git a/internal/nostr/expo.go b/internal/nostr/expo.go index d0de760..a976897 100644 --- a/internal/nostr/expo.go +++ b/internal/nostr/expo.go @@ -48,10 +48,40 @@ func (svc *Service) NIP47ExpoNotificationHandler(c echo.Context) error { }) } + var existingSubscriptions []Subscription + if err := svc.db.Where("push_token = ? AND open = ?", requestData.PushToken, true).Find(&existingSubscriptions).Error; err != nil { + svc.Logger.WithError(err).WithFields(logrus.Fields{ + "push_token": requestData.PushToken, + }).Error("Failed to check existing subscriptions") + return c.JSON(http.StatusInternalServerError, ErrorResponse{ + Message: "internal server error", + Error: err.Error(), + }) + } + + for _, existingSubscription := range existingSubscriptions { + existingWalletPubkey := (*existingSubscription.Authors)[0] + existingConnPubkey := (*existingSubscription.Tags)["p"][0] + + if existingWalletPubkey == requestData.WalletPubkey && existingConnPubkey == requestData.ConnPubkey { + svc.Logger.WithFields(logrus.Fields{ + "wallet_pubkey": requestData.WalletPubkey, + "relay_url": requestData.RelayUrl, + "push_token": requestData.PushToken, + }).Debug("Subscription already started") + return c.JSON(http.StatusOK, ExpoSubscriptionResponse{ + SubscriptionId: existingSubscription.Uuid, + PushToken: requestData.PushToken, + WalletPubkey: requestData.WalletPubkey, + AppPubkey: requestData.ConnPubkey, + }) + } + } + svc.Logger.WithFields(logrus.Fields{ "wallet_pubkey": requestData.WalletPubkey, "relay_url": requestData.RelayUrl, - "push_token": requestData.PushToken, + "push_token": requestData.PushToken, }).Debug("Subscribing to send push notifications") subscription := Subscription{ @@ -65,11 +95,9 @@ func (svc *Service) NIP47ExpoNotificationHandler(c echo.Context) error { tags := make(nostr.TagMap) (tags)["p"] = []string{requestData.ConnPubkey} - subscription.Tags = &tags err = svc.db.Create(&subscription).Error - if err != nil { svc.Logger.WithError(err).WithFields(logrus.Fields{ "wallet_pubkey": requestData.WalletPubkey, @@ -84,7 +112,12 @@ func (svc *Service) NIP47ExpoNotificationHandler(c echo.Context) error { go svc.startSubscription(svc.Ctx, &subscription, nil, svc.handleSubscribedExpoNotification) - return c.NoContent(http.StatusOK) + return c.JSON(http.StatusOK, ExpoSubscriptionResponse{ + SubscriptionId: subscription.Uuid, + PushToken: requestData.PushToken, + WalletPubkey: requestData.WalletPubkey, + AppPubkey: requestData.ConnPubkey, + }) } func (svc *Service) handleSubscribedExpoNotification(event *nostr.Event, subscription *Subscription) { diff --git a/internal/nostr/models.go b/internal/nostr/models.go index ff16e26..9328fb2 100644 --- a/internal/nostr/models.go +++ b/internal/nostr/models.go @@ -216,10 +216,17 @@ type SubscriptionRequest struct { } type SubscriptionResponse struct { - SubscriptionId string `json:"subscription_id"` + SubscriptionId string `json:"subscriptionId"` WebhookUrl string `json:"webhookUrl"` } +type ExpoSubscriptionResponse struct { + SubscriptionId string `json:"subscriptionId"` + PushToken string `json:"pushToken"` + WalletPubkey string `json:"walletPubkey"` + AppPubkey string `json:"appPubkey"` +} + type StopSubscriptionResponse struct { Message string `json:"message"` State string `json:"state"` diff --git a/migrations/202411071013_add_push_token_to_subscriptions.go b/migrations/202411071013_add_push_token_to_subscriptions.go index 617e60f..e4fd0fd 100644 --- a/migrations/202411071013_add_push_token_to_subscriptions.go +++ b/migrations/202411071013_add_push_token_to_subscriptions.go @@ -12,9 +12,15 @@ var _202411071013_add_push_token_to_subscriptions = &gormigrate.Migration{ if err := tx.Exec("ALTER TABLE subscriptions ADD COLUMN push_token TEXT").Error; err != nil { return err } + if err := tx.Exec("CREATE INDEX IF NOT EXISTS subscriptions_push_token ON subscriptions (push_token)").Error; err != nil { + return err + } return nil }, Rollback: func(tx *gorm.DB) error { + if err := tx.Exec("DROP INDEX IF EXISTS subscriptions_push_token").Error; err != nil { + return err + } if err := tx.Exec("ALTER TABLE subscriptions DROP COLUMN push_token").Error; err != nil { return err } From 572b9d8f2d6986e524ff250f56cb87a96829df22 Mon Sep 17 00:00:00 2001 From: im-adithya Date: Wed, 13 Nov 2024 14:27:15 +0530 Subject: [PATCH 5/7] chore: add is_ios column and naming changes --- cmd/server/main.go | 2 +- go.mod | 2 +- go.sum | 4 +- internal/nostr/models.go | 8 +-- internal/nostr/nostr.go | 4 +- internal/nostr/{expo.go => push.go} | 53 ++++++++++--------- ...push_token_and_is_ios_to_subscriptions.go} | 12 +++-- migrations/migrate.go | 2 +- 8 files changed, 49 insertions(+), 38 deletions(-) rename internal/nostr/{expo.go => push.go} (78%) rename migrations/{202411071013_add_push_token_to_subscriptions.go => 202411071013_add_push_token_and_is_ios_to_subscriptions.go} (60%) diff --git a/cmd/server/main.go b/cmd/server/main.go index 9b6d7b8..dadb2c6 100644 --- a/cmd/server/main.go +++ b/cmd/server/main.go @@ -50,7 +50,7 @@ func main() { e.POST("/nip47", svc.NIP47Handler) e.POST("/nip47/webhook", svc.NIP47WebhookHandler) e.POST("/nip47/notifications", svc.NIP47NotificationHandler) - e.POST("/nip47/notifications/go", svc.NIP47ExpoNotificationHandler) + e.POST("/nip47/notifications/push", svc.NIP47PushNotificationHandler) e.POST("/publish", svc.PublishHandler) e.POST("/subscriptions", svc.SubscriptionHandler) e.DELETE("/subscriptions/:id", svc.StopSubscriptionHandler) diff --git a/go.mod b/go.mod index 41b1a49..636d3be 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module http-nostr go 1.21.3 require ( + github.com/getAlby/exponent-server-sdk-golang/sdk v0.0.0-20241113053439-fb024e3a89b1 github.com/getsentry/sentry-go v0.28.1 github.com/jackc/pgx/v5 v5.6.0 github.com/joho/godotenv v1.5.1 @@ -28,7 +29,6 @@ require ( github.com/jinzhu/inflection v1.0.0 // indirect github.com/jinzhu/now v1.1.5 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect - github.com/oliveroneill/exponent-server-sdk-golang v0.0.0-20210823140141-d050598be512 // indirect github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect github.com/puzpuzpuz/xsync/v3 v3.1.0 // indirect github.com/rogpeppe/go-internal v1.12.0 // indirect diff --git a/go.sum b/go.sum index 42b726b..9c6299d 100644 --- a/go.sum +++ b/go.sum @@ -51,6 +51,8 @@ github.com/eapache/queue/v2 v2.0.0-20230407133247-75960ed334e4/go.mod h1:I5sHm0Y github.com/ebitengine/purego v0.7.1 h1:6/55d26lG3o9VCZX8lping+bZcmShseiqlh2bnUDiPA= github.com/ebitengine/purego v0.7.1/go.mod h1:ah1In8AOtksoNK6yk5z1HTJeUkC1Ez4Wk2idgGslMwQ= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/getAlby/exponent-server-sdk-golang/sdk v0.0.0-20241113053439-fb024e3a89b1 h1:u1rDPykjuG3DkUAeHlGby4frrynzjJAfZbuK/jLlu6k= +github.com/getAlby/exponent-server-sdk-golang/sdk v0.0.0-20241113053439-fb024e3a89b1/go.mod h1:EK6N2J42WZk795IUD9GGbKL8XAK5UjfUEvxh4d9hobY= github.com/getsentry/sentry-go v0.28.1 h1:zzaSm/vHmGllRM6Tpx1492r0YDzauArdBfkJRtY6P5k= github.com/getsentry/sentry-go v0.28.1/go.mod h1:1fQZ+7l7eeJ3wYi82q5Hg8GqAPgefRq+FP/QhafYVgg= github.com/glebarez/go-sqlite v1.22.0 h1:uAcMJhaA6r3LHMTFgP0SifzgXg46yJkgxqyuyec+ruQ= @@ -148,8 +150,6 @@ github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyua github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/nbd-wtf/go-nostr v0.31.4 h1:Qq+PHyKixRZR6Tn+omF7LykK/IR6qcdmThNY132pKsA= github.com/nbd-wtf/go-nostr v0.31.4/go.mod h1:vHKtHyLXDXzYBN0fi/9Y/Q5AD0p+hk8TQVKlldAi0gI= -github.com/oliveroneill/exponent-server-sdk-golang v0.0.0-20210823140141-d050598be512 h1:/ZSmjwl1inqsiHMhn+sPlEtSHdVTf+TH3LNGGdMQ/vA= -github.com/oliveroneill/exponent-server-sdk-golang v0.0.0-20210823140141-d050598be512/go.mod h1:Isv/48UnAjtxS8FD80Bito3ZJqZRyIMxKARIEITfW4k= github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= github.com/outcaste-io/ristretto v0.2.3 h1:AK4zt/fJ76kjlYObOeNwh4T3asEuaCmp26pOvUOL9w0= diff --git a/internal/nostr/models.go b/internal/nostr/models.go index 9328fb2..f72d5dc 100644 --- a/internal/nostr/models.go +++ b/internal/nostr/models.go @@ -29,6 +29,7 @@ type Subscription struct { RelayUrl string WebhookUrl string PushToken string + IsIOS bool Open bool Ids *[]string `gorm:"-"` Kinds *[]int `gorm:"-"` @@ -186,11 +187,12 @@ type NIP47NotificationRequest struct { ConnPubkey string `json:"connectionPubkey"` } -type NIP47ExpoNotificationRequest struct { +type NIP47PushNotificationRequest struct { RelayUrl string `json:"relayUrl"` PushToken string `json:"pushToken"` WalletPubkey string `json:"walletPubkey"` ConnPubkey string `json:"connectionPubkey"` + IsIOS bool `json:"isIOS"` } type NIP47Response struct { @@ -216,11 +218,11 @@ type SubscriptionRequest struct { } type SubscriptionResponse struct { - SubscriptionId string `json:"subscriptionId"` + SubscriptionId string `json:"subscription_id"` WebhookUrl string `json:"webhookUrl"` } -type ExpoSubscriptionResponse struct { +type PushSubscriptionResponse struct { SubscriptionId string `json:"subscriptionId"` PushToken string `json:"pushToken"` WalletPubkey string `json:"walletPubkey"` diff --git a/internal/nostr/nostr.go b/internal/nostr/nostr.go index 0f7b801..5251745 100644 --- a/internal/nostr/nostr.go +++ b/internal/nostr/nostr.go @@ -22,8 +22,8 @@ import ( "gorm.io/driver/postgres" "gorm.io/gorm" + expo "github.com/getAlby/exponent-server-sdk-golang/sdk" "github.com/jackc/pgx/v5/stdlib" - expo "github.com/oliveroneill/exponent-server-sdk-golang/sdk" sqltrace "gopkg.in/DataDog/dd-trace-go.v1/contrib/database/sql" gormtrace "gopkg.in/DataDog/dd-trace-go.v1/contrib/gorm.io/gorm.v1" ) @@ -150,7 +150,7 @@ func NewService(ctx context.Context) (*Service, error) { subscription := sub handleEvent := svc.handleSubscribedEvent if sub.PushToken != "" { - handleEvent = svc.handleSubscribedExpoNotification + handleEvent = svc.handlePushNotification } go svc.startSubscription(svc.Ctx, &subscription, nil, handleEvent) } diff --git a/internal/nostr/expo.go b/internal/nostr/push.go similarity index 78% rename from internal/nostr/expo.go rename to internal/nostr/push.go index a976897..812c9fc 100644 --- a/internal/nostr/expo.go +++ b/internal/nostr/push.go @@ -4,14 +4,14 @@ import ( "net/http" "time" + expo "github.com/getAlby/exponent-server-sdk-golang/sdk" "github.com/labstack/echo/v4" "github.com/nbd-wtf/go-nostr" - expo "github.com/oliveroneill/exponent-server-sdk-golang/sdk" "github.com/sirupsen/logrus" ) -func (svc *Service) NIP47ExpoNotificationHandler(c echo.Context) error { - var requestData NIP47ExpoNotificationRequest +func (svc *Service) NIP47PushNotificationHandler(c echo.Context) error { + var requestData NIP47PushNotificationRequest if err := c.Bind(&requestData); err != nil { return c.JSON(http.StatusBadRequest, ErrorResponse{ Message: "Error decoding notification request", @@ -69,7 +69,7 @@ func (svc *Service) NIP47ExpoNotificationHandler(c echo.Context) error { "relay_url": requestData.RelayUrl, "push_token": requestData.PushToken, }).Debug("Subscription already started") - return c.JSON(http.StatusOK, ExpoSubscriptionResponse{ + return c.JSON(http.StatusOK, PushSubscriptionResponse{ SubscriptionId: existingSubscription.Uuid, PushToken: requestData.PushToken, WalletPubkey: requestData.WalletPubkey, @@ -87,6 +87,7 @@ func (svc *Service) NIP47ExpoNotificationHandler(c echo.Context) error { subscription := Subscription{ RelayUrl: requestData.RelayUrl, PushToken: requestData.PushToken, + IsIOS: requestData.IsIOS, Open: true, Since: time.Now(), Authors: &[]string{requestData.WalletPubkey}, @@ -110,9 +111,9 @@ func (svc *Service) NIP47ExpoNotificationHandler(c echo.Context) error { }) } - go svc.startSubscription(svc.Ctx, &subscription, nil, svc.handleSubscribedExpoNotification) + go svc.startSubscription(svc.Ctx, &subscription, nil, svc.handlePushNotification) - return c.JSON(http.StatusOK, ExpoSubscriptionResponse{ + return c.JSON(http.StatusOK, PushSubscriptionResponse{ SubscriptionId: subscription.Uuid, PushToken: requestData.PushToken, WalletPubkey: requestData.WalletPubkey, @@ -120,45 +121,47 @@ func (svc *Service) NIP47ExpoNotificationHandler(c echo.Context) error { }) } -func (svc *Service) handleSubscribedExpoNotification(event *nostr.Event, subscription *Subscription) { +func (svc *Service) handlePushNotification(event *nostr.Event, subscription *Subscription) { svc.Logger.WithFields(logrus.Fields{ "event_id": event.ID, "event_kind": event.Kind, "subscription_id": subscription.ID, "relay_url": subscription.RelayUrl, - }).Debug("Received subscribed notification") + }).Debug("Received subscribed push notification") pushToken, _ := expo.NewExponentPushToken(subscription.PushToken) - response, err := svc.client.Publish( - &expo.PushMessage{ - To: []expo.ExponentPushToken{pushToken}, - Title: "New event", - Body: "", - Data: map[string]string{ - "content": event.Content, - "appPubkey": event.Tags.GetFirst([]string{"p", ""}).Value(), - }, - Priority: expo.DefaultPriority, + pushMessage := &expo.PushMessage{ + To: []expo.ExponentPushToken{pushToken}, + Data: map[string]string{ + "content": event.Content, + "appPubkey": event.Tags.GetFirst([]string{"p", ""}).Value(), }, - ) + } + + if subscription.IsIOS { + pushMessage.Title = "Received notification" + pushMessage.MutableContent = true + } + + response, err := svc.client.Publish(pushMessage) if err != nil { svc.Logger.WithError(err).WithFields(logrus.Fields{ - "push_token": subscription.PushToken, - }).Error("Failed to send expo notification") + "push_token": subscription.PushToken, + }).Error("Failed to send push notification") return } err = response.ValidateResponse() if err != nil { svc.Logger.WithError(err).WithFields(logrus.Fields{ - "push_token": subscription.PushToken, - }).Error("Failed to valid expo publish response") + "push_token": subscription.PushToken, + }).Error("Failed to validate expo publish response") return } svc.Logger.WithFields(logrus.Fields{ - "event_id": event.ID, - "push_token": subscription.PushToken, + "event_id": event.ID, + "push_token": subscription.PushToken, }).Debug("Push notification sent successfully") } diff --git a/migrations/202411071013_add_push_token_to_subscriptions.go b/migrations/202411071013_add_push_token_and_is_ios_to_subscriptions.go similarity index 60% rename from migrations/202411071013_add_push_token_to_subscriptions.go rename to migrations/202411071013_add_push_token_and_is_ios_to_subscriptions.go index e4fd0fd..36abe7f 100644 --- a/migrations/202411071013_add_push_token_to_subscriptions.go +++ b/migrations/202411071013_add_push_token_and_is_ios_to_subscriptions.go @@ -5,13 +5,16 @@ import ( "gorm.io/gorm" ) -// Add push_token column to subscriptions table -var _202411071013_add_push_token_to_subscriptions = &gormigrate.Migration{ - ID: "202411071013_add_push_token_to_subscriptions", +// Add push_token and is_ios column to subscriptions table +var _202411071013_add_push_token_and_is_ios_to_subscriptions = &gormigrate.Migration{ + ID: "202411071013_add_push_token_and_is_ios_to_subscriptions", Migrate: func(tx *gorm.DB) error { if err := tx.Exec("ALTER TABLE subscriptions ADD COLUMN push_token TEXT").Error; err != nil { return err } + if err := tx.Exec("ALTER TABLE subscriptions ADD COLUMN is_ios BOOLEAN DEFAULT NULL").Error; err != nil { + return err + } if err := tx.Exec("CREATE INDEX IF NOT EXISTS subscriptions_push_token ON subscriptions (push_token)").Error; err != nil { return err } @@ -24,6 +27,9 @@ var _202411071013_add_push_token_to_subscriptions = &gormigrate.Migration{ if err := tx.Exec("ALTER TABLE subscriptions DROP COLUMN push_token").Error; err != nil { return err } + if err := tx.Exec("ALTER TABLE subscriptions DROP COLUMN is_ios").Error; err != nil { + return err + } return nil }, } diff --git a/migrations/migrate.go b/migrations/migrate.go index 058cc72..f64863a 100644 --- a/migrations/migrate.go +++ b/migrations/migrate.go @@ -12,7 +12,7 @@ func Migrate(db *gorm.DB) error { _202404021628_add_uuid_to_subscriptions, _202404031539_add_indexes, _202407171220_add_response_received_at_to_request_events, - _202411071013_add_push_token_to_subscriptions, + _202411071013_add_push_token_and_is_ios_to_subscriptions, }) return m.Migrate() From c2c9ca389c0f15e78af27f8e30dfed03fa99854f Mon Sep 17 00:00:00 2001 From: im-adithya Date: Thu, 14 Nov 2024 17:36:38 +0530 Subject: [PATCH 6/7] feat: migrate to jsonb and optimize query --- internal/nostr/models.go | 81 ++++------ internal/nostr/nostr.go | 1 - internal/nostr/push.go | 32 ++-- ...202411131742_update_subscriptions_jsonb.go | 143 ++++++++++++++++++ migrations/migrate.go | 1 + 5 files changed, 190 insertions(+), 68 deletions(-) create mode 100644 migrations/202411131742_update_subscriptions_jsonb.go diff --git a/internal/nostr/models.go b/internal/nostr/models.go index f72d5dc..756f3b6 100644 --- a/internal/nostr/models.go +++ b/internal/nostr/models.go @@ -45,49 +45,36 @@ type Subscription struct { EventChan chan *nostr.Event `gorm:"-"` RequestEvent *RequestEvent `gorm:"-"` - // TODO: fix an elegant solution to store datatypes - IdsString string - KindsString string - AuthorsString string - TagsString string + IdsJson json.RawMessage `gorm:"type:jsonb"` + KindsJson json.RawMessage `gorm:"type:jsonb"` + AuthorsJson json.RawMessage `gorm:"type:jsonb"` + TagsJson json.RawMessage `gorm:"type:jsonb"` } func (s *Subscription) BeforeSave(tx *gorm.DB) error { var err error if s.Ids != nil { - var idsJson []byte - idsJson, err = json.Marshal(s.Ids) - if err != nil { - return err - } - s.IdsString = string(idsJson) + if s.IdsJson, err = json.Marshal(s.Ids); err != nil { + return err + } } if s.Kinds != nil { - var kindsJson []byte - kindsJson, err = json.Marshal(s.Kinds) - if err != nil { - return err - } - s.KindsString = string(kindsJson) + if s.KindsJson, err = json.Marshal(s.Kinds); err != nil { + return err + } } if s.Authors != nil { - var authorsJson []byte - authorsJson, err = json.Marshal(s.Authors) - if err != nil { - return err - } - s.AuthorsString = string(authorsJson) + if s.AuthorsJson, err = json.Marshal(s.Authors); err != nil { + return err + } } if s.Tags != nil { - var tagsJson []byte - tagsJson, err = json.Marshal(s.Tags) - if err != nil { - return err - } - s.TagsString = string(tagsJson) + if s.TagsJson, err = json.Marshal(s.Tags); err != nil { + return err + } } return nil @@ -95,32 +82,28 @@ func (s *Subscription) BeforeSave(tx *gorm.DB) error { func (s *Subscription) AfterFind(tx *gorm.DB) error { var err error - if s.IdsString != "" { - err = json.Unmarshal([]byte(s.IdsString), &s.Ids) - if err != nil { - return err - } + if len(s.IdsJson) > 0 { + if err = json.Unmarshal(s.IdsJson, &s.Ids); err != nil { + return err + } } - if s.KindsString != "" { - err = json.Unmarshal([]byte(s.KindsString), &s.Kinds) - if err != nil { - return err - } + if len(s.KindsJson) > 0 { + if err = json.Unmarshal(s.KindsJson, &s.Kinds); err != nil { + return err + } } - if s.AuthorsString != "" { - err = json.Unmarshal([]byte(s.AuthorsString), &s.Authors) - if err != nil { - return err - } + if len(s.AuthorsJson) > 0 { + if err = json.Unmarshal(s.AuthorsJson, &s.Authors); err != nil { + return err + } } - if s.TagsString != "" { - err = json.Unmarshal([]byte(s.TagsString), &s.Tags) - if err != nil { - return err - } + if len(s.TagsJson) > 0 { + if err = json.Unmarshal(s.TagsJson, &s.Tags); err != nil { + return err + } } return nil diff --git a/internal/nostr/nostr.go b/internal/nostr/nostr.go index 5251745..499ab03 100644 --- a/internal/nostr/nostr.go +++ b/internal/nostr/nostr.go @@ -118,7 +118,6 @@ func NewService(ctx context.Context) (*Service, error) { subscriptions := make(map[string]*nostr.Subscription) - // TODO: Check limits client := expo.NewPushClient(&expo.ClientConfig{ Host: "https://api.expo.dev", APIURL: "/v2", diff --git a/internal/nostr/push.go b/internal/nostr/push.go index 812c9fc..5407aa4 100644 --- a/internal/nostr/push.go +++ b/internal/nostr/push.go @@ -49,7 +49,7 @@ func (svc *Service) NIP47PushNotificationHandler(c echo.Context) error { } var existingSubscriptions []Subscription - if err := svc.db.Where("push_token = ? AND open = ?", requestData.PushToken, true).Find(&existingSubscriptions).Error; err != nil { + if err := svc.db.Where("push_token = ? AND open = ? AND authors_json->>0 = ? AND tags_json->'p'->>0 = ?", requestData.PushToken, true, requestData.WalletPubkey, requestData.ConnPubkey).Find(&existingSubscriptions).Error; err != nil { svc.Logger.WithError(err).WithFields(logrus.Fields{ "push_token": requestData.PushToken, }).Error("Failed to check existing subscriptions") @@ -59,23 +59,19 @@ func (svc *Service) NIP47PushNotificationHandler(c echo.Context) error { }) } - for _, existingSubscription := range existingSubscriptions { - existingWalletPubkey := (*existingSubscription.Authors)[0] - existingConnPubkey := (*existingSubscription.Tags)["p"][0] - - if existingWalletPubkey == requestData.WalletPubkey && existingConnPubkey == requestData.ConnPubkey { - svc.Logger.WithFields(logrus.Fields{ - "wallet_pubkey": requestData.WalletPubkey, - "relay_url": requestData.RelayUrl, - "push_token": requestData.PushToken, - }).Debug("Subscription already started") - return c.JSON(http.StatusOK, PushSubscriptionResponse{ - SubscriptionId: existingSubscription.Uuid, - PushToken: requestData.PushToken, - WalletPubkey: requestData.WalletPubkey, - AppPubkey: requestData.ConnPubkey, - }) - } + if len(existingSubscriptions) > 0 { + existingSubscription := existingSubscriptions[0] + svc.Logger.WithFields(logrus.Fields{ + "wallet_pubkey": requestData.WalletPubkey, + "relay_url": requestData.RelayUrl, + "push_token": requestData.PushToken, + }).Debug("Subscription already started") + return c.JSON(http.StatusOK, PushSubscriptionResponse{ + SubscriptionId: existingSubscription.Uuid, + PushToken: requestData.PushToken, + WalletPubkey: requestData.WalletPubkey, + AppPubkey: requestData.ConnPubkey, + }) } svc.Logger.WithFields(logrus.Fields{ diff --git a/migrations/202411131742_update_subscriptions_jsonb.go b/migrations/202411131742_update_subscriptions_jsonb.go new file mode 100644 index 0000000..0eeffc2 --- /dev/null +++ b/migrations/202411131742_update_subscriptions_jsonb.go @@ -0,0 +1,143 @@ +package migrations + +import ( + "github.com/go-gormigrate/gormigrate/v2" + "gorm.io/gorm" +) + +// Update subscriptions table to use JSONB columns for ids, kinds, authors, and tags +var _202411131742_update_subscriptions_jsonb = &gormigrate.Migration{ + ID: "202411131742_update_subscriptions_jsonb", + Migrate: func(tx *gorm.DB) error { + if err := tx.Exec("ALTER TABLE subscriptions ADD COLUMN ids_json jsonb").Error; err != nil { + return err + } + if err := tx.Exec("ALTER TABLE subscriptions ADD COLUMN kinds_json jsonb").Error; err != nil { + return err + } + if err := tx.Exec("ALTER TABLE subscriptions ADD COLUMN authors_json jsonb").Error; err != nil { + return err + } + if err := tx.Exec("ALTER TABLE subscriptions ADD COLUMN tags_json jsonb").Error; err != nil { + return err + } + + if err := tx.Exec(` + UPDATE subscriptions + SET ids_json = CASE + WHEN ids_string = '' THEN '[]'::jsonb + ELSE ids_string::jsonb + END + WHERE ids_string IS NOT NULL + `).Error; err != nil { + return err + } + + if err := tx.Exec(` + UPDATE subscriptions + SET kinds_json = CASE + WHEN kinds_string = '' THEN '[]'::jsonb + ELSE kinds_string::jsonb + END + WHERE kinds_string IS NOT NULL + `).Error; err != nil { + return err + } + + if err := tx.Exec(` + UPDATE subscriptions + SET authors_json = CASE + WHEN authors_string = '' THEN '[]'::jsonb + ELSE authors_string::jsonb + END + WHERE authors_string IS NOT NULL + `).Error; err != nil { + return err + } + + if err := tx.Exec(` + UPDATE subscriptions + SET tags_json = CASE + WHEN tags_string = '' THEN '{}'::jsonb + ELSE tags_string::jsonb + END + WHERE tags_string IS NOT NULL + `).Error; err != nil { + return err + } + + if err := tx.Exec("ALTER TABLE subscriptions DROP COLUMN ids_string").Error; err != nil { + return err + } + if err := tx.Exec("ALTER TABLE subscriptions DROP COLUMN kinds_string").Error; err != nil { + return err + } + if err := tx.Exec("ALTER TABLE subscriptions DROP COLUMN authors_string").Error; err != nil { + return err + } + if err := tx.Exec("ALTER TABLE subscriptions DROP COLUMN tags_string").Error; err != nil { + return err + } + + if err := tx.Exec("CREATE INDEX IF NOT EXISTS subscriptions_open ON subscriptions (open)").Error; err != nil { + return err + } + if err := tx.Exec("CREATE INDEX IF NOT EXISTS idx_subscriptions_authors_json ON subscriptions USING gin (authors_json)").Error; err != nil { + return err + } + if err := tx.Exec("CREATE INDEX IF NOT EXISTS idx_subscriptions_tags_json ON subscriptions USING gin (tags_json)").Error; err != nil { + return err + } + + return nil + }, + Rollback: func(tx *gorm.DB) error { + if err := tx.Exec("DROP INDEX IF EXISTS idx_subscriptions_authors_json").Error; err != nil { + return err + } + if err := tx.Exec("DROP INDEX IF EXISTS idx_subscriptions_tags_json").Error; err != nil { + return err + } + + if err := tx.Exec("ALTER TABLE subscriptions ADD COLUMN ids_string TEXT").Error; err != nil { + return err + } + if err := tx.Exec("ALTER TABLE subscriptions ADD COLUMN kinds_string TEXT").Error; err != nil { + return err + } + if err := tx.Exec("ALTER TABLE subscriptions ADD COLUMN authors_string TEXT").Error; err != nil { + return err + } + if err := tx.Exec("ALTER TABLE subscriptions ADD COLUMN tags_string TEXT").Error; err != nil { + return err + } + + if err := tx.Exec("UPDATE subscriptions SET ids_string = ids_json::text WHERE ids IS NOT NULL").Error; err != nil { + return err + } + if err := tx.Exec("UPDATE subscriptions SET kinds_string = kinds_json::text WHERE kinds IS NOT NULL").Error; err != nil { + return err + } + if err := tx.Exec("UPDATE subscriptions SET authors_string = authors_json::text WHERE authors IS NOT NULL").Error; err != nil { + return err + } + if err := tx.Exec("UPDATE subscriptions SET tags_string = tags_json::text WHERE tags IS NOT NULL").Error; err != nil { + return err + } + + if err := tx.Exec("ALTER TABLE subscriptions DROP COLUMN ids_json").Error; err != nil { + return err + } + if err := tx.Exec("ALTER TABLE subscriptions DROP COLUMN kinds_json").Error; err != nil { + return err + } + if err := tx.Exec("ALTER TABLE subscriptions DROP COLUMN authors_json").Error; err != nil { + return err + } + if err := tx.Exec("ALTER TABLE subscriptions DROP COLUMN tags_json").Error; err != nil { + return err + } + + return nil + }, +} diff --git a/migrations/migrate.go b/migrations/migrate.go index f64863a..ea1f3f8 100644 --- a/migrations/migrate.go +++ b/migrations/migrate.go @@ -13,6 +13,7 @@ func Migrate(db *gorm.DB) error { _202404031539_add_indexes, _202407171220_add_response_received_at_to_request_events, _202411071013_add_push_token_and_is_ios_to_subscriptions, + _202411131742_update_subscriptions_jsonb, }) return m.Migrate() From d71df159ad7a856c04c95192b5603964e29a7d8b Mon Sep 17 00:00:00 2001 From: im-adithya Date: Thu, 19 Dec 2024 22:48:40 +0530 Subject: [PATCH 7/7] chore: change name to handleSubscribedEventForPushNotification --- internal/nostr/nostr.go | 2 +- internal/nostr/push.go | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/internal/nostr/nostr.go b/internal/nostr/nostr.go index 499ab03..a7eed77 100644 --- a/internal/nostr/nostr.go +++ b/internal/nostr/nostr.go @@ -149,7 +149,7 @@ func NewService(ctx context.Context) (*Service, error) { subscription := sub handleEvent := svc.handleSubscribedEvent if sub.PushToken != "" { - handleEvent = svc.handlePushNotification + handleEvent = svc.handleSubscribedEventForPushNotification } go svc.startSubscription(svc.Ctx, &subscription, nil, handleEvent) } diff --git a/internal/nostr/push.go b/internal/nostr/push.go index 5407aa4..1439f90 100644 --- a/internal/nostr/push.go +++ b/internal/nostr/push.go @@ -107,7 +107,7 @@ func (svc *Service) NIP47PushNotificationHandler(c echo.Context) error { }) } - go svc.startSubscription(svc.Ctx, &subscription, nil, svc.handlePushNotification) + go svc.startSubscription(svc.Ctx, &subscription, nil, svc.handleSubscribedEventForPushNotification) return c.JSON(http.StatusOK, PushSubscriptionResponse{ SubscriptionId: subscription.Uuid, @@ -117,7 +117,7 @@ func (svc *Service) NIP47PushNotificationHandler(c echo.Context) error { }) } -func (svc *Service) handlePushNotification(event *nostr.Event, subscription *Subscription) { +func (svc *Service) handleSubscribedEventForPushNotification(event *nostr.Event, subscription *Subscription) { svc.Logger.WithFields(logrus.Fields{ "event_id": event.ID, "event_kind": event.Kind,