add webhook support
This commit is contained in:
19
packages/server/src/notifiers/mqtt/mqtt.ts
Normal file
19
packages/server/src/notifiers/mqtt/mqtt.ts
Normal file
@@ -0,0 +1,19 @@
|
|||||||
|
import type { DocumentUpsertEvent } from '@morten-olsen/fluxcurrent-core/services/documents/documents.schemas.js';
|
||||||
|
|
||||||
|
import type { Notifier } from '../notifier.types.ts';
|
||||||
|
|
||||||
|
import type { MqttConfig } from '#root/schemas/schemas.config.ts';
|
||||||
|
|
||||||
|
class MqttNotifier implements Notifier {
|
||||||
|
#config: MqttConfig;
|
||||||
|
|
||||||
|
constructor(config: MqttConfig) {
|
||||||
|
this.#config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
public upsert = async (event: DocumentUpsertEvent) => {
|
||||||
|
console.log('upsert', event);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export { MqttNotifier };
|
||||||
7
packages/server/src/notifiers/notifier.types.ts
Normal file
7
packages/server/src/notifiers/notifier.types.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
import type { DocumentUpsertEvent } from '@morten-olsen/fluxcurrent-core/services/documents/documents.schemas.ts';
|
||||||
|
|
||||||
|
type Notifier = {
|
||||||
|
upsert: (event: DocumentUpsertEvent) => Promise<void>;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type { Notifier };
|
||||||
17
packages/server/src/notifiers/notifiers.ts
Normal file
17
packages/server/src/notifiers/notifiers.ts
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
import type { DocumentUpsertEvent } from '@morten-olsen/fluxcurrent-core/services/documents/documents.schemas.ts';
|
||||||
|
|
||||||
|
import type { Notifier } from './notifier.types.ts';
|
||||||
|
|
||||||
|
class Notifiers {
|
||||||
|
#notifiers: Notifier[];
|
||||||
|
|
||||||
|
constructor(notifiers: Notifier[]) {
|
||||||
|
this.#notifiers = notifiers;
|
||||||
|
}
|
||||||
|
|
||||||
|
public upsert = async (event: DocumentUpsertEvent) => {
|
||||||
|
await Promise.all(this.#notifiers.map((notifier) => notifier.upsert(event)));
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export { Notifiers };
|
||||||
36
packages/server/src/notifiers/webhook/webhook.ts
Normal file
36
packages/server/src/notifiers/webhook/webhook.ts
Normal file
@@ -0,0 +1,36 @@
|
|||||||
|
import { createHmac } from 'crypto';
|
||||||
|
|
||||||
|
import type { DocumentUpsertEvent } from '@morten-olsen/fluxcurrent-core/services/documents/documents.schemas.js';
|
||||||
|
|
||||||
|
import type { Notifier } from '../notifier.types.ts';
|
||||||
|
|
||||||
|
import type { WebhookConfig } from '#root/schemas/schemas.config.ts';
|
||||||
|
|
||||||
|
class WebhookNotifier implements Notifier {
|
||||||
|
#config: WebhookConfig;
|
||||||
|
|
||||||
|
constructor(config: WebhookConfig) {
|
||||||
|
this.#config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
public upsert = async (event: DocumentUpsertEvent) => {
|
||||||
|
const body = JSON.stringify(event);
|
||||||
|
const abortController = new AbortController();
|
||||||
|
const hash = this.#config.secret ? createHmac('sha256', this.#config.secret).update(body).digest('hex') : undefined;
|
||||||
|
await fetch(this.#config.url, {
|
||||||
|
method: 'POST',
|
||||||
|
body: JSON.stringify(event),
|
||||||
|
signal: abortController.signal,
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
'x-verify': hash ?? '',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
abortController.abort();
|
||||||
|
}, 1000);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export { WebhookNotifier };
|
||||||
@@ -15,6 +15,8 @@ const webhookConfigSchema = z.object({
|
|||||||
secret: stringWithEnvSubstitutionSchema.optional(),
|
secret: stringWithEnvSubstitutionSchema.optional(),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
type WebhookConfig = z.infer<typeof webhookConfigSchema>;
|
||||||
|
|
||||||
const mqttConfigSchema = z.object({
|
const mqttConfigSchema = z.object({
|
||||||
type: z.literal('mqtt'),
|
type: z.literal('mqtt'),
|
||||||
url: stringWithEnvSubstitutionSchema,
|
url: stringWithEnvSubstitutionSchema,
|
||||||
@@ -23,6 +25,8 @@ const mqttConfigSchema = z.object({
|
|||||||
baseTopic: stringWithEnvSubstitutionSchema,
|
baseTopic: stringWithEnvSubstitutionSchema,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
type MqttConfig = z.infer<typeof mqttConfigSchema>;
|
||||||
|
|
||||||
const oidcConfigSchema = z.object({
|
const oidcConfigSchema = z.object({
|
||||||
type: z.literal('oidc'),
|
type: z.literal('oidc'),
|
||||||
issuer: stringWithEnvSubstitutionSchema,
|
issuer: stringWithEnvSubstitutionSchema,
|
||||||
@@ -54,4 +58,7 @@ const configSchema = z.object({
|
|||||||
notifications: z.array(notificationsConfigSchema).default([]),
|
notifications: z.array(notificationsConfigSchema).default([]),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
type Config = z.infer<typeof configSchema>;
|
||||||
|
|
||||||
|
export type { WebhookConfig, MqttConfig, Config };
|
||||||
export { webhookConfigSchema, mqttConfigSchema, configSchema };
|
export { webhookConfigSchema, mqttConfigSchema, configSchema };
|
||||||
|
|||||||
Reference in New Issue
Block a user