@badzz88/baileys 8.5.7 → 8.5.8
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 +337 -1055
- package/WAProto/WAProto.proto +284 -264
- package/WAProto/index.js +5 -5
- package/engine-requirements.js +7 -15
- package/lib/Defaults/index.js +130 -187
- package/lib/Signal/Group/ciphertext-message.js +11 -14
- package/lib/Signal/Group/group-session-builder.js +29 -91
- package/lib/Signal/Group/group_cipher.js +81 -88
- package/lib/Signal/Group/index.js +12 -136
- package/lib/Signal/Group/keyhelper.js +15 -70
- package/lib/Signal/Group/sender-chain-key.js +25 -31
- package/lib/Signal/Group/sender-key-distribution-message.js +62 -65
- package/lib/Signal/Group/sender-key-message.js +65 -68
- package/lib/Signal/Group/sender-key-name.js +41 -43
- package/lib/Signal/Group/sender-key-record.js +40 -43
- package/lib/Signal/Group/sender-key-state.js +83 -96
- package/lib/Signal/Group/sender-message-key.js +25 -29
- package/lib/Signal/libsignal.js +425 -453
- package/lib/Signal/lid-mapping.js +276 -259
- package/lib/Socket/Client/index.js +3 -30
- package/lib/Socket/Client/types.js +10 -12
- package/lib/Socket/Client/websocket.js +53 -61
- package/lib/Socket/business.js +379 -422
- package/lib/Socket/chats.js +1193 -1816
- package/lib/Socket/communities.js +431 -549
- package/lib/Socket/graphql.js +672 -612
- package/lib/Socket/groups.js +374 -764
- package/lib/Socket/index.js +17 -38
- package/lib/Socket/interop.js +417 -503
- package/lib/Socket/messages-recv.js +1915 -2441
- package/lib/Socket/messages-send.js +1213 -1630
- package/lib/Socket/mex.js +9 -15
- package/lib/Socket/newsletter.js +747 -808
- package/lib/Socket/privacy.js +310 -441
- package/lib/Socket/socket.js +1025 -1022
- package/lib/Socket/username.js +8 -15
- package/lib/Store/index.js +10 -36
- package/lib/Store/make-cache-manager-store.js +80 -85
- package/lib/Store/make-in-memory-store.js +231 -591
- package/lib/Store/make-ordered-dictionary.js +72 -78
- package/lib/Store/object-repository.js +28 -25
- package/lib/Types/Auth.js +2 -38
- package/lib/Types/Bussines.js +2 -2
- package/lib/Types/Call.js +2 -2
- package/lib/Types/Chat.js +8 -4
- package/lib/Types/Contact.js +2 -2
- package/lib/Types/Events.js +2 -2
- package/lib/Types/GroupMetadata.js +2 -2
- package/lib/Types/Label.js +24 -26
- package/lib/Types/LabelAssociation.js +6 -8
- package/lib/Types/Message.js +11 -95
- package/lib/Types/Mex.js +111 -112
- package/lib/Types/Product.js +2 -2
- package/lib/Types/Signal.js +2 -2
- package/lib/Types/Socket.js +3 -2
- package/lib/Types/State.js +56 -70
- package/lib/Types/USync.js +2 -2
- package/lib/Types/index.js +26 -55
- package/lib/Utils/auth-utils.js +288 -292
- package/lib/Utils/browser-utils.js +47 -113
- package/lib/Utils/business.js +224 -240
- package/lib/Utils/chat-utils.js +869 -1205
- package/lib/Utils/companion-reg-client-utils.js +34 -41
- package/lib/Utils/crypto.js +107 -144
- package/lib/Utils/decode-wa-message.js +308 -518
- package/lib/Utils/event-buffer.js +611 -596
- package/lib/Utils/generics.js +355 -515
- package/lib/Utils/history.js +134 -244
- package/lib/Utils/identity-change-handler.js +49 -51
- package/lib/Utils/index.js +23 -57
- package/lib/Utils/link-preview.js +77 -135
- package/lib/Utils/logger.js +3 -9
- package/lib/Utils/lt-hash.js +6 -37
- package/lib/Utils/make-mutex.js +33 -36
- package/lib/Utils/message-composer.js +233 -439
- package/lib/Utils/message-retry-manager.js +260 -265
- package/lib/Utils/messages-media.js +829 -855
- package/lib/Utils/messages.js +961 -2528
- package/lib/Utils/noise-handler.js +200 -195
- package/lib/Utils/offline-node-processor.js +33 -35
- package/lib/Utils/pre-key-manager.js +102 -103
- package/lib/Utils/process-message.js +560 -978
- package/lib/Utils/reporting-utils.js +253 -257
- package/lib/Utils/signal.js +195 -218
- package/lib/Utils/stanza-ack.js +29 -31
- package/lib/Utils/sticker.js +109 -144
- package/lib/Utils/sync-action-utils.js +45 -50
- package/lib/Utils/tc-token-utils.js +139 -137
- package/lib/Utils/use-multi-file-auth-state.js +109 -109
- package/lib/Utils/validate-connection.js +202 -218
- package/lib/WABinary/constants.js +1299 -1302
- package/lib/WABinary/decode.js +262 -343
- package/lib/WABinary/encode.js +4 -12
- package/lib/WABinary/generic-utils.js +187 -223
- package/lib/WABinary/index.js +6 -33
- package/lib/WABinary/jid-utils.js +88 -351
- package/lib/WABinary/types.js +2 -2
- package/lib/WAM/BinaryInfo.js +9 -12
- package/lib/WAM/constants.js +22853 -39486
- package/lib/WAM/encode.js +140 -132
- package/lib/WAM/index.js +4 -31
- package/lib/WAUSync/Protocols/USyncBotProfileProtocol.js +21 -23
- package/lib/WAUSync/Protocols/USyncBusinessProtocol.js +9 -9
- package/lib/WAUSync/Protocols/USyncContactProtocol.js +7 -7
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +10 -10
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +7 -7
- package/lib/WAUSync/Protocols/USyncFeatureProtocol.js +11 -12
- package/lib/WAUSync/Protocols/USyncLIDProtocol.js +4 -5
- package/lib/WAUSync/Protocols/USyncPictureProtocol.js +7 -7
- package/lib/WAUSync/Protocols/USyncSidelistProtocol.js +7 -8
- package/lib/WAUSync/Protocols/USyncStatusProtocol.js +7 -7
- package/lib/WAUSync/Protocols/USyncTextStatusProtocol.js +8 -8
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +7 -7
- package/lib/WAUSync/Protocols/index.js +12 -39
- package/lib/WAUSync/USyncQuery.js +67 -49
- package/lib/WAUSync/USyncUser.js +11 -5
- package/lib/WAUSync/index.js +3 -31
- package/lib/index.js +15 -48
- package/package.json +129 -99
- package/LICENSE +0 -21
- package/lib/Defaults/phonenumber-mcc.json +0 -223
- package/lib/Socket/aigroups.js +0 -240
- package/lib/Socket/interactive-handler.js +0 -522
- package/lib/Socket/managed-account.js +0 -183
- package/lib/Socket/registration.js +0 -427
- package/lib/Socket/text-router.js +0 -83
- package/lib/Types/Newsletter.js +0 -121
- package/lib/Utils/command-loader.d.ts +0 -31
- package/lib/Utils/command-loader.js +0 -100
- package/lib/Utils/consumer-application.js +0 -107
- package/lib/Utils/curve25519-js.js +0 -275
- package/lib/Utils/group-history.js +0 -60
- package/lib/Utils/jid-display-normalization.js +0 -218
- package/lib/Utils/meta-ai-msmsg.js +0 -262
- package/lib/Utils/native-bridge.js +0 -82
- package/lib/Utils/session-pool.d.ts +0 -16
- package/lib/Utils/session-pool.js +0 -94
- package/lib/Utils/sticker.d.ts +0 -17
- package/lib/Utils/view-once-cache.d.ts +0 -9
- package/lib/Utils/view-once-cache.js +0 -79
- package/lib/Utils/voip-rekey.js +0 -22
- package/lib/antiban.js +0 -4637
package/lib/Utils/messages.js
CHANGED
|
@@ -1,73 +1,60 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
exports.generateWAMessage =
|
|
15
|
-
exports.generateWAMessageFromContent =
|
|
16
|
-
exports.generateWAMessageContent =
|
|
17
|
-
exports.hasNonNullishProperty =
|
|
18
|
-
exports.generateForwardMessageContent =
|
|
19
|
-
exports.prepareDisappearingMessageSettingContent =
|
|
20
|
-
exports.prepareWAMessageMedia =
|
|
21
|
-
exports.generateLinkPreviewIfRequired =
|
|
22
|
-
exports.extractUrlFromText =
|
|
23
|
-
void 0
|
|
24
|
-
exports.getAggregateVotesInPollMessage = getAggregateVotesInPollMessage
|
|
25
|
-
exports.getAggregateResponsesInEventMessage = getAggregateResponsesInEventMessage
|
|
26
|
-
const boom_1 = require('@hapi/boom')
|
|
27
|
-
const crypto_1 = require('crypto')
|
|
28
|
-
const fs_1 = require('fs')
|
|
29
|
-
const index_js_1 = require('../../WAProto/index.js')
|
|
30
|
-
const WAProto_1 = require('../../WAProto/index.js')
|
|
31
|
-
const Defaults_1 = require('../Defaults')
|
|
32
|
-
const Types_1 = require('../Types')
|
|
33
|
-
const WABinary_1 = require('../WABinary')
|
|
34
|
-
const crypto_2 = require('./crypto')
|
|
35
|
-
const generics_1 = require('./generics')
|
|
36
|
-
const messages_media_1 = require('./messages-media')
|
|
37
|
-
const reporting_utils_1 = require('./reporting-utils')
|
|
38
|
-
const jid_display_normalization_1 = require('./jid-display-normalization')
|
|
1
|
+
import { Boom } from '@hapi/boom';
|
|
2
|
+
import { randomUUID, randomBytes } from 'crypto';
|
|
3
|
+
import { promises as fs } from 'fs';
|
|
4
|
+
import {} from 'stream';
|
|
5
|
+
import { proto } from '../../WAProto/index.js';
|
|
6
|
+
import { CALL_AUDIO_PREFIX, CALL_VIDEO_PREFIX, MEDIA_KEYS, URL_REGEX, WA_DEFAULT_EPHEMERAL } from '../Defaults/index.js';
|
|
7
|
+
import { WAMessageStatus, WAProto } from '../Types/index.js';
|
|
8
|
+
import { isJidGroup, isJidNewsletter, isJidStatusBroadcast, jidNormalizedUser } from '../WABinary/index.js';
|
|
9
|
+
import { sha256 } from './crypto.js';
|
|
10
|
+
import { generateMessageIDV2, getKeyAuthor, unixTimestampSeconds } from './generics.js';
|
|
11
|
+
import { buildZipArchive, downloadContentFromMessage, encryptedStream, generateThumbnail, getAudioDuration, getAudioWaveform, getRawMediaUploadData, resolveStickerBuffer } from './messages-media.js';
|
|
12
|
+
import { makeSticker } from './sticker.js';
|
|
13
|
+
import { shouldIncludeReportingToken } from './reporting-utils.js';
|
|
39
14
|
const MIMETYPE_MAP = {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
}
|
|
15
|
+
image: 'image/jpeg',
|
|
16
|
+
video: 'video/mp4',
|
|
17
|
+
document: 'application/pdf',
|
|
18
|
+
audio: 'audio/ogg; codecs=opus',
|
|
19
|
+
sticker: 'image/webp',
|
|
20
|
+
'product-catalog-image': 'image/jpeg'
|
|
21
|
+
};
|
|
22
|
+
const RAW_PROTO_MESSAGE_KEYS = [
|
|
23
|
+
'conversation', 'senderKeyDistributionMessage', 'imageMessage', 'contactMessage', 'locationMessage',
|
|
24
|
+
'extendedTextMessage', 'documentMessage', 'audioMessage', 'videoMessage', 'call', 'chat', 'protocolMessage',
|
|
25
|
+
'contactsArrayMessage', 'highlyStructuredMessage', 'fastRatchetKeySenderKeyDistributionMessage',
|
|
26
|
+
'sendPaymentMessage', 'liveLocationMessage', 'requestPaymentMessage', 'declinePaymentRequestMessage',
|
|
27
|
+
'cancelPaymentRequestMessage', 'templateMessage', 'stickerMessage', 'groupInviteMessage',
|
|
28
|
+
'templateButtonReplyMessage', 'productMessage', 'deviceSentMessage', 'messageContextInfo', 'listMessage',
|
|
29
|
+
'viewOnceMessage', 'orderMessage', 'listResponseMessage', 'ephemeralMessage', 'invoiceMessage',
|
|
30
|
+
'buttonsMessage', 'buttonsResponseMessage', 'paymentInviteMessage', 'interactiveMessage', 'reactionMessage',
|
|
31
|
+
'stickerSyncRmrMessage', 'interactiveResponseMessage', 'pollCreationMessage', 'pollUpdateMessage',
|
|
32
|
+
'keepInChatMessage', 'documentWithCaptionMessage', 'requestPhoneNumberMessage', 'viewOnceMessageV2',
|
|
33
|
+
'encReactionMessage', 'editedMessage', 'viewOnceMessageV2Extension', 'pollCreationMessageV2',
|
|
34
|
+
'scheduledCallCreationMessage', 'groupMentionedMessage', 'pinInChatMessage', 'pollCreationMessageV3',
|
|
35
|
+
'scheduledCallEditMessage', 'ptvMessage', 'botInvokeMessage', 'callLogMesssage', 'messageHistoryBundle',
|
|
36
|
+
'encCommentMessage', 'bcallMessage', 'lottieStickerMessage', 'eventMessage', 'encEventResponseMessage',
|
|
37
|
+
'commentMessage', 'newsletterAdminInviteMessage', 'placeholderMessage', 'secretEncryptedMessage',
|
|
38
|
+
'albumMessage', 'eventCoverImage', 'stickerPackMessage', 'statusMentionMessage', 'pollResultSnapshotMessage',
|
|
39
|
+
'pollCreationOptionImageMessage', 'associatedChildMessage', 'groupStatusMentionMessage',
|
|
40
|
+
'pollCreationMessageV4', 'statusAddYours', 'groupStatusMessage', 'richResponseMessage',
|
|
41
|
+
'statusNotificationMessage', 'limitSharingMessage', 'botTaskMessage', 'questionMessage',
|
|
42
|
+
'messageHistoryNotice', 'groupStatusMessageV2', 'botForwardedMessage', 'statusQuestionAnswerMessage',
|
|
43
|
+
'questionReplyMessage', 'questionResponseMessage', 'statusQuotedMessage', 'statusStickerInteractionMessage',
|
|
44
|
+
'pollCreationMessageV5', 'newsletterFollowerInviteMessageV2', 'pollResultSnapshotMessageV3',
|
|
45
|
+
'newsletterAdminProfileMessage', 'newsletterAdminProfileMessageV2', 'spoilerMessage',
|
|
46
|
+
'pollCreationMessageV6', 'conditionalRevealMessage', 'pollAddOptionMessage', 'eventInviteMessage',
|
|
47
|
+
'groupRootKeyShare', 'paymentReminderMessage', 'splitPaymentMessage', 'newsletterAdminProfileStatusMessage',
|
|
48
|
+
'rootSecretDistributeMessage'
|
|
49
|
+
];
|
|
47
50
|
const MessageTypeProto = {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// Input payloads can carry protobuf media message keys (e.g. imageMessage).
|
|
56
|
-
const MEDIA_MESSAGE_TYPE_ALIASES = {
|
|
57
|
-
imageMessage: 'image',
|
|
58
|
-
videoMessage: 'video',
|
|
59
|
-
audioMessage: 'audio',
|
|
60
|
-
documentMessage: 'document',
|
|
61
|
-
stickerMessage: 'sticker',
|
|
62
|
-
// PTV = push-to-video (video note) payload.
|
|
63
|
-
ptvMessage: 'video'
|
|
64
|
-
}
|
|
65
|
-
const MEDIA_MESSAGE_TYPE_ALIAS_KEYS = Object.keys(MEDIA_MESSAGE_TYPE_ALIASES)
|
|
66
|
-
const hasMediaPayload = message =>
|
|
67
|
-
Defaults_1.MEDIA_KEYS.some(key => key in message) || MEDIA_MESSAGE_TYPE_ALIAS_KEYS.some(key => key in message)
|
|
68
|
-
|
|
69
|
-
const ButtonType = WAProto_1.proto.Message.ButtonsMessage.HeaderType
|
|
70
|
-
|
|
51
|
+
image: WAProto.Message.ImageMessage,
|
|
52
|
+
video: WAProto.Message.VideoMessage,
|
|
53
|
+
audio: WAProto.Message.AudioMessage,
|
|
54
|
+
sticker: WAProto.Message.StickerMessage,
|
|
55
|
+
document: WAProto.Message.DocumentMessage
|
|
56
|
+
};
|
|
57
|
+
const ButtonType = proto.Message.ButtonsMessage.HeaderType;
|
|
71
58
|
const RICH_RESPONSE_CODE_KEYWORDS = new Set([
|
|
72
59
|
'break',
|
|
73
60
|
'case',
|
|
@@ -195,333 +182,251 @@ const tokenizeCode = code => {
|
|
|
195
182
|
}
|
|
196
183
|
return merged
|
|
197
184
|
}
|
|
198
|
-
|
|
199
185
|
/**
|
|
200
186
|
* Uses a regex to test whether the string contains a URL, and returns the URL if it does.
|
|
201
187
|
* @param text eg. hello https://google.com
|
|
202
188
|
* @returns the URL, eg. https://google.com
|
|
203
189
|
*/
|
|
204
|
-
const extractUrlFromText = text => text.match(
|
|
205
|
-
|
|
206
|
-
const
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
}
|
|
232
|
-
const prepareWAMessageMedia = async (message, options) => {
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
const content = {
|
|
405
|
-
ephemeralMessage: {
|
|
406
|
-
message: {
|
|
407
|
-
protocolMessage: {
|
|
408
|
-
type: WAProto_1.proto.Message.ProtocolMessage.Type.EPHEMERAL_SETTING,
|
|
409
|
-
ephemeralExpiration
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
}
|
|
413
|
-
}
|
|
414
|
-
return WAProto_1.proto.Message.fromObject(content)
|
|
415
|
-
}
|
|
416
|
-
exports.prepareDisappearingMessageSettingContent = prepareDisappearingMessageSettingContent
|
|
190
|
+
export const extractUrlFromText = (text) => text.match(URL_REGEX)?.[0];
|
|
191
|
+
export const generateLinkPreviewIfRequired = async (text, getUrlInfo, logger) => {
|
|
192
|
+
const url = extractUrlFromText(text);
|
|
193
|
+
if (!!getUrlInfo && url) {
|
|
194
|
+
try {
|
|
195
|
+
const urlInfo = await getUrlInfo(url);
|
|
196
|
+
return urlInfo;
|
|
197
|
+
}
|
|
198
|
+
catch (error) {
|
|
199
|
+
// ignore if fails
|
|
200
|
+
logger?.warn({ trace: error.stack }, 'url generation failed');
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
};
|
|
204
|
+
const assertColor = async (color) => {
|
|
205
|
+
let assertedColor;
|
|
206
|
+
if (typeof color === 'number') {
|
|
207
|
+
assertedColor = color > 0 ? color : 0xffffffff + Number(color) + 1;
|
|
208
|
+
}
|
|
209
|
+
else {
|
|
210
|
+
let hex = color.trim().replace('#', '');
|
|
211
|
+
if (hex.length <= 6) {
|
|
212
|
+
hex = 'FF' + hex.padStart(6, '0');
|
|
213
|
+
}
|
|
214
|
+
assertedColor = parseInt(hex, 16);
|
|
215
|
+
return assertedColor;
|
|
216
|
+
}
|
|
217
|
+
};
|
|
218
|
+
export const prepareWAMessageMedia = async (message, options) => {
|
|
219
|
+
const logger = options.logger;
|
|
220
|
+
let mediaType;
|
|
221
|
+
for (const key of MEDIA_KEYS) {
|
|
222
|
+
if (key in message) {
|
|
223
|
+
mediaType = key;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
if (!mediaType) {
|
|
227
|
+
throw new Boom('Invalid media type', { statusCode: 400 });
|
|
228
|
+
}
|
|
229
|
+
const uploadData = {
|
|
230
|
+
...message,
|
|
231
|
+
media: message[mediaType]
|
|
232
|
+
};
|
|
233
|
+
delete uploadData[mediaType];
|
|
234
|
+
// check if cacheable + generate cache key
|
|
235
|
+
const cacheableKey = typeof uploadData.media === 'object' &&
|
|
236
|
+
'url' in uploadData.media &&
|
|
237
|
+
!!uploadData.media.url &&
|
|
238
|
+
!!options.mediaCache &&
|
|
239
|
+
mediaType + ':' + uploadData.media.url.toString();
|
|
240
|
+
if (mediaType === 'document' && !uploadData.fileName) {
|
|
241
|
+
uploadData.fileName = 'file';
|
|
242
|
+
}
|
|
243
|
+
if (!uploadData.mimetype) {
|
|
244
|
+
uploadData.mimetype = MIMETYPE_MAP[mediaType];
|
|
245
|
+
}
|
|
246
|
+
if (cacheableKey) {
|
|
247
|
+
const mediaBuff = await options.mediaCache.get(cacheableKey);
|
|
248
|
+
if (mediaBuff) {
|
|
249
|
+
logger?.debug({ cacheableKey }, 'got media cache hit');
|
|
250
|
+
const obj = proto.Message.decode(mediaBuff);
|
|
251
|
+
const key = `${mediaType}Message`;
|
|
252
|
+
Object.assign(obj[key], { ...uploadData, media: undefined });
|
|
253
|
+
return obj;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
const isNewsletter = !!options.jid && isJidNewsletter(options.jid);
|
|
257
|
+
if (isNewsletter) {
|
|
258
|
+
logger?.info({ key: cacheableKey }, 'Preparing raw media for newsletter');
|
|
259
|
+
const { filePath, fileSha256, fileLength } = await getRawMediaUploadData(uploadData.media, options.mediaTypeOverride || mediaType, logger);
|
|
260
|
+
const fileSha256B64 = fileSha256.toString('base64');
|
|
261
|
+
const { mediaUrl, directPath } = await options.upload(filePath, {
|
|
262
|
+
fileEncSha256B64: fileSha256B64,
|
|
263
|
+
mediaType: mediaType,
|
|
264
|
+
timeoutMs: options.mediaUploadTimeoutMs
|
|
265
|
+
});
|
|
266
|
+
await fs.unlink(filePath);
|
|
267
|
+
const obj = WAProto.Message.fromObject({
|
|
268
|
+
// todo: add more support here
|
|
269
|
+
[`${mediaType}Message`]: MessageTypeProto[mediaType].fromObject({
|
|
270
|
+
url: mediaUrl,
|
|
271
|
+
directPath,
|
|
272
|
+
fileSha256,
|
|
273
|
+
fileLength,
|
|
274
|
+
...uploadData,
|
|
275
|
+
media: undefined
|
|
276
|
+
})
|
|
277
|
+
});
|
|
278
|
+
if (uploadData.ptv) {
|
|
279
|
+
obj.ptvMessage = obj.videoMessage;
|
|
280
|
+
delete obj.videoMessage;
|
|
281
|
+
}
|
|
282
|
+
if (obj.stickerMessage) {
|
|
283
|
+
obj.stickerMessage.stickerSentTs = Date.now();
|
|
284
|
+
}
|
|
285
|
+
if (cacheableKey) {
|
|
286
|
+
logger?.debug({ cacheableKey }, 'set cache');
|
|
287
|
+
await options.mediaCache.set(cacheableKey, WAProto.Message.encode(obj).finish());
|
|
288
|
+
}
|
|
289
|
+
return obj;
|
|
290
|
+
}
|
|
291
|
+
const requiresDurationComputation = mediaType === 'audio' && typeof uploadData.seconds === 'undefined';
|
|
292
|
+
const requiresThumbnailComputation = (mediaType === 'image' || mediaType === 'video') && typeof uploadData['jpegThumbnail'] === 'undefined';
|
|
293
|
+
const requiresWaveformProcessing = mediaType === 'audio' && uploadData.ptt === true && typeof uploadData.waveform === 'undefined';
|
|
294
|
+
const requiresAudioBackground = options.backgroundColor && mediaType === 'audio' && uploadData.ptt === true;
|
|
295
|
+
const requiresOriginalForSomeProcessing = requiresDurationComputation || requiresThumbnailComputation;
|
|
296
|
+
const { mediaKey, encFilePath, originalFilePath, fileEncSha256, fileSha256, fileLength } = await encryptedStream(uploadData.media, options.mediaTypeOverride || mediaType, {
|
|
297
|
+
logger,
|
|
298
|
+
saveOriginalFileIfRequired: requiresOriginalForSomeProcessing,
|
|
299
|
+
opts: options.options
|
|
300
|
+
});
|
|
301
|
+
const fileEncSha256B64 = fileEncSha256.toString('base64');
|
|
302
|
+
const [{ mediaUrl, directPath }] = await Promise.all([
|
|
303
|
+
(async () => {
|
|
304
|
+
const result = await options.upload(encFilePath, {
|
|
305
|
+
fileEncSha256B64,
|
|
306
|
+
mediaType,
|
|
307
|
+
timeoutMs: options.mediaUploadTimeoutMs
|
|
308
|
+
});
|
|
309
|
+
logger?.debug({ mediaType, cacheableKey }, 'uploaded media');
|
|
310
|
+
return result;
|
|
311
|
+
})(),
|
|
312
|
+
(async () => {
|
|
313
|
+
try {
|
|
314
|
+
if (requiresThumbnailComputation) {
|
|
315
|
+
const { thumbnail, originalImageDimensions } = await generateThumbnail(originalFilePath, mediaType, options);
|
|
316
|
+
uploadData.jpegThumbnail = thumbnail;
|
|
317
|
+
if (!uploadData.width && originalImageDimensions) {
|
|
318
|
+
uploadData.width = originalImageDimensions.width;
|
|
319
|
+
uploadData.height = originalImageDimensions.height;
|
|
320
|
+
logger?.debug('set dimensions');
|
|
321
|
+
}
|
|
322
|
+
logger?.debug('generated thumbnail');
|
|
323
|
+
}
|
|
324
|
+
if (requiresDurationComputation) {
|
|
325
|
+
uploadData.seconds = await getAudioDuration(originalFilePath);
|
|
326
|
+
logger?.debug('computed audio duration');
|
|
327
|
+
}
|
|
328
|
+
if (requiresWaveformProcessing) {
|
|
329
|
+
uploadData.waveform = await getAudioWaveform(originalFilePath, logger);
|
|
330
|
+
logger?.debug('processed waveform');
|
|
331
|
+
}
|
|
332
|
+
if (requiresAudioBackground) {
|
|
333
|
+
uploadData.backgroundArgb = await assertColor(options.backgroundColor);
|
|
334
|
+
logger?.debug('computed backgroundColor audio status');
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
catch (error) {
|
|
338
|
+
logger?.warn({ trace: error.stack }, 'failed to obtain extra info');
|
|
339
|
+
}
|
|
340
|
+
})()
|
|
341
|
+
]).finally(async () => {
|
|
342
|
+
try {
|
|
343
|
+
await fs.unlink(encFilePath);
|
|
344
|
+
if (originalFilePath) {
|
|
345
|
+
await fs.unlink(originalFilePath);
|
|
346
|
+
}
|
|
347
|
+
logger?.debug('removed tmp files');
|
|
348
|
+
}
|
|
349
|
+
catch (error) {
|
|
350
|
+
logger?.warn('failed to remove tmp file');
|
|
351
|
+
}
|
|
352
|
+
});
|
|
353
|
+
const obj = WAProto.Message.fromObject({
|
|
354
|
+
[`${mediaType}Message`]: MessageTypeProto[mediaType].fromObject({
|
|
355
|
+
url: mediaUrl,
|
|
356
|
+
directPath,
|
|
357
|
+
mediaKey,
|
|
358
|
+
fileEncSha256,
|
|
359
|
+
fileSha256,
|
|
360
|
+
fileLength,
|
|
361
|
+
mediaKeyTimestamp: unixTimestampSeconds(),
|
|
362
|
+
...uploadData,
|
|
363
|
+
media: undefined
|
|
364
|
+
})
|
|
365
|
+
});
|
|
366
|
+
if (uploadData.ptv) {
|
|
367
|
+
obj.ptvMessage = obj.videoMessage;
|
|
368
|
+
delete obj.videoMessage;
|
|
369
|
+
}
|
|
370
|
+
if (cacheableKey) {
|
|
371
|
+
logger?.debug({ cacheableKey }, 'set cache');
|
|
372
|
+
await options.mediaCache.set(cacheableKey, WAProto.Message.encode(obj).finish());
|
|
373
|
+
}
|
|
374
|
+
return obj;
|
|
375
|
+
};
|
|
376
|
+
export const prepareDisappearingMessageSettingContent = (ephemeralExpiration) => {
|
|
377
|
+
ephemeralExpiration = ephemeralExpiration || 0;
|
|
378
|
+
const content = {
|
|
379
|
+
ephemeralMessage: {
|
|
380
|
+
message: {
|
|
381
|
+
protocolMessage: {
|
|
382
|
+
type: WAProto.Message.ProtocolMessage.Type.EPHEMERAL_SETTING,
|
|
383
|
+
ephemeralExpiration
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
};
|
|
388
|
+
return WAProto.Message.fromObject(content);
|
|
389
|
+
};
|
|
417
390
|
/**
|
|
418
391
|
* Generate forwarded message content like WA does
|
|
419
392
|
* @param message the message to forward
|
|
420
393
|
* @param options.forceForward will show the message as forwarded even if it is from you
|
|
421
394
|
*/
|
|
422
|
-
const generateForwardMessageContent = (message, forceForward) => {
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
const hasNonNullishProperty = (message, key) => {
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
)
|
|
455
|
-
}
|
|
456
|
-
exports.hasNonNullishProperty = hasNonNullishProperty
|
|
395
|
+
export const generateForwardMessageContent = (message, forceForward) => {
|
|
396
|
+
let content = message.message;
|
|
397
|
+
if (!content) {
|
|
398
|
+
throw new Boom('no content in message', { statusCode: 400 });
|
|
399
|
+
}
|
|
400
|
+
// hacky copy
|
|
401
|
+
content = normalizeMessageContent(content);
|
|
402
|
+
content = proto.Message.decode(proto.Message.encode(content).finish());
|
|
403
|
+
let key = Object.keys(content)[0];
|
|
404
|
+
let score = content?.[key]?.contextInfo?.forwardingScore || 0;
|
|
405
|
+
score += message.key.fromMe && !forceForward ? 0 : 1;
|
|
406
|
+
if (key === 'conversation') {
|
|
407
|
+
content.extendedTextMessage = { text: content[key] };
|
|
408
|
+
delete content.conversation;
|
|
409
|
+
key = 'extendedTextMessage';
|
|
410
|
+
}
|
|
411
|
+
const key_ = content?.[key];
|
|
412
|
+
if (score > 0) {
|
|
413
|
+
key_.contextInfo = { forwardingScore: score, isForwarded: true };
|
|
414
|
+
}
|
|
415
|
+
else {
|
|
416
|
+
key_.contextInfo = {};
|
|
417
|
+
}
|
|
418
|
+
return content;
|
|
419
|
+
};
|
|
420
|
+
export const hasNonNullishProperty = (message, key) => {
|
|
421
|
+
return (typeof message === 'object' &&
|
|
422
|
+
message !== null &&
|
|
423
|
+
key in message &&
|
|
424
|
+
message[key] !== null &&
|
|
425
|
+
message[key] !== undefined);
|
|
426
|
+
};
|
|
457
427
|
function hasOptionalProperty(obj, key) {
|
|
458
|
-
|
|
459
|
-
}
|
|
460
|
-
const normalizeEarFields = ear => {
|
|
461
|
-
const result = { ...ear }
|
|
462
|
-
const applyAlias = (fromKey, toKey) => {
|
|
463
|
-
if (result[fromKey] !== undefined && result[toKey] === undefined) result[toKey] = result[fromKey]
|
|
464
|
-
}
|
|
465
|
-
applyAlias('thumbnail_url', 'thumbnailUrl')
|
|
466
|
-
applyAlias('thumbnailUrl', 'thumbnail')
|
|
467
|
-
applyAlias('source_url', 'sourceUrl')
|
|
468
|
-
applyAlias('media_type', 'mediaType')
|
|
469
|
-
applyAlias('show_ad_attribution', 'showAdAttribution')
|
|
470
|
-
applyAlias('render_larger_thumbnail', 'renderLargerThumbnail')
|
|
471
|
-
if (result.thumbnail && !result.jpegThumbnail) result.jpegThumbnail = result.thumbnail
|
|
472
|
-
if (result.largeThumbnail !== undefined && result.renderLargerThumbnail === undefined)
|
|
473
|
-
result.renderLargerThumbnail = result.largeThumbnail
|
|
474
|
-
if (result.url && !result.sourceUrl) result.sourceUrl = result.url
|
|
475
|
-
delete result.thumbnail
|
|
476
|
-
delete result.largeThumbnail
|
|
477
|
-
delete result.url
|
|
478
|
-
delete result.thumbnail_url
|
|
479
|
-
delete result.source_url
|
|
480
|
-
delete result.media_type
|
|
481
|
-
delete result.show_ad_attribution
|
|
482
|
-
delete result.render_larger_thumbnail
|
|
483
|
-
return result
|
|
484
|
-
}
|
|
485
|
-
const normalizeQuickReplyButton = button => {
|
|
486
|
-
var _a
|
|
487
|
-
if (button.name && typeof button.name === 'string') {
|
|
488
|
-
return {
|
|
489
|
-
name: button.name,
|
|
490
|
-
buttonParamsJson:
|
|
491
|
-
typeof button.buttonParamsJson === 'string'
|
|
492
|
-
? button.buttonParamsJson
|
|
493
|
-
: JSON.stringify(button.buttonParamsJson || {})
|
|
494
|
-
}
|
|
495
|
-
}
|
|
496
|
-
if (button.type === 4 && button.nativeFlowInfo) {
|
|
497
|
-
const { name, paramsJson } = button.nativeFlowInfo
|
|
498
|
-
return {
|
|
499
|
-
name: name || 'quick_reply',
|
|
500
|
-
buttonParamsJson: typeof paramsJson === 'string' ? paramsJson : JSON.stringify(paramsJson || {})
|
|
501
|
-
}
|
|
502
|
-
}
|
|
503
|
-
const buttonTextObject = button.buttonText && typeof button.buttonText === 'object' ? button.buttonText : undefined
|
|
504
|
-
const displayTextCandidates = [
|
|
505
|
-
button.text,
|
|
506
|
-
button.displayText,
|
|
507
|
-
button.display_text,
|
|
508
|
-
typeof button.buttonText === 'string' ? button.buttonText : undefined,
|
|
509
|
-
buttonTextObject === null || buttonTextObject === void 0 ? void 0 : buttonTextObject.displayText,
|
|
510
|
-
buttonTextObject === null || buttonTextObject === void 0 ? void 0 : buttonTextObject.display_text
|
|
511
|
-
]
|
|
512
|
-
const displayText = displayTextCandidates.find(value => typeof value === 'string' && value.length > 0) || ''
|
|
513
|
-
const id =
|
|
514
|
-
button.buttonId || button.id || ((_a = button.buttonParamsJson) === null || _a === void 0 ? void 0 : _a.id) || ''
|
|
515
|
-
return {
|
|
516
|
-
name: 'quick_reply',
|
|
517
|
-
buttonParamsJson: JSON.stringify({
|
|
518
|
-
display_text: displayText,
|
|
519
|
-
id
|
|
520
|
-
})
|
|
521
|
-
}
|
|
428
|
+
return typeof obj === 'object' && obj !== null && key in obj && obj[key] !== null;
|
|
522
429
|
}
|
|
523
|
-
const asciiDecode = arr => arr.map(e => String.fromCharCode(e)).join('')
|
|
524
|
-
|
|
525
430
|
const applyContextInfoAndMentions = (interactiveMessage, message) => {
|
|
526
431
|
if ('contextInfo' in message && !!message.contextInfo) {
|
|
527
432
|
interactiveMessage.contextInfo = message.contextInfo
|
|
@@ -533,563 +438,11 @@ const applyContextInfoAndMentions = (interactiveMessage, message) => {
|
|
|
533
438
|
}
|
|
534
439
|
}
|
|
535
440
|
}
|
|
536
|
-
const
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
stickerMessage: {
|
|
542
|
-
...(stickerPrep === null || stickerPrep === void 0 ? void 0 : stickerPrep.stickerMessage),
|
|
543
|
-
contextInfo: paymentPayload === null || paymentPayload === void 0 ? void 0 : paymentPayload.contextInfo
|
|
544
|
-
}
|
|
545
|
-
}
|
|
546
|
-
} else if (
|
|
547
|
-
typeof (paymentPayload === null || paymentPayload === void 0 ? void 0 : paymentPayload.note) === 'string'
|
|
548
|
-
) {
|
|
549
|
-
notes = {
|
|
550
|
-
extendedTextMessage: {
|
|
551
|
-
text: paymentPayload.note,
|
|
552
|
-
contextInfo: paymentPayload === null || paymentPayload === void 0 ? void 0 : paymentPayload.contextInfo
|
|
553
|
-
}
|
|
554
|
-
}
|
|
555
|
-
} else if (
|
|
556
|
-
(paymentPayload === null || paymentPayload === void 0 ? void 0 : paymentPayload.noteMessage) &&
|
|
557
|
-
typeof paymentPayload.noteMessage === 'object'
|
|
558
|
-
) {
|
|
559
|
-
const noteKeys = Object.keys(paymentPayload.noteMessage)
|
|
560
|
-
const allowedNoteMessageKeys = ['extendedTextMessage', 'stickerMessage']
|
|
561
|
-
const hasOnlyAllowedKeys = noteKeys.length > 0 && noteKeys.every(key => allowedNoteMessageKeys.includes(key))
|
|
562
|
-
if (!noteKeys.length || !hasOnlyAllowedKeys) {
|
|
563
|
-
throw new boom_1.Boom('Invalid payment noteMessage', { statusCode: 400 })
|
|
564
|
-
}
|
|
565
|
-
notes = paymentPayload.noteMessage
|
|
566
|
-
} else {
|
|
567
|
-
notes = { extendedTextMessage: { text: fallbackText } }
|
|
568
|
-
}
|
|
569
|
-
return notes
|
|
570
|
-
}
|
|
571
|
-
|
|
572
|
-
const generateWAMessageContent = async (message, options) => {
|
|
573
|
-
var _a, _b
|
|
574
|
-
let m = {}
|
|
575
|
-
const hasCaptionWithoutMedia = 'caption' in message && !hasMediaPayload(message)
|
|
576
|
-
const hasCaptionContainer =
|
|
577
|
-
('groupStatus' in message && !!message.groupStatus) || ('viewOnce' in message && !!message.viewOnce)
|
|
578
|
-
if ((0, exports.hasNonNullishProperty)(message, 'text')) {
|
|
579
|
-
const extContent = { text: message.text }
|
|
580
|
-
let urlInfo = message.linkPreview
|
|
581
|
-
if (typeof urlInfo === 'undefined') {
|
|
582
|
-
urlInfo = await (0, exports.generateLinkPreviewIfRequired)(message.text, options.getUrlInfo, options.logger)
|
|
583
|
-
}
|
|
584
|
-
if (urlInfo) {
|
|
585
|
-
extContent.matchedText = urlInfo['matched-text']
|
|
586
|
-
extContent.jpegThumbnail = urlInfo.jpegThumbnail
|
|
587
|
-
extContent.description = urlInfo.description
|
|
588
|
-
extContent.title = urlInfo.title
|
|
589
|
-
extContent.previewType = 0
|
|
590
|
-
const img = urlInfo.highQualityThumbnail
|
|
591
|
-
if (img) {
|
|
592
|
-
extContent.thumbnailDirectPath = img.directPath
|
|
593
|
-
extContent.mediaKey = img.mediaKey
|
|
594
|
-
extContent.mediaKeyTimestamp = img.mediaKeyTimestamp
|
|
595
|
-
extContent.thumbnailWidth = img.width
|
|
596
|
-
extContent.thumbnailHeight = img.height
|
|
597
|
-
extContent.thumbnailSha256 = img.fileSha256
|
|
598
|
-
extContent.thumbnailEncSha256 = img.fileEncSha256
|
|
599
|
-
}
|
|
600
|
-
}
|
|
601
|
-
if (options.backgroundColor) {
|
|
602
|
-
extContent.backgroundArgb = await assertColor(options.backgroundColor)
|
|
603
|
-
}
|
|
604
|
-
if (options.font) {
|
|
605
|
-
extContent.font = options.font
|
|
606
|
-
}
|
|
607
|
-
if (
|
|
608
|
-
options.jid &&
|
|
609
|
-
(0, WABinary_1.isInteropUser)(options.jid) &&
|
|
610
|
-
!options.backgroundColor &&
|
|
611
|
-
!options.font &&
|
|
612
|
-
!urlInfo
|
|
613
|
-
) {
|
|
614
|
-
m.conversation = message.text
|
|
615
|
-
} else {
|
|
616
|
-
m.extendedTextMessage = extContent
|
|
617
|
-
}
|
|
618
|
-
} else if ((0, exports.hasNonNullishProperty)(message, 'contacts')) {
|
|
619
|
-
const contactLen = message.contacts.contacts.length
|
|
620
|
-
if (!contactLen) {
|
|
621
|
-
throw new boom_1.Boom('require atleast 1 contact', { statusCode: 400 })
|
|
622
|
-
}
|
|
623
|
-
if (contactLen === 1) {
|
|
624
|
-
m.contactMessage = WAProto_1.proto.Message.ContactMessage.create(message.contacts.contacts[0])
|
|
625
|
-
} else {
|
|
626
|
-
m.contactsArrayMessage = WAProto_1.proto.Message.ContactsArrayMessage.create(message.contacts)
|
|
627
|
-
}
|
|
628
|
-
} else if ((0, exports.hasNonNullishProperty)(message, 'location')) {
|
|
629
|
-
m.locationMessage = WAProto_1.proto.Message.LocationMessage.create(message.location)
|
|
630
|
-
} else if ((0, exports.hasNonNullishProperty)(message, 'react')) {
|
|
631
|
-
if (!message.react.senderTimestampMs) {
|
|
632
|
-
message.react.senderTimestampMs = Date.now()
|
|
633
|
-
}
|
|
634
|
-
m.reactionMessage = WAProto_1.proto.Message.ReactionMessage.create(message.react)
|
|
635
|
-
} else if ((0, exports.hasNonNullishProperty)(message, 'delete')) {
|
|
636
|
-
m.protocolMessage = {
|
|
637
|
-
key: message.delete,
|
|
638
|
-
type: WAProto_1.proto.Message.ProtocolMessage.Type.REVOKE
|
|
639
|
-
}
|
|
640
|
-
} else if ((0, exports.hasNonNullishProperty)(message, 'forward')) {
|
|
641
|
-
m = (0, exports.generateForwardMessageContent)(message.forward, message.force)
|
|
642
|
-
} else if ((0, exports.hasNonNullishProperty)(message, 'disappearingMessagesInChat')) {
|
|
643
|
-
const exp =
|
|
644
|
-
typeof message.disappearingMessagesInChat === 'boolean'
|
|
645
|
-
? message.disappearingMessagesInChat
|
|
646
|
-
? Defaults_1.WA_DEFAULT_EPHEMERAL
|
|
647
|
-
: 0
|
|
648
|
-
: message.disappearingMessagesInChat
|
|
649
|
-
m = (0, exports.prepareDisappearingMessageSettingContent)(exp)
|
|
650
|
-
} else if ((0, exports.hasNonNullishProperty)(message, 'groupInvite')) {
|
|
651
|
-
m.groupInviteMessage = {}
|
|
652
|
-
m.groupInviteMessage.inviteCode = message.groupInvite.inviteCode
|
|
653
|
-
m.groupInviteMessage.inviteExpiration = message.groupInvite.inviteExpiration
|
|
654
|
-
m.groupInviteMessage.caption = message.groupInvite.text
|
|
655
|
-
m.groupInviteMessage.groupJid = message.groupInvite.jid
|
|
656
|
-
m.groupInviteMessage.groupName = message.groupInvite.subject
|
|
657
|
-
//TODO: use built-in interface and get disappearing mode info etc.
|
|
658
|
-
//TODO: cache / use store!?
|
|
659
|
-
if (options.getProfilePicUrl) {
|
|
660
|
-
const pfpUrl = await options.getProfilePicUrl(message.groupInvite.jid, 'preview')
|
|
661
|
-
if (pfpUrl) {
|
|
662
|
-
const resp = await fetch(pfpUrl, { method: 'GET', dispatcher: options?.options?.dispatcher })
|
|
663
|
-
if (resp.ok) {
|
|
664
|
-
const buf = Buffer.from(await resp.arrayBuffer())
|
|
665
|
-
m.groupInviteMessage.jpegThumbnail = buf
|
|
666
|
-
}
|
|
667
|
-
}
|
|
668
|
-
}
|
|
669
|
-
} else if ((0, exports.hasNonNullishProperty)(message, 'pin')) {
|
|
670
|
-
m.pinInChatMessage = {}
|
|
671
|
-
m.messageContextInfo = {}
|
|
672
|
-
m.pinInChatMessage.key = message.pin
|
|
673
|
-
m.pinInChatMessage.type = message.type
|
|
674
|
-
m.pinInChatMessage.senderTimestampMs = Date.now()
|
|
675
|
-
m.messageContextInfo.messageAddOnDurationInSecs = message.type === 1 ? message.time || 86400 : 0
|
|
676
|
-
} else if ((0, exports.hasNonNullishProperty)(message, 'buttonReply')) {
|
|
677
|
-
switch (message.type) {
|
|
678
|
-
case 'template':
|
|
679
|
-
m.templateButtonReplyMessage = {
|
|
680
|
-
selectedDisplayText: message.buttonReply.displayText,
|
|
681
|
-
selectedId: message.buttonReply.id,
|
|
682
|
-
selectedIndex: message.buttonReply.index
|
|
683
|
-
}
|
|
684
|
-
break
|
|
685
|
-
case 'plain':
|
|
686
|
-
m.buttonsResponseMessage = {
|
|
687
|
-
selectedButtonId: message.buttonReply.id,
|
|
688
|
-
selectedDisplayText: message.buttonReply.displayText,
|
|
689
|
-
type: index_js_1.proto.Message.ButtonsResponseMessage.Type.DISPLAY_TEXT
|
|
690
|
-
}
|
|
691
|
-
break
|
|
692
|
-
case 'interactive':
|
|
693
|
-
m.interactiveResponseMessage = {
|
|
694
|
-
body: {
|
|
695
|
-
text: message.buttonReply.displayText,
|
|
696
|
-
format: WAProto_1.proto.Message.InteractiveResponseMessage.Body.Format.EXTENSIONS_1
|
|
697
|
-
},
|
|
698
|
-
nativeFlowResponseMessage: {
|
|
699
|
-
name: message.buttonReply.nativeFlows.name,
|
|
700
|
-
paramsJson: message.buttonReply.nativeFlows.paramsJson,
|
|
701
|
-
version: message.buttonReply.nativeFlows.version
|
|
702
|
-
}
|
|
703
|
-
}
|
|
704
|
-
break
|
|
705
|
-
case 'list':
|
|
706
|
-
m.listResponseMessage = {
|
|
707
|
-
title: message.buttonReply.title,
|
|
708
|
-
description: message.buttonReply.description,
|
|
709
|
-
singleSelectReply: {
|
|
710
|
-
selectedRowId: message.buttonReply.rowId
|
|
711
|
-
},
|
|
712
|
-
listType: WAProto_1.proto.Message.ListResponseMessage.ListType.SINGLE_SELECT
|
|
713
|
-
}
|
|
714
|
-
break
|
|
715
|
-
}
|
|
716
|
-
} else if (hasOptionalProperty(message, 'ptv') && message.ptv) {
|
|
717
|
-
const { videoMessage } = await (0, exports.prepareWAMessageMedia)({ video: message.video }, options)
|
|
718
|
-
m.ptvMessage = videoMessage
|
|
719
|
-
} else if ((0, exports.hasNonNullishProperty)(message, 'product')) {
|
|
720
|
-
const { imageMessage } = await (0, exports.prepareWAMessageMedia)({ image: message.product.productImage }, options)
|
|
721
|
-
m.productMessage = WAProto_1.proto.Message.ProductMessage.create({
|
|
722
|
-
...message,
|
|
723
|
-
product: {
|
|
724
|
-
...message.product,
|
|
725
|
-
productImage: imageMessage
|
|
726
|
-
}
|
|
727
|
-
})
|
|
728
|
-
} else if ((0, exports.hasNonNullishProperty)(message, 'listReply')) {
|
|
729
|
-
m.listResponseMessage = { ...message.listReply }
|
|
730
|
-
} else if ((0, exports.hasNonNullishProperty)(message, 'event')) {
|
|
731
|
-
m.eventMessage = {}
|
|
732
|
-
const startTime = Math.floor(message.event.startDate.getTime() / 1000)
|
|
733
|
-
if (message.event.call && options.getCallLink) {
|
|
734
|
-
const token = await options.getCallLink(message.event.call, { startTime })
|
|
735
|
-
m.eventMessage.joinLink =
|
|
736
|
-
(message.event.call === 'audio' ? Defaults_1.CALL_AUDIO_PREFIX : Defaults_1.CALL_VIDEO_PREFIX) + token
|
|
737
|
-
}
|
|
738
|
-
m.messageContextInfo = {
|
|
739
|
-
// encKey
|
|
740
|
-
messageSecret: message.event.messageSecret || (0, crypto_1.randomBytes)(32)
|
|
741
|
-
}
|
|
742
|
-
m.eventMessage.name = message.event.name
|
|
743
|
-
m.eventMessage.description = message.event.description
|
|
744
|
-
m.eventMessage.startTime = startTime
|
|
745
|
-
m.eventMessage.endTime = message.event.endDate ? message.event.endDate.getTime() / 1000 : undefined
|
|
746
|
-
m.eventMessage.isCanceled = message.event.isCancelled ?? false
|
|
747
|
-
m.eventMessage.extraGuestsAllowed = message.event.extraGuestsAllowed
|
|
748
|
-
m.eventMessage.isScheduleCall = message.event.isScheduleCall ?? false
|
|
749
|
-
m.eventMessage.location = message.event.location
|
|
750
|
-
} else if ((0, exports.hasNonNullishProperty)(message, 'poll')) {
|
|
751
|
-
;(_a = message.poll).selectableCount || (_a.selectableCount = 0)
|
|
752
|
-
;(_b = message.poll).toAnnouncementGroup || (_b.toAnnouncementGroup = false)
|
|
753
|
-
if (!Array.isArray(message.poll.values)) {
|
|
754
|
-
throw new boom_1.Boom('Invalid poll values', { statusCode: 400 })
|
|
755
|
-
}
|
|
756
|
-
if (message.poll.selectableCount < 0 || message.poll.selectableCount > message.poll.values.length) {
|
|
757
|
-
throw new boom_1.Boom(`poll.selectableCount in poll should be >= 0 and <= ${message.poll.values.length}`, {
|
|
758
|
-
statusCode: 400
|
|
759
|
-
})
|
|
760
|
-
}
|
|
761
|
-
m.messageContextInfo = {
|
|
762
|
-
messageSecret: message.poll.messageSecret || (0, crypto_1.randomBytes)(32)
|
|
763
|
-
}
|
|
764
|
-
const isQuiz = message.poll.type === 'quiz' || message.poll.pollType === WAProto_1.proto.Message.PollType.QUIZ
|
|
765
|
-
const pollTypeEnum = WAProto_1.proto.Message.PollType
|
|
766
|
-
const pollCreationMessage = {
|
|
767
|
-
name: message.poll.name,
|
|
768
|
-
selectableOptionsCount: message.poll.selectableCount,
|
|
769
|
-
options: message.poll.values.map(optionName => ({ optionName })),
|
|
770
|
-
pollType: isQuiz ? pollTypeEnum.QUIZ : pollTypeEnum.POLL,
|
|
771
|
-
...(isQuiz && message.poll.correctAnswer ? { correctAnswer: { optionName: message.poll.correctAnswer } } : {}),
|
|
772
|
-
...(message.poll.endTime
|
|
773
|
-
? {
|
|
774
|
-
endTime:
|
|
775
|
-
message.poll.endTime instanceof Date
|
|
776
|
-
? Math.floor(message.poll.endTime.getTime() / 1000)
|
|
777
|
-
: Number(message.poll.endTime)
|
|
778
|
-
}
|
|
779
|
-
: {}),
|
|
780
|
-
...(message.poll.hideParticipantName !== undefined
|
|
781
|
-
? { hideParticipantName: !!message.poll.hideParticipantName }
|
|
782
|
-
: {}),
|
|
783
|
-
...(message.poll.allowAddOption !== undefined ? { allowAddOption: !!message.poll.allowAddOption } : {})
|
|
784
|
-
}
|
|
785
|
-
if (message.poll.version === 6 || message.poll.v6) {
|
|
786
|
-
m.pollCreationMessageV6 = pollCreationMessage
|
|
787
|
-
} else if (message.poll.version === 5 || message.poll.v5) {
|
|
788
|
-
m.pollCreationMessageV5 = pollCreationMessage
|
|
789
|
-
} else if (message.poll.toAnnouncementGroup) {
|
|
790
|
-
// poll v2 is for community announcement groups (single select and multiple)
|
|
791
|
-
m.pollCreationMessageV2 = pollCreationMessage
|
|
792
|
-
} else {
|
|
793
|
-
if (message.poll.selectableCount === 1) {
|
|
794
|
-
//poll v3 is for single select polls
|
|
795
|
-
m.pollCreationMessageV3 = pollCreationMessage
|
|
796
|
-
} else {
|
|
797
|
-
// poll for multiple choice polls
|
|
798
|
-
m.pollCreationMessage = pollCreationMessage
|
|
799
|
-
}
|
|
800
|
-
}
|
|
801
|
-
} else if ('inviteAdmin' in message) {
|
|
802
|
-
m.newsletterAdminInviteMessage = {}
|
|
803
|
-
m.newsletterAdminInviteMessage.inviteExpiration = message.inviteAdmin.inviteExpiration
|
|
804
|
-
m.newsletterAdminInviteMessage.caption = message.inviteAdmin.text
|
|
805
|
-
m.newsletterAdminInviteMessage.newsletterJid = message.inviteAdmin.jid
|
|
806
|
-
m.newsletterAdminInviteMessage.newsletterName = message.inviteAdmin.subject
|
|
807
|
-
m.newsletterAdminInviteMessage.jpegThumbnail = message.inviteAdmin.thumbnail
|
|
808
|
-
} else if ('requestPayment' in message || 'requestPaymentMessage' in message) {
|
|
809
|
-
if ('requestPayment' in message && 'requestPaymentMessage' in message) {
|
|
810
|
-
throw new boom_1.Boom('Use either requestPayment or requestPaymentMessage, not both', { statusCode: 400 })
|
|
811
|
-
}
|
|
812
|
-
const requestPayment = message.requestPayment || message.requestPaymentMessage
|
|
813
|
-
const notes = await buildPaymentNoteMessage(requestPayment, options)
|
|
814
|
-
const amountValue = requestPayment.amount ?? requestPayment.amount1000
|
|
815
|
-
const amount1000Raw =
|
|
816
|
-
typeof (amountValue === null || amountValue === void 0 ? void 0 : amountValue.toNumber) === 'function'
|
|
817
|
-
? amountValue.toNumber()
|
|
818
|
-
: Number(amountValue)
|
|
819
|
-
const amount1000 = Number.isFinite(amount1000Raw) ? Math.round(amount1000Raw) : amount1000Raw
|
|
820
|
-
const currencyCodeIso4217 = requestPayment.currency ?? requestPayment.currencyCodeIso4217
|
|
821
|
-
const requestFrom = requestPayment.from ?? requestPayment.requestFrom ?? options.recipientJid
|
|
822
|
-
const missingFields = []
|
|
823
|
-
if (amountValue === undefined) missingFields.push('amount/amount1000')
|
|
824
|
-
if (currencyCodeIso4217 === undefined) missingFields.push('currency/currencyCodeIso4217')
|
|
825
|
-
if (requestFrom === undefined) missingFields.push('from/requestFrom')
|
|
826
|
-
if (missingFields.length) {
|
|
827
|
-
throw new boom_1.Boom(`Invalid requestPayment fields: missing ${missingFields.join(', ')}`, { statusCode: 400 })
|
|
828
|
-
}
|
|
829
|
-
if (
|
|
830
|
-
typeof amount1000 !== 'number' ||
|
|
831
|
-
!Number.isFinite(amount1000) ||
|
|
832
|
-
!Number.isInteger(amount1000) ||
|
|
833
|
-
amount1000 <= 0
|
|
834
|
-
) {
|
|
835
|
-
throw new boom_1.Boom('Invalid requestPayment fields: amount/amount1000 must be a positive integer', {
|
|
836
|
-
statusCode: 400
|
|
837
|
-
})
|
|
838
|
-
}
|
|
839
|
-
const bg = requestPayment.background
|
|
840
|
-
m.requestPaymentMessage = WAProto_1.proto.Message.RequestPaymentMessage.fromObject({
|
|
841
|
-
expiryTimestamp: requestPayment.expiry ?? requestPayment.expiryTimestamp,
|
|
842
|
-
amount1000,
|
|
843
|
-
currencyCodeIso4217,
|
|
844
|
-
requestFrom,
|
|
845
|
-
noteMessage: notes,
|
|
846
|
-
...(bg != null ? { background: bg } : {})
|
|
847
|
-
})
|
|
848
|
-
} else if ('sendPayment' in message || 'sendPaymentMessage' in message) {
|
|
849
|
-
if ('sendPayment' in message && 'sendPaymentMessage' in message) {
|
|
850
|
-
throw new boom_1.Boom('Use either sendPayment or sendPaymentMessage, not both', { statusCode: 400 })
|
|
851
|
-
}
|
|
852
|
-
const sendPayment = message.sendPayment || message.sendPaymentMessage
|
|
853
|
-
const notes = await buildPaymentNoteMessage(sendPayment, options, message.text || '')
|
|
854
|
-
const requestMessageKey = sendPayment.requestMessageKey ?? sendPayment.requestKey ?? sendPayment.request
|
|
855
|
-
if (!requestMessageKey) {
|
|
856
|
-
throw new boom_1.Boom('Invalid sendPayment fields: missing requestMessageKey/requestKey/request', {
|
|
857
|
-
statusCode: 400
|
|
858
|
-
})
|
|
859
|
-
}
|
|
860
|
-
m.sendPaymentMessage = WAProto_1.proto.Message.SendPaymentMessage.fromObject({
|
|
861
|
-
noteMessage: notes,
|
|
862
|
-
requestMessageKey,
|
|
863
|
-
...(sendPayment.background != null ? { background: sendPayment.background } : {}),
|
|
864
|
-
...(sendPayment.transactionData != null ? { transactionData: sendPayment.transactionData } : {})
|
|
865
|
-
})
|
|
866
|
-
} else if ('declinePaymentRequest' in message || 'declinePaymentRequestMessage' in message) {
|
|
867
|
-
if ('declinePaymentRequest' in message && 'declinePaymentRequestMessage' in message) {
|
|
868
|
-
throw new boom_1.Boom('Use either declinePaymentRequest or declinePaymentRequestMessage, not both', {
|
|
869
|
-
statusCode: 400
|
|
870
|
-
})
|
|
871
|
-
}
|
|
872
|
-
const declinePayment = message.declinePaymentRequest || message.declinePaymentRequestMessage
|
|
873
|
-
const key = (declinePayment === null || declinePayment === void 0 ? void 0 : declinePayment.key) || declinePayment
|
|
874
|
-
if (!key) {
|
|
875
|
-
throw new boom_1.Boom('Invalid declinePaymentRequest fields: missing key', { statusCode: 400 })
|
|
876
|
-
}
|
|
877
|
-
m.declinePaymentRequestMessage = WAProto_1.proto.Message.DeclinePaymentRequestMessage.fromObject({ key })
|
|
878
|
-
} else if ('cancelPaymentRequest' in message || 'cancelPaymentRequestMessage' in message) {
|
|
879
|
-
if ('cancelPaymentRequest' in message && 'cancelPaymentRequestMessage' in message) {
|
|
880
|
-
throw new boom_1.Boom('Use either cancelPaymentRequest or cancelPaymentRequestMessage, not both', {
|
|
881
|
-
statusCode: 400
|
|
882
|
-
})
|
|
883
|
-
}
|
|
884
|
-
const cancelPayment = message.cancelPaymentRequest || message.cancelPaymentRequestMessage
|
|
885
|
-
const key = (cancelPayment === null || cancelPayment === void 0 ? void 0 : cancelPayment.key) || cancelPayment
|
|
886
|
-
if (!key) {
|
|
887
|
-
throw new boom_1.Boom('Invalid cancelPaymentRequest fields: missing key', { statusCode: 400 })
|
|
888
|
-
}
|
|
889
|
-
m.cancelPaymentRequestMessage = WAProto_1.proto.Message.CancelPaymentRequestMessage.fromObject({ key })
|
|
890
|
-
} else if ('requestPaymentFrom' in message && !!message.requestPaymentFrom) {
|
|
891
|
-
const noteText = message.text || ''
|
|
892
|
-
m.requestPaymentMessage = WAProto_1.proto.Message.RequestPaymentMessage.fromObject({
|
|
893
|
-
requestFrom: message.requestPaymentFrom,
|
|
894
|
-
noteMessage: { extendedTextMessage: { text: noteText } }
|
|
895
|
-
})
|
|
896
|
-
} else if ('invoiceNote' in message) {
|
|
897
|
-
const preparedInvoice = await (0, exports.prepareWAMessageMedia)(message, options)
|
|
898
|
-
const mediaType = Object.keys(preparedInvoice)[0]
|
|
899
|
-
const mediaMsg = preparedInvoice[mediaType] || {}
|
|
900
|
-
m.invoiceMessage = WAProto_1.proto.Message.InvoiceMessage.fromObject({
|
|
901
|
-
note: message.invoiceNote,
|
|
902
|
-
token: message.invoiceToken || '',
|
|
903
|
-
attachmentType: mediaType === 'imageMessage' ? 1 : 0,
|
|
904
|
-
attachmentMimetype: mediaMsg.mimetype,
|
|
905
|
-
attachmentMediaKey: mediaMsg.mediaKey,
|
|
906
|
-
attachmentMediaKeyTimestamp: mediaMsg.mediaKeyTimestamp,
|
|
907
|
-
attachmentFileSha256: mediaMsg.fileSha256,
|
|
908
|
-
attachmentFileEncSha256: mediaMsg.fileEncSha256,
|
|
909
|
-
attachmentDirectPath: mediaMsg.directPath,
|
|
910
|
-
attachmentJpegThumbnail: mediaMsg.jpegThumbnail
|
|
911
|
-
})
|
|
912
|
-
} else if ('orderText' in message) {
|
|
913
|
-
m.orderMessage = WAProto_1.proto.Message.OrderMessage.fromObject({
|
|
914
|
-
message: message.orderText,
|
|
915
|
-
thumbnail: message.thumbnail,
|
|
916
|
-
status: message.orderStatus || 1,
|
|
917
|
-
surface: message.orderSurface || 1
|
|
918
|
-
})
|
|
919
|
-
} else if ('paymentInviteServiceType' in message) {
|
|
920
|
-
m.paymentInviteMessage = {
|
|
921
|
-
serviceType: message.paymentInviteServiceType,
|
|
922
|
-
expiryTimestamp: message.paymentInviteExpiry
|
|
923
|
-
}
|
|
924
|
-
} else if ((0, exports.hasNonNullishProperty)(message, 'sharePhoneNumber')) {
|
|
925
|
-
m.protocolMessage = {
|
|
926
|
-
type: index_js_1.proto.Message.ProtocolMessage.Type.SHARE_PHONE_NUMBER
|
|
927
|
-
}
|
|
928
|
-
} else if ((0, exports.hasNonNullishProperty)(message, 'requestPhoneNumber')) {
|
|
929
|
-
m.requestPhoneNumberMessage = {}
|
|
930
|
-
} else if ((0, exports.hasNonNullishProperty)(message, 'limitSharing')) {
|
|
931
|
-
m.protocolMessage = {
|
|
932
|
-
type: index_js_1.proto.Message.ProtocolMessage.Type.LIMIT_SHARING,
|
|
933
|
-
limitSharing: {
|
|
934
|
-
sharingLimited: message.limitSharing === true,
|
|
935
|
-
trigger: 1,
|
|
936
|
-
limitSharingSettingTimestamp: Date.now(),
|
|
937
|
-
initiatedByMe: true
|
|
938
|
-
}
|
|
939
|
-
}
|
|
940
|
-
} else if ('album' in message) {
|
|
941
|
-
const imageMessages = message.album.filter(item => 'image' in item)
|
|
942
|
-
const videoMessages = message.album.filter(item => 'video' in item)
|
|
943
|
-
m.albumMessage = WAProto_1.proto.Message.AlbumMessage.fromObject({
|
|
944
|
-
expectedImageCount: imageMessages.length,
|
|
945
|
-
expectedVideoCount: videoMessages.length
|
|
946
|
-
})
|
|
947
|
-
} else if ('pollResult' in message) {
|
|
948
|
-
if (!Array.isArray(message.pollResult.values)) {
|
|
949
|
-
throw new boom_1.Boom('Invalid pollResult values', { statusCode: 400 })
|
|
950
|
-
}
|
|
951
|
-
const isQuizResult =
|
|
952
|
-
message.pollResult.type === 'quiz' || message.pollResult.pollType === WAProto_1.proto.Message.PollType.QUIZ
|
|
953
|
-
const pollVotes = message.pollResult.values.map(([optionName, optionVoteCount]) => ({
|
|
954
|
-
optionName,
|
|
955
|
-
optionVoteCount
|
|
956
|
-
}))
|
|
957
|
-
const snapshotPayload = {
|
|
958
|
-
name: message.pollResult.name,
|
|
959
|
-
pollVotes,
|
|
960
|
-
pollType: isQuizResult ? WAProto_1.proto.Message.PollType.QUIZ : WAProto_1.proto.Message.PollType.POLL
|
|
961
|
-
}
|
|
962
|
-
if (message.pollResult.version === 3 || message.pollResult.v3) {
|
|
963
|
-
m.pollResultSnapshotMessageV3 = WAProto_1.proto.Message.PollResultSnapshotMessage.fromObject(snapshotPayload)
|
|
964
|
-
} else {
|
|
965
|
-
m.pollResultSnapshotMessage = snapshotPayload
|
|
966
|
-
}
|
|
967
|
-
} else if ('stickerPack' in message || 'stickerPackMessage' in message) {
|
|
968
|
-
if ('stickerPack' in message && 'stickerPackMessage' in message) {
|
|
969
|
-
throw new boom_1.Boom('Cannot specify both stickerPack and stickerPackMessage; use only one property.', {
|
|
970
|
-
statusCode: 400
|
|
971
|
-
})
|
|
972
|
-
}
|
|
973
|
-
const stickerPackMessage = 'stickerPack' in message ? message.stickerPack : message.stickerPackMessage
|
|
974
|
-
m.stickerPackMessage = WAProto_1.proto.Message.StickerPackMessage.fromObject(stickerPackMessage)
|
|
975
|
-
} else if ('listMessage' in message) {
|
|
976
|
-
const lm = { ...message.listMessage }
|
|
977
|
-
if (lm.text !== undefined && lm.description === undefined) {
|
|
978
|
-
lm.description = lm.text
|
|
979
|
-
delete lm.text
|
|
980
|
-
}
|
|
981
|
-
m = { listMessage: lm }
|
|
982
|
-
} else if ('buttonsMessage' in message) {
|
|
983
|
-
m = {
|
|
984
|
-
buttonsMessage: WAProto_1.proto.Message.ButtonsMessage.fromObject(message.buttonsMessage)
|
|
985
|
-
}
|
|
986
|
-
} else if ('interactiveMessage' in message) {
|
|
987
|
-
m = { interactiveMessage: message.interactiveMessage }
|
|
988
|
-
} else if ('richResponse' in message) {
|
|
989
|
-
// handled in richResponse block below
|
|
990
|
-
} else if ('groupStatusMessage' in message) {
|
|
991
|
-
m = { groupStatusMessage: WAProto_1.proto.Message.GroupStatusMessage.fromObject(message.groupStatusMessage) }
|
|
992
|
-
} else if (hasCaptionWithoutMedia && !hasCaptionContainer) {
|
|
993
|
-
m.extendedTextMessage = { text: message.caption }
|
|
994
|
-
} else if (hasCaptionWithoutMedia && hasCaptionContainer) {
|
|
995
|
-
m = {}
|
|
996
|
-
} else if (!hasCaptionWithoutMedia && hasMediaPayload(message)) {
|
|
997
|
-
m = await (0, exports.prepareWAMessageMedia)(message, options)
|
|
998
|
-
}
|
|
999
|
-
if ('buttons' in message && !!message.buttons) {
|
|
1000
|
-
const interactiveMessage = {
|
|
1001
|
-
nativeFlowMessage: WAProto_1.proto.Message.InteractiveMessage.NativeFlowMessage.fromObject({
|
|
1002
|
-
buttons: message.buttons.map(normalizeQuickReplyButton)
|
|
1003
|
-
})
|
|
1004
|
-
}
|
|
1005
|
-
if ('text' in message) {
|
|
1006
|
-
interactiveMessage.body = { text: message.text }
|
|
1007
|
-
} else if ('caption' in message) {
|
|
1008
|
-
interactiveMessage.body = { text: message.caption }
|
|
1009
|
-
interactiveMessage.header = {
|
|
1010
|
-
title: message.title || '',
|
|
1011
|
-
subtitle: message.subtitle,
|
|
1012
|
-
hasMediaAttachment: Boolean(message.hasMediaAttachment)
|
|
1013
|
-
}
|
|
1014
|
-
Object.assign(interactiveMessage.header, m)
|
|
1015
|
-
}
|
|
1016
|
-
if ('title' in message && !!message.title && !interactiveMessage.header) {
|
|
1017
|
-
interactiveMessage.header = {
|
|
1018
|
-
title: message.title,
|
|
1019
|
-
subtitle: message.subtitle,
|
|
1020
|
-
hasMediaAttachment: Boolean(message.hasMediaAttachment)
|
|
1021
|
-
}
|
|
1022
|
-
} else if ('title' in message && !!message.title && interactiveMessage.header) {
|
|
1023
|
-
interactiveMessage.header.title = message.title
|
|
1024
|
-
if (message.subtitle !== undefined) {
|
|
1025
|
-
interactiveMessage.header.subtitle = message.subtitle
|
|
1026
|
-
}
|
|
1027
|
-
}
|
|
1028
|
-
if ('footer' in message && !!message.footer) {
|
|
1029
|
-
interactiveMessage.footer = { text: message.footer }
|
|
1030
|
-
}
|
|
1031
|
-
applyContextInfoAndMentions(interactiveMessage, message)
|
|
1032
|
-
m = { interactiveMessage }
|
|
1033
|
-
} else if ('templateButtons' in message && !!message.templateButtons) {
|
|
1034
|
-
const msg = {
|
|
1035
|
-
hydratedButtons: message.hasOwnProperty('templateButtons') ? message.templateButtons : message.templateButtons
|
|
1036
|
-
}
|
|
1037
|
-
if ('text' in message) {
|
|
1038
|
-
msg.hydratedContentText = message.text
|
|
1039
|
-
} else {
|
|
1040
|
-
if ('caption' in message) {
|
|
1041
|
-
msg.hydratedContentText = message.caption
|
|
1042
|
-
}
|
|
1043
|
-
Object.assign(msg, m)
|
|
1044
|
-
}
|
|
1045
|
-
if ('footer' in message && !!message.footer) {
|
|
1046
|
-
msg.hydratedFooterText = message.footer
|
|
1047
|
-
}
|
|
1048
|
-
m = {
|
|
1049
|
-
templateMessage: {
|
|
1050
|
-
fourRowTemplate: msg,
|
|
1051
|
-
hydratedTemplate: msg
|
|
1052
|
-
}
|
|
1053
|
-
}
|
|
1054
|
-
}
|
|
1055
|
-
if ('sections' in message && !!message.sections) {
|
|
1056
|
-
const listMessage = {
|
|
1057
|
-
sections: message.sections,
|
|
1058
|
-
buttonText: message.buttonText,
|
|
1059
|
-
title: message.title,
|
|
1060
|
-
footerText: message.footer,
|
|
1061
|
-
description: message.text,
|
|
1062
|
-
listType: WAProto_1.proto.Message.ListMessage.ListType.SINGLE_SELECT
|
|
1063
|
-
}
|
|
1064
|
-
m = { listMessage }
|
|
1065
|
-
} else if ('productList' in message && !!message.productList) {
|
|
1066
|
-
if (
|
|
1067
|
-
!Array.isArray(message.productList) ||
|
|
1068
|
-
message.productList.length === 0 ||
|
|
1069
|
-
!Array.isArray(message.productList[0].products) ||
|
|
1070
|
-
message.productList[0].products.length === 0
|
|
1071
|
-
) {
|
|
1072
|
-
throw new boom_1.Boom('Invalid productList: must contain at least one section with one product', {
|
|
1073
|
-
statusCode: 400
|
|
1074
|
-
})
|
|
1075
|
-
}
|
|
1076
|
-
m.listMessage = {
|
|
1077
|
-
title: message.title,
|
|
1078
|
-
buttonText: message.buttonText,
|
|
1079
|
-
footerText: message.footer,
|
|
1080
|
-
description: message.text,
|
|
1081
|
-
productListInfo: {
|
|
1082
|
-
productSections: message.productList,
|
|
1083
|
-
headerImage: {
|
|
1084
|
-
productId: message.productList[0].products[0].productId
|
|
1085
|
-
},
|
|
1086
|
-
businessOwnerJid: message.businessOwnerJid
|
|
1087
|
-
},
|
|
1088
|
-
listType: WAProto_1.proto.Message.ListMessage.ListType.PRODUCT_LIST
|
|
1089
|
-
}
|
|
1090
|
-
}
|
|
1091
|
-
if ('interactiveButtons' in message && !!message.interactiveButtons) {
|
|
1092
|
-
const nativeFlow = WAProto_1.proto.Message.InteractiveMessage.NativeFlowMessage.fromObject({
|
|
441
|
+
export const generateWAMessageContent = async (message, options) => {
|
|
442
|
+
var _a, _b;
|
|
443
|
+
let m = {};
|
|
444
|
+
if ('interactiveButtons' in message && !!message.interactiveButtons) {
|
|
445
|
+
const nativeFlow = proto.Message.InteractiveMessage.NativeFlowMessage.fromObject({
|
|
1093
446
|
buttons: message.interactiveButtons,
|
|
1094
447
|
messageParamsJson: message.messageParams ?? "{}"
|
|
1095
448
|
});
|
|
@@ -1156,53 +509,34 @@ const generateWAMessageContent = async (message, options) => {
|
|
|
1156
509
|
applyContextInfoAndMentions(interactiveMessage, message);
|
|
1157
510
|
m = { interactiveMessage };
|
|
1158
511
|
}
|
|
1159
|
-
if ('
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1181
|
-
|
|
1182
|
-
interactiveMessage.footer = {
|
|
1183
|
-
text: message.footer
|
|
1184
|
-
}
|
|
1185
|
-
}
|
|
1186
|
-
if ('title' in message && !!message.title) {
|
|
1187
|
-
interactiveMessage.header = {
|
|
1188
|
-
title: message.title,
|
|
1189
|
-
subtitle: message.subtitle,
|
|
1190
|
-
hasMediaAttachment: Boolean(message.hasMediaAttachment)
|
|
1191
|
-
}
|
|
1192
|
-
Object.assign(interactiveMessage.header, m)
|
|
1193
|
-
}
|
|
1194
|
-
applyContextInfoAndMentions(interactiveMessage, message)
|
|
1195
|
-
m = { interactiveMessage }
|
|
1196
|
-
if ('interactiveAsTemplate' in message && message.interactiveAsTemplate !== false) {
|
|
1197
|
-
m = { templateMessage: { interactiveMessageTemplate: interactiveMessage } }
|
|
1198
|
-
}
|
|
1199
|
-
}
|
|
1200
|
-
if ('richResponse' in message) {
|
|
512
|
+
else if ('buttons' in message && !!message.buttons) {
|
|
513
|
+
const buttonsMessage = {
|
|
514
|
+
buttons: message.buttons.map(b => ({ ...b, type: proto.Message.ButtonsMessage.Button.Type.RESPONSE }))
|
|
515
|
+
};
|
|
516
|
+
if ('text' in message) {
|
|
517
|
+
buttonsMessage.contentText = message.text;
|
|
518
|
+
buttonsMessage.headerType = ButtonType.EMPTY;
|
|
519
|
+
}
|
|
520
|
+
else {
|
|
521
|
+
if ('caption' in message) {
|
|
522
|
+
buttonsMessage.contentText = message.caption;
|
|
523
|
+
}
|
|
524
|
+
const contentType = getContentType(m);
|
|
525
|
+
const type = contentType.replace('Message', '').toUpperCase();
|
|
526
|
+
buttonsMessage.headerType = ButtonType[type];
|
|
527
|
+
Object.assign(buttonsMessage, m);
|
|
528
|
+
}
|
|
529
|
+
if ('footer' in message && !!message.footer) {
|
|
530
|
+
buttonsMessage.footerText = message.footer;
|
|
531
|
+
}
|
|
532
|
+
m = { buttonsMessage };
|
|
533
|
+
}
|
|
534
|
+
else if ('richResponse' in message) {
|
|
1201
535
|
const {
|
|
1202
536
|
text,
|
|
1203
537
|
code,
|
|
1204
538
|
language = 'javascript',
|
|
1205
|
-
botJid = '
|
|
539
|
+
botJid = '867051314767696@bot',
|
|
1206
540
|
table,
|
|
1207
541
|
latex,
|
|
1208
542
|
map,
|
|
@@ -1232,22 +566,12 @@ const generateWAMessageContent = async (message, options) => {
|
|
|
1232
566
|
}
|
|
1233
567
|
})
|
|
1234
568
|
}
|
|
1235
|
-
if (table) {
|
|
1236
|
-
const isPlainArrayTable = Array.isArray(table)
|
|
1237
|
-
const rows = isPlainArrayTable ? table : table.rows
|
|
1238
|
-
if (!Array.isArray(rows)) {
|
|
1239
|
-
throw new boom_1.Boom(
|
|
1240
|
-
'richResponse.table must be an array of rows (e.g. [["h1","h2"],["a","b"]]) or { rows: [...] }',
|
|
1241
|
-
{ statusCode: 400 }
|
|
1242
|
-
)
|
|
1243
|
-
}
|
|
569
|
+
if (table && Array.isArray(table.rows)) {
|
|
1244
570
|
sections.push({
|
|
1245
571
|
view_model: {
|
|
1246
572
|
primitive: {
|
|
1247
|
-
rows: rows.map(
|
|
1248
|
-
cells: Array.isArray(row) ? row.map(c => ({ text: String(c) })) : row.cells
|
|
1249
|
-
// when a plain 2D array is passed, the first row is treated as the table header
|
|
1250
|
-
isHeading: Array.isArray(row) ? isPlainArrayTable && idx === 0 : row.isHeading
|
|
573
|
+
rows: table.rows.map(row => ({
|
|
574
|
+
cells: Array.isArray(row) ? row.map(c => ({ text: String(c) })) : row.cells
|
|
1251
575
|
})),
|
|
1252
576
|
__typename: 'GenAITableUXPrimitive'
|
|
1253
577
|
},
|
|
@@ -1309,14 +633,14 @@ const generateWAMessageContent = async (message, options) => {
|
|
|
1309
633
|
})
|
|
1310
634
|
}
|
|
1311
635
|
const unifiedData = {
|
|
1312
|
-
response_id: responseId ||
|
|
636
|
+
response_id: responseId || randomUUID(),
|
|
1313
637
|
sections
|
|
1314
638
|
}
|
|
1315
|
-
return
|
|
639
|
+
return proto.Message.fromObject({
|
|
1316
640
|
messageContextInfo: {
|
|
1317
641
|
deviceListMetadata: {},
|
|
1318
642
|
deviceListMetadataVersion: 2,
|
|
1319
|
-
messageSecret: richSecret ||
|
|
643
|
+
messageSecret: richSecret || randomBytes(32)
|
|
1320
644
|
},
|
|
1321
645
|
botForwardedMessage: {
|
|
1322
646
|
message: {
|
|
@@ -1338,1567 +662,676 @@ const generateWAMessageContent = async (message, options) => {
|
|
|
1338
662
|
}
|
|
1339
663
|
})
|
|
1340
664
|
}
|
|
1341
|
-
if ('
|
|
1342
|
-
|
|
1343
|
-
|
|
1344
|
-
|
|
1345
|
-
|
|
1346
|
-
|
|
1347
|
-
|
|
1348
|
-
|
|
1349
|
-
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1364
|
-
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1370
|
-
|
|
1371
|
-
|
|
1372
|
-
|
|
1373
|
-
|
|
1374
|
-
|
|
1375
|
-
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1390
|
-
|
|
1391
|
-
|
|
1392
|
-
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1396
|
-
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1403
|
-
|
|
1404
|
-
|
|
1405
|
-
|
|
1406
|
-
|
|
1407
|
-
|
|
1408
|
-
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1413
|
-
|
|
1414
|
-
|
|
1415
|
-
|
|
1416
|
-
|
|
1417
|
-
|
|
1418
|
-
|
|
1419
|
-
|
|
1420
|
-
|
|
1421
|
-
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
|
|
1425
|
-
|
|
1426
|
-
|
|
1427
|
-
|
|
1428
|
-
|
|
1429
|
-
|
|
1430
|
-
|
|
1431
|
-
|
|
1432
|
-
|
|
1433
|
-
|
|
1434
|
-
|
|
1435
|
-
|
|
1436
|
-
|
|
1437
|
-
|
|
1438
|
-
|
|
1439
|
-
|
|
1440
|
-
|
|
1441
|
-
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1446
|
-
|
|
1447
|
-
|
|
1448
|
-
|
|
1449
|
-
|
|
1450
|
-
|
|
1451
|
-
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1459
|
-
|
|
1460
|
-
|
|
1461
|
-
|
|
1462
|
-
|
|
1463
|
-
|
|
1464
|
-
|
|
1465
|
-
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
|
|
1484
|
-
|
|
1485
|
-
|
|
1486
|
-
|
|
1487
|
-
|
|
1488
|
-
|
|
1489
|
-
|
|
1490
|
-
|
|
1491
|
-
|
|
1492
|
-
|
|
1493
|
-
|
|
1494
|
-
|
|
1495
|
-
|
|
1496
|
-
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
|
|
1500
|
-
|
|
1501
|
-
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1505
|
-
|
|
1506
|
-
|
|
1507
|
-
|
|
1508
|
-
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
|
|
1516
|
-
|
|
1517
|
-
|
|
1518
|
-
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
1574
|
-
|
|
1575
|
-
|
|
1576
|
-
|
|
1577
|
-
|
|
1578
|
-
|
|
1579
|
-
|
|
1580
|
-
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
|
|
1585
|
-
|
|
1586
|
-
|
|
1587
|
-
|
|
1588
|
-
|
|
1589
|
-
|
|
1590
|
-
|
|
1591
|
-
|
|
1592
|
-
|
|
1593
|
-
|
|
1594
|
-
|
|
1595
|
-
|
|
1596
|
-
|
|
1597
|
-
|
|
1598
|
-
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1605
|
-
|
|
1606
|
-
|
|
1607
|
-
|
|
1608
|
-
|
|
1609
|
-
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
|
|
1614
|
-
|
|
1615
|
-
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
1621
|
-
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
|
|
1625
|
-
|
|
1626
|
-
|
|
1627
|
-
|
|
1628
|
-
|
|
1629
|
-
|
|
1630
|
-
|
|
1631
|
-
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
1663
|
-
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
1667
|
-
|
|
1668
|
-
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
|
|
1680
|
-
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
|
|
1709
|
-
|
|
1710
|
-
|
|
1711
|
-
|
|
1712
|
-
|
|
1713
|
-
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
|
|
1717
|
-
|
|
1718
|
-
|
|
1719
|
-
|
|
1720
|
-
|
|
1721
|
-
|
|
1722
|
-
|
|
1723
|
-
|
|
1724
|
-
|
|
1725
|
-
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
1734
|
-
|
|
1735
|
-
|
|
1736
|
-
|
|
1737
|
-
|
|
1738
|
-
|
|
1739
|
-
|
|
1740
|
-
|
|
1741
|
-
|
|
1742
|
-
|
|
1743
|
-
|
|
1744
|
-
colorSchemeId: ct.colorSchemeId
|
|
1745
|
-
}
|
|
1746
|
-
if (ct.solidColor) {
|
|
1747
|
-
const sc = typeof ct.solidColor === 'object' ? ct.solidColor : {}
|
|
1748
|
-
themeSetting.solidColor = WAProto_1.proto.Message.ChatSolidColorWallpaper.fromObject({
|
|
1749
|
-
colorLight: sc.colorLight || sc.color || '#FFFFFF',
|
|
1750
|
-
colorDark: sc.colorDark || sc.color || '#000000',
|
|
1751
|
-
isDoodleEnabled: sc.isDoodleEnabled ?? false
|
|
1752
|
-
})
|
|
1753
|
-
} else if (ct.stockImage) {
|
|
1754
|
-
const si = typeof ct.stockImage === 'object' ? ct.stockImage : {}
|
|
1755
|
-
themeSetting.stockImage = WAProto_1.proto.Message.ChatStockImageWallpaper.fromObject({
|
|
1756
|
-
stockImageId: si.id || si.stockImageId || String(ct.stockImage),
|
|
1757
|
-
dimLevel: (si.dimLevel ?? si.opacity != null) ? (si.opacity ?? 100) / 100 : 0
|
|
1758
|
-
})
|
|
1759
|
-
} else if (ct.defaultWallpaper) {
|
|
1760
|
-
themeSetting.defaultWallpaper = WAProto_1.proto.Message.ChatDefaultWallpaper.fromObject({
|
|
1761
|
-
isDoodleEnabled: ct.defaultWallpaper.isDoodleEnabled ?? false
|
|
1762
|
-
})
|
|
1763
|
-
} else if (ct.customImage) {
|
|
1764
|
-
themeSetting.customImage = WAProto_1.proto.Message.ChatCustomImageWallpaper.fromObject({
|
|
1765
|
-
directPath: ct.customImage.directPath,
|
|
1766
|
-
mediaKey: ct.customImage.mediaKey,
|
|
1767
|
-
fileEncSha256: ct.customImage.fileEncSha256,
|
|
1768
|
-
fileSha256: ct.customImage.fileSha256,
|
|
1769
|
-
dimLevel: ct.customImage.dimLevel ?? 0
|
|
1770
|
-
})
|
|
1771
|
-
}
|
|
1772
|
-
m.protocolMessage = {
|
|
1773
|
-
type: WAProto_1.proto.Message.ProtocolMessage.Type.CHAT_THEME_SETTING,
|
|
1774
|
-
chatThemeSetting: WAProto_1.proto.Message.ChatThemeSetting.fromObject(themeSetting)
|
|
1775
|
-
}
|
|
1776
|
-
}
|
|
1777
|
-
if ('stopGeneration' in message) {
|
|
1778
|
-
const sg = message.stopGeneration
|
|
1779
|
-
m.protocolMessage = {
|
|
1780
|
-
type: WAProto_1.proto.Message.ProtocolMessage.Type.STOP_GENERATION_MESSAGE,
|
|
1781
|
-
key: sg.key || sg
|
|
1782
|
-
}
|
|
1783
|
-
}
|
|
1784
|
-
if ('unscheduleMessage' in message) {
|
|
1785
|
-
const us = message.unscheduleMessage
|
|
1786
|
-
m.protocolMessage = {
|
|
1787
|
-
type: WAProto_1.proto.Message.ProtocolMessage.Type.MESSAGE_UNSCHEDULE,
|
|
1788
|
-
key: us.key || us
|
|
1789
|
-
}
|
|
1790
|
-
}
|
|
1791
|
-
if ('bcall' in message || 'bcallMessage' in message) {
|
|
1792
|
-
const bc = message.bcall || message.bcallMessage
|
|
1793
|
-
const mediaTypeEnum = WAProto_1.proto.Message.BCallMessage.MediaType
|
|
1794
|
-
const mediaTypeMap = { audio: mediaTypeEnum.AUDIO, video: mediaTypeEnum.VIDEO }
|
|
1795
|
-
m.bcallMessage = WAProto_1.proto.Message.BCallMessage.fromObject({
|
|
1796
|
-
sessionId: bc.sessionId || (0, crypto_1.randomUUID)(),
|
|
1797
|
-
mediaType:
|
|
1798
|
-
typeof bc.mediaType === 'string'
|
|
1799
|
-
? (mediaTypeMap[bc.mediaType.toLowerCase()] ?? mediaTypeEnum.AUDIO)
|
|
1800
|
-
: (bc.mediaType ?? mediaTypeEnum.AUDIO),
|
|
1801
|
-
masterKey: bc.masterKey || (0, crypto_1.randomBytes)(32),
|
|
1802
|
-
caption: bc.caption || ''
|
|
1803
|
-
})
|
|
1804
|
-
}
|
|
1805
|
-
if ('liveLocationUpdate' in message) {
|
|
1806
|
-
const llu = message.liveLocationUpdate
|
|
1807
|
-
m.liveLocationMessage = WAProto_1.proto.Message.LiveLocationMessage.fromObject({
|
|
1808
|
-
degreesLatitude: llu.latitude,
|
|
1809
|
-
degreesLongitude: llu.longitude,
|
|
1810
|
-
accuracyInMeters: llu.accuracy,
|
|
1811
|
-
speedInMps: llu.speed,
|
|
1812
|
-
degreesClockwiseFromMagneticNorth: llu.heading,
|
|
1813
|
-
sequenceNumber: llu.sequence || 1,
|
|
1814
|
-
timeOffset: llu.timeOffset || 0,
|
|
1815
|
-
jpegThumbnail: llu.thumbnail
|
|
1816
|
-
})
|
|
1817
|
-
}
|
|
1818
|
-
if ('stopLiveLocation' in message) {
|
|
1819
|
-
const sll = message.stopLiveLocation
|
|
1820
|
-
m.protocolMessage = {
|
|
1821
|
-
type: WAProto_1.proto.Message.ProtocolMessage.Type.REVOKE,
|
|
1822
|
-
key: sll.key || sll
|
|
1823
|
-
}
|
|
1824
|
-
}
|
|
1825
|
-
if ('carousel' in message || 'carouselMessage' in message) {
|
|
1826
|
-
const c = message.carousel || message.carouselMessage
|
|
1827
|
-
if (!Array.isArray(c.cards) || !c.cards.length) {
|
|
1828
|
-
throw new boom_1.Boom('carousel requires at least one card', { statusCode: 400 })
|
|
1829
|
-
}
|
|
1830
|
-
const cardTypeEnum = WAProto_1.proto.Message.InteractiveMessage.CarouselMessage.CarouselCardType
|
|
1831
|
-
const cardTypeMap = {
|
|
1832
|
-
horizontal: cardTypeEnum.HSCROLL_CARDS,
|
|
1833
|
-
album: cardTypeEnum.ALBUM_IMAGE,
|
|
1834
|
-
hscroll: cardTypeEnum.HSCROLL_CARDS
|
|
1835
|
-
}
|
|
1836
|
-
m.interactiveMessage = {
|
|
1837
|
-
carouselMessage: WAProto_1.proto.Message.InteractiveMessage.CarouselMessage.fromObject({
|
|
1838
|
-
cards: c.cards.map(card => card.interactiveMessage || card),
|
|
1839
|
-
messageVersion: c.messageVersion || 1,
|
|
1840
|
-
carouselCardType:
|
|
1841
|
-
typeof c.cardType === 'string'
|
|
1842
|
-
? (cardTypeMap[c.cardType.toLowerCase()] ?? cardTypeEnum.HSCROLL_CARDS)
|
|
1843
|
-
: (c.carouselCardType ?? cardTypeEnum.HSCROLL_CARDS)
|
|
1844
|
-
})
|
|
1845
|
-
}
|
|
1846
|
-
}
|
|
1847
|
-
if ('aiMediaCollection' in message || 'aiMediaCollectionMessage' in message) {
|
|
1848
|
-
const amc = message.aiMediaCollection || message.aiMediaCollectionMessage
|
|
1849
|
-
m.protocolMessage = {
|
|
1850
|
-
type: WAProto_1.proto.Message.ProtocolMessage.Type.AI_MEDIA_COLLECTION_MESSAGE,
|
|
1851
|
-
aiMediaCollectionMessage: WAProto_1.proto.AIMediaCollectionMessage.fromObject({
|
|
1852
|
-
collectionId: amc.collectionId || (0, crypto_1.randomUUID)(),
|
|
1853
|
-
expectedMediaCount: amc.expectedMediaCount || amc.count || 1,
|
|
1854
|
-
hasGlobalCaption: amc.hasGlobalCaption ?? false
|
|
1855
|
-
})
|
|
1856
|
-
}
|
|
1857
|
-
}
|
|
1858
|
-
if ('botCapabilities' in message && Array.isArray(message.botCapabilities) && message.botCapabilities.length) {
|
|
1859
|
-
const capEnum = WAProto_1.proto.BotCapabilityMetadata.BotCapabilityType
|
|
1860
|
-
const capStrMap = Object.fromEntries(Object.entries(capEnum).map(([k, v]) => [k.toLowerCase(), v]))
|
|
1861
|
-
const caps = message.botCapabilities
|
|
1862
|
-
.map(c => (typeof c === 'string' ? (capStrMap[c.toLowerCase()] ?? capEnum.UNKNOWN) : c))
|
|
1863
|
-
.filter(c => typeof c === 'number' && c !== capEnum.UNKNOWN)
|
|
1864
|
-
m.messageContextInfo = m.messageContextInfo || {}
|
|
1865
|
-
m.messageContextInfo.botMetadata = WAProto_1.proto.BotMetadata.fromObject({
|
|
1866
|
-
capabilityMetadata: { capabilities: caps }
|
|
1867
|
-
})
|
|
1868
|
-
}
|
|
1869
|
-
if ('botThreadInfo' in message && message.botThreadInfo) {
|
|
1870
|
-
const bt = message.botThreadInfo
|
|
1871
|
-
const threadTypeEnum = WAProto_1.proto.AIThreadInfo.AIThreadClientInfo.AIThreadType
|
|
1872
|
-
const threadTypeMap = Object.fromEntries(Object.entries(threadTypeEnum).map(([k, v]) => [k.toLowerCase(), v]))
|
|
1873
|
-
const existing = m.messageContextInfo?.botMetadata
|
|
1874
|
-
? WAProto_1.proto.BotMetadata.toObject(m.messageContextInfo.botMetadata)
|
|
1875
|
-
: {}
|
|
1876
|
-
m.messageContextInfo = m.messageContextInfo || {}
|
|
1877
|
-
m.messageContextInfo.botMetadata = WAProto_1.proto.BotMetadata.fromObject({
|
|
1878
|
-
...existing,
|
|
1879
|
-
botThreadInfo: {
|
|
1880
|
-
clientInfo: {
|
|
1881
|
-
type: typeof bt.type === 'string'
|
|
1882
|
-
? (threadTypeMap[bt.type.toLowerCase()] ?? threadTypeEnum.UNKNOWN)
|
|
1883
|
-
: (bt.type ?? threadTypeEnum.UNKNOWN),
|
|
1884
|
-
sourceChatJid: bt.sourceChatJid || ''
|
|
1885
|
-
}
|
|
1886
|
-
}
|
|
1887
|
-
})
|
|
1888
|
-
}
|
|
1889
|
-
if ('messageAssociation' in message && message.messageAssociation) {
|
|
1890
|
-
const ma = message.messageAssociation
|
|
1891
|
-
const assocTypeEnum = WAProto_1.proto.MessageAssociation.AssociationType
|
|
1892
|
-
const assocTypeMap = Object.fromEntries(Object.entries(assocTypeEnum).map(([k, v]) => [k.toLowerCase(), v]))
|
|
1893
|
-
m.messageContextInfo = m.messageContextInfo || {}
|
|
1894
|
-
m.messageContextInfo.messageAssociation = WAProto_1.proto.MessageAssociation.fromObject({
|
|
1895
|
-
associationType:
|
|
1896
|
-
typeof ma.type === 'string'
|
|
1897
|
-
? (assocTypeMap[ma.type.toLowerCase()] ?? assocTypeEnum.UNKNOWN)
|
|
1898
|
-
: (ma.associationType ?? ma.type ?? assocTypeEnum.UNKNOWN),
|
|
1899
|
-
parentMessageKey: ma.parentMessageKey || ma.parentKey,
|
|
1900
|
-
messageIndex: ma.messageIndex || 0
|
|
1901
|
-
})
|
|
1902
|
-
}
|
|
1903
|
-
if ('threadId' in message && message.threadId) {
|
|
1904
|
-
const tid = message.threadId
|
|
1905
|
-
const threadTypeEnum = WAProto_1.proto.ThreadID.ThreadType
|
|
1906
|
-
m.messageContextInfo = m.messageContextInfo || {}
|
|
1907
|
-
m.messageContextInfo.threadId = [
|
|
1908
|
-
WAProto_1.proto.ThreadID.fromObject({
|
|
1909
|
-
threadType:
|
|
1910
|
-
tid.type === 'ai'
|
|
1911
|
-
? threadTypeEnum.AI_THREAD
|
|
1912
|
-
: tid.type === 'replies'
|
|
1913
|
-
? threadTypeEnum.VIEW_REPLIES
|
|
1914
|
-
: (tid.threadType ?? threadTypeEnum.UNKNOWN),
|
|
1915
|
-
threadKey: tid.key || tid.threadKey
|
|
1916
|
-
})
|
|
1917
|
-
]
|
|
1918
|
-
}
|
|
1919
|
-
if ('featureEligibilities' in message && message.featureEligibilities) {
|
|
1920
|
-
const fe = message.featureEligibilities
|
|
1921
|
-
const [msgType] = Object.keys(m)
|
|
1922
|
-
if (msgType && m[msgType] && typeof m[msgType] === 'object') {
|
|
1923
|
-
m[msgType].contextInfo = {
|
|
1924
|
-
...(m[msgType].contextInfo || {}),
|
|
1925
|
-
featureEligibilities: {
|
|
1926
|
-
cannotBeReactedTo: fe.cannotBeReactedTo ?? false,
|
|
1927
|
-
cannotBeRanked: fe.cannotBeRanked ?? false,
|
|
1928
|
-
canRequestFeedback: fe.canRequestFeedback ?? false,
|
|
1929
|
-
canBeReshared: fe.canBeReshared ?? true,
|
|
1930
|
-
canReceiveMultiReact: fe.canReceiveMultiReact ?? true
|
|
1931
|
-
}
|
|
1932
|
-
}
|
|
1933
|
-
}
|
|
1934
|
-
}
|
|
1935
|
-
if ('forwardOrigin' in message) {
|
|
1936
|
-
const [msgType] = Object.keys(m)
|
|
1937
|
-
if (msgType && m[msgType] && typeof m[msgType] === 'object') {
|
|
1938
|
-
const foEnum = WAProto_1.proto.ContextInfo.ForwardOrigin
|
|
1939
|
-
const foMap = {
|
|
1940
|
-
chat: foEnum.CHAT,
|
|
1941
|
-
status: foEnum.STATUS,
|
|
1942
|
-
channels: foEnum.CHANNELS,
|
|
1943
|
-
meta_ai: foEnum.META_AI,
|
|
1944
|
-
ugc: foEnum.UGC
|
|
1945
|
-
}
|
|
1946
|
-
m[msgType].contextInfo = {
|
|
1947
|
-
...(m[msgType].contextInfo || {}),
|
|
1948
|
-
forwardOrigin:
|
|
1949
|
-
typeof message.forwardOrigin === 'string'
|
|
1950
|
-
? (foMap[message.forwardOrigin.toLowerCase()] ?? foEnum.CHAT)
|
|
1951
|
-
: (message.forwardOrigin ?? foEnum.CHAT)
|
|
1952
|
-
}
|
|
1953
|
-
}
|
|
1954
|
-
}
|
|
1955
|
-
if ('statusAudienceMetadata' in message && message.statusAudienceMetadata) {
|
|
1956
|
-
const [msgType] = Object.keys(m)
|
|
1957
|
-
if (msgType && m[msgType] && typeof m[msgType] === 'object') {
|
|
1958
|
-
const audType = WAProto_1.proto.ContextInfo.StatusAudienceMetadata.AudienceType
|
|
1959
|
-
const sam = message.statusAudienceMetadata
|
|
1960
|
-
m[msgType].contextInfo = {
|
|
1961
|
-
...(m[msgType].contextInfo || {}),
|
|
1962
|
-
statusAudienceMetadata: {
|
|
1963
|
-
audienceType: sam.closeFriends ? audType.CLOSE_FRIENDS : audType.UNKNOWN,
|
|
1964
|
-
listName: sam.listName,
|
|
1965
|
-
listEmoji: sam.listEmoji
|
|
1966
|
-
}
|
|
1967
|
-
}
|
|
1968
|
-
}
|
|
1969
|
-
}
|
|
1970
|
-
if ('aiGenerated' in message && message.aiGenerated === true) {
|
|
1971
|
-
if (m.videoMessage) {
|
|
1972
|
-
m.videoMessage.videoSourceType = WAProto_1.proto.Message.VideoMessage.VideoSourceType.AI_GENERATED
|
|
1973
|
-
}
|
|
1974
|
-
if (m.imageMessage) {
|
|
1975
|
-
m.imageMessage.imageSourceType = WAProto_1.proto.Message.ImageMessage.ImageSourceType.AI_GENERATED
|
|
1976
|
-
}
|
|
1977
|
-
}
|
|
1978
|
-
if ('aiModified' in message && message.aiModified === true) {
|
|
1979
|
-
if (m.imageMessage) {
|
|
1980
|
-
m.imageMessage.imageSourceType = WAProto_1.proto.Message.ImageMessage.ImageSourceType.AI_MODIFIED
|
|
1981
|
-
}
|
|
1982
|
-
}
|
|
1983
|
-
if ('imageSourceType' in message) {
|
|
1984
|
-
if (m.imageMessage) {
|
|
1985
|
-
const istEnum = WAProto_1.proto.Message.ImageMessage.ImageSourceType
|
|
1986
|
-
const istMap = {
|
|
1987
|
-
user: istEnum.USER_IMAGE,
|
|
1988
|
-
ai_generated: istEnum.AI_GENERATED,
|
|
1989
|
-
ai_modified: istEnum.AI_MODIFIED,
|
|
1990
|
-
rasterized: istEnum.RASTERIZED_TEXT_STATUS
|
|
1991
|
-
}
|
|
1992
|
-
m.imageMessage.imageSourceType =
|
|
1993
|
-
typeof message.imageSourceType === 'string'
|
|
1994
|
-
? (istMap[message.imageSourceType.toLowerCase()] ?? istEnum.USER_IMAGE)
|
|
1995
|
-
: (message.imageSourceType ?? istEnum.USER_IMAGE)
|
|
1996
|
-
}
|
|
1997
|
-
}
|
|
1998
|
-
if ('qrUrl' in message && message.qrUrl && m.imageMessage) {
|
|
1999
|
-
m.imageMessage.qrUrl = message.qrUrl
|
|
2000
|
-
}
|
|
2001
|
-
if ('videoContentUrl' in message && message.videoContentUrl && m.extendedTextMessage) {
|
|
2002
|
-
m.extendedTextMessage.videoContentUrl = message.videoContentUrl
|
|
2003
|
-
}
|
|
2004
|
-
if ('endCardTiles' in message && Array.isArray(message.endCardTiles) && m.extendedTextMessage) {
|
|
2005
|
-
m.extendedTextMessage.endCardTiles = message.endCardTiles.map(tile =>
|
|
2006
|
-
WAProto_1.proto.Message.VideoEndCard.fromObject({
|
|
2007
|
-
username: tile.username || tile.user,
|
|
2008
|
-
caption: tile.caption || tile.text,
|
|
2009
|
-
thumbnailImageUrl: tile.thumbnailUrl || tile.thumbnail,
|
|
2010
|
-
profilePictureUrl: tile.profilePictureUrl || tile.avatar
|
|
2011
|
-
})
|
|
2012
|
-
)
|
|
2013
|
-
}
|
|
2014
|
-
if ('musicMetadata' in message && message.musicMetadata && m.extendedTextMessage) {
|
|
2015
|
-
const mm = message.musicMetadata
|
|
2016
|
-
m.extendedTextMessage.musicMetadata = WAProto_1.proto.EmbeddedMusic.fromObject({
|
|
2017
|
-
songId: mm.songId,
|
|
2018
|
-
author: mm.author || mm.artist,
|
|
2019
|
-
title: mm.title,
|
|
2020
|
-
artistAttribution: mm.artistAttribution,
|
|
2021
|
-
isExplicit: mm.isExplicit ?? false,
|
|
2022
|
-
musicSongStartTimeInMs: mm.startTimeMs || 0,
|
|
2023
|
-
derivedContentStartTimeInMs: mm.derivedStartTimeMs || 0,
|
|
2024
|
-
overlapDurationInMs: mm.overlapDurationMs || 0
|
|
2025
|
-
})
|
|
2026
|
-
}
|
|
2027
|
-
if ('businessInteractionPills' in message && message.businessInteractionPills) {
|
|
2028
|
-
const bip = message.businessInteractionPills
|
|
2029
|
-
const pillTypeEnum = WAProto_1.proto.ContextInfo.BusinessInteractionPills.PillType
|
|
2030
|
-
const entryEnum = WAProto_1.proto.ContextInfo.BusinessInteractionPills.EntryPoint
|
|
2031
|
-
const pillMap = Object.fromEntries(Object.entries(pillTypeEnum).map(([k, v]) => [k.toLowerCase(), v]))
|
|
2032
|
-
const entryMap = Object.fromEntries(Object.entries(entryEnum).map(([k, v]) => [k.toLowerCase(), v]))
|
|
2033
|
-
const [msgType] = Object.keys(m)
|
|
2034
|
-
if (msgType && m[msgType] && typeof m[msgType] === 'object') {
|
|
2035
|
-
m[msgType].contextInfo = {
|
|
2036
|
-
...(m[msgType].contextInfo || {}),
|
|
2037
|
-
businessInteractionPills: WAProto_1.proto.ContextInfo.BusinessInteractionPills.fromObject({
|
|
2038
|
-
businessJid: bip.businessJid,
|
|
2039
|
-
entryPoint:
|
|
2040
|
-
typeof bip.entryPoint === 'string'
|
|
2041
|
-
? (entryMap[bip.entryPoint.toLowerCase()] ?? entryEnum.ENTRY_POINT_UNKNOWN)
|
|
2042
|
-
: bip.entryPoint,
|
|
2043
|
-
pills: (bip.pills || []).map(p => ({
|
|
2044
|
-
pillType:
|
|
2045
|
-
typeof p.type === 'string'
|
|
2046
|
-
? (pillMap[p.type.toLowerCase()] ?? pillTypeEnum.UNKNOWN)
|
|
2047
|
-
: (p.pillType ?? pillTypeEnum.UNKNOWN),
|
|
2048
|
-
actionUrl: p.url || p.actionUrl
|
|
2049
|
-
}))
|
|
2050
|
-
})
|
|
2051
|
-
}
|
|
2052
|
-
}
|
|
2053
|
-
}
|
|
2054
|
-
if ('dataSharingContext' in message && message.dataSharingContext) {
|
|
2055
|
-
const dsc = message.dataSharingContext
|
|
2056
|
-
const [msgType] = Object.keys(m)
|
|
2057
|
-
if (msgType && m[msgType] && typeof m[msgType] === 'object') {
|
|
2058
|
-
m[msgType].contextInfo = {
|
|
2059
|
-
...(m[msgType].contextInfo || {}),
|
|
2060
|
-
dataSharingContext: WAProto_1.proto.ContextInfo.DataSharingContext.fromObject({
|
|
2061
|
-
showMmDisclosure: dsc.showMmDisclosure ?? false,
|
|
2062
|
-
encryptedSignalTokenConsented: dsc.encryptedToken,
|
|
2063
|
-
dataSharingFlags: dsc.flags || 0
|
|
2064
|
-
})
|
|
2065
|
-
}
|
|
2066
|
-
}
|
|
2067
|
-
}
|
|
2068
|
-
if ('botSession' in message && message.botSession) {
|
|
2069
|
-
const bs = message.botSession
|
|
2070
|
-
const srcEnum = WAProto_1.proto.BotSessionSource
|
|
2071
|
-
const srcMap = Object.fromEntries(Object.entries(srcEnum).map(([k, v]) => [k.toLowerCase(), v]))
|
|
2072
|
-
m.messageContextInfo = m.messageContextInfo || {}
|
|
2073
|
-
const existing = m.messageContextInfo.botMetadata
|
|
2074
|
-
? WAProto_1.proto.BotMetadata.toObject(m.messageContextInfo.botMetadata)
|
|
2075
|
-
: {}
|
|
2076
|
-
m.messageContextInfo.botMetadata = WAProto_1.proto.BotMetadata.fromObject({
|
|
2077
|
-
...existing,
|
|
2078
|
-
sessionMetadata: {
|
|
2079
|
-
sessionId: bs.sessionId,
|
|
2080
|
-
sessionSource:
|
|
2081
|
-
typeof bs.source === 'string'
|
|
2082
|
-
? (srcMap[bs.source.toLowerCase()] ?? srcEnum.NONE)
|
|
2083
|
-
: (bs.sessionSource ?? srcEnum.NONE)
|
|
2084
|
-
}
|
|
2085
|
-
})
|
|
2086
|
-
}
|
|
2087
|
-
if ('botReminder' in message && message.botReminder) {
|
|
2088
|
-
const br = message.botReminder
|
|
2089
|
-
const actionEnum = WAProto_1.proto.BotReminderMetadata.ReminderAction
|
|
2090
|
-
const freqEnum = WAProto_1.proto.BotReminderMetadata.ReminderFrequency
|
|
2091
|
-
const actionMap = {
|
|
2092
|
-
notify: actionEnum.NOTIFY,
|
|
2093
|
-
create: actionEnum.CREATE,
|
|
2094
|
-
delete: actionEnum.DELETE,
|
|
2095
|
-
update: actionEnum.UPDATE
|
|
2096
|
-
}
|
|
2097
|
-
const freqMap = {
|
|
2098
|
-
once: freqEnum.ONCE,
|
|
2099
|
-
daily: freqEnum.DAILY,
|
|
2100
|
-
weekly: freqEnum.WEEKLY,
|
|
2101
|
-
biweekly: freqEnum.BIWEEKLY,
|
|
2102
|
-
monthly: freqEnum.MONTHLY
|
|
2103
|
-
}
|
|
2104
|
-
m.messageContextInfo = m.messageContextInfo || {}
|
|
2105
|
-
const existing = m.messageContextInfo.botMetadata
|
|
2106
|
-
? WAProto_1.proto.BotMetadata.toObject(m.messageContextInfo.botMetadata)
|
|
2107
|
-
: {}
|
|
2108
|
-
m.messageContextInfo.botMetadata = WAProto_1.proto.BotMetadata.fromObject({
|
|
2109
|
-
...existing,
|
|
2110
|
-
reminderMetadata: {
|
|
2111
|
-
requestMessageKey: br.requestMessageKey || br.key,
|
|
2112
|
-
action:
|
|
2113
|
-
typeof br.action === 'string'
|
|
2114
|
-
? (actionMap[br.action.toLowerCase()] ?? actionEnum.NOTIFY)
|
|
2115
|
-
: (br.action ?? actionEnum.NOTIFY),
|
|
2116
|
-
name: br.name,
|
|
2117
|
-
nextTriggerTimestamp: br.nextTriggerTimestamp || br.timestamp,
|
|
2118
|
-
frequency:
|
|
2119
|
-
typeof br.frequency === 'string'
|
|
2120
|
-
? (freqMap[br.frequency.toLowerCase()] ?? freqEnum.ONCE)
|
|
2121
|
-
: (br.frequency ?? freqEnum.ONCE)
|
|
2122
|
-
}
|
|
2123
|
-
})
|
|
2124
|
-
}
|
|
2125
|
-
if ('botPlugin' in message && message.botPlugin) {
|
|
2126
|
-
const bp = message.botPlugin
|
|
2127
|
-
const ptEnum = WAProto_1.proto.BotPluginMetadata.PluginType
|
|
2128
|
-
const spEnum = WAProto_1.proto.BotPluginMetadata.SearchProvider
|
|
2129
|
-
const ptMap = { reels: ptEnum.REELS, search: ptEnum.SEARCH }
|
|
2130
|
-
const spMap = { bing: spEnum.BING, google: spEnum.GOOGLE, support: spEnum.SUPPORT }
|
|
2131
|
-
m.messageContextInfo = m.messageContextInfo || {}
|
|
2132
|
-
const existing = m.messageContextInfo.botMetadata
|
|
2133
|
-
? WAProto_1.proto.BotMetadata.toObject(m.messageContextInfo.botMetadata)
|
|
2134
|
-
: {}
|
|
2135
|
-
m.messageContextInfo.botMetadata = WAProto_1.proto.BotMetadata.fromObject({
|
|
2136
|
-
...existing,
|
|
2137
|
-
pluginMetadata: WAProto_1.proto.BotPluginMetadata.fromObject({
|
|
2138
|
-
provider:
|
|
2139
|
-
typeof bp.provider === 'string'
|
|
2140
|
-
? (spMap[bp.provider.toLowerCase()] ?? spEnum.UNKNOWN)
|
|
2141
|
-
: (bp.provider ?? spEnum.UNKNOWN),
|
|
2142
|
-
pluginType:
|
|
2143
|
-
typeof bp.pluginType === 'string'
|
|
2144
|
-
? (ptMap[bp.pluginType.toLowerCase()] ?? ptEnum.UNKNOWN_PLUGIN)
|
|
2145
|
-
: (bp.pluginType ?? ptEnum.UNKNOWN_PLUGIN),
|
|
2146
|
-
searchProviderUrl: bp.searchProviderUrl,
|
|
2147
|
-
searchQuery: bp.searchQuery,
|
|
2148
|
-
thumbnailCdnUrl: bp.thumbnailCdnUrl,
|
|
2149
|
-
profilePhotoCdnUrl: bp.profilePhotoCdnUrl,
|
|
2150
|
-
expectedLinksCount: bp.expectedLinksCount || 0,
|
|
2151
|
-
referenceIndex: bp.referenceIndex || 0
|
|
2152
|
-
})
|
|
2153
|
-
})
|
|
2154
|
-
}
|
|
2155
|
-
if ('isSpoiler' in message && message.isSpoiler === true) {
|
|
2156
|
-
const [msgType] = Object.keys(m)
|
|
2157
|
-
if (msgType && m[msgType] && typeof m[msgType] === 'object') {
|
|
2158
|
-
m[msgType].contextInfo = {
|
|
2159
|
-
...(m[msgType].contextInfo || {}),
|
|
2160
|
-
isSpoiler: true
|
|
2161
|
-
}
|
|
2162
|
-
}
|
|
2163
|
-
}
|
|
2164
|
-
if ('expiration' in message && typeof message.expiration === 'number') {
|
|
2165
|
-
const [msgType] = Object.keys(m)
|
|
2166
|
-
if (msgType && m[msgType] && typeof m[msgType] === 'object') {
|
|
2167
|
-
m[msgType].contextInfo = {
|
|
2168
|
-
...(m[msgType].contextInfo || {}),
|
|
2169
|
-
expiration: message.expiration
|
|
2170
|
-
}
|
|
2171
|
-
}
|
|
2172
|
-
}
|
|
2173
|
-
if ('ephemeralSettingTimestamp' in message) {
|
|
2174
|
-
const [msgType] = Object.keys(m)
|
|
2175
|
-
if (msgType && m[msgType] && typeof m[msgType] === 'object') {
|
|
2176
|
-
m[msgType].contextInfo = {
|
|
2177
|
-
...(m[msgType].contextInfo || {}),
|
|
2178
|
-
ephemeralSettingTimestamp: message.ephemeralSettingTimestamp
|
|
2179
|
-
}
|
|
2180
|
-
}
|
|
2181
|
-
}
|
|
2182
|
-
if ('groupSubject' in message && message.groupSubject) {
|
|
2183
|
-
const [msgType] = Object.keys(m)
|
|
2184
|
-
if (msgType && m[msgType] && typeof m[msgType] === 'object') {
|
|
2185
|
-
m[msgType].contextInfo = {
|
|
2186
|
-
...(m[msgType].contextInfo || {}),
|
|
2187
|
-
groupSubject: message.groupSubject
|
|
2188
|
-
}
|
|
2189
|
-
}
|
|
2190
|
-
}
|
|
2191
|
-
if ('parentGroupJid' in message && message.parentGroupJid) {
|
|
2192
|
-
const [msgType] = Object.keys(m)
|
|
2193
|
-
if (msgType && m[msgType] && typeof m[msgType] === 'object') {
|
|
2194
|
-
m[msgType].contextInfo = {
|
|
2195
|
-
...(m[msgType].contextInfo || {}),
|
|
2196
|
-
parentGroupJid: message.parentGroupJid
|
|
2197
|
-
}
|
|
2198
|
-
}
|
|
2199
|
-
}
|
|
2200
|
-
if ('memberLabel' in message && message.memberLabel) {
|
|
2201
|
-
const [msgType] = Object.keys(m)
|
|
2202
|
-
if (msgType && m[msgType] && typeof m[msgType] === 'object') {
|
|
2203
|
-
m[msgType].contextInfo = {
|
|
2204
|
-
...(m[msgType].contextInfo || {}),
|
|
2205
|
-
memberLabel: message.memberLabel
|
|
2206
|
-
}
|
|
2207
|
-
}
|
|
2208
|
-
}
|
|
2209
|
-
if ('trustBanner' in message && message.trustBanner) {
|
|
2210
|
-
const tb = message.trustBanner
|
|
2211
|
-
const [msgType] = Object.keys(m)
|
|
2212
|
-
if (msgType && m[msgType] && typeof m[msgType] === 'object') {
|
|
2213
|
-
m[msgType].contextInfo = {
|
|
2214
|
-
...(m[msgType].contextInfo || {}),
|
|
2215
|
-
...(tb.type != null ? { trustBannerType: tb.type } : {}),
|
|
2216
|
-
...(tb.action != null ? { trustBannerAction: tb.action } : {})
|
|
2217
|
-
}
|
|
2218
|
-
}
|
|
2219
|
-
}
|
|
2220
|
-
if ('entryPoint' in message && message.entryPoint) {
|
|
2221
|
-
const ep = message.entryPoint
|
|
2222
|
-
const [msgType] = Object.keys(m)
|
|
2223
|
-
if (msgType && m[msgType] && typeof m[msgType] === 'object') {
|
|
2224
|
-
m[msgType].contextInfo = {
|
|
2225
|
-
...(m[msgType].contextInfo || {}),
|
|
2226
|
-
...(ep.source ? { entryPointConversionSource: ep.source } : {}),
|
|
2227
|
-
...(ep.app ? { entryPointConversionApp: ep.app } : {}),
|
|
2228
|
-
...(ep.delaySecs != null ? { entryPointConversionDelaySeconds: ep.delaySecs } : {}),
|
|
2229
|
-
...(ep.externalSource ? { entryPointConversionExternalSource: ep.externalSource } : {}),
|
|
2230
|
-
...(ep.externalMedium ? { entryPointConversionExternalMedium: ep.externalMedium } : {})
|
|
2231
|
-
}
|
|
2232
|
-
}
|
|
2233
|
-
}
|
|
2234
|
-
if ('utm' in message && message.utm) {
|
|
2235
|
-
const [msgType] = Object.keys(m)
|
|
2236
|
-
if (msgType && m[msgType] && typeof m[msgType] === 'object') {
|
|
2237
|
-
m[msgType].contextInfo = {
|
|
2238
|
-
...(m[msgType].contextInfo || {}),
|
|
2239
|
-
utm: WAProto_1.proto.ContextInfo.UTMInfo.fromObject({
|
|
2240
|
-
utmSource: message.utm.source,
|
|
2241
|
-
utmCampaign: message.utm.campaign
|
|
2242
|
-
})
|
|
2243
|
-
}
|
|
2244
|
-
}
|
|
2245
|
-
}
|
|
2246
|
-
if ('partiallySelectedContent' in message && message.partiallySelectedContent) {
|
|
2247
|
-
const [msgType] = Object.keys(m)
|
|
2248
|
-
if (msgType && m[msgType] && typeof m[msgType] === 'object') {
|
|
2249
|
-
m[msgType].contextInfo = {
|
|
2250
|
-
...(m[msgType].contextInfo || {}),
|
|
2251
|
-
partiallySelectedContent: message.partiallySelectedContent
|
|
2252
|
-
}
|
|
2253
|
-
}
|
|
2254
|
-
}
|
|
2255
|
-
if ('crossAppSource' in message && message.crossAppSource) {
|
|
2256
|
-
const [msgType] = Object.keys(m)
|
|
2257
|
-
if (msgType && m[msgType] && typeof m[msgType] === 'object') {
|
|
2258
|
-
m[msgType].contextInfo = {
|
|
2259
|
-
...(m[msgType].contextInfo || {}),
|
|
2260
|
-
crossAppSource: message.crossAppSource
|
|
2261
|
-
}
|
|
2262
|
-
}
|
|
2263
|
-
}
|
|
2264
|
-
if ('isQuestion' in message && message.isQuestion === true) {
|
|
2265
|
-
const [msgType] = Object.keys(m)
|
|
2266
|
-
if (msgType && m[msgType] && typeof m[msgType] === 'object') {
|
|
2267
|
-
m[msgType].contextInfo = {
|
|
2268
|
-
...(m[msgType].contextInfo || {}),
|
|
2269
|
-
isQuestion: true
|
|
2270
|
-
}
|
|
2271
|
-
}
|
|
2272
|
-
}
|
|
2273
|
-
if ('afterReadDuration' in message && typeof message.afterReadDuration === 'number') {
|
|
2274
|
-
const [msgType] = Object.keys(m)
|
|
2275
|
-
if (msgType && m[msgType] && typeof m[msgType] === 'object') {
|
|
2276
|
-
m[msgType].contextInfo = {
|
|
2277
|
-
...(m[msgType].contextInfo || {}),
|
|
2278
|
-
afterReadDuration: message.afterReadDuration
|
|
2279
|
-
}
|
|
2280
|
-
}
|
|
2281
|
-
m.messageContextInfo = {
|
|
2282
|
-
...(m.messageContextInfo || {}),
|
|
2283
|
-
messageAddOnDurationInSecs: message.afterReadDuration,
|
|
2284
|
-
messageAddOnExpiryType: index_js_1.proto.MessageContextInfo.MessageAddonExpiryType.DEPENDENT_ON_PARENT
|
|
2285
|
-
}
|
|
2286
|
-
}
|
|
2287
|
-
if ('raw' in message && !!message.raw) {
|
|
2288
|
-
const { raw: _, externalAdReply: _ear, ...rawMsg } = message
|
|
2289
|
-
if ('externalAdReply' in message && !!message.externalAdReply) {
|
|
2290
|
-
const ear = normalizeEarFields(message.externalAdReply)
|
|
2291
|
-
const [rawType] = Object.keys(rawMsg)
|
|
2292
|
-
if (rawType && rawMsg[rawType]) {
|
|
2293
|
-
rawMsg[rawType].contextInfo = {
|
|
2294
|
-
...(rawMsg[rawType].contextInfo || {}),
|
|
2295
|
-
externalAdReply: ear
|
|
2296
|
-
}
|
|
2297
|
-
}
|
|
2298
|
-
}
|
|
2299
|
-
return WAProto_1.proto.Message.fromObject(rawMsg)
|
|
2300
|
-
} else if (Object.keys(m).length === 0) {
|
|
2301
|
-
m = await (0, exports.prepareWAMessageMedia)(message, options)
|
|
2302
|
-
}
|
|
2303
|
-
|
|
2304
|
-
if (hasOptionalProperty(message, 'viewOnce') && !!message.viewOnce) {
|
|
2305
|
-
const viewOnceVersion = message.viewOnceVersion || message.viewOnce
|
|
2306
|
-
if (viewOnceVersion === 'v2' || viewOnceVersion === 2) {
|
|
2307
|
-
m = { viewOnceMessageV2: { message: m } }
|
|
2308
|
-
} else if (viewOnceVersion === 'v2ext' || viewOnceVersion === 'v2extension') {
|
|
2309
|
-
m = { viewOnceMessageV2Extension: { message: m } }
|
|
2310
|
-
} else {
|
|
2311
|
-
m = { viewOnceMessage: { message: m } }
|
|
2312
|
-
}
|
|
2313
|
-
}
|
|
2314
|
-
if (hasOptionalProperty(message, 'documentWithCaption') && !!message.documentWithCaption) {
|
|
2315
|
-
m = { documentWithCaptionMessage: { message: m } }
|
|
2316
|
-
}
|
|
2317
|
-
if (hasOptionalProperty(message, 'ephemeral') && !!message.ephemeral) {
|
|
2318
|
-
m = { ephemeralMessage: { message: m } }
|
|
2319
|
-
}
|
|
2320
|
-
if (hasOptionalProperty(message, 'groupMentioned') && !!message.groupMentioned) {
|
|
2321
|
-
m = { groupMentionedMessage: { message: m } }
|
|
2322
|
-
}
|
|
2323
|
-
if ('groupStatus' in message && !!message.groupStatus) {
|
|
2324
|
-
m = { groupStatusMessage: { message: m } }
|
|
2325
|
-
}
|
|
2326
|
-
if (
|
|
2327
|
-
(hasOptionalProperty(message, 'mentions') && message.mentions?.length) ||
|
|
2328
|
-
(hasOptionalProperty(message, 'mentionAll') && message.mentionAll)
|
|
2329
|
-
) {
|
|
2330
|
-
const normalizedMentions = await (0, jid_display_normalization_1.normalizeMentionedJidsForSend)(
|
|
2331
|
-
message.mentions,
|
|
2332
|
-
options.groupData,
|
|
2333
|
-
options.signalRepository,
|
|
2334
|
-
options.logger
|
|
2335
|
-
)
|
|
2336
|
-
const messageType = Object.keys(m)[0]
|
|
2337
|
-
const key = m[messageType]
|
|
2338
|
-
if (key && 'contextInfo' in key) {
|
|
2339
|
-
key.contextInfo = key.contextInfo || {}
|
|
2340
|
-
if (normalizedMentions?.length) {
|
|
2341
|
-
key.contextInfo.mentionedJid = normalizedMentions
|
|
2342
|
-
}
|
|
2343
|
-
if (message.mentionAll) {
|
|
2344
|
-
key.contextInfo.nonJidMentions = 1
|
|
2345
|
-
} else if (!key) {
|
|
2346
|
-
key.contextInfo = {
|
|
2347
|
-
mentionedJid: normalizedMentions,
|
|
2348
|
-
nonJidMentions: message.mentionAll ? 1 : 0
|
|
2349
|
-
}
|
|
2350
|
-
}
|
|
2351
|
-
}
|
|
2352
|
-
}
|
|
2353
|
-
if (hasOptionalProperty(message, 'edit')) {
|
|
2354
|
-
m = {
|
|
2355
|
-
protocolMessage: {
|
|
2356
|
-
key: message.edit,
|
|
2357
|
-
editedMessage: m,
|
|
2358
|
-
timestampMs: Date.now(),
|
|
2359
|
-
type: WAProto_1.proto.Message.ProtocolMessage.Type.MESSAGE_EDIT
|
|
2360
|
-
}
|
|
2361
|
-
}
|
|
2362
|
-
}
|
|
2363
|
-
if (hasOptionalProperty(message, 'contextInfo') && !!message.contextInfo) {
|
|
2364
|
-
const messageType = Object.keys(m)[0]
|
|
2365
|
-
const key = m[messageType]
|
|
2366
|
-
if ('contextInfo' in key && !!key.contextInfo) {
|
|
2367
|
-
key.contextInfo = { ...key.contextInfo, ...message.contextInfo }
|
|
2368
|
-
} else if (key) {
|
|
2369
|
-
key.contextInfo = message.contextInfo
|
|
2370
|
-
}
|
|
2371
|
-
}
|
|
2372
|
-
if ((0, reporting_utils_1.shouldIncludeReportingToken)(m) && !(0, WABinary_1.isInteropUser)(options.jid)) {
|
|
2373
|
-
m.messageContextInfo = m.messageContextInfo || {}
|
|
2374
|
-
if (!m.messageContextInfo.messageSecret) {
|
|
2375
|
-
m.messageContextInfo.messageSecret = (0, crypto_1.randomBytes)(32)
|
|
2376
|
-
}
|
|
2377
|
-
}
|
|
2378
|
-
|
|
2379
|
-
if ('externalAdReply' in message && !!message.externalAdReply) {
|
|
2380
|
-
const wrappers = [
|
|
2381
|
-
'viewOnceMessage',
|
|
2382
|
-
'viewOnceMessageV2',
|
|
2383
|
-
'viewOnceMessageV2Extension',
|
|
2384
|
-
'ephemeralMessage',
|
|
2385
|
-
'groupStatusMessage',
|
|
2386
|
-
'templateMessage'
|
|
2387
|
-
]
|
|
2388
|
-
const [outerType] = Object.keys(m)
|
|
2389
|
-
const inner = wrappers.includes(outerType) ? m[outerType].message : m
|
|
2390
|
-
const [innerType] = Object.keys(inner)
|
|
2391
|
-
const innerPayload = innerType ? inner[innerType] : undefined
|
|
2392
|
-
if (innerType && innerType !== 'carouselMessage' && innerPayload && typeof innerPayload === 'object') {
|
|
2393
|
-
const ear = normalizeEarFields(message.externalAdReply)
|
|
2394
|
-
innerPayload.contextInfo = {
|
|
2395
|
-
...(innerPayload.contextInfo || {}),
|
|
2396
|
-
externalAdReply: ear
|
|
2397
|
-
}
|
|
2398
|
-
}
|
|
2399
|
-
}
|
|
2400
|
-
if ('secureMetaServiceLabel' in message && !!message.secureMetaServiceLabel) {
|
|
2401
|
-
const [messageType] = Object.keys(m)
|
|
2402
|
-
m[messageType] = m[messageType] || {}
|
|
2403
|
-
m[messageType].contextInfo = {
|
|
2404
|
-
...(m[messageType].contextInfo || {}),
|
|
2405
|
-
secureMetaServiceLabel: 1
|
|
2406
|
-
}
|
|
2407
|
-
}
|
|
2408
|
-
|
|
2409
|
-
return WAProto_1.proto.Message.create(m)
|
|
2410
|
-
}
|
|
2411
|
-
exports.generateWAMessageContent = generateWAMessageContent
|
|
2412
|
-
const generateWAMessageFromContent = (jid, message, options) => {
|
|
2413
|
-
// set timestamp to now
|
|
2414
|
-
// if not specified
|
|
2415
|
-
if (!options.timestamp) {
|
|
2416
|
-
options.timestamp = new Date()
|
|
2417
|
-
}
|
|
2418
|
-
const innerMessage = (0, exports.normalizeMessageContent)(message)
|
|
2419
|
-
const key = (0, exports.getContentType)(innerMessage)
|
|
2420
|
-
const timestamp = (0, generics_1.unixTimestampSeconds)(options.timestamp)
|
|
2421
|
-
const { quoted, userJid } = options
|
|
2422
|
-
if (quoted && !(0, WABinary_1.isJidNewsletter)(jid)) {
|
|
2423
|
-
const participant = quoted.key.fromMe
|
|
2424
|
-
? userJid // TODO: Add support for LIDs
|
|
2425
|
-
: quoted.participant || quoted.key.participant || quoted.key.remoteJid
|
|
2426
|
-
let quotedMsg = (0, exports.normalizeMessageContent)(quoted.message)
|
|
2427
|
-
const msgType = (0, exports.getContentType)(quotedMsg)
|
|
2428
|
-
// strip any redundant properties
|
|
2429
|
-
quotedMsg = index_js_1.proto.Message.create({ [msgType]: quotedMsg[msgType] })
|
|
2430
|
-
const quotedContent = quotedMsg[msgType]
|
|
2431
|
-
if (typeof quotedContent === 'object' && quotedContent && 'contextInfo' in quotedContent) {
|
|
2432
|
-
delete quotedContent.contextInfo
|
|
2433
|
-
}
|
|
2434
|
-
const contextInfo = ('contextInfo' in innerMessage[key] && innerMessage[key]?.contextInfo) || {}
|
|
2435
|
-
contextInfo.participant = (0, WABinary_1.jidNormalizedUser)(participant)
|
|
2436
|
-
contextInfo.stanzaId = quoted.key.id
|
|
2437
|
-
contextInfo.quotedMessage = quotedMsg
|
|
2438
|
-
// if a participant is quoted, then it must be a group
|
|
2439
|
-
// hence, remoteJid of group must also be entered
|
|
2440
|
-
if (jid !== quoted.key.remoteJid) {
|
|
2441
|
-
contextInfo.remoteJid = quoted.key.remoteJid
|
|
2442
|
-
}
|
|
2443
|
-
if (contextInfo && innerMessage[key]) {
|
|
2444
|
-
/* @ts-ignore */
|
|
2445
|
-
innerMessage[key].contextInfo = contextInfo
|
|
2446
|
-
}
|
|
2447
|
-
}
|
|
2448
|
-
if (
|
|
2449
|
-
// if we want to send a disappearing message
|
|
2450
|
-
!!options.ephemeralExpiration &&
|
|
2451
|
-
// and it's not a protocol message -- delete, toggle disappear message
|
|
2452
|
-
key !== 'protocolMessage' &&
|
|
2453
|
-
// already not converted to disappearing message
|
|
2454
|
-
key !== 'ephemeralMessage' &&
|
|
2455
|
-
// newsletters don't support ephemeral messages
|
|
2456
|
-
!(0, WABinary_1.isJidNewsletter)(jid)
|
|
2457
|
-
) {
|
|
2458
|
-
/* @ts-ignore */
|
|
2459
|
-
innerMessage[key].contextInfo = {
|
|
2460
|
-
...(innerMessage[key].contextInfo || {}),
|
|
2461
|
-
expiration: options.ephemeralExpiration || Defaults_1.WA_DEFAULT_EPHEMERAL
|
|
2462
|
-
//ephemeralSettingTimestamp: options.ephemeralOptions.eph_setting_ts?.toString()
|
|
2463
|
-
}
|
|
2464
|
-
}
|
|
2465
|
-
message = WAProto_1.proto.Message.create(message)
|
|
2466
|
-
const iosBros = options?.browser?.[0] === 'iOS' || options?.browser?.[1] === 'Safari'
|
|
2467
|
-
const androidBros = options?.browser?.[0] === 'Android'
|
|
2468
|
-
const pickedMessageId =
|
|
2469
|
-
options?.messageId ||
|
|
2470
|
-
(iosBros
|
|
2471
|
-
? (0, generics_1.generateIOSMessageID)()
|
|
2472
|
-
: androidBros
|
|
2473
|
-
? (0, generics_1.generateAndroMessageID)()
|
|
2474
|
-
: (0, generics_1.generateMessageIDV2)(userJid))
|
|
2475
|
-
const messageJSON = {
|
|
2476
|
-
key: {
|
|
2477
|
-
remoteJid: jid,
|
|
2478
|
-
fromMe: true,
|
|
2479
|
-
id: pickedMessageId
|
|
2480
|
-
},
|
|
2481
|
-
message: message,
|
|
2482
|
-
messageTimestamp: timestamp,
|
|
2483
|
-
messageStubParameters: [],
|
|
2484
|
-
participant: (0, WABinary_1.isJidGroup)(jid) || (0, WABinary_1.isJidStatusBroadcast)(jid) ? userJid : undefined, // TODO: Add support for LIDs
|
|
2485
|
-
status: Types_1.WAMessageStatus.PENDING
|
|
2486
|
-
}
|
|
2487
|
-
return WAProto_1.proto.WebMessageInfo.fromObject(messageJSON)
|
|
2488
|
-
}
|
|
2489
|
-
exports.generateWAMessageFromContent = generateWAMessageFromContent
|
|
2490
|
-
const generateWAMessage = async (jid, content, options) => {
|
|
2491
|
-
// ensure msg ID is with every log
|
|
2492
|
-
options.logger = options?.logger?.child({ msgId: options.messageId })
|
|
2493
|
-
// Pass jid in the options to generateWAMessageContent
|
|
2494
|
-
return (0, exports.generateWAMessageFromContent)(
|
|
2495
|
-
jid,
|
|
2496
|
-
await (0, exports.generateWAMessageContent)(content, { ...options, jid }),
|
|
2497
|
-
options
|
|
2498
|
-
)
|
|
2499
|
-
}
|
|
2500
|
-
exports.generateWAMessage = generateWAMessage
|
|
665
|
+
else if ('botInvoke' in message && !!message.botInvoke) {
|
|
666
|
+
m = {
|
|
667
|
+
botInvokeMessage: {
|
|
668
|
+
message: message.botInvoke
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
}
|
|
672
|
+
else if (hasNonNullishProperty(message, 'text')) {
|
|
673
|
+
const extContent = { text: message.text };
|
|
674
|
+
let urlInfo = message.linkPreview;
|
|
675
|
+
if (typeof urlInfo === 'undefined') {
|
|
676
|
+
urlInfo = await generateLinkPreviewIfRequired(message.text, options.getUrlInfo, options.logger);
|
|
677
|
+
}
|
|
678
|
+
if (urlInfo) {
|
|
679
|
+
extContent.matchedText = urlInfo['matched-text'];
|
|
680
|
+
extContent.jpegThumbnail = urlInfo.jpegThumbnail;
|
|
681
|
+
extContent.description = urlInfo.description;
|
|
682
|
+
extContent.title = urlInfo.title;
|
|
683
|
+
extContent.previewType = 0;
|
|
684
|
+
const img = urlInfo.highQualityThumbnail;
|
|
685
|
+
if (img) {
|
|
686
|
+
extContent.thumbnailDirectPath = img.directPath;
|
|
687
|
+
extContent.mediaKey = img.mediaKey;
|
|
688
|
+
extContent.mediaKeyTimestamp = img.mediaKeyTimestamp;
|
|
689
|
+
extContent.thumbnailWidth = img.width;
|
|
690
|
+
extContent.thumbnailHeight = img.height;
|
|
691
|
+
extContent.thumbnailSha256 = img.fileSha256;
|
|
692
|
+
extContent.thumbnailEncSha256 = img.fileEncSha256;
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
if (options.backgroundColor) {
|
|
696
|
+
extContent.backgroundArgb = await assertColor(options.backgroundColor);
|
|
697
|
+
}
|
|
698
|
+
if (options.font) {
|
|
699
|
+
extContent.font = options.font;
|
|
700
|
+
}
|
|
701
|
+
m.extendedTextMessage = extContent;
|
|
702
|
+
}
|
|
703
|
+
else if (hasNonNullishProperty(message, 'contacts')) {
|
|
704
|
+
const contactLen = message.contacts.contacts.length;
|
|
705
|
+
if (!contactLen) {
|
|
706
|
+
throw new Boom('require atleast 1 contact', { statusCode: 400 });
|
|
707
|
+
}
|
|
708
|
+
if (contactLen === 1) {
|
|
709
|
+
m.contactMessage = WAProto.Message.ContactMessage.create(message.contacts.contacts[0]);
|
|
710
|
+
}
|
|
711
|
+
else {
|
|
712
|
+
m.contactsArrayMessage = WAProto.Message.ContactsArrayMessage.create(message.contacts);
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
else if (hasNonNullishProperty(message, 'location')) {
|
|
716
|
+
m.locationMessage = WAProto.Message.LocationMessage.create(message.location);
|
|
717
|
+
}
|
|
718
|
+
else if (hasNonNullishProperty(message, 'react')) {
|
|
719
|
+
if (!message.react.senderTimestampMs) {
|
|
720
|
+
message.react.senderTimestampMs = Date.now();
|
|
721
|
+
}
|
|
722
|
+
m.reactionMessage = WAProto.Message.ReactionMessage.create(message.react);
|
|
723
|
+
}
|
|
724
|
+
else if (hasNonNullishProperty(message, 'delete')) {
|
|
725
|
+
m.protocolMessage = {
|
|
726
|
+
key: message.delete,
|
|
727
|
+
type: WAProto.Message.ProtocolMessage.Type.REVOKE
|
|
728
|
+
};
|
|
729
|
+
}
|
|
730
|
+
else if (hasNonNullishProperty(message, 'forward')) {
|
|
731
|
+
m = generateForwardMessageContent(message.forward, message.force);
|
|
732
|
+
}
|
|
733
|
+
else if (hasNonNullishProperty(message, 'disappearingMessagesInChat')) {
|
|
734
|
+
const exp = typeof message.disappearingMessagesInChat === 'boolean'
|
|
735
|
+
? message.disappearingMessagesInChat
|
|
736
|
+
? WA_DEFAULT_EPHEMERAL
|
|
737
|
+
: 0
|
|
738
|
+
: message.disappearingMessagesInChat;
|
|
739
|
+
m = prepareDisappearingMessageSettingContent(exp);
|
|
740
|
+
}
|
|
741
|
+
else if (hasNonNullishProperty(message, 'groupInvite')) {
|
|
742
|
+
m.groupInviteMessage = {};
|
|
743
|
+
m.groupInviteMessage.inviteCode = message.groupInvite.inviteCode;
|
|
744
|
+
m.groupInviteMessage.inviteExpiration = message.groupInvite.inviteExpiration;
|
|
745
|
+
m.groupInviteMessage.caption = message.groupInvite.text;
|
|
746
|
+
m.groupInviteMessage.groupJid = message.groupInvite.jid;
|
|
747
|
+
m.groupInviteMessage.groupName = message.groupInvite.subject;
|
|
748
|
+
//TODO: use built-in interface and get disappearing mode info etc.
|
|
749
|
+
//TODO: cache / use store!?
|
|
750
|
+
if (options.getProfilePicUrl) {
|
|
751
|
+
const pfpUrl = await options.getProfilePicUrl(message.groupInvite.jid, 'preview');
|
|
752
|
+
if (pfpUrl) {
|
|
753
|
+
const resp = await fetch(pfpUrl, { method: 'GET', dispatcher: options?.options?.dispatcher });
|
|
754
|
+
if (resp.ok) {
|
|
755
|
+
const buf = Buffer.from(await resp.arrayBuffer());
|
|
756
|
+
m.groupInviteMessage.jpegThumbnail = buf;
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
else if (hasNonNullishProperty(message, 'pin')) {
|
|
762
|
+
m.pinInChatMessage = {};
|
|
763
|
+
m.messageContextInfo = {};
|
|
764
|
+
m.pinInChatMessage.key = message.pin;
|
|
765
|
+
m.pinInChatMessage.type = message.type;
|
|
766
|
+
m.pinInChatMessage.senderTimestampMs = Date.now();
|
|
767
|
+
m.messageContextInfo.messageAddOnDurationInSecs = message.type === 1 ? message.time || 86400 : 0;
|
|
768
|
+
}
|
|
769
|
+
else if (hasNonNullishProperty(message, 'buttonReply')) {
|
|
770
|
+
switch (message.type) {
|
|
771
|
+
case 'template':
|
|
772
|
+
m.templateButtonReplyMessage = {
|
|
773
|
+
selectedDisplayText: message.buttonReply.displayText,
|
|
774
|
+
selectedId: message.buttonReply.id,
|
|
775
|
+
selectedIndex: message.buttonReply.index
|
|
776
|
+
};
|
|
777
|
+
break;
|
|
778
|
+
case 'plain':
|
|
779
|
+
m.buttonsResponseMessage = {
|
|
780
|
+
selectedButtonId: message.buttonReply.id,
|
|
781
|
+
selectedDisplayText: message.buttonReply.displayText,
|
|
782
|
+
type: proto.Message.ButtonsResponseMessage.Type.DISPLAY_TEXT
|
|
783
|
+
};
|
|
784
|
+
break;
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
else if (hasOptionalProperty(message, 'ptv') && message.ptv) {
|
|
788
|
+
const { videoMessage } = await prepareWAMessageMedia({ video: message.ptv }, options);
|
|
789
|
+
m.ptvMessage = videoMessage;
|
|
790
|
+
}
|
|
791
|
+
else if (hasNonNullishProperty(message, 'product')) {
|
|
792
|
+
const { imageMessage } = await prepareWAMessageMedia({ image: message.product.productImage }, options);
|
|
793
|
+
m.productMessage = WAProto.Message.ProductMessage.create({
|
|
794
|
+
...message,
|
|
795
|
+
product: {
|
|
796
|
+
...message.product,
|
|
797
|
+
productImage: imageMessage
|
|
798
|
+
}
|
|
799
|
+
});
|
|
800
|
+
}
|
|
801
|
+
else if (hasNonNullishProperty(message, 'listReply')) {
|
|
802
|
+
m.listResponseMessage = { ...message.listReply };
|
|
803
|
+
}
|
|
804
|
+
else if (hasNonNullishProperty(message, 'event')) {
|
|
805
|
+
m.eventMessage = {};
|
|
806
|
+
const startTime = Math.floor(message.event.startDate.getTime() / 1000);
|
|
807
|
+
if (message.event.call && options.getCallLink) {
|
|
808
|
+
const token = await options.getCallLink(message.event.call, { startTime });
|
|
809
|
+
m.eventMessage.joinLink = (message.event.call === 'audio' ? CALL_AUDIO_PREFIX : CALL_VIDEO_PREFIX) + token;
|
|
810
|
+
}
|
|
811
|
+
m.messageContextInfo = {
|
|
812
|
+
// encKey
|
|
813
|
+
messageSecret: message.event.messageSecret || randomBytes(32)
|
|
814
|
+
};
|
|
815
|
+
m.eventMessage.name = message.event.name;
|
|
816
|
+
m.eventMessage.description = message.event.description;
|
|
817
|
+
m.eventMessage.startTime = startTime;
|
|
818
|
+
m.eventMessage.endTime = message.event.endDate ? message.event.endDate.getTime() / 1000 : undefined;
|
|
819
|
+
m.eventMessage.isCanceled = message.event.isCancelled ?? false;
|
|
820
|
+
m.eventMessage.extraGuestsAllowed = message.event.extraGuestsAllowed;
|
|
821
|
+
m.eventMessage.isScheduleCall = message.event.isScheduleCall ?? false;
|
|
822
|
+
m.eventMessage.location = message.event.location;
|
|
823
|
+
}
|
|
824
|
+
else if (hasNonNullishProperty(message, 'poll')) {
|
|
825
|
+
(_a = message.poll).selectableCount || (_a.selectableCount = 0);
|
|
826
|
+
(_b = message.poll).toAnnouncementGroup || (_b.toAnnouncementGroup = false);
|
|
827
|
+
if (!Array.isArray(message.poll.values)) {
|
|
828
|
+
throw new Boom('Invalid poll values', { statusCode: 400 });
|
|
829
|
+
}
|
|
830
|
+
if (message.poll.selectableCount < 0 || message.poll.selectableCount > message.poll.values.length) {
|
|
831
|
+
throw new Boom(`poll.selectableCount in poll should be >= 0 and <= ${message.poll.values.length}`, {
|
|
832
|
+
statusCode: 400
|
|
833
|
+
});
|
|
834
|
+
}
|
|
835
|
+
m.messageContextInfo = {
|
|
836
|
+
// encKey
|
|
837
|
+
messageSecret: message.poll.messageSecret || randomBytes(32)
|
|
838
|
+
};
|
|
839
|
+
const pollCreationMessage = {
|
|
840
|
+
name: message.poll.name,
|
|
841
|
+
selectableOptionsCount: message.poll.selectableCount,
|
|
842
|
+
options: message.poll.values.map(optionName => ({ optionName }))
|
|
843
|
+
};
|
|
844
|
+
if (message.poll.toAnnouncementGroup) {
|
|
845
|
+
// poll v2 is for community announcement groups (single select and multiple)
|
|
846
|
+
m.pollCreationMessageV2 = pollCreationMessage;
|
|
847
|
+
}
|
|
848
|
+
else {
|
|
849
|
+
if (message.poll.selectableCount === 1) {
|
|
850
|
+
//poll v3 is for single select polls
|
|
851
|
+
m.pollCreationMessageV3 = pollCreationMessage;
|
|
852
|
+
}
|
|
853
|
+
else {
|
|
854
|
+
// poll for multiple choice polls
|
|
855
|
+
m.pollCreationMessage = pollCreationMessage;
|
|
856
|
+
}
|
|
857
|
+
}
|
|
858
|
+
}
|
|
859
|
+
else if (hasNonNullishProperty(message, 'album')) {
|
|
860
|
+
m.albumMessage = {
|
|
861
|
+
expectedImageCount: message.album.expectedImageCount,
|
|
862
|
+
expectedVideoCount: message.album.expectedVideoCount
|
|
863
|
+
};
|
|
864
|
+
}
|
|
865
|
+
else if (hasNonNullishProperty(message, 'sharePhoneNumber')) {
|
|
866
|
+
m.protocolMessage = {
|
|
867
|
+
type: proto.Message.ProtocolMessage.Type.SHARE_PHONE_NUMBER
|
|
868
|
+
};
|
|
869
|
+
}
|
|
870
|
+
else if (hasNonNullishProperty(message, 'requestPhoneNumber')) {
|
|
871
|
+
m.requestPhoneNumberMessage = {};
|
|
872
|
+
}
|
|
873
|
+
else if (hasNonNullishProperty(message, 'limitSharing')) {
|
|
874
|
+
m.protocolMessage = {
|
|
875
|
+
type: proto.Message.ProtocolMessage.Type.LIMIT_SHARING,
|
|
876
|
+
limitSharing: {
|
|
877
|
+
sharingLimited: message.limitSharing === true,
|
|
878
|
+
trigger: 1,
|
|
879
|
+
limitSharingSettingTimestamp: Date.now(),
|
|
880
|
+
initiatedByMe: true
|
|
881
|
+
}
|
|
882
|
+
};
|
|
883
|
+
}
|
|
884
|
+
else if (hasNonNullishProperty(message, 'stickerPacks')) {
|
|
885
|
+
const pack = message.stickerPacks;
|
|
886
|
+
const rawStickers = Array.isArray(pack.stickers) ? pack.stickers : [];
|
|
887
|
+
if (rawStickers.length === 0) {
|
|
888
|
+
throw new Boom('stickerPacks.stickers must have at least one sticker', { statusCode: 400 });
|
|
889
|
+
}
|
|
890
|
+
const stickerBuffers = await Promise.all(rawStickers.map(s => resolveStickerBuffer(s, options.options)));
|
|
891
|
+
const zipEntries = stickerBuffers.map((data, i) => ({ name: `sticker_${i}.webp`, data }));
|
|
892
|
+
const archive = buildZipArchive(zipEntries);
|
|
893
|
+
const packName = pack.name || 'Sticker Pack';
|
|
894
|
+
const captionParts = [];
|
|
895
|
+
if (pack.publisher) captionParts.push(`Publisher: ${pack.publisher}`);
|
|
896
|
+
if (pack.author) captionParts.push(`Author: ${pack.author}`);
|
|
897
|
+
// sent as a plain .zip document through the normal, well-tested upload path
|
|
898
|
+
m = await prepareWAMessageMedia({
|
|
899
|
+
document: archive,
|
|
900
|
+
mimetype: 'application/zip',
|
|
901
|
+
fileName: `${packName}.zip`,
|
|
902
|
+
caption: captionParts.length ? captionParts.join('\n') : undefined
|
|
903
|
+
}, options);
|
|
904
|
+
}
|
|
905
|
+
else if (hasNonNullishProperty(message, 'sticker') && (message.pack || message.author || message.isPrivate || message.premium || message.animated)) {
|
|
906
|
+
const rawBuffer = await resolveStickerBuffer(message.sticker, options.options);
|
|
907
|
+
const finalWebp = await makeSticker(rawBuffer, {
|
|
908
|
+
pack: message.pack || '',
|
|
909
|
+
author: message.author || '',
|
|
910
|
+
emojis: message.emojis || [],
|
|
911
|
+
isPrivate: !!message.isPrivate,
|
|
912
|
+
animated: !!message.animated,
|
|
913
|
+
quality: message.quality || 60
|
|
914
|
+
});
|
|
915
|
+
m = await prepareWAMessageMedia({ sticker: finalWebp }, options);
|
|
916
|
+
if (m.stickerMessage) {
|
|
917
|
+
if (message.premium) {
|
|
918
|
+
m.stickerMessage.premium = typeof message.premium === 'number' ? message.premium : 1;
|
|
919
|
+
}
|
|
920
|
+
if (message.isPrivate) {
|
|
921
|
+
m.stickerMessage.isAvatar = true;
|
|
922
|
+
}
|
|
923
|
+
}
|
|
924
|
+
}
|
|
925
|
+
else {
|
|
926
|
+
const rawProtoKey = RAW_PROTO_MESSAGE_KEYS.find(k => hasNonNullishProperty(message, k));
|
|
927
|
+
if (rawProtoKey) {
|
|
928
|
+
const built = proto.Message.fromObject({ [rawProtoKey]: message[rawProtoKey] });
|
|
929
|
+
m = { [rawProtoKey]: built[rawProtoKey] };
|
|
930
|
+
}
|
|
931
|
+
else {
|
|
932
|
+
m = await prepareWAMessageMedia(message, options);
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
if (hasOptionalProperty(message, 'viewOnce') && !!message.viewOnce) {
|
|
936
|
+
m = { viewOnceMessage: { message: m } };
|
|
937
|
+
}
|
|
938
|
+
if ((hasOptionalProperty(message, 'mentions') && message.mentions?.length) ||
|
|
939
|
+
(hasOptionalProperty(message, 'mentionAll') && message.mentionAll)) {
|
|
940
|
+
const messageType = Object.keys(m)[0];
|
|
941
|
+
const key = m[messageType];
|
|
942
|
+
if (key && 'contextInfo' in key) {
|
|
943
|
+
key.contextInfo = key.contextInfo || {};
|
|
944
|
+
if (message.mentions?.length) {
|
|
945
|
+
key.contextInfo.mentionedJid = message.mentions;
|
|
946
|
+
}
|
|
947
|
+
if (message.mentionAll) {
|
|
948
|
+
key.contextInfo.nonJidMentions = 1;
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
else if (key) {
|
|
952
|
+
key.contextInfo = {
|
|
953
|
+
mentionedJid: message.mentions,
|
|
954
|
+
nonJidMentions: message.mentionAll ? 1 : 0
|
|
955
|
+
};
|
|
956
|
+
}
|
|
957
|
+
}
|
|
958
|
+
if (hasOptionalProperty(message, 'edit')) {
|
|
959
|
+
m = {
|
|
960
|
+
protocolMessage: {
|
|
961
|
+
key: message.edit,
|
|
962
|
+
editedMessage: m,
|
|
963
|
+
timestampMs: Date.now(),
|
|
964
|
+
type: WAProto.Message.ProtocolMessage.Type.MESSAGE_EDIT
|
|
965
|
+
}
|
|
966
|
+
};
|
|
967
|
+
}
|
|
968
|
+
if (hasOptionalProperty(message, 'contextInfo') && !!message.contextInfo) {
|
|
969
|
+
const messageType = Object.keys(m)[0];
|
|
970
|
+
const key = m[messageType];
|
|
971
|
+
if ('contextInfo' in key && !!key.contextInfo) {
|
|
972
|
+
key.contextInfo = { ...key.contextInfo, ...message.contextInfo };
|
|
973
|
+
}
|
|
974
|
+
else if (key) {
|
|
975
|
+
key.contextInfo = message.contextInfo;
|
|
976
|
+
}
|
|
977
|
+
}
|
|
978
|
+
if (hasOptionalProperty(message, 'albumParentKey') && !!message.albumParentKey) {
|
|
979
|
+
m.messageContextInfo = {
|
|
980
|
+
...m.messageContextInfo,
|
|
981
|
+
messageAssociation: {
|
|
982
|
+
associationType: WAProto.MessageAssociation.AssociationType.MEDIA_ALBUM,
|
|
983
|
+
parentMessageKey: message.albumParentKey
|
|
984
|
+
}
|
|
985
|
+
};
|
|
986
|
+
}
|
|
987
|
+
if (shouldIncludeReportingToken(m)) {
|
|
988
|
+
m.messageContextInfo = m.messageContextInfo || {};
|
|
989
|
+
if (!m.messageContextInfo.messageSecret) {
|
|
990
|
+
m.messageContextInfo.messageSecret = randomBytes(32);
|
|
991
|
+
}
|
|
992
|
+
}
|
|
993
|
+
return WAProto.Message.create(m);
|
|
994
|
+
};
|
|
995
|
+
export const generateWAMessageFromContent = (jid, message, options) => {
|
|
996
|
+
// set timestamp to now
|
|
997
|
+
// if not specified
|
|
998
|
+
if (!options.timestamp) {
|
|
999
|
+
options.timestamp = new Date();
|
|
1000
|
+
}
|
|
1001
|
+
const innerMessage = normalizeMessageContent(message);
|
|
1002
|
+
const key = getContentType(innerMessage);
|
|
1003
|
+
const timestamp = unixTimestampSeconds(options.timestamp);
|
|
1004
|
+
const { quoted, userJid } = options;
|
|
1005
|
+
if (quoted && !isJidNewsletter(jid)) {
|
|
1006
|
+
const participant = quoted.key.fromMe
|
|
1007
|
+
? userJid // TODO: Add support for LIDs
|
|
1008
|
+
: quoted.participant || quoted.key.participant || quoted.key.remoteJid;
|
|
1009
|
+
let quotedMsg = normalizeMessageContent(quoted.message);
|
|
1010
|
+
const msgType = getContentType(quotedMsg);
|
|
1011
|
+
// strip any redundant properties
|
|
1012
|
+
quotedMsg = proto.Message.create({ [msgType]: quotedMsg[msgType] });
|
|
1013
|
+
const quotedContent = quotedMsg[msgType];
|
|
1014
|
+
if (typeof quotedContent === 'object' && quotedContent && 'contextInfo' in quotedContent) {
|
|
1015
|
+
delete quotedContent.contextInfo;
|
|
1016
|
+
}
|
|
1017
|
+
const contextInfo = ('contextInfo' in innerMessage[key] && innerMessage[key]?.contextInfo) || {};
|
|
1018
|
+
contextInfo.participant = jidNormalizedUser(participant);
|
|
1019
|
+
contextInfo.stanzaId = quoted.key.id;
|
|
1020
|
+
contextInfo.quotedMessage = quotedMsg;
|
|
1021
|
+
// if a participant is quoted, then it must be a group
|
|
1022
|
+
// hence, remoteJid of group must also be entered
|
|
1023
|
+
if (jid !== quoted.key.remoteJid) {
|
|
1024
|
+
contextInfo.remoteJid = quoted.key.remoteJid;
|
|
1025
|
+
}
|
|
1026
|
+
if (contextInfo && innerMessage[key]) {
|
|
1027
|
+
/* @ts-ignore */
|
|
1028
|
+
innerMessage[key].contextInfo = contextInfo;
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
if (
|
|
1032
|
+
// if we want to send a disappearing message
|
|
1033
|
+
!!options?.ephemeralExpiration &&
|
|
1034
|
+
// and it's not a protocol message -- delete, toggle disappear message
|
|
1035
|
+
key !== 'protocolMessage' &&
|
|
1036
|
+
// already not converted to disappearing message
|
|
1037
|
+
key !== 'ephemeralMessage' &&
|
|
1038
|
+
// newsletters don't support ephemeral messages
|
|
1039
|
+
!isJidNewsletter(jid)) {
|
|
1040
|
+
/* @ts-ignore */
|
|
1041
|
+
innerMessage[key].contextInfo = {
|
|
1042
|
+
...(innerMessage[key].contextInfo || {}),
|
|
1043
|
+
expiration: options.ephemeralExpiration || WA_DEFAULT_EPHEMERAL
|
|
1044
|
+
//ephemeralSettingTimestamp: options.ephemeralOptions.eph_setting_ts?.toString()
|
|
1045
|
+
};
|
|
1046
|
+
}
|
|
1047
|
+
message = WAProto.Message.create(message);
|
|
1048
|
+
const messageJSON = {
|
|
1049
|
+
key: {
|
|
1050
|
+
remoteJid: jid,
|
|
1051
|
+
fromMe: true,
|
|
1052
|
+
id: options?.messageId || generateMessageIDV2()
|
|
1053
|
+
},
|
|
1054
|
+
message: message,
|
|
1055
|
+
messageTimestamp: timestamp,
|
|
1056
|
+
messageStubParameters: [],
|
|
1057
|
+
participant: isJidGroup(jid) || isJidStatusBroadcast(jid) ? userJid : undefined, // TODO: Add support for LIDs
|
|
1058
|
+
status: WAMessageStatus.PENDING
|
|
1059
|
+
};
|
|
1060
|
+
return WAProto.WebMessageInfo.fromObject(messageJSON);
|
|
1061
|
+
};
|
|
1062
|
+
export const generateWAMessage = async (jid, content, options) => {
|
|
1063
|
+
// ensure msg ID is with every log
|
|
1064
|
+
options.logger = options?.logger?.child({ msgId: options.messageId });
|
|
1065
|
+
// Pass jid in the options to generateWAMessageContent
|
|
1066
|
+
return generateWAMessageFromContent(jid, await generateWAMessageContent(content, { ...options, jid }), options);
|
|
1067
|
+
};
|
|
2501
1068
|
/** Get the key to access the true type of content */
|
|
2502
|
-
const getContentType = content => {
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
}
|
|
2509
|
-
exports.getContentType = getContentType
|
|
1069
|
+
export const getContentType = (content) => {
|
|
1070
|
+
if (content) {
|
|
1071
|
+
const keys = Object.keys(content);
|
|
1072
|
+
const key = keys.find(k => (k === 'conversation' || k.includes('Message')) && k !== 'senderKeyDistributionMessage');
|
|
1073
|
+
return key;
|
|
1074
|
+
}
|
|
1075
|
+
};
|
|
2510
1076
|
/**
|
|
2511
1077
|
* Normalizes ephemeral, view once messages to regular message content
|
|
2512
1078
|
* Eg. image messages in ephemeral messages, in view once messages etc.
|
|
2513
1079
|
* @param content
|
|
2514
1080
|
* @returns
|
|
2515
1081
|
*/
|
|
2516
|
-
const normalizeMessageContent = content => {
|
|
2517
|
-
|
|
2518
|
-
|
|
2519
|
-
|
|
2520
|
-
|
|
2521
|
-
|
|
2522
|
-
|
|
2523
|
-
|
|
2524
|
-
|
|
2525
|
-
|
|
2526
|
-
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
|
|
2535
|
-
|
|
2536
|
-
|
|
2537
|
-
|
|
2538
|
-
|
|
2539
|
-
|
|
2540
|
-
|
|
2541
|
-
message.statusMentionMessage ||
|
|
2542
|
-
message.pollCreationOptionImageMessage ||
|
|
2543
|
-
message.associatedChildMessage ||
|
|
2544
|
-
message.groupStatusMentionMessage ||
|
|
2545
|
-
message.pollCreationMessageV4 ||
|
|
2546
|
-
message.pollCreationMessageV5 ||
|
|
2547
|
-
message.statusAddYours ||
|
|
2548
|
-
message.groupStatusMessage ||
|
|
2549
|
-
message.limitSharingMessage ||
|
|
2550
|
-
message.botTaskMessage ||
|
|
2551
|
-
message.questionMessage ||
|
|
2552
|
-
message.groupStatusMessageV2 ||
|
|
2553
|
-
message.botForwardedMessage ||
|
|
2554
|
-
message.questionReplyMessage ||
|
|
2555
|
-
message.newsletterAdminProfileMessage ||
|
|
2556
|
-
message.newsletterAdminProfileMessageV2 ||
|
|
2557
|
-
message.newsletterAdminProfileStatusMessage ||
|
|
2558
|
-
message.spoilerMessage ||
|
|
2559
|
-
message.groupStatusV3Message ||
|
|
2560
|
-
message.pollCreationMessageV6
|
|
2561
|
-
)
|
|
2562
|
-
}
|
|
2563
|
-
}
|
|
2564
|
-
exports.normalizeMessageContent = normalizeMessageContent
|
|
1082
|
+
export const normalizeMessageContent = (content) => {
|
|
1083
|
+
if (!content) {
|
|
1084
|
+
return undefined;
|
|
1085
|
+
}
|
|
1086
|
+
// set max iterations to prevent an infinite loop
|
|
1087
|
+
for (let i = 0; i < 5; i++) {
|
|
1088
|
+
const inner = getFutureProofMessage(content);
|
|
1089
|
+
if (!inner) {
|
|
1090
|
+
break;
|
|
1091
|
+
}
|
|
1092
|
+
content = inner.message;
|
|
1093
|
+
}
|
|
1094
|
+
return content;
|
|
1095
|
+
function getFutureProofMessage(message) {
|
|
1096
|
+
return (message?.ephemeralMessage ||
|
|
1097
|
+
message?.viewOnceMessage ||
|
|
1098
|
+
message?.documentWithCaptionMessage ||
|
|
1099
|
+
message?.viewOnceMessageV2 ||
|
|
1100
|
+
message?.viewOnceMessageV2Extension ||
|
|
1101
|
+
message?.editedMessage ||
|
|
1102
|
+
message?.associatedChildMessage ||
|
|
1103
|
+
message?.groupStatusMessage ||
|
|
1104
|
+
message?.groupStatusMessageV2);
|
|
1105
|
+
}
|
|
1106
|
+
};
|
|
2565
1107
|
/**
|
|
2566
1108
|
* Extract the true message content from a message
|
|
2567
1109
|
* Eg. extracts the inner message from a disappearing message/view once message
|
|
2568
1110
|
*/
|
|
2569
|
-
const extractMessageContent = content => {
|
|
2570
|
-
|
|
2571
|
-
|
|
2572
|
-
|
|
2573
|
-
|
|
2574
|
-
|
|
2575
|
-
|
|
2576
|
-
|
|
2577
|
-
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
|
|
2582
|
-
|
|
2583
|
-
|
|
2584
|
-
|
|
2585
|
-
|
|
2586
|
-
|
|
2587
|
-
|
|
2588
|
-
|
|
2589
|
-
|
|
2590
|
-
|
|
2591
|
-
|
|
2592
|
-
|
|
2593
|
-
|
|
2594
|
-
|
|
2595
|
-
|
|
2596
|
-
|
|
2597
|
-
|
|
2598
|
-
|
|
2599
|
-
|
|
2600
|
-
|
|
2601
|
-
|
|
1111
|
+
export const extractMessageContent = (content) => {
|
|
1112
|
+
const extractFromTemplateMessage = (msg) => {
|
|
1113
|
+
if (msg.imageMessage) {
|
|
1114
|
+
return { imageMessage: msg.imageMessage };
|
|
1115
|
+
}
|
|
1116
|
+
else if (msg.documentMessage) {
|
|
1117
|
+
return { documentMessage: msg.documentMessage };
|
|
1118
|
+
}
|
|
1119
|
+
else if (msg.videoMessage) {
|
|
1120
|
+
return { videoMessage: msg.videoMessage };
|
|
1121
|
+
}
|
|
1122
|
+
else if (msg.locationMessage) {
|
|
1123
|
+
return { locationMessage: msg.locationMessage };
|
|
1124
|
+
}
|
|
1125
|
+
else {
|
|
1126
|
+
return {
|
|
1127
|
+
conversation: 'contentText' in msg ? msg.contentText : 'hydratedContentText' in msg ? msg.hydratedContentText : ''
|
|
1128
|
+
};
|
|
1129
|
+
}
|
|
1130
|
+
};
|
|
1131
|
+
content = normalizeMessageContent(content);
|
|
1132
|
+
if (content?.buttonsMessage) {
|
|
1133
|
+
return extractFromTemplateMessage(content.buttonsMessage);
|
|
1134
|
+
}
|
|
1135
|
+
if (content?.templateMessage?.hydratedFourRowTemplate) {
|
|
1136
|
+
return extractFromTemplateMessage(content?.templateMessage?.hydratedFourRowTemplate);
|
|
1137
|
+
}
|
|
1138
|
+
if (content?.templateMessage?.hydratedTemplate) {
|
|
1139
|
+
return extractFromTemplateMessage(content?.templateMessage?.hydratedTemplate);
|
|
1140
|
+
}
|
|
1141
|
+
if (content?.templateMessage?.fourRowTemplate) {
|
|
1142
|
+
return extractFromTemplateMessage(content?.templateMessage?.fourRowTemplate);
|
|
1143
|
+
}
|
|
1144
|
+
return content;
|
|
1145
|
+
};
|
|
2602
1146
|
/**
|
|
2603
1147
|
* Returns the device predicted by message ID
|
|
2604
1148
|
*/
|
|
2605
|
-
const getDevice = id =>
|
|
2606
|
-
|
|
2607
|
-
|
|
2608
|
-
|
|
2609
|
-
|
|
2610
|
-
|
|
2611
|
-
|
|
2612
|
-
|
|
2613
|
-
|
|
2614
|
-
: 'api/baileys'
|
|
2615
|
-
exports.getDevice = getDevice
|
|
1149
|
+
export const getDevice = (id) => /^3A.{18}$/.test(id)
|
|
1150
|
+
? 'ios'
|
|
1151
|
+
: /^3E.{20}$/.test(id)
|
|
1152
|
+
? 'web'
|
|
1153
|
+
: /^(.{21}|.{32})$/.test(id)
|
|
1154
|
+
? 'android'
|
|
1155
|
+
: /^(3F|.{18}$)/.test(id)
|
|
1156
|
+
? 'desktop'
|
|
1157
|
+
: 'wa bot';
|
|
2616
1158
|
/** Upserts a receipt in the message */
|
|
2617
|
-
const updateMessageWithReceipt = (msg, receipt) => {
|
|
2618
|
-
|
|
2619
|
-
|
|
2620
|
-
|
|
2621
|
-
|
|
2622
|
-
|
|
2623
|
-
|
|
2624
|
-
|
|
2625
|
-
}
|
|
2626
|
-
|
|
1159
|
+
export const updateMessageWithReceipt = (msg, receipt) => {
|
|
1160
|
+
msg.userReceipt = msg.userReceipt || [];
|
|
1161
|
+
const recp = msg.userReceipt.find(m => m.userJid === receipt.userJid);
|
|
1162
|
+
if (recp) {
|
|
1163
|
+
Object.assign(recp, receipt);
|
|
1164
|
+
}
|
|
1165
|
+
else {
|
|
1166
|
+
msg.userReceipt.push(receipt);
|
|
1167
|
+
}
|
|
1168
|
+
};
|
|
2627
1169
|
/** Update the message with a new reaction */
|
|
2628
|
-
const updateMessageWithReaction = (msg, reaction) => {
|
|
2629
|
-
|
|
2630
|
-
|
|
2631
|
-
|
|
2632
|
-
|
|
2633
|
-
|
|
2634
|
-
}
|
|
2635
|
-
exports.updateMessageWithReaction = updateMessageWithReaction
|
|
1170
|
+
export const updateMessageWithReaction = (msg, reaction) => {
|
|
1171
|
+
const authorID = getKeyAuthor(reaction.key);
|
|
1172
|
+
const reactions = (msg.reactions || []).filter(r => getKeyAuthor(r.key) !== authorID);
|
|
1173
|
+
reaction.text = reaction.text || '';
|
|
1174
|
+
reactions.push(reaction);
|
|
1175
|
+
msg.reactions = reactions;
|
|
1176
|
+
};
|
|
2636
1177
|
/** Update the message with a new poll update */
|
|
2637
|
-
const updateMessageWithPollUpdate = (msg, update) => {
|
|
2638
|
-
|
|
2639
|
-
|
|
2640
|
-
|
|
2641
|
-
|
|
2642
|
-
|
|
2643
|
-
|
|
2644
|
-
|
|
2645
|
-
msg.pollUpdates = reactions
|
|
2646
|
-
}
|
|
2647
|
-
exports.updateMessageWithPollUpdate = updateMessageWithPollUpdate
|
|
1178
|
+
export const updateMessageWithPollUpdate = (msg, update) => {
|
|
1179
|
+
const authorID = getKeyAuthor(update.pollUpdateMessageKey);
|
|
1180
|
+
const reactions = (msg.pollUpdates || []).filter(r => getKeyAuthor(r.pollUpdateMessageKey) !== authorID);
|
|
1181
|
+
if (update.vote?.selectedOptions?.length) {
|
|
1182
|
+
reactions.push(update);
|
|
1183
|
+
}
|
|
1184
|
+
msg.pollUpdates = reactions;
|
|
1185
|
+
};
|
|
2648
1186
|
/** Update the message with a new event response */
|
|
2649
|
-
const updateMessageWithEventResponse = (msg, update) => {
|
|
2650
|
-
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
msg.eventResponses = responses
|
|
2656
|
-
}
|
|
2657
|
-
exports.updateMessageWithEventResponse = updateMessageWithEventResponse
|
|
1187
|
+
export const updateMessageWithEventResponse = (msg, update) => {
|
|
1188
|
+
const authorID = getKeyAuthor(update.eventResponseMessageKey);
|
|
1189
|
+
const responses = (msg.eventResponses || []).filter(r => getKeyAuthor(r.eventResponseMessageKey) !== authorID);
|
|
1190
|
+
responses.push(update);
|
|
1191
|
+
msg.eventResponses = responses;
|
|
1192
|
+
};
|
|
2658
1193
|
/**
|
|
2659
1194
|
* Aggregates all poll updates in a poll.
|
|
2660
1195
|
* @param msg the poll creation message
|
|
2661
1196
|
* @param meId your jid
|
|
2662
1197
|
* @returns A list of options & their voters
|
|
2663
1198
|
*/
|
|
2664
|
-
function getAggregateVotesInPollMessage({ message, pollUpdates }, meId) {
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
|
|
2681
|
-
|
|
2682
|
-
|
|
2683
|
-
|
|
2684
|
-
|
|
2685
|
-
|
|
2686
|
-
|
|
2687
|
-
|
|
2688
|
-
|
|
2689
|
-
|
|
2690
|
-
|
|
2691
|
-
|
|
2692
|
-
|
|
2693
|
-
|
|
2694
|
-
|
|
2695
|
-
|
|
2696
|
-
}
|
|
2697
|
-
voteHashMap[hash].voters.push((0, generics_1.getKeyAuthor)(update.pollUpdateMessageKey, meId))
|
|
2698
|
-
}
|
|
2699
|
-
}
|
|
2700
|
-
return Object.values(voteHashMap)
|
|
2701
|
-
}
|
|
2702
|
-
/** Given a list of message keys, aggregates them by chat & sender. Useful for sending read receipts in bulk */
|
|
2703
|
-
const aggregateMessageKeysNotFromMe = keys => {
|
|
2704
|
-
const keyMap = {}
|
|
2705
|
-
for (const { remoteJid, id, participant, fromMe, sts } of keys) {
|
|
2706
|
-
if (!fromMe) {
|
|
2707
|
-
const uqKey = `${remoteJid}:${participant || ''}`
|
|
2708
|
-
if (!keyMap[uqKey]) {
|
|
2709
|
-
keyMap[uqKey] = {
|
|
2710
|
-
jid: remoteJid,
|
|
2711
|
-
participant: participant,
|
|
2712
|
-
messageIds: [],
|
|
2713
|
-
// sts is per-message; kept only for single-message interop receipts
|
|
2714
|
-
sts: sts
|
|
2715
|
-
}
|
|
2716
|
-
} else if (keyMap[uqKey].sts !== sts) {
|
|
2717
|
-
// Multiple messages with different sts — can't aggregate a single sts
|
|
2718
|
-
keyMap[uqKey].sts = undefined
|
|
2719
|
-
}
|
|
2720
|
-
keyMap[uqKey].messageIds.push(id)
|
|
2721
|
-
}
|
|
2722
|
-
}
|
|
2723
|
-
return Object.values(keyMap)
|
|
2724
|
-
}
|
|
2725
|
-
exports.aggregateMessageKeysNotFromMe = aggregateMessageKeysNotFromMe
|
|
2726
|
-
|
|
2727
|
-
/**
|
|
2728
|
-
* Check if a WebMessageInfo has a scheduled reveal time (ConditionalRevealMessage)
|
|
2729
|
-
*/
|
|
2730
|
-
const isScheduledMessage = msg => !!msg?.scheduledMessageMetadata?.scheduledTime
|
|
2731
|
-
exports.isScheduledMessage = isScheduledMessage
|
|
2732
|
-
|
|
2733
|
-
/**
|
|
2734
|
-
* Get scheduled reveal time of a message as a Date, or null
|
|
2735
|
-
*/
|
|
2736
|
-
const getScheduledMessageTime = msg => {
|
|
2737
|
-
const t = msg?.scheduledMessageMetadata?.scheduledTime
|
|
2738
|
-
if (!t) return null
|
|
2739
|
-
return new Date(Number(t) * 1000)
|
|
2740
|
-
}
|
|
2741
|
-
exports.getScheduledMessageTime = getScheduledMessageTime
|
|
2742
|
-
|
|
2743
|
-
/**
|
|
2744
|
-
* Extract PaymentInfo from a WebMessageInfo (the payment status field, not the message content)
|
|
2745
|
-
*/
|
|
2746
|
-
const getMessagePaymentInfo = msg => msg?.paymentInfo || msg?.quotedPaymentInfo || null
|
|
2747
|
-
exports.getMessagePaymentInfo = getMessagePaymentInfo
|
|
2748
|
-
|
|
2749
|
-
/**
|
|
2750
|
-
* Get all comment metadata from a WebMessageInfo
|
|
2751
|
-
*/
|
|
2752
|
-
const getMessageCommentMetadata = msg => msg?.commentMetadata || null
|
|
2753
|
-
exports.getMessageCommentMetadata = getMessageCommentMetadata
|
|
2754
|
-
|
|
2755
|
-
/**
|
|
2756
|
-
* Get all message add-ons (reactions, poll updates, pins) from a WebMessageInfo
|
|
2757
|
-
*/
|
|
2758
|
-
const getMessageAddOns = msg => msg?.messageAddOns || []
|
|
2759
|
-
exports.getMessageAddOns = getMessageAddOns
|
|
2760
|
-
|
|
2761
|
-
/**
|
|
2762
|
-
* Get the quiz correct answer from a poll creation message, if it's a quiz
|
|
2763
|
-
*/
|
|
2764
|
-
const getPollCorrectAnswer = pollMsg => {
|
|
2765
|
-
const poll =
|
|
2766
|
-
pollMsg?.pollCreationMessage ||
|
|
2767
|
-
pollMsg?.pollCreationMessageV2 ||
|
|
2768
|
-
pollMsg?.pollCreationMessageV3 ||
|
|
2769
|
-
pollMsg?.pollCreationMessageV5 ||
|
|
2770
|
-
pollMsg?.pollCreationMessageV6
|
|
2771
|
-
if (!poll) return null
|
|
2772
|
-
const isQuiz = poll.pollType === WAProto_1.proto.Message.PollType?.QUIZ || poll.pollType === 1
|
|
2773
|
-
return isQuiz ? poll.correctAnswer?.optionName || null : null
|
|
1199
|
+
export function getAggregateVotesInPollMessage({ message, pollUpdates }, meId) {
|
|
1200
|
+
const opts = message?.pollCreationMessage?.options ||
|
|
1201
|
+
message?.pollCreationMessageV2?.options ||
|
|
1202
|
+
message?.pollCreationMessageV3?.options ||
|
|
1203
|
+
[];
|
|
1204
|
+
const voteHashMap = opts.reduce((acc, opt) => {
|
|
1205
|
+
const hash = sha256(Buffer.from(opt.optionName || '')).toString();
|
|
1206
|
+
acc[hash] = {
|
|
1207
|
+
name: opt.optionName || '',
|
|
1208
|
+
voters: []
|
|
1209
|
+
};
|
|
1210
|
+
return acc;
|
|
1211
|
+
}, {});
|
|
1212
|
+
for (const update of pollUpdates || []) {
|
|
1213
|
+
const { vote } = update;
|
|
1214
|
+
if (!vote) {
|
|
1215
|
+
continue;
|
|
1216
|
+
}
|
|
1217
|
+
for (const option of vote.selectedOptions || []) {
|
|
1218
|
+
const hash = option.toString();
|
|
1219
|
+
let data = voteHashMap[hash];
|
|
1220
|
+
if (!data) {
|
|
1221
|
+
voteHashMap[hash] = {
|
|
1222
|
+
name: 'Unknown',
|
|
1223
|
+
voters: []
|
|
1224
|
+
};
|
|
1225
|
+
data = voteHashMap[hash];
|
|
1226
|
+
}
|
|
1227
|
+
voteHashMap[hash].voters.push(getKeyAuthor(update.pollUpdateMessageKey, meId));
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
return Object.values(voteHashMap);
|
|
2774
1231
|
}
|
|
2775
|
-
exports.getPollCorrectAnswer = getPollCorrectAnswer
|
|
2776
|
-
|
|
2777
1232
|
/**
|
|
2778
1233
|
* Aggregates all event responses in an event message.
|
|
2779
1234
|
* @param msg the event creation message
|
|
2780
|
-
* @param
|
|
1235
|
+
* @param meId your jid
|
|
2781
1236
|
* @returns A list of response types & their responders
|
|
2782
1237
|
*/
|
|
2783
|
-
function getAggregateResponsesInEventMessage({ eventResponses },
|
|
2784
|
-
|
|
2785
|
-
|
|
2786
|
-
|
|
2787
|
-
|
|
2788
|
-
|
|
2789
|
-
|
|
2790
|
-
|
|
2791
|
-
|
|
2792
|
-
|
|
2793
|
-
|
|
2794
|
-
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
|
|
2799
|
-
}
|
|
2800
|
-
|
|
2801
|
-
return Object.values(responseMap)
|
|
1238
|
+
export function getAggregateResponsesInEventMessage({ eventResponses }, meId) {
|
|
1239
|
+
const responseTypes = ['GOING', 'NOT_GOING', 'MAYBE'];
|
|
1240
|
+
const responseMap = {};
|
|
1241
|
+
for (const type of responseTypes) {
|
|
1242
|
+
responseMap[type] = {
|
|
1243
|
+
response: type,
|
|
1244
|
+
responders: []
|
|
1245
|
+
};
|
|
1246
|
+
}
|
|
1247
|
+
for (const update of eventResponses || []) {
|
|
1248
|
+
const responseType = update.eventResponse || 'UNKNOWN';
|
|
1249
|
+
if (responseType !== 'UNKNOWN' && responseMap[responseType]) {
|
|
1250
|
+
responseMap[responseType].responders.push(getKeyAuthor(update.eventResponseMessageKey, meId));
|
|
1251
|
+
}
|
|
1252
|
+
}
|
|
1253
|
+
return Object.values(responseMap);
|
|
2802
1254
|
}
|
|
2803
|
-
|
|
2804
|
-
|
|
2805
|
-
|
|
2806
|
-
const
|
|
1255
|
+
/** Given a list of message keys, aggregates them by chat & sender. Useful for sending read receipts in bulk */
|
|
1256
|
+
export const aggregateMessageKeysNotFromMe = (keys) => {
|
|
1257
|
+
const keyMap = {};
|
|
1258
|
+
for (const { remoteJid, id, participant, fromMe } of keys) {
|
|
1259
|
+
if (!fromMe) {
|
|
1260
|
+
const uqKey = `${remoteJid}:${participant || ''}`;
|
|
1261
|
+
if (!keyMap[uqKey]) {
|
|
1262
|
+
keyMap[uqKey] = {
|
|
1263
|
+
jid: remoteJid,
|
|
1264
|
+
participant: participant,
|
|
1265
|
+
messageIds: []
|
|
1266
|
+
};
|
|
1267
|
+
}
|
|
1268
|
+
keyMap[uqKey].messageIds.push(id);
|
|
1269
|
+
}
|
|
1270
|
+
}
|
|
1271
|
+
return Object.values(keyMap);
|
|
1272
|
+
};
|
|
1273
|
+
const REUPLOAD_REQUIRED_STATUS = [410, 404];
|
|
2807
1274
|
/**
|
|
2808
1275
|
* Downloads the given message. Throws an error if it's not a media message
|
|
2809
1276
|
*/
|
|
2810
|
-
const downloadMediaMessage = async (message, type, options, ctx) => {
|
|
2811
|
-
|
|
2812
|
-
|
|
2813
|
-
|
|
2814
|
-
|
|
2815
|
-
|
|
2816
|
-
|
|
2817
|
-
|
|
2818
|
-
|
|
2819
|
-
|
|
2820
|
-
|
|
2821
|
-
|
|
2822
|
-
|
|
2823
|
-
|
|
2824
|
-
|
|
2825
|
-
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
2829
|
-
|
|
2830
|
-
|
|
2831
|
-
|
|
2832
|
-
|
|
2833
|
-
|
|
2834
|
-
|
|
2835
|
-
|
|
2836
|
-
|
|
2837
|
-
|
|
2838
|
-
|
|
2839
|
-
|
|
2840
|
-
|
|
2841
|
-
|
|
2842
|
-
|
|
2843
|
-
|
|
2844
|
-
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
|
|
2848
|
-
|
|
2849
|
-
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
}
|
|
2858
|
-
exports.downloadMediaMessage = downloadMediaMessage
|
|
1277
|
+
export const downloadMediaMessage = async (message, type, options, ctx) => {
|
|
1278
|
+
const result = await downloadMsg().catch(async (error) => {
|
|
1279
|
+
if (ctx &&
|
|
1280
|
+
typeof error?.status === 'number' && // treat errors with status as HTTP failures requiring reupload
|
|
1281
|
+
REUPLOAD_REQUIRED_STATUS.includes(error.status)) {
|
|
1282
|
+
ctx.logger.info({ key: message.key }, 'sending reupload media request...');
|
|
1283
|
+
// request reupload
|
|
1284
|
+
message = await ctx.reuploadRequest(message);
|
|
1285
|
+
const result = await downloadMsg();
|
|
1286
|
+
return result;
|
|
1287
|
+
}
|
|
1288
|
+
throw error;
|
|
1289
|
+
});
|
|
1290
|
+
return result;
|
|
1291
|
+
async function downloadMsg() {
|
|
1292
|
+
const mContent = extractMessageContent(message.message);
|
|
1293
|
+
if (!mContent) {
|
|
1294
|
+
throw new Boom('No message present', { statusCode: 400, data: message });
|
|
1295
|
+
}
|
|
1296
|
+
const contentType = getContentType(mContent);
|
|
1297
|
+
let mediaType = contentType?.replace('Message', '');
|
|
1298
|
+
const media = mContent[contentType];
|
|
1299
|
+
if (!media || typeof media !== 'object' || (!('url' in media) && !('thumbnailDirectPath' in media))) {
|
|
1300
|
+
throw new Boom(`"${contentType}" message is not a media message`);
|
|
1301
|
+
}
|
|
1302
|
+
let download;
|
|
1303
|
+
if ('thumbnailDirectPath' in media && !('url' in media)) {
|
|
1304
|
+
download = {
|
|
1305
|
+
directPath: media.thumbnailDirectPath,
|
|
1306
|
+
mediaKey: media.mediaKey
|
|
1307
|
+
};
|
|
1308
|
+
mediaType = 'thumbnail-link';
|
|
1309
|
+
}
|
|
1310
|
+
else {
|
|
1311
|
+
download = media;
|
|
1312
|
+
}
|
|
1313
|
+
const stream = await downloadContentFromMessage(download, mediaType, options);
|
|
1314
|
+
if (type === 'buffer') {
|
|
1315
|
+
const bufferArray = [];
|
|
1316
|
+
for await (const chunk of stream) {
|
|
1317
|
+
bufferArray.push(chunk);
|
|
1318
|
+
}
|
|
1319
|
+
return Buffer.concat(bufferArray);
|
|
1320
|
+
}
|
|
1321
|
+
return stream;
|
|
1322
|
+
}
|
|
1323
|
+
};
|
|
2859
1324
|
/** Checks whether the given message is a media message; if it is returns the inner content */
|
|
2860
|
-
const assertMediaContent = content => {
|
|
2861
|
-
|
|
2862
|
-
|
|
2863
|
-
|
|
2864
|
-
|
|
2865
|
-
|
|
2866
|
-
|
|
2867
|
-
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
exports.assertMediaContent = assertMediaContent
|
|
2874
|
-
/**
|
|
2875
|
-
* Normalizes a bare user id to @s.whatsapp.net. Does not convert LID↔PN; use lidMapping / PN in key.remoteJidAlt when needed.
|
|
2876
|
-
*/
|
|
2877
|
-
const toJid = id => {
|
|
2878
|
-
if (!id) return ''
|
|
2879
|
-
if (id.includes('@')) return id
|
|
2880
|
-
return `${id}@s.whatsapp.net`
|
|
2881
|
-
}
|
|
2882
|
-
exports.toJid = toJid
|
|
2883
|
-
/**
|
|
2884
|
-
* Returns the peer LID JID when the key is LID-primary (decode sets remoteJid/participant to @lid when WA sends LID).
|
|
2885
|
-
*/
|
|
2886
|
-
const getSenderLid = message => {
|
|
2887
|
-
const k = message.key
|
|
2888
|
-
if (!k) {
|
|
2889
|
-
return { jid: '', lid: '' }
|
|
2890
|
-
}
|
|
2891
|
-
const jid = k.participant || k.remoteJid || ''
|
|
2892
|
-
if (jid.endsWith('@lid') || jid.endsWith('@hosted.lid')) {
|
|
2893
|
-
return { jid, lid: jid }
|
|
2894
|
-
}
|
|
2895
|
-
if (k.lid && typeof k.lid === 'string') {
|
|
2896
|
-
const lid = k.lid.includes('@') ? k.lid : (0, WABinary_1.jidEncode)(k.lid, 'lid')
|
|
2897
|
-
return { jid, lid }
|
|
2898
|
-
}
|
|
2899
|
-
if (k.participantLid && (0, WABinary_1.isLidUser)(k.participantLid)) {
|
|
2900
|
-
return { jid, lid: k.participantLid }
|
|
2901
|
-
}
|
|
2902
|
-
return { jid, lid: '' }
|
|
2903
|
-
}
|
|
2904
|
-
exports.getSenderLid = getSenderLid
|
|
1325
|
+
export const assertMediaContent = (content) => {
|
|
1326
|
+
content = extractMessageContent(content);
|
|
1327
|
+
const mediaContent = content?.documentMessage ||
|
|
1328
|
+
content?.imageMessage ||
|
|
1329
|
+
content?.videoMessage ||
|
|
1330
|
+
content?.audioMessage ||
|
|
1331
|
+
content?.stickerMessage;
|
|
1332
|
+
if (!mediaContent) {
|
|
1333
|
+
throw new Boom('given message is not a media message', { statusCode: 400, data: content });
|
|
1334
|
+
}
|
|
1335
|
+
return mediaContent;
|
|
1336
|
+
};
|
|
1337
|
+
//# sourceMappingURL=messages.js.map
|