diff --git a/src/StoneRed.NetificationApi.Example/Program.cs b/src/StoneRed.NetificationApi.Example/Program.cs index 20a6c06..13cfc30 100644 --- a/src/StoneRed.NetificationApi.Example/Program.cs +++ b/src/StoneRed.NetificationApi.Example/Program.cs @@ -47,6 +47,23 @@ notificationApiClient.UnreadCountReceived += (sender, args) => Console.WriteLine($"Unread count received: {args.Count}"); }; +notificationApiClient.UserPreferencesReceived += (sender, args) => +{ + Console.WriteLine("User preferences received"); + foreach (NotificationUserPreference notificationPreference in args.UserPreferences) + { + Console.WriteLine($"Notification preference received: {notificationPreference.Title}"); + foreach (NotificationUserPreferenceSetting preference in notificationPreference.Settings) + { + Console.WriteLine($"Notification preference: {preference.Channel} {preference.ChannelName} {preference.State}"); + } + } +}; + +Console.WriteLine("Request user preferences"); +notificationApiClient.RequestUserPreferences(); +Console.WriteLine("User preferences requested"); + Console.WriteLine("Request unread count"); notificationApiClient.RequestUnreadCount(); Console.WriteLine("Unread count requested"); diff --git a/src/StoneRed.NetificationApi/Client/Models/NotificationChannelPreference.cs b/src/StoneRed.NetificationApi/Client/Models/NotificationChannelPreference.cs new file mode 100644 index 0000000..8e117b4 --- /dev/null +++ b/src/StoneRed.NetificationApi/Client/Models/NotificationChannelPreference.cs @@ -0,0 +1,25 @@ +using StoneRed.NetificationApi.Shared; + +using System.Diagnostics.CodeAnalysis; + +namespace StoneRed.NetificationApi.Client.Models; + +public class NotificationChannelPreference +{ + public NotificationChannel Channel { get; set; } + + public bool State { get; set; } + public string? SubNotificationId { get; set; } + + [SetsRequiredMembers] + public NotificationChannelPreference(NotificationChannel channel, bool state, string? subNotificationId = null) + { + Channel = channel; + State = state; + SubNotificationId = subNotificationId; + } + + public NotificationChannelPreference() + { + } +} \ No newline at end of file diff --git a/src/StoneRed.NetificationApi/Client/Models/NotificationUserPreference.cs b/src/StoneRed.NetificationApi/Client/Models/NotificationUserPreference.cs new file mode 100644 index 0000000..9ff5f02 --- /dev/null +++ b/src/StoneRed.NetificationApi/Client/Models/NotificationUserPreference.cs @@ -0,0 +1,9 @@ +namespace StoneRed.NetificationApi.Client.Models; + +public class NotificationUserPreference +{ + public required string NotificationId { get; set; } + public required string Title { get; set; } + public required List Settings { get; set; } + public required List SubNotificationPreferences { get; set; } +} \ No newline at end of file diff --git a/src/StoneRed.NetificationApi/Client/Models/NotificationUserPreferenceSetting.cs b/src/StoneRed.NetificationApi/Client/Models/NotificationUserPreferenceSetting.cs new file mode 100644 index 0000000..2f59790 --- /dev/null +++ b/src/StoneRed.NetificationApi/Client/Models/NotificationUserPreferenceSetting.cs @@ -0,0 +1,10 @@ +using StoneRed.NetificationApi.Shared; + +namespace StoneRed.NetificationApi.Client.Models; + +public class NotificationUserPreferenceSetting +{ + public required NotificationChannel Channel { get; set; } + public bool State { get; set; } + public required string ChannelName { get; set; } +} \ No newline at end of file diff --git a/src/StoneRed.NetificationApi/Client/Models/UserPreferencesReceivedEventArgs.cs b/src/StoneRed.NetificationApi/Client/Models/UserPreferencesReceivedEventArgs.cs new file mode 100644 index 0000000..97e434a --- /dev/null +++ b/src/StoneRed.NetificationApi/Client/Models/UserPreferencesReceivedEventArgs.cs @@ -0,0 +1,6 @@ +namespace StoneRed.NetificationApi.Client.Models; + +public class UserPreferencesReceivedEventArgs(List userPreferences) +{ + public List UserPreferences { get; set; } = userPreferences; +} \ No newline at end of file diff --git a/src/StoneRed.NetificationApi/Client/NotificationApiClient.cs b/src/StoneRed.NetificationApi/Client/NotificationApiClient.cs index 97465c6..1889bde 100644 --- a/src/StoneRed.NetificationApi/Client/NotificationApiClient.cs +++ b/src/StoneRed.NetificationApi/Client/NotificationApiClient.cs @@ -21,6 +21,8 @@ public class NotificationApiClient public event EventHandler? UnreadCountReceived; + public event EventHandler? UserPreferencesReceived; + private readonly WebsocketClient client; public NotificationApiClient(string userId, string clientId, string? userIdHash = null, string baseAddress = "wss://ws.notificationapi.com") @@ -86,6 +88,20 @@ public class NotificationApiClient UnreadCountReceived?.Invoke(this, new CountReceivedEventArgs(msg.Payload.Count)); }); + + _ = client.MessageReceived + .Where(msg => msg.Text is not null) + .Where(msg => WebsocketMessageComparer.Compare(msg.Text, "user_preferences/preferences")) + .Select(msg => WebsocketMessageConverter.ConvertWebsocketMessage(msg.Text!)) + .Subscribe(msg => + { + if (msg.Payload is null) + { + return; + } + + UserPreferencesReceived?.Invoke(this, new UserPreferencesReceivedEventArgs(msg.Payload.UserPreferences)); + }); } public Task Start() @@ -130,6 +146,32 @@ public class NotificationApiClient return client.Send(JsonSerializer.Serialize(message, Configuration.JsonSerializerOptions)); } + public bool RequestUserPreferences() + { + WebsocketMessage message = new("user_preferences/get_preferences"); + + return client.Send(JsonSerializer.Serialize(message, Configuration.JsonSerializerOptions)); + } + + public bool PatchUserPreferences(string notificationId, params NotificationChannelPreference[] channelPreferences) + { + WebsocketMessage message = new("user_preferences/patch_preferences") + { + Payload = new object[] + { + new + { + notificationId, + channelPreferences + } + } + }; + + string msg = JsonSerializer.Serialize(message, Configuration.JsonSerializerOptions); + + return client.Send(msg); + } + public Task Stop() { return client.StopOrFail(WebSocketCloseStatus.NormalClosure, "Normal closure"); diff --git a/src/StoneRed.NetificationApi/Client/Payloads/UserPreferencesPayload.cs b/src/StoneRed.NetificationApi/Client/Payloads/UserPreferencesPayload.cs new file mode 100644 index 0000000..e1f14e5 --- /dev/null +++ b/src/StoneRed.NetificationApi/Client/Payloads/UserPreferencesPayload.cs @@ -0,0 +1,8 @@ +using StoneRed.NetificationApi.Client.Models; + +namespace StoneRed.NetificationApi.Client.Payloads; + +internal class UserPreferencesPayload +{ + public required List UserPreferences { get; set; } +} \ No newline at end of file diff --git a/src/StoneRed.NetificationApi/Utilities/WebsocketMessageComparer.cs b/src/StoneRed.NetificationApi/Utilities/WebsocketMessageComparer.cs index 9d5cb16..e93242f 100644 --- a/src/StoneRed.NetificationApi/Utilities/WebsocketMessageComparer.cs +++ b/src/StoneRed.NetificationApi/Utilities/WebsocketMessageComparer.cs @@ -12,8 +12,16 @@ internal static class WebsocketMessageComparer { return false; } + WebsocketMessage? websocketMessage; - WebsocketMessage? websocketMessage = JsonSerializer.Deserialize(message, Configuration.JsonSerializerOptions); + try + { + websocketMessage = JsonSerializer.Deserialize(message, Configuration.JsonSerializerOptions); + } + catch (JsonException) + { + return false; + } return websocketMessage?.Route == route; }