@skoolite/notify-hub 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.
- package/README.md +452 -0
- package/dist/index.d.mts +1080 -0
- package/dist/index.d.ts +1080 -0
- package/dist/index.js +1692 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +1646 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +70 -0
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,1080 @@
|
|
|
1
|
+
import { CountryCode } from 'libphonenumber-js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Notification channels supported by NotifyHub
|
|
5
|
+
*/
|
|
6
|
+
type Channel = 'sms' | 'whatsapp' | 'email';
|
|
7
|
+
/**
|
|
8
|
+
* Message delivery status
|
|
9
|
+
*/
|
|
10
|
+
type MessageStatus = 'queued' | 'sent' | 'delivered' | 'read' | 'failed' | 'undelivered' | 'unknown';
|
|
11
|
+
/**
|
|
12
|
+
* Result of sending a notification
|
|
13
|
+
*/
|
|
14
|
+
interface SendResult {
|
|
15
|
+
/** Whether the send operation succeeded */
|
|
16
|
+
success: boolean;
|
|
17
|
+
/** Provider-specific message ID */
|
|
18
|
+
messageId?: string;
|
|
19
|
+
/** Channel used for sending */
|
|
20
|
+
channel: Channel;
|
|
21
|
+
/** Current message status */
|
|
22
|
+
status: MessageStatus;
|
|
23
|
+
/** Provider that was used */
|
|
24
|
+
provider: string;
|
|
25
|
+
/** Error details if failed */
|
|
26
|
+
error?: NotifyError;
|
|
27
|
+
/** Cost information if available */
|
|
28
|
+
cost?: Cost;
|
|
29
|
+
/** Timestamp of the send operation */
|
|
30
|
+
timestamp: Date;
|
|
31
|
+
/** Additional metadata */
|
|
32
|
+
metadata?: Record<string, unknown>;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Error information
|
|
36
|
+
*/
|
|
37
|
+
interface NotifyError {
|
|
38
|
+
/** Error code from provider or internal */
|
|
39
|
+
code: string;
|
|
40
|
+
/** Human-readable error message */
|
|
41
|
+
message: string;
|
|
42
|
+
/** Whether this error is retriable */
|
|
43
|
+
retriable: boolean;
|
|
44
|
+
/** Original error from provider */
|
|
45
|
+
originalError?: unknown;
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Cost information for a message
|
|
49
|
+
*/
|
|
50
|
+
interface Cost {
|
|
51
|
+
/** Amount in the smallest currency unit */
|
|
52
|
+
amount: number;
|
|
53
|
+
/** Currency code (e.g., 'USD', 'PKR') */
|
|
54
|
+
currency: string;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Result of bulk sending operation
|
|
58
|
+
*/
|
|
59
|
+
interface BulkResult {
|
|
60
|
+
/** Individual results for each message */
|
|
61
|
+
results: SendResult[];
|
|
62
|
+
/** Summary statistics */
|
|
63
|
+
summary: BulkSummary;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Summary of bulk operation
|
|
67
|
+
*/
|
|
68
|
+
interface BulkSummary {
|
|
69
|
+
/** Total messages attempted */
|
|
70
|
+
total: number;
|
|
71
|
+
/** Successfully sent count */
|
|
72
|
+
sent: number;
|
|
73
|
+
/** Failed count */
|
|
74
|
+
failed: number;
|
|
75
|
+
/** Total cost if available */
|
|
76
|
+
cost?: Cost;
|
|
77
|
+
/** Duration in milliseconds */
|
|
78
|
+
durationMs: number;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Options for bulk sending
|
|
82
|
+
*/
|
|
83
|
+
interface BulkOptions {
|
|
84
|
+
/** Rate limiting configuration */
|
|
85
|
+
rateLimit?: RateLimitConfig;
|
|
86
|
+
/** Progress callback */
|
|
87
|
+
onProgress?: (sent: number, total: number) => void;
|
|
88
|
+
/** Whether to stop on first error */
|
|
89
|
+
stopOnError?: boolean;
|
|
90
|
+
/** Maximum concurrent sends */
|
|
91
|
+
concurrency?: number;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Rate limiting configuration
|
|
95
|
+
*/
|
|
96
|
+
interface RateLimitConfig {
|
|
97
|
+
/** Maximum messages per second */
|
|
98
|
+
messagesPerSecond: number;
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Base provider interface
|
|
102
|
+
*/
|
|
103
|
+
interface BaseProvider {
|
|
104
|
+
/** Provider name */
|
|
105
|
+
readonly name: string;
|
|
106
|
+
/** Initialize the provider */
|
|
107
|
+
initialize?(): Promise<void>;
|
|
108
|
+
/** Cleanup resources */
|
|
109
|
+
destroy?(): Promise<void>;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* SMS provider interface
|
|
113
|
+
*/
|
|
114
|
+
interface SmsProvider extends BaseProvider {
|
|
115
|
+
/**
|
|
116
|
+
* Send an SMS message
|
|
117
|
+
* @param to Phone number in E.164 format
|
|
118
|
+
* @param message Message content
|
|
119
|
+
* @param options Additional options
|
|
120
|
+
*/
|
|
121
|
+
send(to: string, message: string, options?: SmsOptions): Promise<SendResult>;
|
|
122
|
+
/**
|
|
123
|
+
* Get delivery status of a message
|
|
124
|
+
* @param messageId Provider-specific message ID
|
|
125
|
+
*/
|
|
126
|
+
getStatus?(messageId: string): Promise<MessageStatus>;
|
|
127
|
+
/**
|
|
128
|
+
* Send bulk SMS messages
|
|
129
|
+
* @param messages Array of messages to send
|
|
130
|
+
* @param options Bulk options
|
|
131
|
+
*/
|
|
132
|
+
sendBulk?(messages: SmsMessage[], options?: BulkOptions): Promise<BulkResult>;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* SMS message for bulk sending
|
|
136
|
+
*/
|
|
137
|
+
interface SmsMessage {
|
|
138
|
+
/** Phone number in E.164 format */
|
|
139
|
+
to: string;
|
|
140
|
+
/** Message content */
|
|
141
|
+
message: string;
|
|
142
|
+
/** Additional metadata */
|
|
143
|
+
metadata?: Record<string, unknown>;
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* SMS sending options
|
|
147
|
+
*/
|
|
148
|
+
interface SmsOptions {
|
|
149
|
+
/** Sender ID or phone number */
|
|
150
|
+
from?: string;
|
|
151
|
+
/** Additional metadata */
|
|
152
|
+
metadata?: Record<string, unknown>;
|
|
153
|
+
}
|
|
154
|
+
/**
|
|
155
|
+
* WhatsApp provider interface
|
|
156
|
+
*/
|
|
157
|
+
interface WhatsAppProvider extends BaseProvider {
|
|
158
|
+
/**
|
|
159
|
+
* Send a text message (within 24hr window)
|
|
160
|
+
* @param to Phone number in E.164 format
|
|
161
|
+
* @param message Message content
|
|
162
|
+
*/
|
|
163
|
+
sendText(to: string, message: string, options?: WhatsAppOptions): Promise<SendResult>;
|
|
164
|
+
/**
|
|
165
|
+
* Send a template message
|
|
166
|
+
* @param to Phone number in E.164 format
|
|
167
|
+
* @param template Template configuration
|
|
168
|
+
*/
|
|
169
|
+
sendTemplate(to: string, template: WhatsAppTemplate, options?: WhatsAppOptions): Promise<SendResult>;
|
|
170
|
+
/**
|
|
171
|
+
* Get delivery status of a message
|
|
172
|
+
* @param messageId Provider-specific message ID
|
|
173
|
+
*/
|
|
174
|
+
getStatus?(messageId: string): Promise<MessageStatus>;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* WhatsApp template configuration
|
|
178
|
+
*/
|
|
179
|
+
interface WhatsAppTemplate {
|
|
180
|
+
/** Template name as registered with Meta */
|
|
181
|
+
name: string;
|
|
182
|
+
/** Template language code (e.g., 'en', 'en_US') */
|
|
183
|
+
language: string;
|
|
184
|
+
/** Template variables (positional or named) */
|
|
185
|
+
variables?: Record<string, string> | string[];
|
|
186
|
+
/** Header parameters */
|
|
187
|
+
header?: WhatsAppTemplateHeader;
|
|
188
|
+
/** Button parameters */
|
|
189
|
+
buttons?: WhatsAppTemplateButton[];
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* WhatsApp template header
|
|
193
|
+
*/
|
|
194
|
+
interface WhatsAppTemplateHeader {
|
|
195
|
+
type: 'text' | 'image' | 'document' | 'video';
|
|
196
|
+
/** URL for media types */
|
|
197
|
+
url?: string;
|
|
198
|
+
/** Text for text type */
|
|
199
|
+
text?: string;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* WhatsApp template button
|
|
203
|
+
*/
|
|
204
|
+
interface WhatsAppTemplateButton {
|
|
205
|
+
type: 'url' | 'quick_reply';
|
|
206
|
+
index: number;
|
|
207
|
+
payload?: string;
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* WhatsApp sending options
|
|
211
|
+
*/
|
|
212
|
+
interface WhatsAppOptions {
|
|
213
|
+
/** Additional metadata */
|
|
214
|
+
metadata?: Record<string, unknown>;
|
|
215
|
+
}
|
|
216
|
+
/**
|
|
217
|
+
* WhatsApp message for bulk sending
|
|
218
|
+
*/
|
|
219
|
+
interface WhatsAppMessage {
|
|
220
|
+
/** Phone number in E.164 format */
|
|
221
|
+
to: string;
|
|
222
|
+
/** Text message (for text type) */
|
|
223
|
+
message?: string;
|
|
224
|
+
/** Template configuration (for template type) */
|
|
225
|
+
template?: WhatsAppTemplate;
|
|
226
|
+
/** Additional metadata */
|
|
227
|
+
metadata?: Record<string, unknown>;
|
|
228
|
+
}
|
|
229
|
+
/**
|
|
230
|
+
* Email provider interface
|
|
231
|
+
*/
|
|
232
|
+
interface EmailProvider extends BaseProvider {
|
|
233
|
+
/**
|
|
234
|
+
* Send an email
|
|
235
|
+
* @param to Recipient email address
|
|
236
|
+
* @param email Email content
|
|
237
|
+
*/
|
|
238
|
+
send(to: string, email: EmailMessage, options?: EmailOptions): Promise<SendResult>;
|
|
239
|
+
/**
|
|
240
|
+
* Send to multiple recipients
|
|
241
|
+
* @param messages Array of email messages
|
|
242
|
+
* @param options Bulk options
|
|
243
|
+
*/
|
|
244
|
+
sendBulk?(messages: EmailMessageWithRecipient[], options?: BulkOptions): Promise<BulkResult>;
|
|
245
|
+
}
|
|
246
|
+
/**
|
|
247
|
+
* Email message content
|
|
248
|
+
*/
|
|
249
|
+
interface EmailMessage {
|
|
250
|
+
/** Email subject */
|
|
251
|
+
subject: string;
|
|
252
|
+
/** Plain text body */
|
|
253
|
+
body?: string;
|
|
254
|
+
/** HTML body */
|
|
255
|
+
html?: string;
|
|
256
|
+
/** Attachments */
|
|
257
|
+
attachments?: EmailAttachment[];
|
|
258
|
+
}
|
|
259
|
+
/**
|
|
260
|
+
* Email message with recipient for bulk sending
|
|
261
|
+
*/
|
|
262
|
+
interface EmailMessageWithRecipient extends EmailMessage {
|
|
263
|
+
/** Recipient email address */
|
|
264
|
+
to: string;
|
|
265
|
+
/** Additional metadata */
|
|
266
|
+
metadata?: Record<string, unknown>;
|
|
267
|
+
}
|
|
268
|
+
/**
|
|
269
|
+
* Email attachment
|
|
270
|
+
*/
|
|
271
|
+
interface EmailAttachment {
|
|
272
|
+
/** Attachment filename */
|
|
273
|
+
filename: string;
|
|
274
|
+
/** Content as Buffer or base64 string */
|
|
275
|
+
content: Buffer | string;
|
|
276
|
+
/** MIME type */
|
|
277
|
+
contentType: string;
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Email sending options
|
|
281
|
+
*/
|
|
282
|
+
interface EmailOptions {
|
|
283
|
+
/** From address override */
|
|
284
|
+
from?: string;
|
|
285
|
+
/** From name override */
|
|
286
|
+
fromName?: string;
|
|
287
|
+
/** Reply-to address */
|
|
288
|
+
replyTo?: string;
|
|
289
|
+
/** CC recipients */
|
|
290
|
+
cc?: string[];
|
|
291
|
+
/** BCC recipients */
|
|
292
|
+
bcc?: string[];
|
|
293
|
+
/** Additional metadata */
|
|
294
|
+
metadata?: Record<string, unknown>;
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Twilio SMS provider configuration
|
|
298
|
+
*/
|
|
299
|
+
interface TwilioConfig {
|
|
300
|
+
/** Twilio Account SID */
|
|
301
|
+
accountSid: string;
|
|
302
|
+
/** Twilio Auth Token */
|
|
303
|
+
authToken: string;
|
|
304
|
+
/** Default from phone number */
|
|
305
|
+
fromNumber: string;
|
|
306
|
+
/** Messaging Service SID (optional, for advanced features) */
|
|
307
|
+
messagingServiceSid?: string;
|
|
308
|
+
}
|
|
309
|
+
/**
|
|
310
|
+
* Local Pakistan SMS provider configuration
|
|
311
|
+
*/
|
|
312
|
+
interface LocalSmsConfig {
|
|
313
|
+
/** Provider name: telenor, jazz, zong */
|
|
314
|
+
provider: 'telenor' | 'jazz' | 'zong';
|
|
315
|
+
/** API key or username */
|
|
316
|
+
apiKey: string;
|
|
317
|
+
/** API secret or password */
|
|
318
|
+
apiSecret?: string;
|
|
319
|
+
/** Sender ID */
|
|
320
|
+
senderId: string;
|
|
321
|
+
/** Base URL override */
|
|
322
|
+
baseUrl?: string;
|
|
323
|
+
}
|
|
324
|
+
/**
|
|
325
|
+
* Meta WhatsApp Cloud API configuration
|
|
326
|
+
*/
|
|
327
|
+
interface MetaWhatsAppConfig {
|
|
328
|
+
/** Access token from Meta */
|
|
329
|
+
accessToken: string;
|
|
330
|
+
/** Phone Number ID */
|
|
331
|
+
phoneNumberId: string;
|
|
332
|
+
/** Business Account ID */
|
|
333
|
+
businessAccountId?: string;
|
|
334
|
+
/** API version (default: v18.0) */
|
|
335
|
+
apiVersion?: string;
|
|
336
|
+
/** Webhook verify token */
|
|
337
|
+
webhookVerifyToken?: string;
|
|
338
|
+
}
|
|
339
|
+
/**
|
|
340
|
+
* AWS SES email provider configuration
|
|
341
|
+
*/
|
|
342
|
+
interface SesConfig {
|
|
343
|
+
/** AWS region */
|
|
344
|
+
region: string;
|
|
345
|
+
/** Default from address */
|
|
346
|
+
fromAddress: string;
|
|
347
|
+
/** Default from name */
|
|
348
|
+
fromName?: string;
|
|
349
|
+
/** AWS credentials (optional, will use default credential chain) */
|
|
350
|
+
credentials?: {
|
|
351
|
+
accessKeyId: string;
|
|
352
|
+
secretAccessKey: string;
|
|
353
|
+
};
|
|
354
|
+
}
|
|
355
|
+
/**
|
|
356
|
+
* Provider-specific configuration union
|
|
357
|
+
*/
|
|
358
|
+
type SmsProviderConfig = {
|
|
359
|
+
provider: 'twilio';
|
|
360
|
+
config: TwilioConfig;
|
|
361
|
+
} | {
|
|
362
|
+
provider: 'local';
|
|
363
|
+
config: LocalSmsConfig;
|
|
364
|
+
} | {
|
|
365
|
+
provider: 'custom';
|
|
366
|
+
instance: SmsProvider;
|
|
367
|
+
};
|
|
368
|
+
type WhatsAppProviderConfig = {
|
|
369
|
+
provider: 'meta';
|
|
370
|
+
config: MetaWhatsAppConfig;
|
|
371
|
+
} | {
|
|
372
|
+
provider: 'custom';
|
|
373
|
+
instance: WhatsAppProvider;
|
|
374
|
+
};
|
|
375
|
+
type EmailProviderConfig = {
|
|
376
|
+
provider: 'ses';
|
|
377
|
+
config: SesConfig;
|
|
378
|
+
} | {
|
|
379
|
+
provider: 'custom';
|
|
380
|
+
instance: EmailProvider;
|
|
381
|
+
};
|
|
382
|
+
/**
|
|
383
|
+
* Routing configuration for smart provider selection
|
|
384
|
+
*/
|
|
385
|
+
interface RoutingConfig {
|
|
386
|
+
/** Phone prefix to provider mapping (e.g., '+92': 'primary') */
|
|
387
|
+
[prefix: string]: 'primary' | 'fallback';
|
|
388
|
+
}
|
|
389
|
+
/**
|
|
390
|
+
* SMS channel configuration
|
|
391
|
+
*/
|
|
392
|
+
interface SmsChannelConfig {
|
|
393
|
+
/** Primary provider */
|
|
394
|
+
primary: SmsProviderConfig;
|
|
395
|
+
/** Fallback provider (optional) */
|
|
396
|
+
fallback?: SmsProviderConfig;
|
|
397
|
+
/** Routing rules */
|
|
398
|
+
routing?: RoutingConfig;
|
|
399
|
+
}
|
|
400
|
+
/**
|
|
401
|
+
* Retry configuration
|
|
402
|
+
*/
|
|
403
|
+
interface RetryConfig {
|
|
404
|
+
/** Maximum number of retry attempts */
|
|
405
|
+
maxAttempts: number;
|
|
406
|
+
/** Initial backoff in milliseconds */
|
|
407
|
+
backoffMs: number;
|
|
408
|
+
/** Backoff multiplier for exponential backoff */
|
|
409
|
+
backoffMultiplier: number;
|
|
410
|
+
/** Maximum backoff in milliseconds */
|
|
411
|
+
maxBackoffMs?: number;
|
|
412
|
+
/** Add jitter to backoff */
|
|
413
|
+
jitter?: boolean;
|
|
414
|
+
}
|
|
415
|
+
/**
|
|
416
|
+
* Logger interface (compatible with console, winston, pino)
|
|
417
|
+
*/
|
|
418
|
+
interface Logger {
|
|
419
|
+
debug(message: string, ...args: unknown[]): void;
|
|
420
|
+
info(message: string, ...args: unknown[]): void;
|
|
421
|
+
warn(message: string, ...args: unknown[]): void;
|
|
422
|
+
error(message: string, ...args: unknown[]): void;
|
|
423
|
+
}
|
|
424
|
+
/**
|
|
425
|
+
* Main NotifyHub configuration
|
|
426
|
+
*/
|
|
427
|
+
interface NotifyHubConfig {
|
|
428
|
+
/** Default channel for notifications */
|
|
429
|
+
defaultChannel?: Channel;
|
|
430
|
+
/** SMS configuration */
|
|
431
|
+
sms?: SmsChannelConfig;
|
|
432
|
+
/** WhatsApp configuration */
|
|
433
|
+
whatsapp?: WhatsAppProviderConfig;
|
|
434
|
+
/** Email configuration */
|
|
435
|
+
email?: EmailProviderConfig;
|
|
436
|
+
/** Retry configuration */
|
|
437
|
+
retry?: RetryConfig;
|
|
438
|
+
/** Logger instance */
|
|
439
|
+
logger?: Logger;
|
|
440
|
+
}
|
|
441
|
+
/**
|
|
442
|
+
* Generic webhook event
|
|
443
|
+
*/
|
|
444
|
+
interface WebhookEvent {
|
|
445
|
+
/** Event type */
|
|
446
|
+
type: 'status' | 'message';
|
|
447
|
+
/** Provider-specific message ID */
|
|
448
|
+
messageId: string;
|
|
449
|
+
/** Channel */
|
|
450
|
+
channel: Channel;
|
|
451
|
+
/** Timestamp */
|
|
452
|
+
timestamp: Date;
|
|
453
|
+
/** Provider name */
|
|
454
|
+
provider: string;
|
|
455
|
+
}
|
|
456
|
+
/**
|
|
457
|
+
* Delivery status webhook event
|
|
458
|
+
*/
|
|
459
|
+
interface StatusWebhookEvent extends WebhookEvent {
|
|
460
|
+
type: 'status';
|
|
461
|
+
/** New status */
|
|
462
|
+
status: MessageStatus;
|
|
463
|
+
/** Recipient phone/email */
|
|
464
|
+
to: string;
|
|
465
|
+
/** Error info if failed */
|
|
466
|
+
error?: NotifyError;
|
|
467
|
+
}
|
|
468
|
+
/**
|
|
469
|
+
* Incoming message webhook event
|
|
470
|
+
*/
|
|
471
|
+
interface IncomingMessageEvent extends WebhookEvent {
|
|
472
|
+
type: 'message';
|
|
473
|
+
/** Sender phone/email */
|
|
474
|
+
from: string;
|
|
475
|
+
/** Message content */
|
|
476
|
+
message?: string;
|
|
477
|
+
/** Media URL if present */
|
|
478
|
+
mediaUrl?: string;
|
|
479
|
+
/** Media type */
|
|
480
|
+
mediaType?: string;
|
|
481
|
+
}
|
|
482
|
+
/**
|
|
483
|
+
* Webhook handler interface
|
|
484
|
+
*/
|
|
485
|
+
interface WebhookHandler<T = unknown> {
|
|
486
|
+
/**
|
|
487
|
+
* Verify webhook signature
|
|
488
|
+
* @param body Raw request body
|
|
489
|
+
* @param headers Request headers
|
|
490
|
+
*/
|
|
491
|
+
verify(body: unknown, headers: Record<string, string>): boolean;
|
|
492
|
+
/**
|
|
493
|
+
* Parse webhook payload
|
|
494
|
+
* @param body Request body
|
|
495
|
+
*/
|
|
496
|
+
parse(body: T): WebhookEvent[];
|
|
497
|
+
/**
|
|
498
|
+
* Handle verification challenge (for WhatsApp)
|
|
499
|
+
* @param verifyToken Token from query params
|
|
500
|
+
* @param challenge Challenge string
|
|
501
|
+
*/
|
|
502
|
+
verifyChallenge?(verifyToken: string, challenge: string): string | null;
|
|
503
|
+
}
|
|
504
|
+
/**
|
|
505
|
+
* Generic notification for the send() method
|
|
506
|
+
*/
|
|
507
|
+
interface Notification {
|
|
508
|
+
/** Channel to use */
|
|
509
|
+
channel: Channel;
|
|
510
|
+
/** Recipient (phone or email) */
|
|
511
|
+
to: string;
|
|
512
|
+
/** Message content (for SMS and WhatsApp text) */
|
|
513
|
+
message?: string;
|
|
514
|
+
/** Template (for WhatsApp template messages) */
|
|
515
|
+
template?: WhatsAppTemplate;
|
|
516
|
+
/** Email content */
|
|
517
|
+
email?: EmailMessage;
|
|
518
|
+
/** Additional metadata */
|
|
519
|
+
metadata?: Record<string, unknown>;
|
|
520
|
+
}
|
|
521
|
+
|
|
522
|
+
/**
|
|
523
|
+
* NotifyHub - Multi-channel notification hub
|
|
524
|
+
*
|
|
525
|
+
* @example
|
|
526
|
+
* ```typescript
|
|
527
|
+
* const notifyHub = new NotifyHub({
|
|
528
|
+
* sms: {
|
|
529
|
+
* primary: {
|
|
530
|
+
* provider: 'twilio',
|
|
531
|
+
* config: {
|
|
532
|
+
* accountSid: 'xxx',
|
|
533
|
+
* authToken: 'xxx',
|
|
534
|
+
* fromNumber: '+1234567890',
|
|
535
|
+
* },
|
|
536
|
+
* },
|
|
537
|
+
* },
|
|
538
|
+
* });
|
|
539
|
+
*
|
|
540
|
+
* await notifyHub.sms('+923001234567', 'Hello!');
|
|
541
|
+
* ```
|
|
542
|
+
*/
|
|
543
|
+
declare class NotifyHub {
|
|
544
|
+
private readonly config;
|
|
545
|
+
private readonly logger;
|
|
546
|
+
private readonly retryConfig;
|
|
547
|
+
private primarySmsProvider?;
|
|
548
|
+
private fallbackSmsProvider?;
|
|
549
|
+
private whatsappProvider?;
|
|
550
|
+
private emailProvider?;
|
|
551
|
+
private initialized;
|
|
552
|
+
constructor(config: NotifyHubConfig);
|
|
553
|
+
/**
|
|
554
|
+
* Initialize all configured providers
|
|
555
|
+
*/
|
|
556
|
+
initialize(): Promise<void>;
|
|
557
|
+
/**
|
|
558
|
+
* Create an SMS provider from configuration
|
|
559
|
+
*/
|
|
560
|
+
private createSmsProvider;
|
|
561
|
+
/**
|
|
562
|
+
* Create a WhatsApp provider from configuration
|
|
563
|
+
*/
|
|
564
|
+
private createWhatsAppProvider;
|
|
565
|
+
/**
|
|
566
|
+
* Create an Email provider from configuration
|
|
567
|
+
*/
|
|
568
|
+
private createEmailProvider;
|
|
569
|
+
/**
|
|
570
|
+
* Ensure NotifyHub is initialized
|
|
571
|
+
*/
|
|
572
|
+
private ensureInitialized;
|
|
573
|
+
/**
|
|
574
|
+
* Get the appropriate SMS provider based on phone number
|
|
575
|
+
*/
|
|
576
|
+
private getSmsProvider;
|
|
577
|
+
/**
|
|
578
|
+
* Send an SMS message
|
|
579
|
+
* @param to Phone number in any format (will be converted to E.164)
|
|
580
|
+
* @param message Message content
|
|
581
|
+
* @param options Additional options
|
|
582
|
+
*/
|
|
583
|
+
sms(to: string, message: string, options?: SmsOptions): Promise<SendResult>;
|
|
584
|
+
/**
|
|
585
|
+
* Send bulk SMS messages
|
|
586
|
+
*/
|
|
587
|
+
bulkSms(messages: SmsMessage[], options?: BulkOptions): Promise<BulkResult>;
|
|
588
|
+
/**
|
|
589
|
+
* Get SMS delivery status
|
|
590
|
+
*/
|
|
591
|
+
getSmsStatus(messageId: string): Promise<MessageStatus>;
|
|
592
|
+
/**
|
|
593
|
+
* Send a WhatsApp text message (within 24hr window)
|
|
594
|
+
*/
|
|
595
|
+
whatsapp(to: string, message: string, options?: WhatsAppOptions): Promise<SendResult>;
|
|
596
|
+
/**
|
|
597
|
+
* Send a WhatsApp template message
|
|
598
|
+
*/
|
|
599
|
+
whatsappTemplate(to: string, template: WhatsAppTemplate, options?: WhatsAppOptions): Promise<SendResult>;
|
|
600
|
+
/**
|
|
601
|
+
* Send bulk WhatsApp messages
|
|
602
|
+
*/
|
|
603
|
+
bulkWhatsApp(messages: WhatsAppMessage[], options?: BulkOptions): Promise<BulkResult>;
|
|
604
|
+
/**
|
|
605
|
+
* Send an email
|
|
606
|
+
*/
|
|
607
|
+
email(to: string, email: EmailMessage, options?: EmailOptions): Promise<SendResult>;
|
|
608
|
+
/**
|
|
609
|
+
* Send bulk emails
|
|
610
|
+
*/
|
|
611
|
+
bulkEmail(messages: EmailMessageWithRecipient[], options?: BulkOptions): Promise<BulkResult>;
|
|
612
|
+
/**
|
|
613
|
+
* Send a notification using the specified channel
|
|
614
|
+
*/
|
|
615
|
+
send(notification: Notification): Promise<SendResult>;
|
|
616
|
+
/**
|
|
617
|
+
* Cleanup and destroy all providers
|
|
618
|
+
*/
|
|
619
|
+
destroy(): Promise<void>;
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
/**
|
|
623
|
+
* Twilio SMS provider implementation
|
|
624
|
+
*/
|
|
625
|
+
declare class TwilioSmsProvider implements SmsProvider {
|
|
626
|
+
readonly name = "twilio";
|
|
627
|
+
private client;
|
|
628
|
+
private readonly config;
|
|
629
|
+
private readonly logger?;
|
|
630
|
+
private readonly retryConfig;
|
|
631
|
+
constructor(config: TwilioConfig, options?: {
|
|
632
|
+
logger?: Logger;
|
|
633
|
+
retryConfig?: RetryConfig;
|
|
634
|
+
});
|
|
635
|
+
/**
|
|
636
|
+
* Initialize the Twilio client
|
|
637
|
+
*/
|
|
638
|
+
initialize(): Promise<void>;
|
|
639
|
+
/**
|
|
640
|
+
* Ensure client is initialized
|
|
641
|
+
*/
|
|
642
|
+
private ensureClient;
|
|
643
|
+
/**
|
|
644
|
+
* Send an SMS message
|
|
645
|
+
*/
|
|
646
|
+
send(to: string, message: string, options?: SmsOptions): Promise<SendResult>;
|
|
647
|
+
/**
|
|
648
|
+
* Get delivery status of a message
|
|
649
|
+
*/
|
|
650
|
+
getStatus(messageId: string): Promise<MessageStatus>;
|
|
651
|
+
/**
|
|
652
|
+
* Send bulk SMS messages
|
|
653
|
+
*/
|
|
654
|
+
sendBulk(messages: SmsMessage[], options?: BulkOptions): Promise<BulkResult>;
|
|
655
|
+
/**
|
|
656
|
+
* Cleanup resources
|
|
657
|
+
*/
|
|
658
|
+
destroy(): Promise<void>;
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
/**
|
|
662
|
+
* Abstract base class for Pakistan local SMS providers
|
|
663
|
+
* Each provider (Telenor, Jazz, Zong) extends this class
|
|
664
|
+
*/
|
|
665
|
+
declare abstract class BaseLocalSmsProvider implements SmsProvider {
|
|
666
|
+
abstract readonly name: string;
|
|
667
|
+
protected readonly config: LocalSmsConfig;
|
|
668
|
+
protected readonly logger?: Logger;
|
|
669
|
+
protected readonly retryConfig: RetryConfig;
|
|
670
|
+
protected abstract readonly baseUrl: string;
|
|
671
|
+
constructor(config: LocalSmsConfig, options?: {
|
|
672
|
+
logger?: Logger;
|
|
673
|
+
retryConfig?: RetryConfig;
|
|
674
|
+
});
|
|
675
|
+
/**
|
|
676
|
+
* Initialize the provider
|
|
677
|
+
*/
|
|
678
|
+
initialize(): Promise<void>;
|
|
679
|
+
/**
|
|
680
|
+
* Format phone number for local provider
|
|
681
|
+
* Pakistan providers typically want: 923001234567 (no + prefix)
|
|
682
|
+
*/
|
|
683
|
+
protected formatPhoneNumber(phone: string): string | null;
|
|
684
|
+
/**
|
|
685
|
+
* Make API request to the provider
|
|
686
|
+
* Each provider implements this differently
|
|
687
|
+
*/
|
|
688
|
+
protected abstract makeRequest(to: string, message: string): Promise<{
|
|
689
|
+
success: boolean;
|
|
690
|
+
messageId?: string;
|
|
691
|
+
error?: string;
|
|
692
|
+
}>;
|
|
693
|
+
/**
|
|
694
|
+
* Send an SMS message
|
|
695
|
+
*/
|
|
696
|
+
send(to: string, message: string, options?: SmsOptions): Promise<SendResult>;
|
|
697
|
+
/**
|
|
698
|
+
* Get delivery status (most local providers don't support this)
|
|
699
|
+
*/
|
|
700
|
+
getStatus(_messageId: string): Promise<MessageStatus>;
|
|
701
|
+
/**
|
|
702
|
+
* Send bulk SMS messages
|
|
703
|
+
*/
|
|
704
|
+
sendBulk(messages: SmsMessage[], options?: BulkOptions): Promise<BulkResult>;
|
|
705
|
+
/**
|
|
706
|
+
* Cleanup resources
|
|
707
|
+
*/
|
|
708
|
+
destroy(): Promise<void>;
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
/**
|
|
712
|
+
* Telenor Pakistan SMS provider
|
|
713
|
+
*
|
|
714
|
+
* API Documentation: Contact Telenor Pakistan for API access
|
|
715
|
+
*
|
|
716
|
+
* Note: This is a simplified implementation. Actual Telenor API
|
|
717
|
+
* may have different endpoints and authentication methods.
|
|
718
|
+
*/
|
|
719
|
+
declare class TelenorSmsProvider extends BaseLocalSmsProvider {
|
|
720
|
+
readonly name = "telenor";
|
|
721
|
+
protected readonly baseUrl: string;
|
|
722
|
+
constructor(config: LocalSmsConfig, options?: {
|
|
723
|
+
logger?: Logger;
|
|
724
|
+
retryConfig?: RetryConfig;
|
|
725
|
+
});
|
|
726
|
+
/**
|
|
727
|
+
* Make API request to Telenor
|
|
728
|
+
*/
|
|
729
|
+
protected makeRequest(to: string, message: string): Promise<{
|
|
730
|
+
success: boolean;
|
|
731
|
+
messageId?: string;
|
|
732
|
+
error?: string;
|
|
733
|
+
}>;
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
/**
|
|
737
|
+
* Jazz (Mobilink) Pakistan SMS provider
|
|
738
|
+
*
|
|
739
|
+
* API Documentation: Contact Jazz Pakistan for API access
|
|
740
|
+
*
|
|
741
|
+
* Note: This is a simplified implementation. Actual Jazz API
|
|
742
|
+
* may have different endpoints and authentication methods.
|
|
743
|
+
*/
|
|
744
|
+
declare class JazzSmsProvider extends BaseLocalSmsProvider {
|
|
745
|
+
readonly name = "jazz";
|
|
746
|
+
protected readonly baseUrl: string;
|
|
747
|
+
constructor(config: LocalSmsConfig, options?: {
|
|
748
|
+
logger?: Logger;
|
|
749
|
+
retryConfig?: RetryConfig;
|
|
750
|
+
});
|
|
751
|
+
/**
|
|
752
|
+
* Make API request to Jazz
|
|
753
|
+
*/
|
|
754
|
+
protected makeRequest(to: string, message: string): Promise<{
|
|
755
|
+
success: boolean;
|
|
756
|
+
messageId?: string;
|
|
757
|
+
error?: string;
|
|
758
|
+
}>;
|
|
759
|
+
}
|
|
760
|
+
|
|
761
|
+
/**
|
|
762
|
+
* Zong Pakistan SMS provider
|
|
763
|
+
*
|
|
764
|
+
* API Documentation: Contact Zong Pakistan for API access
|
|
765
|
+
*
|
|
766
|
+
* Note: This is a simplified implementation. Actual Zong API
|
|
767
|
+
* may have different endpoints and authentication methods.
|
|
768
|
+
*/
|
|
769
|
+
declare class ZongSmsProvider extends BaseLocalSmsProvider {
|
|
770
|
+
readonly name = "zong";
|
|
771
|
+
protected readonly baseUrl: string;
|
|
772
|
+
constructor(config: LocalSmsConfig, options?: {
|
|
773
|
+
logger?: Logger;
|
|
774
|
+
retryConfig?: RetryConfig;
|
|
775
|
+
});
|
|
776
|
+
/**
|
|
777
|
+
* Make API request to Zong
|
|
778
|
+
*/
|
|
779
|
+
protected makeRequest(to: string, message: string): Promise<{
|
|
780
|
+
success: boolean;
|
|
781
|
+
messageId?: string;
|
|
782
|
+
error?: string;
|
|
783
|
+
}>;
|
|
784
|
+
}
|
|
785
|
+
|
|
786
|
+
/**
|
|
787
|
+
* Meta WhatsApp Cloud API provider implementation
|
|
788
|
+
* @see https://developers.facebook.com/docs/whatsapp/cloud-api
|
|
789
|
+
*/
|
|
790
|
+
declare class MetaWhatsAppProvider implements WhatsAppProvider {
|
|
791
|
+
readonly name = "meta";
|
|
792
|
+
private readonly config;
|
|
793
|
+
private readonly logger?;
|
|
794
|
+
private readonly retryConfig;
|
|
795
|
+
private readonly apiVersion;
|
|
796
|
+
private readonly baseUrl;
|
|
797
|
+
constructor(config: MetaWhatsAppConfig, options?: {
|
|
798
|
+
logger?: Logger;
|
|
799
|
+
retryConfig?: RetryConfig;
|
|
800
|
+
});
|
|
801
|
+
/**
|
|
802
|
+
* Initialize the provider (no-op for Meta, just validates config)
|
|
803
|
+
*/
|
|
804
|
+
initialize(): Promise<void>;
|
|
805
|
+
/**
|
|
806
|
+
* Make an API request to Meta WhatsApp Cloud API
|
|
807
|
+
*/
|
|
808
|
+
private makeRequest;
|
|
809
|
+
/**
|
|
810
|
+
* Send a text message (within 24hr conversation window)
|
|
811
|
+
*/
|
|
812
|
+
sendText(to: string, message: string, options?: WhatsAppOptions): Promise<SendResult>;
|
|
813
|
+
/**
|
|
814
|
+
* Send a template message (works outside 24hr window)
|
|
815
|
+
*/
|
|
816
|
+
sendTemplate(to: string, template: WhatsAppTemplate, options?: WhatsAppOptions): Promise<SendResult>;
|
|
817
|
+
/**
|
|
818
|
+
* Get delivery status of a message
|
|
819
|
+
* Note: Meta doesn't have a direct status lookup API - statuses come via webhooks
|
|
820
|
+
*/
|
|
821
|
+
getStatus(_messageId: string): Promise<MessageStatus>;
|
|
822
|
+
/**
|
|
823
|
+
* Cleanup resources (no-op for Meta)
|
|
824
|
+
*/
|
|
825
|
+
destroy(): Promise<void>;
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
/**
|
|
829
|
+
* Twilio webhook payload for message status updates
|
|
830
|
+
*/
|
|
831
|
+
interface TwilioStatusPayload {
|
|
832
|
+
MessageSid: string;
|
|
833
|
+
MessageStatus: string;
|
|
834
|
+
To: string;
|
|
835
|
+
From?: string;
|
|
836
|
+
ErrorCode?: string;
|
|
837
|
+
ErrorMessage?: string;
|
|
838
|
+
AccountSid?: string;
|
|
839
|
+
ApiVersion?: string;
|
|
840
|
+
}
|
|
841
|
+
/**
|
|
842
|
+
* Twilio webhook payload for incoming messages
|
|
843
|
+
*/
|
|
844
|
+
interface TwilioIncomingPayload {
|
|
845
|
+
MessageSid: string;
|
|
846
|
+
Body: string;
|
|
847
|
+
From: string;
|
|
848
|
+
To: string;
|
|
849
|
+
NumMedia?: string;
|
|
850
|
+
MediaUrl0?: string;
|
|
851
|
+
MediaContentType0?: string;
|
|
852
|
+
AccountSid?: string;
|
|
853
|
+
}
|
|
854
|
+
/**
|
|
855
|
+
* Twilio webhook handler
|
|
856
|
+
*/
|
|
857
|
+
declare class TwilioWebhookHandler implements WebhookHandler<TwilioStatusPayload | TwilioIncomingPayload> {
|
|
858
|
+
private readonly authToken;
|
|
859
|
+
constructor(authToken: string);
|
|
860
|
+
/**
|
|
861
|
+
* Verify Twilio webhook signature
|
|
862
|
+
* @see https://www.twilio.com/docs/usage/webhooks/webhooks-security
|
|
863
|
+
*/
|
|
864
|
+
verify(body: unknown, headers: Record<string, string>): boolean;
|
|
865
|
+
/**
|
|
866
|
+
* Parse Twilio webhook payload
|
|
867
|
+
*/
|
|
868
|
+
parse(body: TwilioStatusPayload | TwilioIncomingPayload): WebhookEvent[];
|
|
869
|
+
}
|
|
870
|
+
/**
|
|
871
|
+
* Create a Twilio webhook handler
|
|
872
|
+
*/
|
|
873
|
+
declare function createTwilioWebhookHandler(authToken: string): TwilioWebhookHandler;
|
|
874
|
+
|
|
875
|
+
/**
|
|
876
|
+
* Meta WhatsApp webhook payload structure
|
|
877
|
+
* @see https://developers.facebook.com/docs/whatsapp/cloud-api/webhooks/components
|
|
878
|
+
*/
|
|
879
|
+
interface MetaWebhookPayload {
|
|
880
|
+
object: 'whatsapp_business_account';
|
|
881
|
+
entry: Array<{
|
|
882
|
+
id: string;
|
|
883
|
+
changes: Array<{
|
|
884
|
+
value: {
|
|
885
|
+
messaging_product: 'whatsapp';
|
|
886
|
+
metadata: {
|
|
887
|
+
display_phone_number: string;
|
|
888
|
+
phone_number_id: string;
|
|
889
|
+
};
|
|
890
|
+
contacts?: Array<{
|
|
891
|
+
profile: {
|
|
892
|
+
name: string;
|
|
893
|
+
};
|
|
894
|
+
wa_id: string;
|
|
895
|
+
}>;
|
|
896
|
+
messages?: Array<{
|
|
897
|
+
from: string;
|
|
898
|
+
id: string;
|
|
899
|
+
timestamp: string;
|
|
900
|
+
type: 'text' | 'image' | 'document' | 'audio' | 'video' | 'sticker' | 'location' | 'contacts' | 'button' | 'interactive';
|
|
901
|
+
text?: {
|
|
902
|
+
body: string;
|
|
903
|
+
};
|
|
904
|
+
image?: {
|
|
905
|
+
id: string;
|
|
906
|
+
mime_type: string;
|
|
907
|
+
sha256: string;
|
|
908
|
+
};
|
|
909
|
+
document?: {
|
|
910
|
+
id: string;
|
|
911
|
+
mime_type: string;
|
|
912
|
+
sha256: string;
|
|
913
|
+
filename?: string;
|
|
914
|
+
};
|
|
915
|
+
audio?: {
|
|
916
|
+
id: string;
|
|
917
|
+
mime_type: string;
|
|
918
|
+
};
|
|
919
|
+
video?: {
|
|
920
|
+
id: string;
|
|
921
|
+
mime_type: string;
|
|
922
|
+
};
|
|
923
|
+
button?: {
|
|
924
|
+
text: string;
|
|
925
|
+
payload: string;
|
|
926
|
+
};
|
|
927
|
+
interactive?: {
|
|
928
|
+
type: string;
|
|
929
|
+
button_reply?: {
|
|
930
|
+
id: string;
|
|
931
|
+
title: string;
|
|
932
|
+
};
|
|
933
|
+
list_reply?: {
|
|
934
|
+
id: string;
|
|
935
|
+
title: string;
|
|
936
|
+
};
|
|
937
|
+
};
|
|
938
|
+
}>;
|
|
939
|
+
statuses?: Array<{
|
|
940
|
+
id: string;
|
|
941
|
+
status: 'sent' | 'delivered' | 'read' | 'failed';
|
|
942
|
+
timestamp: string;
|
|
943
|
+
recipient_id: string;
|
|
944
|
+
errors?: Array<{
|
|
945
|
+
code: number;
|
|
946
|
+
title: string;
|
|
947
|
+
message?: string;
|
|
948
|
+
error_data?: {
|
|
949
|
+
details: string;
|
|
950
|
+
};
|
|
951
|
+
}>;
|
|
952
|
+
}>;
|
|
953
|
+
};
|
|
954
|
+
field: 'messages';
|
|
955
|
+
}>;
|
|
956
|
+
}>;
|
|
957
|
+
}
|
|
958
|
+
/**
|
|
959
|
+
* Meta WhatsApp Cloud API webhook handler
|
|
960
|
+
*/
|
|
961
|
+
declare class WhatsAppWebhookHandler implements WebhookHandler<MetaWebhookPayload> {
|
|
962
|
+
private readonly appSecret;
|
|
963
|
+
private readonly verifyToken;
|
|
964
|
+
constructor(appSecret: string, verifyToken: string);
|
|
965
|
+
/**
|
|
966
|
+
* Verify WhatsApp webhook challenge (for initial setup)
|
|
967
|
+
*/
|
|
968
|
+
verifyChallenge(verifyToken: string, challenge: string): string | null;
|
|
969
|
+
/**
|
|
970
|
+
* Verify Meta webhook signature
|
|
971
|
+
* @see https://developers.facebook.com/docs/graph-api/webhooks/getting-started#verification-requests
|
|
972
|
+
*/
|
|
973
|
+
verify(body: unknown, headers: Record<string, string>): boolean;
|
|
974
|
+
/**
|
|
975
|
+
* Parse Meta WhatsApp webhook payload
|
|
976
|
+
*/
|
|
977
|
+
parse(body: MetaWebhookPayload): WebhookEvent[];
|
|
978
|
+
}
|
|
979
|
+
/**
|
|
980
|
+
* Create a WhatsApp webhook handler
|
|
981
|
+
*/
|
|
982
|
+
declare function createWhatsAppWebhookHandler(appSecret: string, verifyToken: string): WhatsAppWebhookHandler;
|
|
983
|
+
|
|
984
|
+
/**
|
|
985
|
+
* Default retry configuration
|
|
986
|
+
*/
|
|
987
|
+
declare const DEFAULT_RETRY_CONFIG: RetryConfig;
|
|
988
|
+
/**
|
|
989
|
+
* Check if an error is retriable
|
|
990
|
+
*/
|
|
991
|
+
declare function isRetriableError(error: unknown): boolean;
|
|
992
|
+
/**
|
|
993
|
+
* Calculate backoff delay with optional jitter
|
|
994
|
+
*/
|
|
995
|
+
declare function calculateBackoff(attempt: number, config: RetryConfig): number;
|
|
996
|
+
/**
|
|
997
|
+
* Retry result containing the value or error
|
|
998
|
+
*/
|
|
999
|
+
interface RetryResult<T> {
|
|
1000
|
+
success: boolean;
|
|
1001
|
+
value?: T;
|
|
1002
|
+
error?: Error;
|
|
1003
|
+
attempts: number;
|
|
1004
|
+
totalDurationMs: number;
|
|
1005
|
+
}
|
|
1006
|
+
/**
|
|
1007
|
+
* Execute a function with retries
|
|
1008
|
+
* @param fn Function to execute
|
|
1009
|
+
* @param config Retry configuration
|
|
1010
|
+
* @param shouldRetry Optional custom retry predicate
|
|
1011
|
+
*/
|
|
1012
|
+
declare function withRetry<T>(fn: () => Promise<T>, config?: RetryConfig, shouldRetry?: (error: unknown) => boolean): Promise<RetryResult<T>>;
|
|
1013
|
+
/**
|
|
1014
|
+
* Create a NotifyError from an unknown error
|
|
1015
|
+
*/
|
|
1016
|
+
declare function createNotifyError(error: unknown, defaultCode?: string): NotifyError;
|
|
1017
|
+
|
|
1018
|
+
/**
|
|
1019
|
+
* Phone number validation result
|
|
1020
|
+
*/
|
|
1021
|
+
interface PhoneValidationResult {
|
|
1022
|
+
isValid: boolean;
|
|
1023
|
+
e164?: string;
|
|
1024
|
+
countryCode?: string;
|
|
1025
|
+
nationalNumber?: string;
|
|
1026
|
+
error?: string;
|
|
1027
|
+
}
|
|
1028
|
+
/**
|
|
1029
|
+
* Validate and parse a phone number to E.164 format
|
|
1030
|
+
* @param phone Phone number in any format
|
|
1031
|
+
* @param defaultCountry Default country code for numbers without country prefix
|
|
1032
|
+
*/
|
|
1033
|
+
declare function validatePhoneNumber(phone: string, defaultCountry?: CountryCode): PhoneValidationResult;
|
|
1034
|
+
/**
|
|
1035
|
+
* Clean a phone number by removing common formatting characters
|
|
1036
|
+
*/
|
|
1037
|
+
declare function cleanPhoneNumber(phone: string): string;
|
|
1038
|
+
/**
|
|
1039
|
+
* Format phone number to E.164 format
|
|
1040
|
+
* @param phone Phone number in any format
|
|
1041
|
+
* @param defaultCountry Default country code
|
|
1042
|
+
* @returns E.164 formatted number or null if invalid
|
|
1043
|
+
*/
|
|
1044
|
+
declare function toE164(phone: string, defaultCountry?: CountryCode): string | null;
|
|
1045
|
+
/**
|
|
1046
|
+
* Check if a phone number belongs to a specific country
|
|
1047
|
+
* @param phone Phone number in E.164 format
|
|
1048
|
+
* @param countryCode Two-letter country code
|
|
1049
|
+
*/
|
|
1050
|
+
declare function isCountry(phone: string, countryCode: CountryCode): boolean;
|
|
1051
|
+
/**
|
|
1052
|
+
* Get the country code from a phone number
|
|
1053
|
+
* @param phone Phone number in E.164 format
|
|
1054
|
+
*/
|
|
1055
|
+
declare function getCountryCode(phone: string): string | null;
|
|
1056
|
+
/**
|
|
1057
|
+
* Get the calling code (e.g., +92 for Pakistan)
|
|
1058
|
+
* @param phone Phone number in E.164 format
|
|
1059
|
+
*/
|
|
1060
|
+
declare function getCallingCode(phone: string): string | null;
|
|
1061
|
+
/**
|
|
1062
|
+
* Check if a phone number is a Pakistan mobile number
|
|
1063
|
+
* Pakistan mobile numbers start with 03xx
|
|
1064
|
+
*/
|
|
1065
|
+
declare function isPakistanMobile(phone: string): boolean;
|
|
1066
|
+
/**
|
|
1067
|
+
* Get the Pakistan mobile network from a phone number
|
|
1068
|
+
* @param phone Phone number
|
|
1069
|
+
* @returns Network name or null if not a Pakistan mobile
|
|
1070
|
+
*/
|
|
1071
|
+
declare function getPakistanNetwork(phone: string): 'jazz' | 'telenor' | 'zong' | 'ufone' | null;
|
|
1072
|
+
/**
|
|
1073
|
+
* Determine the best provider for a phone number based on prefix
|
|
1074
|
+
* @param phone Phone number in E.164 format
|
|
1075
|
+
* @param routing Routing configuration
|
|
1076
|
+
* @returns 'primary' or 'fallback'
|
|
1077
|
+
*/
|
|
1078
|
+
declare function routeByPrefix(phone: string, routing: Record<string, 'primary' | 'fallback'>): 'primary' | 'fallback';
|
|
1079
|
+
|
|
1080
|
+
export { BaseLocalSmsProvider, type BaseProvider, type BulkOptions, type BulkResult, type BulkSummary, type Channel, type Cost, DEFAULT_RETRY_CONFIG, type EmailAttachment, type EmailMessage, type EmailMessageWithRecipient, type EmailOptions, type EmailProvider, type EmailProviderConfig, type IncomingMessageEvent, JazzSmsProvider, type LocalSmsConfig, type Logger, type MessageStatus, type MetaWhatsAppConfig, MetaWhatsAppProvider, type Notification, type NotifyError, NotifyHub, type NotifyHubConfig, type RateLimitConfig, type RetryConfig, type RoutingConfig, type SendResult, type SesConfig, type SmsChannelConfig, type SmsMessage, type SmsOptions, type SmsProvider, type SmsProviderConfig, type StatusWebhookEvent, TelenorSmsProvider, type TwilioConfig, TwilioSmsProvider, TwilioWebhookHandler, type WebhookEvent, type WebhookHandler, type WhatsAppMessage, type WhatsAppOptions, type WhatsAppProvider, type WhatsAppProviderConfig, type WhatsAppTemplate, type WhatsAppTemplateButton, type WhatsAppTemplateHeader, WhatsAppWebhookHandler, ZongSmsProvider, calculateBackoff, cleanPhoneNumber, createNotifyError, createTwilioWebhookHandler, createWhatsAppWebhookHandler, getCallingCode, getCountryCode, getPakistanNetwork, isCountry, isPakistanMobile, isRetriableError, routeByPrefix, toE164, validatePhoneNumber, withRetry };
|