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.
- package/LICENSE +21 -0
- package/README.md +440 -0
- package/dist/index.cjs +569 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +460 -0
- package/dist/index.d.ts +460 -0
- package/dist/index.js +557 -0
- package/dist/index.js.map +1 -0
- package/package.json +63 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Nick Leeman
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,440 @@
|
|
|
1
|
+
# budgetsms-client
|
|
2
|
+
|
|
3
|
+
Modern, type-safe TypeScript/JavaScript client for the [BudgetSMS.net](https://www.budgetsms.net) HTTP API.
|
|
4
|
+
|
|
5
|
+
> **Note:** This is an **unofficial** client library and is not affiliated with or endorsed by BudgetSMS.net. It is a community-maintained open-source project.
|
|
6
|
+
|
|
7
|
+
[](https://www.npmjs.com/package/budgetsms-client)
|
|
8
|
+
[](https://github.com/Frozenverse/budgetsms-client/actions/workflows/ci.yml)
|
|
9
|
+
[](https://opensource.org/licenses/MIT)
|
|
10
|
+
[](https://www.typescriptlang.org/)
|
|
11
|
+
[](https://nodejs.org/)
|
|
12
|
+
[](https://www.npmjs.com/package/budgetsms-client)
|
|
13
|
+
|
|
14
|
+
## Features
|
|
15
|
+
|
|
16
|
+
- ðŊ **Works with JavaScript & TypeScript** - No TypeScript required!
|
|
17
|
+
- ðĶ **Dual module support** - ESM and CommonJS
|
|
18
|
+
- ð **Type-safe error handling** - Error code enums with helper methods
|
|
19
|
+
- ðĻ **Response parsing** - Clean, typed response objects
|
|
20
|
+
- ðŠķ **Zero dependencies** - Lightweight (22KB) and fast
|
|
21
|
+
- â
**Fully tested** - 42 tests, 100% coverage
|
|
22
|
+
- ð **Complete API coverage** - All 7 BudgetSMS endpoints
|
|
23
|
+
- ðĄ **IntelliSense support** - Autocomplete in VS Code, even in JavaScript
|
|
24
|
+
- ð **Node.js 18+** - Uses native fetch (no extra dependencies)
|
|
25
|
+
|
|
26
|
+
## Installation
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm install budgetsms-client
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
yarn add budgetsms-client
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
pnpm add budgetsms-client
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Quick Start
|
|
41
|
+
|
|
42
|
+
### TypeScript / ESM
|
|
43
|
+
|
|
44
|
+
```typescript
|
|
45
|
+
import { BudgetSMS } from 'budgetsms-client';
|
|
46
|
+
|
|
47
|
+
// Initialize the client
|
|
48
|
+
const client = new BudgetSMS({
|
|
49
|
+
username: 'your-username',
|
|
50
|
+
userid: 'your-userid',
|
|
51
|
+
handle: 'your-api-handle'
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
// Send an SMS
|
|
55
|
+
const result = await client.sendSMS({
|
|
56
|
+
msg: 'Hello World!',
|
|
57
|
+
from: 'YourApp',
|
|
58
|
+
to: '31612345678'
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
console.log(`SMS sent with ID: ${result.smsId}`);
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### JavaScript / CommonJS
|
|
65
|
+
|
|
66
|
+
```javascript
|
|
67
|
+
const { BudgetSMS } = require('budgetsms-client');
|
|
68
|
+
|
|
69
|
+
// Initialize the client
|
|
70
|
+
const client = new BudgetSMS({
|
|
71
|
+
username: 'your-username',
|
|
72
|
+
userid: 'your-userid',
|
|
73
|
+
handle: 'your-api-handle'
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
// Send an SMS (using .then() or async/await)
|
|
77
|
+
client.sendSMS({
|
|
78
|
+
msg: 'Hello World!',
|
|
79
|
+
from: 'YourApp',
|
|
80
|
+
to: '31612345678'
|
|
81
|
+
}).then(result => {
|
|
82
|
+
console.log(`SMS sent with ID: ${result.smsId}`);
|
|
83
|
+
}).catch(error => {
|
|
84
|
+
console.error('Error:', error.message);
|
|
85
|
+
});
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### JavaScript / ESM (Node.js with "type": "module")
|
|
89
|
+
|
|
90
|
+
```javascript
|
|
91
|
+
import { BudgetSMS } from 'budgetsms-client';
|
|
92
|
+
|
|
93
|
+
const client = new BudgetSMS({
|
|
94
|
+
username: 'your-username',
|
|
95
|
+
userid: 'your-userid',
|
|
96
|
+
handle: 'your-api-handle'
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
const result = await client.sendSMS({
|
|
100
|
+
msg: 'Hello World!',
|
|
101
|
+
from: 'YourApp',
|
|
102
|
+
to: '31612345678'
|
|
103
|
+
});
|
|
104
|
+
|
|
105
|
+
console.log(`SMS sent with ID: ${result.smsId}`);
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## API Reference
|
|
109
|
+
|
|
110
|
+
### Initialize Client
|
|
111
|
+
|
|
112
|
+
```typescript
|
|
113
|
+
import { BudgetSMS } from 'budgetsms-client';
|
|
114
|
+
|
|
115
|
+
const client = new BudgetSMS({
|
|
116
|
+
username: 'your-username', // Your BudgetSMS username
|
|
117
|
+
userid: 'your-userid', // Your BudgetSMS user ID
|
|
118
|
+
handle: 'your-api-handle', // Your API handle
|
|
119
|
+
|
|
120
|
+
// Optional configuration
|
|
121
|
+
baseUrl: 'https://api.budgetsms.net', // Custom API base URL
|
|
122
|
+
timeout: 30000 // Request timeout in ms (default: 30000)
|
|
123
|
+
});
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
### Send SMS
|
|
127
|
+
|
|
128
|
+
Send an SMS message to a recipient.
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
const result = await client.sendSMS({
|
|
132
|
+
msg: 'Your message text',
|
|
133
|
+
from: 'YourApp', // Sender ID (max 11 alphanumeric or 16 numeric)
|
|
134
|
+
to: '31612345678', // Recipient phone number (international format, no +)
|
|
135
|
+
|
|
136
|
+
// Optional parameters
|
|
137
|
+
customid: 'unique-id-123', // Custom message ID (max 50 chars, must be unique)
|
|
138
|
+
price: true, // Include price information in response
|
|
139
|
+
mccmnc: true, // Include operator network information
|
|
140
|
+
credit: true // Include remaining credit in response
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
console.log(`SMS ID: ${result.smsId}`);
|
|
144
|
+
|
|
145
|
+
// If price was requested
|
|
146
|
+
if (result.price) {
|
|
147
|
+
console.log(`Cost: âŽ${result.price} for ${result.parts} part(s)`);
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
// If mccmnc was requested
|
|
151
|
+
if (result.mccMnc) {
|
|
152
|
+
console.log(`Network: ${result.mccMnc}`);
|
|
153
|
+
}
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Test SMS
|
|
157
|
+
|
|
158
|
+
Test your SMS implementation without actually sending or consuming credits.
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
const result = await client.testSMS({
|
|
162
|
+
msg: 'Test message',
|
|
163
|
+
from: 'TestApp',
|
|
164
|
+
to: '31612345678'
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
console.log(`Test successful, would get SMS ID: ${result.smsId}`);
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
### Check Credit
|
|
171
|
+
|
|
172
|
+
Get your remaining account balance.
|
|
173
|
+
|
|
174
|
+
```typescript
|
|
175
|
+
const result = await client.checkCredit();
|
|
176
|
+
console.log(`Remaining credit: âŽ${result.credit}`);
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
### Check Operator
|
|
180
|
+
|
|
181
|
+
Check the operator for a phone number based on its prefix.
|
|
182
|
+
|
|
183
|
+
> **Note:** This checks the original operator. If a number has been ported to another operator, use `hlr()` instead.
|
|
184
|
+
|
|
185
|
+
```typescript
|
|
186
|
+
const result = await client.checkOperator('31612345678');
|
|
187
|
+
console.log(`Operator: ${result.operatorName}`);
|
|
188
|
+
console.log(`Network: ${result.mccMnc}`);
|
|
189
|
+
console.log(`Cost per SMS: âŽ${result.messageCost}`);
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### HLR Lookup
|
|
193
|
+
|
|
194
|
+
Perform an HLR (Home Location Register) lookup to determine the actual current operator, even if the number has been ported.
|
|
195
|
+
|
|
196
|
+
```typescript
|
|
197
|
+
const result = await client.hlr('31612345678');
|
|
198
|
+
console.log(`Current operator: ${result.operatorName}`);
|
|
199
|
+
console.log(`Network: ${result.mccMnc}`);
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Check SMS Status
|
|
203
|
+
|
|
204
|
+
Check the delivery status of a sent message (Pull DLR).
|
|
205
|
+
|
|
206
|
+
```typescript
|
|
207
|
+
const result = await client.checkSMS('12345678'); // SMS ID from sendSMS()
|
|
208
|
+
console.log(`Status: ${result.status}`);
|
|
209
|
+
|
|
210
|
+
// Use DLRStatus enum for type-safe status checking
|
|
211
|
+
import { DLRStatus, DLR_STATUS_MESSAGES } from 'budgetsms-client';
|
|
212
|
+
|
|
213
|
+
if (result.status === DLRStatus.DELIVERED) {
|
|
214
|
+
console.log('Message was delivered!');
|
|
215
|
+
} else {
|
|
216
|
+
console.log(`Status: ${DLR_STATUS_MESSAGES[result.status]}`);
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
### Get Pricing
|
|
221
|
+
|
|
222
|
+
Retrieve pricing information for all operators in your account.
|
|
223
|
+
|
|
224
|
+
```typescript
|
|
225
|
+
const pricing = await client.getPricing();
|
|
226
|
+
|
|
227
|
+
for (const entry of pricing) {
|
|
228
|
+
console.log(`${entry.countryname} - ${entry.operatorname}: âŽ${entry.price}`);
|
|
229
|
+
console.log(` MCC/MNC: ${entry.mcc}/${entry.mnc}`);
|
|
230
|
+
console.log(` Last modified: ${entry.last_modified}`);
|
|
231
|
+
}
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
## Error Handling
|
|
235
|
+
|
|
236
|
+
The client uses typed error handling with the `BudgetSMSError` class.
|
|
237
|
+
|
|
238
|
+
```typescript
|
|
239
|
+
import { BudgetSMSError, BudgetSMSErrorCode } from 'budgetsms-client';
|
|
240
|
+
|
|
241
|
+
try {
|
|
242
|
+
await client.sendSMS({
|
|
243
|
+
msg: 'Test',
|
|
244
|
+
from: 'App',
|
|
245
|
+
to: '31612345678'
|
|
246
|
+
});
|
|
247
|
+
} catch (error) {
|
|
248
|
+
if (error instanceof BudgetSMSError) {
|
|
249
|
+
console.error(`BudgetSMS Error: ${error.message}`);
|
|
250
|
+
console.error(`Error Code: ${error.code}`);
|
|
251
|
+
|
|
252
|
+
// Check specific error conditions
|
|
253
|
+
if (error.isInsufficientCredits()) {
|
|
254
|
+
console.error('Please top up your account!');
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
if (error.isAuthenticationError()) {
|
|
258
|
+
console.error('Check your credentials!');
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
if (error.isRetryable()) {
|
|
262
|
+
console.error('Temporary error, you can retry');
|
|
263
|
+
}
|
|
264
|
+
} else {
|
|
265
|
+
console.error('Unexpected error:', error);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
### Error Codes
|
|
271
|
+
|
|
272
|
+
All BudgetSMS API error codes are available as an enum:
|
|
273
|
+
|
|
274
|
+
```typescript
|
|
275
|
+
import { BudgetSMSErrorCode, ERROR_MESSAGES } from 'budgetsms-client';
|
|
276
|
+
|
|
277
|
+
// Access error codes
|
|
278
|
+
BudgetSMSErrorCode.NOT_ENOUGH_CREDITS // 1001
|
|
279
|
+
BudgetSMSErrorCode.INVALID_CREDENTIALS // 1002
|
|
280
|
+
BudgetSMSErrorCode.ACCOUNT_NOT_ACTIVE // 1003
|
|
281
|
+
// ... and many more
|
|
282
|
+
|
|
283
|
+
// Get error message for a code
|
|
284
|
+
console.log(ERROR_MESSAGES[BudgetSMSErrorCode.NOT_ENOUGH_CREDITS]);
|
|
285
|
+
// "Not enough credits to send messages"
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
## DLR Status Codes
|
|
289
|
+
|
|
290
|
+
Delivery report statuses are available as an enum:
|
|
291
|
+
|
|
292
|
+
```typescript
|
|
293
|
+
import { DLRStatus, DLR_STATUS_MESSAGES } from 'budgetsms-client';
|
|
294
|
+
|
|
295
|
+
// DLR status values
|
|
296
|
+
DLRStatus.DELIVERED // 1 - Message is delivered
|
|
297
|
+
DLRStatus.DELIVERY_FAILED // 3 - Message delivery failed
|
|
298
|
+
DLRStatus.EXPIRED // 5 - Message expired
|
|
299
|
+
DLRStatus.SENT_NO_STATUS // 0 - Message is sent, no status yet
|
|
300
|
+
// ... and more
|
|
301
|
+
|
|
302
|
+
// Get human-readable status message
|
|
303
|
+
console.log(DLR_STATUS_MESSAGES[DLRStatus.DELIVERED]);
|
|
304
|
+
// "Message is delivered"
|
|
305
|
+
```
|
|
306
|
+
|
|
307
|
+
## Validation Utilities
|
|
308
|
+
|
|
309
|
+
The package includes validation utilities for common use cases:
|
|
310
|
+
|
|
311
|
+
```typescript
|
|
312
|
+
import { validatePhoneNumber, validateSender, validateMessage } from 'budgetsms-client';
|
|
313
|
+
|
|
314
|
+
// Validate phone number (8-16 digits)
|
|
315
|
+
if (!validatePhoneNumber('31612345678')) {
|
|
316
|
+
console.error('Invalid phone number format');
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
// Validate sender ID
|
|
320
|
+
// - Alphanumeric: max 11 characters [a-zA-Z0-9]
|
|
321
|
+
// - Numeric: max 16 digits
|
|
322
|
+
if (!validateSender('MyApp')) {
|
|
323
|
+
console.error('Invalid sender format');
|
|
324
|
+
}
|
|
325
|
+
|
|
326
|
+
// Validate message text (not empty, max 612 chars for 4 SMS parts)
|
|
327
|
+
if (!validateMessage('Hello World')) {
|
|
328
|
+
console.error('Invalid message');
|
|
329
|
+
}
|
|
330
|
+
```
|
|
331
|
+
|
|
332
|
+
## TypeScript Support
|
|
333
|
+
|
|
334
|
+
This package is written in TypeScript and provides full type definitions.
|
|
335
|
+
|
|
336
|
+
```typescript
|
|
337
|
+
import type {
|
|
338
|
+
BudgetSMSConfig,
|
|
339
|
+
SendSMSParams,
|
|
340
|
+
SendSMSResponse,
|
|
341
|
+
OperatorResponse,
|
|
342
|
+
PricingEntry,
|
|
343
|
+
// ... and more
|
|
344
|
+
} from 'budgetsms-client';
|
|
345
|
+
```
|
|
346
|
+
|
|
347
|
+
## Requirements
|
|
348
|
+
|
|
349
|
+
- Node.js >= 18.0.0 (for native `fetch` support)
|
|
350
|
+
- Works with **both JavaScript and TypeScript** projects
|
|
351
|
+
- No build step required for JavaScript users
|
|
352
|
+
|
|
353
|
+
## JavaScript & TypeScript Support
|
|
354
|
+
|
|
355
|
+
This package is **fully compatible with JavaScript** projects:
|
|
356
|
+
|
|
357
|
+
- â
**JavaScript (CommonJS)**: `require('budgetsms-client')`
|
|
358
|
+
- â
**JavaScript (ESM)**: `import { BudgetSMS } from 'budgetsms-client'`
|
|
359
|
+
- â
**TypeScript**: Full type definitions included
|
|
360
|
+
- â
**No TypeScript required**: The package ships as compiled JavaScript
|
|
361
|
+
- â
**IntelliSense support**: Get autocomplete even in JavaScript projects (VS Code, etc.)
|
|
362
|
+
|
|
363
|
+
### For JavaScript Users
|
|
364
|
+
|
|
365
|
+
You don't need TypeScript installed to use this package. It's written in TypeScript but **compiled to JavaScript** before publishing. The TypeScript definitions are optional and only provide better editor autocomplete.
|
|
366
|
+
|
|
367
|
+
```javascript
|
|
368
|
+
// Plain JavaScript - works perfectly!
|
|
369
|
+
const { BudgetSMS } = require('budgetsms-client');
|
|
370
|
+
|
|
371
|
+
const client = new BudgetSMS({
|
|
372
|
+
username: 'test',
|
|
373
|
+
userid: '123',
|
|
374
|
+
handle: 'abc'
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
// Your editor will still show autocomplete thanks to included .d.ts files
|
|
378
|
+
client.sendSMS({ /* autocomplete works here! */ });
|
|
379
|
+
```
|
|
380
|
+
|
|
381
|
+
### For TypeScript Users
|
|
382
|
+
|
|
383
|
+
Full type safety out of the box:
|
|
384
|
+
|
|
385
|
+
```typescript
|
|
386
|
+
import { BudgetSMS, SendSMSResponse, BudgetSMSError } from 'budgetsms-client';
|
|
387
|
+
|
|
388
|
+
const client = new BudgetSMS({ ... });
|
|
389
|
+
const result: SendSMSResponse = await client.sendSMS({ ... });
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
## Module Format Support
|
|
393
|
+
|
|
394
|
+
This package supports both ESM and CommonJS:
|
|
395
|
+
|
|
396
|
+
```typescript
|
|
397
|
+
// ESM (TypeScript or JavaScript with "type": "module")
|
|
398
|
+
import { BudgetSMS } from 'budgetsms-client';
|
|
399
|
+
|
|
400
|
+
// CommonJS (Traditional Node.js)
|
|
401
|
+
const { BudgetSMS } = require('budgetsms-client');
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
## Examples
|
|
405
|
+
|
|
406
|
+
Check out the [examples](./examples) directory for complete working examples:
|
|
407
|
+
|
|
408
|
+
- **[javascript-example.js](./examples/javascript-example.js)** - CommonJS (traditional Node.js)
|
|
409
|
+
- **[javascript-esm-example.mjs](./examples/javascript-esm-example.mjs)** - ES Modules
|
|
410
|
+
- **[typescript-example.ts](./examples/typescript-example.ts)** - TypeScript with full types
|
|
411
|
+
|
|
412
|
+
Each example includes:
|
|
413
|
+
- Client initialization
|
|
414
|
+
- Sending SMS
|
|
415
|
+
- Error handling
|
|
416
|
+
- Credit checking
|
|
417
|
+
- Operator lookup
|
|
418
|
+
- Status tracking
|
|
419
|
+
|
|
420
|
+
## API Documentation
|
|
421
|
+
|
|
422
|
+
For complete BudgetSMS API documentation, visit:
|
|
423
|
+
- [Official BudgetSMS API Documentation](https://www.budgetsms.net/sms-http-api/)
|
|
424
|
+
|
|
425
|
+
## License
|
|
426
|
+
|
|
427
|
+
MIT ÂĐ [Nick Leeman](https://github.com/Frozenverse)
|
|
428
|
+
|
|
429
|
+
## Contributing
|
|
430
|
+
|
|
431
|
+
Contributions are welcome! Please feel free to submit a Pull Request.
|
|
432
|
+
|
|
433
|
+
## Support
|
|
434
|
+
|
|
435
|
+
- ð§ For BudgetSMS API issues: [contact BudgetSMS support](https://www.budgetsms.net/contact/)
|
|
436
|
+
- ð For package issues: [GitHub Issues](https://github.com/Frozenverse/budgetsms-client/issues)
|
|
437
|
+
|
|
438
|
+
## Changelog
|
|
439
|
+
|
|
440
|
+
See [Releases](https://github.com/Frozenverse/budgetsms-client/releases) for version history.
|