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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # waba-toolkit
2
2
 
3
- A minimal, type-safe toolkit for WhatsApp Business API webhook processing and media handling.
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
- // 3. Classify message type
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
- // 4. Handle media messages
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
- | Function | Description |
230
- |----------|-------------|
231
- | `isMediaMessage(message)` | Type guard: returns `true` if message has downloadable media |
232
- | `extractMediaId(message)` | Extracts media ID from image/audio/video/document/sticker messages |
233
- | `getContactInfo(webhook)` | Extracts sender's `waId`, `profileName`, and `phoneNumberId` |
234
- | `getMessageTimestamp(message)` | Parses timestamp string to `Date` object |
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());