@vzaps/sdk 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 VZaps
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,396 @@
1
+ # VZaps TypeScript SDK
2
+
3
+ Official TypeScript/JavaScript client for the [VZaps public API](https://docs.vzaps.com). Send WhatsApp messages, manage instances, configure webhooks, and subscribe to realtime events with a typed, promise-based interface.
4
+
5
+ Works in **Node.js 18+** (ESM and CommonJS). Browser usage is supported for HTTP calls; WebSocket realtime in Node uses the bundled `ws` client automatically.
6
+
7
+ ---
8
+
9
+ ## Table of contents
10
+
11
+ - [Features](#features)
12
+ - [Requirements](#requirements)
13
+ - [Installation](#installation)
14
+ - [Quick start](#quick-start)
15
+ - [Authentication](#authentication)
16
+ - [Configuration](#configuration)
17
+ - [Resources](#resources)
18
+ - [Instance tokens](#instance-tokens)
19
+ - [Webhooks](#webhooks)
20
+ - [Realtime events](#realtime-events)
21
+ - [Error handling](#error-handling)
22
+ - [TypeScript](#typescript)
23
+ - [Documentation](#documentation)
24
+
25
+ ---
26
+
27
+ ## Features
28
+
29
+ - **Automatic JWT handling** — exchanges `clientToken` + `clientSecret` for a bearer token and refreshes it before expiry.
30
+ - **Resource-oriented API** — `instances`, `messages`, `webhooks`, `contacts`, `groups`, and `events` mirror the public HTTP contract.
31
+ - **Realtime WebSocket client** — subscribe to instance events with reconnect, resume (`lastEventId`), and server-side ack.
32
+ - **Instance token support** — set a default token on the client or override it per request.
33
+ - **Fully typed** — ships TypeScript definitions for client options, events, and request payloads.
34
+ - **Extensible transport** — inject custom `fetch` and `webSocketFactory` implementations for tests or edge runtimes.
35
+
36
+ ---
37
+
38
+ ## Requirements
39
+
40
+ | Runtime | Minimum version |
41
+ | --- | --- |
42
+ | Node.js | 18+ |
43
+ | TypeScript | 5.x (optional, for app development) |
44
+
45
+ The SDK uses the global `fetch` API. On Node 18+, no extra HTTP dependency is required.
46
+
47
+ ---
48
+
49
+ ## Installation
50
+
51
+ ```bash
52
+ npm install @vzaps/sdk
53
+ ```
54
+
55
+ ```bash
56
+ yarn add @vzaps/sdk
57
+ ```
58
+
59
+ ```bash
60
+ pnpm add @vzaps/sdk
61
+ ```
62
+
63
+ ---
64
+
65
+ ## Quick start
66
+
67
+ Create credentials in the [VZaps dashboard](https://docs.vzaps.com) (`clientToken` and `clientSecret`), then send a text message:
68
+
69
+ ```ts
70
+ import { VZapsClient } from '@vzaps/sdk';
71
+
72
+ const vzaps = new VZapsClient({
73
+ clientToken: process.env.VZAPS_CLIENT_TOKEN!,
74
+ clientSecret: process.env.VZAPS_CLIENT_SECRET!,
75
+ });
76
+
77
+ await vzaps.messages.sendText({
78
+ instanceId: 'VZKB8AU4S4CWY1SLXX4I5WJGRZQMDDFTV6',
79
+ instanceToken: process.env.VZAPS_INSTANCE_TOKEN!,
80
+ phone: '5511999999999',
81
+ message: 'Hello from VZaps',
82
+ });
83
+ ```
84
+
85
+ ---
86
+
87
+ ## Authentication
88
+
89
+ VZaps uses a two-step model:
90
+
91
+ 1. **Account credentials** — `clientToken` and `clientSecret` identify your integration. The SDK calls `POST /auth/token` and caches the JWT.
92
+ 2. **Instance token** — instance-scoped routes also require `X-Instance-Token`. Pass it on each instance-scoped request (see [Instance tokens](#instance-tokens)).
93
+
94
+ Every authenticated HTTP request sends:
95
+
96
+ | Header | Value |
97
+ | --- | --- |
98
+ | `Authorization` | `Bearer <jwt>` |
99
+ | `X-Client-Token` | Your client token |
100
+ | `X-Instance-Token` | Instance token, on instance-scoped requests |
101
+
102
+ You rarely need to call `auth.getAccessToken()` directly — resources attach the token for you. Use it when integrating with custom HTTP logic:
103
+
104
+ ```ts
105
+ const token = await vzaps.auth.getAccessToken();
106
+ ```
107
+
108
+ ---
109
+
110
+ ## Configuration
111
+
112
+ The SDK connects to the VZaps production platform automatically:
113
+
114
+ | Service | Endpoint |
115
+ | --- | --- |
116
+ | REST API | `https://api.vzaps.com` |
117
+ | Realtime WebSocket | `wss://realtime.vzaps.com/events/ws` |
118
+
119
+ Pass options to `new VZapsClient(options)`:
120
+
121
+ | Option | Type | Default | Description |
122
+ | --- | --- | --- | --- |
123
+ | `clientToken` | `string` | — | **Required.** Public client token from the dashboard. |
124
+ | `clientSecret` | `string` | — | **Required.** Client secret used to obtain JWTs. |
125
+ | `timeoutMs` | `number` | `30000` | HTTP request timeout in milliseconds. |
126
+ | `tokenSkewMs` | `number` | `60000` | Refresh JWT this many ms before expiry. |
127
+ | `fetch` | `FetchLike` | `globalThis.fetch` | Custom fetch implementation. |
128
+ | `webSocketFactory` | `WebSocketFactory` | Node: `ws` / browser: `WebSocket` | Custom WebSocket constructor. |
129
+ | `userAgent` | `string` | — | Optional `User-Agent` header on HTTP requests. |
130
+
131
+ No host configuration is required — install the package, pass your credentials, and the client targets the production API and realtime service.
132
+
133
+ ---
134
+
135
+ ## Resources
136
+
137
+ The client exposes namespaced resources. Generic response types (`TResponse`) let you align with your own interfaces or the [OpenAPI schema](https://docs.vzaps.com/api-reference).
138
+
139
+ ### `vzaps.instances`
140
+
141
+ | Method | HTTP | Description |
142
+ | --- | --- | --- |
143
+ | `create(data)` | `PUT /instances/create` | Create a WhatsApp instance. |
144
+ | `list(data?)` | `POST /instances/list` | List instances (pagination, search, sort). |
145
+ | `get(instanceId, options?)` | `GET /instances/:id` | Get instance details. |
146
+ | `update(instanceId, data, options?)` | `PATCH /instances/:id` | Update instance settings. |
147
+ | `restart(instanceId, options?)` | `POST /instances/:id/restart` | Restart instance runtime. |
148
+
149
+ ### `vzaps.messages`
150
+
151
+ `vzaps.messages` wraps the public WhatsApp send and chat endpoints. The most common calls are shown below; the SDK also exposes the other public message operations documented in the API reference, including media, interactive messages, reactions, polls, downloads, edits, deletes, presence, and read receipts.
152
+
153
+ ```ts
154
+ await vzaps.messages.sendText({
155
+ instanceId: 'VZ...',
156
+ instanceToken: 'instance-token',
157
+ phone: '5511999999999',
158
+ message: 'Hello',
159
+ });
160
+
161
+ await vzaps.messages.sendImage({
162
+ instanceId: 'VZ...',
163
+ instanceToken: 'instance-token',
164
+ phone: '5511999999999',
165
+ image: 'https://example.com/photo.jpg',
166
+ caption: 'Check this out',
167
+ });
168
+ ```
169
+
170
+ Available send helpers include `sendText`, `sendImage`, `sendAudio`, `sendDocument`, `sendVideo`, `sendSticker`, `sendGif`, `sendLocation`, `sendContact`, `sendButtons`, `sendList`, `sendLink`, and `sendPoll`. See the API documentation for complete payload examples.
171
+
172
+ ### `vzaps.webhooks`
173
+
174
+ | Method | HTTP | Description |
175
+ | --- | --- | --- |
176
+ | `get(instanceId, options?)` | `GET /instances/:id/webhook` | Read current webhook configuration. |
177
+ | `set(request)` | `POST /instances/:id/webhook` | Configure webhook URL and subscribed events. |
178
+
179
+ ### `vzaps.contacts`
180
+
181
+ | Method | HTTP | Description |
182
+ | --- | --- | --- |
183
+ | `list(instanceId, options?)` | `GET /instances/:id/contact/list` | List contacts for the instance. |
184
+ | `add(request)` | `POST /instances/:id/contact/add` | Add a contact. |
185
+
186
+ ### `vzaps.groups`
187
+
188
+ | Method | HTTP | Description |
189
+ | --- | --- | --- |
190
+ | `list(request)` | `GET /instances/:id/group/list` | List groups (paginated). |
191
+ | `get(request)` | `GET /instances/:id/group/info` | Get group metadata by `groupId`. |
192
+
193
+ Other public namespaces are available as first-class resources too: `sessions`, `users`, `queues`, `typebots`, `chatwoot`, and `chats`.
194
+
195
+ ### `vzaps.request(method, path, options?)`
196
+
197
+ Escape hatch for advanced calls or newly released endpoints:
198
+
199
+ ```ts
200
+ const result = await vzaps.request('GET', '/plans/list');
201
+ ```
202
+
203
+ ---
204
+
205
+ ## Instance Tokens
206
+
207
+ Instance-scoped routes require the instance token in addition to account credentials. Pass it on each request that targets an instance:
208
+
209
+ ```ts
210
+ await vzaps.messages.sendText({
211
+ instanceId: 'VZ...',
212
+ instanceToken: 'instance-token',
213
+ phone: '5511999999999',
214
+ message: 'Hello',
215
+ });
216
+ ```
217
+
218
+ ---
219
+
220
+ ## Webhooks
221
+
222
+ Configure HTTP callbacks for instance events (same payload shape as realtime `data`, delivered to your URL):
223
+
224
+ ```ts
225
+ await vzaps.webhooks.set({
226
+ instanceId: 'VZ...',
227
+ webhookURL: 'https://example.com/webhooks/vzaps',
228
+ events: ['Message', 'Connected', 'Disconnected'],
229
+ });
230
+ ```
231
+
232
+ Common event types: `Message`, `ReadReceipt`, `Connected`, `Disconnected`, `Presence`, `ChatPresence`, `HistorySync`, `GroupParticipantsAdd`, `GroupParticipantsRemove`, or `All`.
233
+
234
+ Event payloads (webhook and realtime) use **snake_case**, matching the platform. Incoming media events include `media_url` inside `data` when platform storage is available.
235
+
236
+ ---
237
+
238
+ ## Realtime events
239
+
240
+ Subscribe to the same events over WebSocket at **`wss://realtime.vzaps.com`**. This is the recommended path for in-app notifications, bots, and dashboards that need low-latency delivery without exposing a public webhook URL.
241
+
242
+ ### Subscribe
243
+
244
+ ```ts
245
+ const subscription = await vzaps.events.subscribe({
246
+ instanceId: 'VZ...',
247
+ instanceToken: 'instance-token',
248
+ events: ['Message', 'Connected', 'Disconnected'],
249
+ reconnect: true,
250
+ lastEventId: 'evt_previous_id', // optional resume after disconnect
251
+ });
252
+
253
+ subscription.on('open', () => {
254
+ console.log('Connected to realtime');
255
+ });
256
+
257
+ subscription.on('Message', (event) => {
258
+ console.log(event.data);
259
+ });
260
+
261
+ subscription.on('error', (error) => {
262
+ console.error(error);
263
+ });
264
+
265
+ // Graceful shutdown
266
+ await subscription.close();
267
+ ```
268
+
269
+ ### Event envelope
270
+
271
+ Each WebSocket message keeps the platform shape (`snake_case`):
272
+
273
+ ```json
274
+ {
275
+ "id": "evt_…",
276
+ "type": "Message",
277
+ "instance_id": "VZ…",
278
+ "created_at": "2026-06-23T22:57:17.000Z",
279
+ "data": {
280
+ "type": "Message",
281
+ "event": { },
282
+ "media_url": "https://…"
283
+ }
284
+ }
285
+ ```
286
+
287
+ - **`data`** — same payload as webhook delivery (`snake_case`).
288
+ - **`media_url`** — present on incoming media messages when platform storage is available.
289
+
290
+ ### Delivery and ack
291
+
292
+ Delivery is **at-least-once**. After your handler runs, the SDK sends an ack automatically on the WebSocket connection. Use `lastEventId` when reconnecting if you need to reduce gaps. Deduplicate on `event.id` in your application if you process events idempotently.
293
+
294
+ ### Subscribe options
295
+
296
+ | Option | Type | Default | Description |
297
+ | --- | --- | --- | --- |
298
+ | `instanceId` | `string` | — | **Required.** Instance to watch. |
299
+ | `events` | `VZapsEventType[]` | all subscribed | Comma-filtered event types. |
300
+ | `instanceToken` | `string` | — | **Required.** Instance token for authorization. |
301
+ | `reconnect` | `boolean` | `true` | Reconnect after socket close. |
302
+ | `maxRetries` | `number` | unlimited | Max reconnect attempts. |
303
+ | `retryDelayMs` | `number` | exponential backoff | Delay between reconnects. |
304
+ | `lastEventId` | `string` | — | Resume cursor after disconnect. |
305
+ | `signal` | `AbortSignal` | — | Abort subscription (closes socket). |
306
+
307
+ ### Handler registration
308
+
309
+ | Event name | When it fires |
310
+ | --- | --- |
311
+ | `open` | WebSocket connected. |
312
+ | `close` | WebSocket closed. |
313
+ | `error` | Handler or transport error. |
314
+ | `Message`, `Connected`, … | Matching realtime event type. |
315
+ | `All` | Every event type. |
316
+
317
+ ---
318
+
319
+ ## Error handling
320
+
321
+ The SDK throws typed errors you can catch and branch on:
322
+
323
+ | Class | When |
324
+ | --- | --- |
325
+ | `VZapsError` | Base class; HTTP errors include `status`, `code`, and `details`. |
326
+ | `VZapsAuthenticationError` | Invalid `clientToken` / `clientSecret` (401). |
327
+ | `VZapsTimeoutError` | Request exceeded `timeoutMs`. |
328
+
329
+ ```ts
330
+ import {
331
+ VZapsClient,
332
+ VZapsAuthenticationError,
333
+ VZapsError,
334
+ VZapsTimeoutError,
335
+ } from '@vzaps/sdk';
336
+
337
+ try {
338
+ await vzaps.messages.sendText({ instanceId, instanceToken, phone, message });
339
+ } catch (error) {
340
+ if (error instanceof VZapsAuthenticationError) {
341
+ console.error('Check client credentials');
342
+ } else if (error instanceof VZapsTimeoutError) {
343
+ console.error('Request timed out');
344
+ } else if (error instanceof VZapsError) {
345
+ console.error(error.status, error.message, error.details);
346
+ }
347
+ throw error;
348
+ }
349
+ ```
350
+
351
+ ---
352
+
353
+ ## TypeScript
354
+
355
+ The package uses **camelCase** for HTTP request types and API responses. **Realtime and webhook event payloads stay in snake_case** so both delivery channels match.
356
+
357
+ Exported types include options, events, and requests:
358
+
359
+ ```ts
360
+ import type {
361
+ VZapsClientOptions,
362
+ VZapsEvent,
363
+ VZapsEventType,
364
+ MessageSendTextRequest,
365
+ WebhookConfigRequest,
366
+ EventSubscribeRequest,
367
+ } from '@vzaps/sdk';
368
+ ```
369
+
370
+ Resources accept a generic `TResponse` when you want strongly typed API responses:
371
+
372
+ ```ts
373
+ interface InstanceListResponse {
374
+ data: Array<{ instanceId: string; name: string }>;
375
+ }
376
+
377
+ const page = await vzaps.instances.list<InstanceListResponse>({
378
+ page: 1,
379
+ pageSize: 20,
380
+ });
381
+ ```
382
+
383
+ ---
384
+
385
+ ## Documentation
386
+
387
+ - [VZaps docs](https://docs.vzaps.com)
388
+ - [API reference (OpenAPI)](https://docs.vzaps.com/api-reference)
389
+ - [Postman collections](https://docs.vzaps.com/postman/)
390
+ - [Report an issue](https://github.com/vzaps/vzaps-sdk-typescript/issues)
391
+
392
+ ---
393
+
394
+ ## License
395
+
396
+ MIT © VZaps