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 CHANGED
@@ -7,7 +7,7 @@
7
7
 
8
8
  [![npm version](https://img.shields.io/npm/v/plogme?style=flat-square)](https://www.npmjs.com/package/plogme)
9
9
  [![Node.js](https://img.shields.io/badge/Node.js-%3E%3D20-10b981?style=flat-square&logo=node.js)](https://nodejs.org/)
10
- [![Tests](https://img.shields.io/badge/tests-30%20passing-10b981?style=flat-square)](https://github.com/crysnovax/baileys)
10
+ [![Tests](https://img.shields.io/badge/tests-174%20passing-10b981?style=flat-square)](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. [Development](#development)
32
- 19. [License and support](#license-and-support)
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
- To install the development branch directly from GitHub:
43
+ The published package is available from npm:
43
44
 
44
45
  ```bash
45
- npm install github:crysnovax/baileys
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. Image primitives explicitly request full-width presentation and carry preview/full URL fallbacks.
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 '@crysnovax/baileys'
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 @crysnovax/baileys' | Footer text |
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: '@crysnovax/baileys',
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('@crysnovax/baileys', 'Fresh updates weekly')
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: '@crysnovax/baileys' })
1910
- sock.newsletterUpdateName('1231111111111@newsletter', '@crysnovax/baileys')
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('@crysnovax/baileys', ['628123456789@s.whatsapp.net'])
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, '@crysnovax/baileys')
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, '@crysnovax/baileys')
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('@crysnovax/baileys', 'Fresh updates weekly')
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, '@crysnovax/baileys')
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. Delete it manually when ready — no "edited" badge ever appears.
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 '@crysnovax/baileys'
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
- // Delete the indicator cleanly
2348
- await sock.sendMessage(jid, { delete: placeholder.key })
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
- [auto-deletes]
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: indicator shows → auto-deletes → clean final message lands. Works with every rich content type.
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 '@crysnovax/baileys'
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, then the final rich message lands clean.
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 '@crysnovax/baileys'
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 '@crysnovax/baileys'
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 '@crysnovax/baileys'
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 '@crysnovax/baileys'
3115
+ import { getImageProcessingLibrary } from 'plogme'
2569
3116
  import { readFile } from 'fs/promises'
2570
3117
 
2571
3118
  const lib = await getImageProcessingLibrary()