Support apprise(s) webhook URLs and tag forwarding

pull/1163/head
voc0der 2 months ago
parent c52e079453
commit ac86fde443

@ -319,16 +319,32 @@ function sendSlackNotification({body, title, type, url, thumbnail}) {
// Generic
function isLikelyAppriseWebhookURL(webhook_url) {
try {
const url = new URL(webhook_url);
const path = url.pathname.toLowerCase();
const host = url.hostname.toLowerCase();
function parseWebhookURL(webhook_url) {
if (typeof webhook_url !== 'string') return null;
const trimmed_url = webhook_url.trim();
if (!trimmed_url) return null;
let request_url = trimmed_url;
let explicit_apprise = false;
const apprises_match = trimmed_url.match(/^apprises:\/\/(.+)$/i);
const apprise_match = trimmed_url.match(/^apprise:\/\/(.+)$/i);
if (apprises_match) {
request_url = `https://${apprises_match[1]}`;
explicit_apprise = true;
} else if (apprise_match) {
request_url = `http://${apprise_match[1]}`;
explicit_apprise = true;
}
// Apprise commonly exposes /notify[/<key>], while reverse proxies often include /apprise.
return /(^|\/)notify(\/[\w-]{1,128})?\/?$/.test(path) || /(^|\/)apprise(\/|$)/.test(path) || host.includes('apprise');
try {
return {
request_url: request_url,
parsed_url: new URL(request_url),
explicit_apprise: explicit_apprise
};
} catch {
return false;
return null;
}
}
@ -336,9 +352,21 @@ function mapNotificationTypeToAppriseType(type) {
return NOTIFICATION_TYPE_TO_APPRISE_TYPE[type] ? NOTIFICATION_TYPE_TO_APPRISE_TYPE[type] : 'info';
}
function getWebhookPayload(webhook_url, data) {
if (!isLikelyAppriseWebhookURL(webhook_url)) return data;
return {
function isLikelyAppriseWebhookURL(webhook_info) {
if (!webhook_info || !webhook_info['parsed_url']) return false;
if (webhook_info['explicit_apprise']) return true;
const path = webhook_info['parsed_url'].pathname.toLowerCase();
const host = webhook_info['parsed_url'].hostname.toLowerCase();
// Apprise commonly exposes /notify[/<key>], while reverse proxies often include /apprise.
return /(^|\/)notify(\/[\w-]{1,128})?\/?$/.test(path) || /(^|\/)apprise(\/|$)/.test(path) || host.includes('apprise');
}
function getWebhookPayload(webhook_info, data) {
if (!isLikelyAppriseWebhookURL(webhook_info)) return data;
const payload = {
title: data['title'],
body: data['body'],
type: mapNotificationTypeToAppriseType(data['type']),
@ -346,13 +374,20 @@ function getWebhookPayload(webhook_url, data) {
url: data['url'],
thumbnail: data['thumbnail']
};
const apprise_tag = webhook_info['parsed_url'].searchParams.get('tag') || webhook_info['parsed_url'].searchParams.get('tags');
if (apprise_tag) payload['tag'] = apprise_tag;
return payload;
}
function sendGenericNotification(data) {
const webhook_url = config_api.getConfigItem('ytdl_webhook_url');
logger.verbose(`Sending generic notification to ${webhook_url}`);
const payload = getWebhookPayload(webhook_url, data);
fetch(webhook_url, {
const webhook_info = parseWebhookURL(webhook_url);
const request_url = webhook_info ? webhook_info['request_url'] : webhook_url;
logger.verbose(`Sending generic notification to ${request_url}`);
const payload = getWebhookPayload(webhook_info, data);
fetch(request_url, {
method: 'POST',
headers: {
"Content-Type": "application/json"

@ -400,7 +400,7 @@
<mat-form-field class="text-field" color="accent">
<mat-label i18n="webhook URL">Webhook URL</mat-label>
<input placeholder="https://example.com/endpoint/12345" [(ngModel)]="new_config['API']['webhook_URL']" matInput>
<mat-hint>Place endpoint URL here to integrate with services like Zapier, Automatisch, and Apprise (/notify/&lt;key&gt;).</mat-hint>
<mat-hint>Place endpoint URL here to integrate with services like Zapier, Automatisch, and Apprise (/notify/&lt;key&gt; or apprise(s)://...?...).</mat-hint>
</mat-form-field>
</div>
<div class="col-12 mb-2 mt-3">

Loading…
Cancel
Save