@nice2dev/ui-communication 1.0.4 → 1.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.cjs +17 -2
- package/dist/index.d.ts +9 -1
- package/dist/index.mjs +4665 -2939
- package/dist/services/emailTrackingService.d.ts +279 -0
- package/dist/services/mailMergeService.d.ts +365 -0
- package/dist/services/pstnGatewayService.d.ts +341 -0
- package/dist/services/slackImportService.d.ts +426 -0
- package/package.json +1 -1
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Email Tracking Service for open and click tracking
|
|
3
|
+
* @module @nice2dev/ui-communication/services/emailTrackingService
|
|
4
|
+
* @description Provides tracking pixel generation, link wrapping, and analytics
|
|
5
|
+
* for email campaigns with privacy-compliant options.
|
|
6
|
+
*/
|
|
7
|
+
export type TrackingEventType = 'open' | 'click' | 'bounce' | 'unsubscribe' | 'complaint';
|
|
8
|
+
export interface TrackingEvent {
|
|
9
|
+
/** Unique event ID */
|
|
10
|
+
id: string;
|
|
11
|
+
/** Type of tracking event */
|
|
12
|
+
type: TrackingEventType;
|
|
13
|
+
/** Email message ID */
|
|
14
|
+
messageId: string;
|
|
15
|
+
/** Recipient email (hashed for privacy) */
|
|
16
|
+
recipientHash: string;
|
|
17
|
+
/** Link URL (for click events) */
|
|
18
|
+
url?: string;
|
|
19
|
+
/** Timestamp of the event */
|
|
20
|
+
timestamp: Date;
|
|
21
|
+
/** User agent string */
|
|
22
|
+
userAgent?: string;
|
|
23
|
+
/** IP address (can be anonymized) */
|
|
24
|
+
ipAddress?: string;
|
|
25
|
+
/** Geo location derived from IP */
|
|
26
|
+
geoLocation?: {
|
|
27
|
+
country?: string;
|
|
28
|
+
region?: string;
|
|
29
|
+
city?: string;
|
|
30
|
+
};
|
|
31
|
+
/** Device type */
|
|
32
|
+
device?: 'desktop' | 'mobile' | 'tablet' | 'unknown';
|
|
33
|
+
/** Email client */
|
|
34
|
+
emailClient?: string;
|
|
35
|
+
/** Campaign ID if part of a campaign */
|
|
36
|
+
campaignId?: string;
|
|
37
|
+
}
|
|
38
|
+
export interface TrackingPixelOptions {
|
|
39
|
+
/** Base URL for tracking server */
|
|
40
|
+
trackingServerUrl: string;
|
|
41
|
+
/** Message ID to track */
|
|
42
|
+
messageId: string;
|
|
43
|
+
/** Recipient identifier (will be hashed) */
|
|
44
|
+
recipientId: string;
|
|
45
|
+
/** Campaign ID */
|
|
46
|
+
campaignId?: string;
|
|
47
|
+
/** Custom metadata */
|
|
48
|
+
metadata?: Record<string, string>;
|
|
49
|
+
/** Pixel dimensions (default 1x1) */
|
|
50
|
+
width?: number;
|
|
51
|
+
height?: number;
|
|
52
|
+
}
|
|
53
|
+
export interface TrackedLinkOptions {
|
|
54
|
+
/** Original URL */
|
|
55
|
+
url: string;
|
|
56
|
+
/** Base URL for tracking redirect */
|
|
57
|
+
trackingServerUrl: string;
|
|
58
|
+
/** Message ID */
|
|
59
|
+
messageId: string;
|
|
60
|
+
/** Recipient identifier */
|
|
61
|
+
recipientId: string;
|
|
62
|
+
/** Campaign ID */
|
|
63
|
+
campaignId?: string;
|
|
64
|
+
/** Link position/name for analytics */
|
|
65
|
+
linkName?: string;
|
|
66
|
+
}
|
|
67
|
+
export interface EmailTrackingStats {
|
|
68
|
+
/** Total emails sent */
|
|
69
|
+
sent: number;
|
|
70
|
+
/** Total emails delivered */
|
|
71
|
+
delivered: number;
|
|
72
|
+
/** Total opens (can include duplicates) */
|
|
73
|
+
opens: number;
|
|
74
|
+
/** Unique opens */
|
|
75
|
+
uniqueOpens: number;
|
|
76
|
+
/** Total clicks */
|
|
77
|
+
clicks: number;
|
|
78
|
+
/** Unique clicks */
|
|
79
|
+
uniqueClicks: number;
|
|
80
|
+
/** Bounced emails */
|
|
81
|
+
bounces: number;
|
|
82
|
+
/** Unsubscribes */
|
|
83
|
+
unsubscribes: number;
|
|
84
|
+
/** Spam complaints */
|
|
85
|
+
complaints: number;
|
|
86
|
+
/** Open rate (unique opens / delivered) */
|
|
87
|
+
openRate: number;
|
|
88
|
+
/** Click rate (unique clicks / delivered) */
|
|
89
|
+
clickRate: number;
|
|
90
|
+
/** Click-to-open rate (unique clicks / unique opens) */
|
|
91
|
+
clickToOpenRate: number;
|
|
92
|
+
/** Bounce rate */
|
|
93
|
+
bounceRate: number;
|
|
94
|
+
}
|
|
95
|
+
export interface LinkStats {
|
|
96
|
+
/** Link URL */
|
|
97
|
+
url: string;
|
|
98
|
+
/** Link name/identifier */
|
|
99
|
+
linkName?: string;
|
|
100
|
+
/** Total clicks */
|
|
101
|
+
totalClicks: number;
|
|
102
|
+
/** Unique clicks */
|
|
103
|
+
uniqueClicks: number;
|
|
104
|
+
/** Click share (% of total clicks) */
|
|
105
|
+
clickShare: number;
|
|
106
|
+
}
|
|
107
|
+
export interface EmailTrackingConfig {
|
|
108
|
+
/** Tracking server base URL */
|
|
109
|
+
serverUrl: string;
|
|
110
|
+
/** API key for authentication */
|
|
111
|
+
apiKey?: string;
|
|
112
|
+
/** Whether to anonymize IP addresses */
|
|
113
|
+
anonymizeIp?: boolean;
|
|
114
|
+
/** Enable geo location lookup */
|
|
115
|
+
enableGeoLocation?: boolean;
|
|
116
|
+
/** Custom tracking pixel path */
|
|
117
|
+
pixelPath?: string;
|
|
118
|
+
/** Custom redirect path */
|
|
119
|
+
redirectPath?: string;
|
|
120
|
+
/** Hash algorithm for recipient IDs */
|
|
121
|
+
hashAlgorithm?: 'sha256' | 'sha512' | 'md5';
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Service for tracking email opens and clicks.
|
|
125
|
+
*
|
|
126
|
+
* @example
|
|
127
|
+
* ```tsx
|
|
128
|
+
* const tracking = new EmailTrackingService({
|
|
129
|
+
* serverUrl: 'https://track.example.com',
|
|
130
|
+
* apiKey: 'your-api-key',
|
|
131
|
+
* });
|
|
132
|
+
*
|
|
133
|
+
* // Generate tracking pixel
|
|
134
|
+
* const pixel = tracking.generateTrackingPixel({
|
|
135
|
+
* messageId: 'msg-123',
|
|
136
|
+
* recipientId: 'user@example.com',
|
|
137
|
+
* });
|
|
138
|
+
*
|
|
139
|
+
* // Wrap links for click tracking
|
|
140
|
+
* const trackedHtml = tracking.wrapLinksForTracking(htmlContent, {
|
|
141
|
+
* messageId: 'msg-123',
|
|
142
|
+
* recipientId: 'user@example.com',
|
|
143
|
+
* });
|
|
144
|
+
* ```
|
|
145
|
+
*/
|
|
146
|
+
export declare class EmailTrackingService {
|
|
147
|
+
private config;
|
|
148
|
+
private events;
|
|
149
|
+
private eventListeners;
|
|
150
|
+
constructor(config: EmailTrackingConfig);
|
|
151
|
+
/**
|
|
152
|
+
* Generates a tracking pixel HTML for email opens.
|
|
153
|
+
*/
|
|
154
|
+
generateTrackingPixel(options: Omit<TrackingPixelOptions, 'trackingServerUrl'>): string;
|
|
155
|
+
/**
|
|
156
|
+
* Generates tracking pixel URL only (without HTML).
|
|
157
|
+
*/
|
|
158
|
+
generateTrackingPixelUrl(options: Omit<TrackingPixelOptions, 'trackingServerUrl'>): string;
|
|
159
|
+
/**
|
|
160
|
+
* Wraps a single URL for click tracking.
|
|
161
|
+
*/
|
|
162
|
+
wrapLink(options: Omit<TrackedLinkOptions, 'trackingServerUrl'>): string;
|
|
163
|
+
/**
|
|
164
|
+
* Wraps all links in HTML content for click tracking.
|
|
165
|
+
*/
|
|
166
|
+
wrapLinksForTracking(html: string, options: {
|
|
167
|
+
messageId: string;
|
|
168
|
+
recipientId: string;
|
|
169
|
+
campaignId?: string;
|
|
170
|
+
excludePatterns?: RegExp[];
|
|
171
|
+
}): string;
|
|
172
|
+
/**
|
|
173
|
+
* Records a tracking event.
|
|
174
|
+
*/
|
|
175
|
+
recordEvent(event: Omit<TrackingEvent, 'id' | 'timestamp'>): TrackingEvent;
|
|
176
|
+
/**
|
|
177
|
+
* Parses tracking parameters from a request.
|
|
178
|
+
*/
|
|
179
|
+
parseTrackingParams(params: URLSearchParams): {
|
|
180
|
+
messageId: string;
|
|
181
|
+
recipientHash: string;
|
|
182
|
+
campaignId?: string;
|
|
183
|
+
url?: string;
|
|
184
|
+
linkName?: string;
|
|
185
|
+
metadata?: Record<string, string>;
|
|
186
|
+
} | null;
|
|
187
|
+
/**
|
|
188
|
+
* Calculates tracking statistics for a campaign or message.
|
|
189
|
+
*/
|
|
190
|
+
getStats(filter?: {
|
|
191
|
+
campaignId?: string;
|
|
192
|
+
messageId?: string;
|
|
193
|
+
startDate?: Date;
|
|
194
|
+
endDate?: Date;
|
|
195
|
+
}): EmailTrackingStats;
|
|
196
|
+
/**
|
|
197
|
+
* Gets click statistics per link.
|
|
198
|
+
*/
|
|
199
|
+
getLinkStats(filter?: {
|
|
200
|
+
campaignId?: string;
|
|
201
|
+
messageId?: string;
|
|
202
|
+
}): LinkStats[];
|
|
203
|
+
/**
|
|
204
|
+
* Gets device/client breakdown.
|
|
205
|
+
*/
|
|
206
|
+
getDeviceStats(filter?: {
|
|
207
|
+
campaignId?: string;
|
|
208
|
+
}): Record<string, number>;
|
|
209
|
+
/**
|
|
210
|
+
* Subscribes to tracking events.
|
|
211
|
+
*/
|
|
212
|
+
on(eventType: TrackingEventType, callback: (event: TrackingEvent) => void): () => void;
|
|
213
|
+
/**
|
|
214
|
+
* Subscribes to all tracking events.
|
|
215
|
+
*/
|
|
216
|
+
onAny(callback: (event: TrackingEvent) => void): () => void;
|
|
217
|
+
/**
|
|
218
|
+
* Generates a privacy-compliant unsubscribe link.
|
|
219
|
+
*/
|
|
220
|
+
generateUnsubscribeLink(options: {
|
|
221
|
+
recipientId: string;
|
|
222
|
+
listId?: string;
|
|
223
|
+
}): string;
|
|
224
|
+
/**
|
|
225
|
+
* Generates List-Unsubscribe header value.
|
|
226
|
+
*/
|
|
227
|
+
generateListUnsubscribeHeader(options: {
|
|
228
|
+
recipientId: string;
|
|
229
|
+
listId?: string;
|
|
230
|
+
}): string;
|
|
231
|
+
/**
|
|
232
|
+
* Clears all stored events (for privacy/GDPR compliance).
|
|
233
|
+
*/
|
|
234
|
+
clearEvents(): void;
|
|
235
|
+
/**
|
|
236
|
+
* Exports events for backup/analysis (anonymized).
|
|
237
|
+
*/
|
|
238
|
+
exportEvents(options?: {
|
|
239
|
+
anonymize?: boolean;
|
|
240
|
+
}): TrackingEvent[];
|
|
241
|
+
private buildTrackingParams;
|
|
242
|
+
private hashRecipientId;
|
|
243
|
+
private anonymizeIpAddress;
|
|
244
|
+
private extractLinkName;
|
|
245
|
+
private escapeHtml;
|
|
246
|
+
private generateEventId;
|
|
247
|
+
private notifyListeners;
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Gets or creates the email tracking service singleton.
|
|
251
|
+
*/
|
|
252
|
+
export declare function getEmailTrackingService(config?: EmailTrackingConfig): EmailTrackingService;
|
|
253
|
+
/**
|
|
254
|
+
* Disposes the email tracking service singleton.
|
|
255
|
+
*/
|
|
256
|
+
export declare function disposeEmailTrackingService(): void;
|
|
257
|
+
export interface UseEmailTrackingOptions {
|
|
258
|
+
config?: EmailTrackingConfig;
|
|
259
|
+
campaignId?: string;
|
|
260
|
+
autoRefreshInterval?: number;
|
|
261
|
+
}
|
|
262
|
+
export interface UseEmailTrackingReturn {
|
|
263
|
+
/** Generate tracking pixel HTML */
|
|
264
|
+
generatePixel: (messageId: string, recipientId: string) => string;
|
|
265
|
+
/** Wrap links in HTML for tracking */
|
|
266
|
+
wrapLinks: (html: string, messageId: string, recipientId: string) => string;
|
|
267
|
+
/** Current statistics */
|
|
268
|
+
stats: EmailTrackingStats | null;
|
|
269
|
+
/** Link statistics */
|
|
270
|
+
linkStats: LinkStats[];
|
|
271
|
+
/** Record a tracking event */
|
|
272
|
+
recordEvent: (event: Omit<TrackingEvent, 'id' | 'timestamp'>) => void;
|
|
273
|
+
/** Refresh statistics */
|
|
274
|
+
refreshStats: () => void;
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* React hook for email tracking functionality.
|
|
278
|
+
*/
|
|
279
|
+
export declare function useEmailTracking(options: UseEmailTrackingOptions): UseEmailTrackingReturn;
|
|
@@ -0,0 +1,365 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @fileoverview Mail Merge Service for bulk personalized emails
|
|
3
|
+
* @module @nice2dev/ui-communication/services/mailMergeService
|
|
4
|
+
* @description Provides template processing, variable substitution,
|
|
5
|
+
* recipient management, and batch sending for email campaigns.
|
|
6
|
+
*/
|
|
7
|
+
export type MergeFieldType = 'text' | 'number' | 'date' | 'currency' | 'boolean' | 'list' | 'conditional';
|
|
8
|
+
export interface MergeField {
|
|
9
|
+
/** Field name (used in template as {{fieldName}}) */
|
|
10
|
+
name: string;
|
|
11
|
+
/** Field type for formatting */
|
|
12
|
+
type: MergeFieldType;
|
|
13
|
+
/** Default value if not provided */
|
|
14
|
+
defaultValue?: string | number | boolean;
|
|
15
|
+
/** Whether field is required */
|
|
16
|
+
required?: boolean;
|
|
17
|
+
/** Format string (for dates, numbers, currency) */
|
|
18
|
+
format?: string;
|
|
19
|
+
/** Description for UI */
|
|
20
|
+
description?: string;
|
|
21
|
+
}
|
|
22
|
+
export interface MergeRecipient {
|
|
23
|
+
/** Unique recipient ID */
|
|
24
|
+
id: string;
|
|
25
|
+
/** Primary email address */
|
|
26
|
+
email: string;
|
|
27
|
+
/** Additional email addresses (CC) */
|
|
28
|
+
cc?: string[];
|
|
29
|
+
/** BCC addresses */
|
|
30
|
+
bcc?: string[];
|
|
31
|
+
/** Merge field values */
|
|
32
|
+
data: Record<string, unknown>;
|
|
33
|
+
/** Custom subject override */
|
|
34
|
+
subjectOverride?: string;
|
|
35
|
+
/** Recipient tags for filtering */
|
|
36
|
+
tags?: string[];
|
|
37
|
+
/** Send status */
|
|
38
|
+
status?: 'pending' | 'sent' | 'failed' | 'bounced';
|
|
39
|
+
/** Error message if failed */
|
|
40
|
+
error?: string;
|
|
41
|
+
/** Scheduled send time */
|
|
42
|
+
scheduledAt?: Date;
|
|
43
|
+
}
|
|
44
|
+
export interface MergeTemplate {
|
|
45
|
+
/** Template ID */
|
|
46
|
+
id: string;
|
|
47
|
+
/** Template name */
|
|
48
|
+
name: string;
|
|
49
|
+
/** Email subject (can contain merge fields) */
|
|
50
|
+
subject: string;
|
|
51
|
+
/** HTML body (can contain merge fields) */
|
|
52
|
+
htmlBody: string;
|
|
53
|
+
/** Plain text body (can contain merge fields) */
|
|
54
|
+
textBody?: string;
|
|
55
|
+
/** Defined merge fields */
|
|
56
|
+
fields: MergeField[];
|
|
57
|
+
/** Template tags */
|
|
58
|
+
tags?: string[];
|
|
59
|
+
/** Created timestamp */
|
|
60
|
+
createdAt: Date;
|
|
61
|
+
/** Last modified timestamp */
|
|
62
|
+
updatedAt: Date;
|
|
63
|
+
}
|
|
64
|
+
export interface MergeCampaign {
|
|
65
|
+
/** Campaign ID */
|
|
66
|
+
id: string;
|
|
67
|
+
/** Campaign name */
|
|
68
|
+
name: string;
|
|
69
|
+
/** Template ID */
|
|
70
|
+
templateId: string;
|
|
71
|
+
/** Sender email */
|
|
72
|
+
fromEmail: string;
|
|
73
|
+
/** Sender name */
|
|
74
|
+
fromName: string;
|
|
75
|
+
/** Reply-to address */
|
|
76
|
+
replyTo?: string;
|
|
77
|
+
/** Recipients */
|
|
78
|
+
recipients: MergeRecipient[];
|
|
79
|
+
/** Campaign status */
|
|
80
|
+
status: 'draft' | 'scheduled' | 'sending' | 'paused' | 'completed' | 'cancelled';
|
|
81
|
+
/** Scheduled send time */
|
|
82
|
+
scheduledAt?: Date;
|
|
83
|
+
/** Send rate limit (emails per minute) */
|
|
84
|
+
rateLimit?: number;
|
|
85
|
+
/** Enable tracking */
|
|
86
|
+
enableTracking?: boolean;
|
|
87
|
+
/** Campaign metadata */
|
|
88
|
+
metadata?: Record<string, unknown>;
|
|
89
|
+
/** Created timestamp */
|
|
90
|
+
createdAt: Date;
|
|
91
|
+
/** Started timestamp */
|
|
92
|
+
startedAt?: Date;
|
|
93
|
+
/** Completed timestamp */
|
|
94
|
+
completedAt?: Date;
|
|
95
|
+
}
|
|
96
|
+
export interface MergeProgress {
|
|
97
|
+
/** Campaign ID */
|
|
98
|
+
campaignId: string;
|
|
99
|
+
/** Total recipients */
|
|
100
|
+
total: number;
|
|
101
|
+
/** Sent count */
|
|
102
|
+
sent: number;
|
|
103
|
+
/** Failed count */
|
|
104
|
+
failed: number;
|
|
105
|
+
/** Pending count */
|
|
106
|
+
pending: number;
|
|
107
|
+
/** Current recipient being processed */
|
|
108
|
+
current?: string;
|
|
109
|
+
/** Progress percentage */
|
|
110
|
+
percentage: number;
|
|
111
|
+
/** Estimated time remaining (seconds) */
|
|
112
|
+
estimatedTimeRemaining?: number;
|
|
113
|
+
/** Is complete */
|
|
114
|
+
isComplete: boolean;
|
|
115
|
+
}
|
|
116
|
+
export interface MergeValidationResult {
|
|
117
|
+
/** Is template valid */
|
|
118
|
+
isValid: boolean;
|
|
119
|
+
/** Validation errors */
|
|
120
|
+
errors: MergeValidationError[];
|
|
121
|
+
/** Warnings */
|
|
122
|
+
warnings: MergeValidationWarning[];
|
|
123
|
+
/** Missing fields per recipient */
|
|
124
|
+
missingFields: Map<string, string[]>;
|
|
125
|
+
}
|
|
126
|
+
export interface MergeValidationError {
|
|
127
|
+
/** Error type */
|
|
128
|
+
type: 'missing_field' | 'invalid_format' | 'syntax_error' | 'empty_recipient';
|
|
129
|
+
/** Field name if applicable */
|
|
130
|
+
field?: string;
|
|
131
|
+
/** Recipient ID if applicable */
|
|
132
|
+
recipientId?: string;
|
|
133
|
+
/** Error message */
|
|
134
|
+
message: string;
|
|
135
|
+
}
|
|
136
|
+
export interface MergeValidationWarning {
|
|
137
|
+
/** Warning type */
|
|
138
|
+
type: 'unused_field' | 'long_content' | 'suspicious_content';
|
|
139
|
+
/** Field name if applicable */
|
|
140
|
+
field?: string;
|
|
141
|
+
/** Warning message */
|
|
142
|
+
message: string;
|
|
143
|
+
}
|
|
144
|
+
export interface MailMergeConfig {
|
|
145
|
+
/** Email sending function */
|
|
146
|
+
sendEmail: (email: SendEmailParams) => Promise<{
|
|
147
|
+
success: boolean;
|
|
148
|
+
messageId?: string;
|
|
149
|
+
error?: string;
|
|
150
|
+
}>;
|
|
151
|
+
/** Rate limit (emails per minute, default: 60) */
|
|
152
|
+
rateLimit?: number;
|
|
153
|
+
/** Batch size for processing */
|
|
154
|
+
batchSize?: number;
|
|
155
|
+
/** Retry failed sends */
|
|
156
|
+
retryOnFail?: boolean;
|
|
157
|
+
/** Max retries per recipient */
|
|
158
|
+
maxRetries?: number;
|
|
159
|
+
/** Custom date formatter */
|
|
160
|
+
dateFormatter?: (date: Date, format: string) => string;
|
|
161
|
+
/** Custom number formatter */
|
|
162
|
+
numberFormatter?: (num: number, format: string) => string;
|
|
163
|
+
/** Custom currency formatter */
|
|
164
|
+
currencyFormatter?: (amount: number, currency: string, locale: string) => string;
|
|
165
|
+
}
|
|
166
|
+
export interface SendEmailParams {
|
|
167
|
+
to: string;
|
|
168
|
+
cc?: string[];
|
|
169
|
+
bcc?: string[];
|
|
170
|
+
from: string;
|
|
171
|
+
fromName?: string;
|
|
172
|
+
replyTo?: string;
|
|
173
|
+
subject: string;
|
|
174
|
+
html: string;
|
|
175
|
+
text?: string;
|
|
176
|
+
headers?: Record<string, string>;
|
|
177
|
+
attachments?: Array<{
|
|
178
|
+
filename: string;
|
|
179
|
+
content: string | Buffer;
|
|
180
|
+
contentType?: string;
|
|
181
|
+
}>;
|
|
182
|
+
}
|
|
183
|
+
/**
|
|
184
|
+
* Service for mail merge and bulk email campaigns with personalization.
|
|
185
|
+
*
|
|
186
|
+
* @example
|
|
187
|
+
* ```tsx
|
|
188
|
+
* const mergeService = new MailMergeService({
|
|
189
|
+
* sendEmail: async (params) => {
|
|
190
|
+
* // Your email sending logic
|
|
191
|
+
* return { success: true, messageId: 'msg-123' };
|
|
192
|
+
* },
|
|
193
|
+
* rateLimit: 100,
|
|
194
|
+
* });
|
|
195
|
+
*
|
|
196
|
+
* // Create template
|
|
197
|
+
* const template = mergeService.createTemplate({
|
|
198
|
+
* name: 'Welcome Email',
|
|
199
|
+
* subject: 'Welcome, {{firstName}}!',
|
|
200
|
+
* htmlBody: '<p>Hello {{firstName}} {{lastName}},</p><p>Welcome to our platform!</p>',
|
|
201
|
+
* fields: [
|
|
202
|
+
* { name: 'firstName', type: 'text', required: true },
|
|
203
|
+
* { name: 'lastName', type: 'text', required: true },
|
|
204
|
+
* ],
|
|
205
|
+
* });
|
|
206
|
+
*
|
|
207
|
+
* // Create campaign
|
|
208
|
+
* const campaign = mergeService.createCampaign({
|
|
209
|
+
* name: 'Welcome Campaign',
|
|
210
|
+
* templateId: template.id,
|
|
211
|
+
* fromEmail: 'hello@example.com',
|
|
212
|
+
* fromName: 'Example Team',
|
|
213
|
+
* recipients: [
|
|
214
|
+
* { id: '1', email: 'john@example.com', data: { firstName: 'John', lastName: 'Doe' } },
|
|
215
|
+
* { id: '2', email: 'jane@example.com', data: { firstName: 'Jane', lastName: 'Smith' } },
|
|
216
|
+
* ],
|
|
217
|
+
* });
|
|
218
|
+
*
|
|
219
|
+
* // Send campaign
|
|
220
|
+
* for await (const progress of mergeService.sendCampaign(campaign.id)) {
|
|
221
|
+
* console.log(`Progress: ${progress.percentage}%`);
|
|
222
|
+
* }
|
|
223
|
+
* ```
|
|
224
|
+
*/
|
|
225
|
+
export declare class MailMergeService {
|
|
226
|
+
private config;
|
|
227
|
+
private templates;
|
|
228
|
+
private campaigns;
|
|
229
|
+
private abortControllers;
|
|
230
|
+
constructor(config: MailMergeConfig);
|
|
231
|
+
/**
|
|
232
|
+
* Creates a new merge template.
|
|
233
|
+
*/
|
|
234
|
+
createTemplate(input: Omit<MergeTemplate, 'id' | 'createdAt' | 'updatedAt'>): MergeTemplate;
|
|
235
|
+
/**
|
|
236
|
+
* Updates an existing template.
|
|
237
|
+
*/
|
|
238
|
+
updateTemplate(id: string, updates: Partial<Omit<MergeTemplate, 'id' | 'createdAt'>>): MergeTemplate;
|
|
239
|
+
/**
|
|
240
|
+
* Gets a template by ID.
|
|
241
|
+
*/
|
|
242
|
+
getTemplate(id: string): MergeTemplate | undefined;
|
|
243
|
+
/**
|
|
244
|
+
* Deletes a template.
|
|
245
|
+
*/
|
|
246
|
+
deleteTemplate(id: string): boolean;
|
|
247
|
+
/**
|
|
248
|
+
* Lists all templates.
|
|
249
|
+
*/
|
|
250
|
+
listTemplates(): MergeTemplate[];
|
|
251
|
+
/**
|
|
252
|
+
* Extracts merge fields from template content.
|
|
253
|
+
*/
|
|
254
|
+
extractFields(content: string): string[];
|
|
255
|
+
/**
|
|
256
|
+
* Creates a new mail merge campaign.
|
|
257
|
+
*/
|
|
258
|
+
createCampaign(input: Omit<MergeCampaign, 'id' | 'status' | 'createdAt'>): MergeCampaign;
|
|
259
|
+
/**
|
|
260
|
+
* Gets a campaign by ID.
|
|
261
|
+
*/
|
|
262
|
+
getCampaign(id: string): MergeCampaign | undefined;
|
|
263
|
+
/**
|
|
264
|
+
* Updates a campaign.
|
|
265
|
+
*/
|
|
266
|
+
updateCampaign(id: string, updates: Partial<Omit<MergeCampaign, 'id' | 'createdAt'>>): MergeCampaign;
|
|
267
|
+
/**
|
|
268
|
+
* Adds recipients to a campaign.
|
|
269
|
+
*/
|
|
270
|
+
addRecipients(campaignId: string, recipients: MergeRecipient[]): void;
|
|
271
|
+
/**
|
|
272
|
+
* Removes a recipient from a campaign.
|
|
273
|
+
*/
|
|
274
|
+
removeRecipient(campaignId: string, recipientId: string): boolean;
|
|
275
|
+
/**
|
|
276
|
+
* Lists all campaigns.
|
|
277
|
+
*/
|
|
278
|
+
listCampaigns(): MergeCampaign[];
|
|
279
|
+
/**
|
|
280
|
+
* Validates a campaign before sending.
|
|
281
|
+
*/
|
|
282
|
+
validateCampaign(campaignId: string): MergeValidationResult;
|
|
283
|
+
/**
|
|
284
|
+
* Previews merged content for a specific recipient.
|
|
285
|
+
*/
|
|
286
|
+
previewMerge(templateId: string, recipientData: Record<string, unknown>): {
|
|
287
|
+
subject: string;
|
|
288
|
+
html: string;
|
|
289
|
+
text?: string;
|
|
290
|
+
};
|
|
291
|
+
/**
|
|
292
|
+
* Sends a campaign. Returns an async generator for progress updates.
|
|
293
|
+
*/
|
|
294
|
+
sendCampaign(campaignId: string): AsyncGenerator<MergeProgress, void, unknown>;
|
|
295
|
+
/**
|
|
296
|
+
* Pauses a running campaign.
|
|
297
|
+
*/
|
|
298
|
+
pauseCampaign(campaignId: string): void;
|
|
299
|
+
/**
|
|
300
|
+
* Resumes a paused campaign.
|
|
301
|
+
*/
|
|
302
|
+
resumeCampaign(campaignId: string): AsyncGenerator<MergeProgress, void, unknown>;
|
|
303
|
+
/**
|
|
304
|
+
* Cancels a campaign.
|
|
305
|
+
*/
|
|
306
|
+
cancelCampaign(campaignId: string): void;
|
|
307
|
+
/**
|
|
308
|
+
* Retries failed recipients in a campaign.
|
|
309
|
+
*/
|
|
310
|
+
retryFailed(campaignId: string): AsyncGenerator<MergeProgress, void, unknown>;
|
|
311
|
+
private processTemplate;
|
|
312
|
+
private processConditionals;
|
|
313
|
+
private processLoops;
|
|
314
|
+
private formatValue;
|
|
315
|
+
private applyFormatter;
|
|
316
|
+
private getNestedValue;
|
|
317
|
+
private isTruthy;
|
|
318
|
+
private defaultDateFormatter;
|
|
319
|
+
private defaultNumberFormatter;
|
|
320
|
+
private defaultCurrencyFormatter;
|
|
321
|
+
private generateId;
|
|
322
|
+
private escapeHtml;
|
|
323
|
+
private delay;
|
|
324
|
+
}
|
|
325
|
+
/**
|
|
326
|
+
* Gets or creates the mail merge service singleton.
|
|
327
|
+
*/
|
|
328
|
+
export declare function getMailMergeService(config?: MailMergeConfig): MailMergeService;
|
|
329
|
+
/**
|
|
330
|
+
* Disposes the mail merge service singleton.
|
|
331
|
+
*/
|
|
332
|
+
export declare function disposeMailMergeService(): void;
|
|
333
|
+
export interface UseMailMergeOptions {
|
|
334
|
+
config?: MailMergeConfig;
|
|
335
|
+
}
|
|
336
|
+
export interface UseMailMergeReturn {
|
|
337
|
+
/** Create a merge template */
|
|
338
|
+
createTemplate: (input: Omit<MergeTemplate, 'id' | 'createdAt' | 'updatedAt'>) => MergeTemplate;
|
|
339
|
+
/** Create a campaign */
|
|
340
|
+
createCampaign: (input: Omit<MergeCampaign, 'id' | 'status' | 'createdAt'>) => MergeCampaign;
|
|
341
|
+
/** Preview merge for a recipient */
|
|
342
|
+
preview: (templateId: string, data: Record<string, unknown>) => {
|
|
343
|
+
subject: string;
|
|
344
|
+
html: string;
|
|
345
|
+
text?: string;
|
|
346
|
+
};
|
|
347
|
+
/** Validate a campaign */
|
|
348
|
+
validate: (campaignId: string) => MergeValidationResult;
|
|
349
|
+
/** Send campaign (returns progress generator) */
|
|
350
|
+
send: (campaignId: string) => AsyncGenerator<MergeProgress, void, unknown>;
|
|
351
|
+
/** Pause sending */
|
|
352
|
+
pause: (campaignId: string) => void;
|
|
353
|
+
/** Current progress */
|
|
354
|
+
progress: MergeProgress | null;
|
|
355
|
+
/** Is sending */
|
|
356
|
+
isSending: boolean;
|
|
357
|
+
/** Templates */
|
|
358
|
+
templates: MergeTemplate[];
|
|
359
|
+
/** Campaigns */
|
|
360
|
+
campaigns: MergeCampaign[];
|
|
361
|
+
}
|
|
362
|
+
/**
|
|
363
|
+
* React hook for mail merge functionality.
|
|
364
|
+
*/
|
|
365
|
+
export declare function useMailMerge(options?: UseMailMergeOptions): UseMailMergeReturn;
|