botcast-sdk 1.0.4 → 1.0.7

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 CHANGED
@@ -16,7 +16,7 @@ Official Node.js and TypeScript SDK for [Botcast](https://botcast.site) — a hi
16
16
  - **Strict TypeScript Types**: Fully typed request parameters, response models, error classes, and event payloads.
17
17
  - **Dual Authentication**:
18
18
  - **WhatsApp**: Scan QR code string or request an 8-digit PIN code without a camera.
19
- - **Telegram**: Scan QR code via *Telegram > Settings > Devices > Link Desktop Device* or authenticate via phone verification code with optional Cloud 2FA password.
19
+ - **Telegram**: Scan QR code via _Telegram > Settings > Devices > Link Desktop Device_ or authenticate via phone verification code with optional Cloud 2FA password.
20
20
  - **Unified Messaging**: Send text messages, automated OTP codes, images, videos, audio, voice notes (PTT), documents, stickers, locations, contact cards, and interactive polls.
21
21
  - **Message Operations**: Edit sent messages, delete for everyone (revoke), mark as read, reactions, pin messages, and forward.
22
22
  - **Chat & History Management**: Query dialogs, contact lists, and message history for both platforms.
@@ -41,33 +41,67 @@ bun add botcast-sdk
41
41
 
42
42
  ## Quick Start
43
43
 
44
- ### 1. WhatsApp Client
44
+ ### 1. Admin & Fleet Management (Create, Manage & Renew Instances)
45
+
46
+ Use `BotcastAdminClient` with your Master Partner API Key (`bcast_live_...`) to programmatically create and manage customer instances:
45
47
 
46
48
  ```typescript
47
- import { BotcastClient } from 'botcast-sdk';
49
+ import { BotcastAdminClient } from "botcast-sdk";
50
+
51
+ const admin = new BotcastAdminClient({
52
+ baseUrl: "https://botcast.site",
53
+ apiKey: process.env.BOTCAST_API_KEY!, // Master API Key
54
+ });
55
+
56
+ // List all instances
57
+ const { instances } = await admin.listInstances();
58
+
59
+ // Create a new WhatsApp or Telegram instance for a customer
60
+ const { instance } = await admin.createInstance({
61
+ name: "Customer Store 1",
62
+ platform: "whatsapp",
63
+ type: "paid",
64
+ plan_months: 12,
65
+ });
66
+
67
+ // Renew subscription
68
+ await admin.renewInstance(instance.id, { months: 12 });
69
+ ```
70
+
71
+ ---
72
+
73
+ ### 2. WhatsApp Client
74
+
75
+ ```typescript
76
+ import { BotcastClient } from "botcast-sdk";
48
77
 
49
78
  const whatsappBot = new BotcastClient({
50
- baseUrl: 'https://botcast.site', // or your self-hosted server URL
51
- platform: 'whatsapp', // 'whatsapp' (default) or 'telegram'
52
- instanceId: 'your_instance_id',
53
- instanceToken: 'your_instance_token',
79
+ baseUrl: "https://botcast.site", // or your self-hosted server URL
80
+ platform: "whatsapp", // 'whatsapp' (default) or 'telegram'
81
+ instanceId: "your_instance_id",
82
+ instanceToken: "your_instance_token",
54
83
  });
55
84
 
56
85
  async function main() {
57
86
  // Check connectivity
58
87
  const status = await whatsappBot.getStatus();
59
- console.log(`WhatsApp state: ${status.status} (${status.phoneNumber || 'Unpaired'})`);
88
+ console.log(
89
+ `WhatsApp state: ${status.status} (${status.phoneNumber || "Unpaired"})`,
90
+ );
60
91
 
61
92
  // Send a text message
62
- const res = await whatsappBot.messages.sendText('201012345678', 'Hello from WhatsApp via Botcast SDK!');
63
- console.log('Message sent! ID:', res.messageId);
93
+ const res = await whatsappBot.messages.sendText(
94
+ "201012345678",
95
+ "Hello from WhatsApp via Botcast SDK!",
96
+ );
97
+ console.log("Message sent! ID:", res.messageId);
64
98
 
65
99
  // Send a secure 6-digit OTP code
66
- const otp = await whatsappBot.messages.sendOTP('201012345678', {
67
- appName: 'My App',
100
+ const otp = await whatsappBot.messages.sendOTP("201012345678", {
101
+ appName: "My App",
68
102
  expiryMinutes: 5,
69
103
  });
70
- console.log('Dispatched OTP:', otp.codeSent);
104
+ console.log("Dispatched OTP:", otp.codeSent);
71
105
  }
72
106
 
73
107
  main().catch(console.error);
@@ -78,13 +112,13 @@ main().catch(console.error);
78
112
  ### 2. Telegram MTProto Client
79
113
 
80
114
  ```typescript
81
- import { BotcastClient } from 'botcast-sdk';
115
+ import { BotcastClient } from "botcast-sdk";
82
116
 
83
117
  const telegramBot = new BotcastClient({
84
- baseUrl: 'https://botcast.site',
85
- platform: 'telegram',
86
- instanceId: 'your_telegram_instance_id',
87
- instanceToken: 'your_telegram_instance_token',
118
+ baseUrl: "https://botcast.site",
119
+ platform: "telegram",
120
+ instanceId: "your_telegram_instance_id",
121
+ instanceToken: "your_telegram_instance_token",
88
122
  });
89
123
 
90
124
  async function main() {
@@ -93,20 +127,23 @@ async function main() {
93
127
  console.log(`Telegram state: ${status.status}`);
94
128
 
95
129
  // Send a text message to a phone number or @username
96
- const res = await telegramBot.messages.sendText('+1234567890', 'Hello from Telegram MTProto!');
97
- console.log('Message ID:', res.messageId);
130
+ const res = await telegramBot.messages.sendText(
131
+ "+1234567890",
132
+ "Hello from Telegram MTProto!",
133
+ );
134
+ console.log("Message ID:", res.messageId);
98
135
 
99
136
  // Send a photo
100
- await telegramBot.messages.sendImage('+1234567890', {
101
- url: 'https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?w=800',
102
- caption: 'Welcome flyer',
137
+ await telegramBot.messages.sendImage("+1234567890", {
138
+ url: "https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?w=800",
139
+ caption: "Welcome flyer",
103
140
  });
104
141
 
105
142
  // Send OTP
106
- const otp = await telegramBot.messages.sendOTP('+1234567890', {
107
- appName: 'Security Portal',
143
+ const otp = await telegramBot.messages.sendOTP("+1234567890", {
144
+ appName: "Security Portal",
108
145
  });
109
- console.log('Telegram OTP sent:', otp.codeSent);
146
+ console.log("Telegram OTP sent:", otp.codeSent);
110
147
  }
111
148
 
112
149
  main().catch(console.error);
@@ -117,12 +154,12 @@ main().catch(console.error);
117
154
  ### CommonJS (require)
118
155
 
119
156
  ```javascript
120
- const { BotcastClient } = require('botcast-sdk');
157
+ const { BotcastClient } = require("botcast-sdk");
121
158
 
122
159
  const client = new BotcastClient({
123
- platform: 'telegram', // or 'whatsapp'
124
- instanceId: 'your_instance_id',
125
- instanceToken: 'your_instance_token',
160
+ platform: "telegram", // or 'whatsapp'
161
+ instanceId: "your_instance_id",
162
+ instanceToken: "your_instance_token",
126
163
  });
127
164
  ```
128
165
 
@@ -135,24 +172,24 @@ const client = new BotcastClient({
135
172
  ```typescript
136
173
  // 1. Get live status
137
174
  const status = await client.instances.getStatus();
138
- console.log('State:', status.status); // 'connected' | 'qr_ready' | 'stopped' | 'connecting'
175
+ console.log("State:", status.status); // 'connected' | 'qr_ready' | 'stopped' | 'connecting'
139
176
 
140
177
  // 2. Option A: Get QR code string for camera scanning
141
178
  // (WhatsApp: Linked Devices | Telegram: Settings > Devices > Link Desktop Device)
142
179
  const qr = await client.getQR(); // or client.instances.getQR()
143
- console.log('QR DataURL:', qr.qr);
180
+ console.log("QR DataURL:", qr.qr);
144
181
 
145
182
  // 3. Option B: Request Phone Pairing / Login Code
146
183
  // (WhatsApp sends 8-digit PIN | Telegram sends verification code into app)
147
- const pair = await client.pairWithCode('+1234567890');
148
- console.log('Code request status:', pair);
184
+ const pair = await client.pairWithCode("+1234567890");
185
+ console.log("Code request status:", pair);
149
186
 
150
187
  // 4. Complete Telegram Phone Login (with optional 2FA cloud password)
151
- await client.instances.verifyCode('+1234567890', '12345', 'myCloudPassword2fa');
188
+ await client.instances.verifyCode("+1234567890", "12345", "myCloudPassword2fa");
152
189
 
153
190
  // 5. Socket engine controls
154
- await client.instances.start(); // Boots socket / MTProto connection
155
- await client.instances.stop(); // Suspends socket session
191
+ await client.instances.start(); // Boots socket / MTProto connection
192
+ await client.instances.stop(); // Suspends socket session
156
193
  await client.instances.logout(); // Unlinks device and clears session credentials
157
194
  ```
158
195
 
@@ -164,51 +201,51 @@ All messaging methods work across both **WhatsApp** and **Telegram**:
164
201
 
165
202
  ```typescript
166
203
  // 1. Text message
167
- await client.messages.sendText('+1234567890', 'Hello World', {
168
- mentions: ['1234567890'], // WhatsApp mentions
204
+ await client.messages.sendText("+1234567890", "Hello World", {
205
+ mentions: ["1234567890"], // WhatsApp mentions
169
206
  });
170
207
 
171
208
  // 2. Image / Photo
172
- await client.messages.sendImage('+1234567890', {
173
- url: 'https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?w=800',
174
- caption: 'Photo preview',
209
+ await client.messages.sendImage("+1234567890", {
210
+ url: "https://images.unsplash.com/photo-1618005182384-a83a8bd57fbe?w=800",
211
+ caption: "Photo preview",
175
212
  });
176
213
 
177
214
  // 3. Video
178
- await client.messages.sendVideo('+1234567890', {
179
- url: 'https://sample-videos.com/video321/mp4/720/big_buck_bunny_720p_1mb.mp4',
180
- caption: 'Product tutorial video',
215
+ await client.messages.sendVideo("+1234567890", {
216
+ url: "https://sample-videos.com/video321/mp4/720/big_buck_bunny_720p_1mb.mp4",
217
+ caption: "Product tutorial video",
181
218
  });
182
219
 
183
220
  // 4. Voice note and audio
184
- await client.messages.sendVoice('+1234567890', {
185
- url: 'https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3',
221
+ await client.messages.sendVoice("+1234567890", {
222
+ url: "https://www.soundhelix.com/examples/mp3/SoundHelix-Song-1.mp3",
186
223
  });
187
224
 
188
225
  // 5. Document / PDF / File
189
- await client.messages.sendDocument('+1234567890', {
190
- url: 'https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf',
191
- fileName: 'Invoice_2026.pdf',
192
- caption: 'Monthly invoice statement',
226
+ await client.messages.sendDocument("+1234567890", {
227
+ url: "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf",
228
+ fileName: "Invoice_2026.pdf",
229
+ caption: "Monthly invoice statement",
193
230
  });
194
231
 
195
232
  // 6. Location coordinates
196
- await client.messages.sendLocation('+1234567890', {
233
+ await client.messages.sendLocation("+1234567890", {
197
234
  latitude: 24.7136,
198
235
  longitude: 46.6753,
199
- name: 'Kingdom Tower',
200
- address: 'King Fahd Rd, Riyadh, Saudi Arabia',
236
+ name: "Kingdom Tower",
237
+ address: "King Fahd Rd, Riyadh, Saudi Arabia",
201
238
  });
202
239
 
203
240
  // 7. Contact Card
204
- await client.messages.sendContact('+1234567890', {
205
- firstName: 'Support Agent',
206
- phone: '+1234567890',
241
+ await client.messages.sendContact("+1234567890", {
242
+ firstName: "Support Agent",
243
+ phone: "+1234567890",
207
244
  });
208
245
 
209
246
  // 8. Automated OTP verification code
210
- const otp = await client.messages.sendOTP('+1234567890', {
211
- appName: 'Botcast Portal',
247
+ const otp = await client.messages.sendOTP("+1234567890", {
248
+ appName: "Botcast Portal",
212
249
  expiryMinutes: 5,
213
250
  });
214
251
  ```
@@ -219,28 +256,30 @@ const otp = await client.messages.sendOTP('+1234567890', {
219
256
 
220
257
  ```typescript
221
258
  const msgKey = {
222
- remoteJid: '201012345678@s.whatsapp.net',
259
+ remoteJid: "201012345678@s.whatsapp.net",
223
260
  fromMe: true,
224
- id: '3EB0ABCDEF1234567890',
261
+ id: "3EB0ABCDEF1234567890",
225
262
  };
226
263
 
227
264
  // 1. Edit sent message
228
- await client.messages.edit('201012345678', msgKey, 'Corrected text content');
265
+ await client.messages.edit("201012345678", msgKey, "Corrected text content");
229
266
 
230
267
  // 2. Delete message for everyone (revoke)
231
- await client.messages.delete('201012345678', msgKey);
268
+ await client.messages.delete("201012345678", msgKey);
232
269
 
233
270
  // 3. Mark message as read
234
271
  await client.messages.markAsRead(msgKey);
235
272
 
236
273
  // 4. Emoji reaction
237
- await client.messages.react('201012345678', msgKey, '👍');
274
+ await client.messages.react("201012345678", msgKey, "👍");
238
275
 
239
276
  // 5. Pin message
240
- await client.messages.pin('201012345678', msgKey, 1, 86400);
277
+ await client.messages.pin("201012345678", msgKey, 1, 86400);
241
278
 
242
279
  // 6. Forward message
243
- await client.messages.forward('201012345678', { conversation: 'Forwarded message text' });
280
+ await client.messages.forward("201012345678", {
281
+ conversation: "Forwarded message text",
282
+ });
244
283
  ```
245
284
 
246
285
  ---
@@ -255,12 +294,15 @@ const { chats } = await client.chats.list({ limit: 50 });
255
294
  const { contacts } = await client.chats.listContacts({ limit: 100 });
256
295
 
257
296
  // 3. List messages for a chat
258
- const { messages } = await client.chats.listMessages({ chatJid: '201012345678@s.whatsapp.net', limit: 50 });
297
+ const { messages } = await client.chats.listMessages({
298
+ chatJid: "201012345678@s.whatsapp.net",
299
+ limit: 50,
300
+ });
259
301
 
260
302
  // 4. Modify WhatsApp chat state (archive, mute, pin, delete)
261
- await client.chats.archive('201012345678@s.whatsapp.net');
262
- await client.chats.mute('201012345678@s.whatsapp.net', 8 * 60 * 60 * 1000); // 8 hours
263
- await client.chats.pin('201012345678@s.whatsapp.net');
303
+ await client.chats.archive("201012345678@s.whatsapp.net");
304
+ await client.chats.mute("201012345678@s.whatsapp.net", 8 * 60 * 60 * 1000); // 8 hours
305
+ await client.chats.pin("201012345678@s.whatsapp.net");
264
306
  ```
265
307
 
266
308
  ---
@@ -272,24 +314,26 @@ The SDK includes a built-in event dispatcher and middleware for handling inbound
272
314
  #### Express Example
273
315
 
274
316
  ```typescript
275
- import express from 'express';
276
- import { BotcastClient } from 'botcast-sdk';
317
+ import express from "express";
318
+ import { BotcastClient } from "botcast-sdk";
277
319
 
278
320
  const app = express();
279
321
  app.use(express.json());
280
322
 
281
323
  const client = new BotcastClient({
282
- platform: 'telegram', // or 'whatsapp'
283
- instanceId: 'inst_123',
284
- instanceToken: 'tok_abc',
324
+ platform: "telegram", // or 'whatsapp'
325
+ instanceId: "inst_123",
326
+ instanceToken: "tok_abc",
285
327
  });
286
328
 
287
329
  // Listen for incoming messages
288
330
  client.webhook.onMessage(async (event) => {
289
- console.log(`Message from ${event.sender}: ${event.message} [Platform: ${event.platform || 'whatsapp'}]`);
331
+ console.log(
332
+ `Message from ${event.sender}: ${event.message} [Platform: ${event.platform || "whatsapp"}]`,
333
+ );
290
334
 
291
- if (event.message.trim().toLowerCase() === 'ping') {
292
- await client.messages.sendText(event.sender, 'pong');
335
+ if (event.message.trim().toLowerCase() === "ping") {
336
+ await client.messages.sendText(event.sender, "pong");
293
337
  }
294
338
  });
295
339
 
@@ -299,9 +343,9 @@ client.webhook.onConnection(async (event) => {
299
343
  });
300
344
 
301
345
  // Mount middleware on your webhook route
302
- app.post('/webhook/botcast', client.webhook.middleware());
346
+ app.post("/webhook/botcast", client.webhook.middleware());
303
347
 
304
- app.listen(3000, () => console.log('Webhook server running on port 3000'));
348
+ app.listen(3000, () => console.log("Webhook server running on port 3000"));
305
349
  ```
306
350
 
307
351
  ---
@@ -319,25 +363,25 @@ import {
319
363
  BotcastRateLimitError,
320
364
  BotcastValidationError,
321
365
  BotcastNotFoundError,
322
- } from 'botcast-sdk';
366
+ } from "botcast-sdk";
323
367
 
324
368
  try {
325
- await client.messages.sendText('+1234567890', 'Hello World');
369
+ await client.messages.sendText("+1234567890", "Hello World");
326
370
  } catch (error) {
327
371
  if (error instanceof BotcastAuthError) {
328
- console.error('Invalid instance credentials or token.');
372
+ console.error("Invalid instance credentials or token.");
329
373
  } else if (error instanceof BotcastPaymentRequiredError) {
330
- console.error('Instance requires payment confirmation.');
374
+ console.error("Instance requires payment confirmation.");
331
375
  } else if (error instanceof BotcastSubscriptionExpiredError) {
332
- console.error('Subscription expired on:', error.expiresAt);
376
+ console.error("Subscription expired on:", error.expiresAt);
333
377
  } else if (error instanceof BotcastRateLimitError) {
334
- console.error('Daily message limit reached.');
378
+ console.error("Daily message limit reached.");
335
379
  } else if (error instanceof BotcastValidationError) {
336
- console.error('Validation error:', error.message, error.details);
380
+ console.error("Validation error:", error.message, error.details);
337
381
  } else if (error instanceof BotcastNotFoundError) {
338
- console.error('Resource not found:', error.message);
382
+ console.error("Resource not found:", error.message);
339
383
  } else {
340
- console.error('Unexpected error:', error);
384
+ console.error("Unexpected error:", error);
341
385
  }
342
386
  }
343
387
  ```
@@ -349,7 +393,7 @@ try {
349
393
  - Website: [https://botcast.site](https://botcast.site)
350
394
  - Documentation: [https://botcast.site/docs](https://botcast.site/docs)
351
395
  - NPM Package: [https://www.npmjs.com/package/botcast-sdk](https://www.npmjs.com/package/botcast-sdk)
352
- - GitHub Repository: [https://github.com/ANOOBALSA/Botcast](https://github.com/ANOOBALSA/Botcast)
396
+ - GitHub Repository: [https://github.com/alsasoft-web/Botcast](https://github.com/alsasoft-web/Botcast)
353
397
 
354
398
  ---
355
399
 
package/dist/admin.cjs ADDED
@@ -0,0 +1,118 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BotcastAdminClient = void 0;
4
+ const errors_js_1 = require("./errors.js");
5
+ class BotcastAdminClient {
6
+ baseUrl;
7
+ apiKey;
8
+ timeout;
9
+ headers;
10
+ constructor(config) {
11
+ if (!config.apiKey) {
12
+ throw new Error('BotcastAdminClient requires a valid "apiKey" (e.g. bcast_live_...)');
13
+ }
14
+ this.baseUrl = (config.baseUrl || 'https://botcast.site').replace(/\/+$/, '');
15
+ this.apiKey = config.apiKey.trim();
16
+ this.timeout = config.timeout || 30000;
17
+ this.headers = config.headers || {};
18
+ }
19
+ async request(endpoint, options = {}) {
20
+ const url = `${this.baseUrl}${endpoint.startsWith('/') ? '' : '/'}${endpoint}`;
21
+ const controller = new AbortController();
22
+ const timer = setTimeout(() => controller.abort(), this.timeout);
23
+ const mergedHeaders = {
24
+ 'Content-Type': 'application/json',
25
+ 'x-api-key': this.apiKey,
26
+ ...this.headers,
27
+ ...(options.headers || {}),
28
+ };
29
+ try {
30
+ const res = await fetch(url, {
31
+ ...options,
32
+ headers: mergedHeaders,
33
+ signal: controller.signal,
34
+ });
35
+ const body = await res.json().catch(() => ({}));
36
+ if (!res.ok) {
37
+ throw new errors_js_1.BotcastError(body.message || body.error || `HTTP ${res.status}: ${res.statusText}`, res.status, body);
38
+ }
39
+ return body;
40
+ }
41
+ catch (err) {
42
+ if (err.name === 'AbortError') {
43
+ throw new errors_js_1.BotcastError(`Request timed out after ${this.timeout}ms`, 408);
44
+ }
45
+ throw err;
46
+ }
47
+ finally {
48
+ clearTimeout(timer);
49
+ }
50
+ }
51
+ /**
52
+ * Lists all instances under this admin/partner account with live statuses and stats.
53
+ */
54
+ async listInstances() {
55
+ return this.request('/api/instances', { method: 'GET' });
56
+ }
57
+ /**
58
+ * Retrieves single instance details including QR code, pairing code, status, and expiry.
59
+ */
60
+ async getInstance(instanceId) {
61
+ return this.request(`/api/instances/${instanceId}`, { method: 'GET' });
62
+ }
63
+ /**
64
+ * Creates and immediately provisions a new WhatsApp or Telegram instance.
65
+ * Admins are zero-payment, so instances are provisioned as active paid instances.
66
+ */
67
+ async createInstance(options) {
68
+ return this.request('/api/instances', {
69
+ method: 'POST',
70
+ body: JSON.stringify({
71
+ name: options.name,
72
+ platform: options.platform || 'whatsapp',
73
+ type: options.type || 'paid',
74
+ plan_months: options.plan_months || 12,
75
+ allowed_numbers: options.allowed_numbers || [],
76
+ webhook_url: options.webhook_url || '',
77
+ target_user_id: options.target_user_id,
78
+ }),
79
+ });
80
+ }
81
+ /**
82
+ * Programmatically renews an instance's subscription without payment transactions.
83
+ */
84
+ async renewInstance(instanceId, options) {
85
+ return this.request(`/api/instances/${instanceId}/renew`, {
86
+ method: 'POST',
87
+ body: JSON.stringify({
88
+ months: options?.months || options?.plan_months || 12,
89
+ }),
90
+ });
91
+ }
92
+ /**
93
+ * Updates instance configuration (name, webhook URL, allowed recipient numbers).
94
+ */
95
+ async updateInstance(instanceId, updates) {
96
+ return this.request(`/api/instances/${instanceId}`, {
97
+ method: 'PUT',
98
+ body: JSON.stringify(updates),
99
+ });
100
+ }
101
+ /**
102
+ * Regenerates secret instance token for an instance.
103
+ */
104
+ async regenerateInstanceToken(instanceId) {
105
+ return this.request(`/api/instances/${instanceId}/regenerate-token`, {
106
+ method: 'POST',
107
+ });
108
+ }
109
+ /**
110
+ * Deletes and cleans up an instance.
111
+ */
112
+ async deleteInstance(instanceId) {
113
+ return this.request(`/api/instances/${instanceId}`, {
114
+ method: 'DELETE',
115
+ });
116
+ }
117
+ }
118
+ exports.BotcastAdminClient = BotcastAdminClient;
@@ -0,0 +1,97 @@
1
+ export interface BotcastAdminConfig {
2
+ baseUrl?: string;
3
+ apiKey: string;
4
+ timeout?: number;
5
+ headers?: Record<string, string>;
6
+ }
7
+ export interface CreateAdminInstanceOptions {
8
+ name: string;
9
+ platform?: 'whatsapp' | 'telegram';
10
+ type?: 'dev' | 'paid';
11
+ plan_months?: number;
12
+ allowed_numbers?: string[];
13
+ webhook_url?: string;
14
+ target_user_id?: number;
15
+ }
16
+ export interface AdminInstanceRecord {
17
+ id: string;
18
+ user_id: number;
19
+ name: string;
20
+ instance_token: string;
21
+ platform: 'whatsapp' | 'telegram';
22
+ type: 'dev' | 'paid';
23
+ status: string;
24
+ allowed_numbers: string[];
25
+ webhook_url: string | null;
26
+ plan_months: number;
27
+ expires_at: string | null;
28
+ is_expired?: boolean;
29
+ qr?: string | null;
30
+ pairingCode?: string | null;
31
+ created_at: string;
32
+ }
33
+ export declare class BotcastAdminClient {
34
+ private baseUrl;
35
+ private apiKey;
36
+ private timeout;
37
+ private headers;
38
+ constructor(config: BotcastAdminConfig);
39
+ private request;
40
+ /**
41
+ * Lists all instances under this admin/partner account with live statuses and stats.
42
+ */
43
+ listInstances(): Promise<{
44
+ instances: AdminInstanceRecord[];
45
+ }>;
46
+ /**
47
+ * Retrieves single instance details including QR code, pairing code, status, and expiry.
48
+ */
49
+ getInstance(instanceId: string): Promise<{
50
+ instance: AdminInstanceRecord;
51
+ }>;
52
+ /**
53
+ * Creates and immediately provisions a new WhatsApp or Telegram instance.
54
+ * Admins are zero-payment, so instances are provisioned as active paid instances.
55
+ */
56
+ createInstance(options: CreateAdminInstanceOptions): Promise<{
57
+ message: string;
58
+ instance: AdminInstanceRecord;
59
+ }>;
60
+ /**
61
+ * Programmatically renews an instance's subscription without payment transactions.
62
+ */
63
+ renewInstance(instanceId: string, options?: {
64
+ months?: number;
65
+ plan_months?: number;
66
+ }): Promise<{
67
+ success: boolean;
68
+ message: string;
69
+ instance: AdminInstanceRecord;
70
+ }>;
71
+ /**
72
+ * Updates instance configuration (name, webhook URL, allowed recipient numbers).
73
+ */
74
+ updateInstance(instanceId: string, updates: {
75
+ name?: string;
76
+ webhook_url?: string;
77
+ allowed_numbers?: string[];
78
+ }): Promise<{
79
+ message: string;
80
+ instance: AdminInstanceRecord;
81
+ }>;
82
+ /**
83
+ * Regenerates secret instance token for an instance.
84
+ */
85
+ regenerateInstanceToken(instanceId: string): Promise<{
86
+ message: string;
87
+ instance_token: string;
88
+ }>;
89
+ /**
90
+ * Deletes and cleans up an instance.
91
+ */
92
+ deleteInstance(instanceId: string): Promise<{
93
+ message: string;
94
+ instanceId: string;
95
+ }>;
96
+ }
97
+ //# sourceMappingURL=admin.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"admin.d.ts","sourceRoot":"","sources":["../../src/admin.ts"],"names":[],"mappings":"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"}
package/dist/admin.js ADDED
@@ -0,0 +1,114 @@
1
+ import { BotcastError } from './errors.js';
2
+ export class BotcastAdminClient {
3
+ baseUrl;
4
+ apiKey;
5
+ timeout;
6
+ headers;
7
+ constructor(config) {
8
+ if (!config.apiKey) {
9
+ throw new Error('BotcastAdminClient requires a valid "apiKey" (e.g. bcast_live_...)');
10
+ }
11
+ this.baseUrl = (config.baseUrl || 'https://botcast.site').replace(/\/+$/, '');
12
+ this.apiKey = config.apiKey.trim();
13
+ this.timeout = config.timeout || 30000;
14
+ this.headers = config.headers || {};
15
+ }
16
+ async request(endpoint, options = {}) {
17
+ const url = `${this.baseUrl}${endpoint.startsWith('/') ? '' : '/'}${endpoint}`;
18
+ const controller = new AbortController();
19
+ const timer = setTimeout(() => controller.abort(), this.timeout);
20
+ const mergedHeaders = {
21
+ 'Content-Type': 'application/json',
22
+ 'x-api-key': this.apiKey,
23
+ ...this.headers,
24
+ ...(options.headers || {}),
25
+ };
26
+ try {
27
+ const res = await fetch(url, {
28
+ ...options,
29
+ headers: mergedHeaders,
30
+ signal: controller.signal,
31
+ });
32
+ const body = await res.json().catch(() => ({}));
33
+ if (!res.ok) {
34
+ throw new BotcastError(body.message || body.error || `HTTP ${res.status}: ${res.statusText}`, res.status, body);
35
+ }
36
+ return body;
37
+ }
38
+ catch (err) {
39
+ if (err.name === 'AbortError') {
40
+ throw new BotcastError(`Request timed out after ${this.timeout}ms`, 408);
41
+ }
42
+ throw err;
43
+ }
44
+ finally {
45
+ clearTimeout(timer);
46
+ }
47
+ }
48
+ /**
49
+ * Lists all instances under this admin/partner account with live statuses and stats.
50
+ */
51
+ async listInstances() {
52
+ return this.request('/api/instances', { method: 'GET' });
53
+ }
54
+ /**
55
+ * Retrieves single instance details including QR code, pairing code, status, and expiry.
56
+ */
57
+ async getInstance(instanceId) {
58
+ return this.request(`/api/instances/${instanceId}`, { method: 'GET' });
59
+ }
60
+ /**
61
+ * Creates and immediately provisions a new WhatsApp or Telegram instance.
62
+ * Admins are zero-payment, so instances are provisioned as active paid instances.
63
+ */
64
+ async createInstance(options) {
65
+ return this.request('/api/instances', {
66
+ method: 'POST',
67
+ body: JSON.stringify({
68
+ name: options.name,
69
+ platform: options.platform || 'whatsapp',
70
+ type: options.type || 'paid',
71
+ plan_months: options.plan_months || 12,
72
+ allowed_numbers: options.allowed_numbers || [],
73
+ webhook_url: options.webhook_url || '',
74
+ target_user_id: options.target_user_id,
75
+ }),
76
+ });
77
+ }
78
+ /**
79
+ * Programmatically renews an instance's subscription without payment transactions.
80
+ */
81
+ async renewInstance(instanceId, options) {
82
+ return this.request(`/api/instances/${instanceId}/renew`, {
83
+ method: 'POST',
84
+ body: JSON.stringify({
85
+ months: options?.months || options?.plan_months || 12,
86
+ }),
87
+ });
88
+ }
89
+ /**
90
+ * Updates instance configuration (name, webhook URL, allowed recipient numbers).
91
+ */
92
+ async updateInstance(instanceId, updates) {
93
+ return this.request(`/api/instances/${instanceId}`, {
94
+ method: 'PUT',
95
+ body: JSON.stringify(updates),
96
+ });
97
+ }
98
+ /**
99
+ * Regenerates secret instance token for an instance.
100
+ */
101
+ async regenerateInstanceToken(instanceId) {
102
+ return this.request(`/api/instances/${instanceId}/regenerate-token`, {
103
+ method: 'POST',
104
+ });
105
+ }
106
+ /**
107
+ * Deletes and cleans up an instance.
108
+ */
109
+ async deleteInstance(instanceId) {
110
+ return this.request(`/api/instances/${instanceId}`, {
111
+ method: 'DELETE',
112
+ });
113
+ }
114
+ }
package/dist/index.cjs CHANGED
@@ -14,9 +14,11 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
14
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
- exports.BotcastWebhook = exports.BotcastClient = void 0;
17
+ exports.BotcastWebhook = exports.BotcastAdminClient = exports.BotcastClient = void 0;
18
18
  var client_js_1 = require("./client.js");
19
19
  Object.defineProperty(exports, "BotcastClient", { enumerable: true, get: function () { return client_js_1.BotcastClient; } });
20
+ var admin_js_1 = require("./admin.js");
21
+ Object.defineProperty(exports, "BotcastAdminClient", { enumerable: true, get: function () { return admin_js_1.BotcastAdminClient; } });
20
22
  var index_js_1 = require("./webhooks/index.js");
21
23
  Object.defineProperty(exports, "BotcastWebhook", { enumerable: true, get: function () { return index_js_1.BotcastWebhook; } });
22
24
  __exportStar(require("./errors.js"), exports);
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export { BotcastClient } from './client.js';
2
+ export { BotcastAdminClient, BotcastAdminConfig, CreateAdminInstanceOptions, AdminInstanceRecord } from './admin.js';
2
3
  export { BotcastWebhook } from './webhooks/index.js';
3
4
  export * from './errors.js';
4
5
  export * from './types/index.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AAGjC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,eAAe,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,0BAA0B,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACrH,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AACrD,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AAGjC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,eAAe,aAAa,CAAC"}
package/dist/index.js CHANGED
@@ -1,4 +1,5 @@
1
1
  export { BotcastClient } from './client.js';
2
+ export { BotcastAdminClient } from './admin.js';
2
3
  export { BotcastWebhook } from './webhooks/index.js';
3
4
  export * from './errors.js';
4
5
  export * from './types/index.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "botcast-sdk",
3
- "version": "1.0.4",
3
+ "version": "1.0.7",
4
4
  "description": "Official TypeScript/JavaScript SDK for Botcast WhatsApp & Telegram MTProto Multi-Instance API Gateway",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -51,7 +51,7 @@
51
51
  "homepage": "https://botcast.site",
52
52
  "repository": {
53
53
  "type": "git",
54
- "url": "git+https://github.com/ANOOBALSA/botcast-sdk.git",
54
+ "url": "git+https://github.com/alsasoft-web/botcast-sdk.git",
55
55
  "directory": "packages/botcast-sdk"
56
56
  },
57
57
  "bugs": {