From e0a5225116cc166e2406ac1c3771cd3cb5842e4e Mon Sep 17 00:00:00 2001 From: Ofir Matasas <88926592+OfirMatasas@users.noreply.github.com> Date: Fri, 15 Sep 2023 14:02:15 +0300 Subject: [PATCH] Send newsfeeds as notifications (#138) * Send newsfeeds as notifications * Send Wi-Fi newsfeeds --- .../Notification/CreateNotification.cs | 3 +- Notify/Notify/Notify.Android/MainActivity.cs | 11 ++-- .../Managers/AndroidWiFiManager.cs | 24 +++++++-- .../AndroidNotificationManager.cs | 18 ++++++- Notify/Notify/Notify/AppShell.xaml.cs | 28 ++++++++-- .../Azure/HttpClient/AzureHttpClient.cs | 51 +++++++++++++++++++ Notify/Notify/Notify/Core/Newsfeed.cs | 16 ++++++ Notify/Notify/Notify/Core/Notification.cs | 4 +- Notify/Notify/Notify/Helpers/Constants.cs | 2 + Notify/Notify/Notify/Helpers/Converter.cs | 11 +++- .../Notifications/INotificationManager.cs | 1 + 11 files changed, 153 insertions(+), 16 deletions(-) create mode 100644 Notify/Notify/Notify/Core/Newsfeed.cs diff --git a/Notify/Notify.Functions/Notify.Functions/NotifyFunctions/Notification/CreateNotification.cs b/Notify/Notify.Functions/Notify.Functions/NotifyFunctions/Notification/CreateNotification.cs index 1855859f..05d504c1 100644 --- a/Notify/Notify.Functions/Notify.Functions/NotifyFunctions/Notification/CreateNotification.cs +++ b/Notify/Notify.Functions/Notify.Functions/NotifyFunctions/Notification/CreateNotification.cs @@ -96,7 +96,8 @@ private static void createDocumentForEachUser(JToken json, string type, ref List extraElement } }, - { "user", user } + { "user", user }, + { "shouldBeNotified", Convert.ToString(json["shouldBeNotified"] ?? user) } }; if (type.ToLower().Equals(Constants.NOTIFICATION_TYPE_LOCATION_LOWER)) diff --git a/Notify/Notify/Notify.Android/MainActivity.cs b/Notify/Notify/Notify.Android/MainActivity.cs index 19422391..1b0aea41 100644 --- a/Notify/Notify/Notify.Android/MainActivity.cs +++ b/Notify/Notify/Notify.Android/MainActivity.cs @@ -142,13 +142,16 @@ private void createNotificationFromIntent(Intent intent) string message = intent.GetStringExtra(AndroidNotificationManager.messageKey); string data = intent.GetStringExtra(AndroidNotificationManager.dataKey); Notification notification = Newtonsoft.Json.JsonConvert.DeserializeObject(data); - NotificationsPageViewModel viewModel = NotificationsPageViewModel.Instance; - viewModel.ExpandedNotificationId = notification.ID; - viewModel.SelectedFilter = Constants.FILTER_TYPE_ALL; DependencyService.Get().ReceiveNotification(title, message, notification); - App.Current.MainPage.Navigation.PushAsync(new NotificationsPage(viewModel)); + + if (notification != null) + { + viewModel.ExpandedNotificationId = notification.ID; + viewModel.SelectedFilter = Constants.FILTER_TYPE_ALL; + App.Current.MainPage.Navigation.PushAsync(new NotificationsPage(viewModel)); + } } } } diff --git a/Notify/Notify/Notify.Android/Managers/AndroidWiFiManager.cs b/Notify/Notify/Notify.Android/Managers/AndroidWiFiManager.cs index 669d6e70..75c61b0f 100644 --- a/Notify/Notify/Notify.Android/Managers/AndroidWiFiManager.cs +++ b/Notify/Notify/Notify.Android/Managers/AndroidWiFiManager.cs @@ -147,8 +147,16 @@ private static void sendNotificationsForArrivalDestinations(List n { if (isArrivalNotification) { - r_Logger.LogInformation($"Sending notification for arrival notification: {notification.Name}"); - DependencyService.Get().SendNotification(notification); + if (notification.ShouldBeNotified.Equals(notification.Creator)) + { + r_Logger.LogInformation($"Sending newsfeed to creator {notification.Creator} for arrival notification: {notification.Name}"); + AzureHttpClient.Instance.SendNewsfeed(new Newsfeed(notification.Creator, $"{notification.Target} Arrived {notification.TypeInfo}", $"{notification.Target} has arrived to {notification.TypeInfo}")); + } + else + { + r_Logger.LogInformation($"Sending notification for arrival notification: {notification.Name}"); + DependencyService.Get().SendNotification(notification); + } if (notification.IsPermanent) { @@ -191,8 +199,16 @@ private static void sendNotificationsForLeaveDestinations(List not { if (isLeaveNotification) { - r_Logger.LogInformation($"Sending notification for leave notification: {notification.Name}"); - DependencyService.Get().SendNotification(notification); + if(notification.ShouldBeNotified.Equals(notification.Creator)) + { + r_Logger.LogInformation($"Sending newsfeed to creator {notification.Creator} for leave notification: {notification.Name}"); + AzureHttpClient.Instance.SendNewsfeed(new Newsfeed(notification.Creator, $"{notification.Target} Left {notification.TypeInfo}", $"{notification.Target} has left {notification.TypeInfo}")); + } + else + { + r_Logger.LogInformation($"Sending notification for leave notification: {notification.Name}"); + DependencyService.Get().SendNotification(notification); + } if(notification.IsPermanent) { diff --git a/Notify/Notify/Notify.Android/Notifications/AndroidNotificationManager.cs b/Notify/Notify/Notify.Android/Notifications/AndroidNotificationManager.cs index 423497f5..28ad5156 100644 --- a/Notify/Notify/Notify.Android/Notifications/AndroidNotificationManager.cs +++ b/Notify/Notify/Notify.Android/Notifications/AndroidNotificationManager.cs @@ -1,15 +1,16 @@ using System; using Android.App; using Android.Content; -using Android.Graphics; using Android.OS; using AndroidX.Core.App; using Newtonsoft.Json; +using Notify.Core; using Notify.Helpers; using Notify.Notifications; using Notify.Services; using Xamarin.Forms; using AndroidApp = Android.App.Application; +using Notification = Android.App.Notification; [assembly: Dependency(typeof(Notify.Droid.Notifications.AndroidNotificationManager))] namespace Notify.Droid.Notifications @@ -159,5 +160,20 @@ long GetNotifyTime(DateTime notifyTime) return utcAlarmTime; // milliseconds } + + public void SendNewsfeed(Newsfeed newsfeed) + { + r_Logger.LogDebug($"Sending newsfeed with title: {newsfeed.Title} and content: {newsfeed.Content}"); + + try + { + DependencyService.Get() + .SendNotification(newsfeed.Title, newsfeed.Content, null); + } + catch (Exception ex) + { + r_Logger.LogError($"Error sending notification: {ex.Message}"); + } + } } } diff --git a/Notify/Notify/Notify/AppShell.xaml.cs b/Notify/Notify/Notify/AppShell.xaml.cs index fc1e7f20..3c88e49a 100644 --- a/Notify/Notify/Notify/AppShell.xaml.cs +++ b/Notify/Notify/Notify/AppShell.xaml.cs @@ -28,6 +28,7 @@ public partial class AppShell private static readonly object m_InitializeLock = new object(); private static bool m_IsInitialized; private BluetoothManager m_BluetoothManager; + private DateTime m_LastTimeCheckedForNewsfeeds = DateTime.MinValue; public AppShell() { @@ -45,7 +46,7 @@ private void initializeAppShell() Connectivity.ConnectivityChanged += internetConnectivityChanged; m_BluetoothManager = BluetoothManager.Instance; m_BluetoothManager.StartBluetoothScanning(); - setNoficicationManagerNotificationReceived(); + setNotificationManagerNotificationReceived(); setMessagingCenterSubscriptions(); if (Preferences.Get(Constants.START_LOCATION_SERVICE, false)) @@ -53,7 +54,7 @@ private void initializeAppShell() startService(); } - retriveDestinations(); + retrieveDestinations(); } } } @@ -72,7 +73,7 @@ private void setMessagingCenterSubscriptions() setMessagingCenterLocationArrivedMessageSubscription(); } - private async void retriveDestinations() + private async void retrieveDestinations() { await Task.Run(() => { @@ -128,9 +129,28 @@ private void setMessagingCenterLocationSubscription() checkIfDynamicLocationNotificationShouldBeUpdated(location); sendAllRelevantLocationNotifications(location); + getNewsfeeds(); }); } + private async void getNewsfeeds() + { + if (DateTime.Now - m_LastTimeCheckedForNewsfeeds > TimeSpan.FromMinutes(1)) + { + LoggerService.Instance.LogInformation("Getting newsfeeds"); + List newsfeeds = await AzureHttpClient.Instance.GetNewsfeeds(); + LoggerService.Instance.LogInformation($"Got {newsfeeds.Count} newsfeeds"); + + foreach (Newsfeed newsfeed in newsfeeds) + { + LoggerService.Instance.LogDebug($"Sending newsfeed: {newsfeed.Title}, {newsfeed.Content}"); + DependencyService.Get().SendNewsfeed(newsfeed); + } + + m_LastTimeCheckedForNewsfeeds = DateTime.Now; + } + } + private async void checkIfDynamicLocationNotificationShouldBeUpdated(Location location) { string destinationsJson = Preferences.Get(Constants.PREFERENCES_DESTINATIONS, string.Empty); @@ -368,7 +388,7 @@ private void updateStatusOfNotifications(string newStatus, List se AzureHttpClient.Instance.UpdateNotificationsStatus(sentNotifications, newStatus); } - private void setNoficicationManagerNotificationReceived() + private void setNotificationManagerNotificationReceived() { notificationManager.NotificationReceived += (sender, eventArgs) => { diff --git a/Notify/Notify/Notify/Azure/HttpClient/AzureHttpClient.cs b/Notify/Notify/Notify/Azure/HttpClient/AzureHttpClient.cs index 3523472b..b54d3d7c 100644 --- a/Notify/Notify/Notify/Azure/HttpClient/AzureHttpClient.cs +++ b/Notify/Notify/Notify/Azure/HttpClient/AzureHttpClient.cs @@ -10,6 +10,7 @@ using Newtonsoft.Json.Linq; using Notify.Core; using Notify.Helpers; +using Notify.Notifications; using Notify.Services; using Notify.WiFi; using Xamarin.Essentials; @@ -281,6 +282,8 @@ public async Task> GetNotifications() createNewDynamicDestinations(notifications); DependencyService.Get().SendNotifications(null, null); + GetNewsfeedsAndSendThem(); + return notifications; } @@ -457,6 +460,7 @@ private async Task updateNotification(string ID, string name, string descr public async Task> GetFriends() { + GetNewsfeedsAndSendThem(); await GetFriendsPermissions(); return await GetData( @@ -1081,5 +1085,52 @@ private async Task deleteAsync(string requestUri, StringCon return await m_HttpClient.SendAsync(request); } + + public async Task> GetNewsfeeds() + { + return await GetData( + endpoint: Constants.AZURE_FUNCTIONS_PATTERN_NEWSFEED, + preferencesKey: Constants.PREFERENCES_NEWSFEED, + converter: Converter.ToNewsfeed); + } + + public async void GetNewsfeedsAndSendThem() + { + List newsfeeds = await GetNewsfeeds(); + + foreach (Newsfeed newsfeed in newsfeeds) + { + DependencyService.Get().SendNewsfeed(newsfeed); + } + } + + public void SendNewsfeed(Newsfeed newsfeed) + { + HttpResponseMessage response; + string json; + dynamic data = new JObject + { + { "username", newsfeed.Username }, + { "title", newsfeed.Title }, + { "content", newsfeed.Content }, + }; + + json = JsonConvert.SerializeObject(data); + r_Logger.LogInformation($"request:{Environment.NewLine}{json}"); + + try + { + response = postAsync( + requestUri: Constants.AZURE_FUNCTIONS_PATTERN_NEWSFEED, + content: createJsonStringContent(json)).Result; + + response.EnsureSuccessStatusCode(); + r_Logger.LogInformation($"Successful status code from Azure Function from SendNewsfeeds"); + } + catch (Exception ex) + { + r_Logger.LogError($"Error occurred on SendNewsfeeds: {ex.Message}"); + } + } } } diff --git a/Notify/Notify/Notify/Core/Newsfeed.cs b/Notify/Notify/Notify/Core/Newsfeed.cs new file mode 100644 index 00000000..78c05021 --- /dev/null +++ b/Notify/Notify/Notify/Core/Newsfeed.cs @@ -0,0 +1,16 @@ +namespace Notify.Core +{ + public class Newsfeed + { + public string Username { get; set; } + public string Title { get; set; } + public string Content { get; set; } + + public Newsfeed(string username, string title, string content) + { + Username = username; + Title = title; + Content = content; + } + } +} diff --git a/Notify/Notify/Notify/Core/Notification.cs b/Notify/Notify/Notify/Core/Notification.cs index 38d5fb73..4ecde352 100644 --- a/Notify/Notify/Notify/Core/Notification.cs +++ b/Notify/Notify/Notify/Core/Notification.cs @@ -25,6 +25,7 @@ public class Notification public string Activation { get; set; } public bool IsPermanent { get; set; } public string Target { get; set; } + public string ShouldBeNotified { get; set; } public bool IsPending => Status == Constants.NOTIFICATION_STATUS_PENDING; public bool IsRenewable => Status == Constants.NOTIFICATION_STATUS_EXPIRED && Type != NotificationType.Time; @@ -37,7 +38,7 @@ public Notification() } - public Notification(string id, string name, string description, DateTime creationDateTime, string status, string creator, NotificationType type, object typeInfo, string target, string activation, bool permanent) + public Notification(string id, string name, string description, DateTime creationDateTime, string status, string creator, NotificationType type, object typeInfo, string target, string activation, bool permanent, string shouldBeNotified) { ID = id; Name = name; @@ -50,6 +51,7 @@ public Notification(string id, string name, string description, DateTime creatio Activation = activation; IsPermanent = permanent; Target = target; + ShouldBeNotified = shouldBeNotified; } public Notification(string id) diff --git a/Notify/Notify/Notify/Helpers/Constants.cs b/Notify/Notify/Notify/Helpers/Constants.cs index d38c79e3..7c2fd3e5 100644 --- a/Notify/Notify/Notify/Helpers/Constants.cs +++ b/Notify/Notify/Notify/Helpers/Constants.cs @@ -142,6 +142,7 @@ public static List GetRaceTypesList() public static readonly string AZURE_FUNCTIONS_PATTERN_NOTIFICATION_UPDATE_DYNAMIC = $"{AZURE_FUNCTIONS_PATTERN_NOTIFICATION_UPDATE}/dynamic"; public static readonly string AZURE_FUNCTIONS_PATTERN_NOTIFICATION_UPDATE_STATUS = $"{AZURE_FUNCTIONS_PATTERN_NOTIFICATION}/status"; public static readonly string AZURE_FUNCTIONS_PATTERN_NOTIFICATION_RENEW = $"{AZURE_FUNCTIONS_PATTERN_NOTIFICATION}/renew"; + public static readonly string AZURE_FUNCTIONS_PATTERN_NEWSFEED = "newsfeed"; public static readonly string AZURE_FUNCTIONS_PATTERN_DESTINATION = "destination"; public static readonly string AZURE_FUNCTIONS_PATTERN_DESTINATION_UPDATE = AZURE_FUNCTIONS_PATTERN_DESTINATION + "/update"; public static readonly string AZURE_FUNCTIONS_PATTERN_DESTINATION_SUGGESTIONS = AZURE_FUNCTIONS_PATTERN_DESTINATION + "/suggestions"; @@ -198,6 +199,7 @@ public static List GetRaceTypesList() #region Prefrences_Keys public static readonly string PREFERENCES_NOTIFICATIONS = "Notifications"; + public static readonly string PREFERENCES_NEWSFEED = "Newsfeed"; public static readonly string PREFERENCES_DESTINATIONS = "Destinations"; public static readonly string PREFERENCES_FRIENDS = "Friends"; public static readonly string PREFERENCES_PENDING_FRIEND_REQUESTS = "PendingFriendRequests"; diff --git a/Notify/Notify/Notify/Helpers/Converter.cs b/Notify/Notify/Notify/Helpers/Converter.cs index 29911aa6..a472d509 100644 --- a/Notify/Notify/Notify/Helpers/Converter.cs +++ b/Notify/Notify/Notify/Helpers/Converter.cs @@ -230,7 +230,8 @@ public static Notification ToNotification(dynamic notification) typeInfo: notificationTypeValue, activation: activation, permanent: notification.notification.permanent != null && (bool)notification.notification.permanent, - target: (string)notification.user); + target: (string)notification.user, + shouldBeNotified: (string)notification.shouldBeNotified ?? (string)notification.user); } public static User ToFriend(dynamic friend) @@ -282,5 +283,13 @@ public static Permission ToPermission(dynamic permission) timeNotificationPermission: (string)permission.time, dynamicNotificationPermission: (string)permission.dynamic); } + + public static Newsfeed ToNewsfeed(dynamic newsfeed) + { + return new Newsfeed( + username: (string)newsfeed.username, + title: (string)newsfeed.title, + content: (string)newsfeed.content); + } } } diff --git a/Notify/Notify/Notify/Notifications/INotificationManager.cs b/Notify/Notify/Notify/Notifications/INotificationManager.cs index 9b6dd37f..c2d7c6de 100644 --- a/Notify/Notify/Notify/Notifications/INotificationManager.cs +++ b/Notify/Notify/Notify/Notifications/INotificationManager.cs @@ -8,6 +8,7 @@ public interface INotificationManager event EventHandler NotificationReceived; void Initialize(); void SendNotification(Notification notification); + void SendNewsfeed(Newsfeed newsfeed); void SendNotification(string title, string message, Notification notification, DateTime? notifyTime = null); void ReceiveNotification(string title, string message, Notification notification); }