140 lines
3.0 KiB
TypeScript
140 lines
3.0 KiB
TypeScript
import type {
|
|
SeverityLevel,
|
|
NotificationAction,
|
|
NotificationPayload,
|
|
SendResult,
|
|
} from './types';
|
|
import type { NotifyClient } from './client';
|
|
|
|
/**
|
|
* Builder for creating notifications with a fluent API.
|
|
*/
|
|
export class EventBuilder {
|
|
private readonly client: NotifyClient;
|
|
private readonly eventType: string;
|
|
private title: string = '';
|
|
private message?: string;
|
|
private severity: SeverityLevel = 'info';
|
|
private metadata: Record<string, unknown> = {};
|
|
private actions: NotificationAction[] = [];
|
|
private userId?: string;
|
|
private groupKey?: string;
|
|
private deduplicationKey?: string;
|
|
private expiresAt?: Date;
|
|
|
|
constructor(client: NotifyClient, eventType: string) {
|
|
this.client = client;
|
|
this.eventType = eventType;
|
|
}
|
|
|
|
/**
|
|
* Set the notification title.
|
|
*/
|
|
withTitle(title: string): this {
|
|
this.title = title;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set the notification message.
|
|
*/
|
|
withMessage(message: string): this {
|
|
this.message = message;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set the severity level.
|
|
*/
|
|
withSeverity(severity: SeverityLevel): this {
|
|
this.severity = severity;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set metadata for the notification.
|
|
*/
|
|
withMetadata(metadata: Record<string, unknown>): this {
|
|
this.metadata = { ...this.metadata, ...metadata };
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Add an action button to the notification.
|
|
*/
|
|
withAction(action: NotificationAction): this {
|
|
this.actions.push(action);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set the target user ID.
|
|
*/
|
|
forUser(userId: string): this {
|
|
this.userId = userId;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set the group key for grouping related notifications.
|
|
*/
|
|
withGroupKey(groupKey: string): this {
|
|
this.groupKey = groupKey;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set the deduplication key to prevent duplicate notifications.
|
|
*/
|
|
withDeduplicationKey(key: string): this {
|
|
this.deduplicationKey = key;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set the expiration time for the notification.
|
|
*/
|
|
expiresIn(ms: number): this {
|
|
this.expiresAt = new Date(Date.now() + ms);
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Set the expiration date for the notification.
|
|
*/
|
|
expiresOn(date: Date): this {
|
|
this.expiresAt = date;
|
|
return this;
|
|
}
|
|
|
|
/**
|
|
* Build the notification payload.
|
|
*/
|
|
build(): NotificationPayload {
|
|
if (!this.title) {
|
|
throw new Error('Notification title is required');
|
|
}
|
|
|
|
return {
|
|
eventType: this.eventType,
|
|
title: this.title,
|
|
message: this.message,
|
|
severity: this.severity,
|
|
metadata: Object.keys(this.metadata).length > 0 ? this.metadata : undefined,
|
|
actions: this.actions.length > 0 ? this.actions : undefined,
|
|
userId: this.userId,
|
|
groupKey: this.groupKey,
|
|
deduplicationKey: this.deduplicationKey,
|
|
expiresAt: this.expiresAt?.toISOString(),
|
|
};
|
|
}
|
|
|
|
/**
|
|
* Send the notification.
|
|
*/
|
|
async send(): Promise<SendResult> {
|
|
const payload = this.build();
|
|
return this.client.sendPayload(payload);
|
|
}
|
|
}
|