waba-toolkit 0.1.2 → 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/README.md +72 -18
- package/dist/index.d.mts +580 -0
- package/dist/index.d.ts +18 -4
- package/dist/index.js +78 -6
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +312 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +20 -6
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# waba-toolkit
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Type-safe, zero-dependency WhatsApp Business API toolkit for webhooks, media downloads, and signature verification.
|
|
4
4
|
|
|
5
5
|
> **Note:** This is not an official Meta/WhatsApp package, nor is it a full API wrapper. It is a utility toolkit derived from patterns across several production projects that interface directly with the WhatsApp Business API (Cloud API).
|
|
6
6
|
|
|
@@ -43,6 +43,8 @@ import {
|
|
|
43
43
|
WABAClient,
|
|
44
44
|
classifyWebhook,
|
|
45
45
|
classifyMessage,
|
|
46
|
+
getContactInfo,
|
|
47
|
+
getMessageId,
|
|
46
48
|
isMediaMessage,
|
|
47
49
|
extractMediaId,
|
|
48
50
|
} from 'waba-toolkit';
|
|
@@ -69,22 +71,36 @@ app.post('/webhook', async (req, res) => {
|
|
|
69
71
|
const webhook = classifyWebhook(req.body);
|
|
70
72
|
|
|
71
73
|
if (webhook.type === 'message') {
|
|
74
|
+
// 3. Extract contact info
|
|
75
|
+
const contact = getContactInfo(req.body);
|
|
76
|
+
if (contact) {
|
|
77
|
+
console.log('From:', contact.waId, contact.profileName);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// 4. Get message ID for marking as read
|
|
81
|
+
const messageId = getMessageId(req.body);
|
|
82
|
+
|
|
72
83
|
const message = webhook.payload.messages?.[0];
|
|
73
84
|
if (!message) return res.sendStatus(200);
|
|
74
85
|
|
|
75
|
-
//
|
|
86
|
+
// 5. Classify message type
|
|
76
87
|
const classified = classifyMessage(message);
|
|
77
88
|
|
|
78
89
|
if (classified.type === 'text') {
|
|
79
90
|
console.log('Text:', classified.message.text.body);
|
|
80
91
|
}
|
|
81
92
|
|
|
82
|
-
//
|
|
93
|
+
// 6. Handle media messages
|
|
83
94
|
if (isMediaMessage(message)) {
|
|
84
95
|
const mediaId = extractMediaId(message);
|
|
85
96
|
const { stream, mimeType } = await client.getMedia(mediaId);
|
|
86
97
|
// Process stream...
|
|
87
98
|
}
|
|
99
|
+
|
|
100
|
+
// 7. Mark as read
|
|
101
|
+
if (messageId) {
|
|
102
|
+
await markAsRead(messageId);
|
|
103
|
+
}
|
|
88
104
|
}
|
|
89
105
|
|
|
90
106
|
res.sendStatus(200);
|
|
@@ -226,35 +242,73 @@ switch (result.type) {
|
|
|
226
242
|
|
|
227
243
|
### Helper Functions
|
|
228
244
|
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
|
234
|
-
|
|
245
|
+
#### Webhook-level Helpers
|
|
246
|
+
|
|
247
|
+
These helpers accept `WebhookPayload` and extract data from the top-level webhook structure:
|
|
248
|
+
|
|
249
|
+
| Function | Description | Returns |
|
|
250
|
+
|----------|-------------|---------|
|
|
251
|
+
| `getContactInfo(webhook)` | Extracts sender's `waId`, `profileName`, and `phoneNumberId` | `ContactInfo \| null` |
|
|
252
|
+
| `getMessageId(webhook)` | Extracts message ID from message or status webhooks | `string \| null` |
|
|
253
|
+
| `getCallId(webhook)` | Extracts call ID from call webhooks | `string \| null` |
|
|
254
|
+
|
|
255
|
+
```typescript
|
|
256
|
+
import { getContactInfo, getMessageId, getCallId } from 'waba-toolkit';
|
|
257
|
+
|
|
258
|
+
// Get sender info from message/call webhooks
|
|
259
|
+
const contact = getContactInfo(webhookPayload);
|
|
260
|
+
if (contact) {
|
|
261
|
+
console.log(contact.waId); // e.g., '14155551234'
|
|
262
|
+
console.log(contact.profileName); // e.g., 'John Doe' (may be undefined)
|
|
263
|
+
console.log(contact.phoneNumberId); // Your business phone number ID
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
// Get message ID from message webhooks
|
|
267
|
+
const messageId = getMessageId(webhookPayload);
|
|
268
|
+
if (messageId) {
|
|
269
|
+
await markAsRead(messageId);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
// Get message ID from status webhooks
|
|
273
|
+
const statusMessageId = getMessageId(statusWebhook);
|
|
274
|
+
if (statusMessageId) {
|
|
275
|
+
console.log('Status update for message:', statusMessageId);
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
// Get call ID from call webhooks
|
|
279
|
+
const callId = getCallId(webhookPayload);
|
|
280
|
+
if (callId) {
|
|
281
|
+
await logCall(callId);
|
|
282
|
+
}
|
|
283
|
+
```
|
|
284
|
+
|
|
285
|
+
#### Message-level Helpers
|
|
286
|
+
|
|
287
|
+
These helpers operate on individual message objects:
|
|
288
|
+
|
|
289
|
+
| Function | Description | Returns |
|
|
290
|
+
|----------|-------------|---------|
|
|
291
|
+
| `isMediaMessage(message)` | Type guard: returns `true` if message has downloadable media | `boolean` |
|
|
292
|
+
| `extractMediaId(message)` | Extracts media ID from image/audio/video/document/sticker messages | `string \| undefined` |
|
|
293
|
+
| `getMessageTimestamp(message)` | Parses timestamp string to `Date` object | `Date` |
|
|
235
294
|
|
|
236
295
|
```typescript
|
|
237
296
|
import {
|
|
238
297
|
isMediaMessage,
|
|
239
298
|
extractMediaId,
|
|
240
|
-
getContactInfo,
|
|
241
299
|
getMessageTimestamp,
|
|
242
300
|
} from 'waba-toolkit';
|
|
243
301
|
|
|
302
|
+
// Extract message from webhook first
|
|
303
|
+
const message = webhookPayload.entry[0].changes[0].value.messages?.[0];
|
|
304
|
+
if (!message) return;
|
|
305
|
+
|
|
244
306
|
// Check if message has media
|
|
245
307
|
if (isMediaMessage(message)) {
|
|
246
308
|
const mediaId = extractMediaId(message); // guaranteed non-undefined
|
|
247
309
|
const media = await client.getMedia(mediaId);
|
|
248
310
|
}
|
|
249
311
|
|
|
250
|
-
// Get sender info
|
|
251
|
-
const contact = getContactInfo(webhookPayload);
|
|
252
|
-
if (contact) {
|
|
253
|
-
console.log(contact.waId); // e.g., '14155551234'
|
|
254
|
-
console.log(contact.profileName); // e.g., 'John Doe' (may be undefined)
|
|
255
|
-
console.log(contact.phoneNumberId); // Your business phone number ID
|
|
256
|
-
}
|
|
257
|
-
|
|
258
312
|
// Parse timestamp
|
|
259
313
|
const sentAt = getMessageTimestamp(message);
|
|
260
314
|
console.log(sentAt.toISOString());
|