diff --git a/README.md b/README.md
index 69c7253..df0e885 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,6 @@
+# UPDATE 2023-08-29
+I've begun working on a new version of SynoAI from the ground up which has an administrative interface instead of a config based approach. I will also be taking the opportunity to implement a number of requested features that have been requested for a long time.
+
# SynoAI
A Synology Surveillance Station notification system utilising DeepStack AI, inspired by Christopher Adams' [sssAI](https://github.com/Christofo/sssAI) implementation.
@@ -188,6 +191,8 @@ The Deepstack API is a free to use AI that can identify objects, faces and more.
### CodeProject.AI-Server
+For a full list of supported types see the [CodeProject.AI documentation](https://www.codeproject.com/AI/docs/api/api_reference.html).
+
```json
"AI": {
"Type": "CodeProjectAIServer",
@@ -235,7 +240,8 @@ The webhook notification can be used to make web requests (e.g. API calls) eithe
"Method": "POST",
"Authentication": "Bearer",
"Token": "XYZ.123456",
- "SendImage": "false"
+ "SendImage": false,
+ "AllowInsecureUrl": false
}
```
* Url [required]: The URL to send the image to
@@ -252,7 +258,8 @@ The webhook notification can be used to make web requests (e.g. API calls) eithe
* Bearer
* Token [optional]: The token to use when using Basic Authorization
* ImageField [optional] (Default: ```image```): The field name of the image in the POST data
-* SendImage [optional] (Default: ```true```): The image will be sent to the webhook when the method is POST, PATCH or PUT.
+* SendImage [optional] (Default: ```true```): The image will be sent to the webhook when the method is POST, PATCH or PUT
+* AllowInsecureUrl [optional] (Default: ```false```): Whether to allow an insecure HTTPS connection to the Webhook.
#### Example POST data
The following is example data for when ```SendImage``` is ```false``` and ```SynoAIUrl``` is ```"http://192.168.1.2"```.
diff --git a/SynoAI/Notifiers/Webhook/Webhook.cs b/SynoAI/Notifiers/Webhook/Webhook.cs
index ebe5235..fce9931 100644
--- a/SynoAI/Notifiers/Webhook/Webhook.cs
+++ b/SynoAI/Notifiers/Webhook/Webhook.cs
@@ -1,5 +1,11 @@
using Newtonsoft.Json;
using SynoAI.Models;
+using SynoAI.Services;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Net;
+using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
@@ -45,6 +51,10 @@ internal class Webhook : NotifierBase
/// content-type of multipart/form-data.
///
public bool SendImage { get; set; }
+ ///
+ /// Allow insecure URL Access to the API.
+ ///
+ public bool AllowInsecureUrl { get; set; }
///
/// Sends a notification to the Webhook.
@@ -55,7 +65,7 @@ internal class Webhook : NotifierBase
public override async Task SendAsync(Camera camera, Notification notification, ILogger logger)
{
logger.LogInformation($"{camera.Name}: Webhook: Processing");
- using (HttpClient client = new())
+ using (HttpClient client = GetHttpClient())
{
FileStream fileStream = null;
client.DefaultRequestHeaders.Authorization = GetAuthenticationHeader();
@@ -106,26 +116,34 @@ public override async Task SendAsync(Camera camera, Notification notification, I
logger.LogInformation($"{camera.Name}: Webhook: Calling {Method}.");
HttpResponseMessage response;
- switch (Method)
+ try
+ {
+ switch (Method)
+ {
+ case "DELETE":
+ response = await client.DeleteAsync(Url);
+ break;
+ case "GET":
+ response = await client.GetAsync(Url);
+ break;
+ case "PATCH":
+ response = await client.PatchAsync(Url, content);
+ break;
+ case "POST":
+ response = await client.PostAsync(Url, content);
+ break;
+ case "PUT":
+ response = await client.PutAsync(Url, content);
+ break;
+ default:
+ logger.LogError($"{camera.Name}: Webhook: The method type '{Method}' is not supported.");
+ return;
+ }
+ }
+ catch (Exception ex)
{
- case "DELETE":
- response = await client.DeleteAsync(Url);
- break;
- case "GET":
- response = await client.GetAsync(Url);
- break;
- case "PATCH":
- response = await client.PatchAsync(Url, content);
- break;
- case "POST":
- response = await client.PostAsync(Url, content);
- break;
- case "PUT":
- response = await client.PutAsync(Url, content);
- break;
- default:
- logger.LogError($"{camera.Name}: Webhook: The method type '{Method}' is not supported.");
- return;
+ logger.LogError($"{camera.Name}: Webhook: Unhandled Exception occurred '{ex.Message}'.");
+ return;
}
if (response.IsSuccessStatusCode)
@@ -145,6 +163,24 @@ public override async Task SendAsync(Camera camera, Notification notification, I
}
}
+ ///
+ /// Gets a object for the Webhook request.
+ ///
+ /// A .
+ private HttpClient GetHttpClient()
+ {
+ if (!Config.AllowInsecureUrl)
+ {
+ return new();
+ }
+
+ HttpClientHandler httpClientHandler = new()
+ {
+ ServerCertificateCustomValidationCallback = (message, cert, chain, sslPolicyErrors) => true
+ };
+ return new(httpClientHandler);
+ }
+
///
/// Generates an authentication header for the client.
///
diff --git a/SynoAI/Notifiers/Webhook/WebhookFactory.cs b/SynoAI/Notifiers/Webhook/WebhookFactory.cs
index 3ae5779..34629c0 100644
--- a/SynoAI/Notifiers/Webhook/WebhookFactory.cs
+++ b/SynoAI/Notifiers/Webhook/WebhookFactory.cs
@@ -17,15 +17,17 @@ public override INotifier Create(ILogger logger, IConfigurationSection section)
string method = section.GetValue("Method", "POST");
bool sendImage = section.GetValue("SendImage", true);
bool sendTypes = section.GetValue("SendTypes", false);
+ bool allowInsecureUrl = section.GetValue("AllowInsecureUrl", false);
- Webhook webhook = new Webhook()
+ Webhook webhook = new()
{
Url = url,
Authentication = authentication,
Username = username,
Password = password,
Token = token,
- SendImage = sendImage
+ SendImage = sendImage,
+ AllowInsecureUrl = allowInsecureUrl
};
if (!string.IsNullOrWhiteSpace(imageField))