@wazzapi/wazzapi 0.2.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/docs/README.md ADDED
@@ -0,0 +1,61 @@
1
+ # WazzAPI Node SDK Docs
2
+
3
+ Official documentation for the WazzAPI Node.js and TypeScript SDK.
4
+
5
+ ## What you can do
6
+
7
+ - Send direct WhatsApp messages, including text, image, video, voice, document, location, contact cards, buttons, and lists
8
+ - Manage WhatsApp groups, including participants, invite links, and group settings
9
+ - Manage contacts and contact groups
10
+ - Create, preview, update, and delete reusable templates
11
+ - Verify and parse incoming webhook payloads
12
+ - Download and decrypt encrypted WhatsApp media files
13
+ - Work with typed request and response models in TypeScript
14
+
15
+ ## Requirements
16
+
17
+ - Node.js 20+
18
+ - A WazzAPI account
19
+ - A WazzAPI API key
20
+
21
+ ## Install
22
+
23
+ With Bun:
24
+
25
+ ```bash
26
+ bun add @wazzapi/wazzapi
27
+ ```
28
+
29
+ With npm:
30
+
31
+ ```bash
32
+ npm install @wazzapi/wazzapi
33
+ ```
34
+
35
+ ## Quick start
36
+
37
+ ```ts
38
+ import { WazzapiClient } from "@wazzapi/wazzapi";
39
+
40
+ const client = new WazzapiClient({ apiKey: process.env.WAZZAPI_API_KEY });
41
+
42
+ const response = await client.messages.send({
43
+ phone_number: "+6281234567890",
44
+ whatsapp_account_id: "your-whatsapp-account-id",
45
+ content: "Hello from WazzAPI!",
46
+ });
47
+
48
+ console.log(response.message_id);
49
+ ```
50
+
51
+ ## Topics
52
+
53
+ - [Authentication](./authentication.md)
54
+ - [Client](./client.md)
55
+ - [Messages](./messages.md)
56
+ - [Groups](./groups.md)
57
+ - [Contacts](./contacts.md)
58
+ - [Templates](./templates.md)
59
+ - [Webhooks](./webhooks.md)
60
+ - [Media](./media.md)
61
+ - [Errors](./errors.md)
@@ -0,0 +1,37 @@
1
+ # Authentication
2
+
3
+ The SDK authenticates using an API key. You can find yours in the WazzAPI dashboard.
4
+
5
+ ## API key
6
+
7
+ Pass it directly to the client:
8
+
9
+ ```ts
10
+ import { WazzapiClient } from "@wazzapi/wazzapi";
11
+
12
+ const client = new WazzapiClient({ apiKey: "your-api-key" });
13
+ ```
14
+
15
+ Or load it from the environment:
16
+
17
+ ```ts
18
+ import { WazzapiClient } from "@wazzapi/wazzapi";
19
+
20
+ const client = new WazzapiClient({
21
+ apiKey: process.env.WAZZAPI_API_KEY,
22
+ });
23
+ ```
24
+
25
+ The SDK automatically prefixes the key with `Bearer` if it is not already present.
26
+
27
+ ## Webhook secret
28
+
29
+ If you plan to receive webhooks, you also need your webhook secret:
30
+
31
+ ```ts
32
+ import { WebhookHandler } from "@wazzapi/wazzapi";
33
+
34
+ const handler = new WebhookHandler(process.env.WAZZAPI_WEBHOOK_SECRET || "");
35
+ ```
36
+
37
+ You can find the webhook secret in the WazzAPI dashboard under webhook settings.
package/docs/client.md ADDED
@@ -0,0 +1,68 @@
1
+ # Client
2
+
3
+ `WazzapiClient` is the main entry point for all API calls.
4
+
5
+ ## Initialize
6
+
7
+ ```ts
8
+ import { WazzapiClient } from "@wazzapi/wazzapi";
9
+
10
+ const client = new WazzapiClient({ apiKey: "your-api-key" });
11
+ ```
12
+
13
+ ## Close the client
14
+
15
+ The SDK uses `fetch`, so there is no long-lived HTTP session to tear down, but `close()` is available for API symmetry:
16
+
17
+ ```ts
18
+ await client.close();
19
+ ```
20
+
21
+ ## Custom base URL
22
+
23
+ For testing or custom deployments:
24
+
25
+ ```ts
26
+ const client = new WazzapiClient({
27
+ baseUrl: "https://api.example.com",
28
+ apiKey: "your-api-key",
29
+ });
30
+ ```
31
+
32
+ ## Custom timeout
33
+
34
+ ```ts
35
+ const client = new WazzapiClient({
36
+ apiKey: "your-api-key",
37
+ timeout: 60_000,
38
+ });
39
+ ```
40
+
41
+ ## Bring your own fetch
42
+
43
+ ```ts
44
+ const client = new WazzapiClient({
45
+ apiKey: "your-api-key",
46
+ fetch: async (input, init) => fetch(input, init),
47
+ });
48
+ ```
49
+
50
+ ## Custom headers
51
+
52
+ ```ts
53
+ const client = new WazzapiClient({
54
+ apiKey: "your-api-key",
55
+ headers: {
56
+ "X-SDK-Example": "custom-header",
57
+ },
58
+ });
59
+ ```
60
+
61
+ ## Resources
62
+
63
+ The client exposes resources as properties:
64
+
65
+ - `client.contacts` — contact and contact-group management
66
+ - `client.groups` — WhatsApp group management
67
+ - `client.messages` — send and manage messages
68
+ - `client.templates` — template management
@@ -0,0 +1,194 @@
1
+ # Contacts
2
+
3
+ Manage contacts and contact groups.
4
+
5
+ ## List contacts
6
+
7
+ ```ts
8
+ import { WazzapiClient } from "@wazzapi/wazzapi";
9
+
10
+ const client = new WazzapiClient({ apiKey: process.env.WAZZAPI_API_KEY });
11
+ const response = await client.contacts.list({ limit: 50, search: "alice" });
12
+
13
+ for (const contact of response.contacts) {
14
+ console.log(contact.name, contact.phone_number);
15
+ }
16
+ ```
17
+
18
+ ## Get a contact
19
+
20
+ ```ts
21
+ const contact = await client.contacts.get("contact-id");
22
+ console.log(contact.phone_number, contact.tags);
23
+ ```
24
+
25
+ ## Create a contact
26
+
27
+ ```ts
28
+ const contact = await client.contacts.create({
29
+ phone_number: "+6281234567890",
30
+ name: "Alice",
31
+ tags: ["customer", "vip"],
32
+ });
33
+
34
+ console.log(contact.id);
35
+ ```
36
+
37
+ ## Update a contact
38
+
39
+ ```ts
40
+ const contact = await client.contacts.update("contact-id", {
41
+ name: "Alice Smith",
42
+ tags: ["customer"],
43
+ });
44
+
45
+ console.log(contact.name);
46
+ ```
47
+
48
+ ## Delete a contact
49
+
50
+ ```ts
51
+ await client.contacts.delete("contact-id");
52
+ ```
53
+
54
+ ## Bulk delete
55
+
56
+ ```ts
57
+ const result = await client.contacts.bulkDelete({
58
+ contact_ids: ["id-1", "id-2"],
59
+ });
60
+
61
+ console.log(result.deleted);
62
+ ```
63
+
64
+ ## Contact groups
65
+
66
+ ### List groups
67
+
68
+ ```ts
69
+ const response = await client.contacts.listGroups({ limit: 20 });
70
+
71
+ for (const group of response.groups) {
72
+ console.log(group.name, group.member_count);
73
+ }
74
+ ```
75
+
76
+ ### Create a group
77
+
78
+ ```ts
79
+ const group = await client.contacts.createGroup({
80
+ name: "VIP Customers",
81
+ description: "Top tier",
82
+ });
83
+
84
+ console.log(group.id);
85
+ ```
86
+
87
+ ### Get a group with members
88
+
89
+ ```ts
90
+ const response = await client.contacts.getGroup("group-id");
91
+ console.log(response.group.name);
92
+
93
+ for (const contact of response.contacts) {
94
+ console.log(contact.name);
95
+ }
96
+ ```
97
+
98
+ ### Update a group
99
+
100
+ ```ts
101
+ const group = await client.contacts.updateGroup("group-id", {
102
+ name: "Updated Name",
103
+ });
104
+
105
+ console.log(group.name);
106
+ ```
107
+
108
+ ### Delete a group
109
+
110
+ ```ts
111
+ await client.contacts.deleteGroup("group-id");
112
+ ```
113
+
114
+ ### Add contacts to a group
115
+
116
+ ```ts
117
+ const result = await client.contacts.addToGroup("group-id", {
118
+ contact_ids: ["contact-1", "contact-2"],
119
+ });
120
+
121
+ console.log(result.added);
122
+ ```
123
+
124
+ ### Remove contacts from a group
125
+
126
+ ```ts
127
+ const result = await client.contacts.removeFromGroup("group-id", {
128
+ contact_ids: ["contact-1"],
129
+ });
130
+
131
+ console.log(result.added);
132
+ ```
133
+
134
+ ## Import and export
135
+
136
+ ### Import from CSV
137
+
138
+ ```ts
139
+ const result = await client.contacts.importCsv({
140
+ csv_content: "phone_number,name\n+6281234567890,Alice",
141
+ skip_duplicates: true,
142
+ });
143
+
144
+ console.log(result.imported, result.updated, result.errors);
145
+ ```
146
+
147
+ ### Export to CSV
148
+
149
+ ```ts
150
+ const result = await client.contacts.exportCsv({ group_id: "group-id" });
151
+ console.log(result.csv_data);
152
+ ```
153
+
154
+ ### Get import template
155
+
156
+ ```ts
157
+ const template = await client.contacts.importTemplate();
158
+ console.log(template);
159
+ ```
160
+
161
+ ## Sync contacts from WhatsApp
162
+
163
+ ### Start sync
164
+
165
+ ```ts
166
+ const result = await client.contacts.sync({
167
+ whatsapp_account_id: "wa-123",
168
+ sync_type: "full",
169
+ });
170
+
171
+ console.log(result.job_id, result.status);
172
+ ```
173
+
174
+ ### Check sync status
175
+
176
+ ```ts
177
+ const statuses = await client.contacts.syncStatus();
178
+ for (const status of statuses) {
179
+ console.log(
180
+ status.account_name,
181
+ status.last_sync_status,
182
+ status.contacts_synced_count,
183
+ );
184
+ }
185
+ ```
186
+
187
+ ### Sync history
188
+
189
+ ```ts
190
+ const response = await client.contacts.syncHistory({ limit: 10 });
191
+ for (const item of response.history) {
192
+ console.log(item.account_name, item.status, item.contacts_count);
193
+ }
194
+ ```
package/docs/errors.md ADDED
@@ -0,0 +1,57 @@
1
+ # Errors
2
+
3
+ The SDK throws typed error classes for API, media, and webhook failures.
4
+
5
+ ## `WazzapiAPIError`
6
+
7
+ Raised when the API returns a non-2xx response:
8
+
9
+ ```ts
10
+ import { WazzapiAPIError, WazzapiClient } from "@wazzapi/wazzapi";
11
+
12
+ try {
13
+ const client = new WazzapiClient({ apiKey: process.env.WAZZAPI_API_KEY });
14
+ await client.messages.get("missing-message-id");
15
+ } catch (error) {
16
+ if (error instanceof WazzapiAPIError) {
17
+ console.log(error.statusCode);
18
+ console.log(error.message);
19
+ console.log(error.details);
20
+ }
21
+ }
22
+ ```
23
+
24
+ ## `WazzapiMediaError`
25
+
26
+ Raised when media download or decryption fails:
27
+
28
+ ```ts
29
+ import { WazzapiMediaError, downloadMedia } from "@wazzapi/wazzapi";
30
+
31
+ try {
32
+ await downloadMedia("https://example.com/missing.jpg", "media-key", "image/jpeg");
33
+ } catch (error) {
34
+ if (error instanceof WazzapiMediaError) {
35
+ console.log(error.message);
36
+ }
37
+ }
38
+ ```
39
+
40
+ ## Webhook errors
41
+
42
+ The webhook helpers raise these classes:
43
+
44
+ - `WazzapiWebhookError`
45
+ - `WazzapiWebhookVerificationError`
46
+ - `WazzapiWebhookParseError`
47
+
48
+ ## Error hierarchy
49
+
50
+ ```text
51
+ WazzapiError
52
+ ├── WazzapiAPIError
53
+ ├── WazzapiMediaError
54
+ └── WazzapiWebhookError
55
+ ├── WazzapiWebhookVerificationError
56
+ └── WazzapiWebhookParseError
57
+ ```
package/docs/groups.md ADDED
@@ -0,0 +1,233 @@
1
+ # Groups
2
+
3
+ Manage WhatsApp groups.
4
+
5
+ ## List groups
6
+
7
+ ```ts
8
+ import { WazzapiClient } from "@wazzapi/wazzapi";
9
+
10
+ const client = new WazzapiClient({ apiKey: process.env.WAZZAPI_API_KEY });
11
+ const response = await client.groups.list({ session_name: "main", limit: 50 });
12
+
13
+ for (const group of response.groups) {
14
+ console.log(group.id, group.name, group.participants_count);
15
+ }
16
+ ```
17
+
18
+ ## Get a group
19
+
20
+ ```ts
21
+ const group = await client.groups.get("123456789@g.us", {
22
+ session_name: "main",
23
+ });
24
+
25
+ console.log(group.name, group.description);
26
+ ```
27
+
28
+ ## Get group participants
29
+
30
+ ```ts
31
+ const response = await client.groups.getParticipants("123456789@g.us", {
32
+ session_name: "main",
33
+ });
34
+
35
+ for (const participant of response.participants) {
36
+ console.log(participant.id, participant.is_admin, participant.is_super_admin);
37
+ }
38
+ ```
39
+
40
+ ## Create a group
41
+
42
+ ```ts
43
+ const result = await client.groups.create({
44
+ session_name: "main",
45
+ name: "My New Group",
46
+ participants: ["+6281234567890", "+6281234567891"],
47
+ });
48
+
49
+ console.log(result.jid);
50
+ ```
51
+
52
+ ## Send text to a group
53
+
54
+ ```ts
55
+ const result = await client.groups.sendText({
56
+ session_name: "main",
57
+ group_jid: "123456789@g.us",
58
+ text: "Hello everyone!",
59
+ });
60
+
61
+ console.log(result.message_id);
62
+ ```
63
+
64
+ ## Send media to a group
65
+
66
+ ```ts
67
+ const result = await client.groups.sendMedia({
68
+ session_name: "main",
69
+ group_jid: "123456789@g.us",
70
+ media_url: "https://example.com/image.jpg",
71
+ media_type: "image",
72
+ caption: "Group photo",
73
+ });
74
+
75
+ console.log(result.message_id);
76
+ ```
77
+
78
+ ## Add a participant
79
+
80
+ ```ts
81
+ const result = await client.groups.addParticipant("123456789@g.us", {
82
+ session_name: "main",
83
+ participant_jid: "6281234567890@s.whatsapp.net",
84
+ });
85
+
86
+ console.log(result.details);
87
+ ```
88
+
89
+ ## Remove a participant
90
+
91
+ ```ts
92
+ const result = await client.groups.removeParticipant("123456789@g.us", {
93
+ session_name: "main",
94
+ participant_jid: "6281234567890@s.whatsapp.net",
95
+ });
96
+
97
+ console.log(result.details);
98
+ ```
99
+
100
+ ## Update participants
101
+
102
+ ```ts
103
+ const result = await client.groups.updateParticipants({
104
+ session_name: "main",
105
+ group_jid: "123456789@g.us",
106
+ action: "promote",
107
+ participants: ["6281234567890@s.whatsapp.net"],
108
+ });
109
+
110
+ console.log(result.details);
111
+ ```
112
+
113
+ ## Get invite link
114
+
115
+ ```ts
116
+ const result = await client.groups.getInviteLink("123456789@g.us", {
117
+ session_name: "main",
118
+ });
119
+
120
+ console.log(result.invite_link);
121
+ ```
122
+
123
+ ## Get invite info
124
+
125
+ ```ts
126
+ const result = await client.groups.getInviteInfo({
127
+ session_name: "main",
128
+ invite_link: "https://chat.whatsapp.com/AbCdEfGh",
129
+ });
130
+
131
+ console.log(result.jid, result.name);
132
+ ```
133
+
134
+ ## Join a group
135
+
136
+ ```ts
137
+ const result = await client.groups.join({
138
+ session_name: "main",
139
+ invite_link: "https://chat.whatsapp.com/AbCdEfGh",
140
+ });
141
+
142
+ console.log(result.details);
143
+ ```
144
+
145
+ ## Leave a group
146
+
147
+ ```ts
148
+ const result = await client.groups.leave("123456789@g.us", {
149
+ session_name: "main",
150
+ });
151
+
152
+ console.log(result.details);
153
+ ```
154
+
155
+ ## Set group name
156
+
157
+ ```ts
158
+ const result = await client.groups.setName("123456789@g.us", {
159
+ session_name: "main",
160
+ name: "New Group Name",
161
+ });
162
+
163
+ console.log(result.details);
164
+ ```
165
+
166
+ ## Set group topic
167
+
168
+ ```ts
169
+ const result = await client.groups.setTopic("123456789@g.us", {
170
+ session_name: "main",
171
+ topic: "New topic description",
172
+ });
173
+
174
+ console.log(result.details);
175
+ ```
176
+
177
+ ## Set group photo
178
+
179
+ ```ts
180
+ const result = await client.groups.setPhoto("123456789@g.us", {
181
+ session_name: "main",
182
+ image_data_uri: "data:image/png;base64,iVBORw0KGgo...",
183
+ });
184
+
185
+ console.log(result.details);
186
+ ```
187
+
188
+ ## Remove group photo
189
+
190
+ ```ts
191
+ const result = await client.groups.removePhoto("123456789@g.us", {
192
+ session_name: "main",
193
+ });
194
+
195
+ console.log(result.details);
196
+ ```
197
+
198
+ ## Set announce mode
199
+
200
+ Only admins can send messages when announce mode is enabled.
201
+
202
+ ```ts
203
+ const result = await client.groups.setAnnounce("123456789@g.us", {
204
+ session_name: "main",
205
+ announce: true,
206
+ });
207
+
208
+ console.log(result.details);
209
+ ```
210
+
211
+ ## Set locked mode
212
+
213
+ Only admins can edit group info when locked mode is enabled.
214
+
215
+ ```ts
216
+ const result = await client.groups.setLocked("123456789@g.us", {
217
+ session_name: "main",
218
+ locked: true,
219
+ });
220
+
221
+ console.log(result.details);
222
+ ```
223
+
224
+ ## Set ephemeral messages
225
+
226
+ ```ts
227
+ const result = await client.groups.setEphemeral("123456789@g.us", {
228
+ session_name: "main",
229
+ duration: "24h",
230
+ });
231
+
232
+ console.log(result.details);
233
+ ```
package/docs/media.md ADDED
@@ -0,0 +1,38 @@
1
+ # Media
2
+
3
+ Download and decrypt encrypted WhatsApp media files.
4
+
5
+ ## Download media
6
+
7
+ ```ts
8
+ import { downloadMedia } from "@wazzapi/wazzapi";
9
+
10
+ const result = await downloadMedia(
11
+ "https://example.com/media",
12
+ "your-media-key",
13
+ "image/jpeg",
14
+ {
15
+ file_name: "photo.jpg",
16
+ file_sha256: "expected-plain-sha256-base64",
17
+ file_enc_sha256: "expected-encrypted-sha256-base64",
18
+ },
19
+ );
20
+
21
+ console.log(result.file_name);
22
+ console.log(result.mimetype);
23
+ console.log(result.file_size);
24
+ ```
25
+
26
+ ## `MediaDownloadResult`
27
+
28
+ - `content` — decrypted file contents as `Buffer`
29
+ - `mimetype` — MIME type passed to the downloader
30
+ - `file_name` — file name from options or fallback name
31
+ - `file_size` — decrypted content size in bytes
32
+
33
+ ## Low-level helpers
34
+
35
+ If you need lower-level primitives, the SDK also exports:
36
+
37
+ - `_decryptWaMedia()` / `_decrypt_wa_media()`
38
+ - `_mediaInfoBytes()` / `_media_info_bytes()`