@k-msg/messaging 0.1.0

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.
@@ -0,0 +1,854 @@
1
+ import { z } from 'zod';
2
+ import { EventEmitter } from 'events';
3
+
4
+ interface MessageRequest {
5
+ templateId: string;
6
+ recipients: Recipient[];
7
+ variables: VariableMap;
8
+ scheduling?: SchedulingOptions;
9
+ options?: SendingOptions;
10
+ }
11
+ interface Recipient {
12
+ phoneNumber: string;
13
+ variables?: VariableMap;
14
+ metadata?: Record<string, any>;
15
+ }
16
+ interface VariableMap {
17
+ [key: string]: string | number | Date;
18
+ }
19
+ interface SchedulingOptions {
20
+ scheduledAt: Date;
21
+ timezone?: string;
22
+ retryCount?: number;
23
+ }
24
+ interface SendingOptions {
25
+ priority?: 'high' | 'normal' | 'low';
26
+ ttl?: number;
27
+ failover?: {
28
+ enabled: boolean;
29
+ fallbackChannel?: 'sms' | 'lms';
30
+ fallbackContent?: string;
31
+ };
32
+ deduplication?: {
33
+ enabled: boolean;
34
+ window: number;
35
+ };
36
+ tracking?: {
37
+ enabled: boolean;
38
+ webhookUrl?: string;
39
+ };
40
+ }
41
+ interface MessageResult {
42
+ requestId: string;
43
+ results: RecipientResult[];
44
+ summary: {
45
+ total: number;
46
+ queued: number;
47
+ sent: number;
48
+ failed: number;
49
+ };
50
+ metadata: {
51
+ createdAt: Date;
52
+ provider: string;
53
+ templateId: string;
54
+ };
55
+ }
56
+ interface RecipientResult {
57
+ phoneNumber: string;
58
+ messageId?: string;
59
+ status: MessageStatus;
60
+ error?: MessageError;
61
+ metadata?: Record<string, any>;
62
+ }
63
+ declare enum MessageStatus {
64
+ QUEUED = "QUEUED",// 큐에 대기 중
65
+ SENDING = "SENDING",// 발송 중
66
+ SENT = "SENT",// 발송 완료
67
+ DELIVERED = "DELIVERED",// 전달 완료
68
+ FAILED = "FAILED",// 발송 실패
69
+ CLICKED = "CLICKED",// 버튼 클릭됨
70
+ CANCELLED = "CANCELLED"
71
+ }
72
+ interface MessageError {
73
+ code: string;
74
+ message: string;
75
+ details?: Record<string, any>;
76
+ }
77
+ interface DeliveryReport {
78
+ messageId: string;
79
+ phoneNumber: string;
80
+ status: MessageStatus;
81
+ sentAt?: Date;
82
+ deliveredAt?: Date;
83
+ clickedAt?: Date;
84
+ failedAt?: Date;
85
+ error?: MessageError;
86
+ attempts: DeliveryAttempt[];
87
+ metadata: Record<string, any>;
88
+ }
89
+ interface DeliveryAttempt {
90
+ attemptNumber: number;
91
+ attemptedAt: Date;
92
+ status: MessageStatus;
93
+ error?: MessageError;
94
+ provider: string;
95
+ }
96
+ interface BulkMessageRequest {
97
+ templateId: string;
98
+ recipients: BulkRecipient[];
99
+ commonVariables?: VariableMap;
100
+ options?: BulkSendingOptions;
101
+ }
102
+ interface BulkRecipient {
103
+ phoneNumber: string;
104
+ variables: VariableMap;
105
+ metadata?: Record<string, any>;
106
+ }
107
+ interface BulkSendingOptions extends SendingOptions {
108
+ batchSize?: number;
109
+ batchDelay?: number;
110
+ maxConcurrency?: number;
111
+ }
112
+ interface BulkMessageResult {
113
+ requestId: string;
114
+ totalRecipients: number;
115
+ batches: BulkBatchResult[];
116
+ summary: {
117
+ queued: number;
118
+ sent: number;
119
+ failed: number;
120
+ processing: number;
121
+ };
122
+ createdAt: Date;
123
+ completedAt?: Date;
124
+ }
125
+ interface BulkBatchResult {
126
+ batchId: string;
127
+ batchNumber: number;
128
+ recipients: RecipientResult[];
129
+ status: 'pending' | 'processing' | 'completed' | 'failed';
130
+ createdAt: Date;
131
+ completedAt?: Date;
132
+ }
133
+ declare enum MessageEventType {
134
+ TEMPLATE_CREATED = "template.created",
135
+ TEMPLATE_APPROVED = "template.approved",
136
+ TEMPLATE_REJECTED = "template.rejected",
137
+ TEMPLATE_UPDATED = "template.updated",
138
+ TEMPLATE_DELETED = "template.deleted",
139
+ MESSAGE_QUEUED = "message.queued",
140
+ MESSAGE_SENT = "message.sent",
141
+ MESSAGE_DELIVERED = "message.delivered",
142
+ MESSAGE_FAILED = "message.failed",
143
+ MESSAGE_CLICKED = "message.clicked",
144
+ MESSAGE_CANCELLED = "message.cancelled",
145
+ CHANNEL_CREATED = "channel.created",
146
+ CHANNEL_VERIFIED = "channel.verified",
147
+ SENDER_NUMBER_ADDED = "sender_number.added",
148
+ QUOTA_WARNING = "system.quota_warning",
149
+ QUOTA_EXCEEDED = "system.quota_exceeded",
150
+ PROVIDER_ERROR = "system.provider_error"
151
+ }
152
+ interface MessageEvent<T = any> {
153
+ id: string;
154
+ type: MessageEventType;
155
+ timestamp: Date;
156
+ data: T;
157
+ metadata: {
158
+ providerId?: string;
159
+ userId?: string;
160
+ organizationId?: string;
161
+ correlationId?: string;
162
+ };
163
+ }
164
+ declare const VariableMapSchema: z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodDate]>>;
165
+ declare const RecipientSchema: z.ZodObject<{
166
+ phoneNumber: z.ZodString;
167
+ variables: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodDate]>>>;
168
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
169
+ }, z.core.$strip>;
170
+ declare const SchedulingOptionsSchema: z.ZodObject<{
171
+ scheduledAt: z.ZodDate;
172
+ timezone: z.ZodOptional<z.ZodString>;
173
+ retryCount: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
174
+ }, z.core.$strip>;
175
+ declare const SendingOptionsSchema: z.ZodObject<{
176
+ priority: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
177
+ high: "high";
178
+ normal: "normal";
179
+ low: "low";
180
+ }>>>;
181
+ ttl: z.ZodOptional<z.ZodNumber>;
182
+ failover: z.ZodOptional<z.ZodObject<{
183
+ enabled: z.ZodBoolean;
184
+ fallbackChannel: z.ZodOptional<z.ZodEnum<{
185
+ sms: "sms";
186
+ lms: "lms";
187
+ }>>;
188
+ fallbackContent: z.ZodOptional<z.ZodString>;
189
+ }, z.core.$strip>>;
190
+ deduplication: z.ZodOptional<z.ZodObject<{
191
+ enabled: z.ZodBoolean;
192
+ window: z.ZodNumber;
193
+ }, z.core.$strip>>;
194
+ tracking: z.ZodOptional<z.ZodObject<{
195
+ enabled: z.ZodBoolean;
196
+ webhookUrl: z.ZodOptional<z.ZodString>;
197
+ }, z.core.$strip>>;
198
+ }, z.core.$strip>;
199
+ declare const MessageRequestSchema: z.ZodObject<{
200
+ templateId: z.ZodString;
201
+ recipients: z.ZodArray<z.ZodObject<{
202
+ phoneNumber: z.ZodString;
203
+ variables: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodDate]>>>;
204
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
205
+ }, z.core.$strip>>;
206
+ variables: z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodDate]>>;
207
+ scheduling: z.ZodOptional<z.ZodObject<{
208
+ scheduledAt: z.ZodDate;
209
+ timezone: z.ZodOptional<z.ZodString>;
210
+ retryCount: z.ZodDefault<z.ZodOptional<z.ZodNumber>>;
211
+ }, z.core.$strip>>;
212
+ options: z.ZodOptional<z.ZodObject<{
213
+ priority: z.ZodDefault<z.ZodOptional<z.ZodEnum<{
214
+ high: "high";
215
+ normal: "normal";
216
+ low: "low";
217
+ }>>>;
218
+ ttl: z.ZodOptional<z.ZodNumber>;
219
+ failover: z.ZodOptional<z.ZodObject<{
220
+ enabled: z.ZodBoolean;
221
+ fallbackChannel: z.ZodOptional<z.ZodEnum<{
222
+ sms: "sms";
223
+ lms: "lms";
224
+ }>>;
225
+ fallbackContent: z.ZodOptional<z.ZodString>;
226
+ }, z.core.$strip>>;
227
+ deduplication: z.ZodOptional<z.ZodObject<{
228
+ enabled: z.ZodBoolean;
229
+ window: z.ZodNumber;
230
+ }, z.core.$strip>>;
231
+ tracking: z.ZodOptional<z.ZodObject<{
232
+ enabled: z.ZodBoolean;
233
+ webhookUrl: z.ZodOptional<z.ZodString>;
234
+ }, z.core.$strip>>;
235
+ }, z.core.$strip>>;
236
+ }, z.core.$strip>;
237
+ declare const MessageErrorSchema: z.ZodObject<{
238
+ code: z.ZodString;
239
+ message: z.ZodString;
240
+ details: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
241
+ }, z.core.$strip>;
242
+ declare const RecipientResultSchema: z.ZodObject<{
243
+ phoneNumber: z.ZodString;
244
+ messageId: z.ZodOptional<z.ZodString>;
245
+ status: z.ZodEnum<typeof MessageStatus>;
246
+ error: z.ZodOptional<z.ZodObject<{
247
+ code: z.ZodString;
248
+ message: z.ZodString;
249
+ details: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
250
+ }, z.core.$strip>>;
251
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
252
+ }, z.core.$strip>;
253
+ declare const MessageResultSchema: z.ZodObject<{
254
+ requestId: z.ZodString;
255
+ results: z.ZodArray<z.ZodObject<{
256
+ phoneNumber: z.ZodString;
257
+ messageId: z.ZodOptional<z.ZodString>;
258
+ status: z.ZodEnum<typeof MessageStatus>;
259
+ error: z.ZodOptional<z.ZodObject<{
260
+ code: z.ZodString;
261
+ message: z.ZodString;
262
+ details: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
263
+ }, z.core.$strip>>;
264
+ metadata: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
265
+ }, z.core.$strip>>;
266
+ summary: z.ZodObject<{
267
+ total: z.ZodNumber;
268
+ queued: z.ZodNumber;
269
+ sent: z.ZodNumber;
270
+ failed: z.ZodNumber;
271
+ }, z.core.$strip>;
272
+ metadata: z.ZodObject<{
273
+ createdAt: z.ZodDate;
274
+ provider: z.ZodString;
275
+ templateId: z.ZodString;
276
+ }, z.core.$strip>;
277
+ }, z.core.$strip>;
278
+ type MessageRequestType = z.infer<typeof MessageRequestSchema>;
279
+ type RecipientType = z.infer<typeof RecipientSchema>;
280
+ type MessageResultType = z.infer<typeof MessageResultSchema>;
281
+
282
+ interface Provider {
283
+ id: string;
284
+ name: string;
285
+ send(request: ProviderMessageRequest): Promise<ProviderMessageResult>;
286
+ }
287
+ interface ProviderMessageRequest {
288
+ templateCode: string;
289
+ phoneNumber: string;
290
+ variables: Record<string, any>;
291
+ options?: Record<string, any>;
292
+ }
293
+ interface ProviderMessageResult {
294
+ messageId: string;
295
+ status: MessageStatus;
296
+ error?: {
297
+ code: string;
298
+ message: string;
299
+ };
300
+ }
301
+ declare class SingleMessageSender {
302
+ private providers;
303
+ private templates;
304
+ addProvider(provider: Provider): void;
305
+ removeProvider(providerId: string): void;
306
+ send(request: MessageRequest): Promise<MessageResult>;
307
+ private sendToRecipient;
308
+ private getTemplate;
309
+ private calculateSummary;
310
+ private generateRequestId;
311
+ cancelMessage(messageId: string): Promise<boolean>;
312
+ getMessageStatus(messageId: string): Promise<MessageStatus>;
313
+ resendMessage(messageId: string, options?: {
314
+ newRecipient?: string;
315
+ }): Promise<MessageResult>;
316
+ }
317
+
318
+ declare class BulkMessageSender {
319
+ private singleSender;
320
+ private activeBulkJobs;
321
+ constructor(singleSender: SingleMessageSender);
322
+ sendBulk(request: BulkMessageRequest): Promise<BulkMessageResult>;
323
+ private processBatchesAsync;
324
+ private processBatch;
325
+ private processRecipient;
326
+ private createBatches;
327
+ private delay;
328
+ private generateRequestId;
329
+ getBulkStatus(requestId: string): Promise<BulkMessageResult | null>;
330
+ cancelBulkJob(requestId: string): Promise<boolean>;
331
+ retryFailedBatch(requestId: string, batchId: string): Promise<BulkBatchResult | null>;
332
+ cleanup(): void;
333
+ }
334
+
335
+ /**
336
+ * Job processor for message queue system
337
+ */
338
+
339
+ interface Job<T = any> {
340
+ id: string;
341
+ type: string;
342
+ data: T;
343
+ priority: number;
344
+ attempts: number;
345
+ maxAttempts: number;
346
+ delay: number;
347
+ createdAt: Date;
348
+ processAt: Date;
349
+ completedAt?: Date;
350
+ failedAt?: Date;
351
+ error?: string;
352
+ metadata: Record<string, any>;
353
+ }
354
+ interface JobProcessorOptions {
355
+ concurrency: number;
356
+ retryDelays: number[];
357
+ maxRetries: number;
358
+ pollInterval: number;
359
+ enableMetrics: boolean;
360
+ rateLimiter?: {
361
+ maxRequests: number;
362
+ windowMs: number;
363
+ };
364
+ circuitBreaker?: {
365
+ failureThreshold: number;
366
+ timeout: number;
367
+ resetTimeout: number;
368
+ };
369
+ }
370
+ interface JobHandler<T = any> {
371
+ (job: Job<T>): Promise<any>;
372
+ }
373
+ interface JobProcessorMetrics {
374
+ processed: number;
375
+ succeeded: number;
376
+ failed: number;
377
+ retried: number;
378
+ activeJobs: number;
379
+ queueSize: number;
380
+ averageProcessingTime: number;
381
+ lastProcessedAt?: Date;
382
+ }
383
+ declare class JobProcessor extends EventEmitter {
384
+ private options;
385
+ private handlers;
386
+ private queue;
387
+ private processing;
388
+ private isRunning;
389
+ private pollTimer?;
390
+ private metrics;
391
+ private rateLimiter?;
392
+ private circuitBreaker?;
393
+ constructor(options: JobProcessorOptions);
394
+ /**
395
+ * Register a job handler
396
+ */
397
+ handle<T>(jobType: string, handler: JobHandler<T>): void;
398
+ /**
399
+ * Add a job to the queue
400
+ */
401
+ add<T>(jobType: string, data: T, options?: {
402
+ priority?: number;
403
+ delay?: number;
404
+ maxAttempts?: number;
405
+ metadata?: Record<string, any>;
406
+ }): Promise<string>;
407
+ /**
408
+ * Start processing jobs
409
+ */
410
+ start(): void;
411
+ /**
412
+ * Stop processing jobs
413
+ */
414
+ stop(): Promise<void>;
415
+ /**
416
+ * Get current metrics
417
+ */
418
+ getMetrics(): JobProcessorMetrics;
419
+ /**
420
+ * Get queue status
421
+ */
422
+ getQueueStatus(): {
423
+ pending: number;
424
+ processing: number;
425
+ failed: number;
426
+ totalProcessed: number;
427
+ };
428
+ /**
429
+ * Remove completed jobs from queue
430
+ */
431
+ cleanup(): number;
432
+ /**
433
+ * Get specific job by ID
434
+ */
435
+ getJob(jobId: string): Job | undefined;
436
+ /**
437
+ * Remove job from queue
438
+ */
439
+ removeJob(jobId: string): boolean;
440
+ private scheduleNextPoll;
441
+ private processJobs;
442
+ private processJob;
443
+ private failJob;
444
+ private getRetryDelay;
445
+ private updateMetrics;
446
+ private updateAverageProcessingTime;
447
+ }
448
+ /**
449
+ * Specific processor for message jobs
450
+ */
451
+ declare class MessageJobProcessor extends JobProcessor {
452
+ constructor(options?: Partial<JobProcessorOptions>);
453
+ private setupMessageHandlers;
454
+ private processSingleMessage;
455
+ private processBulkMessages;
456
+ private processDeliveryUpdate;
457
+ private processScheduledMessage;
458
+ /**
459
+ * Add a message to the processing queue
460
+ */
461
+ queueMessage(messageRequest: MessageRequest, options?: {
462
+ priority?: number;
463
+ delay?: number;
464
+ metadata?: Record<string, any>;
465
+ }): Promise<string>;
466
+ /**
467
+ * Add bulk messages to the processing queue
468
+ */
469
+ queueBulkMessages(messageRequests: MessageRequest[], options?: {
470
+ priority?: number;
471
+ delay?: number;
472
+ metadata?: Record<string, any>;
473
+ }): Promise<string>;
474
+ /**
475
+ * Schedule a message for future delivery
476
+ */
477
+ scheduleMessage(messageRequest: MessageRequest, scheduledAt: Date, options?: {
478
+ metadata?: Record<string, any>;
479
+ }): Promise<string>;
480
+ }
481
+
482
+ /**
483
+ * Retry handler for failed message deliveries
484
+ */
485
+
486
+ interface RetryPolicy {
487
+ maxAttempts: number;
488
+ backoffMultiplier: number;
489
+ initialDelay: number;
490
+ maxDelay: number;
491
+ jitter: boolean;
492
+ retryableStatuses: MessageStatus[];
493
+ retryableErrorCodes: string[];
494
+ }
495
+ interface RetryAttempt {
496
+ messageId: string;
497
+ phoneNumber: string;
498
+ attemptNumber: number;
499
+ scheduledAt: Date;
500
+ provider: string;
501
+ templateId: string;
502
+ variables: Record<string, any>;
503
+ metadata: Record<string, any>;
504
+ }
505
+ interface RetryQueueItem {
506
+ id: string;
507
+ messageId: string;
508
+ phoneNumber: string;
509
+ originalDeliveryReport: DeliveryReport;
510
+ attempts: RetryAttempt[];
511
+ nextRetryAt: Date;
512
+ status: 'pending' | 'processing' | 'exhausted' | 'cancelled';
513
+ createdAt: Date;
514
+ updatedAt: Date;
515
+ }
516
+ interface RetryHandlerOptions {
517
+ policy: RetryPolicy;
518
+ checkInterval: number;
519
+ maxQueueSize: number;
520
+ enablePersistence: boolean;
521
+ onRetryExhausted?: (item: RetryQueueItem) => Promise<void>;
522
+ onRetrySuccess?: (item: RetryQueueItem, result: any) => Promise<void>;
523
+ onRetryFailed?: (item: RetryQueueItem, error: Error) => Promise<void>;
524
+ }
525
+ interface RetryHandlerMetrics {
526
+ totalRetries: number;
527
+ successfulRetries: number;
528
+ failedRetries: number;
529
+ exhaustedRetries: number;
530
+ queueSize: number;
531
+ averageRetryDelay: number;
532
+ lastRetryAt?: Date;
533
+ }
534
+ declare class MessageRetryHandler extends EventEmitter {
535
+ private options;
536
+ private retryQueue;
537
+ private processing;
538
+ private checkTimer?;
539
+ private isRunning;
540
+ private metrics;
541
+ private defaultPolicy;
542
+ constructor(options: RetryHandlerOptions);
543
+ /**
544
+ * Start the retry handler
545
+ */
546
+ start(): void;
547
+ /**
548
+ * Stop the retry handler
549
+ */
550
+ stop(): Promise<void>;
551
+ /**
552
+ * Add a failed delivery for retry
553
+ */
554
+ addForRetry(deliveryReport: DeliveryReport): Promise<boolean>;
555
+ /**
556
+ * Cancel retry for a specific message
557
+ */
558
+ cancelRetry(messageId: string): boolean;
559
+ /**
560
+ * Get retry status for a message
561
+ */
562
+ getRetryStatus(messageId: string): RetryQueueItem | undefined;
563
+ /**
564
+ * Get all retry queue items
565
+ */
566
+ getRetryQueue(): RetryQueueItem[];
567
+ /**
568
+ * Get metrics
569
+ */
570
+ getMetrics(): RetryHandlerMetrics;
571
+ /**
572
+ * Clean up completed/exhausted retry items
573
+ */
574
+ cleanup(): number;
575
+ private scheduleNextCheck;
576
+ private processRetryQueue;
577
+ private processRetryItem;
578
+ private executeRetry;
579
+ private shouldRetry;
580
+ private createRetryItem;
581
+ private updateRetryItem;
582
+ private calculateRetryDelay;
583
+ private cleanupQueue;
584
+ private updateMetrics;
585
+ }
586
+
587
+ /**
588
+ * Delivery tracking system for messages
589
+ */
590
+
591
+ interface DeliveryTrackingOptions {
592
+ trackingInterval: number;
593
+ maxTrackingDuration: number;
594
+ batchSize: number;
595
+ enableWebhooks: boolean;
596
+ webhookRetries: number;
597
+ webhookTimeout: number;
598
+ persistence: {
599
+ enabled: boolean;
600
+ retentionDays: number;
601
+ };
602
+ }
603
+ interface DeliveryWebhook {
604
+ url: string;
605
+ events: MessageEventType[];
606
+ secret?: string;
607
+ headers?: Record<string, string>;
608
+ timeout: number;
609
+ retries: number;
610
+ }
611
+ interface TrackingRecord {
612
+ messageId: string;
613
+ phoneNumber: string;
614
+ templateId: string;
615
+ provider: string;
616
+ currentStatus: MessageStatus;
617
+ statusHistory: StatusHistoryEntry[];
618
+ deliveryReport: DeliveryReport;
619
+ webhooks: DeliveryWebhook[];
620
+ createdAt: Date;
621
+ updatedAt: Date;
622
+ expiresAt: Date;
623
+ metadata: Record<string, any>;
624
+ }
625
+ interface StatusHistoryEntry {
626
+ status: MessageStatus;
627
+ timestamp: Date;
628
+ provider: string;
629
+ details?: Record<string, any>;
630
+ source: 'provider' | 'webhook' | 'manual' | 'system';
631
+ }
632
+ interface DeliveryStats {
633
+ totalMessages: number;
634
+ byStatus: Record<MessageStatus, number>;
635
+ byProvider: Record<string, number>;
636
+ averageDeliveryTime: number;
637
+ deliveryRate: number;
638
+ failureRate: number;
639
+ lastUpdated: Date;
640
+ }
641
+ declare class DeliveryTracker extends EventEmitter {
642
+ private options;
643
+ private trackingRecords;
644
+ private statusIndex;
645
+ private trackingTimer?;
646
+ private webhookQueue;
647
+ private isRunning;
648
+ private stats;
649
+ private defaultOptions;
650
+ constructor(options: DeliveryTrackingOptions);
651
+ /**
652
+ * Start delivery tracking
653
+ */
654
+ start(): void;
655
+ /**
656
+ * Stop delivery tracking
657
+ */
658
+ stop(): void;
659
+ /**
660
+ * Start tracking a message
661
+ */
662
+ trackMessage(messageId: string, phoneNumber: string, templateId: string, provider: string, options?: {
663
+ webhooks?: DeliveryWebhook[];
664
+ metadata?: Record<string, any>;
665
+ initialStatus?: MessageStatus;
666
+ }): Promise<void>;
667
+ /**
668
+ * Update message status
669
+ */
670
+ updateStatus(messageId: string, status: MessageStatus, details?: {
671
+ provider?: string;
672
+ error?: {
673
+ code: string;
674
+ message: string;
675
+ details?: any;
676
+ };
677
+ metadata?: Record<string, any>;
678
+ source?: 'provider' | 'webhook' | 'manual' | 'system';
679
+ sentAt?: Date;
680
+ deliveredAt?: Date;
681
+ clickedAt?: Date;
682
+ failedAt?: Date;
683
+ }): Promise<boolean>;
684
+ /**
685
+ * Get delivery report for a message
686
+ */
687
+ getDeliveryReport(messageId: string): DeliveryReport | undefined;
688
+ /**
689
+ * Get tracking record for a message
690
+ */
691
+ getTrackingRecord(messageId: string): TrackingRecord | undefined;
692
+ /**
693
+ * Get messages by status
694
+ */
695
+ getMessagesByStatus(status: MessageStatus): TrackingRecord[];
696
+ /**
697
+ * Get delivery statistics
698
+ */
699
+ getStats(): DeliveryStats;
700
+ /**
701
+ * Get delivery statistics for a specific time range
702
+ */
703
+ getStatsForPeriod(startDate: Date, endDate: Date): DeliveryStats;
704
+ /**
705
+ * Clean up expired tracking records
706
+ */
707
+ cleanup(): number;
708
+ /**
709
+ * Stop tracking a specific message
710
+ */
711
+ stopTracking(messageId: string): boolean;
712
+ private scheduleTracking;
713
+ private processTracking;
714
+ private processWebhookQueue;
715
+ private deliverWebhook;
716
+ private sendWebhook;
717
+ private queueWebhook;
718
+ private isStatusProgression;
719
+ private isTerminalStatus;
720
+ private getEventTypeForStatus;
721
+ private updateStats;
722
+ }
723
+
724
+ /**
725
+ * Variable replacement and personalization system
726
+ */
727
+
728
+ interface VariableReplacementOptions {
729
+ variablePattern: RegExp;
730
+ allowUndefined: boolean;
731
+ undefinedReplacement: string;
732
+ caseSensitive: boolean;
733
+ enableFormatting: boolean;
734
+ enableConditionals: boolean;
735
+ enableLoops: boolean;
736
+ maxRecursionDepth: number;
737
+ }
738
+ interface VariableInfo {
739
+ name: string;
740
+ value: any;
741
+ formatted: string;
742
+ type: 'string' | 'number' | 'date' | 'boolean' | 'array' | 'object' | 'undefined';
743
+ position: {
744
+ start: number;
745
+ end: number;
746
+ };
747
+ }
748
+ interface ReplacementResult {
749
+ content: string;
750
+ variables: VariableInfo[];
751
+ missingVariables: string[];
752
+ errors: ReplacementError[];
753
+ metadata: {
754
+ originalLength: number;
755
+ finalLength: number;
756
+ variableCount: number;
757
+ replacementTime: number;
758
+ };
759
+ }
760
+ interface ReplacementError {
761
+ type: 'missing_variable' | 'format_error' | 'syntax_error' | 'recursion_limit';
762
+ message: string;
763
+ variable?: string;
764
+ position?: {
765
+ start: number;
766
+ end: number;
767
+ };
768
+ }
769
+ declare class VariableReplacer {
770
+ private options;
771
+ private defaultOptions;
772
+ constructor(options?: Partial<VariableReplacementOptions>);
773
+ /**
774
+ * Replace variables in content
775
+ */
776
+ replace(content: string, variables: VariableMap): ReplacementResult;
777
+ /**
778
+ * Extract variables from content without replacing
779
+ */
780
+ extractVariables(content: string): string[];
781
+ /**
782
+ * Validate that all required variables are provided
783
+ */
784
+ validate(content: string, variables: VariableMap): {
785
+ isValid: boolean;
786
+ missingVariables: string[];
787
+ errors: ReplacementError[];
788
+ };
789
+ /**
790
+ * Preview replacement result without actually replacing
791
+ */
792
+ preview(content: string, variables: VariableMap): {
793
+ originalContent: string;
794
+ previewContent: string;
795
+ variableHighlights: Array<{
796
+ variable: string;
797
+ value: string;
798
+ positions: Array<{
799
+ start: number;
800
+ end: number;
801
+ }>;
802
+ }>;
803
+ };
804
+ private replaceSimpleVariables;
805
+ private replaceRecursive;
806
+ private processConditionals;
807
+ private processLoops;
808
+ private parseVariableName;
809
+ private getVariableValue;
810
+ private formatValue;
811
+ private formatDate;
812
+ private getValueType;
813
+ private hasVariables;
814
+ private extractConditionals;
815
+ private extractLoops;
816
+ private extractVariablesFromExpression;
817
+ private evaluateCondition;
818
+ private buildConditionalPattern;
819
+ private buildLoopPattern;
820
+ }
821
+ /**
822
+ * Default instance with Korean-optimized settings
823
+ */
824
+ declare const defaultVariableReplacer: VariableReplacer;
825
+ /**
826
+ * Utility functions
827
+ */
828
+ declare const VariableUtils: {
829
+ /**
830
+ * Extract all variables from content
831
+ */
832
+ extractVariables: (content: string) => string[];
833
+ /**
834
+ * Replace variables in content
835
+ */
836
+ replace: (content: string, variables: VariableMap) => string;
837
+ /**
838
+ * Validate content has all required variables
839
+ */
840
+ validate: (content: string, variables: VariableMap) => boolean;
841
+ /**
842
+ * Create personalized content for multiple recipients
843
+ */
844
+ personalize: (content: string, recipients: Array<{
845
+ phoneNumber: string;
846
+ variables: VariableMap;
847
+ }>) => Array<{
848
+ phoneNumber: string;
849
+ content: string;
850
+ errors?: string[];
851
+ }>;
852
+ };
853
+
854
+ export { type BulkBatchResult, type BulkMessageRequest, type BulkMessageResult, BulkMessageSender, type BulkRecipient, type BulkSendingOptions, type DeliveryAttempt, type DeliveryReport, DeliveryTracker, JobProcessor, type MessageError, MessageErrorSchema, type MessageEvent, MessageEventType, MessageJobProcessor, type MessageRequest, MessageRequestSchema, type MessageRequestType, type MessageResult, MessageResultSchema, type MessageResultType, MessageRetryHandler, MessageStatus, type Provider, type ProviderMessageRequest, type ProviderMessageResult, type Recipient, type RecipientResult, RecipientResultSchema, RecipientSchema, type RecipientType, type SchedulingOptions, SchedulingOptionsSchema, type SendingOptions, SendingOptionsSchema, SingleMessageSender, type VariableMap, VariableMapSchema, VariableReplacer, VariableUtils, defaultVariableReplacer };