Crunchy-Downloader/CRD/Utils/Notifications/Providers/WebhookNotificationProvider.cs
Elwador ff3e28093e - Added notification service for webhooks
- Added retry delay for rate limit handling
- Added toggle to control whether auto refresh also adds missing episodes to the queue
- Added configurable delay after each dub download
- Changed encoding preset dialog to show a preview of the FFmpeg command
- Changed play sound on queue empty and execute file on completion to be handled by the notification service
- Changed shutdown PC option to disable once triggered
- Fixed crash with queue persistence
- Fixed crash with audio player
- Fixed subscription countdown on the account page
2026-05-14 21:49:57 +02:00

71 lines
2.7 KiB
C#

using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using CRD.Utils.Http;
using Newtonsoft.Json;
namespace CRD.Utils.Notifications.Providers;
public class WebhookNotificationProvider : INotificationProvider{
public NotificationProviderType Type => NotificationProviderType.Webhook;
public async Task SendAsync(NotificationProviderConfig config, NotificationEvent notificationEvent, CancellationToken cancellationToken = default){
if (string.IsNullOrWhiteSpace(config.Url)){
return;
}
using var request = new HttpRequestMessage(new HttpMethod(string.IsNullOrWhiteSpace(config.Method) ? "POST" : config.Method), config.Url);
foreach (var header in config.Headers){
request.Headers.TryAddWithoutValidation(header.Key, header.Value);
}
var body = BuildBody(config, notificationEvent);
if (!string.IsNullOrEmpty(body)){
request.Content = new StringContent(body, Encoding.UTF8, string.IsNullOrWhiteSpace(config.ContentType) ? "application/json" : config.ContentType);
}
var response = await HttpClientReq.Instance.SendHttpRequest(request, suppressError: false);
if (!response.IsOk){
throw new InvalidOperationException($"Webhook request failed for '{config.Url}'.");
}
}
private static string BuildBody(NotificationProviderConfig config, NotificationEvent notificationEvent){
if (!string.IsNullOrWhiteSpace(config.BodyTemplate)){
return ApplyTemplate(config.BodyTemplate, notificationEvent);
}
var payload = new{
eventType = notificationEvent.Type.ToString(),
title = notificationEvent.Title,
message = notificationEvent.Message,
timestampUtc = notificationEvent.TimestampUtc,
metadata = notificationEvent.Metadata
};
return JsonConvert.SerializeObject(payload);
}
private static string ApplyTemplate(string template, NotificationEvent notificationEvent){
var values = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase){
["eventType"] = notificationEvent.Type.ToString(),
["title"] = notificationEvent.Title,
["message"] = notificationEvent.Message,
["timestampUtc"] = notificationEvent.TimestampUtc.ToString("O")
};
foreach (var pair in notificationEvent.Metadata){
values[pair.Key] = pair.Value;
}
foreach (var pair in values){
template = template.Replace("{{" + pair.Key + "}}", pair.Value, StringComparison.OrdinalIgnoreCase);
}
return template;
}
}