diff --git a/Core/Resgrid.Config/ChatConfig.cs b/Core/Resgrid.Config/ChatConfig.cs index 91b12b90..6a3563af 100644 --- a/Core/Resgrid.Config/ChatConfig.cs +++ b/Core/Resgrid.Config/ChatConfig.cs @@ -11,7 +11,11 @@ public static class ChatConfig public static string NovuSecretKey = ""; public static string NovuUnitFcmProviderId = ""; + public static string NovuUnitApnsProviderId = ""; public static string NovuResponderFcmProviderId = ""; public static string NovuDispatchUnitWorkflowId = "unit-dispatch"; + public static string NovuDispatchUserWorkflowId = "user-dispatch"; + public static string NovuMessageUserWorkflowId = "user-message"; + public static string NovuNotificationUserWorkflowId = "user-notification"; } } diff --git a/Core/Resgrid.Model/Messages/StandardPushMessage.cs b/Core/Resgrid.Model/Messages/StandardPushMessage.cs index c4bc177f..4df13e25 100644 --- a/Core/Resgrid.Model/Messages/StandardPushMessage.cs +++ b/Core/Resgrid.Model/Messages/StandardPushMessage.cs @@ -6,5 +6,6 @@ public class StandardPushMessage public string Title { get; set; } public string SubTitle { get; set; } public string Id { get; set; } + public string DepartmentCode { get; set; } } } diff --git a/Core/Resgrid.Model/Platforms.cs b/Core/Resgrid.Model/Platforms.cs index 805326d3..abeb0d6c 100644 --- a/Core/Resgrid.Model/Platforms.cs +++ b/Core/Resgrid.Model/Platforms.cs @@ -2,15 +2,16 @@ { public enum Platforms { - WindowsPhone7 = 0, - iPhone = 1, - iPad = 2, - Android = 3, + None = 0, + iOS = 1, + Android = 2, + Web = 3, Windows8 = 4, - WindowsPhone8 = 5, - Blackberry = 6, - UnitIOS = 7, - UnitAndroid = 8, - UnitWin = 9 + //Windows8 = 4, + //WindowsPhone8 = 5, + //Blackberry = 6, + //UnitIOS = 7, + //UnitAndroid = 8, + //UnitWin = 9 } -} \ No newline at end of file +} diff --git a/Core/Resgrid.Model/Providers/Models/INovuProvider.cs b/Core/Resgrid.Model/Providers/Models/INovuProvider.cs index 71772a19..452c120f 100644 --- a/Core/Resgrid.Model/Providers/Models/INovuProvider.cs +++ b/Core/Resgrid.Model/Providers/Models/INovuProvider.cs @@ -2,15 +2,96 @@ namespace Resgrid.Model.Providers; +/// +/// Defines operations for managing Novu notification subscribers and sending notifications. +/// public interface INovuProvider { + /// + /// Creates a Novu subscriber for a user. + /// + /// The unique identifier of the user. + /// The Novu integration code or API key. + /// The department the user belongs to. + /// The user's email address. + /// The user's first name. + /// The user's last name. + /// True if the subscriber was created successfully; otherwise, false. Task CreateUserSubscriber(string userId, string code, int departmentId, string email, string firstName, string lastName); + + /// + /// Creates a Novu subscriber for a unit (device or group). + /// + /// The unique identifier of the unit. + /// The Novu integration code or API key. + /// The department the unit belongs to. + /// The name of the unit. + /// The device identifier associated with the unit. + /// True if the subscriber was created successfully; otherwise, false. Task CreateUnitSubscriber(int unitId, string code, int departmentId, string unitName, string deviceId); + + /// + /// Updates the Firebase Cloud Messaging (FCM) token for a user subscriber. + /// + /// The unique identifier of the user. + /// The Novu integration code or API key. + /// The FCM token to associate with the user. + /// True if the token was updated successfully; otherwise, false. Task UpdateUserSubscriberFcm(string userId, string code, string token); + + /// + /// Updates the Firebase Cloud Messaging (FCM) token for a unit subscriber. + /// + /// The unique identifier of the unit. + /// The Novu integration code or API key. + /// The FCM token to associate with the unit. + /// True if the token was updated successfully; otherwise, false. Task UpdateUnitSubscriberFcm(int unitId, string code, string token); + /// + /// Updates the Apple Push Notification Service (APNS) token for a unit subscriber. + /// + /// The unique identifier of the unit. + /// The Novu integration code or API key. + /// The APNS token to associate with the unit. + /// True if the token was updated successfully; otherwise, false. + Task UpdateUnitSubscriberApns(int unitId, string code, string token); + + /// + /// Updates the Apple Push Notification Service (APNS) token for a user subscriber. + /// + /// The unique identifier of the user. + /// The Novu integration code or API key. + /// The APNS token to associate with the user. + /// True if the token was updated successfully; otherwise, false. + Task UpdateUserSubscriberApns(string userId, string code, string token); + + /// + /// Sends a dispatch notification to a unit. + /// + /// The notification title. + /// The notification body content. + /// The unique identifier of the unit to notify. + /// The department code. + /// The event code associated with the dispatch. + /// The type of notification. + /// Whether to enable custom notification sounds. + /// The badge or notification count. + /// The color code for the notification. + /// True if the notification was sent successfully; otherwise, false. Task SendUnitDispatch(string title, string body, int unitId, string depCode, string eventCode, string type, bool enableCustomSounds, int count, string color); + /// + /// Deletes a notification message by its identifier. + /// + /// The unique identifier of the message to delete. + /// True if the message was deleted successfully; otherwise, false. Task DeleteMessage(string messageId); + + Task SendUserDispatch(string title, string body, string userId, string depCode, string eventCode, string type, bool enableCustomSounds, int count, string color); + + Task SendUserMessage(string title, string body, string userId, string depCode, string eventCode, string type); + + Task SendUserNotification(string title, string body, string userId, string depCode, string eventCode, string type); } diff --git a/Core/Resgrid.Model/PushUri.cs b/Core/Resgrid.Model/PushUri.cs index ef89bf5f..d0a709cf 100644 --- a/Core/Resgrid.Model/PushUri.cs +++ b/Core/Resgrid.Model/PushUri.cs @@ -45,8 +45,8 @@ public string PushLocation { _pushLocation = value; - if (((Platforms)PlatformType) == Platforms.Windows8 || ((Platforms)PlatformType) == Platforms.WindowsPhone7 || ((Platforms)PlatformType) == Platforms.WindowsPhone8 || ((Platforms)PlatformType) == Platforms.UnitWin) - ChannelUri = new Uri(_pushLocation, UriKind.Absolute); + //if (((Platforms)PlatformType) == Platforms.Windows8 || ((Platforms)PlatformType) == Platforms.WindowsPhone7 || ((Platforms)PlatformType) == Platforms.WindowsPhone8 || ((Platforms)PlatformType) == Platforms.UnitWin) + // ChannelUri = new Uri(_pushLocation, UriKind.Absolute); } } } diff --git a/Core/Resgrid.Model/Services/ICommunicationService.cs b/Core/Resgrid.Model/Services/ICommunicationService.cs index 08b36cf5..801c60b7 100644 --- a/Core/Resgrid.Model/Services/ICommunicationService.cs +++ b/Core/Resgrid.Model/Services/ICommunicationService.cs @@ -55,7 +55,7 @@ Task SendUnitCallAsync(Call call, CallDispatchUnit dispatch, string depart /// The title. /// The profile. /// Task<System.Boolean>. - Task SendNotificationAsync(string userId, int departmentId, string message, string departmentNumber, + Task SendNotificationAsync(string userId, int departmentId, string message, string departmentNumber, Department department, string title = "Notification", UserProfile profile = null); /// diff --git a/Core/Resgrid.Services/CalendarService.cs b/Core/Resgrid.Services/CalendarService.cs index 9797d5ac..568e0bfd 100644 --- a/Core/Resgrid.Services/CalendarService.cs +++ b/Core/Resgrid.Services/CalendarService.cs @@ -487,9 +487,9 @@ public async Task NotifyNewCalendarItemAsync(CalendarItem calendarItem) foreach (var member in group.Members) { if (profiles.ContainsKey(member.UserId)) - await _communicationService.SendNotificationAsync(member.UserId, calendarItem.DepartmentId, message, departmentNumber, title, profiles[member.UserId]); + await _communicationService.SendNotificationAsync(member.UserId, calendarItem.DepartmentId, message, departmentNumber, department, title, profiles[member.UserId]); else - await _communicationService.SendNotificationAsync(member.UserId, calendarItem.DepartmentId, message, departmentNumber, title, null); + await _communicationService.SendNotificationAsync(member.UserId, calendarItem.DepartmentId, message, departmentNumber, department, title, null); } } } diff --git a/Core/Resgrid.Services/CommunicationService.cs b/Core/Resgrid.Services/CommunicationService.cs index ddb85467..1424c64d 100644 --- a/Core/Resgrid.Services/CommunicationService.cs +++ b/Core/Resgrid.Services/CommunicationService.cs @@ -290,7 +290,7 @@ public async Task SendUnitCallAsync(Call call, CallDispatchUnit dispatch, return true; } - public async Task SendNotificationAsync(string userId, int departmentId, string message, string departmentNumber, string title = "Notification", UserProfile profile = null) + public async Task SendNotificationAsync(string userId, int departmentId, string message, string departmentNumber, Department department, string title = "Notification", UserProfile profile = null) { if (Config.SystemBehaviorConfig.DoNotBroadcast && !Config.SystemBehaviorConfig.BypassDoNotBroadcastDepartments.Contains(departmentId)) return false; @@ -319,6 +319,7 @@ public async Task SendNotificationAsync(string userId, int departmentId, s var spm = new StandardPushMessage(); spm.Title = "Notification"; spm.SubTitle = $"{title} {message}"; + spm.DepartmentCode = department?.Code; try { diff --git a/Core/Resgrid.Services/PushService.cs b/Core/Resgrid.Services/PushService.cs index e3dbb0e4..e74684d0 100644 --- a/Core/Resgrid.Services/PushService.cs +++ b/Core/Resgrid.Services/PushService.cs @@ -1,14 +1,16 @@ -using System; -using System.IO; -using System.Linq; -using System.Reflection; -using System.Collections.Generic; -using System.Threading.Tasks; +using DnsClient; +using FirebaseAdmin.Messaging; using Resgrid.Model; using Resgrid.Model.Messages; using Resgrid.Model.Providers; using Resgrid.Model.Services; -using DnsClient; +using System; +using System.Collections.Generic; +using System.Drawing; +using System.IO; +using System.Linq; +using System.Reflection; +using System.Threading.Tasks; namespace Resgrid.Services { @@ -36,31 +38,18 @@ public async Task Register(PushUri pushUri) if (pushUri == null || String.IsNullOrWhiteSpace(pushUri.DeviceId)) return false; - string deviceId = pushUri.DeviceId.GetHashCode().ToString(); + var code = pushUri.PushLocation; - // We just store the full Device Id in the PushUri object, the hashed version is for Azure - //var existingPushUri = _pushUriService.GetPushUriByPlatformDeviceId((Platforms)pushUri.PlatformType, pushUri.DeviceId); - List usersDevices = null; + // 1) iOS -> APNS + if (pushUri.PlatformType == (int)Platforms.iOS) + return await _novuProvider.UpdateUserSubscriberApns(pushUri.UserId, code, pushUri.DeviceId); - try - { - usersDevices = await _notificationProvider.GetRegistrationsByUserId(pushUri.UserId); - - if (usersDevices == null || !usersDevices.Any(x => x.Tags.Contains(deviceId))) - await _notificationProvider.RegisterPush(pushUri); - } - catch (TimeoutException) - { } - catch (TaskCanceledException) - { } + // 2) Android -> FCM + if (pushUri.PlatformType == (int)Platforms.Android) + return await _novuProvider.UpdateUserSubscriberFcm(pushUri.UserId, code, pushUri.DeviceId); - //if (existingPushUri == null) - // pushUri = _pushUriService.SavePushUri(pushUri); - - //if (usersDevices == null || !usersDevices.Any(x => x.Tags.Contains(deviceId))) - // await _notificationProvider.RegisterPush(pushUri); - - return true; + // 3) TODO: Web Push (other platforms) + return false; } public async Task UnRegister(PushUri pushUri) @@ -72,29 +61,22 @@ public async Task UnRegister(PushUri pushUri) public async Task RegisterUnit(PushUri pushUri) { - //string deviceId = pushUri.DeviceId; - List usersDevices = null; - - //try - //{ - // usersDevices = await _unitNotificationProvider.GetRegistrationsByUUID(pushUri.PushLocation); - //} - //catch (TimeoutException) - //{ } + if (pushUri == null || !pushUri.UnitId.HasValue || string.IsNullOrWhiteSpace(pushUri.PushLocation)) + return false; - if (pushUri.UnitId.HasValue && !string.IsNullOrWhiteSpace(pushUri.PushLocation)) - await _novuProvider.UpdateUnitSubscriberFcm(pushUri.UnitId.Value, pushUri.PushLocation, pushUri.DeviceId); + var unitId = pushUri.UnitId.Value; + var code = pushUri.PushLocation; + // 1) iOS -> APNS + if (pushUri.PlatformType == (int)Platforms.iOS) + return await _novuProvider.UpdateUnitSubscriberApns(unitId, code, pushUri.DeviceId); - //if (usersDevices == null || !usersDevices.Any(x => x.Tags.Contains(string.Format("unitId:{0}", pushUri.UnitId.ToString())))) - // await _unitNotificationProvider.RegisterPush(pushUri); - //else - //{ - // await _unitNotificationProvider.UnRegisterPushByUUID(pushUri.PushLocation); - // await _unitNotificationProvider.RegisterPush(pushUri); - //} + // 2) Android -> FCM + if (pushUri.PlatformType == (int)Platforms.Android) + return await _novuProvider.UpdateUnitSubscriberFcm(unitId, code, pushUri.DeviceId); - return true; + // 3) TODO: Web Push (other platforms) + return false; } public async Task UnRegisterUnit(PushUri pushUri) @@ -118,7 +100,25 @@ public async Task PushMessage(StandardPushMessage message, string userId, profile = await _userProfileService.GetProfileByUserIdAsync(userId); if (profile != null && profile.SendMessagePush) - await _notificationProvider.SendAllNotifications(message.Title, message.SubTitle, userId, string.Format("M{0}", message.MessageId), ((int)PushSoundTypes.Message).ToString(), true, 1, "#000000"); + { + try + { + await _notificationProvider.SendAllNotifications(message.Title, message.SubTitle, userId, string.Format("M{0}", message.MessageId), ((int)PushSoundTypes.Message).ToString(), true, 1, "#000000"); + } + catch (Exception ex) + { + Framework.Logging.LogException(ex); + } + + try + { + await _novuProvider.SendUserMessage(message.Title, message.SubTitle, userId, message.DepartmentCode, string.Format("M{0}", message.MessageId), null); + } + catch (Exception ex) + { + Framework.Logging.LogException(ex); + } + } return true; } @@ -132,8 +132,24 @@ public async Task PushNotification(StandardPushMessage message, string use profile = await _userProfileService.GetProfileByUserIdAsync(userId); if (profile != null && profile.SendNotificationPush) - await _notificationProvider.SendAllNotifications(message.Title, message.SubTitle, userId, string.Format("N{0}", message.MessageId), ((int)PushSoundTypes.Notifiation).ToString(), true, 1, "#000000"); - + { + try + { + await _notificationProvider.SendAllNotifications(message.Title, message.SubTitle, userId, string.Format("N{0}", message.MessageId), ((int)PushSoundTypes.Notifiation).ToString(), true, 1, "#000000"); + } + catch (Exception ex) + { + Framework.Logging.LogException(ex); + } + try + { + await _novuProvider.SendUserMessage(message.Title, message.SubTitle, userId, message.DepartmentCode, string.Format("N{0}", message.MessageId), null); + } + catch (Exception ex) + { + Framework.Logging.LogException(ex); + } + } return true; } @@ -167,7 +183,26 @@ public async Task PushCall(StandardPushCall call, string userId, UserProfi color = priority.Color; if (profile != null && profile.SendPush) - await _notificationProvider.SendAllNotifications(call.SubTitle, call.Title, userId, string.Format("C{0}", call.CallId), ConvertCallPriorityToSound((int)call.Priority, priority), true, call.ActiveCallCount, color); + { + // Legacy Push Notifications (Azure) + try + { + await _notificationProvider.SendAllNotifications(call.SubTitle, call.Title, userId, string.Format("C{0}", call.CallId), ConvertCallPriorityToSound((int)call.Priority, priority), true, call.ActiveCallCount, color); + } + catch (Exception ex) + { + Framework.Logging.LogException(ex); + } + + try + { + await _novuProvider.SendUserDispatch(call.Title, call.SubTitle, userId, call.DepartmentCode, string.Format("C{0}", call.CallId), ConvertCallPriorityToSound((int)call.Priority, priority), true, call.ActiveCallCount, color); + } + catch (Exception ex) + { + Framework.Logging.LogException(ex); + } + } return true; } @@ -184,15 +219,6 @@ public async Task PushCallUnit(StandardPushCall call, int unitId, Departme if (priority != null) color = priority.Color; - try - { - await _unitNotificationProvider.SendAllNotifications(call.SubTitle, call.Title, unitId, string.Format("C{0}", call.CallId), ConvertCallPriorityToSound((int)call.Priority, priority), true, call.ActiveCallCount, color); - } - catch (Exception ex) - { - Framework.Logging.LogException(ex); - } - try { await _novuProvider.SendUnitDispatch(call.Title, call.SubTitle, unitId, call.DepartmentCode, string.Format("C{0}", call.CallId), ConvertCallPriorityToSound((int)call.Priority, priority), true, call.ActiveCallCount, color); diff --git a/Core/Resgrid.Services/TrainingService.cs b/Core/Resgrid.Services/TrainingService.cs index d94f7448..69ed2b3b 100644 --- a/Core/Resgrid.Services/TrainingService.cs +++ b/Core/Resgrid.Services/TrainingService.cs @@ -180,7 +180,9 @@ public async Task SendInitialTrainingNoticeAsync(Training training) else message = string.Format("Training ({0}) assigned to you", training.Name); - await _communicationService.SendNotificationAsync(user.UserId, training.DepartmentId, message, "New Training"); + var department = await _departmentService.GetDepartmentByIdAsync(training.DepartmentId); + + await _communicationService.SendNotificationAsync(user.UserId, training.DepartmentId, message, "New Training", department); } return true; diff --git a/Providers/Resgrid.Providers.Bus/NotificationProvider.cs b/Providers/Resgrid.Providers.Bus/NotificationProvider.cs index 370a4a07..21711fe4 100644 --- a/Providers/Resgrid.Providers.Bus/NotificationProvider.cs +++ b/Providers/Resgrid.Providers.Bus/NotificationProvider.cs @@ -57,47 +57,8 @@ public async Task RegisterPush(PushUri pushUri) } } - if (pushUri.PlatformType == (int)Platforms.WindowsPhone7 || pushUri.PlatformType == (int)Platforms.WindowsPhone8) - { - if (!String.IsNullOrWhiteSpace(pushUri.PushLocation)) - { - try - { - var result = await hubClient.CreateMpnsNativeRegistrationAsync(pushUri.PushLocation, tagsWithHashedDeviceId.ToArray()); - } - catch (Exception ex) - { - //Framework.Logging.LogException(ex); - } - //catch (ArgumentException ex) - //{ - // Framework.Logging.LogException(ex, - // string.Format("Device Information: {0} {1} {2} {3}", tagsWithHashedDeviceId[0], tagsWithHashedDeviceId[1], - // tagsWithHashedDeviceId[2], tagsWithHashedDeviceId[3])); - //} - } - } - else if (pushUri.PlatformType == (int)Platforms.Windows8) - { - if (!String.IsNullOrWhiteSpace(pushUri.PushLocation)) - { - try - { - var result = await hubClient.CreateWindowsNativeRegistrationAsync(pushUri.PushLocation, tagsWithHashedDeviceId.ToArray()); - } - catch (Exception ex) - { - //Framework.Logging.LogException(ex); - } - //catch (ArgumentException ex) - //{ - // Framework.Logging.LogException(ex, - // string.Format("Device Information: {0} {1} {2} {3}", tagsWithHashedDeviceId[0], tagsWithHashedDeviceId[1], - // tagsWithHashedDeviceId[2], tagsWithHashedDeviceId[3])); - //} - } - } - else if (pushUri.PlatformType == (int)Platforms.Android) + + else if (pushUri.PlatformType == 3) //(int)Platforms.Android) { try { @@ -115,7 +76,7 @@ public async Task RegisterPush(PushUri pushUri) // tagsWithHashedDeviceId[2], tagsWithHashedDeviceId[3])); //} } - else if (pushUri.PlatformType == (int)Platforms.iPad || pushUri.PlatformType == (int)Platforms.iPhone) + else if (pushUri.PlatformType == 1 || pushUri.PlatformType == 2) //(int)Platforms.iPad || pushUri.PlatformType == (int)Platforms.iPhone) { try { @@ -143,21 +104,13 @@ public async Task UnRegisterPush(PushUri pushUri) foreach (var registration in registrations) { - if (pushUri.PlatformType == (int)Platforms.Windows8 || - pushUri.PlatformType == (int)Platforms.WindowsPhone7 || - pushUri.PlatformType == (int)Platforms.WindowsPhone8) - { - var winReg = registration as WindowsRegistrationDescription; - if (winReg != null && winReg.ChannelUri == pushUri.ChannelUri) - await hubClient.DeleteRegistrationAsync(registration); - } - else if (pushUri.PlatformType == (int)Platforms.Android) + if (pushUri.PlatformType == 3)// (int)Platforms.Android) { var androidReg = registration as GcmRegistrationDescription; if (androidReg != null && androidReg.GcmRegistrationId == pushUri.DeviceId) await hubClient.DeleteRegistrationAsync(registration); } - else if (pushUri.PlatformType == (int)Platforms.iPad || pushUri.PlatformType == (int)Platforms.iPhone) + else if (pushUri.PlatformType == 1 || pushUri.PlatformType == 2) //(int)Platforms.iPad || pushUri.PlatformType == (int)Platforms.iPhone) { var iosReg = registration as AppleRegistrationDescription; if (iosReg != null && iosReg.DeviceToken == pushUri.DeviceId) @@ -363,7 +316,7 @@ public async Task SendAppleNotification(string title, category = category, sound = new ApnsSound { - name = GetSoundFileNameFromType(Platforms.iPhone, type), + name = GetSoundFileNameFromType(Platforms.iOS, type), critical = category == "calls" ? 1 : 0, volume = 1.0f } @@ -419,7 +372,7 @@ private string GetSoundFileNameFromType(Platforms platform, string type) { if (type == ((int)PushSoundTypes.CallEmergency).ToString()) { - if (platform == Platforms.iPhone) + if (platform == Platforms.iOS) return "callemergency.caf"; return "callemergency.wav"; @@ -427,42 +380,42 @@ private string GetSoundFileNameFromType(Platforms platform, string type) else if (type == ((int)PushSoundTypes.CallHigh).ToString()) { - if (platform == Platforms.iPhone) + if (platform == Platforms.iOS) return "callhigh.caf"; return "callhigh.mp3"; } else if (type == ((int)PushSoundTypes.CallMedium).ToString()) { - if (platform == Platforms.iPhone) + if (platform == Platforms.iOS) return "callmedium.caf"; return "callmedium.mp3"; } else if (type == ((int)PushSoundTypes.CallLow).ToString()) { - if (platform == Platforms.iPhone) + if (platform == Platforms.iOS) return "calllow.caf"; return "calllow.mp3"; } else if (type == ((int)PushSoundTypes.Notifiation).ToString()) { - if (platform == Platforms.iPhone) + if (platform == Platforms.iOS) return "notification.caf"; return "notification.mp3"; } else if (type == ((int)PushSoundTypes.Message).ToString()) { - if (platform == Platforms.iPhone) + if (platform == Platforms.iOS) return "message.caf"; return "message.mp3"; } else { - if (platform == Platforms.iPhone) + if (platform == Platforms.iOS) return $"{type}.caf"; return $"{type}.mp3"; diff --git a/Providers/Resgrid.Providers.Bus/UnitNotificationProvider.cs b/Providers/Resgrid.Providers.Bus/UnitNotificationProvider.cs index 3463fd6f..e44de4f8 100644 --- a/Providers/Resgrid.Providers.Bus/UnitNotificationProvider.cs +++ b/Providers/Resgrid.Providers.Bus/UnitNotificationProvider.cs @@ -66,20 +66,7 @@ public async Task RegisterPush(PushUri pushUri) } } - if (pushUri.PlatformType == (int)Platforms.UnitWin) - { - try - { - var result = await hubClient.CreateMpnsNativeRegistrationAsync(pushUri.PushLocation, tagsWithHashedDeviceId.ToArray()); - } - catch (ArgumentException ex) - { - Framework.Logging.LogException(ex, - string.Format("Device Information: {0} {1} {2} {3}", tagsWithHashedDeviceId[0], tagsWithHashedDeviceId[1], - tagsWithHashedDeviceId[2], tagsWithHashedDeviceId[3])); - } - } - else if (pushUri.PlatformType == (int)Platforms.UnitAndroid) + if (pushUri.PlatformType == 8)//(int)Platforms.UnitAndroid) { try { @@ -93,7 +80,7 @@ public async Task RegisterPush(PushUri pushUri) tagsWithHashedDeviceId[2], tagsWithHashedDeviceId[3])); } } - else if (pushUri.PlatformType == (int)Platforms.UnitIOS) + else if (pushUri.PlatformType == 7)//(int)Platforms.UnitIOS) { try { @@ -117,13 +104,13 @@ public async Task UnRegisterPush(PushUri pushUri) foreach (var registration in registrations) { - if (pushUri.PlatformType == (int)Platforms.Android) + if (pushUri.PlatformType == 3 || pushUri.PlatformType == 8)//(int)Platforms.Android) { var androidReg = registration as GcmRegistrationDescription; if (androidReg != null && androidReg.GcmRegistrationId == pushUri.DeviceId) await hubClient.DeleteRegistrationAsync(registration); } - else if (pushUri.PlatformType == (int)Platforms.iPad || pushUri.PlatformType == (int)Platforms.iPhone) + else if (pushUri.PlatformType == 1 || pushUri.PlatformType == 2 || pushUri.PlatformType == 7)//(int)Platforms.iPad || pushUri.PlatformType == (int)Platforms.iPhone) { var iosReg = registration as AppleRegistrationDescription; if (iosReg != null && iosReg.DeviceToken == pushUri.DeviceId) @@ -358,7 +345,7 @@ public async Task SendAppleNotification(string title, category = category, sound = new ApnsSound { - name = GetSoundFileNameFromType(Platforms.iPhone, type, enableCustomSounds), + name = GetSoundFileNameFromType(Platforms.iOS, type, enableCustomSounds), critical = category == "calls" ? 1 : 0, volume = 1.0f } @@ -414,7 +401,7 @@ private string GetSoundFileNameFromType(Platforms platform, string type, bool en { if (!enableCustomSounds) { - if (platform == Platforms.iPhone) + if (platform == Platforms.iOS) return "beep.caf"; return "beep.mp3"; @@ -422,7 +409,7 @@ private string GetSoundFileNameFromType(Platforms platform, string type, bool en if (type == ((int)PushSoundTypes.CallEmergency).ToString()) { - if (platform == Platforms.iPhone) + if (platform == Platforms.iOS) return "callemergency.caf"; return "callemergency.wav"; @@ -430,42 +417,42 @@ private string GetSoundFileNameFromType(Platforms platform, string type, bool en else if (type == ((int)PushSoundTypes.CallHigh).ToString()) { - if (platform == Platforms.iPhone) + if (platform == Platforms.iOS) return "callhigh.caf"; return "callhigh.mp3"; } else if (type == ((int)PushSoundTypes.CallMedium).ToString()) { - if (platform == Platforms.iPhone) + if (platform == Platforms.iOS) return "callmedium.caf"; return "callmedium.mp3"; } else if (type == ((int)PushSoundTypes.CallLow).ToString()) { - if (platform == Platforms.iPhone) + if (platform == Platforms.iOS) return "calllow.caf"; return "calllow.mp3"; } else if (type == ((int)PushSoundTypes.Notifiation).ToString()) { - if (platform == Platforms.iPhone) + if (platform == Platforms.iOS) return "notification.caf"; return "notification.mp3"; } else if (type == ((int)PushSoundTypes.Message).ToString()) { - if (platform == Platforms.iPhone) + if (platform == Platforms.iOS) return "message.caf"; return "message.mp3"; } else { - if (platform == Platforms.iPhone) + if (platform == Platforms.iOS) return $"{type}.caf"; return $"{type}.mp3"; diff --git a/Providers/Resgrid.Providers.Messaging/NovuProvider.cs b/Providers/Resgrid.Providers.Messaging/NovuProvider.cs index fae5a830..3adbbbd3 100644 --- a/Providers/Resgrid.Providers.Messaging/NovuProvider.cs +++ b/Providers/Resgrid.Providers.Messaging/NovuProvider.cs @@ -21,7 +21,7 @@ private async Task CreateSubscriber(string id, int departmentId, string em { var requestUrl = $"{ChatConfig.NovuBackendUrl}/v2/subscribers"; httpClient.DefaultRequestHeaders.Add("idempotency-key", Guid.NewGuid().ToString()); - httpClient.DefaultRequestHeaders.Add("Authorization", Config.ChatConfig.NovuSecretKey); + httpClient.DefaultRequestHeaders.Add("Authorization", $"ApiKey {ChatConfig.NovuSecretKey}"); var payload = new { @@ -45,7 +45,8 @@ private async Task CreateSubscriber(string id, int departmentId, string em payload.data.Add(item.Key, item.Value); } } - string jsonContent = JsonConvert.SerializeObject(payload); + + string jsonContent = JsonConvert.SerializeObject(payload, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); var content = new StringContent(jsonContent, Encoding.UTF8, "application/json"); @@ -64,6 +65,17 @@ private async Task CreateSubscriber(string id, int departmentId, string em public async Task CreateUserSubscriber(string userId, string code, int departmentId, string email, string firstName, string lastName) { + //var data = new List(); + + //if (!String.IsNullOrWhiteSpace(deviceId)) + //{ + // data.Add(new AdditionalData + // { + // Key = "DeviceId", + // Value = deviceId + // }); + //} + return await CreateSubscriber($"{code}_User_{userId}", departmentId, email, firstName, lastName, null); } @@ -79,6 +91,7 @@ public async Task CreateUnitSubscriber(int unitId, string code, int depart Value = deviceId }); } + return await CreateSubscriber($"{code}_Unit_{unitId}", departmentId, $"{code}_Unit_{unitId}@units.resgrid.net", unitName, "", data); } @@ -96,14 +109,14 @@ private async Task UpdateSubscriberFcm(string id, string token, string fcm var payload = new { - providerId = "fcm", + providerId = "fcm", //https://github.com/novuhq/novu-ts/blob/main/docs/models/components/chatorpushproviderenum.md credentials = new { deviceTokens = new string[] { token } }, integrationIdentifier = fcmId }; - string jsonContent = JsonConvert.SerializeObject(payload); + string jsonContent = JsonConvert.SerializeObject(payload, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); request.Content = new StringContent(jsonContent, Encoding.UTF8, "application/json"); HttpResponseMessage response = await client.SendAsync(request); @@ -118,6 +131,42 @@ private async Task UpdateSubscriberFcm(string id, string token, string fcm } } + private async Task UpdateSubscriberApns(string id, string token, string apnsId) + { + try + { + using (HttpClient client = new HttpClient()) + { + var url = $"{ChatConfig.NovuBackendUrl}/v1/subscribers/{id}/credentials"; + var request = new HttpRequestMessage(HttpMethod.Put, url); + request.Headers.Add("Accept", "application/json"); + request.Headers.Add("idempotency-key", Guid.NewGuid().ToString()); + request.Headers.Add("Authorization", $"ApiKey {ChatConfig.NovuSecretKey}"); + + var payload = new + { + providerId = "apns", + credentials = new + { + deviceTokens = new string[] { token } + }, + integrationIdentifier = apnsId + }; + string jsonContent = JsonConvert.SerializeObject(payload, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }); + + request.Content = new StringContent(jsonContent, Encoding.UTF8, "application/json"); + HttpResponseMessage response = await client.SendAsync(request); + + return response.IsSuccessStatusCode; + } + } + catch (Exception e) + { + Logging.LogException(e, "Failed to add apns token to novu subscriber"); + return false; + } + } + public async Task DeleteMessage(string messageId) { try @@ -145,11 +194,21 @@ public async Task UpdateUserSubscriberFcm(string userId, string code, stri return await UpdateSubscriberFcm($"{code}_User_{userId}", token, ChatConfig.NovuResponderFcmProviderId); } + public async Task UpdateUserSubscriberApns(string userId, string code, string token) + { + return await UpdateSubscriberApns($"{code}_User_{userId}", token, ChatConfig.NovuUnitApnsProviderId); + } + public async Task UpdateUnitSubscriberFcm(int unitId, string code, string token) { return await UpdateSubscriberFcm($"{code}_Unit_{unitId}", token, ChatConfig.NovuUnitFcmProviderId); } + public async Task UpdateUnitSubscriberApns(int unitId, string code, string token) + { + return await UpdateSubscriberApns($"{code}_Unit_{unitId}", token, ChatConfig.NovuUnitApnsProviderId); + } + private async Task SendNotification(string title, string body, string recipientId, string eventCode, string type, bool enableCustomSounds, int count, string color, string workflowIdentifier) { @@ -198,13 +257,13 @@ private async Task SendNotification(string title, string body, string reci type = type } }//, - //data = new - //{ - // title = title, - // message = body, - // eventCode = eventCode, - // type = type - //} + //data = new + //{ + // title = title, + // message = body, + // eventCode = eventCode, + // type = type + //} } }, to = new[]{ new @@ -214,10 +273,12 @@ private async Task SendNotification(string title, string body, string reci }; var content = new StringContent( - JsonConvert.SerializeObject(payload), + JsonConvert.SerializeObject(payload, new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore }), Encoding.UTF8, "application/json"); + + var result = await httpClient.PostAsync("v1/events/trigger", content); return result.IsSuccessStatusCode; @@ -235,13 +296,28 @@ public async Task SendUnitDispatch(string title, string body, int unitId, return await SendNotification(title, body, $"{depCode}_Unit_{unitId}", eventCode, type, enableCustomSounds, count, color, ChatConfig.NovuDispatchUnitWorkflowId); } + public async Task SendUserDispatch(string title, string body, string userId, string depCode, string eventCode, string type, bool enableCustomSounds, int count, string color) + { + return await SendNotification(title, body, $"{depCode}_User_{userId}", eventCode, type, enableCustomSounds, count, color, ChatConfig.NovuDispatchUserWorkflowId); + } + + public async Task SendUserMessage(string title, string body, string userId, string depCode, string eventCode, string type) + { + return await SendNotification(title, body, $"{depCode}_User_{userId}", eventCode, type, false, 0, null, ChatConfig.NovuMessageUserWorkflowId); + } + + public async Task SendUserNotification(string title, string body, string userId, string depCode, string eventCode, string type) + { + return await SendNotification(title, body, $"{depCode}_User_{userId}", eventCode, type, false, 0, null, ChatConfig.NovuNotificationUserWorkflowId); + } + #region Private Push Helpers private string GetSoundFileNameFromType(Platforms platform, string type) { if (type == ((int)PushSoundTypes.CallEmergency).ToString()) { - if (platform == Platforms.iPhone) + if (platform == Platforms.iOS) return "callemergency.caf"; return "callemergency.wav"; @@ -249,42 +325,42 @@ private string GetSoundFileNameFromType(Platforms platform, string type) else if (type == ((int)PushSoundTypes.CallHigh).ToString()) { - if (platform == Platforms.iPhone) + if (platform == Platforms.iOS) return "callhigh.caf"; return "callhigh.mp3"; } else if (type == ((int)PushSoundTypes.CallMedium).ToString()) { - if (platform == Platforms.iPhone) + if (platform == Platforms.iOS) return "callmedium.caf"; return "callmedium.mp3"; } else if (type == ((int)PushSoundTypes.CallLow).ToString()) { - if (platform == Platforms.iPhone) + if (platform == Platforms.iOS) return "calllow.caf"; return "calllow.mp3"; } else if (type == ((int)PushSoundTypes.Notifiation).ToString()) { - if (platform == Platforms.iPhone) + if (platform == Platforms.iOS) return "notification.caf"; return "notification.mp3"; } else if (type == ((int)PushSoundTypes.Message).ToString()) { - if (platform == Platforms.iPhone) + if (platform == Platforms.iOS) return "message.caf"; return "message.mp3"; } else { - if (platform == Platforms.iPhone) + if (platform == Platforms.iOS) return $"{type}.caf"; return $"{type}.mp3"; @@ -394,7 +470,7 @@ private string CreateAppleNotification(string title, string subTitle, string typ category = category, sound = new ApnsSound { - name = GetSoundFileNameFromType(Platforms.iPhone, type), + name = GetSoundFileNameFromType(Platforms.iOS, type), critical = category == "calls" ? 1 : 0, volume = 1.0f } diff --git a/Web/Resgrid.Web.Services/Controllers/v3/DevicesController.cs b/Web/Resgrid.Web.Services/Controllers/v3/DevicesController.cs index b6782924..66d6eb6a 100644 --- a/Web/Resgrid.Web.Services/Controllers/v3/DevicesController.cs +++ b/Web/Resgrid.Web.Services/Controllers/v3/DevicesController.cs @@ -78,7 +78,7 @@ public async Task> RegisterDevice([FromBo push.PushLocation = HttpUtility.UrlDecode(registrationInput.Uri); else if (registrationInput.Plt == (int)Platforms.Android) push.PushLocation = "Android"; - else if (registrationInput.Plt == (int)Platforms.iPhone || registrationInput.Plt == (int)Platforms.iPad) + else if (registrationInput.Plt == 1 || registrationInput.Plt == 2)//(int)Platforms.iPhone || registrationInput.Plt == (int)Platforms.iPad) push.PushLocation = "Apple"; push.DeviceId = registrationInput.Did; diff --git a/Web/Resgrid.Web.Services/Controllers/v4/DevicesController.cs b/Web/Resgrid.Web.Services/Controllers/v4/DevicesController.cs index c15d61ef..554603f1 100644 --- a/Web/Resgrid.Web.Services/Controllers/v4/DevicesController.cs +++ b/Web/Resgrid.Web.Services/Controllers/v4/DevicesController.cs @@ -25,12 +25,14 @@ public class DevicesController : V4AuthenticatedApiControllerbase { #region Members and Constructors private readonly IPushService _pushService; + private readonly IDepartmentsService _departmentsService; private readonly ICqrsProvider _cqrsProvider; - public DevicesController(IPushService pushService, ICqrsProvider cqrsProvider) + public DevicesController(IPushService pushService, ICqrsProvider cqrsProvider, IDepartmentsService departmentsService) { _pushService = pushService; _cqrsProvider = cqrsProvider; + _departmentsService = departmentsService; } #endregion Members and Constructors @@ -148,15 +150,12 @@ public async Task> RegisterDevice([FromBody if (registrationInput == null) return BadRequest(); - var push = new PushUri(); push.UserId = UserId; push.PlatformType = registrationInput.Platform; - if (registrationInput.Platform == (int)Platforms.Android) - push.PushLocation = "Android"; - else if (registrationInput.Platform == (int)Platforms.iPhone || registrationInput.Platform == (int)Platforms.iPad) - push.PushLocation = "Apple"; + var department = await _departmentsService.GetDepartmentByIdAsync(DepartmentId, false); + push.PushLocation = department.Code; push.DeviceId = registrationInput.Token; push.Uuid = registrationInput.DeviceUuid; diff --git a/Web/Resgrid.Web/Areas/User/Views/Profile/Devices.cshtml b/Web/Resgrid.Web/Areas/User/Views/Profile/Devices.cshtml index 680867b6..3624537c 100644 --- a/Web/Resgrid.Web/Areas/User/Views/Profile/Devices.cshtml +++ b/Web/Resgrid.Web/Areas/User/Views/Profile/Devices.cshtml @@ -42,7 +42,7 @@ { - @if ((Platforms)p.PlatformType == Platforms.iPhone || (Platforms)p.PlatformType == Platforms.iPad) + @if ((Platforms)p.PlatformType == Platforms.iOS) { iOS } @@ -74,4 +74,4 @@ @section Scripts { -} \ No newline at end of file +} diff --git a/Workers/Resgrid.Workers.Framework/Logic/CalendarNotifierLogic.cs b/Workers/Resgrid.Workers.Framework/Logic/CalendarNotifierLogic.cs index dedb509e..1c6a18b0 100644 --- a/Workers/Resgrid.Workers.Framework/Logic/CalendarNotifierLogic.cs +++ b/Workers/Resgrid.Workers.Framework/Logic/CalendarNotifierLogic.cs @@ -57,7 +57,7 @@ public async Task> Process(CalendarNotifierQueueItem item) foreach (var person in item.CalendarItem.Attendees) { var profile = profiles.FirstOrDefault(x => x.UserId == person.UserId); - await _communicationService.SendNotificationAsync(person.UserId, item.CalendarItem.DepartmentId, message, departmentNumber, title, profile); + await _communicationService.SendNotificationAsync(person.UserId, item.CalendarItem.DepartmentId, message, departmentNumber, department, title, profile); } } } @@ -96,7 +96,7 @@ public async Task> Process(CalendarNotifierQueueItem item) // Notify the entire department foreach (var profile in profiles) { - await _communicationService.SendNotificationAsync(profile.Key, item.CalendarItem.DepartmentId, message, departmentNumber, title, profile.Value); + await _communicationService.SendNotificationAsync(profile.Key, item.CalendarItem.DepartmentId, message, departmentNumber, department, title, profile.Value); } } else @@ -114,9 +114,9 @@ public async Task> Process(CalendarNotifierQueueItem item) foreach (var member in group.Members) { if (profiles.ContainsKey(member.UserId)) - await _communicationService.SendNotificationAsync(member.UserId, item.CalendarItem.DepartmentId, message, departmentNumber, title, profiles[member.UserId]); + await _communicationService.SendNotificationAsync(member.UserId, item.CalendarItem.DepartmentId, message, departmentNumber, department, title, profiles[member.UserId]); else - await _communicationService.SendNotificationAsync(member.UserId, item.CalendarItem.DepartmentId, message, departmentNumber, title, null); + await _communicationService.SendNotificationAsync(member.UserId, item.CalendarItem.DepartmentId, message, departmentNumber, department, title, null); } } } diff --git a/Workers/Resgrid.Workers.Framework/Logic/NotificationBroadcastLogic.cs b/Workers/Resgrid.Workers.Framework/Logic/NotificationBroadcastLogic.cs index 672f3fef..fa18bd75 100644 --- a/Workers/Resgrid.Workers.Framework/Logic/NotificationBroadcastLogic.cs +++ b/Workers/Resgrid.Workers.Framework/Logic/NotificationBroadcastLogic.cs @@ -70,7 +70,7 @@ public static async Task ProcessNotificationItem(NotificationItem ni, stri if (!_notificationService.AllowToSendViaSms(notification.Type)) profile.SendNotificationSms = false; - await _communicationService.SendNotificationAsync(user, notification.DepartmentId, text, queueItem.DepartmentTextNumber, "Notification", profile); + await _communicationService.SendNotificationAsync(user, notification.DepartmentId, text, queueItem.DepartmentTextNumber, queueItem.Department, "Notification", profile); } } } diff --git a/Workers/Resgrid.Workers.Framework/Logic/ShiftNotificationLogic.cs b/Workers/Resgrid.Workers.Framework/Logic/ShiftNotificationLogic.cs index 9990d4a4..2a5c8a2e 100644 --- a/Workers/Resgrid.Workers.Framework/Logic/ShiftNotificationLogic.cs +++ b/Workers/Resgrid.Workers.Framework/Logic/ShiftNotificationLogic.cs @@ -17,6 +17,9 @@ public static async Task ProcessShiftQueueItem(ShiftQueueItem sqi) var _shiftsService = Bootstrapper.GetKernel().Resolve(); var _communicationService = Bootstrapper.GetKernel().Resolve(); var _userProfileService = Bootstrapper.GetKernel().Resolve(); + var _departmentService = Bootstrapper.GetKernel().Resolve(); + + var department = await _departmentService.GetDepartmentByIdAsync(sqi.DepartmentId, false); if (sqi.Type == (int)ShiftQueueTypes.TradeRequested) { @@ -28,7 +31,7 @@ public static async Task ProcessShiftQueueItem(ShiftQueueItem sqi) foreach (var user in tradeRequest.Users) { UserProfile profile = userProfiles.FirstOrDefault(x => x.UserId == user.UserId); - await _communicationService.SendNotificationAsync(user.UserId, tradeRequest.SourceShiftSignup.Shift.DepartmentId, text, sqi.DepartmentNumber, + await _communicationService.SendNotificationAsync(user.UserId, tradeRequest.SourceShiftSignup.Shift.DepartmentId, text, sqi.DepartmentNumber, department, tradeRequest.SourceShiftSignup.Shift.Name, profile); } } @@ -40,7 +43,7 @@ await _communicationService.SendNotificationAsync(user.UserId, tradeRequest.Sour var text = _shiftsService.GenerateShiftTradeRejectionText(targetUserProfile, tradeRequest); - await _communicationService.SendNotificationAsync(sourceUserProfile.UserId, tradeRequest.SourceShiftSignup.Shift.DepartmentId, text, sqi.DepartmentNumber, + await _communicationService.SendNotificationAsync(sourceUserProfile.UserId, tradeRequest.SourceShiftSignup.Shift.DepartmentId, text, sqi.DepartmentNumber, department, tradeRequest.SourceShiftSignup.Shift.Name, sourceUserProfile); } else if (sqi.Type == (int)ShiftQueueTypes.TradeProposed && !String.IsNullOrWhiteSpace(sqi.SourceUserId)) @@ -51,7 +54,7 @@ await _communicationService.SendNotificationAsync(sourceUserProfile.UserId, trad var text = _shiftsService.GenerateShiftTradeProposedText(proposedUserProfile, tradeRequest); - await _communicationService.SendNotificationAsync(sourceUserProfile.UserId, tradeRequest.SourceShiftSignup.Shift.DepartmentId, text, sqi.DepartmentNumber, + await _communicationService.SendNotificationAsync(sourceUserProfile.UserId, tradeRequest.SourceShiftSignup.Shift.DepartmentId, text, sqi.DepartmentNumber, department, tradeRequest.SourceShiftSignup.Shift.Name, sourceUserProfile); } else if (sqi.Type == (int)ShiftQueueTypes.TradeFilled && !String.IsNullOrWhiteSpace(sqi.SourceUserId)) @@ -62,7 +65,7 @@ await _communicationService.SendNotificationAsync(sourceUserProfile.UserId, trad var text = _shiftsService.GenerateShiftTradeFilledText(sourceUserProfile, tradeRequest); - await _communicationService.SendNotificationAsync(proposedUserProfile.UserId, tradeRequest.SourceShiftSignup.Shift.DepartmentId, text, sqi.DepartmentNumber, + await _communicationService.SendNotificationAsync(proposedUserProfile.UserId, tradeRequest.SourceShiftSignup.Shift.DepartmentId, text, sqi.DepartmentNumber, department, tradeRequest.SourceShiftSignup.Shift.Name, proposedUserProfile); } else if (sqi.Type == (int)ShiftQueueTypes.ShiftCreated) @@ -74,7 +77,7 @@ await _communicationService.SendNotificationAsync(proposedUserProfile.UserId, tr foreach (var profile in profiles.Select(x => x.Value)) { - await _communicationService.SendNotificationAsync(profile.UserId, sqi.DepartmentId, text, sqi.DepartmentNumber, "New Shift", profile); + await _communicationService.SendNotificationAsync(profile.UserId, sqi.DepartmentId, text, sqi.DepartmentNumber, department, "New Shift", profile); } } else if (sqi.Type == (int)ShiftQueueTypes.ShiftUpdated) @@ -87,9 +90,9 @@ await _communicationService.SendNotificationAsync(proposedUserProfile.UserId, tr foreach (var profile in shift.Personnel) { if (profiles.ContainsKey(profile.UserId)) - await _communicationService.SendNotificationAsync(profile.UserId, sqi.DepartmentId, text, sqi.DepartmentNumber, shift.Name, profiles[profile.UserId]); + await _communicationService.SendNotificationAsync(profile.UserId, sqi.DepartmentId, text, sqi.DepartmentNumber, department, shift.Name, profiles[profile.UserId]); else - await _communicationService.SendNotificationAsync(profile.UserId, sqi.DepartmentId, text, sqi.DepartmentNumber, shift.Name); + await _communicationService.SendNotificationAsync(profile.UserId, sqi.DepartmentId, text, sqi.DepartmentNumber, department, shift.Name); } } else if (sqi.Type == (int)ShiftQueueTypes.ShiftDaysAdded) @@ -104,9 +107,9 @@ await _communicationService.SendNotificationAsync(proposedUserProfile.UserId, tr foreach (var profile in shift.Personnel) { if (profiles.ContainsKey(profile.UserId)) - await _communicationService.SendNotificationAsync(profile.UserId, sqi.DepartmentId, text, sqi.DepartmentNumber, shift.Name, profiles[profile.UserId]); + await _communicationService.SendNotificationAsync(profile.UserId, sqi.DepartmentId, text, sqi.DepartmentNumber, department, shift.Name, profiles[profile.UserId]); else - await _communicationService.SendNotificationAsync(profile.UserId, sqi.DepartmentId, text, sqi.DepartmentNumber, shift.Name); + await _communicationService.SendNotificationAsync(profile.UserId, sqi.DepartmentId, text, sqi.DepartmentNumber, department, shift.Name); } } } diff --git a/Workers/Resgrid.Workers.Framework/Logic/ShiftNotifierLogic.cs b/Workers/Resgrid.Workers.Framework/Logic/ShiftNotifierLogic.cs index 5f385401..cb57d4df 100644 --- a/Workers/Resgrid.Workers.Framework/Logic/ShiftNotifierLogic.cs +++ b/Workers/Resgrid.Workers.Framework/Logic/ShiftNotifierLogic.cs @@ -14,12 +14,14 @@ public class ShiftNotifierLogic private IShiftsService _shiftsService; private ICommunicationService _communicationService; private IDepartmentSettingsService _departmentSettingsService; + private IDepartmentsService _departmentsService; public ShiftNotifierLogic() { _shiftsService = Bootstrapper.GetKernel().Resolve(); _communicationService = Bootstrapper.GetKernel().Resolve(); _departmentSettingsService = Bootstrapper.GetKernel().Resolve(); + _departmentsService = Bootstrapper.GetKernel().Resolve(); } public async Task> Process(ShiftNotifierQueueItem item) @@ -31,6 +33,7 @@ public async Task> Process(ShiftNotifierQueueItem item) { var text = _shiftsService.GenerateShiftNotificationText(item.Shift); string departmentNumber = await _departmentSettingsService.GetTextToCallNumberForDepartmentAsync(item.Shift.DepartmentId); + var department = await _departmentsService.GetDepartmentByIdAsync(item.Shift.DepartmentId, false); if (ConfigHelper.CanTransmit(item.Shift.DepartmentId)) { @@ -39,7 +42,7 @@ public async Task> Process(ShiftNotifierQueueItem item) foreach (var person in item.Shift.Personnel) { UserProfile profile = item.Profiles.FirstOrDefault(x => x.UserId == person.UserId); - await _communicationService.SendNotificationAsync(person.UserId, item.Shift.DepartmentId, text, departmentNumber, + await _communicationService.SendNotificationAsync(person.UserId, item.Shift.DepartmentId, text, departmentNumber, department, item.Shift.Name, profile); } } @@ -53,26 +56,26 @@ await _communicationService.SendNotificationAsync(person.UserId, item.Shift.Depa if (!String.IsNullOrWhiteSpace(signup.Trade.UserId)) { UserProfile profile = item.Profiles.FirstOrDefault(x => x.UserId == signup.Trade.UserId); - await _communicationService.SendNotificationAsync(signup.Trade.UserId, item.Shift.DepartmentId, text, departmentNumber, + await _communicationService.SendNotificationAsync(signup.Trade.UserId, item.Shift.DepartmentId, text, departmentNumber, department, item.Shift.Name, profile); } else if (signup.GetTradeType() == ShiftTradeTypes.Source) { UserProfile profile = item.Profiles.FirstOrDefault(x => x.UserId == signup.Trade.TargetShiftSignup.UserId); - await _communicationService.SendNotificationAsync(signup.Trade.TargetShiftSignup.UserId, item.Shift.DepartmentId, text, departmentNumber, + await _communicationService.SendNotificationAsync(signup.Trade.TargetShiftSignup.UserId, item.Shift.DepartmentId, text, departmentNumber, department, item.Shift.Name, profile); } else if (signup.GetTradeType() == ShiftTradeTypes.Target) { UserProfile profile = item.Profiles.FirstOrDefault(x => x.UserId == signup.Trade.SourceShiftSignup.UserId); - await _communicationService.SendNotificationAsync(signup.Trade.SourceShiftSignup.UserId, item.Shift.DepartmentId, text, departmentNumber, + await _communicationService.SendNotificationAsync(signup.Trade.SourceShiftSignup.UserId, item.Shift.DepartmentId, text, departmentNumber, department, item.Shift.Name, profile); } } else { UserProfile profile = item.Profiles.FirstOrDefault(x => x.UserId == signup.UserId); - await _communicationService.SendNotificationAsync(signup.UserId, item.Shift.DepartmentId, text, departmentNumber, + await _communicationService.SendNotificationAsync(signup.UserId, item.Shift.DepartmentId, text, departmentNumber, department, item.Shift.Name, profile); } } diff --git a/Workers/Resgrid.Workers.Framework/Logic/TrainingNotifierLogic.cs b/Workers/Resgrid.Workers.Framework/Logic/TrainingNotifierLogic.cs index ef6f9eff..076cd24e 100644 --- a/Workers/Resgrid.Workers.Framework/Logic/TrainingNotifierLogic.cs +++ b/Workers/Resgrid.Workers.Framework/Logic/TrainingNotifierLogic.cs @@ -14,6 +14,7 @@ public class TrainingNotifierLogic private ICommunicationService _communicationService; private IUserProfileService _userProfileService; private IDepartmentSettingsService _departmentSettingsService; + private IDepartmentsService _departmentsService; public TrainingNotifierLogic() { @@ -21,6 +22,7 @@ public TrainingNotifierLogic() _communicationService = Bootstrapper.GetKernel().Resolve(); _userProfileService = Bootstrapper.GetKernel().Resolve(); _departmentSettingsService = Bootstrapper.GetKernel().Resolve(); + _departmentsService = Bootstrapper.GetKernel().Resolve(); } public async Task> Process(TrainingNotifierQueueItem item) @@ -34,6 +36,7 @@ public async Task> Process(TrainingNotifierQueueItem item) var title = String.Empty; var profiles = await _userProfileService.GetSelectedUserProfilesAsync(item.Training.Users.Select(x => x.UserId).ToList()); var departmentNumber = await _departmentSettingsService.GetTextToCallNumberForDepartmentAsync(item.Training.DepartmentId); + var department = await _departmentsService.GetDepartmentByIdAsync(item.Training.DepartmentId, false); if (ConfigHelper.CanTransmit(item.Training.DepartmentId)) { @@ -57,7 +60,7 @@ public async Task> Process(TrainingNotifierQueueItem item) var profile = profiles.FirstOrDefault(x => x.UserId == person.UserId); if (!item.Training.Notified.HasValue || !person.Complete) - await _communicationService.SendNotificationAsync(person.UserId, item.Training.DepartmentId, message, departmentNumber, title, profile); + await _communicationService.SendNotificationAsync(person.UserId, item.Training.DepartmentId, message, departmentNumber, department, title, profile); title = "Training Due Notice"; }