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 }