From f157b83e651259402c122d443b96536897fe3c41 Mon Sep 17 00:00:00 2001 From: Shawn Jackson Date: Sat, 8 Nov 2025 22:07:57 -0800 Subject: [PATCH 1/3] RE1-T88 Looking at using FCM to forward APNS messages with Novu --- .../NovuProvider.cs | 56 +++++++++++++++---- 1 file changed, 45 insertions(+), 11 deletions(-) diff --git a/Providers/Resgrid.Providers.Messaging/NovuProvider.cs b/Providers/Resgrid.Providers.Messaging/NovuProvider.cs index 6ef9c843..133fed93 100644 --- a/Providers/Resgrid.Providers.Messaging/NovuProvider.cs +++ b/Providers/Resgrid.Providers.Messaging/NovuProvider.cs @@ -132,7 +132,7 @@ private async Task UpdateSubscriberFcm(string id, string token, string fcm } } - private async Task UpdateSubscriberApns(string id, string token, string apnsId) + private async Task UpdateSubscriberApns(string id, string token, string apnsId, string fcmId) { try { @@ -144,16 +144,36 @@ private async Task UpdateSubscriberApns(string id, string token, string ap request.Headers.Add("idempotency-key", Guid.NewGuid().ToString()); request.Headers.Add("Authorization", $"ApiKey {ChatConfig.NovuSecretKey}"); - var payload = new + string jsonContent = string.Empty; + if (!string.IsNullOrWhiteSpace(apnsId)) { - providerId = "apns", - credentials = new + var payload = new { - deviceTokens = new string[] { token } - }, - integrationIdentifier = apnsId - }; - string jsonContent = JsonConvert.SerializeObject(payload, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + providerId = "apns", + credentials = new + { + deviceTokens = new string[] { token } + }, + integrationIdentifier = apnsId + }; + + jsonContent = JsonConvert.SerializeObject(payload, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + } + else if (!string.IsNullOrWhiteSpace(fcmId)) + { + var payload = new + { + providerId = "fcm", + credentials = new + { + deviceTokens = new string[] { token } + }, + integrationIdentifier = fcmId + }; + + jsonContent = JsonConvert.SerializeObject(payload, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + } + request.Content = new StringContent(jsonContent, Encoding.UTF8, "application/json"); HttpResponseMessage response = await client.SendAsync(request); @@ -197,7 +217,7 @@ public async Task UpdateUserSubscriberFcm(string userId, string code, stri public async Task UpdateUserSubscriberApns(string userId, string code, string token) { - return await UpdateSubscriberApns($"{code}_User_{userId}", token, ChatConfig.NovuResponderApnsProviderId); + return await UpdateSubscriberApns($"{code}_User_{userId}", token, ChatConfig.NovuResponderApnsProviderId, null); } public async Task UpdateUnitSubscriberFcm(int unitId, string code, string token) @@ -207,7 +227,8 @@ public async Task UpdateUnitSubscriberFcm(int unitId, string code, string public async Task UpdateUnitSubscriberApns(int unitId, string code, string token) { - return await UpdateSubscriberApns($"{code}_Unit_{unitId}", token, ChatConfig.NovuUnitApnsProviderId); + //return await UpdateSubscriberApns($"{code}_Unit_{unitId}", token, ChatConfig.NovuUnitApnsProviderId); + return await UpdateSubscriberApns($"{code}_Unit_{unitId}", token, null, ChatConfig.NovuUnitFcmProviderId); } private async Task SendNotification(string title, string body, string recipientId, string eventCode, @@ -259,6 +280,19 @@ private async Task SendNotification(string title, string body, string reci type = type, } }, + apns = new + { + badge = count, + sound = new + { + name = sound, + critical = channelName == "calls" ? 1 : 0, + volume = 1.0f + }, + type = type, + category = channelName, + eventCode = eventCode, + }, }, apns = new Dictionary { From 2292217c09c484f979d610eb4d8e4ec670ffb7a8 Mon Sep 17 00:00:00 2001 From: Shawn Jackson Date: Sat, 8 Nov 2025 22:26:09 -0800 Subject: [PATCH 2/3] RE1-T88 PR#264 fix --- Providers/Resgrid.Providers.Messaging/NovuProvider.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/Providers/Resgrid.Providers.Messaging/NovuProvider.cs b/Providers/Resgrid.Providers.Messaging/NovuProvider.cs index 133fed93..dbd9b90f 100644 --- a/Providers/Resgrid.Providers.Messaging/NovuProvider.cs +++ b/Providers/Resgrid.Providers.Messaging/NovuProvider.cs @@ -174,6 +174,10 @@ private async Task UpdateSubscriberApns(string id, string token, string ap jsonContent = JsonConvert.SerializeObject(payload, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); } + if (string.IsNullOrWhiteSpace(jsonContent)) + { + return false; + } request.Content = new StringContent(jsonContent, Encoding.UTF8, "application/json"); HttpResponseMessage response = await client.SendAsync(request); From 63060578a3a13da01f566decd6ddce6ec8574d06 Mon Sep 17 00:00:00 2001 From: Shawn Jackson Date: Sat, 8 Nov 2025 22:44:25 -0800 Subject: [PATCH 3/3] RE1-T88 PR#264 fix --- .../NovuProvider.cs | 41 +++++++++++++------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/Providers/Resgrid.Providers.Messaging/NovuProvider.cs b/Providers/Resgrid.Providers.Messaging/NovuProvider.cs index dbd9b90f..c128e115 100644 --- a/Providers/Resgrid.Providers.Messaging/NovuProvider.cs +++ b/Providers/Resgrid.Providers.Messaging/NovuProvider.cs @@ -7,6 +7,7 @@ using Resgrid.Model; using Resgrid.Model.Providers; using Resgrid.Providers.Bus.Models; +using SharpCompress.Common; using System.Text; @@ -296,22 +297,38 @@ private async Task SendNotification(string title, string body, string reci type = type, category = channelName, eventCode = eventCode, + payload = new + { + aps = new + { + badge = count, + sound = new + { + name = sound, + critical = channelName == "calls" ? 1 : 0, + volume = 1.0f + }, + category = channelName, + eventCode = eventCode, + customType = type + }, + }, }, }, - apns = new Dictionary - { - ["badge"] = count, - ["sound"] = new + apns = new Dictionary { - name = sound, - critical = channelName == "calls" ? 1 : 0, - volume = 1.0f + ["badge"] = count, + ["sound"] = new + { + name = sound, + critical = channelName == "calls" ? 1 : 0, + volume = 1.0f + }, + ["type"] = type, + ["category"] = channelName, + ["eventCode"] = eventCode, + ["gcm.message_id"] = "123" }, - ["type"] = type, - ["category"] = channelName, - ["eventCode"] = eventCode, - ["gcm.message_id"] = "123" - }, }, to = new[]{ new {