plogme 2.0.7 → 2.0.9
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 +583 -36
- package/WAProto/WAProto.proto +934 -3
- package/WAProto/index.d.ts +33887 -21445
- package/WAProto/index.js +114447 -78804
- package/lib/Defaults/index.js +1 -1
- package/lib/Socket/messages-send.js +135 -113
- package/lib/Types/Message.js +2 -1
- package/lib/Utils/bot-planning-replay.js +6 -9
- package/lib/Utils/chat-utils.js +8 -0
- package/lib/Utils/history.js +21 -1
- package/lib/Utils/messages.js +84 -11
- package/lib/Utils/meta-ai-msmsg.js +75 -2
- package/lib/Utils/meta-compositing.js +38 -9
- package/lib/Utils/rich-message-utils.js +123 -13
- package/lib/Utils/validate-connection.js +4 -2
- package/lib/index.d.ts +45 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
[](https://www.npmjs.com/package/plogme)
|
|
9
9
|
[](https://nodejs.org/)
|
|
10
|
-
[](https://github.com/crysnovax/baileys)
|
|
11
11
|
|
|
12
12
|
## Contents
|
|
13
13
|
|
|
@@ -28,8 +28,9 @@
|
|
|
28
28
|
15. [View-once utilities](#view-once-utilities)
|
|
29
29
|
16. [Connection handling](#connection-handling)
|
|
30
30
|
17. [Security and removed automatic behavior](#security-and-removed-automatic-behavior)
|
|
31
|
-
18. [
|
|
32
|
-
19. [
|
|
31
|
+
18. [Complete public API examples](#complete-public-api-examples)
|
|
32
|
+
19. [Development](#development)
|
|
33
|
+
20. [License and support](#license-and-support)
|
|
33
34
|
|
|
34
35
|
## Installation
|
|
35
36
|
|
|
@@ -39,10 +40,10 @@ npm install plogme
|
|
|
39
40
|
|
|
40
41
|
The package currently requires **Node.js 20 or newer**.
|
|
41
42
|
|
|
42
|
-
|
|
43
|
+
The published package is available from npm:
|
|
43
44
|
|
|
44
45
|
```bash
|
|
45
|
-
npm install
|
|
46
|
+
npm install plogme
|
|
46
47
|
```
|
|
47
48
|
|
|
48
49
|
Plogme is an ES module package. Use `import` syntax in Node.js projects configured with `"type": "module"`.
|
|
@@ -196,6 +197,19 @@ await sock.sendMessage(jid, {
|
|
|
196
197
|
}
|
|
197
198
|
}
|
|
198
199
|
})
|
|
200
|
+
|
|
201
|
+
// Solid-color themes use ARGB values internally. Hex strings and numbers are accepted.
|
|
202
|
+
await sock.sendMessage(jid, {
|
|
203
|
+
chatTheme: {
|
|
204
|
+
solidColor: {
|
|
205
|
+
colorLight: '#FFFFFFFF',
|
|
206
|
+
colorDark: '#FF101010',
|
|
207
|
+
doodleColorLight: '#FFCCE8FF',
|
|
208
|
+
doodleColorDark: 0xFF202020,
|
|
209
|
+
isDoodleEnabled: true
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
})
|
|
199
213
|
```
|
|
200
214
|
|
|
201
215
|
### Editing and deleting
|
|
@@ -251,6 +265,57 @@ await sock.sendMessage(jid, {
|
|
|
251
265
|
}
|
|
252
266
|
})
|
|
253
267
|
|
|
268
|
+
// EventInviteMessage supports call links, cover handles, locations, timestamps, and status.
|
|
269
|
+
await sock.sendMessage(jid, {
|
|
270
|
+
eventInvite: {
|
|
271
|
+
eventId: 'release-2026',
|
|
272
|
+
title: 'Plogme release room',
|
|
273
|
+
text: 'Join the release discussion',
|
|
274
|
+
startTime: Math.floor(Date.now() / 1000) + 3600,
|
|
275
|
+
endTime: Math.floor(Date.now() / 1000) + 7200,
|
|
276
|
+
callLink: 'https://call.whatsapp.com/video/example',
|
|
277
|
+
coverImageHandle: 'cover-handle-from-whatsapp',
|
|
278
|
+
locationName: 'Lagos',
|
|
279
|
+
lastUpdatedTsUsec: Date.now() * 1000,
|
|
280
|
+
status: 'ACTIVE'
|
|
281
|
+
}
|
|
282
|
+
})
|
|
283
|
+
|
|
284
|
+
// Plogme already supports sending a live location through the existing
|
|
285
|
+
// `location` builder by setting `isLive: true`.
|
|
286
|
+
const liveLocationMessage = await sock.sendMessage(jid, {
|
|
287
|
+
location: {
|
|
288
|
+
degreesLatitude: 6.5244,
|
|
289
|
+
degreesLongitude: 3.3792,
|
|
290
|
+
name: 'Lagos',
|
|
291
|
+
isLive: true,
|
|
292
|
+
accuracyInMeters: 10,
|
|
293
|
+
speedInMps: 0
|
|
294
|
+
}
|
|
295
|
+
})
|
|
296
|
+
|
|
297
|
+
// These newer fields are different: they ask the recipient to share a
|
|
298
|
+
// location, or update/cancel a request for an existing live location.
|
|
299
|
+
await sock.sendMessage(jid, { requestLocation: true })
|
|
300
|
+
await sock.sendMessage(jid, {
|
|
301
|
+
requestLocationUpdate: {
|
|
302
|
+
key: liveLocationMessage.key,
|
|
303
|
+
cancel: false,
|
|
304
|
+
senderTimestampMs: Date.now()
|
|
305
|
+
}
|
|
306
|
+
})
|
|
307
|
+
await sock.sendMessage(jid, {
|
|
308
|
+
requestLocationUpdate: { key: liveLocationMessage.key, cancel: true }
|
|
309
|
+
})
|
|
310
|
+
|
|
311
|
+
// The latest proto also exposes these lower-level fields for forward-compatible relays.
|
|
312
|
+
await sock.relayMessage(jid, {
|
|
313
|
+
instantImageMessage: { caption: 'Instant image' }
|
|
314
|
+
}, {})
|
|
315
|
+
await sock.relayMessage(groupJid, {
|
|
316
|
+
botGroupParticipantMessage: {}
|
|
317
|
+
}, {})
|
|
318
|
+
|
|
254
319
|
await sock.sendMessage(jid, {
|
|
255
320
|
poll: {
|
|
256
321
|
name: 'Release preference',
|
|
@@ -263,6 +328,53 @@ await sock.sendMessage(jid, {
|
|
|
263
328
|
})
|
|
264
329
|
```
|
|
265
330
|
|
|
331
|
+
### Latest WAProto additions
|
|
332
|
+
|
|
333
|
+
The WAProto generation is updated to WhatsApp Web revision
|
|
334
|
+
`2.3000.1049983640`. The following new fields are available through the
|
|
335
|
+
generated `proto` namespace and are preserved during encode/decode:
|
|
336
|
+
|
|
337
|
+
| Surface | What it represents |
|
|
338
|
+
| --- | --- |
|
|
339
|
+
| `requestLocationMessage` | Ask a chat to share its current location. |
|
|
340
|
+
| `requestLocationUpdateMessage` | Request a live-location update or cancel an existing request. |
|
|
341
|
+
| `instantImageMessage` | Image content using the newer instant-image message slot. |
|
|
342
|
+
| `botGroupParticipantMessage` | Bot participant content for group-addressed protocol messages. |
|
|
343
|
+
| `favoriteStickers` | Favorite sticker metadata in history sync. |
|
|
344
|
+
| `omittedConversations` | Conversations deliberately omitted from a history-sync batch. |
|
|
345
|
+
| `CommunityNestingStateAction` | Community nesting state changes from app-state sync. |
|
|
346
|
+
| ARGB wallpaper fields | Light, dark, and doodle wallpaper colors as fixed ARGB values. |
|
|
347
|
+
| Event-invite fields | Call link, cover handle, location, update timestamp, and status. |
|
|
348
|
+
|
|
349
|
+
Favorite stickers and omitted conversations arrive through the normal history
|
|
350
|
+
event. `omittedConversationsProvided` tells consumers that the omission list
|
|
351
|
+
was explicitly supplied by WhatsApp, so an incomplete batch is not mistaken
|
|
352
|
+
for a complete history:
|
|
353
|
+
|
|
354
|
+
```javascript
|
|
355
|
+
sock.ev.on('messaging-history.set', ({ favoriteStickers, omittedConversations, omittedConversationsProvided }) => {
|
|
356
|
+
if (favoriteStickers?.length) {
|
|
357
|
+
console.log('favorite stickers:', favoriteStickers.length)
|
|
358
|
+
}
|
|
359
|
+
if (omittedConversationsProvided) {
|
|
360
|
+
console.log('history intentionally omitted:', omittedConversations)
|
|
361
|
+
}
|
|
362
|
+
})
|
|
363
|
+
```
|
|
364
|
+
|
|
365
|
+
Community nesting changes arrive through `groups.update`. The update contains
|
|
366
|
+
the raw proto enum and a convenient boolean:
|
|
367
|
+
|
|
368
|
+
```javascript
|
|
369
|
+
sock.ev.on('groups.update', updates => {
|
|
370
|
+
for (const update of updates) {
|
|
371
|
+
if (update.nestingState !== undefined) {
|
|
372
|
+
console.log('community nested:', update.nested, update.nestingState)
|
|
373
|
+
}
|
|
374
|
+
}
|
|
375
|
+
})
|
|
376
|
+
```
|
|
377
|
+
|
|
266
378
|
### Forward and edit
|
|
267
379
|
|
|
268
380
|
```js
|
|
@@ -338,10 +450,10 @@ await sock.sendAlbumMessage(jid, [
|
|
|
338
450
|
image: {
|
|
339
451
|
sourceUrl: 'https://example.com/two-preview.jpg',
|
|
340
452
|
imageHighResUrl: 'https://example.com/two.jpg',
|
|
341
|
-
darkModePreviewUrl: 'https://example.com/two-dark-preview.jpg',
|
|
342
|
-
darkModeHighResUrl: 'https://example.com/two-dark.jpg',
|
|
343
453
|
width: 1200,
|
|
344
|
-
height: 800
|
|
454
|
+
height: 800,
|
|
455
|
+
fullWidth: 2400,
|
|
456
|
+
fullHeight: 1600
|
|
345
457
|
}
|
|
346
458
|
},
|
|
347
459
|
{
|
|
@@ -367,7 +479,7 @@ await sock.sendMessage(jid, {
|
|
|
367
479
|
})
|
|
368
480
|
```
|
|
369
481
|
|
|
370
|
-
`sendAlbumMessage()` accepts fetchable image and video URLs. Local `Buffer`/file inputs are not uploaded by this rich album API. The lower-level `prepareGridImageMessage()` helper remains available when a compact `GRID_IMAGE` layout is specifically required; `sendAlbumMessage()` itself uses a full-width `GenAIVStackLayoutViewModel` presentation for both images and videos.
|
|
482
|
+
`sendAlbumMessage()` accepts fetchable image and video URLs. Local `Buffer`/file inputs are not uploaded by this rich album API. The lower-level `prepareGridImageMessage()` helper remains available when a compact `GRID_IMAGE` layout is specifically required; `sendAlbumMessage()` itself uses a full-width `GenAIVStackLayoutViewModel` presentation for both images and videos. Vertical image album items intentionally send only `full_image`—without preview or dark-mode slots—so WhatsApp does not render a broken preview placeholder before opening the original. When available, `imageHighResUrl`, `highResUrl`, or `fullUrl` is used as the full asset; provide `fullWidth` and `fullHeight` to preserve the source dimensions. Preview and dark-mode URL fields are not used by this vertical album path.
|
|
371
483
|
|
|
372
484
|
### Video grids
|
|
373
485
|
|
|
@@ -534,6 +646,68 @@ await sock.sendMessage(jid, {
|
|
|
534
646
|
})
|
|
535
647
|
```
|
|
536
648
|
|
|
649
|
+
### Native carousel details
|
|
650
|
+
|
|
651
|
+
The native carousel composer accepts both `sendMessage` and the convenient
|
|
652
|
+
`sendCarousel` socket method. A top-level `text` is optional: cards-only
|
|
653
|
+
messages are valid. The default card type is horizontal scrolling
|
|
654
|
+
(`HSCROLL_CARDS`); use `carouselCardType: 2` or `'album'` only when the
|
|
655
|
+
receiving client supports the album-image card layout.
|
|
656
|
+
|
|
657
|
+
```js
|
|
658
|
+
await sock.sendCarousel(jid, [
|
|
659
|
+
{
|
|
660
|
+
title: 'Documentation',
|
|
661
|
+
subtitle: 'Read the guide',
|
|
662
|
+
body: { text: 'Open the latest API documentation.' },
|
|
663
|
+
image: { url: 'https://cdn.example.com/docs.jpg' },
|
|
664
|
+
buttons: [
|
|
665
|
+
{ text: 'Open docs', url: 'https://example.com/docs', useWebview: true }
|
|
666
|
+
],
|
|
667
|
+
footer: 'Plogme'
|
|
668
|
+
},
|
|
669
|
+
{
|
|
670
|
+
title: 'Release video',
|
|
671
|
+
body: 'See what changed in this release.',
|
|
672
|
+
video: { url: 'https://cdn.example.com/release.mp4' },
|
|
673
|
+
nativeFlow: [{ text: 'Watch', id: 'watch-release' }]
|
|
674
|
+
}
|
|
675
|
+
], {
|
|
676
|
+
carouselCardType: 'horizontal',
|
|
677
|
+
text: 'Choose an item',
|
|
678
|
+
footer: 'Swipe to continue'
|
|
679
|
+
})
|
|
680
|
+
```
|
|
681
|
+
|
|
682
|
+
The equivalent lower-level form is:
|
|
683
|
+
|
|
684
|
+
```js
|
|
685
|
+
await sock.sendMessage(jid, {
|
|
686
|
+
cards: [
|
|
687
|
+
{
|
|
688
|
+
title: 'First card',
|
|
689
|
+
body: { text: 'Cards may be sent without a top-level message.' },
|
|
690
|
+
image: { url: 'https://cdn.example.com/first.jpg' },
|
|
691
|
+
nativeFlow: [{ text: 'Select', id: 'first-card' }]
|
|
692
|
+
},
|
|
693
|
+
{
|
|
694
|
+
title: 'Second card',
|
|
695
|
+
caption: 'Use `caption` as a shorthand for body text.',
|
|
696
|
+
image: { url: 'https://cdn.example.com/second.jpg' }
|
|
697
|
+
}
|
|
698
|
+
],
|
|
699
|
+
carouselCardType: 1
|
|
700
|
+
})
|
|
701
|
+
```
|
|
702
|
+
|
|
703
|
+
Carousel media must use the normal fetchable media inputs supported by
|
|
704
|
+
`prepareWAMessageMedia` (for example public URLs or uploaded media objects).
|
|
705
|
+
Each card can contain an image or video header, `title`, `subtitle`, `body`,
|
|
706
|
+
`caption`, `footer`, `thumbnail`, and native-flow buttons. A card that contains
|
|
707
|
+
both body text and media retains its media header; it is not converted into a
|
|
708
|
+
blank text-only card. Button IDs are event values and must be validated by the
|
|
709
|
+
receiving application.
|
|
710
|
+
|
|
537
711
|
### Hydrated templates
|
|
538
712
|
|
|
539
713
|
```js
|
|
@@ -1468,6 +1642,322 @@ Plogme does not automatically follow WhatsApp channels, fingerprint the host mac
|
|
|
1468
1642
|
|
|
1469
1643
|
The project license still applies. Removing runtime enforcement does not change the license terms.
|
|
1470
1644
|
|
|
1645
|
+
## Complete public API examples
|
|
1646
|
+
|
|
1647
|
+
The examples below provide a call shape for every public method in `lib/index.d.ts`. Replace the placeholder values with data from your application and review the method's TypeScript signature before using account, privacy, interop, or security operations. Methods that change account state, permissions, group membership, or credentials should only be called after your application has obtained the appropriate user authorization.
|
|
1648
|
+
|
|
1649
|
+
### Rich, status, and diagnostics
|
|
1650
|
+
|
|
1651
|
+
```js
|
|
1652
|
+
const jid = '1234567890@s.whatsapp.net'
|
|
1653
|
+
const groupJid = '120363000000000000@g.us'
|
|
1654
|
+
const userJid = '15551234567@s.whatsapp.net'
|
|
1655
|
+
|
|
1656
|
+
// relayMessage: send the raw forwarded GenAI label envelope.
|
|
1657
|
+
const labelPayload = {
|
|
1658
|
+
__typename: 'GenAIUnifiedResponse',
|
|
1659
|
+
response_id: 'test123',
|
|
1660
|
+
sections: [{
|
|
1661
|
+
__typename: 'GenAIUnifiedResponseSection',
|
|
1662
|
+
view_model: {
|
|
1663
|
+
__typename: 'GenAISingleLayoutViewModel',
|
|
1664
|
+
primitive: {
|
|
1665
|
+
__typename: 'GenAILabelPrimitive',
|
|
1666
|
+
text: 'Hello goys',
|
|
1667
|
+
variant: 'POSITIVE',
|
|
1668
|
+
background_color_override: '#FF0000FF',
|
|
1669
|
+
text_color_override: '#000000FF'
|
|
1670
|
+
}
|
|
1671
|
+
}
|
|
1672
|
+
}]
|
|
1673
|
+
}
|
|
1674
|
+
await sock.relayMessage(jid, {
|
|
1675
|
+
botForwardedMessage: {
|
|
1676
|
+
message: {
|
|
1677
|
+
richResponseMessage: {
|
|
1678
|
+
messageType: 1,
|
|
1679
|
+
unifiedResponse: {
|
|
1680
|
+
data: Buffer.from(JSON.stringify(labelPayload)).toString('base64')
|
|
1681
|
+
},
|
|
1682
|
+
contextInfo: { isForwarded: true, forwardOrigin: 4 }
|
|
1683
|
+
}
|
|
1684
|
+
}
|
|
1685
|
+
}
|
|
1686
|
+
}, {})
|
|
1687
|
+
// sendStatusMentions
|
|
1688
|
+
await sock.sendStatusMentions({ text: 'Hello from my status' }, [userJid])
|
|
1689
|
+
// sendBotPlanning
|
|
1690
|
+
await sock.sendBotPlanning(jid, { text: 'Working through the plan', steps: ['Fetch data', 'Send result'] })
|
|
1691
|
+
// sendRichLabelMessage
|
|
1692
|
+
await sock.sendRichLabelMessage(jid, {
|
|
1693
|
+
text: 'Hello goys',
|
|
1694
|
+
responseId: 'test123',
|
|
1695
|
+
variant: 'POSITIVE',
|
|
1696
|
+
backgroundColor: '#FF0000FF',
|
|
1697
|
+
textColor: '#000000FF'
|
|
1698
|
+
})
|
|
1699
|
+
// sendRichGeneration
|
|
1700
|
+
await sock.sendRichGeneration(jid, {}, undefined, undefined)
|
|
1701
|
+
// getStatusPrivacy
|
|
1702
|
+
await sock.getStatusPrivacy()
|
|
1703
|
+
// setStatusPrivacy
|
|
1704
|
+
await sock.setStatusPrivacy('contacts', [userJid])
|
|
1705
|
+
// fetchBroadcastListQuota
|
|
1706
|
+
await sock.fetchBroadcastListQuota()
|
|
1707
|
+
// getChatBlockingStatus
|
|
1708
|
+
await sock.getChatBlockingStatus()
|
|
1709
|
+
// updateChatBlockingStatus
|
|
1710
|
+
await sock.updateChatBlockingStatus('block')
|
|
1711
|
+
// getUserDisclosures
|
|
1712
|
+
await sock.getUserDisclosures(0)
|
|
1713
|
+
// acceptTosNotice
|
|
1714
|
+
await sock.acceptTosNotice(0, {})
|
|
1715
|
+
// getOptOutList
|
|
1716
|
+
await sock.getOptOutList()
|
|
1717
|
+
// sendKeyIndexList
|
|
1718
|
+
await sock.sendKeyIndexList()
|
|
1719
|
+
```
|
|
1720
|
+
|
|
1721
|
+
### Account, privacy, and security
|
|
1722
|
+
|
|
1723
|
+
```js
|
|
1724
|
+
const jid = '1234567890@s.whatsapp.net'
|
|
1725
|
+
const groupJid = '120363000000000000@g.us'
|
|
1726
|
+
const userJid = '15551234567@s.whatsapp.net'
|
|
1727
|
+
|
|
1728
|
+
// signPrivateCredential
|
|
1729
|
+
await sock.signPrivateCredential(Buffer.from('payload'))
|
|
1730
|
+
// getPushConfig
|
|
1731
|
+
await sock.getPushConfig()
|
|
1732
|
+
// setPushConfig
|
|
1733
|
+
await sock.setPushConfig({})
|
|
1734
|
+
// toggleCallLinkWaitingRoom
|
|
1735
|
+
await sock.toggleCallLinkWaitingRoom('example', true, 0)
|
|
1736
|
+
// storePrivacyTokens
|
|
1737
|
+
await sock.storePrivacyTokens([userJid])
|
|
1738
|
+
// updateBioPrivacy
|
|
1739
|
+
await sock.updateBioPrivacy('example')
|
|
1740
|
+
// blockBot
|
|
1741
|
+
await sock.blockBot(jid)
|
|
1742
|
+
// unblockBot
|
|
1743
|
+
await sock.unblockBot(jid)
|
|
1744
|
+
// getBotProfile
|
|
1745
|
+
await sock.getBotProfile(jid)
|
|
1746
|
+
// fetchABProps
|
|
1747
|
+
await sock.fetchABProps('example', 'example', 'example', 'example')
|
|
1748
|
+
// removeCompanionDevice
|
|
1749
|
+
await sock.removeCompanionDevice(jid, 0)
|
|
1750
|
+
// updateKeyIndexList
|
|
1751
|
+
await sock.updateKeyIndexList(0, Buffer.from('payload'))
|
|
1752
|
+
// fetchMediaConn
|
|
1753
|
+
await sock.fetchMediaConn('example')
|
|
1754
|
+
// deleteBroadcastList
|
|
1755
|
+
await sock.deleteBroadcastList(0)
|
|
1756
|
+
// fetchQRCode
|
|
1757
|
+
await sock.fetchQRCode('example', 'example')
|
|
1758
|
+
// confirmDeviceLogout
|
|
1759
|
+
await sock.confirmDeviceLogout(0, true)
|
|
1760
|
+
// checkUsername
|
|
1761
|
+
await sock.checkUsername('example')
|
|
1762
|
+
// checkUsernameMulti
|
|
1763
|
+
await sock.checkUsernameMulti([userJid])
|
|
1764
|
+
// setUsername
|
|
1765
|
+
await sock.setUsername('example', undefined)
|
|
1766
|
+
// deleteUsername
|
|
1767
|
+
await sock.deleteUsername()
|
|
1768
|
+
// getMyUsername
|
|
1769
|
+
await sock.getMyUsername()
|
|
1770
|
+
// getUsernameRecommendations
|
|
1771
|
+
await sock.getUsernameRecommendations()
|
|
1772
|
+
// setUsernamePin
|
|
1773
|
+
await sock.setUsernamePin('example')
|
|
1774
|
+
// findUserByUsername
|
|
1775
|
+
await sock.findUserByUsername('example')
|
|
1776
|
+
// fetchContactUsernames
|
|
1777
|
+
await sock.fetchContactUsernames(jid)
|
|
1778
|
+
// getPrivacySettings
|
|
1779
|
+
await sock.getPrivacySettings()
|
|
1780
|
+
// setPrivacySetting
|
|
1781
|
+
await sock.setPrivacySetting(undefined, 'example')
|
|
1782
|
+
// updatePrivacyContactList
|
|
1783
|
+
await sock.updatePrivacyContactList(undefined, 'example', jid)
|
|
1784
|
+
// getPrivacyContactList
|
|
1785
|
+
await sock.getPrivacyContactList(undefined)
|
|
1786
|
+
// updateTextStatus
|
|
1787
|
+
await sock.updateTextStatus(undefined)
|
|
1788
|
+
// getTextStatusList
|
|
1789
|
+
await sock.getTextStatusList()
|
|
1790
|
+
// updateUserStatus
|
|
1791
|
+
await sock.updateUserStatus(undefined)
|
|
1792
|
+
// fetchUserPictureInfo
|
|
1793
|
+
await sock.fetchUserPictureInfo(jid)
|
|
1794
|
+
// setProfilePictureMex
|
|
1795
|
+
await sock.setProfilePictureMex(jid, Buffer.from('payload'))
|
|
1796
|
+
// hasPassword
|
|
1797
|
+
await sock.hasPassword()
|
|
1798
|
+
// setPassword
|
|
1799
|
+
await sock.setPassword('example')
|
|
1800
|
+
// checkPassword
|
|
1801
|
+
await sock.checkPassword('example')
|
|
1802
|
+
// deletePassword
|
|
1803
|
+
await sock.deletePassword()
|
|
1804
|
+
// passkeyExists
|
|
1805
|
+
await sock.passkeyExists()
|
|
1806
|
+
// getRegistrationUpsells
|
|
1807
|
+
await sock.getRegistrationUpsells()
|
|
1808
|
+
// contactsUpload
|
|
1809
|
+
await sock.contactsUpload([userJid])
|
|
1810
|
+
// submitAge
|
|
1811
|
+
await sock.submitAge(0)
|
|
1812
|
+
// managedAccountInitiateLinking
|
|
1813
|
+
await sock.managedAccountInitiateLinking()
|
|
1814
|
+
// managedAccountValidateLinking
|
|
1815
|
+
await sock.managedAccountValidateLinking('example')
|
|
1816
|
+
// managedAccountAcceptLinking
|
|
1817
|
+
await sock.managedAccountAcceptLinking('example')
|
|
1818
|
+
// managedAccountCompleteLinking
|
|
1819
|
+
await sock.managedAccountCompleteLinking('example')
|
|
1820
|
+
// managedAccountRevokeLinking
|
|
1821
|
+
await sock.managedAccountRevokeLinking()
|
|
1822
|
+
// managedAccountSyncActivities
|
|
1823
|
+
await sock.managedAccountSyncActivities()
|
|
1824
|
+
// managedAccountUpdatePin
|
|
1825
|
+
await sock.managedAccountUpdatePin('example')
|
|
1826
|
+
// setAccessToken
|
|
1827
|
+
await sock.setAccessToken('example')
|
|
1828
|
+
// setWamoAuth
|
|
1829
|
+
await sock.setWamoAuth('example')
|
|
1830
|
+
// acquireAccessToken
|
|
1831
|
+
await sock.acquireAccessToken()
|
|
1832
|
+
// executeWWWGraphQL
|
|
1833
|
+
await sock.executeWWWGraphQL('example', undefined)
|
|
1834
|
+
// executeFacebookGraphQL
|
|
1835
|
+
await sock.executeFacebookGraphQL('example', undefined)
|
|
1836
|
+
// executeWamoGraphQL
|
|
1837
|
+
await sock.executeWamoGraphQL('example', undefined)
|
|
1838
|
+
```
|
|
1839
|
+
|
|
1840
|
+
### Groups, AI groups, and calls
|
|
1841
|
+
|
|
1842
|
+
```js
|
|
1843
|
+
const jid = '1234567890@s.whatsapp.net'
|
|
1844
|
+
const groupJid = '120363000000000000@g.us'
|
|
1845
|
+
const userJid = '15551234567@s.whatsapp.net'
|
|
1846
|
+
|
|
1847
|
+
// groupCall
|
|
1848
|
+
await sock.groupCall(jid, [userJid], true)
|
|
1849
|
+
// cancelGroupCall
|
|
1850
|
+
await sock.cancelGroupCall(jid, 'example')
|
|
1851
|
+
// aiGroupMetadata
|
|
1852
|
+
await sock.aiGroupMetadata(jid)
|
|
1853
|
+
// aiGroupCreate
|
|
1854
|
+
await sock.aiGroupCreate('example', [userJid], undefined)
|
|
1855
|
+
// aiGroupAddBot
|
|
1856
|
+
await sock.aiGroupAddBot(jid, undefined)
|
|
1857
|
+
// aiGroupLeave
|
|
1858
|
+
await sock.aiGroupLeave('example')
|
|
1859
|
+
// aiGroupParticipantsUpdate
|
|
1860
|
+
await sock.aiGroupParticipantsUpdate(jid, [userJid], 'example')
|
|
1861
|
+
// aiGroupUpdateSubject
|
|
1862
|
+
await sock.aiGroupUpdateSubject(jid, 'example')
|
|
1863
|
+
// aiGroupInviteCode
|
|
1864
|
+
await sock.aiGroupInviteCode(jid)
|
|
1865
|
+
// aiGroupRevokeInvite
|
|
1866
|
+
await sock.aiGroupRevokeInvite(jid)
|
|
1867
|
+
// aiGroupAcceptInvite
|
|
1868
|
+
await sock.aiGroupAcceptInvite('example')
|
|
1869
|
+
// aiGroupSettingUpdate
|
|
1870
|
+
await sock.aiGroupSettingUpdate(jid, 'example')
|
|
1871
|
+
// aiGroupToggleEphemeral
|
|
1872
|
+
await sock.aiGroupToggleEphemeral(jid, 0)
|
|
1873
|
+
// groupAcknowledge
|
|
1874
|
+
await sock.groupAcknowledge(jid)
|
|
1875
|
+
// groupGetLinkedParticipants
|
|
1876
|
+
await sock.groupGetLinkedParticipants(jid)
|
|
1877
|
+
// groupJoinLinked
|
|
1878
|
+
await sock.groupJoinLinked(jid, jid, 'example')
|
|
1879
|
+
// groupCreateSubGroupSuggestion
|
|
1880
|
+
await sock.groupCreateSubGroupSuggestion(jid, {})
|
|
1881
|
+
// groupSubGroupSuggestionsAction
|
|
1882
|
+
await sock.groupSubGroupSuggestionsAction(jid, 'example', {})
|
|
1883
|
+
```
|
|
1884
|
+
|
|
1885
|
+
### Interop
|
|
1886
|
+
|
|
1887
|
+
```js
|
|
1888
|
+
const jid = '1234567890@s.whatsapp.net'
|
|
1889
|
+
const groupJid = '120363000000000000@g.us'
|
|
1890
|
+
const userJid = '15551234567@s.whatsapp.net'
|
|
1891
|
+
|
|
1892
|
+
// initInterop
|
|
1893
|
+
await sock.initInterop()
|
|
1894
|
+
// resetInteropSession
|
|
1895
|
+
await sock.resetInteropSession()
|
|
1896
|
+
// acceptInteropTOS
|
|
1897
|
+
await sock.acceptInteropTOS()
|
|
1898
|
+
// resolveInteropUser
|
|
1899
|
+
await sock.resolveInteropUser(jid)
|
|
1900
|
+
// resolveInteropUsers
|
|
1901
|
+
await sock.resolveInteropUsers(jid)
|
|
1902
|
+
// blockInteropUser
|
|
1903
|
+
await sock.blockInteropUser(jid)
|
|
1904
|
+
// unblockInteropUser
|
|
1905
|
+
await sock.unblockInteropUser(jid)
|
|
1906
|
+
// reportInteropSpam
|
|
1907
|
+
await sock.reportInteropSpam(jid)
|
|
1908
|
+
// trustInteropContact
|
|
1909
|
+
await sock.trustInteropContact(jid)
|
|
1910
|
+
// createInteropGroup
|
|
1911
|
+
await sock.createInteropGroup('example', [userJid])
|
|
1912
|
+
// leaveInteropGroup
|
|
1913
|
+
await sock.leaveInteropGroup(jid)
|
|
1914
|
+
// addParticipantsToInteropGroup
|
|
1915
|
+
await sock.addParticipantsToInteropGroup(jid, [userJid])
|
|
1916
|
+
// queryInteropGroupInfo
|
|
1917
|
+
await sock.queryInteropGroupInfo(jid)
|
|
1918
|
+
// queryInteropPrivacySettings
|
|
1919
|
+
await sock.queryInteropPrivacySettings()
|
|
1920
|
+
// updateInteropPrivacySetting
|
|
1921
|
+
await sock.updateInteropPrivacySetting('example', 'example')
|
|
1922
|
+
// updateInteropPrivacySettingWithContactList
|
|
1923
|
+
await sock.updateInteropPrivacySettingWithContactList('example', 'example', [userJid])
|
|
1924
|
+
// getInteropGroupAddPrivacy
|
|
1925
|
+
await sock.getInteropGroupAddPrivacy()
|
|
1926
|
+
```
|
|
1927
|
+
|
|
1928
|
+
### Generic helpers
|
|
1929
|
+
|
|
1930
|
+
```js
|
|
1931
|
+
const jid = '1234567890@s.whatsapp.net'
|
|
1932
|
+
const groupJid = '120363000000000000@g.us'
|
|
1933
|
+
const userJid = '15551234567@s.whatsapp.net'
|
|
1934
|
+
|
|
1935
|
+
// updateRichGeneration
|
|
1936
|
+
await sock.updateRichGeneration(jid, 'example', {}, undefined)
|
|
1937
|
+
// aiPrompt
|
|
1938
|
+
await sock.aiPrompt(jid, 'example', undefined)
|
|
1939
|
+
// getGroupProfilePictures
|
|
1940
|
+
await sock.getGroupProfilePictures(jid, 'example')
|
|
1941
|
+
// fetchIntegrators
|
|
1942
|
+
await sock.fetchIntegrators()
|
|
1943
|
+
// optInIntegrators
|
|
1944
|
+
await sock.optInIntegrators()
|
|
1945
|
+
// optOutIntegrators
|
|
1946
|
+
await sock.optOutIntegrators()
|
|
1947
|
+
// getReachabilitySettings
|
|
1948
|
+
await sock.getReachabilitySettings()
|
|
1949
|
+
// setReachabilitySettings
|
|
1950
|
+
await sock.setReachabilitySettings('example')
|
|
1951
|
+
// get
|
|
1952
|
+
await sock.get(undefined)
|
|
1953
|
+
// set
|
|
1954
|
+
await sock.set(undefined, 'example', 0)
|
|
1955
|
+
// delete
|
|
1956
|
+
await sock.delete(undefined)
|
|
1957
|
+
// keys
|
|
1958
|
+
await sock.keys(undefined)
|
|
1959
|
+
```
|
|
1960
|
+
|
|
1471
1961
|
## Development
|
|
1472
1962
|
|
|
1473
1963
|
```bash
|
|
@@ -1504,7 +1994,7 @@ Auto-greet new contacts with an interactive FAQ menu. Fires once per contact, ne
|
|
|
1504
1994
|
### Basic Setup
|
|
1505
1995
|
|
|
1506
1996
|
```javascript
|
|
1507
|
-
import { createWelcomeFlow } from '
|
|
1997
|
+
import { createWelcomeFlow } from 'plogme'
|
|
1508
1998
|
|
|
1509
1999
|
const welcome = createWelcomeFlow(sock, {
|
|
1510
2000
|
greeting: 'Welcome! How can I help you today?',
|
|
@@ -1580,7 +2070,7 @@ welcome.hasGreeted(jid) // check if greeted → boolean
|
|
|
1580
2070
|
| Option | Type | Default | Description |
|
|
1581
2071
|
|--------|------|---------|-------------|
|
|
1582
2072
|
| greeting | string | 'Welcome!…' | Body text of welcome message |
|
|
1583
|
-
| footer | string | 'Powered by
|
|
2073
|
+
| footer | string | 'Powered by plogme' | Footer text |
|
|
1584
2074
|
| buttonText | string | 'Choose an option' | List button label |
|
|
1585
2075
|
| sectionTitle | string | 'How can we help?' | Section header |
|
|
1586
2076
|
| faqs | Array | 4 defaults | { id, title, description } |
|
|
@@ -1703,7 +2193,7 @@ sock.sendMessage(jid, {
|
|
|
1703
2193
|
text: 'Built manually',
|
|
1704
2194
|
contextInfo: {
|
|
1705
2195
|
externalAdReply: {
|
|
1706
|
-
title: '
|
|
2196
|
+
title: 'plogme',
|
|
1707
2197
|
thumbnail: fs.readFileSync('./image.jpg'),
|
|
1708
2198
|
sourceApp: 'whatsapp',
|
|
1709
2199
|
showAdAttribution: true,
|
|
@@ -1885,7 +2375,7 @@ saveFavs(remaining)
|
|
|
1885
2375
|
|
|
1886
2376
|
```javascript
|
|
1887
2377
|
// Create
|
|
1888
|
-
sock.newsletterCreate('
|
|
2378
|
+
sock.newsletterCreate('plogme', 'Fresh updates weekly')
|
|
1889
2379
|
|
|
1890
2380
|
// Metadata
|
|
1891
2381
|
const metadata = await sock.newsletterMetadata('1231111111111@newsletter')
|
|
@@ -1906,8 +2396,8 @@ sock.newsletterDemote('1231111111111@newsletter', '6281111111111@s.whatsapp.net'
|
|
|
1906
2396
|
sock.newsletterChangeOwner('1231111111111@newsletter', '6281111111111@s.whatsapp.net')
|
|
1907
2397
|
|
|
1908
2398
|
// Update
|
|
1909
|
-
sock.newsletterUpdate('1231111111111@newsletter', { name: '
|
|
1910
|
-
sock.newsletterUpdateName('1231111111111@newsletter', '
|
|
2399
|
+
sock.newsletterUpdate('1231111111111@newsletter', { name: 'plogme' })
|
|
2400
|
+
sock.newsletterUpdateName('1231111111111@newsletter', 'plogme')
|
|
1911
2401
|
sock.newsletterUpdateDescription('1231111111111@newsletter', 'Fresh updates weekly')
|
|
1912
2402
|
sock.newsletterUpdatePicture('1231111111111@newsletter', { url: 'path/to/image.jpg' })
|
|
1913
2403
|
sock.newsletterRemovePicture('1231111111111@newsletter')
|
|
@@ -1934,7 +2424,7 @@ sock.newsletterDelete('1231111111111@newsletter')
|
|
|
1934
2424
|
|
|
1935
2425
|
```javascript
|
|
1936
2426
|
// Create
|
|
1937
|
-
const group = await sock.groupCreate('
|
|
2427
|
+
const group = await sock.groupCreate('plogme', ['628123456789@s.whatsapp.net'])
|
|
1938
2428
|
|
|
1939
2429
|
// Metadata
|
|
1940
2430
|
const metadata = await sock.groupMetadata(jid)
|
|
@@ -1957,7 +2447,7 @@ sock.groupParticipantsUpdate(jid, ['628123456789@s.whatsapp.net'], 'demote')
|
|
|
1957
2447
|
sock.groupRequestParticipantsUpdate(jid, ['628123456789@s.whatsapp.net'], 'approve')
|
|
1958
2448
|
|
|
1959
2449
|
// Info updates
|
|
1960
|
-
sock.groupUpdateSubject(jid, '
|
|
2450
|
+
sock.groupUpdateSubject(jid, 'plogme')
|
|
1961
2451
|
sock.groupUpdateDescription(jid, 'Updated description')
|
|
1962
2452
|
sock.updateProfilePicture(jid, { url: 'path/to/image.jpg' })
|
|
1963
2453
|
sock.removeProfilePicture(jid)
|
|
@@ -1990,7 +2480,7 @@ const requests = await sock.groupRequestParticipantsList(jid)
|
|
|
1990
2480
|
const group = await sock.groupGetInviteInfo('ABC123456789')
|
|
1991
2481
|
|
|
1992
2482
|
// Member label
|
|
1993
|
-
sock.updateMemberLabel(jid, '
|
|
2483
|
+
sock.updateMemberLabel(jid, 'plogme')
|
|
1994
2484
|
```
|
|
1995
2485
|
|
|
1996
2486
|
---
|
|
@@ -1999,7 +2489,7 @@ sock.updateMemberLabel(jid, '@crysnovax/baileys')
|
|
|
1999
2489
|
|
|
2000
2490
|
```javascript
|
|
2001
2491
|
// Create
|
|
2002
|
-
const community = await sock.communityCreate('
|
|
2492
|
+
const community = await sock.communityCreate('plogme', 'Fresh updates weekly')
|
|
2003
2493
|
|
|
2004
2494
|
// Create subgroup
|
|
2005
2495
|
const group = await sock.communityCreateGroup(
|
|
@@ -2027,7 +2517,7 @@ sock.communityLeave(jid)
|
|
|
2027
2517
|
sock.communityRequestParticipantsUpdate(jid, ['628123456789@s.whatsapp.net'], 'approve')
|
|
2028
2518
|
|
|
2029
2519
|
// Updates
|
|
2030
|
-
sock.communityUpdateSubject(jid, '
|
|
2520
|
+
sock.communityUpdateSubject(jid, 'plogme')
|
|
2031
2521
|
sock.communityUpdateDescription(jid, 'Updated description')
|
|
2032
2522
|
|
|
2033
2523
|
// Settings
|
|
@@ -2328,14 +2818,66 @@ await sock.cleanDirtyBits('account_sync', timestamp)
|
|
|
2328
2818
|
|
|
2329
2819
|
Meta AI-style thinking indicators and live reasoning feeds. Works on all WhatsApp clients — no "Update WhatsApp" messages.
|
|
2330
2820
|
|
|
2821
|
+
### Verified Meta AI prompts and streaming `MESSAGE_EDIT` replies
|
|
2822
|
+
|
|
2823
|
+
The Hatch-compatible Meta AI sender routes prompts to the bot endpoint and
|
|
2824
|
+
returns the outgoing message ID:
|
|
2825
|
+
|
|
2826
|
+
```javascript
|
|
2827
|
+
const messageId = await sock.sendMetaAI('Summarize this conversation', {
|
|
2828
|
+
// Defaults to 867051314767696@bot
|
|
2829
|
+
jid: '867051314767696@bot'
|
|
2830
|
+
})
|
|
2831
|
+
```
|
|
2832
|
+
|
|
2833
|
+
Meta AI responses can arrive as a sequence rather than one final message. The
|
|
2834
|
+
first message is often a placeholder or partial response. WhatsApp then sends
|
|
2835
|
+
`MESSAGE_EDIT` protocol messages whose `protocolMessage.editedMessage` contains
|
|
2836
|
+
the newest version of the bot response. Each edit replaces the previous text;
|
|
2837
|
+
it is not a separate conversation message.
|
|
2838
|
+
|
|
2839
|
+
Plogme's `extractMetaAiText()` checks the edited body first and also handles
|
|
2840
|
+
plain text, rich-response submessages, and base64 unified responses:
|
|
2841
|
+
|
|
2842
|
+
```javascript
|
|
2843
|
+
import { extractMetaAiText } from 'plogme'
|
|
2844
|
+
|
|
2845
|
+
sock.ev.on('messages.upsert', ({ messages }) => {
|
|
2846
|
+
for (const message of messages) {
|
|
2847
|
+
const text = extractMetaAiText(message.message)
|
|
2848
|
+
if (text) console.log('latest Meta AI text:', text)
|
|
2849
|
+
}
|
|
2850
|
+
})
|
|
2851
|
+
```
|
|
2852
|
+
|
|
2853
|
+
An incoming edit has the conceptual shape below:
|
|
2854
|
+
|
|
2855
|
+
```javascript
|
|
2856
|
+
{
|
|
2857
|
+
protocolMessage: {
|
|
2858
|
+
type: 'MESSAGE_EDIT',
|
|
2859
|
+
key: { remoteJid: '867051314767696@bot', id: 'ORIGINAL_ID' },
|
|
2860
|
+
editedMessage: {
|
|
2861
|
+
extendedTextMessage: { text: 'latest streamed response' }
|
|
2862
|
+
}
|
|
2863
|
+
}
|
|
2864
|
+
}
|
|
2865
|
+
```
|
|
2866
|
+
|
|
2867
|
+
For unified responses, the raw payload remains available in
|
|
2868
|
+
`unifiedResponse.data`; the decoder adds `decodedData` and flattened `text` in
|
|
2869
|
+
place. This makes it possible to render partial edits immediately while still
|
|
2870
|
+
retaining the original wire representation.
|
|
2871
|
+
|
|
2331
2872
|
**Note:** These use plain text placeholders with typing indicators by default, avoiding unsupported-message bubbles. Final code blocks, tables, links, and rich responses are unchanged. Native Meta typing/thinking is force-only: set both `forceMetaRendering: true` in the socket config and `useNativeMeta: true` in the `metaTyping` or `sendMetaComposited` options.
|
|
2332
2873
|
|
|
2333
2874
|
### Meta Typing Indicator
|
|
2334
2875
|
|
|
2335
|
-
Show a live thinking indicator that you control.
|
|
2876
|
+
Show a live thinking indicator that you control. It is a real message, so you
|
|
2877
|
+
can edit it in place or delete it manually when finished.
|
|
2336
2878
|
|
|
2337
2879
|
```javascript
|
|
2338
|
-
import { metaTyping, buildSteps } from '
|
|
2880
|
+
import { metaTyping, editMetaMessage, buildSteps } from 'plogme'
|
|
2339
2881
|
|
|
2340
2882
|
const placeholder = await metaTyping(sock, jid, {
|
|
2341
2883
|
description: 'Thinking…',
|
|
@@ -2344,11 +2886,9 @@ const placeholder = await metaTyping(sock, jid, {
|
|
|
2344
2886
|
|
|
2345
2887
|
// Do your work here…
|
|
2346
2888
|
|
|
2347
|
-
//
|
|
2348
|
-
await sock
|
|
2349
|
-
|
|
2350
|
-
// Send the real message
|
|
2351
|
-
await sock.sendMessage(jid, { text: 'Here is your answer!' })
|
|
2889
|
+
// Keep the same message key while streaming progress
|
|
2890
|
+
await editMetaMessage(sock, jid, placeholder.key, { text: 'Thinking… I found something.' })
|
|
2891
|
+
await editMetaMessage(sock, jid, placeholder.key, { text: 'Here is your answer!' })
|
|
2352
2892
|
```
|
|
2353
2893
|
|
|
2354
2894
|
What users see:
|
|
@@ -2360,17 +2900,18 @@ _Thinking…_
|
|
|
2360
2900
|
○ Reading your message…
|
|
2361
2901
|
○ Writing response…
|
|
2362
2902
|
|
|
2363
|
-
|
|
2903
|
+
_Thinking… I found something._
|
|
2364
2904
|
|
|
2365
|
-
Here is your answer!
|
|
2905
|
+
Here is your answer! // same message, updated through MESSAGE_EDIT
|
|
2366
2906
|
```
|
|
2367
2907
|
|
|
2368
2908
|
### Meta Compositing
|
|
2369
2909
|
|
|
2370
|
-
Full flow:
|
|
2910
|
+
Full flow: initial message → optional `MESSAGE_EDIT` stream frames → final
|
|
2911
|
+
`MESSAGE_EDIT` on the same message key. Works with every rich content type.
|
|
2371
2912
|
|
|
2372
2913
|
```javascript
|
|
2373
|
-
import { sendMetaComposited, PlanningStepStatus } from '
|
|
2914
|
+
import { sendMetaComposited, PlanningStepStatus } from 'plogme'
|
|
2374
2915
|
|
|
2375
2916
|
// With code block
|
|
2376
2917
|
await sendMetaComposited(
|
|
@@ -2379,6 +2920,11 @@ await sendMetaComposited(
|
|
|
2379
2920
|
{
|
|
2380
2921
|
thinkingMs: 3000,
|
|
2381
2922
|
description: 'Analyzing…',
|
|
2923
|
+
streamUpdates: [
|
|
2924
|
+
'Thinking…',
|
|
2925
|
+
'Thinking… I found the relevant code.'
|
|
2926
|
+
],
|
|
2927
|
+
streamUpdateDelayMs: 700,
|
|
2382
2928
|
steps: [
|
|
2383
2929
|
{ title: 'Reading context…', status: PlanningStepStatus.DONE },
|
|
2384
2930
|
{ title: 'Writing code…', status: PlanningStepStatus.IN_PROGRESS }
|
|
@@ -2416,10 +2962,11 @@ await sendMetaComposited(
|
|
|
2416
2962
|
|
|
2417
2963
|
### Replay Planning
|
|
2418
2964
|
|
|
2419
|
-
Live Meta AI-style reasoning feed — each step visibly completes in real time,
|
|
2965
|
+
Live Meta AI-style reasoning feed — each step visibly completes in real time,
|
|
2966
|
+
then the final rich message is written with `MESSAGE_EDIT` on the same key.
|
|
2420
2967
|
|
|
2421
2968
|
```javascript
|
|
2422
|
-
import { replayPlanning, mixedSteps } from '
|
|
2969
|
+
import { replayPlanning, mixedSteps } from 'plogme'
|
|
2423
2970
|
|
|
2424
2971
|
await replayPlanning(
|
|
2425
2972
|
sock, jid,
|
|
@@ -2476,7 +3023,7 @@ import {
|
|
|
2476
3023
|
buildSearchSteps, // isEnhancedSearch: true
|
|
2477
3024
|
mixedSteps, // mix any combination
|
|
2478
3025
|
buildSteps // plain steps
|
|
2479
|
-
} from '
|
|
3026
|
+
} from 'plogme'
|
|
2480
3027
|
|
|
2481
3028
|
// All reasoning
|
|
2482
3029
|
buildReasoningSteps(['Analyzing the problem…', 'Checking edge cases…'])
|
|
@@ -2495,7 +3042,7 @@ mixedSteps([
|
|
|
2495
3042
|
Replay planning only (no final message):
|
|
2496
3043
|
|
|
2497
3044
|
```javascript
|
|
2498
|
-
import { replayPlanningOnly, buildSearchSteps } from '
|
|
3045
|
+
import { replayPlanningOnly, buildSearchSteps } from 'plogme'
|
|
2499
3046
|
|
|
2500
3047
|
await replayPlanningOnly(
|
|
2501
3048
|
sock, jid,
|
|
@@ -2565,7 +3112,7 @@ sock.ev.on('settings.update', (update) => {})
|
|
|
2565
3112
|
Auto-detects available libraries: sharp, @napi-rs/image, or jimp.
|
|
2566
3113
|
|
|
2567
3114
|
```javascript
|
|
2568
|
-
import { getImageProcessingLibrary } from '
|
|
3115
|
+
import { getImageProcessingLibrary } from 'plogme'
|
|
2569
3116
|
import { readFile } from 'fs/promises'
|
|
2570
3117
|
|
|
2571
3118
|
const lib = await getImageProcessingLibrary()
|