botcast-sdk 1.0.2 → 1.0.3
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 +321 -125
- package/dist/client.cjs +22 -0
- package/dist/client.d.ts +16 -0
- package/dist/client.d.ts.map +1 -1
- package/dist/client.js +22 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,23 +1,37 @@
|
|
|
1
1
|
# botcast-sdk
|
|
2
2
|
|
|
3
|
-
Node.js and TypeScript client for [Botcast](https://botcast.site), a multi-instance WhatsApp API gateway.
|
|
4
|
-
|
|
5
|
-
Connect WhatsApp numbers, send messages (text, OTP, media, documents, polls), manage group chats, and process incoming webhooks.
|
|
3
|
+
Node.js and TypeScript client for [Botcast](https://botcast.site), a multi-instance WhatsApp REST API gateway.
|
|
6
4
|
|
|
7
5
|
[](https://www.npmjs.com/package/botcast-sdk)
|
|
6
|
+
[](https://www.npmjs.com/package/botcast-sdk)
|
|
8
7
|
[](https://opensource.org/licenses/MIT)
|
|
9
8
|
[](https://www.typescriptlang.org/)
|
|
10
9
|
|
|
11
10
|
---
|
|
12
11
|
|
|
12
|
+
## Features
|
|
13
|
+
|
|
14
|
+
- Zero runtime dependencies: built on native `fetch`.
|
|
15
|
+
- Full TypeScript types for every request payload, response model, and error class.
|
|
16
|
+
- Dual device pairing: scan a QR code string or request an 8-digit phone PIN to link without a camera.
|
|
17
|
+
- 42 WhatsApp REST endpoints: text messages with mentions, OTPs, images, videos, audio, voice notes (PTT), documents, stickers, locations, contact vCards, and interactive polls.
|
|
18
|
+
- Message controls: edit, delete for everyone, mark as read, reactions, pin messages, and forward.
|
|
19
|
+
- Group management: create groups, manage participants, update subjects and descriptions, configure settings, and handle join requests.
|
|
20
|
+
- Safety controls: configure daily caps on sent messages and new contacts.
|
|
21
|
+
- Built-in webhook router: parse and handle inbound messages and connection events in Express, Fastify, Next.js, or raw Node HTTP.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
13
25
|
## Installation
|
|
14
26
|
|
|
15
27
|
```bash
|
|
16
28
|
npm install botcast-sdk
|
|
17
29
|
# or
|
|
30
|
+
pnpm add botcast-sdk
|
|
31
|
+
# or
|
|
18
32
|
yarn add botcast-sdk
|
|
19
33
|
# or
|
|
20
|
-
|
|
34
|
+
bun add botcast-sdk
|
|
21
35
|
```
|
|
22
36
|
|
|
23
37
|
---
|
|
@@ -27,41 +41,40 @@ pnpm add botcast-sdk
|
|
|
27
41
|
```typescript
|
|
28
42
|
import { BotcastClient } from 'botcast-sdk';
|
|
29
43
|
|
|
30
|
-
const
|
|
44
|
+
const client = new BotcastClient({
|
|
31
45
|
baseUrl: 'https://botcast.site', // or your self-hosted server URL
|
|
32
46
|
instanceId: 'your_instance_id',
|
|
33
47
|
instanceToken: 'your_instance_token',
|
|
34
48
|
});
|
|
35
49
|
|
|
36
50
|
async function main() {
|
|
37
|
-
// 1. Check
|
|
38
|
-
const status = await
|
|
39
|
-
console.log(
|
|
40
|
-
|
|
41
|
-
// 2. Send a text message
|
|
42
|
-
const result = await
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
51
|
+
// 1. Check instance connectivity
|
|
52
|
+
const status = await client.getStatus();
|
|
53
|
+
console.log(`Connected phone: ${status.phoneNumber || 'Not linked'}`);
|
|
54
|
+
|
|
55
|
+
// 2. Send a text message with user mentions
|
|
56
|
+
const result = await client.messages.sendText('201012345678', 'Hello @201012345678!', {
|
|
57
|
+
mentions: ['201012345678'],
|
|
58
|
+
});
|
|
59
|
+
console.log('Message ID:', result.messageId);
|
|
60
|
+
|
|
61
|
+
// 3. Send a secure 6-digit OTP code
|
|
62
|
+
const otp = await client.messages.sendOTP('201012345678', {
|
|
63
|
+
appName: 'My App',
|
|
49
64
|
expiryMinutes: 5,
|
|
50
65
|
});
|
|
51
|
-
console.log('OTP
|
|
66
|
+
console.log('Dispatched OTP:', otp.codeSent);
|
|
52
67
|
}
|
|
53
68
|
|
|
54
69
|
main().catch(console.error);
|
|
55
70
|
```
|
|
56
71
|
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
## CommonJS usage
|
|
72
|
+
### CommonJS (require)
|
|
60
73
|
|
|
61
74
|
```javascript
|
|
62
75
|
const { BotcastClient } = require('botcast-sdk');
|
|
63
76
|
|
|
64
|
-
const
|
|
77
|
+
const client = new BotcastClient({
|
|
65
78
|
instanceId: 'your_instance_id',
|
|
66
79
|
instanceToken: 'your_instance_token',
|
|
67
80
|
});
|
|
@@ -71,173 +84,348 @@ const botcast = new BotcastClient({
|
|
|
71
84
|
|
|
72
85
|
## API reference
|
|
73
86
|
|
|
74
|
-
### 1.
|
|
87
|
+
### 1. Device pairing and lifecycle (`client.instances`)
|
|
75
88
|
|
|
76
89
|
```typescript
|
|
77
|
-
// Get status
|
|
78
|
-
const status = await
|
|
90
|
+
// 1. Get live status
|
|
91
|
+
const status = await client.instances.getStatus();
|
|
92
|
+
console.log('Socket state:', status.status); // 'connected' | 'pairing' | 'disconnected'
|
|
79
93
|
|
|
80
|
-
// Get QR code string for scanning
|
|
81
|
-
const qr = await
|
|
94
|
+
// 2. Option A: Get QR code string for camera scanning
|
|
95
|
+
const qr = await client.getQR(); // or client.instances.getQR()
|
|
96
|
+
console.log('Scan QR:', qr.qr);
|
|
82
97
|
|
|
83
|
-
//
|
|
84
|
-
const pair = await
|
|
85
|
-
console.log('Enter this
|
|
98
|
+
// 3. Option B: Request 8-digit phone PIN code (link without scanning)
|
|
99
|
+
const pair = await client.pairWithCode('201012345678'); // or client.instances.pairWithCode(...)
|
|
100
|
+
console.log('Enter this PIN on WhatsApp notification:', pair.code); // e.g. "8492-0193"
|
|
86
101
|
|
|
87
|
-
// Start, stop, or log out
|
|
88
|
-
await
|
|
89
|
-
await
|
|
90
|
-
await
|
|
102
|
+
// 4. Start, stop, or log out
|
|
103
|
+
await client.instances.start(); // Boots socket connection
|
|
104
|
+
await client.instances.stop(); // Suspends socket session
|
|
105
|
+
await client.instances.logout(); // Unlinks device and deletes session
|
|
91
106
|
|
|
92
|
-
//
|
|
93
|
-
const check = await
|
|
94
|
-
console.log('Exists:', check.exists, 'JID:', check.jid);
|
|
107
|
+
// 5. Verify phone number on WhatsApp
|
|
108
|
+
const check = await client.checkNumber('201012345678');
|
|
109
|
+
console.log('Exists on WhatsApp:', check.exists, 'JID:', check.jid);
|
|
95
110
|
|
|
96
|
-
// Set presence
|
|
97
|
-
await
|
|
111
|
+
// 6. Set presence state
|
|
112
|
+
await client.instances.setPresence({
|
|
98
113
|
presence: 'composing', // 'available' | 'unavailable' | 'composing' | 'recording' | 'paused'
|
|
99
|
-
recipient: '
|
|
114
|
+
recipient: '201012345678',
|
|
100
115
|
});
|
|
116
|
+
|
|
117
|
+
// 7. Manage sandbox allowed numbers (developer tier)
|
|
118
|
+
const allowed = await client.instances.getAllowedNumbers();
|
|
119
|
+
await client.instances.setAllowedNumbers(['201012345678', '966500000000']);
|
|
101
120
|
```
|
|
102
121
|
|
|
103
122
|
---
|
|
104
123
|
|
|
105
|
-
### 2.
|
|
124
|
+
### 2. Message and media dispatching (`client.messages`)
|
|
106
125
|
|
|
107
126
|
```typescript
|
|
108
|
-
// 1. Text message with mentions
|
|
109
|
-
await
|
|
110
|
-
mentions: ['
|
|
127
|
+
// 1. Text message with mentions and quoted replies
|
|
128
|
+
await client.messages.sendText('201012345678', 'Hello World', {
|
|
129
|
+
mentions: ['201012345678'],
|
|
130
|
+
quotedMsgId: 'MSG_ID_TO_REPLY_TO',
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
// 2. Image
|
|
134
|
+
await client.messages.sendImage('201012345678', {
|
|
135
|
+
url: 'https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?w=800',
|
|
136
|
+
caption: 'Photo preview',
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
// 3. Video (or round PTV message)
|
|
140
|
+
await client.messages.sendVideo('201012345678', {
|
|
141
|
+
url: 'https://sample-videos.com/video321/mp4/720/big_buck_bunny_720p_1mb.mp4',
|
|
142
|
+
caption: 'Product tutorial video',
|
|
143
|
+
ptv: false,
|
|
111
144
|
});
|
|
112
145
|
|
|
113
|
-
//
|
|
114
|
-
await
|
|
115
|
-
url: 'https://
|
|
116
|
-
caption: 'Here is your monthly invoice.',
|
|
146
|
+
// 4. Voice note (PTT waveform) and audio
|
|
147
|
+
await client.messages.sendVoice('201012345678', {
|
|
148
|
+
url: 'https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3',
|
|
117
149
|
});
|
|
118
150
|
|
|
119
|
-
//
|
|
120
|
-
await
|
|
121
|
-
url: 'https://
|
|
122
|
-
fileName: '
|
|
151
|
+
// 5. Document, PDF, or file attachment
|
|
152
|
+
await client.messages.sendDocument('201012345678', {
|
|
153
|
+
url: 'https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf',
|
|
154
|
+
fileName: 'Invoice_2026.pdf',
|
|
123
155
|
mimetype: 'application/pdf',
|
|
156
|
+
caption: 'Monthly invoice statement',
|
|
124
157
|
});
|
|
125
158
|
|
|
126
|
-
//
|
|
127
|
-
await
|
|
128
|
-
url: 'https://
|
|
159
|
+
// 6. Sticker
|
|
160
|
+
await client.messages.sendSticker('201012345678', {
|
|
161
|
+
url: 'https://raw.githubusercontent.com/WhatsApp/stickers/main/Android/app/src/main/assets/1/01_Cider_Happy.webp',
|
|
129
162
|
});
|
|
130
163
|
|
|
131
|
-
//
|
|
132
|
-
await
|
|
133
|
-
|
|
134
|
-
|
|
164
|
+
// 7. Location coordinates
|
|
165
|
+
await client.messages.sendLocation('201012345678', {
|
|
166
|
+
latitude: 24.7136,
|
|
167
|
+
longitude: 46.6753,
|
|
168
|
+
name: 'Kingdom Tower',
|
|
169
|
+
address: 'King Fahd Rd, Riyadh, Saudi Arabia',
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
// 8. Contact vCard
|
|
173
|
+
await client.messages.sendContact('201012345678', {
|
|
174
|
+
displayName: 'Support Team',
|
|
175
|
+
vcard: 'BEGIN:VCARD\nVERSION:3.0\nFN:Support Team\nTEL;TYPE=CELL:+201012345678\nEND:VCARD',
|
|
176
|
+
});
|
|
177
|
+
|
|
178
|
+
// 9. Interactive poll
|
|
179
|
+
await client.messages.sendPoll('201012345678', {
|
|
180
|
+
name: 'How do you rate Botcast API speed?',
|
|
181
|
+
values: ['Fast', 'Good', 'Needs improvement'],
|
|
135
182
|
selectableCount: 1,
|
|
136
183
|
});
|
|
137
184
|
|
|
138
|
-
//
|
|
139
|
-
await
|
|
140
|
-
|
|
141
|
-
|
|
185
|
+
// 10. OTP verification code
|
|
186
|
+
const otp = await client.messages.sendOTP('201012345678', {
|
|
187
|
+
appName: 'Botcast Portal',
|
|
188
|
+
expiryMinutes: 5,
|
|
142
189
|
});
|
|
190
|
+
```
|
|
143
191
|
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
### 3. Message operations (`client.messages`)
|
|
195
|
+
|
|
196
|
+
```typescript
|
|
197
|
+
const msgKey = {
|
|
198
|
+
remoteJid: '201012345678@s.whatsapp.net',
|
|
199
|
+
fromMe: true,
|
|
200
|
+
id: '3EB0ABCDEF1234567890',
|
|
201
|
+
};
|
|
202
|
+
|
|
203
|
+
// 1. Edit sent message (within 15 minutes)
|
|
204
|
+
await client.messages.edit('201012345678', msgKey, 'Corrected text content');
|
|
205
|
+
|
|
206
|
+
// 2. Delete message for everyone (revoke)
|
|
207
|
+
await client.messages.delete('201012345678', msgKey);
|
|
208
|
+
|
|
209
|
+
// 3. Mark message as read (blue tick)
|
|
210
|
+
await client.messages.markAsRead(msgKey);
|
|
211
|
+
|
|
212
|
+
// 4. Emoji reaction (pass empty string to remove)
|
|
213
|
+
await client.messages.react('201012345678', msgKey, '👍');
|
|
214
|
+
|
|
215
|
+
// 5. Pin message (86400 = 24h, 604800 = 7d, 2592000 = 30d)
|
|
216
|
+
await client.messages.pin('201012345678', msgKey, 1, 86400);
|
|
217
|
+
|
|
218
|
+
// 6. Forward message
|
|
219
|
+
await client.messages.forward('201012345678', { conversation: 'Forwarded message text' });
|
|
149
220
|
```
|
|
150
221
|
|
|
151
222
|
---
|
|
152
223
|
|
|
153
|
-
###
|
|
224
|
+
### 4. Chats, contacts, and sync (`client.chats`)
|
|
154
225
|
|
|
155
226
|
```typescript
|
|
156
|
-
//
|
|
157
|
-
const
|
|
227
|
+
// 1. List synced chats
|
|
228
|
+
const { chats, total } = await client.chats.list({ limit: 50, offset: 0 });
|
|
158
229
|
|
|
159
|
-
// List
|
|
160
|
-
const
|
|
230
|
+
// 2. List synced contacts
|
|
231
|
+
const { contacts } = await client.chats.listContacts({ limit: 100 });
|
|
161
232
|
|
|
162
|
-
//
|
|
163
|
-
await
|
|
164
|
-
await botcast.groups.removeParticipants('group-jid@g.us', ['201222222222']);
|
|
233
|
+
// 3. List synced messages
|
|
234
|
+
const { messages } = await client.chats.listMessages({ chatJid: '201012345678@s.whatsapp.net', limit: 50 });
|
|
165
235
|
|
|
166
|
-
//
|
|
167
|
-
await
|
|
236
|
+
// 4. Modify chat state (archive, mute, pin, delete)
|
|
237
|
+
await client.chats.archive('201012345678@s.whatsapp.net');
|
|
238
|
+
await client.chats.unarchive('201012345678@s.whatsapp.net');
|
|
239
|
+
await client.chats.mute('201012345678@s.whatsapp.net', 8 * 60 * 60 * 1000); // 8 hours
|
|
240
|
+
await client.chats.unmute('201012345678@s.whatsapp.net');
|
|
241
|
+
await client.chats.pin('201012345678@s.whatsapp.net');
|
|
242
|
+
await client.chats.unpin('201012345678@s.whatsapp.net');
|
|
243
|
+
await client.chats.deleteChat('201012345678@s.whatsapp.net');
|
|
168
244
|
|
|
169
|
-
//
|
|
170
|
-
await
|
|
171
|
-
await botcast.groups.updateSubject('group-jid@g.us', 'New Group Name');
|
|
172
|
-
await botcast.groups.updateDescription('group-jid@g.us', 'Official VIP group discussion.');
|
|
245
|
+
// 5. Set disappearing messages timer
|
|
246
|
+
await client.chats.setDisappearing('201012345678', 86400, true);
|
|
173
247
|
|
|
174
|
-
//
|
|
175
|
-
|
|
176
|
-
|
|
248
|
+
// 6. Request older history from linked phone
|
|
249
|
+
await client.chats.fetchHistory({ count: 50 });
|
|
250
|
+
|
|
251
|
+
// 7. Trigger immediate sync
|
|
252
|
+
await client.instances.sync();
|
|
177
253
|
```
|
|
178
254
|
|
|
179
255
|
---
|
|
180
256
|
|
|
181
|
-
###
|
|
257
|
+
### 5. Profile, presence, and business details (`client.profile`)
|
|
258
|
+
|
|
259
|
+
```typescript
|
|
260
|
+
// 1. Get and update bio status
|
|
261
|
+
const bio = await client.profile.getStatus('201012345678');
|
|
262
|
+
await client.profile.setStatus('Available via Botcast API');
|
|
263
|
+
|
|
264
|
+
// 2. Update display name
|
|
265
|
+
await client.profile.setName('Botcast Agent');
|
|
266
|
+
|
|
267
|
+
// 3. Profile picture management
|
|
268
|
+
const pic = await client.profile.getPicture('201012345678', true); // High-res
|
|
269
|
+
await client.profile.setPicture({ url: 'https://botcast.site/logo.png' });
|
|
270
|
+
await client.profile.removePicture();
|
|
182
271
|
|
|
183
|
-
|
|
272
|
+
// 4. Inspect WhatsApp Business profile
|
|
273
|
+
const biz = await client.profile.getBusinessProfile('201012345678');
|
|
274
|
+
console.log('Business category:', biz.businessProfile.category);
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
---
|
|
278
|
+
|
|
279
|
+
### 6. Group administration (`client.groups`)
|
|
184
280
|
|
|
185
|
-
#### Express example:
|
|
186
281
|
```typescript
|
|
187
|
-
|
|
188
|
-
|
|
282
|
+
// 1. Create a WhatsApp group
|
|
283
|
+
const group = await client.groups.create('VIP Customers', ['201012345678', '966500000000']);
|
|
284
|
+
const groupJid = group.group.id;
|
|
285
|
+
|
|
286
|
+
// 2. List groups and fetch metadata
|
|
287
|
+
const { groups } = await client.groups.list();
|
|
288
|
+
const { metadata } = await client.groups.getMetadata(groupJid);
|
|
289
|
+
|
|
290
|
+
// 3. Participant management (add, remove, promote, demote)
|
|
291
|
+
await client.groups.addParticipants(groupJid, ['201099999999']);
|
|
292
|
+
await client.groups.removeParticipants(groupJid, ['201099999999']);
|
|
293
|
+
await client.groups.promoteParticipants(groupJid, ['201012345678']);
|
|
294
|
+
await client.groups.demoteParticipants(groupJid, ['201012345678']);
|
|
295
|
+
|
|
296
|
+
// 4. Update group subject and description
|
|
297
|
+
await client.groups.updateSubject(groupJid, 'New Group Title');
|
|
298
|
+
await client.groups.updateDescription(groupJid, 'Official VIP discussion group.');
|
|
299
|
+
|
|
300
|
+
// 5. Update group settings
|
|
301
|
+
await client.groups.updateSettings(groupJid, 'announcement'); // Admins only send messages
|
|
302
|
+
await client.groups.updateSettings(groupJid, 'not_announcement'); // All members can chat
|
|
303
|
+
await client.groups.updateSettings(groupJid, 'locked'); // Admins only edit info
|
|
304
|
+
await client.groups.updateSettings(groupJid, 'unlocked');
|
|
305
|
+
|
|
306
|
+
// 6. Shareable invite codes and links
|
|
307
|
+
const invite = await client.groups.getInviteCode(groupJid);
|
|
308
|
+
console.log('Invite link:', invite.link);
|
|
309
|
+
await client.groups.revokeInviteCode(groupJid);
|
|
310
|
+
await client.groups.acceptInvite('InviteCodeString');
|
|
311
|
+
const info = await client.groups.getInviteInfo('InviteCodeString');
|
|
189
312
|
|
|
190
|
-
|
|
191
|
-
|
|
313
|
+
// 7. Join requests moderation (admin approval mode)
|
|
314
|
+
const pending = await client.groups.getJoinRequests(groupJid);
|
|
315
|
+
await client.groups.updateJoinRequests(groupJid, ['201012345678'], 'approve');
|
|
192
316
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
});
|
|
317
|
+
// 8. Ephemeral messages and member add mode
|
|
318
|
+
await client.groups.setEphemeral(groupJid, 86400); // 24h
|
|
319
|
+
await client.groups.setMemberAddMode(groupJid, 'admin_add'); // Only admins add
|
|
197
320
|
|
|
198
|
-
//
|
|
199
|
-
|
|
200
|
-
|
|
321
|
+
// 9. Leave group
|
|
322
|
+
await client.groups.leave(groupJid);
|
|
323
|
+
```
|
|
201
324
|
|
|
202
|
-
|
|
203
|
-
await botcast.messages.sendText(event.sender, 'pong');
|
|
204
|
-
}
|
|
205
|
-
});
|
|
325
|
+
---
|
|
206
326
|
|
|
207
|
-
|
|
208
|
-
app.post('/webhook', botcast.webhook.middleware());
|
|
327
|
+
### 7. Privacy and blocklist (`client.profile`)
|
|
209
328
|
|
|
210
|
-
|
|
329
|
+
```typescript
|
|
330
|
+
// 1. Block and unblock contacts
|
|
331
|
+
await client.profile.block('201012345678');
|
|
332
|
+
await client.profile.unblock('201012345678');
|
|
333
|
+
|
|
334
|
+
// 2. Get blocklist
|
|
335
|
+
const { blocklist } = await client.profile.getBlocklist();
|
|
336
|
+
|
|
337
|
+
// 3. Get and update privacy visibility settings
|
|
338
|
+
const privacy = await client.profile.getPrivacySettings();
|
|
339
|
+
// Options: 'all' | 'contacts' | 'contact_blacklist' | 'none'
|
|
340
|
+
await client.profile.updatePrivacySetting('lastSeen', 'all');
|
|
341
|
+
await client.profile.updatePrivacySetting('online', 'all');
|
|
342
|
+
await client.profile.updatePrivacySetting('profilePicture', 'contacts');
|
|
343
|
+
await client.profile.updatePrivacySetting('status', 'contacts');
|
|
344
|
+
await client.profile.updatePrivacySetting('readReceipts', 'all');
|
|
211
345
|
```
|
|
212
346
|
|
|
213
347
|
---
|
|
214
348
|
|
|
215
|
-
###
|
|
349
|
+
### 8. 24-hour status stories and broadcasts (`client.broadcast`)
|
|
216
350
|
|
|
217
|
-
|
|
351
|
+
```typescript
|
|
352
|
+
// 1. Publish status story (text, image, video, or audio)
|
|
353
|
+
await client.broadcast.sendStatusStory({
|
|
354
|
+
type: 'text',
|
|
355
|
+
text: 'New update available on Botcast.',
|
|
356
|
+
backgroundColor: '#10b981',
|
|
357
|
+
});
|
|
358
|
+
|
|
359
|
+
// 2. Get broadcast list info
|
|
360
|
+
const list = await client.broadcast.getListInfo('1234567890@broadcast');
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
---
|
|
364
|
+
|
|
365
|
+
### 9. Rate limits and safety controls (`client.instances`)
|
|
218
366
|
|
|
219
367
|
```typescript
|
|
220
|
-
// Read current
|
|
221
|
-
const limits = await
|
|
368
|
+
// 1. Read current limits
|
|
369
|
+
const limits = await client.instances.getLimits();
|
|
222
370
|
console.log('Daily message limit:', limits.daily_message_limit);
|
|
223
371
|
console.log('Daily new contacts limit:', limits.daily_new_contacts_limit);
|
|
224
372
|
|
|
225
|
-
// Update limits
|
|
226
|
-
await
|
|
227
|
-
await
|
|
373
|
+
// 2. Update limits (pass 0 to disable)
|
|
374
|
+
await client.instances.setDailyMessageLimit(1000);
|
|
375
|
+
await client.instances.setDailyNewContactsLimit(100);
|
|
228
376
|
|
|
229
377
|
// Or update both at once
|
|
230
|
-
await
|
|
231
|
-
daily_message_limit:
|
|
232
|
-
daily_new_contacts_limit:
|
|
378
|
+
await client.instances.updateLimits({
|
|
379
|
+
daily_message_limit: 500,
|
|
380
|
+
daily_new_contacts_limit: 50,
|
|
233
381
|
});
|
|
234
382
|
```
|
|
235
383
|
|
|
236
384
|
---
|
|
237
385
|
|
|
238
|
-
###
|
|
386
|
+
### 10. Webhook event handling
|
|
387
|
+
|
|
388
|
+
The SDK includes an event dispatcher and middleware for handling inbound webhooks:
|
|
389
|
+
|
|
390
|
+
#### Express example
|
|
391
|
+
|
|
392
|
+
```typescript
|
|
393
|
+
import express from 'express';
|
|
394
|
+
import { BotcastClient } from 'botcast-sdk';
|
|
395
|
+
|
|
396
|
+
const app = express();
|
|
397
|
+
app.use(express.json());
|
|
398
|
+
|
|
399
|
+
const client = new BotcastClient({
|
|
400
|
+
instanceId: 'inst_123',
|
|
401
|
+
instanceToken: 'tok_abc',
|
|
402
|
+
});
|
|
403
|
+
|
|
404
|
+
// Listen for incoming messages
|
|
405
|
+
client.webhook.onMessage(async (event) => {
|
|
406
|
+
console.log(`Message from ${event.pushName || event.sender}: ${event.message}`);
|
|
407
|
+
|
|
408
|
+
if (event.message.trim().toLowerCase() === 'ping') {
|
|
409
|
+
await client.messages.sendText(event.sender, 'pong');
|
|
410
|
+
}
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
// Listen for connection changes
|
|
414
|
+
client.webhook.onConnection(async (event) => {
|
|
415
|
+
console.log(`Instance state updated: ${event.status}`);
|
|
416
|
+
});
|
|
417
|
+
|
|
418
|
+
// Mount middleware on your webhook route
|
|
419
|
+
app.post('/webhook/botcast', client.webhook.middleware());
|
|
420
|
+
|
|
421
|
+
app.listen(3000, () => console.log('Webhook server running on port 3000'));
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
---
|
|
425
|
+
|
|
426
|
+
## Error handling
|
|
239
427
|
|
|
240
|
-
|
|
428
|
+
`botcast-sdk` maps API status codes to typed error classes:
|
|
241
429
|
|
|
242
430
|
```typescript
|
|
243
431
|
import {
|
|
@@ -246,21 +434,27 @@ import {
|
|
|
246
434
|
BotcastPaymentRequiredError,
|
|
247
435
|
BotcastSubscriptionExpiredError,
|
|
248
436
|
BotcastRateLimitError,
|
|
437
|
+
BotcastValidationError,
|
|
438
|
+
BotcastNotFoundError,
|
|
249
439
|
} from 'botcast-sdk';
|
|
250
440
|
|
|
251
441
|
try {
|
|
252
|
-
await
|
|
442
|
+
await client.messages.sendText('201012345678', 'Hello World');
|
|
253
443
|
} catch (error) {
|
|
254
444
|
if (error instanceof BotcastAuthError) {
|
|
255
|
-
console.error('Invalid instance
|
|
445
|
+
console.error('Invalid instance credentials or token.');
|
|
256
446
|
} else if (error instanceof BotcastPaymentRequiredError) {
|
|
257
|
-
console.error('Instance requires
|
|
447
|
+
console.error('Instance requires subscription activation.');
|
|
258
448
|
} else if (error instanceof BotcastSubscriptionExpiredError) {
|
|
259
449
|
console.error('Instance subscription expired on:', error.expiresAt);
|
|
260
450
|
} else if (error instanceof BotcastRateLimitError) {
|
|
261
|
-
console.error('
|
|
451
|
+
console.error('Daily sending limit reached. Please wait before retrying.');
|
|
452
|
+
} else if (error instanceof BotcastValidationError) {
|
|
453
|
+
console.error('Validation error:', error.message, error.details);
|
|
454
|
+
} else if (error instanceof BotcastNotFoundError) {
|
|
455
|
+
console.error('Resource not found:', error.message);
|
|
262
456
|
} else {
|
|
263
|
-
console.error('
|
|
457
|
+
console.error('Unexpected error:', error);
|
|
264
458
|
}
|
|
265
459
|
}
|
|
266
460
|
```
|
|
@@ -270,8 +464,10 @@ try {
|
|
|
270
464
|
## Links
|
|
271
465
|
|
|
272
466
|
- Website: [https://botcast.site](https://botcast.site)
|
|
273
|
-
-
|
|
274
|
-
-
|
|
467
|
+
- Documentation: [https://botcast.site/docs](https://botcast.site/docs)
|
|
468
|
+
- Postman collection: [https://botcast.site/botcast.postman_collection.json](https://botcast.site/botcast.postman_collection.json)
|
|
469
|
+
- NPM package: [https://www.npmjs.com/package/botcast-sdk](https://www.npmjs.com/package/botcast-sdk)
|
|
470
|
+
- GitHub repository: [https://github.com/ANOOBALSA/Botcast](https://github.com/ANOOBALSA/Botcast)
|
|
275
471
|
|
|
276
472
|
---
|
|
277
473
|
|
package/dist/client.cjs
CHANGED
|
@@ -87,5 +87,27 @@ class BotcastClient {
|
|
|
87
87
|
async getStatus() {
|
|
88
88
|
return this.instances.getStatus();
|
|
89
89
|
}
|
|
90
|
+
/**
|
|
91
|
+
* Shortcut to get the device pairing QR code string.
|
|
92
|
+
*/
|
|
93
|
+
async getQR() {
|
|
94
|
+
return this.instances.getQR();
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Shortcut to request an 8-digit phone PIN pairing code without scanning QR.
|
|
98
|
+
*
|
|
99
|
+
* @param phoneNumber Recipient phone number with country code (e.g. `201000000000` or `15551234567`)
|
|
100
|
+
*/
|
|
101
|
+
async pairWithCode(phoneNumber) {
|
|
102
|
+
return this.instances.pairWithCode(phoneNumber);
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Shortcut to verify if a phone number exists on WhatsApp.
|
|
106
|
+
*
|
|
107
|
+
* @param phoneNumber The phone number to check (with country code)
|
|
108
|
+
*/
|
|
109
|
+
async checkNumber(phoneNumber) {
|
|
110
|
+
return this.instances.checkNumber(phoneNumber);
|
|
111
|
+
}
|
|
90
112
|
}
|
|
91
113
|
exports.BotcastClient = BotcastClient;
|
package/dist/client.d.ts
CHANGED
|
@@ -60,5 +60,21 @@ export declare class BotcastClient {
|
|
|
60
60
|
* Shortcut to check instance connectivity status.
|
|
61
61
|
*/
|
|
62
62
|
getStatus(): Promise<import("./types/instances.js").InstanceStatusResponse>;
|
|
63
|
+
/**
|
|
64
|
+
* Shortcut to get the device pairing QR code string.
|
|
65
|
+
*/
|
|
66
|
+
getQR(): Promise<import("./types/instances.js").InstanceQRResponse>;
|
|
67
|
+
/**
|
|
68
|
+
* Shortcut to request an 8-digit phone PIN pairing code without scanning QR.
|
|
69
|
+
*
|
|
70
|
+
* @param phoneNumber Recipient phone number with country code (e.g. `201000000000` or `15551234567`)
|
|
71
|
+
*/
|
|
72
|
+
pairWithCode(phoneNumber: string): Promise<import("./types/instances.js").PairCodeResponse>;
|
|
73
|
+
/**
|
|
74
|
+
* Shortcut to verify if a phone number exists on WhatsApp.
|
|
75
|
+
*
|
|
76
|
+
* @param phoneNumber The phone number to check (with country code)
|
|
77
|
+
*/
|
|
78
|
+
checkNumber(phoneNumber: string): Promise<import("./types/instances.js").CheckNumberResponse>;
|
|
63
79
|
}
|
|
64
80
|
//# sourceMappingURL=client.d.ts.map
|
package/dist/client.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErD,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAgC;IAE9C,iDAAiD;IAC1C,SAAS,EAAE,eAAe,CAAC;IAElC,6EAA6E;IACtE,QAAQ,EAAE,cAAc,CAAC;IAEhC,0DAA0D;IACnD,KAAK,EAAE,WAAW,CAAC;IAE1B,iDAAiD;IAC1C,MAAM,EAAE,YAAY,CAAC;IAE5B,0DAA0D;IACnD,OAAO,EAAE,aAAa,CAAC;IAE9B,gDAAgD;IACzC,SAAS,EAAE,eAAe,CAAC;IAElC,mCAAmC;IAC5B,OAAO,EAAE,cAAc,CAAC;IAE/B;;;;;;;;;;;;;;;;;;OAkBG;gBACS,MAAM,EAAE,mBAAmB;IA8BvC;;OAEG;IACU,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;IAIrD;;OAEG;IACU,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE;;;IAI7G;;OAEG;IACU,SAAS;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAErD,qBAAa,aAAa;IACxB,OAAO,CAAC,MAAM,CAAgC;IAE9C,iDAAiD;IAC1C,SAAS,EAAE,eAAe,CAAC;IAElC,6EAA6E;IACtE,QAAQ,EAAE,cAAc,CAAC;IAEhC,0DAA0D;IACnD,KAAK,EAAE,WAAW,CAAC;IAE1B,iDAAiD;IAC1C,MAAM,EAAE,YAAY,CAAC;IAE5B,0DAA0D;IACnD,OAAO,EAAE,aAAa,CAAC;IAE9B,gDAAgD;IACzC,SAAS,EAAE,eAAe,CAAC;IAElC,mCAAmC;IAC5B,OAAO,EAAE,cAAc,CAAC;IAE/B;;;;;;;;;;;;;;;;;;OAkBG;gBACS,MAAM,EAAE,mBAAmB;IA8BvC;;OAEG;IACU,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM;IAIrD;;OAEG;IACU,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAC;QAAC,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE;;;IAI7G;;OAEG;IACU,SAAS;IAItB;;OAEG;IACU,KAAK;IAIlB;;;;OAIG;IACU,YAAY,CAAC,WAAW,EAAE,MAAM;IAI7C;;;;OAIG;IACU,WAAW,CAAC,WAAW,EAAE,MAAM;CAG7C"}
|
package/dist/client.js
CHANGED
|
@@ -84,4 +84,26 @@ export class BotcastClient {
|
|
|
84
84
|
async getStatus() {
|
|
85
85
|
return this.instances.getStatus();
|
|
86
86
|
}
|
|
87
|
+
/**
|
|
88
|
+
* Shortcut to get the device pairing QR code string.
|
|
89
|
+
*/
|
|
90
|
+
async getQR() {
|
|
91
|
+
return this.instances.getQR();
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Shortcut to request an 8-digit phone PIN pairing code without scanning QR.
|
|
95
|
+
*
|
|
96
|
+
* @param phoneNumber Recipient phone number with country code (e.g. `201000000000` or `15551234567`)
|
|
97
|
+
*/
|
|
98
|
+
async pairWithCode(phoneNumber) {
|
|
99
|
+
return this.instances.pairWithCode(phoneNumber);
|
|
100
|
+
}
|
|
101
|
+
/**
|
|
102
|
+
* Shortcut to verify if a phone number exists on WhatsApp.
|
|
103
|
+
*
|
|
104
|
+
* @param phoneNumber The phone number to check (with country code)
|
|
105
|
+
*/
|
|
106
|
+
async checkNumber(phoneNumber) {
|
|
107
|
+
return this.instances.checkNumber(phoneNumber);
|
|
108
|
+
}
|
|
87
109
|
}
|