From b1923cab4de5c7206cc56ee96ce07163249fc348 Mon Sep 17 00:00:00 2001 From: Samuel Newman Date: Fri, 22 May 2026 16:43:02 +0300 Subject: [PATCH] Fix group chat push notifications rendering as direct messages on iOS iOS classifies Communication Notifications as either MessagingDirect or MessagingGroup based on recipient count on the INSendMessageIntent. Our push payload omits the recipient list, so iOS sees zero recipients and falls back to MessagingDirect, ignoring speakableGroupName. Use INSendMessageIntentDonationMetadata.recipientCount with the new convoMemberCount field from the chat service to tell iOS the conversation has multiple participants. Apple documents this as the supported escape hatch when the full recipient list is too large to ship. Co-Authored-By: Claude Opus 4.7 (1M context) --- modules/BlueskyNSE/NotificationService.swift | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/modules/BlueskyNSE/NotificationService.swift b/modules/BlueskyNSE/NotificationService.swift index 18b63b1606..46e9b85740 100644 --- a/modules/BlueskyNSE/NotificationService.swift +++ b/modules/BlueskyNSE/NotificationService.swift @@ -120,6 +120,19 @@ class NotificationService: UNNotificationServiceExtension { attachments: nil ) + // The push payload omits the full recipient list for group convos. Without + // any signal of multiple recipients, iOS classifies the notification as + // `MessagingDirect` and ignores `speakableGroupName`. Setting + // `recipientCount` on the donation metadata is Apple's documented escape + // hatch for this case, and overrides the (zero-length) recipients array. + if userInfo["convoKind"] as? String == "group", + let convoMemberCount = userInfo["convoMemberCount"] as? Int, + convoMemberCount > 0 { + let metadata = INSendMessageIntentDonationMetadata() + metadata.recipientCount = convoMemberCount + intent.donationMetadata = metadata + } + // For group convos, attach the composite group avatar (rendered by the // ogcard service) to the `speakableGroupName` parameter so iOS shows it // alongside the sender on the Communication Notification.