diff --git a/Tranga.sln.DotSettings b/Tranga.sln.DotSettings
index 672ec3b..e47766a 100644
--- a/Tranga.sln.DotSettings
+++ b/Tranga.sln.DotSettings
@@ -9,5 +9,6 @@
True
True
True
+ True
True
True
\ No newline at end of file
diff --git a/Tranga/NotificationConnectors/NotificationConnector.cs b/Tranga/NotificationConnectors/NotificationConnector.cs
index c497657..51b9469 100644
--- a/Tranga/NotificationConnectors/NotificationConnector.cs
+++ b/Tranga/NotificationConnectors/NotificationConnector.cs
@@ -10,7 +10,7 @@ public abstract class NotificationConnector : GlobalBase
this.notificationConnectorType = notificationConnectorType;
}
- public enum NotificationConnectorType : byte { Gotify = 0, LunaSea = 1 }
+ public enum NotificationConnectorType : byte { Gotify = 0, LunaSea = 1, Ntfy = 2 }
public abstract void SendNotification(string title, string notificationText);
}
\ No newline at end of file
diff --git a/Tranga/NotificationConnectors/NotificationManagerJsonConverter.cs b/Tranga/NotificationConnectors/NotificationManagerJsonConverter.cs
index 5214183..c5963c2 100644
--- a/Tranga/NotificationConnectors/NotificationManagerJsonConverter.cs
+++ b/Tranga/NotificationConnectors/NotificationManagerJsonConverter.cs
@@ -21,11 +21,15 @@ public class NotificationManagerJsonConverter : JsonConverter
JsonSerializer serializer)
{
JObject jo = JObject.Load(reader);
- if (jo["notificationConnectorType"]!.Value() == (byte)NotificationConnector.NotificationConnectorType.Gotify)
- return new Gotify(this._clone, jo.GetValue("endpoint")!.Value()!, jo.GetValue("appToken")!.Value()!);
- else if (jo["notificationConnectorType"]!.Value() ==
- (byte)NotificationConnector.NotificationConnectorType.LunaSea)
- return new LunaSea(this._clone, jo.GetValue("id")!.Value()!);
+ switch (jo["notificationConnectorType"]!.Value())
+ {
+ case (byte)NotificationConnector.NotificationConnectorType.Gotify:
+ return new Gotify(this._clone, jo.GetValue("endpoint")!.Value()!, jo.GetValue("appToken")!.Value()!);
+ case (byte)NotificationConnector.NotificationConnectorType.LunaSea:
+ return new LunaSea(this._clone, jo.GetValue("id")!.Value()!);
+ case (byte)NotificationConnector.NotificationConnectorType.Ntfy:
+ return new Ntfy(this._clone, jo.GetValue("endpoint")!.Value()!, jo.GetValue("auth")!.Value()!);
+ }
throw new Exception();
}
diff --git a/Tranga/NotificationConnectors/Ntfy.cs b/Tranga/NotificationConnectors/Ntfy.cs
new file mode 100644
index 0000000..a7fed50
--- /dev/null
+++ b/Tranga/NotificationConnectors/Ntfy.cs
@@ -0,0 +1,58 @@
+using System.Text;
+using Newtonsoft.Json;
+
+namespace Tranga.NotificationConnectors;
+
+public class Ntfy : NotificationConnector
+{
+ // ReSharper disable once MemberCanBePrivate.Global
+ public string endpoint { get; init; }
+ private string auth { get; init; }
+ private const string Topic = "tranga";
+ private readonly HttpClient _client = new();
+
+ [JsonConstructor]
+ public Ntfy(GlobalBase clone, string endpoint, string auth) : base(clone, NotificationConnectorType.Ntfy)
+ {
+ if (!baseUrlRex.IsMatch(endpoint))
+ throw new ArgumentException("endpoint does not match pattern");
+ this.endpoint = endpoint;
+ this.auth = auth;
+ }
+
+ public override string ToString()
+ {
+ return $"Ntfy {endpoint} {Topic}";
+ }
+
+ public override void SendNotification(string title, string notificationText)
+ {
+ Log($"Sending notification: {title} - {notificationText}");
+ MessageData message = new(title, notificationText);
+ HttpRequestMessage request = new(HttpMethod.Post, $"{this.endpoint}?auth={this.auth}");
+ request.Content = new StringContent(JsonConvert.SerializeObject(message, Formatting.None), Encoding.UTF8, "application/json");
+ HttpResponseMessage response = _client.Send(request);
+ if (!response.IsSuccessStatusCode)
+ {
+ StreamReader sr = new (response.Content.ReadAsStream());
+ Log($"{response.StatusCode}: {sr.ReadToEnd()}");
+ }
+ }
+
+ private class MessageData
+ {
+ // ReSharper disable UnusedAutoPropertyAccessor.Local
+ public string topic { get; }
+ public string title { get; }
+ public string message { get; }
+ public int priority { get; }
+
+ public MessageData(string title, string message)
+ {
+ this.topic = Topic;
+ this.title = title;
+ this.message = message;
+ this.priority = 3;
+ }
+ }
+}
\ No newline at end of file
diff --git a/Tranga/Server.cs b/Tranga/Server.cs
index 7ba6122..e2c2e1d 100644
--- a/Tranga/Server.cs
+++ b/Tranga/Server.cs
@@ -362,10 +362,7 @@ public class Server : GlobalBase
}
AddNotificationConnector(new Gotify(this, gotifyUrl, gotifyAppToken));
SendResponse(HttpStatusCode.Accepted, response);
- break;
- }
-
- if (notificationConnectorType is NotificationConnector.NotificationConnectorType.LunaSea)
+ }else if (notificationConnectorType is NotificationConnector.NotificationConnectorType.LunaSea)
{
if (!requestVariables.TryGetValue("lunaseaWebhook", out string? lunaseaWebhook))
{
@@ -374,7 +371,20 @@ public class Server : GlobalBase
}
AddNotificationConnector(new LunaSea(this, lunaseaWebhook));
SendResponse(HttpStatusCode.Accepted, response);
- break;
+ }else if (notificationConnectorType is NotificationConnector.NotificationConnectorType.Ntfy)
+ {
+ if (!requestVariables.TryGetValue("ntfyUrl", out string? ntfyUrl) ||
+ !requestVariables.TryGetValue("ntfyAuth", out string? ntfyAuth))
+ {
+ SendResponse(HttpStatusCode.BadRequest, response);
+ break;
+ }
+ AddNotificationConnector(new Ntfy(this, ntfyUrl, ntfyAuth));
+ SendResponse(HttpStatusCode.Accepted, response);
+ }
+ else
+ {
+ SendResponse(HttpStatusCode.BadRequest, response);
}
break;
case "LibraryConnectors/Update":