eleven / messenger Public

server: make the admin test push hit native (APNs/relay) too (#172)

sendTestPush was Web Push only, so the admin "Send test notification" button
never exercised APNs — the transport that goes through the push relay. Fan out
over apnsFanOut as well (no exclusions, always-show), so one tap tests both
browsers and native iOS. The dummy thread/blob can't be decrypted, so the NSE
ships the placeholder "New message" banner — the connectivity signal a test
wants. No-op on instances without APNs/relay configured.
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Paul Campbell cb039560a5053f6886ab98823ec681aedac35c3e parent 6c73c3b
1 file changed, +9 −1
  • push.go +9 −1
diff --git a/push.go b/push.go
index 64c66b8..e18b6be 100644
--- a/push.go
+++ b/push.go
@@ -180,9 +180,17 @@ func (s *Server) pushNewMessage(blob, threadID, senderToken string) {
// sendTestPush delivers a generic "it works" notification to every subscriber,
// bypassing the message flow (and ignoring active state, so it always lands).
+// It covers BOTH transports: Web Push (browsers) and APNs (native iOS, via the
+// relay when configured). The APNs side carries a dummy thread/blob the NSE
+// can't decrypt, so the phone shows the placeholder "New message" banner (see
+// ios/LChatNSE) — which is exactly the "push reached this device" signal a test
+// wants. No exclusions (exceptToken="", recipients=nil) and skipActive=false, so
+// it always lands, on every registered device including the admin's own.
func (s *Server) sendTestPush() int {
payload, _ := json.Marshal(map[string]bool{"test": true})
- return s.sendToRecipients(payload, "test", "", false, nil)
+ sent := s.sendToRecipients(payload, "test", "", false, nil)
+ sent += s.apnsFanOut("test", "test", "", false, nil) // no-op unless APNs/relay configured
+ return sent
}
// maxPushConcurrency bounds simultaneous sends so a large group doesn't open