budgetsms-client 1.0.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,460 @@
1
+ /**
2
+ * BudgetSMS API Base URL and Endpoints
3
+ */
4
+ declare const API_BASE = "https://api.budgetsms.net";
5
+ declare const ENDPOINTS: {
6
+ readonly SEND_SMS: "/sendsms/";
7
+ readonly TEST_SMS: "/testsms/";
8
+ readonly CHECK_CREDIT: "/checkcredit/";
9
+ readonly CHECK_OPERATOR: "/checkoperator/";
10
+ readonly HLR: "/hlr/";
11
+ readonly CHECK_SMS: "/checksms/";
12
+ readonly GET_PRICING: "/getpricing/";
13
+ };
14
+ /**
15
+ * BudgetSMS API Error Codes
16
+ * Source: HTTP API Specification V2.7, Chapter 11
17
+ */
18
+ declare enum BudgetSMSErrorCode {
19
+ NOT_ENOUGH_CREDITS = 1001,
20
+ INVALID_CREDENTIALS = 1002,
21
+ ACCOUNT_NOT_ACTIVE = 1003,
22
+ IP_NOT_ALLOWED = 1004,
23
+ NO_HANDLE_PROVIDED = 1005,
24
+ NO_USERID_PROVIDED = 1006,
25
+ NO_USERNAME_PROVIDED = 1007,
26
+ SMS_TEXT_EMPTY = 2001,
27
+ SMS_NUMERIC_SENDER_TOO_LONG = 2002,
28
+ SMS_ALPHANUMERIC_SENDER_TOO_LONG = 2003,
29
+ SMS_SENDER_EMPTY_OR_INVALID = 2004,
30
+ DESTINATION_TOO_SHORT = 2005,
31
+ DESTINATION_NOT_NUMERIC = 2006,
32
+ DESTINATION_EMPTY = 2007,
33
+ SMS_TEXT_NOT_OK = 2008,
34
+ PARAMETER_ISSUE = 2009,
35
+ DESTINATION_INVALIDLY_FORMATTED = 2010,
36
+ DESTINATION_INVALID = 2011,
37
+ SMS_TEXT_TOO_LONG = 2012,
38
+ SMS_MESSAGE_INVALID = 2013,
39
+ CUSTOM_ID_ALREADY_USED = 2014,
40
+ CHARSET_PROBLEM = 2015,
41
+ INVALID_UTF8_ENCODING = 2016,
42
+ INVALID_SMS_ID = 2017,
43
+ NO_ROUTE_TO_DESTINATION = 3001,
44
+ NO_ROUTES_SETUP = 3002,
45
+ INVALID_DESTINATION = 3003,
46
+ SYSTEM_ERROR_CUSTOM_ID = 4001,
47
+ SYSTEM_ERROR_TEMPORARY = 4002,
48
+ SYSTEM_ERROR_TEMPORARY_2 = 4003,
49
+ SYSTEM_ERROR_CONTACT_SUPPORT = 4004,
50
+ SYSTEM_ERROR_PERMANENT = 4005,
51
+ GATEWAY_NOT_REACHABLE = 4006,
52
+ SYSTEM_ERROR_CONTACT_SUPPORT_2 = 4007,
53
+ SEND_ERROR = 5001,
54
+ WRONG_SMS_TYPE = 5002,
55
+ WRONG_OPERATOR = 5003,
56
+ UNKNOWN_ERROR = 6001,
57
+ NO_HLR_PROVIDER = 7001,
58
+ UNEXPECTED_HLR_RESULTS = 7002,
59
+ BAD_NUMBER_FORMAT = 7003,
60
+ HLR_UNEXPECTED_ERROR = 7901,
61
+ HLR_PROVIDER_ERROR = 7902,
62
+ HLR_PROVIDER_ERROR_2 = 7903
63
+ }
64
+ /**
65
+ * Error code descriptions for better error messages
66
+ */
67
+ declare const ERROR_MESSAGES: Record<BudgetSMSErrorCode, string>;
68
+ /**
69
+ * DLR (Delivery Report) Status Codes
70
+ * Source: HTTP API Specification V2.7, Chapter 12
71
+ */
72
+ declare enum DLRStatus {
73
+ /** Message is sent, no status yet (default) */
74
+ SENT_NO_STATUS = 0,
75
+ /** Message is delivered */
76
+ DELIVERED = 1,
77
+ /** Message is not sent */
78
+ NOT_SENT = 2,
79
+ /** Message delivery failed */
80
+ DELIVERY_FAILED = 3,
81
+ /** Message is sent */
82
+ SENT = 4,
83
+ /** Message expired */
84
+ EXPIRED = 5,
85
+ /** Message has a invalid destination address */
86
+ INVALID_DESTINATION = 6,
87
+ /** SMSC error, message could not be processed */
88
+ SMSC_ERROR = 7,
89
+ /** Message is not allowed */
90
+ NOT_ALLOWED = 8,
91
+ /** Message status unknown, usually after 24 hours without status update SMSC */
92
+ STATUS_UNKNOWN_24H = 11,
93
+ /** Message status unknown, SMSC received unknown status code */
94
+ STATUS_UNKNOWN_CODE = 12,
95
+ /** Message status unknown, no status update received from SMSC after 72 hours after submit */
96
+ STATUS_UNKNOWN_72H = 13
97
+ }
98
+ /**
99
+ * DLR status descriptions for better understanding
100
+ */
101
+ declare const DLR_STATUS_MESSAGES: Record<DLRStatus, string>;
102
+
103
+ /**
104
+ * Authentication credentials for BudgetSMS API
105
+ */
106
+ interface BudgetSMSCredentials {
107
+ /** Your BudgetSMS username */
108
+ username: string;
109
+ /** Your BudgetSMS userid (numeric) */
110
+ userid: string;
111
+ /** Your API handle (unique identifier) */
112
+ handle: string;
113
+ }
114
+ /**
115
+ * Parameters for sending an SMS message
116
+ */
117
+ interface SendSMSParams {
118
+ /** The SMS message text (UTF-8 encoded, max 612 characters recommended) */
119
+ msg: string;
120
+ /** Sender ID (alphanumeric max 11 chars, or numeric max 16 digits) */
121
+ from: string;
122
+ /** Receiver phone number in international format (no +, no spaces) */
123
+ to: string;
124
+ /** Optional custom message ID (alphanumeric, max 50 chars, must be unique) */
125
+ customid?: string;
126
+ /** Request price information in response (default: false) */
127
+ price?: boolean;
128
+ /** Request MCC/MNC information in response (default: false) */
129
+ mccmnc?: boolean;
130
+ /** Show remaining credit in response (default: false) */
131
+ credit?: boolean;
132
+ }
133
+ /**
134
+ * Parameters for test SMS (same as SendSMSParams)
135
+ * Test SMS simulates sending without actually sending or reducing credit
136
+ */
137
+ type TestSMSParams = SendSMSParams;
138
+ /**
139
+ * Response from sending an SMS
140
+ */
141
+ interface SendSMSResponse {
142
+ /** Whether the SMS was successfully submitted */
143
+ success: true;
144
+ /** The SMS message ID assigned by BudgetSMS */
145
+ smsId: string;
146
+ /** Price per SMS part (if price parameter was set to true) */
147
+ price?: number;
148
+ /** Number of SMS parts (if price parameter was set to true) */
149
+ parts?: number;
150
+ /** Mobile Country Code + Mobile Network Code (if mccmnc parameter was set to true) */
151
+ mccMnc?: string;
152
+ /** Remaining account credit (if credit parameter was set to true) */
153
+ credit?: number;
154
+ }
155
+ /**
156
+ * Response from test SMS (same as SendSMSResponse)
157
+ */
158
+ type TestSMSResponse = SendSMSResponse;
159
+ /**
160
+ * Response from checking account credit
161
+ */
162
+ interface CheckCreditResponse {
163
+ /** Whether the check was successful */
164
+ success: true;
165
+ /** Remaining credit amount */
166
+ credit: number;
167
+ }
168
+ /**
169
+ * Response from checking operator or HLR lookup
170
+ */
171
+ interface OperatorResponse {
172
+ /** Whether the check was successful */
173
+ success: true;
174
+ /** Mobile Country Code + Mobile Network Code combined (e.g., "20416") */
175
+ mccMnc: string;
176
+ /** Name of the mobile operator */
177
+ operatorName: string;
178
+ /** Cost per SMS message to this operator */
179
+ messageCost: number;
180
+ }
181
+ /**
182
+ * Response from HLR lookup (same structure as OperatorResponse)
183
+ */
184
+ type HLRResponse = OperatorResponse;
185
+ /**
186
+ * Response from checking SMS status
187
+ */
188
+ interface SMSStatusResponse {
189
+ /** Whether the check was successful */
190
+ success: true;
191
+ /** The SMS message ID */
192
+ smsId: string;
193
+ /** Current delivery status */
194
+ status: DLRStatus;
195
+ }
196
+ /**
197
+ * Single pricing entry for an operator
198
+ */
199
+ interface PricingEntry {
200
+ /** Country prefix (e.g., "31" for Netherlands) */
201
+ countryprefix: string;
202
+ /** Country name */
203
+ countryname: string;
204
+ /** Mobile Country Code */
205
+ mcc: string;
206
+ /** Operator name */
207
+ operatorname: string;
208
+ /** Mobile Network Code */
209
+ mnc: string;
210
+ /** Price per SMS part in euro */
211
+ price: string;
212
+ /** Old price before the change */
213
+ old_price: string;
214
+ /** Last modified date (GMT+1) */
215
+ last_modified: string;
216
+ }
217
+ /**
218
+ * Response from getting account pricing
219
+ * Returns a JSON array of pricing entries
220
+ */
221
+ type GetPricingResponse = PricingEntry[];
222
+ /**
223
+ * Configuration options for BudgetSMS client
224
+ */
225
+ interface BudgetSMSConfig extends BudgetSMSCredentials {
226
+ /** Custom base URL (default: https://api.budgetsms.net) */
227
+ baseUrl?: string;
228
+ /** Request timeout in milliseconds (default: 30000) */
229
+ timeout?: number;
230
+ }
231
+
232
+ /**
233
+ * BudgetSMS API Client
234
+ *
235
+ * A modern, type-safe client for the BudgetSMS.net HTTP API.
236
+ * Supports all API endpoints with proper error handling and response parsing.
237
+ *
238
+ * @example
239
+ * ```typescript
240
+ * const client = new BudgetSMS({
241
+ * username: 'your-username',
242
+ * userid: 'your-userid',
243
+ * handle: 'your-api-handle'
244
+ * });
245
+ *
246
+ * // Send an SMS
247
+ * const result = await client.sendSMS({
248
+ * msg: 'Hello World!',
249
+ * from: 'YourApp',
250
+ * to: '31612345678'
251
+ * });
252
+ * ```
253
+ */
254
+ declare class BudgetSMS {
255
+ private readonly username;
256
+ private readonly userid;
257
+ private readonly handle;
258
+ private readonly baseUrl;
259
+ private readonly timeout;
260
+ /**
261
+ * Create a new BudgetSMS client
262
+ * @param config - Configuration object with credentials and optional settings
263
+ */
264
+ constructor(config: BudgetSMSConfig);
265
+ /**
266
+ * Make an HTTP GET request to the API
267
+ * @param endpoint - API endpoint path
268
+ * @param params - Query parameters
269
+ * @returns Response text
270
+ */
271
+ private request;
272
+ /**
273
+ * Get base authentication parameters
274
+ */
275
+ private getAuthParams;
276
+ /**
277
+ * Send an SMS message
278
+ *
279
+ * @param params - SMS parameters
280
+ * @returns Promise resolving to SendSMSResponse
281
+ * @throws {BudgetSMSError} If the API returns an error
282
+ *
283
+ * @example
284
+ * ```typescript
285
+ * const result = await client.sendSMS({
286
+ * msg: 'Hello World!',
287
+ * from: 'YourApp',
288
+ * to: '31612345678',
289
+ * price: true, // Get price info in response
290
+ * mccmnc: true // Get operator info in response
291
+ * });
292
+ *
293
+ * console.log(`SMS sent with ID: ${result.smsId}`);
294
+ * if (result.price) {
295
+ * console.log(`Cost: €${result.price} for ${result.parts} part(s)`);
296
+ * }
297
+ * ```
298
+ */
299
+ sendSMS(params: SendSMSParams): Promise<SendSMSResponse>;
300
+ /**
301
+ * Test SMS sending without actually sending or reducing credit
302
+ *
303
+ * Useful for testing your implementation without consuming credits.
304
+ *
305
+ * @param params - SMS parameters (same as sendSMS)
306
+ * @returns Promise resolving to TestSMSResponse
307
+ * @throws {BudgetSMSError} If the API returns an error
308
+ *
309
+ * @example
310
+ * ```typescript
311
+ * const result = await client.testSMS({
312
+ * msg: 'Test message',
313
+ * from: 'TestApp',
314
+ * to: '31612345678'
315
+ * });
316
+ *
317
+ * console.log(`Test successful, would get SMS ID: ${result.smsId}`);
318
+ * ```
319
+ */
320
+ testSMS(params: TestSMSParams): Promise<TestSMSResponse>;
321
+ /**
322
+ * Check remaining account credit
323
+ *
324
+ * @returns Promise resolving to CheckCreditResponse
325
+ * @throws {BudgetSMSError} If the API returns an error
326
+ *
327
+ * @example
328
+ * ```typescript
329
+ * const result = await client.checkCredit();
330
+ * console.log(`Remaining credit: €${result.credit}`);
331
+ * ```
332
+ */
333
+ checkCredit(): Promise<CheckCreditResponse>;
334
+ /**
335
+ * Check operator based on phone number prefix
336
+ *
337
+ * Note: This checks the original operator based on prefix.
338
+ * If a number has been ported, use hlr() instead.
339
+ *
340
+ * @param phoneNumber - Phone number to check (international format, no +)
341
+ * @returns Promise resolving to OperatorResponse
342
+ * @throws {BudgetSMSError} If the API returns an error
343
+ *
344
+ * @example
345
+ * ```typescript
346
+ * const result = await client.checkOperator('31612345678');
347
+ * console.log(`Operator: ${result.operatorName} (${result.mccMnc})`);
348
+ * console.log(`Cost: €${result.messageCost}`);
349
+ * ```
350
+ */
351
+ checkOperator(phoneNumber: string): Promise<OperatorResponse>;
352
+ /**
353
+ * Perform HLR (Home Location Register) lookup
354
+ *
355
+ * Returns the actual current operator, even if the number has been ported.
356
+ * More accurate than checkOperator() but may cost credits.
357
+ *
358
+ * @param phoneNumber - Phone number to lookup (international format, no +)
359
+ * @returns Promise resolving to HLRResponse
360
+ * @throws {BudgetSMSError} If the API returns an error
361
+ *
362
+ * @example
363
+ * ```typescript
364
+ * const result = await client.hlr('31612345678');
365
+ * console.log(`Current operator: ${result.operatorName}`);
366
+ * console.log(`Network: ${result.mccMnc}`);
367
+ * ```
368
+ */
369
+ hlr(phoneNumber: string): Promise<HLRResponse>;
370
+ /**
371
+ * Check SMS delivery status (Pull DLR)
372
+ *
373
+ * Retrieve the current delivery status of a sent message.
374
+ * For automatic updates, consider using Push DLR instead.
375
+ *
376
+ * @param smsId - The SMS ID returned from sendSMS()
377
+ * @returns Promise resolving to SMSStatusResponse
378
+ * @throws {BudgetSMSError} If the API returns an error
379
+ *
380
+ * @example
381
+ * ```typescript
382
+ * const result = await client.checkSMS('12345678');
383
+ * console.log(`Status: ${result.status}`); // DLRStatus enum value
384
+ * ```
385
+ */
386
+ checkSMS(smsId: string): Promise<SMSStatusResponse>;
387
+ /**
388
+ * Get account pricing for all operators
389
+ *
390
+ * Returns a comprehensive list of pricing for all available operators.
391
+ * Each entry includes country, operator, MCC/MNC codes, and pricing info.
392
+ *
393
+ * @returns Promise resolving to GetPricingResponse (array of pricing entries)
394
+ * @throws {BudgetSMSError} If the API returns an error
395
+ *
396
+ * @example
397
+ * ```typescript
398
+ * const pricing = await client.getPricing();
399
+ * for (const entry of pricing) {
400
+ * console.log(`${entry.countryname} - ${entry.operatorname}: €${entry.price}`);
401
+ * }
402
+ * ```
403
+ */
404
+ getPricing(): Promise<GetPricingResponse>;
405
+ }
406
+
407
+ /**
408
+ * Custom error class for BudgetSMS API errors
409
+ */
410
+ declare class BudgetSMSError extends Error {
411
+ readonly code: BudgetSMSErrorCode;
412
+ /**
413
+ * Creates a new BudgetSMSError
414
+ * @param code - The BudgetSMS error code
415
+ * @param message - Optional custom error message (defaults to standard message for the code)
416
+ */
417
+ constructor(code: BudgetSMSErrorCode, message?: string);
418
+ /**
419
+ * Returns true if the error code indicates a temporary/retryable error
420
+ */
421
+ isRetryable(): boolean;
422
+ /**
423
+ * Returns true if the error code indicates an authentication/credentials issue
424
+ */
425
+ isAuthenticationError(): boolean;
426
+ /**
427
+ * Returns true if the error code indicates insufficient credits
428
+ */
429
+ isInsufficientCredits(): boolean;
430
+ /**
431
+ * Convert error to JSON for logging/serialization
432
+ */
433
+ toJSON(): {
434
+ name: string;
435
+ code: BudgetSMSErrorCode;
436
+ message: string;
437
+ stack: string | undefined;
438
+ };
439
+ }
440
+
441
+ /**
442
+ * Validate phone number format (basic MSISDN validation)
443
+ * @param phoneNumber - Phone number to validate
444
+ * @returns true if valid, false otherwise
445
+ */
446
+ declare function validatePhoneNumber(phoneNumber: string): boolean;
447
+ /**
448
+ * Validate sender ID format
449
+ * @param sender - Sender ID to validate
450
+ * @returns true if valid, false otherwise
451
+ */
452
+ declare function validateSender(sender: string): boolean;
453
+ /**
454
+ * Validate message text
455
+ * @param message - Message text to validate
456
+ * @returns true if valid, false otherwise
457
+ */
458
+ declare function validateMessage(message: string): boolean;
459
+
460
+ export { API_BASE, BudgetSMS, type BudgetSMSConfig, type BudgetSMSCredentials, BudgetSMSError, BudgetSMSErrorCode, type CheckCreditResponse, DLRStatus, DLR_STATUS_MESSAGES, ENDPOINTS, ERROR_MESSAGES, type GetPricingResponse, type HLRResponse, type OperatorResponse, type PricingEntry, type SMSStatusResponse, type SendSMSParams, type SendSMSResponse, type TestSMSParams, type TestSMSResponse, validateMessage, validatePhoneNumber, validateSender };