plogme 2.1.0 → 2.1.2
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 +226 -2
- package/WAProto/WAProto.proto +12 -0
- package/WAProto/index.d.ts +12 -0
- package/WAProto/index.js +12 -0
- package/engine-requirements.js +12 -0
- package/lib/Defaults/ban-checker.js +12 -0
- package/lib/Defaults/index.js +12 -0
- package/lib/Signal/Group/ciphertext-message.js +12 -0
- package/lib/Signal/Group/group-session-builder.js +12 -0
- package/lib/Signal/Group/group_cipher.js +12 -0
- package/lib/Signal/Group/index.js +12 -0
- package/lib/Signal/Group/keyhelper.js +12 -0
- package/lib/Signal/Group/sender-chain-key.js +12 -0
- package/lib/Signal/Group/sender-key-distribution-message.js +12 -0
- package/lib/Signal/Group/sender-key-message.js +12 -0
- package/lib/Signal/Group/sender-key-name.js +12 -0
- package/lib/Signal/Group/sender-key-record.js +12 -0
- package/lib/Signal/Group/sender-key-state.js +12 -0
- package/lib/Signal/Group/sender-message-key.js +12 -0
- package/lib/Signal/libsignal.js +12 -0
- package/lib/Signal/lid-mapping.js +12 -0
- package/lib/Socket/Client/index.js +12 -0
- package/lib/Socket/Client/types.js +12 -0
- package/lib/Socket/Client/websocket.js +12 -0
- package/lib/Socket/aigroups.js +12 -0
- package/lib/Socket/ban-checker.js +12 -0
- package/lib/Socket/business.js +12 -0
- package/lib/Socket/chats.js +12 -0
- package/lib/Socket/communities.js +12 -0
- package/lib/Socket/graphql.js +12 -0
- package/lib/Socket/groups.js +12 -0
- package/lib/Socket/index.js +12 -0
- package/lib/Socket/interactive-handler.js +12 -0
- package/lib/Socket/interop.js +12 -0
- package/lib/Socket/managed-account.js +12 -0
- package/lib/Socket/messages-recv.js +12 -0
- package/lib/Socket/messages-send.js +358 -7
- package/lib/Socket/mex.js +12 -0
- package/lib/Socket/newsletter.js +12 -0
- package/lib/Socket/privacy.js +12 -0
- package/lib/Socket/registration.js +12 -0
- package/lib/Socket/socket.js +12 -0
- package/lib/Socket/username.js +12 -0
- package/lib/Store/index.js +12 -0
- package/lib/Store/make-cache-manager-store.js +12 -0
- package/lib/Store/make-in-memory-store.js +12 -0
- package/lib/Store/make-ordered-dictionary.js +12 -0
- package/lib/Store/object-repository.js +12 -0
- package/lib/Types/Auth.js +12 -0
- package/lib/Types/Bussines.js +12 -0
- package/lib/Types/Call.js +12 -0
- package/lib/Types/Chat.js +12 -0
- package/lib/Types/Contact.js +12 -0
- package/lib/Types/Events.js +12 -0
- package/lib/Types/GroupMetadata.js +12 -0
- package/lib/Types/Label.js +12 -0
- package/lib/Types/LabelAssociation.js +12 -0
- package/lib/Types/Message.js +12 -0
- package/lib/Types/Mex.js +12 -0
- package/lib/Types/Product.js +12 -0
- package/lib/Types/RichType.js +12 -0
- package/lib/Types/Signal.js +12 -0
- package/lib/Types/Socket.js +12 -0
- package/lib/Types/State.js +12 -0
- package/lib/Types/USync.js +12 -0
- package/lib/Types/index.js +12 -0
- package/lib/Utils/auth-utils.js +12 -0
- package/lib/Utils/bot-capabilities.js +12 -0
- package/lib/Utils/bot-planning-replay.js +12 -0
- package/lib/Utils/browser-utils.js +12 -0
- package/lib/Utils/business.js +12 -0
- package/lib/Utils/channel-policy.js +12 -0
- package/lib/Utils/chat-utils.js +12 -0
- package/lib/Utils/companion-reg-client-utils.js +12 -0
- package/lib/Utils/consumer-application.js +12 -0
- package/lib/Utils/crypto.js +12 -0
- package/lib/Utils/decode-wa-message.js +12 -0
- package/lib/Utils/event-buffer.js +12 -0
- package/lib/Utils/games/miniapp.js +12 -0
- package/lib/Utils/games/slot-machine.js +12 -0
- package/lib/Utils/games/website-preview.js +12 -0
- package/lib/Utils/generics.js +12 -0
- package/lib/Utils/group-history.js +12 -0
- package/lib/Utils/history.js +12 -0
- package/lib/Utils/identity-change-handler.js +12 -0
- package/lib/Utils/index.js +12 -0
- package/lib/Utils/jid-display-normalization.js +12 -0
- package/lib/Utils/link-preview.js +12 -0
- package/lib/Utils/logger.js +12 -0
- package/lib/Utils/lt-hash.js +12 -0
- package/lib/Utils/make-mutex.js +12 -0
- package/lib/Utils/message-composer.js +18 -1
- package/lib/Utils/message-inspect.js +12 -0
- package/lib/Utils/message-retry-manager.js +12 -0
- package/lib/Utils/messages-media.js +12 -0
- package/lib/Utils/messages.js +232 -4
- package/lib/Utils/meta-ai-msmsg.js +12 -0
- package/lib/Utils/meta-compositing.js +12 -0
- package/lib/Utils/native-flow.js +12 -0
- package/lib/Utils/noise-handler.js +12 -0
- package/lib/Utils/offline-node-processor.js +12 -0
- package/lib/Utils/pre-key-manager.js +12 -0
- package/lib/Utils/process-message.js +12 -0
- package/lib/Utils/reporting-utils.js +12 -0
- package/lib/Utils/rich-message-utils.js +484 -91
- package/lib/Utils/signal.js +12 -0
- package/lib/Utils/source-grep.js +12 -0
- package/lib/Utils/stanza-ack.js +12 -0
- package/lib/Utils/sync-action-utils.js +12 -0
- package/lib/Utils/tc-token-utils.js +12 -0
- package/lib/Utils/use-multi-file-auth-state.js +12 -0
- package/lib/Utils/use-single-file-auth-state.js +12 -0
- package/lib/Utils/use-sqlite-auth-state.js +12 -0
- package/lib/Utils/validate-connection.js +12 -0
- package/lib/Utils/view-once-utils.js +12 -0
- package/lib/Utils/voip-rekey.js +12 -0
- package/lib/Utils/welcome-flow.js +12 -0
- package/lib/WABinary/constants.js +12 -0
- package/lib/WABinary/decode.js +12 -0
- package/lib/WABinary/encode.js +12 -0
- package/lib/WABinary/generic-utils.js +12 -0
- package/lib/WABinary/index.js +12 -0
- package/lib/WABinary/jid-utils.js +12 -0
- package/lib/WABinary/types.js +12 -0
- package/lib/WAM/BinaryInfo.js +12 -0
- package/lib/WAM/constants.js +12 -0
- package/lib/WAM/encode.js +12 -0
- package/lib/WAM/index.js +12 -0
- package/lib/WAUSync/Protocols/USyncBusinessProtocol.js +12 -0
- package/lib/WAUSync/Protocols/USyncContactProtocol.js +12 -0
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +12 -0
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +12 -0
- package/lib/WAUSync/Protocols/USyncFeatureProtocol.js +12 -0
- package/lib/WAUSync/Protocols/USyncPictureProtocol.js +12 -0
- package/lib/WAUSync/Protocols/USyncSidelistProtocol.js +12 -0
- package/lib/WAUSync/Protocols/USyncStatusProtocol.js +12 -0
- package/lib/WAUSync/Protocols/USyncTextStatusProtocol.js +12 -0
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +12 -0
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +12 -0
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +12 -0
- package/lib/WAUSync/Protocols/index.js +12 -0
- package/lib/WAUSync/USyncQuery.js +12 -0
- package/lib/WAUSync/USyncUser.js +12 -0
- package/lib/WAUSync/index.js +12 -0
- package/lib/index.d.ts +50 -2
- package/lib/index.js +12 -0
- package/package.json +9 -2
package/lib/Socket/aigroups.js
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @crysnpvax
|
|
3
|
+
*
|
|
4
|
+
* File: lib/Socket/aigroups.js
|
|
5
|
+
* About: Aigroups module for the Plogme WhatsApp protocol client.
|
|
6
|
+
* Important exports: META_AI_BOT_JID, isMetaAIBotResponse, collectMetaAIBotParticipantJids, makeAIGroupsSocket, extractAIGroupMetadata
|
|
7
|
+
* Directions: Import the listed exports and preserve protocol, validation, and compatibility invariants when modifying.
|
|
8
|
+
*
|
|
9
|
+
* Copyright and attribution notice.
|
|
10
|
+
* Do not copy, reproduce, redistribute, modify, or create derivative works
|
|
11
|
+
* from this source without explicit written permission.
|
|
12
|
+
*/
|
|
1
13
|
import { WAMessageAddressingMode } from '../Types/index.js';
|
|
2
14
|
import { generateMessageIDV2, normalizeMessageContent } from '../Utils/index.js';
|
|
3
15
|
import { getBinaryNodeChild, getBinaryNodeChildren, getBinaryNodeChildString, isJidGroup, isJidMetaAI, isLidUser, isPnUser, jidEncode, jidNormalizedUser } from '../WABinary/index.js';
|
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @crysnpvax
|
|
3
|
+
*
|
|
4
|
+
* File: lib/Socket/ban-checker.js
|
|
5
|
+
* About: Ban checker module for the Plogme WhatsApp protocol client.
|
|
6
|
+
* Important exports: checkStatusWA, getBanDetails, normalizePhone
|
|
7
|
+
* Directions: Import the listed exports and preserve protocol, validation, and compatibility invariants when modifying.
|
|
8
|
+
*
|
|
9
|
+
* Copyright and attribution notice.
|
|
10
|
+
* Do not copy, reproduce, redistribute, modify, or create derivative works
|
|
11
|
+
* from this source without explicit written permission.
|
|
12
|
+
*/
|
|
1
13
|
import { randomBytes, randomUUID } from 'crypto';
|
|
2
14
|
import { initAuthCreds } from '../Utils/auth-utils.js';
|
|
3
15
|
import { Curve, md5, signedKeyPair } from '../Utils/crypto.js';
|
package/lib/Socket/business.js
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @crysnpvax
|
|
3
|
+
*
|
|
4
|
+
* File: lib/Socket/business.js
|
|
5
|
+
* About: Business module for the Plogme WhatsApp protocol client.
|
|
6
|
+
* Important exports: makeBusinessSocket
|
|
7
|
+
* Directions: Import the listed exports and preserve protocol, validation, and compatibility invariants when modifying.
|
|
8
|
+
*
|
|
9
|
+
* Copyright and attribution notice.
|
|
10
|
+
* Do not copy, reproduce, redistribute, modify, or create derivative works
|
|
11
|
+
* from this source without explicit written permission.
|
|
12
|
+
*/
|
|
1
13
|
import { unlink } from 'node:fs/promises';
|
|
2
14
|
import { getRawMediaUploadData } from '../Utils/index.js';
|
|
3
15
|
import { parseCatalogNode, parseCollectionsNode, parseOrderDetailsNode, parseProductNode, toProductNode, uploadingNecessaryImagesOfProduct } from '../Utils/business.js';
|
package/lib/Socket/chats.js
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @crysnpvax
|
|
3
|
+
*
|
|
4
|
+
* File: lib/Socket/chats.js
|
|
5
|
+
* About: Chats module for the Plogme WhatsApp protocol client.
|
|
6
|
+
* Important exports: makeChatsSocket
|
|
7
|
+
* Directions: Import the listed exports and preserve protocol, validation, and compatibility invariants when modifying.
|
|
8
|
+
*
|
|
9
|
+
* Copyright and attribution notice.
|
|
10
|
+
* Do not copy, reproduce, redistribute, modify, or create derivative works
|
|
11
|
+
* from this source without explicit written permission.
|
|
12
|
+
*/
|
|
1
13
|
import NodeCache from '@cacheable/node-cache';
|
|
2
14
|
import { Boom } from '@hapi/boom';
|
|
3
15
|
import { proto } from '../../WAProto/index.js';
|
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @crysnpvax
|
|
3
|
+
*
|
|
4
|
+
* File: lib/Socket/communities.js
|
|
5
|
+
* About: Communities module for the Plogme WhatsApp protocol client.
|
|
6
|
+
* Important exports: makeCommunitiesSocket, extractCommunityMetadata
|
|
7
|
+
* Directions: Import the listed exports and preserve protocol, validation, and compatibility invariants when modifying.
|
|
8
|
+
*
|
|
9
|
+
* Copyright and attribution notice.
|
|
10
|
+
* Do not copy, reproduce, redistribute, modify, or create derivative works
|
|
11
|
+
* from this source without explicit written permission.
|
|
12
|
+
*/
|
|
1
13
|
import { proto } from '../../WAProto/index.js';
|
|
2
14
|
import { WAMessageStubType } from '../Types/index.js';
|
|
3
15
|
import { generateMessageID, generateMessageIDV2, unixTimestampSeconds } from '../Utils/index.js';
|
package/lib/Socket/graphql.js
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @crysnpvax
|
|
3
|
+
*
|
|
4
|
+
* File: lib/Socket/graphql.js
|
|
5
|
+
* About: Graphql module for the Plogme WhatsApp protocol client.
|
|
6
|
+
* Important exports: executeWWWGraphQL, executeFacebookGraphQL, executeWamoGraphQL, makeGraphQLSocket
|
|
7
|
+
* Directions: Import the listed exports and preserve protocol, validation, and compatibility invariants when modifying.
|
|
8
|
+
*
|
|
9
|
+
* Copyright and attribution notice.
|
|
10
|
+
* Do not copy, reproduce, redistribute, modify, or create derivative works
|
|
11
|
+
* from this source without explicit written permission.
|
|
12
|
+
*/
|
|
1
13
|
import { Boom } from '@hapi/boom';
|
|
2
14
|
|
|
3
15
|
// Endpoints confirmed from APX.java and WamoGraphQLExecutor.java
|
package/lib/Socket/groups.js
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @crysnpvax
|
|
3
|
+
*
|
|
4
|
+
* File: lib/Socket/groups.js
|
|
5
|
+
* About: Groups module for the Plogme WhatsApp protocol client.
|
|
6
|
+
* Important exports: buildReportNode, buildGroupStatusRevokeMessage, makeGroupsSocket, extractGroupMetadata
|
|
7
|
+
* Directions: Import the listed exports and preserve protocol, validation, and compatibility invariants when modifying.
|
|
8
|
+
*
|
|
9
|
+
* Copyright and attribution notice.
|
|
10
|
+
* Do not copy, reproduce, redistribute, modify, or create derivative works
|
|
11
|
+
* from this source without explicit written permission.
|
|
12
|
+
*/
|
|
1
13
|
import { Boom } from '@hapi/boom';
|
|
2
14
|
import { proto } from '../../WAProto/index.js';
|
|
3
15
|
import { WAMessageAddressingMode, WAMessageStubType } from '../Types/index.js';
|
package/lib/Socket/index.js
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @crysnpvax
|
|
3
|
+
*
|
|
4
|
+
* File: lib/Socket/index.js
|
|
5
|
+
* About: Socket module for the Plogme WhatsApp protocol client.
|
|
6
|
+
* Important exports: checkStatusWA
|
|
7
|
+
* Directions: Import the listed exports and preserve protocol, validation, and compatibility invariants when modifying.
|
|
8
|
+
*
|
|
9
|
+
* Copyright and attribution notice.
|
|
10
|
+
* Do not copy, reproduce, redistribute, modify, or create derivative works
|
|
11
|
+
* from this source without explicit written permission.
|
|
12
|
+
*/
|
|
1
13
|
import { DEFAULT_CONNECTION_CONFIG } from '../Defaults/index.js';
|
|
2
14
|
import { makeCommunitiesSocket } from './communities.js';
|
|
3
15
|
import { makeInteropSocket } from './interop.js';
|
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @crysnpvax
|
|
3
|
+
*
|
|
4
|
+
* File: lib/Socket/interactive-handler.js
|
|
5
|
+
* About: Interactive handler module for the Plogme WhatsApp protocol client.
|
|
6
|
+
* Important exports: Baron
|
|
7
|
+
* Directions: Import the listed exports and preserve protocol, validation, and compatibility invariants when modifying.
|
|
8
|
+
*
|
|
9
|
+
* Copyright and attribution notice.
|
|
10
|
+
* Do not copy, reproduce, redistribute, modify, or create derivative works
|
|
11
|
+
* from this source without explicit written permission.
|
|
12
|
+
*/
|
|
1
13
|
import { randomBytes } from 'crypto';
|
|
2
14
|
import { proto } from '../../WAProto/index.js';
|
|
3
15
|
import {
|
package/lib/Socket/interop.js
CHANGED
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @crysnpvax
|
|
3
|
+
*
|
|
4
|
+
* File: lib/Socket/interop.js
|
|
5
|
+
* About: Interop module for the Plogme WhatsApp protocol client.
|
|
6
|
+
* Important exports: makeInteropSocket
|
|
7
|
+
* Directions: Import the listed exports and preserve protocol, validation, and compatibility invariants when modifying.
|
|
8
|
+
*
|
|
9
|
+
* Copyright and attribution notice.
|
|
10
|
+
* Do not copy, reproduce, redistribute, modify, or create derivative works
|
|
11
|
+
* from this source without explicit written permission.
|
|
12
|
+
*/
|
|
1
13
|
import { getBinaryNodeChild, getBinaryNodeChildren, S_WHATSAPP_NET } from '../WABinary/index.js';
|
|
2
14
|
import { executeWMexQuery } from './mex.js';
|
|
3
15
|
|
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @crysnpvax
|
|
3
|
+
*
|
|
4
|
+
* File: lib/Socket/managed-account.js
|
|
5
|
+
* About: Managed account module for the Plogme WhatsApp protocol client.
|
|
6
|
+
* Important exports: makeManagedAccountSocket
|
|
7
|
+
* Directions: Import the listed exports and preserve protocol, validation, and compatibility invariants when modifying.
|
|
8
|
+
*
|
|
9
|
+
* Copyright and attribution notice.
|
|
10
|
+
* Do not copy, reproduce, redistribute, modify, or create derivative works
|
|
11
|
+
* from this source without explicit written permission.
|
|
12
|
+
*/
|
|
1
13
|
import { executeWMexQuery } from './mex.js';
|
|
2
14
|
|
|
3
15
|
const MANAGED_ACCOUNT_MEX_IDS = {
|
|
@@ -1,3 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @crysnpvax
|
|
3
|
+
*
|
|
4
|
+
* File: lib/Socket/messages-recv.js
|
|
5
|
+
* About: Messages recv module for the Plogme WhatsApp protocol client.
|
|
6
|
+
* Important exports: buildGroupCallStanza, buildGroupCallCancelStanza, makeMessagesRecvSocket
|
|
7
|
+
* Directions: Import the listed exports and preserve protocol, validation, and compatibility invariants when modifying.
|
|
8
|
+
*
|
|
9
|
+
* Copyright and attribution notice.
|
|
10
|
+
* Do not copy, reproduce, redistribute, modify, or create derivative works
|
|
11
|
+
* from this source without explicit written permission.
|
|
12
|
+
*/
|
|
1
13
|
import NodeCache from '@cacheable/node-cache';
|
|
2
14
|
import { Boom } from '@hapi/boom';
|
|
3
15
|
import { randomBytes } from 'crypto';
|
|
@@ -1,9 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @crysnpvax
|
|
3
|
+
*
|
|
4
|
+
* File: lib/Socket/messages-send.js
|
|
5
|
+
* About: Messages send module for the Plogme WhatsApp protocol client.
|
|
6
|
+
* Important exports: normalizeStatusJidList, makeMessagesSocket
|
|
7
|
+
* Directions: Import the listed exports and preserve protocol, validation, and compatibility invariants when modifying.
|
|
8
|
+
*
|
|
9
|
+
* Copyright and attribution notice.
|
|
10
|
+
* Do not copy, reproduce, redistribute, modify, or create derivative works
|
|
11
|
+
* from this source without explicit written permission.
|
|
12
|
+
*/
|
|
1
13
|
import NodeCache from '@cacheable/node-cache';
|
|
2
14
|
import { Boom } from '@hapi/boom';
|
|
3
15
|
import { randomBytes, randomUUID } from 'crypto';
|
|
4
16
|
import { proto } from '../../WAProto/index.js';
|
|
5
17
|
import { BIZ_BOT_SUPPORT_PAYLOAD, DEFAULT_CACHE_TTLS, WA_DEFAULT_EPHEMERAL } from '../Defaults/index.js';
|
|
6
|
-
import { aggregateMessageKeysNotFromMe, assertMediaContent, assertMeId, bindWaitForEvent, buildLinkPreview, decryptMediaRetryData, DEF_MEDIA_HOST, delay, encodeNewsletterMessage, encodeSignedDeviceIdentity, encodeWAMessage, encryptMediaRetryRequest, extractDeviceJids, extractImageThumb, generateMessageIDV2, generateParticipantHashV2, generateWAMessage, generateWAMessageFromContent, getStatusCodeForMediaRetry, makeWhatsAppFlowButton, getUrlFromDirectPath, getWAUploadToServer, MessageRetryManager, normalizeMessageContent, parseAndInjectE2ESessions, prepareWAMessageMedia, shouldIncludeBizBinaryNode, unixTimestampSeconds } from '../Utils/index.js';
|
|
18
|
+
import { aggregateMessageKeysNotFromMe, assertMediaContent, assertMeId, bindWaitForEvent, buildLinkPreview, decryptMediaRetryData, DEF_MEDIA_HOST, delay, encodeNewsletterMessage, encodeSignedDeviceIdentity, encodeWAMessage, encryptMediaRetryRequest, extractDeviceJids, extractImageThumb, generateMessageIDV2, generateParticipantHashV2, generateWAMessage, generateWAMessageFromContent, generateWAMessageFromImagePoll, generateWAMessageFromLivePhoto, getStatusCodeForMediaRetry, makeWhatsAppFlowButton, getUrlFromDirectPath, getWAUploadToServer, MessageRetryManager, normalizeMessageContent, parseAndInjectE2ESessions, prepareWAMessageMedia, shouldIncludeBizBinaryNode, unixTimestampSeconds } from '../Utils/index.js';
|
|
7
19
|
import { getUrlInfo } from '../Utils/link-preview.js';
|
|
8
20
|
import { prepareRichMenuMessage, prepareA2UIMessage, prepareA2UICommandMenu, prepareAIRichCommandMenu, prepareSocialEntityMessage, prepareInstagramProfileMessage, prepareRichResponseMessage, prepareRichGenerationMessage, prepareCopyToClipboardMessage, prepareRichTextMessage, prepareRichQuoteMessage, prepareRichImageMessage, prepareRichLinkMessage, prepareSocialProfileMessage, prepareUnifiedResponseMessage, prepareRichMapMessage, prepareBotPromptSuggestionsMessage, prepareBotSourcesMessage, prepareRichDynamicMediaMessage, prepareBotPttTranscriptMessage, prepareGridImageMessage, prepareVerticalAlbumMessage, prepareVideoGridMessage, prepareHtmlMessage, prepareRichHtmlMessage, buildRichLabelMessage, attachBotVerificationProofs, hasVerifiableProofs } from '../Utils/rich-message-utils.js';
|
|
9
21
|
import { generateSlotMachineHtml } from '../Utils/games/slot-machine.js';
|
|
@@ -1093,6 +1105,69 @@ export const makeMessagesSocket = (config) => {
|
|
|
1093
1105
|
return fullMsg;
|
|
1094
1106
|
};
|
|
1095
1107
|
|
|
1108
|
+
const sendImagePoll = async (jid, poll, sendOptions = {}) => {
|
|
1109
|
+
const userJid = authState.creds.me.id;
|
|
1110
|
+
const { additionalNodes: _callerNodes, ...relayBaseOptions } = sendOptions;
|
|
1111
|
+
return generateWAMessageFromImagePoll(jid, poll, async (message, relayOptions, fullMessage) => {
|
|
1112
|
+
await relayMessage(jid, message, {
|
|
1113
|
+
...relayBaseOptions,
|
|
1114
|
+
useCachedGroupMetadata: sendOptions.useCachedGroupMetadata,
|
|
1115
|
+
statusJidList: sendOptions.statusJidList,
|
|
1116
|
+
statusPrivacy: sendOptions.statusPrivacy,
|
|
1117
|
+
...relayOptions
|
|
1118
|
+
});
|
|
1119
|
+
if (config.emitOwnEvents && fullMessage) {
|
|
1120
|
+
process.nextTick(async () => {
|
|
1121
|
+
await messageMutex.mutex(() => upsertMessage(fullMessage, 'append'));
|
|
1122
|
+
});
|
|
1123
|
+
}
|
|
1124
|
+
}, {
|
|
1125
|
+
logger,
|
|
1126
|
+
userJid,
|
|
1127
|
+
upload: waUploadToServer,
|
|
1128
|
+
mediaCache: config.mediaCache,
|
|
1129
|
+
options: config.options,
|
|
1130
|
+
...sendOptions
|
|
1131
|
+
});
|
|
1132
|
+
};
|
|
1133
|
+
const sendLivePhoto = async (jid, content, quoted, sendOptions = {}) => {
|
|
1134
|
+
const userJid = authState.creds.me?.id;
|
|
1135
|
+
const {
|
|
1136
|
+
relayOptions: callerRelayOptions = {},
|
|
1137
|
+
photo_live: _photoLive,
|
|
1138
|
+
photoLive: _photoLiveCamel,
|
|
1139
|
+
thumbnail: _thumbnail,
|
|
1140
|
+
image: _image,
|
|
1141
|
+
videoThumbnail: _videoThumbnail,
|
|
1142
|
+
motionPhotoPresentationOffsetMs: _motionOffset,
|
|
1143
|
+
presentationOffsetMs: _presentationOffset,
|
|
1144
|
+
...transportOptions
|
|
1145
|
+
} = sendOptions;
|
|
1146
|
+
const mediaOptions = {
|
|
1147
|
+
logger,
|
|
1148
|
+
userJid,
|
|
1149
|
+
upload: waUploadToServer,
|
|
1150
|
+
mediaCache: config.mediaCache,
|
|
1151
|
+
options: config.options,
|
|
1152
|
+
...transportOptions,
|
|
1153
|
+
...(quoted ? { quoted } : {})
|
|
1154
|
+
};
|
|
1155
|
+
return generateWAMessageFromLivePhoto(jid, content, async (message, relayOpts, fullMessage) => {
|
|
1156
|
+
await relayMessage(jid, message, {
|
|
1157
|
+
...transportOptions,
|
|
1158
|
+
...callerRelayOptions,
|
|
1159
|
+
useCachedGroupMetadata: sendOptions.useCachedGroupMetadata,
|
|
1160
|
+
statusJidList: sendOptions.statusJidList,
|
|
1161
|
+
statusPrivacy: sendOptions.statusPrivacy,
|
|
1162
|
+
messageId: relayOpts.messageId
|
|
1163
|
+
});
|
|
1164
|
+
if (config.emitOwnEvents && fullMessage) {
|
|
1165
|
+
process.nextTick(async () => {
|
|
1166
|
+
await messageMutex.mutex(() => upsertMessage(fullMessage, 'append'));
|
|
1167
|
+
});
|
|
1168
|
+
}
|
|
1169
|
+
}, mediaOptions);
|
|
1170
|
+
};
|
|
1096
1171
|
const getMessageType = (message) => {
|
|
1097
1172
|
if (!message)
|
|
1098
1173
|
return 'text';
|
|
@@ -1323,26 +1398,37 @@ export const makeMessagesSocket = (config) => {
|
|
|
1323
1398
|
await relayRichMessage(jid, fullMsg, options);
|
|
1324
1399
|
return fullMsg;
|
|
1325
1400
|
},
|
|
1326
|
-
sendCarousel: async (jid, cards,
|
|
1401
|
+
sendCarousel: async (jid, cards, quotedOrOptions = {}, maybeOptions = undefined) => {
|
|
1327
1402
|
if (!Array.isArray(cards) || cards.length === 0) {
|
|
1328
1403
|
throw new Boom('sendCarousel requires a non-empty card array', { statusCode: 400 });
|
|
1329
1404
|
}
|
|
1405
|
+
// Support both Plogme's original (jid, cards, options) form and
|
|
1406
|
+
// the compatibility form used by working carousel helpers:
|
|
1407
|
+
// (jid, cards, quoted, options).
|
|
1408
|
+
const hasQuotedSignature = maybeOptions !== undefined;
|
|
1409
|
+
const quoted = hasQuotedSignature ? quotedOrOptions : undefined;
|
|
1410
|
+
const options = hasQuotedSignature ? (maybeOptions || {}) : (quotedOrOptions || {});
|
|
1330
1411
|
const normalizedCards = cards.map(card => ({
|
|
1331
1412
|
...card,
|
|
1332
1413
|
text: card.text ?? card.body?.text,
|
|
1333
1414
|
caption: card.caption ?? card.body?.text,
|
|
1334
1415
|
footer: card.footer?.text ?? card.footer,
|
|
1335
1416
|
buttons: card.buttons ?? card.nativeFlowMessage?.buttons,
|
|
1417
|
+
...(card.header?.imageMessage ? { image: typeof card.header.imageMessage === 'string' ? { url: card.header.imageMessage } : card.header.imageMessage } : {}),
|
|
1418
|
+
...(card.header?.videoMessage ? { video: typeof card.header.videoMessage === 'string' ? { url: card.header.videoMessage } : card.header.videoMessage } : {}),
|
|
1336
1419
|
...(card.media?.image ? { image: card.media.image } : {}),
|
|
1337
1420
|
...(card.media?.video ? { video: card.media.video } : {}),
|
|
1338
|
-
...(card.media?.document ? { document: card.media.document } : {})
|
|
1421
|
+
...(card.media?.document ? { document: card.media.document } : {}),
|
|
1422
|
+
...(card.header?.title ? { title: card.title ?? card.header.title } : {}),
|
|
1423
|
+
...(card.header?.subtitle ? { subtitle: card.subtitle ?? card.header.subtitle } : {}),
|
|
1424
|
+
...(card.nativeFlowMessage?.buttons ? { nativeFlow: card.nativeFlow || card.nativeFlowMessage.buttons } : {})
|
|
1339
1425
|
}));
|
|
1340
|
-
const { text, footer, ...messageOptions } = options;
|
|
1426
|
+
const { text, content, footer, ...messageOptions } = options;
|
|
1341
1427
|
const fullMsg = await generateWAMessage(jid, {
|
|
1342
1428
|
...messageOptions,
|
|
1343
1429
|
cards: normalizedCards,
|
|
1344
1430
|
...(options.carouselCardType != null ? { carouselCardType: options.carouselCardType } : {}),
|
|
1345
|
-
...(text !== undefined ? { text } : {}),
|
|
1431
|
+
...((text ?? content) !== undefined ? { text: text ?? content } : {}),
|
|
1346
1432
|
...(footer !== undefined ? { footer } : {})
|
|
1347
1433
|
}, {
|
|
1348
1434
|
logger,
|
|
@@ -1351,11 +1437,244 @@ export const makeMessagesSocket = (config) => {
|
|
|
1351
1437
|
mediaCache: config.mediaCache,
|
|
1352
1438
|
options: config.options,
|
|
1353
1439
|
...options,
|
|
1440
|
+
...(quoted ? { quoted } : {}),
|
|
1354
1441
|
messageId: options.messageId || generateMessageIDV2(jid)
|
|
1355
1442
|
});
|
|
1356
1443
|
await relayMessage(jid, fullMsg.message, { messageId: fullMsg.key.id, ...options });
|
|
1357
1444
|
return fullMsg;
|
|
1358
1445
|
},
|
|
1446
|
+
/** Send legacy reply buttons with an optional single media or location header. */
|
|
1447
|
+
replyButton: async (jid, buttons, quotedOrOptions = {}, maybeOptions = undefined) => {
|
|
1448
|
+
if (!jid) throw new Boom('replyButton requires a target JID', { statusCode: 400 });
|
|
1449
|
+
if (!Array.isArray(buttons) || buttons.length === 0) {
|
|
1450
|
+
throw new Boom('replyButton requires at least one button', { statusCode: 400 });
|
|
1451
|
+
}
|
|
1452
|
+
const hasQuotedSignature = !!(quotedOrOptions?.key && quotedOrOptions?.message);
|
|
1453
|
+
const quoted = hasQuotedSignature ? quotedOrOptions : undefined;
|
|
1454
|
+
const options = hasQuotedSignature ? (maybeOptions || {}) : (maybeOptions || quotedOrOptions || {});
|
|
1455
|
+
const normalizeButton = (button, index) => {
|
|
1456
|
+
if (!button || typeof button !== 'object') {
|
|
1457
|
+
throw new Boom(`replyButton button ${index + 1} must be an object`, { statusCode: 400 });
|
|
1458
|
+
}
|
|
1459
|
+
const label = button.text || button.buttonText || button.displayText || `Option ${index + 1}`;
|
|
1460
|
+
if (button.sections) {
|
|
1461
|
+
return {
|
|
1462
|
+
name: 'single_select',
|
|
1463
|
+
paramsJson: JSON.stringify({ title: label, sections: button.sections })
|
|
1464
|
+
};
|
|
1465
|
+
}
|
|
1466
|
+
if (button.name) {
|
|
1467
|
+
return {
|
|
1468
|
+
...button,
|
|
1469
|
+
paramsJson: typeof button.paramsJson === 'string'
|
|
1470
|
+
? button.paramsJson
|
|
1471
|
+
: JSON.stringify(button.params || {})
|
|
1472
|
+
};
|
|
1473
|
+
}
|
|
1474
|
+
if (button.url) {
|
|
1475
|
+
return {
|
|
1476
|
+
name: 'cta_url',
|
|
1477
|
+
paramsJson: JSON.stringify({
|
|
1478
|
+
display_text: label,
|
|
1479
|
+
url: button.url,
|
|
1480
|
+
merchant_url: button.merchantUrl || button.url
|
|
1481
|
+
})
|
|
1482
|
+
};
|
|
1483
|
+
}
|
|
1484
|
+
if (button.call || button.phoneNumber) {
|
|
1485
|
+
return {
|
|
1486
|
+
name: 'cta_call',
|
|
1487
|
+
paramsJson: JSON.stringify({ display_text: label, phone_number: button.call || button.phoneNumber })
|
|
1488
|
+
};
|
|
1489
|
+
}
|
|
1490
|
+
if (button.copy || button.copyCode) {
|
|
1491
|
+
return {
|
|
1492
|
+
name: 'cta_copy',
|
|
1493
|
+
paramsJson: JSON.stringify({ display_text: label, copy_code: button.copy || button.copyCode })
|
|
1494
|
+
};
|
|
1495
|
+
}
|
|
1496
|
+
const id = button.command || button.id || button.buttonId;
|
|
1497
|
+
if (!id) throw new Boom(`replyButton button ${index + 1} needs an id, command, or native-flow action`, { statusCode: 400 });
|
|
1498
|
+
return { text: label, id, ...(button.type != null ? { type: button.type } : {}) };
|
|
1499
|
+
};
|
|
1500
|
+
const location = options.location;
|
|
1501
|
+
const documentOptions = options.document && typeof options.document === 'object' ? options.document : {};
|
|
1502
|
+
const media = options.media ?? options.image ?? options.video ?? options.document?.url;
|
|
1503
|
+
const hasExplicitMedia = options.image != null || options.video != null || options.document != null || options.media != null;
|
|
1504
|
+
if (location && hasExplicitMedia) {
|
|
1505
|
+
throw new Boom('replyButton accepts one header attachment; choose either location or media', { statusCode: 400 });
|
|
1506
|
+
}
|
|
1507
|
+
if (hasExplicitMedia && media == null) {
|
|
1508
|
+
throw new Boom('replyButton media header requires an image, video, or document source', { statusCode: 400 });
|
|
1509
|
+
}
|
|
1510
|
+
const content = { buttons: buttons.map(normalizeButton) };
|
|
1511
|
+
if (options.footer !== undefined) content.footer = options.footer;
|
|
1512
|
+
if (options.title !== undefined) content.title = options.title;
|
|
1513
|
+
const text = options.text ?? options.caption ?? '';
|
|
1514
|
+
if (location) {
|
|
1515
|
+
content.location = {
|
|
1516
|
+
...location,
|
|
1517
|
+
...(location.description && !location.address ? { address: location.description } : {})
|
|
1518
|
+
};
|
|
1519
|
+
content.caption = text;
|
|
1520
|
+
}
|
|
1521
|
+
else if (hasExplicitMedia) {
|
|
1522
|
+
const source = media == null ? options.document : media;
|
|
1523
|
+
const sourceName = String(options.filename || documentOptions.filename || (typeof source === 'string' ? source : source?.url || '')).toLowerCase();
|
|
1524
|
+
const mimeType = options.mimetype || documentOptions.mimetype || source?.mimetype || '';
|
|
1525
|
+
const extension = sourceName.split(/[?#]/)[0].split('.').pop();
|
|
1526
|
+
let mediaType = options.mediaType || (options.document ? 'document' : options.video ? 'video' : undefined);
|
|
1527
|
+
if (!mediaType) {
|
|
1528
|
+
mediaType = mimeType.startsWith('video/') || ['mp4', 'mov', 'm4v', '3gp'].includes(extension) ? 'video' : 'image';
|
|
1529
|
+
}
|
|
1530
|
+
if (!['image', 'video', 'document'].includes(mediaType)) {
|
|
1531
|
+
throw new Boom('replyButton mediaType must be image, video, or document', { statusCode: 400 });
|
|
1532
|
+
}
|
|
1533
|
+
const mediaInput = typeof source === 'string' ? { url: source } : source;
|
|
1534
|
+
content[mediaType] = mediaInput;
|
|
1535
|
+
if (mediaType === 'document') {
|
|
1536
|
+
content.fileName = options.filename || documentOptions.filename || 'file';
|
|
1537
|
+
if (mimeType) content.mimetype = mimeType;
|
|
1538
|
+
}
|
|
1539
|
+
content.caption = text;
|
|
1540
|
+
}
|
|
1541
|
+
else {
|
|
1542
|
+
content.text = text;
|
|
1543
|
+
}
|
|
1544
|
+
const {
|
|
1545
|
+
text: _text, caption: _caption, footer: _footer, title: _title,
|
|
1546
|
+
location: _location, media: _media, image: _image, video: _video,
|
|
1547
|
+
document: _document, filename: _filename, mimetype: _mimetype,
|
|
1548
|
+
mediaType: _mediaType, sendOptions: nestedSendOptions = {},
|
|
1549
|
+
...transportOptions
|
|
1550
|
+
} = options;
|
|
1551
|
+
return socket.sendMessage(jid, content, {
|
|
1552
|
+
...transportOptions,
|
|
1553
|
+
...nestedSendOptions,
|
|
1554
|
+
...(quoted ? { quoted } : {})
|
|
1555
|
+
});
|
|
1556
|
+
},
|
|
1557
|
+
/** Send a motion photo from its video and optional still image/thumbnail. */
|
|
1558
|
+
sendPhotoLive: async (jid, content, quoted, options = {}) => {
|
|
1559
|
+
if (!jid) throw new Boom('sendPhotoLive requires a target JID', { statusCode: 400 });
|
|
1560
|
+
return sendLivePhoto(jid, content, quoted, options);
|
|
1561
|
+
},
|
|
1562
|
+
/** Send a file; `photo_live: true` pairs a still with its motion-video child. */
|
|
1563
|
+
sendFile: async (jid, media, filename = '', caption = '', quoted, options = {}) => {
|
|
1564
|
+
if (!jid) throw new Boom('sendFile requires a target JID', { statusCode: 400 });
|
|
1565
|
+
if (options.photo_live || options.photoLive) {
|
|
1566
|
+
return sendLivePhoto(jid, {
|
|
1567
|
+
video: media,
|
|
1568
|
+
image: options.image,
|
|
1569
|
+
thumbnail: options.thumbnail,
|
|
1570
|
+
videoThumbnail: options.videoThumbnail,
|
|
1571
|
+
caption,
|
|
1572
|
+
motionPhotoPresentationOffsetMs: options.motionPhotoPresentationOffsetMs ?? options.presentationOffsetMs
|
|
1573
|
+
}, quoted, options);
|
|
1574
|
+
}
|
|
1575
|
+
const sourceName = String(filename || options.fileName || (typeof media === 'string' ? media : media?.url || '')).toLowerCase();
|
|
1576
|
+
const extension = sourceName.split(/[?#]/)[0].split('.').pop();
|
|
1577
|
+
const mimeType = options.mimetype || media?.mimetype || '';
|
|
1578
|
+
const mediaType = options.mediaType || (options.document ? 'document' : mimeType.startsWith('image/') ? 'image' : mimeType.startsWith('video/') ? 'video' : mimeType.startsWith('audio/') ? 'audio' : ['jpg', 'jpeg', 'png', 'gif', 'webp', 'heic'].includes(extension) ? 'image' : ['mp4', 'mov', 'm4v', '3gp', 'webm'].includes(extension) ? 'video' : ['mp3', 'ogg', 'opus', 'wav', 'm4a', 'aac'].includes(extension) ? 'audio' : 'document');
|
|
1579
|
+
if (!['image', 'video', 'audio', 'document'].includes(mediaType)) {
|
|
1580
|
+
throw new Boom('sendFile mediaType must be image, video, audio, or document', { statusCode: 400 });
|
|
1581
|
+
}
|
|
1582
|
+
const source = typeof media === 'string' ? { url: media } : media;
|
|
1583
|
+
const message = {
|
|
1584
|
+
[mediaType]: source,
|
|
1585
|
+
caption,
|
|
1586
|
+
...(filename || options.fileName ? { fileName: filename || options.fileName } : {}),
|
|
1587
|
+
...(mimeType ? { mimetype: mimeType } : {}),
|
|
1588
|
+
...(mediaType === 'audio' && options.ptt ? { ptt: true } : {})
|
|
1589
|
+
};
|
|
1590
|
+
const { photo_live: _photoLive, photoLive: _photoLiveCamel, thumbnail: _thumbnail, ...sendOptions } = options;
|
|
1591
|
+
return socket.sendMessage(jid, message, {
|
|
1592
|
+
...sendOptions,
|
|
1593
|
+
...(quoted ? { quoted } : {})
|
|
1594
|
+
});
|
|
1595
|
+
},
|
|
1596
|
+
/** Send or edit a textual progress bar; pass messageKey to update in place. */
|
|
1597
|
+
sendProgress: async (jid, text, quotedOrOptions = {}, maybeOptions = undefined) => {
|
|
1598
|
+
if (!jid) throw new Boom('sendProgress requires a target JID', { statusCode: 400 });
|
|
1599
|
+
const hasQuotedSignature = !!(quotedOrOptions?.key && quotedOrOptions?.message);
|
|
1600
|
+
const quoted = hasQuotedSignature ? quotedOrOptions : undefined;
|
|
1601
|
+
const options = hasQuotedSignature ? (maybeOptions || {}) : (maybeOptions || quotedOrOptions || {});
|
|
1602
|
+
const progress = Number(options.progress ?? 0);
|
|
1603
|
+
if (!Number.isFinite(progress) || progress < 0 || progress > 100) {
|
|
1604
|
+
throw new Boom('sendProgress progress must be between 0 and 100', { statusCode: 400 });
|
|
1605
|
+
}
|
|
1606
|
+
const width = Math.max(4, Math.min(40, Math.floor(Number(options.width) || 12)));
|
|
1607
|
+
const percent = Math.round(progress);
|
|
1608
|
+
const filled = Math.round(width * percent / 100);
|
|
1609
|
+
const bar = `[${'█'.repeat(filled)}${'░'.repeat(width - filled)}] ${percent}%`;
|
|
1610
|
+
const content = { text: `${String(text || '')}${text ? '\n' : ''}${bar}` };
|
|
1611
|
+
const messageKey = options.messageKey || options.editKey;
|
|
1612
|
+
if (messageKey) content.edit = messageKey;
|
|
1613
|
+
const {
|
|
1614
|
+
progress: _progress, width: _width, messageKey: _messageKey, editKey: _editKey,
|
|
1615
|
+
sendOptions: nestedSendOptions = {}, ...sendOptions
|
|
1616
|
+
} = options;
|
|
1617
|
+
return socket.sendMessage(jid, content, {
|
|
1618
|
+
...sendOptions,
|
|
1619
|
+
...nestedSendOptions,
|
|
1620
|
+
...(quoted ? { quoted } : {})
|
|
1621
|
+
});
|
|
1622
|
+
},
|
|
1623
|
+
/** Send text with a custom external preview card (thumbnail, title, URL and attribution). */
|
|
1624
|
+
sendMessageModify: async (jid, text, quotedOrOptions = {}, maybeOptions = undefined) => {
|
|
1625
|
+
if (!jid) throw new Boom('sendMessageModify requires a target JID', { statusCode: 400 });
|
|
1626
|
+
const hasQuotedSignature = !!(quotedOrOptions?.key && quotedOrOptions?.message);
|
|
1627
|
+
const quoted = hasQuotedSignature ? quotedOrOptions : undefined;
|
|
1628
|
+
const options = hasQuotedSignature ? (maybeOptions || {}) : (maybeOptions || quotedOrOptions || {});
|
|
1629
|
+
const thumbnail = options.thumbnail;
|
|
1630
|
+
const thumbnailSource = typeof thumbnail === 'string' ? thumbnail : thumbnail?.url;
|
|
1631
|
+
const thumbnailUrl = thumbnailSource && /^https?:\/\//i.test(thumbnailSource)
|
|
1632
|
+
? thumbnailSource
|
|
1633
|
+
: options.thumbnailUrl || options.originalImageUrl;
|
|
1634
|
+
let thumbnailBuffer;
|
|
1635
|
+
if (Buffer.isBuffer(thumbnail) || thumbnail instanceof Uint8Array) {
|
|
1636
|
+
thumbnailBuffer = Buffer.from(thumbnail);
|
|
1637
|
+
}
|
|
1638
|
+
else if (typeof thumbnailSource === 'string' && !/^https?:\/\//i.test(thumbnailSource)) {
|
|
1639
|
+
try {
|
|
1640
|
+
thumbnailBuffer = (await extractImageThumb(thumbnailSource, 192)).buffer;
|
|
1641
|
+
}
|
|
1642
|
+
catch (error) {
|
|
1643
|
+
throw new Boom(`sendMessageModify could not read thumbnail: ${error.message}`, { statusCode: 400 });
|
|
1644
|
+
}
|
|
1645
|
+
}
|
|
1646
|
+
const externalAdReply = {
|
|
1647
|
+
title: options.title || '',
|
|
1648
|
+
body: options.description || options.body || '',
|
|
1649
|
+
mediaType: thumbnailBuffer || thumbnailUrl ? 1 : 0,
|
|
1650
|
+
...(thumbnailBuffer ? { thumbnail: thumbnailBuffer } : {}),
|
|
1651
|
+
...(thumbnailUrl ? { thumbnailUrl, originalImageUrl: thumbnailUrl } : {}),
|
|
1652
|
+
...(options.url ? { mediaUrl: options.url, sourceUrl: options.url } : {}),
|
|
1653
|
+
showAdAttribution: options.ads ?? false,
|
|
1654
|
+
renderLargerThumbnail: options.largeThumb ?? options.largeThumbnail ?? true
|
|
1655
|
+
};
|
|
1656
|
+
const message = {
|
|
1657
|
+
text: String(text ?? ''),
|
|
1658
|
+
externalAdReply,
|
|
1659
|
+
...(options.icon ? { favicon: typeof options.icon === 'string' ? { url: options.icon } : options.icon } : {})
|
|
1660
|
+
};
|
|
1661
|
+
const {
|
|
1662
|
+
title: _title, description: _description, body: _body, url: _url,
|
|
1663
|
+
thumbnail: _thumbnailValue, thumbnailUrl: _thumbnailUrl,
|
|
1664
|
+
originalImageUrl: _originalImageUrl, icon: _icon,
|
|
1665
|
+
ads: _ads, largeThumb: _largeThumb, largeThumbnail: _largeThumbnail,
|
|
1666
|
+
ratio: _ratio, type: _type, sendOptions: nestedSendOptions = {},
|
|
1667
|
+
...transportOptions
|
|
1668
|
+
} = options;
|
|
1669
|
+
return socket.sendMessage(jid, message, {
|
|
1670
|
+
...transportOptions,
|
|
1671
|
+
...nestedSendOptions,
|
|
1672
|
+
...(quoted ? { quoted } : {})
|
|
1673
|
+
});
|
|
1674
|
+
},
|
|
1675
|
+
/** Compatibility alias for sendMessageModify. */
|
|
1676
|
+
sendMessageModifyV2: async (jid, text, quotedOrOptions = {}, maybeOptions = undefined) =>
|
|
1677
|
+
socket.sendMessageModify(jid, text, quotedOrOptions, maybeOptions),
|
|
1359
1678
|
sendLatex: async (jid, quoted, options = {}) => {
|
|
1360
1679
|
const { message, messageId } = generateLatexContent(quoted, { expressions: [], ...options });
|
|
1361
1680
|
const fullMsg = generateWAMessageFromContent(jid, message, {
|
|
@@ -1471,7 +1790,7 @@ export const makeMessagesSocket = (config) => {
|
|
|
1471
1790
|
await relayMessage(jid, message, relayOptions);
|
|
1472
1791
|
return msgId;
|
|
1473
1792
|
},
|
|
1474
|
-
// Additive
|
|
1793
|
+
// Additive New-compatible AI-rich helpers. Existing Gen4/table/grid/carousel APIs remain unchanged.
|
|
1475
1794
|
sendRichMedia: async (jid, content = {}, quoted, options = {}) => {
|
|
1476
1795
|
const contentMessage = prepareRichResponseMessage({ ...content, noDonation: options.noDonation ?? true });
|
|
1477
1796
|
const generated = generateWAMessageFromContent(jid, contentMessage, {
|
|
@@ -1484,6 +1803,13 @@ export const makeMessagesSocket = (config) => {
|
|
|
1484
1803
|
await relayRichMessage(jid, generated, options);
|
|
1485
1804
|
return { ...generated, messageId: generated.key.id };
|
|
1486
1805
|
},
|
|
1806
|
+
/**
|
|
1807
|
+
* Send native Plogme rich media with the additive New compatibility field
|
|
1808
|
+
* compatibility sections enabled. The native serializer is retained.
|
|
1809
|
+
*/
|
|
1810
|
+
sendNewRichMedia: async (jid, content = {}, quoted, options = {}) => {
|
|
1811
|
+
return socket.sendRichMedia(jid, { ...content, compatibility: 'both' }, quoted, options);
|
|
1812
|
+
},
|
|
1487
1813
|
/**
|
|
1488
1814
|
* Send a native AI image/video generation card. The returned messageId
|
|
1489
1815
|
* is required by updateRichGeneration() for an in-place edit.
|
|
@@ -1576,7 +1902,7 @@ export const makeMessagesSocket = (config) => {
|
|
|
1576
1902
|
* section present in `content`. Missing sections are intentionally
|
|
1577
1903
|
* ignored by prepareRichResponseMessage instead of causing a partial
|
|
1578
1904
|
* response to fail. This is the stable entry point for Plogme/CODY
|
|
1579
|
-
* callers that may receive optional text, links, media, products,
|
|
1905
|
+
* callers that may receive optional text, HTML, links, media, products,
|
|
1580
1906
|
* reels, tables, code, latex, or suggestion data.
|
|
1581
1907
|
*/
|
|
1582
1908
|
sendPlogmeMessage: async (jid, content = {}, quoted, options = {}) => {
|
|
@@ -1807,6 +2133,10 @@ export const makeMessagesSocket = (config) => {
|
|
|
1807
2133
|
},
|
|
1808
2134
|
sendMessage: async (jid, content, options = {}) => {
|
|
1809
2135
|
const userJid = authState.creds.me.id;
|
|
2136
|
+
const pollValues = content?.poll?.values;
|
|
2137
|
+
if (Array.isArray(pollValues) && pollValues.some(value => value && typeof value === 'object' && value.image)) {
|
|
2138
|
+
return sendImagePoll(jid, content.poll, options);
|
|
2139
|
+
}
|
|
1810
2140
|
if (content?.groupStatus === true && !isJidGroup(jid)) {
|
|
1811
2141
|
throw new Boom('groupStatus requires a valid group JID', { statusCode: 400 });
|
|
1812
2142
|
}
|
|
@@ -3025,6 +3355,27 @@ export const makeMessagesSocket = (config) => {
|
|
|
3025
3355
|
return fullMsg;
|
|
3026
3356
|
};
|
|
3027
3357
|
|
|
3358
|
+
/**
|
|
3359
|
+
* Send a native group status. `content.private` adds WhatsApp's
|
|
3360
|
+
* statusAudienceMetadata without creating a group message or changing
|
|
3361
|
+
* group membership.
|
|
3362
|
+
*/
|
|
3363
|
+
socket.sendGroupStatus = async (jid, content = {}, options = {}) => {
|
|
3364
|
+
if (!jid || !isJidGroup(jid)) {
|
|
3365
|
+
throw new Boom('sendGroupStatus requires a valid group JID', { statusCode: 400 });
|
|
3366
|
+
}
|
|
3367
|
+
if (!content || typeof content !== 'object' || Array.isArray(content)) {
|
|
3368
|
+
throw new Boom('sendGroupStatus content must be a message object', { statusCode: 400 });
|
|
3369
|
+
}
|
|
3370
|
+
const { private: privateAudience, ...statusContent } = content;
|
|
3371
|
+
const audience = privateAudience ?? options.private;
|
|
3372
|
+
return socket.sendMessage(
|
|
3373
|
+
jid,
|
|
3374
|
+
{ ...statusContent, groupStatus: true, ...(audience !== undefined ? { private: audience } : {}) },
|
|
3375
|
+
options
|
|
3376
|
+
);
|
|
3377
|
+
};
|
|
3378
|
+
|
|
3028
3379
|
|
|
3029
3380
|
/**
|
|
3030
3381
|
* Sends an HTML message — renders raw HTML inside the chat bubble.
|