feat: generic webhook provider with JSONPath payload extraction
Add a new "webhook" provider type that accepts arbitrary HTTP POST payloads, extracts template variables via user-defined JSONPath mappings, and dispatches notifications through the existing pipeline. Supports three auth modes (HMAC-SHA256, Bearer token, none), bounded JSONPath cache, and 1MB payload limit. Full stack: core provider + event parser, API endpoint, DB migration, capabilities, seeds, default templates (EN/RU), frontend descriptor, i18n.
This commit is contained in:
@@ -12,6 +12,7 @@ import { plankaDescriptor } from './planka';
|
||||
import { schedulerDescriptor } from './scheduler';
|
||||
import { nutDescriptor } from './nut';
|
||||
import { googlePhotosDescriptor } from './google-photos';
|
||||
import { webhookDescriptor } from './webhook';
|
||||
|
||||
const REGISTRY: ReadonlyMap<string, ProviderDescriptor> = new Map([
|
||||
['immich', immichDescriptor],
|
||||
@@ -20,6 +21,7 @@ const REGISTRY: ReadonlyMap<string, ProviderDescriptor> = new Map([
|
||||
['scheduler', schedulerDescriptor],
|
||||
['nut', nutDescriptor],
|
||||
['google_photos', googlePhotosDescriptor],
|
||||
['webhook', webhookDescriptor],
|
||||
]);
|
||||
|
||||
/** Look up a provider descriptor by type. Returns null for unknown types. */
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
import type { ProviderDescriptor } from './types';
|
||||
|
||||
export const webhookDescriptor: ProviderDescriptor = {
|
||||
type: 'webhook',
|
||||
defaultName: 'Generic Webhook',
|
||||
icon: 'mdiWebhook',
|
||||
hasUrl: false,
|
||||
|
||||
configFields: [
|
||||
{
|
||||
key: 'auth_mode', configKey: 'auth_mode',
|
||||
label: 'providers.authMode',
|
||||
type: 'text',
|
||||
placeholder: 'hmac_sha256 | bearer_token | none',
|
||||
defaultValue: 'none',
|
||||
hint: 'providers.authModeHint',
|
||||
},
|
||||
{
|
||||
key: 'webhook_secret', configKey: 'webhook_secret',
|
||||
label: 'providers.webhookSecret', editLabel: 'providers.webhookSecretKeep',
|
||||
type: 'password', optional: true,
|
||||
hint: 'providers.genericWebhookSecretHint',
|
||||
},
|
||||
],
|
||||
|
||||
buildConfig(form, editing) {
|
||||
const config: Record<string, any> = {
|
||||
auth_mode: form.auth_mode || 'none',
|
||||
payload_mappings: form.payload_mappings || [],
|
||||
};
|
||||
if (form.webhook_secret) config.webhook_secret = form.webhook_secret;
|
||||
if (form.event_type_path) config.event_type_path = form.event_type_path;
|
||||
if (form.collection_path) config.collection_path = form.collection_path;
|
||||
return { config };
|
||||
},
|
||||
|
||||
hasConfigChanged(form, existing) {
|
||||
return form.auth_mode !== (existing.auth_mode || 'none') ||
|
||||
!!form.webhook_secret;
|
||||
},
|
||||
|
||||
eventFields: [
|
||||
{ key: 'track_webhook_received', label: 'trackingConfig.webhookReceived', default: true },
|
||||
],
|
||||
|
||||
collectionMeta: null,
|
||||
webhookBased: true,
|
||||
webhookUrlPattern: '/api/webhooks/webhook/{id}',
|
||||
};
|
||||
Reference in New Issue
Block a user