diff --git a/.github/workflows/publish-nuget.yml b/.github/workflows/publish-nuget.yml new file mode 100644 index 0000000..6ed5798 --- /dev/null +++ b/.github/workflows/publish-nuget.yml @@ -0,0 +1,28 @@ +name: Upload nuget package + +on: + push: + branches: + - main + +jobs: + deploy: + runs-on: ubuntu-latest + permissions: + packages: write + contents: read + steps: + - uses: actions/checkout@v4 + - uses: actions/setup-dotnet@v4 + with: + dotnet-version: '8.0.x' # SDK Version to use. + source-url: https://nuget.pkg.github.com/Stone-Red-Software/index.json + env: + NUGET_AUTH_TOKEN: ${{secrets.NUGET_TOKEN}} + - run: dotnet build --configuration Release src/StoneRed.NetificationApi + - name: Create the package + run: dotnet pack --configuration Release src/StoneRed.NetificationApi + - name: Publish the package to nuget.org + run: dotnet nuget push src/StoneRed.NetificationApi/bin/Release/*.nupkg -k $NUGET_AUTH_TOKEN -s https://api.nuget.org/v3/index.json + env: + NUGET_AUTH_TOKEN: ${{secrets.NUGET_TOKEN}} diff --git a/README.md b/README.md index dc2c3cf..c1ab0ef 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,97 @@ # StoneRed.NetificationApi + > A .NET library for NotificationAPI + +This is an *unofficial* library for [NotificationAPI](https://www.notificationapi.com/) and attempts to replicate the functionality of the official [Server SDK](https://docs.notificationapi.com/reference/server) and [JS Client SDK](https://docs.notificationapi.com/reference/js-client) as closely as possible.\ +(A prebuilt notification widget is not included in this library.) + +## Supported Features + +**Server:** + +- Send all types of notifications +- Retract notifications +- Identify user +- Set user preferences + +**Client:** + +- Receive `In-App` notification +- Get old notifications +- Get unread notification count +- Clear unread notifications +- Get user preferences +- Update user preferences + +## Installation + +Package Manager + +```bash +Install-Package StoneRed.NetificationApi +``` + +.NET CLI + +```bash +dotnet add package StoneRed.NetificationApi +``` + +## Usage + +### Server + +```cs +using StoneRed.NetificationApi.Server; +using StoneRed.NetificationApi.Server.Send; + +// Initialize NotificationApiServer +NotificationApiServer notificationApiServer = new NotificationApiServer("", "", secureMode: false); + +// Construct notification +SendNotificationData sendNotificationData = new SendNotificationData +{ + NotificationId = "", + User = new NotificationUser + { + Id = "", + } +}; + +// Send notification +await notificationApiServer.Send(sendNotificationData); +``` + +### Client + +```cs +using StoneRed.NetificationApi.Client; +using StoneRed.NetificationApi.Client.Models; + +// The client is used to receive notifications +NotificationApiClient notificationApiClient = new NotificationApiClient("", ""); + +// Listen for new notifications +notificationApiClient.NewNotificationsReceived += (sender, args) => +{ + Console.WriteLine("New notifications received"); + foreach (NotificationReceivedData notificationReceiveData in args.Notifications) + { + Console.WriteLine($"New notification received: {notificationReceiveData.Id}"); + } +}; + +// Listen for unread count +notificationApiClient.UnreadCountReceived += (sender, args) => +{ + Console.WriteLine($"Unread count received: {args.Count}"); +}; + +// Request unread count +notificationApiClient.RequestUnreadCount(); +``` + +For a more sophisticated example, please check out this [example](https://github.com/Stone-Red-Software/StoneRed.NetificationApi/blob/main/src/StoneRed.NetificationApi.Example/Program.cs). + +# Third party licenses +- [Websocket.Client](https://github.com/Marfusios/websocket-client) - [MIT](https://github.com/Marfusios/websocket-client/blob/master/LICENSE) diff --git a/src/StoneRed.NetificationApi.Example/Program.cs b/src/StoneRed.NetificationApi.Example/Program.cs index 13cfc30..ef22d51 100644 --- a/src/StoneRed.NetificationApi.Example/Program.cs +++ b/src/StoneRed.NetificationApi.Example/Program.cs @@ -83,6 +83,7 @@ Console.WriteLine("Send notification"); SendNotificationData sendNotificationData = new SendNotificationData { NotificationId = notificationId, + Schedule = DateTime.Now.AddSeconds(10), User = new NotificationUser { Id = userId diff --git a/src/StoneRed.NetificationApi/Client/Models/CountReceivedEventArgs.cs b/src/StoneRed.NetificationApi/Client/Models/CountReceivedEventArgs.cs index a1c21b4..6c1e580 100644 --- a/src/StoneRed.NetificationApi/Client/Models/CountReceivedEventArgs.cs +++ b/src/StoneRed.NetificationApi/Client/Models/CountReceivedEventArgs.cs @@ -1,6 +1,16 @@ namespace StoneRed.NetificationApi.Client.Models; +/// +/// Represents the event arguments for when the count of unread notifications is received. +/// +/// +/// Initializes a new instance of the class with the specified count. +/// +/// The count of unread notifications. public class CountReceivedEventArgs(int count) : EventArgs { + /// + /// Gets the count of unread notifications. + /// public int Count { get; } = count; } \ No newline at end of file diff --git a/src/StoneRed.NetificationApi/Client/Models/NotificationChannelPreference.cs b/src/StoneRed.NetificationApi/Client/Models/NotificationChannelPreference.cs index 8e117b4..be03e14 100644 --- a/src/StoneRed.NetificationApi/Client/Models/NotificationChannelPreference.cs +++ b/src/StoneRed.NetificationApi/Client/Models/NotificationChannelPreference.cs @@ -4,13 +4,32 @@ using System.Diagnostics.CodeAnalysis; namespace StoneRed.NetificationApi.Client.Models; +/// +/// Represents a preference for a notification channel. +/// public class NotificationChannelPreference { + /// + /// Gets or sets the channel to set the preference for. + /// public NotificationChannel Channel { get; set; } + /// + /// Gets or sets the state of the preference. + /// public bool State { get; set; } + + /// + /// Gets or sets the sub notification id. + /// public string? SubNotificationId { get; set; } + /// + /// Initializes a new instance of the class. + /// + /// The channel to set the preference for. + /// The state of the preference. + /// The sub notification id. [SetsRequiredMembers] public NotificationChannelPreference(NotificationChannel channel, bool state, string? subNotificationId = null) { @@ -19,6 +38,9 @@ public class NotificationChannelPreference SubNotificationId = subNotificationId; } + /// + /// Initializes a new instance of the class. + /// public NotificationChannelPreference() { } diff --git a/src/StoneRed.NetificationApi/Client/Models/NotificationReceivedData.cs b/src/StoneRed.NetificationApi/Client/Models/NotificationReceivedData.cs index bfadba8..107788b 100644 --- a/src/StoneRed.NetificationApi/Client/Models/NotificationReceivedData.cs +++ b/src/StoneRed.NetificationApi/Client/Models/NotificationReceivedData.cs @@ -1,11 +1,37 @@ namespace StoneRed.NetificationApi.Client.Models; +/// +/// Represents the data of a notification received. +/// public class NotificationReceivedData { + /// + /// Gets or sets the ID of the notification. + /// public required string Id { get; set; } + + /// + /// Gets or sets a value indicating whether the notification has been seen. + /// public required bool Seen { get; set; } + + /// + /// Gets or sets the title of the notification. + /// public required string Title { get; set; } + + /// + /// Gets or sets the redirect URL of the notification. + /// public required string RedirectURL { get; set; } + + /// + /// Gets or sets the image URL of the notification. + /// public required string ImageURL { get; set; } + + /// + /// Gets or sets the date of the notification. + /// public required DateTime Date { get; set; } } \ No newline at end of file diff --git a/src/StoneRed.NetificationApi/Client/Models/NotificationUserPreference.cs b/src/StoneRed.NetificationApi/Client/Models/NotificationUserPreference.cs index 9ff5f02..9da94f8 100644 --- a/src/StoneRed.NetificationApi/Client/Models/NotificationUserPreference.cs +++ b/src/StoneRed.NetificationApi/Client/Models/NotificationUserPreference.cs @@ -1,9 +1,27 @@ namespace StoneRed.NetificationApi.Client.Models; +/// +/// Represents a user's preference for a notification. +/// public class NotificationUserPreference { + /// + /// Gets or sets the notification ID. + /// public required string NotificationId { get; set; } + + /// + /// Gets or sets the title of the notification. + /// public required string Title { get; set; } + + /// + /// Gets or sets the list of settings for the notification. + /// public required List Settings { get; set; } + + /// + /// Gets or sets the list of sub-notification preferences. + /// 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 index 2f59790..35a5870 100644 --- a/src/StoneRed.NetificationApi/Client/Models/NotificationUserPreferenceSetting.cs +++ b/src/StoneRed.NetificationApi/Client/Models/NotificationUserPreferenceSetting.cs @@ -2,9 +2,23 @@ namespace StoneRed.NetificationApi.Client.Models; +/// +/// Represents a user preference setting for a notification channel. +/// public class NotificationUserPreferenceSetting { + /// + /// Gets or sets the notification channel. + /// public required NotificationChannel Channel { get; set; } + + /// + /// Gets or sets the state of the user preference. + /// public bool State { get; set; } + + /// + /// Gets or sets the name of the notification channel. + /// public required string ChannelName { get; set; } } \ No newline at end of file diff --git a/src/StoneRed.NetificationApi/Client/Models/NotificationsReceivedEventArgs.cs b/src/StoneRed.NetificationApi/Client/Models/NotificationsReceivedEventArgs.cs index 6728dbd..429d9f9 100644 --- a/src/StoneRed.NetificationApi/Client/Models/NotificationsReceivedEventArgs.cs +++ b/src/StoneRed.NetificationApi/Client/Models/NotificationsReceivedEventArgs.cs @@ -1,6 +1,16 @@ namespace StoneRed.NetificationApi.Client.Models; +/// +/// Represents the event arguments for notifications received. +/// +/// +/// Initializes a new instance of the class. +/// +/// The list of notifications received. public class NotificationsReceivedEventArgs(List notifications) : EventArgs { + /// + /// Gets or sets the list of notifications received. + /// public List Notifications { get; set; } = notifications; } \ No newline at end of file diff --git a/src/StoneRed.NetificationApi/Client/Models/UserPreferencesReceivedEventArgs.cs b/src/StoneRed.NetificationApi/Client/Models/UserPreferencesReceivedEventArgs.cs index 97e434a..7a339aa 100644 --- a/src/StoneRed.NetificationApi/Client/Models/UserPreferencesReceivedEventArgs.cs +++ b/src/StoneRed.NetificationApi/Client/Models/UserPreferencesReceivedEventArgs.cs @@ -1,6 +1,16 @@ namespace StoneRed.NetificationApi.Client.Models; +/// +/// Represents the event arguments for when user preferences are received. +/// +/// +/// Initializes a new instance of the class. +/// +/// The list of user preferences. public class UserPreferencesReceivedEventArgs(List userPreferences) { + /// + /// Gets or sets the list of user preferences. + /// 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 1889bde..e179351 100644 --- a/src/StoneRed.NetificationApi/Client/NotificationApiClient.cs +++ b/src/StoneRed.NetificationApi/Client/NotificationApiClient.cs @@ -13,18 +13,40 @@ using Websocket.Client; namespace StoneRed.NetificationApi.Client; +/// +/// Represents a client for interacting with the Notification API. +/// public class NotificationApiClient { + /// + /// Event that is raised when requested notifications are received. + /// public event EventHandler? RequestedNotificationsReceived; + /// + /// Event that is raised when new notifications are received. + /// public event EventHandler? NewNotificationsReceived; + /// + /// Event that is raised when the unread count is received. + /// public event EventHandler? UnreadCountReceived; + /// + /// Event that is raised when user preferences are received. + /// public event EventHandler? UserPreferencesReceived; private readonly WebsocketClient client; + /// + /// Initializes a new instance of the class. + /// + /// The user ID. + /// The client ID. + /// The user ID hash. + /// The base address of the WebSocket server. public NotificationApiClient(string userId, string clientId, string? userIdHash = null, string baseAddress = "wss://ws.notificationapi.com") { UriBuilder uriBuilder = new UriBuilder(baseAddress); @@ -104,11 +126,20 @@ public class NotificationApiClient }); } + /// + /// Starts the Websocket client. + /// + /// A task representing the asynchronous operation. public Task Start() { return client.StartOrFail(); } + /// + /// Requests notifications from the server. + /// + /// The number of notifications to request. + /// True if the request was sent successfully; otherwise, false. public bool RequestNotifications(int count) { WebsocketMessage message = new("inapp_web/notifications") @@ -119,6 +150,10 @@ public class NotificationApiClient return client.Send(JsonSerializer.Serialize(message, Configuration.JsonSerializerOptions)); } + /// + /// Requests the unread count from the server. + /// + /// True if the request was sent successfully; otherwise, false. public bool RequestUnreadCount() { WebsocketMessage message = new("inapp_web/unread_count"); @@ -126,6 +161,10 @@ public class NotificationApiClient return client.Send(JsonSerializer.Serialize(message, Configuration.JsonSerializerOptions)); } + /// + /// Clears the unread count on the server. + /// + /// True if the request was sent successfully; otherwise, false. public bool ClearUnread() { WebsocketMessage message = new("inapp_web/unread_clear"); @@ -133,6 +172,11 @@ public class NotificationApiClient return client.Send(JsonSerializer.Serialize(message, Configuration.JsonSerializerOptions)); } + /// + /// Clears the unread count for a specific notification on the server. + /// + /// The ID of the notification to clear. + /// True if the request was sent successfully; otherwise, false. public bool ClearUnread(string notificationId) { WebsocketMessage message = new("inapp_web/unread_clear") @@ -146,6 +190,10 @@ public class NotificationApiClient return client.Send(JsonSerializer.Serialize(message, Configuration.JsonSerializerOptions)); } + /// + /// Requests the user preferences from the server. + /// + /// True if the request was sent successfully; otherwise, false. public bool RequestUserPreferences() { WebsocketMessage message = new("user_preferences/get_preferences"); @@ -153,17 +201,23 @@ public class NotificationApiClient return client.Send(JsonSerializer.Serialize(message, Configuration.JsonSerializerOptions)); } + /// + /// Patches the user preferences for a specific notification on the server. + /// + /// The ID of the notification to patch. + /// The channel preferences to patch. + /// True if the request was sent successfully; otherwise, false. public bool PatchUserPreferences(string notificationId, params NotificationChannelPreference[] channelPreferences) { WebsocketMessage message = new("user_preferences/patch_preferences") { Payload = new object[] { - new - { - notificationId, - channelPreferences - } + new + { + notificationId, + channelPreferences + } } }; @@ -172,6 +226,10 @@ public class NotificationApiClient return client.Send(msg); } + /// + /// Stops the Websocket client. + /// + /// A task representing the asynchronous operation. public Task Stop() { return client.StopOrFail(WebSocketCloseStatus.NormalClosure, "Normal closure"); diff --git a/src/StoneRed.NetificationApi/Server/IdentifyUser/IdentifyUserData.cs b/src/StoneRed.NetificationApi/Server/IdentifyUser/IdentifyUserData.cs index 7ce2932..92fbefa 100644 --- a/src/StoneRed.NetificationApi/Server/IdentifyUser/IdentifyUserData.cs +++ b/src/StoneRed.NetificationApi/Server/IdentifyUser/IdentifyUserData.cs @@ -3,25 +3,51 @@ using System.Text.Json.Serialization; namespace StoneRed.NetificationApi.Server.IdentifyUser; +/// +/// Represents the data for identifying a user. +/// public class IdentifyUserData { + /// + /// Gets or sets the user ID. + /// [JsonIgnore] public required string UserId { get; set; } + /// + /// Gets or sets the email address of the user. + /// public string? Email { get; set; } + /// + /// Gets or sets the telephone number of the user. + /// [JsonPropertyName("number")] public string? TelephoneNumber { get; set; } + /// + /// Gets or sets the list of push tokens for the user. + /// public List? PushTokens { get; set; } + + /// + /// Gets or sets the list of web push tokens for the user. + /// public List? WebPushTokens { get; set; } + /// + /// Initializes a new instance of the class with the specified user ID. + /// + /// The user ID. [SetsRequiredMembers] public IdentifyUserData(string userId) { UserId = userId; } + /// + /// Initializes a new instance of the class. + /// public IdentifyUserData() { } diff --git a/src/StoneRed.NetificationApi/Server/IdentifyUser/NotificationPushProviders.cs b/src/StoneRed.NetificationApi/Server/IdentifyUser/NotificationPushProviders.cs index db6b577..abab35d 100644 --- a/src/StoneRed.NetificationApi/Server/IdentifyUser/NotificationPushProviders.cs +++ b/src/StoneRed.NetificationApi/Server/IdentifyUser/NotificationPushProviders.cs @@ -1,7 +1,17 @@ namespace StoneRed.NetificationApi.Server.IdentifyUser; +/// +/// Represents the notification push providers. +/// public enum NotificationPushProviders { + /// + /// Firebase Cloud Messaging. + /// FCM, + + /// + /// Apple Push Notification service. + /// APM } \ No newline at end of file diff --git a/src/StoneRed.NetificationApi/Server/IdentifyUser/NotificationPushToken.cs b/src/StoneRed.NetificationApi/Server/IdentifyUser/NotificationPushToken.cs index 39d3290..26b01dd 100644 --- a/src/StoneRed.NetificationApi/Server/IdentifyUser/NotificationPushToken.cs +++ b/src/StoneRed.NetificationApi/Server/IdentifyUser/NotificationPushToken.cs @@ -2,12 +2,32 @@ namespace StoneRed.NetificationApi.Server.IdentifyUser; +/// +/// Represents a notification push token. +/// public class NotificationPushToken { + /// + /// Gets or sets the type of the notification push provider. + /// public required NotificationPushProviders Type { get; set; } + + /// + /// Gets or sets the token value. + /// public required string Token { get; set; } + + /// + /// Gets or sets the device associated with the token. + /// public required NotificationPushTokenDevice Device { get; set; } + /// + /// Initializes a new instance of the class. + /// + /// The type of the notification push provider. + /// The token value. + /// The device associated with the token. [SetsRequiredMembers] public NotificationPushToken(NotificationPushProviders type, string token, NotificationPushTokenDevice device) { @@ -16,6 +36,9 @@ public class NotificationPushToken Device = device; } + /// + /// Initializes a new instance of the class. + /// public NotificationPushToken() { } diff --git a/src/StoneRed.NetificationApi/Server/IdentifyUser/NotificationPushTokenDevice.cs b/src/StoneRed.NetificationApi/Server/IdentifyUser/NotificationPushTokenDevice.cs index 08b1bd2..01e1b25 100644 --- a/src/StoneRed.NetificationApi/Server/IdentifyUser/NotificationPushTokenDevice.cs +++ b/src/StoneRed.NetificationApi/Server/IdentifyUser/NotificationPushTokenDevice.cs @@ -3,27 +3,57 @@ using System.Text.Json.Serialization; namespace StoneRed.NetificationApi.Server.IdentifyUser; +/// +/// Represents a notification push token device. +/// public class NotificationPushTokenDevice { + /// + /// Gets or sets the app ID. + /// [JsonPropertyName("app_id")] public string? AppId { get; set; } + /// + /// Gets or sets the ad ID. + /// [JsonPropertyName("ad_id")] public string? AdId { get; set; } + /// + /// Gets or sets the device ID. + /// [JsonPropertyName("device_id")] public required string DeviceId { get; set; } + /// + /// Gets or sets the platform. + /// public string? Platform { get; set; } + + /// + /// Gets or sets the manufacturer. + /// public string? Manufacturer { get; set; } + + /// + /// Gets or sets the model. + /// public string? Model { get; set; } + /// + /// Initializes a new instance of the class. + /// + /// The device ID. [SetsRequiredMembers] public NotificationPushTokenDevice(string deviceId) { DeviceId = deviceId; } + /// + /// Initializes a new instance of the class. + /// public NotificationPushTokenDevice() { } diff --git a/src/StoneRed.NetificationApi/Server/IdentifyUser/NotificationWebPushToken.cs b/src/StoneRed.NetificationApi/Server/IdentifyUser/NotificationWebPushToken.cs index f91bd2d..e79e5da 100644 --- a/src/StoneRed.NetificationApi/Server/IdentifyUser/NotificationWebPushToken.cs +++ b/src/StoneRed.NetificationApi/Server/IdentifyUser/NotificationWebPushToken.cs @@ -2,16 +2,29 @@ namespace StoneRed.NetificationApi.Server.IdentifyUser; +/// +/// Represents a notification web push token. +/// public class NotificationWebPushToken { + /// + /// Gets or sets the sub property of the notification web push token. + /// public required NotificationWebPushTokenSub Sub { get; set; } + /// + /// Initializes a new instance of the class with the specified sub. + /// + /// The sub value. [SetsRequiredMembers] public NotificationWebPushToken(NotificationWebPushTokenSub sub) { Sub = sub; } + /// + /// Initializes a new instance of the class. + /// public NotificationWebPushToken() { } diff --git a/src/StoneRed.NetificationApi/Server/IdentifyUser/NotificationWebPushTokenKeys.cs b/src/StoneRed.NetificationApi/Server/IdentifyUser/NotificationWebPushTokenKeys.cs index c6a76a9..d384c45 100644 --- a/src/StoneRed.NetificationApi/Server/IdentifyUser/NotificationWebPushTokenKeys.cs +++ b/src/StoneRed.NetificationApi/Server/IdentifyUser/NotificationWebPushTokenKeys.cs @@ -2,11 +2,26 @@ namespace StoneRed.NetificationApi.Server.IdentifyUser; +/// +/// Represents the keys required for a web push notification token. +/// public class NotificationWebPushTokenKeys { + /// + /// Gets or sets the P256dh key. + /// public required string P256dh { get; set; } + + /// + /// Gets or sets the Auth key. + /// public required string Auth { get; set; } + /// + /// Initializes a new instance of the class. + /// + /// The P256dh key. + /// The Auth key. [SetsRequiredMembers] public NotificationWebPushTokenKeys(string p256dh, string auth) { @@ -14,6 +29,9 @@ public class NotificationWebPushTokenKeys Auth = auth; } + /// + /// Initializes a new instance of the class. + /// public NotificationWebPushTokenKeys() { } diff --git a/src/StoneRed.NetificationApi/Server/IdentifyUser/NotificationWebPushTokenSub.cs b/src/StoneRed.NetificationApi/Server/IdentifyUser/NotificationWebPushTokenSub.cs index 371c97f..a97ad91 100644 --- a/src/StoneRed.NetificationApi/Server/IdentifyUser/NotificationWebPushTokenSub.cs +++ b/src/StoneRed.NetificationApi/Server/IdentifyUser/NotificationWebPushTokenSub.cs @@ -2,11 +2,26 @@ namespace StoneRed.NetificationApi.Server.IdentifyUser; +/// +/// Represents a subscription for web push notifications. +/// public class NotificationWebPushTokenSub { + /// + /// Gets or sets the endpoint of the web push notification. + /// public required string Endpoint { get; set; } + + /// + /// Gets or sets the keys for the web push notification. + /// public required NotificationWebPushTokenKeys Keys { get; set; } + /// + /// Initializes a new instance of the class. + /// + /// The endpoint of the web push notification. + /// The keys for the web push notification. [SetsRequiredMembers] public NotificationWebPushTokenSub(string endpoint, NotificationWebPushTokenKeys keys) { @@ -14,6 +29,9 @@ public class NotificationWebPushTokenSub Keys = keys; } + /// + /// Initializes a new instance of the class. + /// public NotificationWebPushTokenSub() { } diff --git a/src/StoneRed.NetificationApi/Server/NotificationApiServer.cs b/src/StoneRed.NetificationApi/Server/NotificationApiServer.cs index 954f04a..803ac97 100644 --- a/src/StoneRed.NetificationApi/Server/NotificationApiServer.cs +++ b/src/StoneRed.NetificationApi/Server/NotificationApiServer.cs @@ -9,6 +9,9 @@ using System.Text; namespace StoneRed.NetificationApi.Server; +/// +/// Represents a server for the Notification API. +/// public class NotificationApiServer { private readonly string clientId; @@ -16,12 +19,27 @@ public class NotificationApiServer private readonly bool secureMode; private readonly HttpClient httpClient; + /// + /// Initializes a new instance of the class. + /// + /// The client ID. + /// The client secret. + /// Indicates whether secure mode is enabled. + /// The base address of the API. public NotificationApiServer(string clientId, string clientSecret, bool secureMode, string baseAddress = "https://api.notificationapi.com") : this(new HttpClient(), clientId, clientSecret, secureMode, baseAddress) { this.clientId = clientId; this.clientSecret = clientSecret; } + /// + /// Initializes a new instance of the class. + /// + /// The HTTP client. + /// The client ID. + /// The client secret. + /// Indicates whether secure mode is enabled. + /// The base address of the API. public NotificationApiServer(HttpClient httpClient, string clientId, string clientSecret, bool secureMode, string baseAddress = "https://api.notificationapi.com") { string authToken = Convert.ToBase64String(Encoding.ASCII.GetBytes($"{clientId}:{clientSecret}")); @@ -35,16 +53,31 @@ public class NotificationApiServer this.httpClient = httpClient; } + /// + /// Sends a notification. + /// + /// The data for sending the notification. + /// The HTTP response message. public async Task Send(SendNotificationData sendNotificationData) { return await httpClient.PostAsJsonAsync("sender", sendNotificationData, Configuration.JsonSerializerOptions); } + /// + /// Retracts a notification. + /// + /// The data for retracting the notification. + /// The HTTP response message. public async Task Retract(RetractNotificationData retractNotificationData) { return await httpClient.PostAsJsonAsync("sender/retract", retractNotificationData, Configuration.JsonSerializerOptions); } + /// + /// Identifies a user. + /// + /// The data for identifying the user. + /// The HTTP response message. public async Task Identify(IdentifyUserData identifyUserData) { string authToken; @@ -75,6 +108,11 @@ public class NotificationApiServer return await httpClient.SendAsync(request); } + /// + /// Sets user preferences. + /// + /// The data for setting user preferences. + /// The HTTP response message. public async Task SetUserPreferences(SetUserPreferencesData setUserPreferencesData) { return await httpClient.PostAsJsonAsync($"user_preferences/{setUserPreferencesData.UserId}", setUserPreferencesData, Configuration.JsonSerializerOptions); diff --git a/src/StoneRed.NetificationApi/Server/Retract/RetractNotificationData.cs b/src/StoneRed.NetificationApi/Server/Retract/RetractNotificationData.cs index 55985d8..ea52812 100644 --- a/src/StoneRed.NetificationApi/Server/Retract/RetractNotificationData.cs +++ b/src/StoneRed.NetificationApi/Server/Retract/RetractNotificationData.cs @@ -2,14 +2,31 @@ namespace StoneRed.NetificationApi.Server.Retract; +/// +/// Represents the data required to retract a notification. +/// public class RetractNotificationData { + /// + /// Gets or sets the user ID. + /// public required string UserId { get; set; } + /// + /// Gets or sets the notification ID. + /// public required string NotificationId { get; set; } + /// + /// Gets or sets the secondary ID. + /// public string? SecondaryId { get; set; } + /// + /// Initializes a new instance of the class. + /// + /// The user ID. + /// The notification ID. [SetsRequiredMembers] public RetractNotificationData(string userId, string notificationId) { @@ -17,6 +34,9 @@ public class RetractNotificationData NotificationId = notificationId; } + /// + /// Initializes a new instance of the class. + /// public RetractNotificationData() { } diff --git a/src/StoneRed.NetificationApi/Server/Send/NotificationApnOptions.cs b/src/StoneRed.NetificationApi/Server/Send/NotificationApnOptions.cs index f4df57a..23cb499 100644 --- a/src/StoneRed.NetificationApi/Server/Send/NotificationApnOptions.cs +++ b/src/StoneRed.NetificationApi/Server/Send/NotificationApnOptions.cs @@ -1,18 +1,42 @@ namespace StoneRed.NetificationApi.Server.Send; +/// +/// Represents the options for sending APN (Apple Push Notification) notifications. +/// public class NotificationApnOptions { + /// + /// Gets or sets the expiry time of the notification. + /// public int? Expiry { get; set; } + /// + /// Gets or sets the priority of the notification. + /// public int? Priority { get; set; } + /// + /// Gets or sets the collapse identifier of the notification. + /// public string? CollapseId { get; set; } + /// + /// Gets or sets the thread identifier of the notification. + /// public string? ThreadId { get; set; } + /// + /// Gets or sets the badge count of the notification. + /// public int? Badge { get; set; } + /// + /// Gets or sets the sound of the notification. + /// public string? Sound { get; set; } + /// + /// Gets or sets a value indicating whether the notification content is available. + /// public bool? ContentAvailable { get; set; } } \ No newline at end of file diff --git a/src/StoneRed.NetificationApi/Server/Send/NotificationEmailAttachments.cs b/src/StoneRed.NetificationApi/Server/Send/NotificationEmailAttachments.cs index acab24a..1b7e3d3 100644 --- a/src/StoneRed.NetificationApi/Server/Send/NotificationEmailAttachments.cs +++ b/src/StoneRed.NetificationApi/Server/Send/NotificationEmailAttachments.cs @@ -2,12 +2,26 @@ namespace StoneRed.NetificationApi.Server.Send; -internal class NotificationEmailAttachments +/// +/// Represents an email attachment for notification emails. +/// +public class NotificationEmailAttachments { + /// + /// Gets or sets the file name of the attachment. + /// public required string FileName { get; set; } + /// + /// Gets or sets the URL of the attachment. + /// public required string Url { get; set; } + /// + /// Initializes a new instance of the class. + /// + /// The file name of the attachment. + /// The URL of the attachment. [SetsRequiredMembers] public NotificationEmailAttachments(string fileName, string url) { @@ -15,6 +29,9 @@ internal class NotificationEmailAttachments Url = url; } + /// + /// Initializes a new instance of the class. + /// public NotificationEmailAttachments() { } diff --git a/src/StoneRed.NetificationApi/Server/Send/NotificationEmailOptions.cs b/src/StoneRed.NetificationApi/Server/Send/NotificationEmailOptions.cs index 9136bc6..8e27de7 100644 --- a/src/StoneRed.NetificationApi/Server/Send/NotificationEmailOptions.cs +++ b/src/StoneRed.NetificationApi/Server/Send/NotificationEmailOptions.cs @@ -1,12 +1,27 @@ namespace StoneRed.NetificationApi.Server.Send; +/// +/// Represents the options for a notification email. +/// public class NotificationEmailOptions { + /// + /// Gets or sets the reply-to addresses for the email. + /// public string[]? ReplyToAddresses { get; set; } + /// + /// Gets or sets the CC (carbon copy) addresses for the email. + /// public string[]? CcAddresses { get; set; } + /// + /// Gets or sets the BCC (blind carbon copy) addresses for the email. + /// public string[]? BccAddresses { get; set; } - public string[]? Attachments { get; set; } + /// + /// Gets or sets the attachments for the email. + /// + public NotificationEmailAttachments[]? Attachments { get; set; } } \ No newline at end of file diff --git a/src/StoneRed.NetificationApi/Server/Send/NotificationFcmAndroidOptions.cs b/src/StoneRed.NetificationApi/Server/Send/NotificationFcmAndroidOptions.cs index 4ad5dc6..e8fb591 100644 --- a/src/StoneRed.NetificationApi/Server/Send/NotificationFcmAndroidOptions.cs +++ b/src/StoneRed.NetificationApi/Server/Send/NotificationFcmAndroidOptions.cs @@ -1,10 +1,22 @@ namespace StoneRed.NetificationApi.Server.Send; -internal class NotificationFcmAndroidOptions +/// +/// Represents the options for sending FCM notifications to Android devices. +/// +public class NotificationFcmAndroidOptions { + /// + /// Gets or sets the collapse key for the notification. + /// public string? CollapseKey { get; set; } + /// + /// Gets or sets the priority of the notification. + /// public string? Priority { get; set; } + /// + /// Gets or sets the time to live (TTL) for the notification. + /// public string? Ttl { get; set; } } \ No newline at end of file diff --git a/src/StoneRed.NetificationApi/Server/Send/NotificationFcmOptions.cs b/src/StoneRed.NetificationApi/Server/Send/NotificationFcmOptions.cs index 8c7c44e..49e78bc 100644 --- a/src/StoneRed.NetificationApi/Server/Send/NotificationFcmOptions.cs +++ b/src/StoneRed.NetificationApi/Server/Send/NotificationFcmOptions.cs @@ -1,6 +1,12 @@ namespace StoneRed.NetificationApi.Server.Send; -internal class NotificationFcmOptions +/// +/// Represents the options for sending FCM notifications. +/// +public class NotificationFcmOptions { + /// + /// Gets or sets the Android-specific options for FCM notifications. + /// public NotificationFcmAndroidOptions? Android { get; set; } } \ No newline at end of file diff --git a/src/StoneRed.NetificationApi/Server/Send/NotificationOptions.cs b/src/StoneRed.NetificationApi/Server/Send/NotificationOptions.cs index efe1fcb..07e7b19 100644 --- a/src/StoneRed.NetificationApi/Server/Send/NotificationOptions.cs +++ b/src/StoneRed.NetificationApi/Server/Send/NotificationOptions.cs @@ -1,8 +1,22 @@ namespace StoneRed.NetificationApi.Server.Send; +/// +/// Represents the options for sending a notification. +/// public class NotificationOptions { + /// + /// Gets or sets the email notification options. + /// public NotificationEmailOptions? Email { get; set; } + /// + /// Gets or sets the Apple Push Notification (APN) options. + /// public NotificationApnOptions? Apn { get; set; } + + /// + /// Gets or sets the Firebase Cloud Messaging (FCM) options. + /// + public NotificationFcmOptions? Fcm { get; set; } } \ No newline at end of file diff --git a/src/StoneRed.NetificationApi/Server/Send/NotificationUser.cs b/src/StoneRed.NetificationApi/Server/Send/NotificationUser.cs index bc75217..32f7415 100644 --- a/src/StoneRed.NetificationApi/Server/Send/NotificationUser.cs +++ b/src/StoneRed.NetificationApi/Server/Send/NotificationUser.cs @@ -3,19 +3,38 @@ using System.Text.Json.Serialization; namespace StoneRed.NetificationApi.Server.Send; +/// +/// Represents a notification user. +/// public class NotificationUser { + /// + /// Gets or sets the ID of the user. + /// public required string Id { get; set; } + /// + /// Gets or sets the email of the user. + /// public string? Email { get; set; } + /// + /// Gets or sets the telephone number of the user. + /// [JsonPropertyName("number")] public string? TelephoneNumber { get; set; } + /// + /// Initializes a new instance of the class. + /// public NotificationUser() { } + /// + /// Initializes a new instance of the class with the specified ID. + /// + /// The ID of the user. [SetsRequiredMembers] public NotificationUser(string id) { diff --git a/src/StoneRed.NetificationApi/Server/Send/SendNotificationData.cs b/src/StoneRed.NetificationApi/Server/Send/SendNotificationData.cs index 56b8adc..cba313e 100644 --- a/src/StoneRed.NetificationApi/Server/Send/SendNotificationData.cs +++ b/src/StoneRed.NetificationApi/Server/Send/SendNotificationData.cs @@ -2,21 +2,56 @@ namespace StoneRed.NetificationApi.Server.Send; +/// +/// Represents the data for sending a notification. +/// public class SendNotificationData { + /// + /// Gets or sets the notification ID. + /// public required string NotificationId { get; set; } + /// + /// Gets or sets the sub-notification ID. + /// public string? SubNotificationId { get; set; } + /// + /// Gets or sets the template ID. + /// public string? TemplateId { get; set; } + /// + /// Gets or sets the user for the notification. + /// public required NotificationUser User { get; set; } + /// + /// Gets or sets the merge tags for the notification. + /// public Dictionary? MergeTags { get; set; } + + /// + /// Gets or sets the replace tags for the notification. + /// public Dictionary? Replace { get; set; } + /// + /// Gets or sets the time when the notification should be scheduled. + /// + public DateTime? Schedule { get; set; } + + /// + /// Gets or sets the options for the notification. + /// public NotificationOptions? Options { get; set; } + /// + /// Initializes a new instance of the class. + /// + /// The notification ID. + /// The user for the notification. [SetsRequiredMembers] public SendNotificationData(string notificationId, NotificationUser user) { @@ -24,6 +59,9 @@ public class SendNotificationData User = user; } + /// + /// Initializes a new instance of the class. + /// public SendNotificationData() { } diff --git a/src/StoneRed.NetificationApi/Server/SetUserPreferences/NotificationPreference.cs b/src/StoneRed.NetificationApi/Server/SetUserPreferences/NotificationPreference.cs index 2502d54..3e52e41 100644 --- a/src/StoneRed.NetificationApi/Server/SetUserPreferences/NotificationPreference.cs +++ b/src/StoneRed.NetificationApi/Server/SetUserPreferences/NotificationPreference.cs @@ -4,14 +4,32 @@ using System.Diagnostics.CodeAnalysis; namespace StoneRed.NetificationApi.Server.SetUserPreferences; +/// +/// Represents a notification preference for a user. +/// public class NotificationPreference { + /// + /// Gets or sets the notification ID. + /// public required string NotificationId { get; set; } + /// + /// Gets or sets the notification channel. + /// public required NotificationChannel Channel { get; set; } + /// + /// Gets or sets the state of the notification preference. + /// public required bool State { get; set; } + /// + /// Initializes a new instance of the class. + /// + /// The notification ID. + /// The notification channel. + /// The state of the notification preference. [SetsRequiredMembers] public NotificationPreference(string notificationId, NotificationChannel channel, bool state) { @@ -20,6 +38,9 @@ public class NotificationPreference State = state; } + /// + /// Initializes a new instance of the class. + /// public NotificationPreference() { } diff --git a/src/StoneRed.NetificationApi/Server/SetUserPreferences/SetUserPreferencesData.cs b/src/StoneRed.NetificationApi/Server/SetUserPreferences/SetUserPreferencesData.cs index 951a02d..5e7be5f 100644 --- a/src/StoneRed.NetificationApi/Server/SetUserPreferences/SetUserPreferencesData.cs +++ b/src/StoneRed.NetificationApi/Server/SetUserPreferences/SetUserPreferencesData.cs @@ -3,13 +3,27 @@ using System.Text.Json.Serialization; namespace StoneRed.NetificationApi.Server.SetUserPreferences; +/// +/// Represents the data for setting user preferences. +/// public class SetUserPreferencesData { + /// + /// Gets or sets the user ID. + /// [JsonIgnore] public required string UserId { get; set; } + /// + /// Gets or sets the list of notification preferences. + /// public required List Preferences { get; set; } + /// + /// Initializes a new instance of the class. + /// + /// The user ID. + /// The list of notification preferences. [SetsRequiredMembers] public SetUserPreferencesData(string userId, List preferences) { @@ -17,6 +31,9 @@ public class SetUserPreferencesData Preferences = preferences; } + /// + /// Initializes a new instance of the class. + /// public SetUserPreferencesData() { } diff --git a/src/StoneRed.NetificationApi/Shared/NotificationChannels.cs b/src/StoneRed.NetificationApi/Shared/NotificationChannels.cs index 0a067c4..81f1595 100644 --- a/src/StoneRed.NetificationApi/Shared/NotificationChannels.cs +++ b/src/StoneRed.NetificationApi/Shared/NotificationChannels.cs @@ -1,11 +1,37 @@ namespace StoneRed.NetificationApi.Shared; +/// +/// Represents the available notification channels. +/// public enum NotificationChannel { + /// + /// Email notification channel. + /// EMAIL, + + /// + /// In-app web notification channel. + /// INAPP_WEB, + + /// + /// Web push notification channel. + /// WEB_PUSH, + + /// + /// SMS notification channel. + /// SMS, + + /// + /// Push notification channel. + /// PUSH, + + /// + /// Call notification channel. + /// CALL } \ No newline at end of file diff --git a/src/StoneRed.NetificationApi/StoneRed.NetificationApi.csproj b/src/StoneRed.NetificationApi/StoneRed.NetificationApi.csproj index 114f131..d558442 100644 --- a/src/StoneRed.NetificationApi/StoneRed.NetificationApi.csproj +++ b/src/StoneRed.NetificationApi/StoneRed.NetificationApi.csproj @@ -4,8 +4,23 @@ net8.0 enable enable + True + 1.0.3.0 + https://github.com/Stone-Red-Software/StoneRed.NetificationApi + MIT + A .NET library for NotificationAPI + https://github.com/Stone-Red-Software/StoneRed.NetificationApi + README.md + True + + + True + \ + + + diff --git a/src/StoneRed.NetificationApi/Utilities/UserIdHasher.cs b/src/StoneRed.NetificationApi/Utilities/UserIdHasher.cs index 1fdd103..c074a1a 100644 --- a/src/StoneRed.NetificationApi/Utilities/UserIdHasher.cs +++ b/src/StoneRed.NetificationApi/Utilities/UserIdHasher.cs @@ -3,8 +3,17 @@ using System.Text; namespace StoneRed.NetificationApi.Utilities; +/// +/// Provides methods for hashing user IDs. +/// public static class UserIdHasher { + /// + /// Hashes the specified user ID using the provided client secret. + /// + /// The user ID to hash. + /// The client secret used for hashing. + /// The hashed user ID. public static string Hash(string userId, string clientSecret) { using HMACSHA256 hmac = new HMACSHA256(Encoding.ASCII.GetBytes(clientSecret));