@hansaka02/baileys 7.3.4 → 7.3.6
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 +203 -247
- package/lib/Defaults/baileys-version.json +2 -2
- package/lib/Defaults/connection.js +1 -1
- package/lib/Defaults/constants.js +13 -1
- package/lib/Defaults/history.js +3 -1
- package/lib/Signal/Group/sender-chain-key.js +1 -14
- package/lib/Signal/Group/sender-key-distribution-message.js +2 -2
- package/lib/Signal/Group/sender-key-record.js +2 -11
- package/lib/Signal/Group/sender-key-state.js +11 -57
- package/lib/Signal/libsignal.js +200 -116
- package/lib/Signal/lid-mapping.js +121 -68
- package/lib/Socket/Client/websocket.js +9 -2
- package/lib/Socket/business.js +5 -1
- package/lib/Socket/chats.js +180 -89
- package/lib/Socket/community.js +169 -41
- package/lib/Socket/groups.js +25 -21
- package/lib/Socket/messages-recv.js +458 -333
- package/lib/Socket/messages-send.js +517 -572
- package/lib/Socket/mex.js +61 -0
- package/lib/Socket/newsletter.js +159 -252
- package/lib/Socket/socket.js +283 -100
- package/lib/Types/Newsletter.js +32 -25
- package/lib/Utils/auth-utils.js +189 -354
- package/lib/Utils/browser-utils.js +43 -0
- package/lib/Utils/chat-utils.js +166 -41
- package/lib/Utils/decode-wa-message.js +77 -35
- package/lib/Utils/event-buffer.js +80 -24
- package/lib/Utils/generics.js +28 -128
- package/lib/Utils/history.js +10 -8
- package/lib/Utils/index.js +1 -1
- package/lib/Utils/link-preview.js +17 -32
- package/lib/Utils/lt-hash.js +28 -22
- package/lib/Utils/make-mutex.js +26 -28
- package/lib/Utils/message-retry-manager.js +51 -3
- package/lib/Utils/messages-media.js +343 -151
- package/lib/Utils/messages.js +806 -792
- package/lib/Utils/noise-handler.js +33 -2
- package/lib/Utils/pre-key-manager.js +126 -0
- package/lib/Utils/process-message.js +115 -55
- package/lib/Utils/signal.js +45 -18
- package/lib/Utils/validate-connection.js +52 -29
- package/lib/WABinary/constants.js +1268 -1268
- package/lib/WABinary/decode.js +58 -4
- package/lib/WABinary/encode.js +54 -7
- package/lib/WABinary/jid-utils.js +58 -11
- package/lib/WAM/constants.js +19064 -11563
- package/lib/WAM/encode.js +57 -8
- package/lib/WAUSync/USyncQuery.js +35 -19
- package/package.json +9 -8
- package/lib/Socket/usync.js +0 -83
package/lib/Utils/messages.js
CHANGED
|
@@ -3,7 +3,6 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true })
|
|
4
4
|
|
|
5
5
|
const { Boom } = require("@hapi/boom")
|
|
6
|
-
const axios_1 = require("axios")
|
|
7
6
|
const { randomBytes } = require("crypto")
|
|
8
7
|
const { promises } = require("fs")
|
|
9
8
|
const { proto } = require("../../WAProto")
|
|
@@ -97,65 +96,70 @@ const assertColor = async (color) => {
|
|
|
97
96
|
|
|
98
97
|
const prepareWAMessageMedia = async (message, options) => {
|
|
99
98
|
const logger = options.logger
|
|
99
|
+
|
|
100
100
|
let mediaType
|
|
101
|
-
|
|
101
|
+
|
|
102
102
|
for (const key of MEDIA_KEYS) {
|
|
103
103
|
if (key in message) {
|
|
104
104
|
mediaType = key
|
|
105
105
|
}
|
|
106
106
|
}
|
|
107
|
-
|
|
107
|
+
|
|
108
108
|
if (!mediaType) {
|
|
109
|
-
throw new Boom('Invalid media type', { statusCode: 400 })
|
|
109
|
+
throw new Boom('Invalid media type', { statusCode: 400 })
|
|
110
110
|
}
|
|
111
|
-
|
|
111
|
+
|
|
112
112
|
const uploadData = {
|
|
113
113
|
...message,
|
|
114
114
|
media: message[mediaType]
|
|
115
115
|
}
|
|
116
|
-
|
|
116
|
+
|
|
117
117
|
delete uploadData[mediaType]
|
|
118
|
-
|
|
118
|
+
|
|
119
119
|
// check if cacheable + generate cache key
|
|
120
120
|
const cacheableKey = typeof uploadData.media === 'object' &&
|
|
121
121
|
'url' in uploadData.media &&
|
|
122
122
|
!!uploadData.media.url &&
|
|
123
123
|
!!options.mediaCache &&
|
|
124
124
|
mediaType + ':' + uploadData.media.url.toString()
|
|
125
|
-
|
|
125
|
+
|
|
126
126
|
if (mediaType === 'document' && !uploadData.fileName) {
|
|
127
127
|
uploadData.fileName = 'file'
|
|
128
128
|
}
|
|
129
|
-
|
|
129
|
+
|
|
130
130
|
if (!uploadData.mimetype) {
|
|
131
131
|
uploadData.mimetype = MIMETYPE_MAP[mediaType]
|
|
132
132
|
}
|
|
133
|
-
|
|
133
|
+
|
|
134
134
|
if (cacheableKey) {
|
|
135
135
|
const mediaBuff = await options.mediaCache.get(cacheableKey)
|
|
136
|
+
|
|
136
137
|
if (mediaBuff) {
|
|
137
138
|
logger?.debug({ cacheableKey }, 'got media cache hit')
|
|
138
|
-
|
|
139
|
+
|
|
140
|
+
const obj = proto.Message.decode(mediaBuff)
|
|
139
141
|
const key = `${mediaType}Message`
|
|
142
|
+
|
|
140
143
|
Object.assign(obj[key], { ...uploadData, media: undefined })
|
|
144
|
+
|
|
141
145
|
return obj
|
|
142
146
|
}
|
|
143
147
|
}
|
|
144
|
-
|
|
148
|
+
|
|
145
149
|
const isNewsletter = !!options.jid && isJidNewsletter(options.jid)
|
|
146
|
-
|
|
150
|
+
|
|
147
151
|
if (isNewsletter) {
|
|
148
152
|
logger?.info({ key: cacheableKey }, 'Preparing raw media for newsletter')
|
|
149
153
|
const { filePath, fileSha256, fileLength } = await getRawMediaUploadData(uploadData.media, options.mediaTypeOverride || mediaType, logger)
|
|
150
|
-
const fileSha256B64 = fileSha256.toString('base64')
|
|
154
|
+
const fileSha256B64 = fileSha256.toString('base64');
|
|
151
155
|
const { mediaUrl, directPath } = await options.upload(filePath, {
|
|
152
156
|
fileEncSha256B64: fileSha256B64,
|
|
153
157
|
mediaType: mediaType,
|
|
154
158
|
timeoutMs: options.mediaUploadTimeoutMs
|
|
155
159
|
})
|
|
156
|
-
|
|
160
|
+
|
|
157
161
|
await promises.unlink(filePath)
|
|
158
|
-
|
|
162
|
+
|
|
159
163
|
const obj = WAProto.Message.fromObject({
|
|
160
164
|
// todo: add more support here
|
|
161
165
|
[`${mediaType}Message`]: MessageTypeProto[mediaType].fromObject({
|
|
@@ -167,34 +171,35 @@ const prepareWAMessageMedia = async (message, options) => {
|
|
|
167
171
|
media: undefined
|
|
168
172
|
})
|
|
169
173
|
})
|
|
170
|
-
|
|
174
|
+
|
|
171
175
|
if (uploadData.ptv) {
|
|
172
176
|
obj.ptvMessage = obj.videoMessage
|
|
173
177
|
delete obj.videoMessage
|
|
174
178
|
}
|
|
175
|
-
|
|
179
|
+
|
|
180
|
+
if (obj.stickerMessage) {
|
|
181
|
+
obj.stickerMessage.stickerSentTs = Date.now()
|
|
182
|
+
}
|
|
183
|
+
|
|
176
184
|
if (cacheableKey) {
|
|
177
185
|
logger?.debug({ cacheableKey }, 'set cache');
|
|
178
186
|
await options.mediaCache.set(cacheableKey, WAProto.Message.encode(obj).finish())
|
|
179
187
|
}
|
|
180
|
-
|
|
188
|
+
|
|
181
189
|
return obj
|
|
182
190
|
}
|
|
183
|
-
|
|
191
|
+
|
|
184
192
|
const requiresDurationComputation = mediaType === 'audio' && typeof uploadData.seconds === 'undefined'
|
|
185
193
|
const requiresThumbnailComputation = (mediaType === 'image' || mediaType === 'video') && typeof uploadData['jpegThumbnail'] === 'undefined'
|
|
186
194
|
const requiresWaveformProcessing = mediaType === 'audio' && uploadData.ptt === true
|
|
187
195
|
const requiresAudioBackground = options.backgroundColor && mediaType === 'audio' && uploadData.ptt === true
|
|
188
196
|
const requiresOriginalForSomeProcessing = requiresDurationComputation || requiresThumbnailComputation
|
|
189
|
-
|
|
190
197
|
const { mediaKey, encFilePath, originalFilePath, fileEncSha256, fileSha256, fileLength } = await encryptedStream(uploadData.media, options.mediaTypeOverride || mediaType, {
|
|
191
198
|
logger,
|
|
192
199
|
saveOriginalFileIfRequired: requiresOriginalForSomeProcessing,
|
|
193
200
|
opts: options.options
|
|
194
201
|
})
|
|
195
|
-
|
|
196
202
|
const fileEncSha256B64 = fileEncSha256.toString('base64')
|
|
197
|
-
|
|
198
203
|
const [{ mediaUrl, directPath }] = await Promise.all([
|
|
199
204
|
(async () => {
|
|
200
205
|
const result = await options.upload(encFilePath, {
|
|
@@ -205,32 +210,31 @@ const prepareWAMessageMedia = async (message, options) => {
|
|
|
205
210
|
logger?.debug({ mediaType, cacheableKey }, 'uploaded media')
|
|
206
211
|
return result
|
|
207
212
|
})(),
|
|
208
|
-
|
|
209
213
|
(async () => {
|
|
210
214
|
try {
|
|
211
215
|
if (requiresThumbnailComputation) {
|
|
212
216
|
const { thumbnail, originalImageDimensions } = await generateThumbnail(originalFilePath, mediaType, options)
|
|
217
|
+
|
|
213
218
|
uploadData.jpegThumbnail = thumbnail
|
|
219
|
+
|
|
214
220
|
if (!uploadData.width && originalImageDimensions) {
|
|
215
221
|
uploadData.width = originalImageDimensions.width
|
|
216
222
|
uploadData.height = originalImageDimensions.height
|
|
217
|
-
|
|
218
223
|
logger?.debug('set dimensions')
|
|
219
224
|
}
|
|
220
|
-
|
|
221
|
-
logger?.debug('generated thumbnail');
|
|
225
|
+
logger?.debug('generated thumbnail')
|
|
222
226
|
}
|
|
223
|
-
|
|
227
|
+
|
|
224
228
|
if (requiresDurationComputation) {
|
|
225
229
|
uploadData.seconds = await getAudioDuration(originalFilePath)
|
|
226
230
|
logger?.debug('computed audio duration')
|
|
227
231
|
}
|
|
228
|
-
|
|
232
|
+
|
|
229
233
|
if (requiresWaveformProcessing) {
|
|
230
234
|
uploadData.waveform = await getAudioWaveform(originalFilePath, logger)
|
|
231
235
|
logger?.debug('processed waveform')
|
|
232
236
|
}
|
|
233
|
-
|
|
237
|
+
|
|
234
238
|
if (requiresAudioBackground) {
|
|
235
239
|
uploadData.backgroundArgb = await assertColor(options.backgroundColor)
|
|
236
240
|
logger?.debug('computed backgroundColor audio status')
|
|
@@ -243,18 +247,18 @@ const prepareWAMessageMedia = async (message, options) => {
|
|
|
243
247
|
]).finally(async () => {
|
|
244
248
|
try {
|
|
245
249
|
await promises.unlink(encFilePath)
|
|
246
|
-
|
|
250
|
+
|
|
247
251
|
if (originalFilePath) {
|
|
248
252
|
await promises.unlink(originalFilePath)
|
|
249
253
|
}
|
|
250
|
-
|
|
254
|
+
|
|
251
255
|
logger?.debug('removed tmp files')
|
|
252
256
|
}
|
|
253
257
|
catch (error) {
|
|
254
258
|
logger?.warn('failed to remove tmp file')
|
|
255
259
|
}
|
|
256
260
|
})
|
|
257
|
-
|
|
261
|
+
|
|
258
262
|
const obj = WAProto.Message.fromObject({
|
|
259
263
|
[`${mediaType}Message`]: MessageTypeProto[mediaType].fromObject({
|
|
260
264
|
url: mediaUrl,
|
|
@@ -268,17 +272,17 @@ const prepareWAMessageMedia = async (message, options) => {
|
|
|
268
272
|
media: undefined
|
|
269
273
|
})
|
|
270
274
|
})
|
|
271
|
-
|
|
275
|
+
|
|
272
276
|
if (uploadData.ptv) {
|
|
273
277
|
obj.ptvMessage = obj.videoMessage
|
|
274
278
|
delete obj.videoMessage
|
|
275
279
|
}
|
|
276
|
-
|
|
280
|
+
|
|
277
281
|
if (cacheableKey) {
|
|
278
|
-
logger?.debug({ cacheableKey }, 'set cache')
|
|
282
|
+
logger?.debug({ cacheableKey }, 'set cache')
|
|
279
283
|
await options.mediaCache.set(cacheableKey, WAProto.Message.encode(obj).finish())
|
|
280
284
|
}
|
|
281
|
-
|
|
285
|
+
|
|
282
286
|
return obj
|
|
283
287
|
}
|
|
284
288
|
|
|
@@ -292,7 +296,7 @@ const prepareAlbumMessageContent = async (jid, albums, options) => {
|
|
|
292
296
|
}
|
|
293
297
|
|
|
294
298
|
const validCount = albums.filter(m => ('image' in m) || ('video' in m)).length
|
|
295
|
-
|
|
299
|
+
|
|
296
300
|
if (validCount === 0) {
|
|
297
301
|
throw new Error("albums contains no valid media. Use 'image' or 'video' keys.")
|
|
298
302
|
}
|
|
@@ -411,879 +415,916 @@ const generateForwardMessageContent = (message, forceForward) => {
|
|
|
411
415
|
return content
|
|
412
416
|
}
|
|
413
417
|
|
|
414
|
-
const
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
if (urlInfo) {
|
|
425
|
-
extContent.canonicalUrl = urlInfo['canonical-url']
|
|
426
|
-
extContent.matchedText = urlInfo['matched-text']
|
|
427
|
-
extContent.jpegThumbnail = urlInfo.jpegThumbnail
|
|
428
|
-
extContent.description = urlInfo.description
|
|
429
|
-
extContent.title = urlInfo.title
|
|
430
|
-
extContent.previewType = 0
|
|
431
|
-
const img = urlInfo.highQualityThumbnail
|
|
432
|
-
|
|
433
|
-
if (img) {
|
|
434
|
-
extContent.thumbnailDirectPath = img.directPath
|
|
435
|
-
extContent.mediaKey = img.mediaKey
|
|
436
|
-
extContent.mediaKeyTimestamp = img.mediaKeyTimestamp
|
|
437
|
-
extContent.thumbnailWidth = img.width
|
|
438
|
-
extContent.thumbnailHeight = img.height
|
|
439
|
-
extContent.thumbnailSha256 = img.fileSha256
|
|
440
|
-
extContent.thumbnailEncSha256 = img.fileEncSha256
|
|
441
|
-
}
|
|
442
|
-
}
|
|
443
|
-
|
|
444
|
-
if (options.backgroundColor) {
|
|
445
|
-
extContent.backgroundArgb = await assertColor(options.backgroundColor)
|
|
446
|
-
}
|
|
447
|
-
|
|
448
|
-
if (options.textColor) {
|
|
449
|
-
extContent.textArgb = await assertColor(options.textColor)
|
|
450
|
-
}
|
|
418
|
+
const hasNonNullishProperty = (message, key) => {
|
|
419
|
+
return (
|
|
420
|
+
typeof message === 'object' &&
|
|
421
|
+
message !== null &&
|
|
422
|
+
key in message &&
|
|
423
|
+
message[key] !== null &&
|
|
424
|
+
message[key] !== undefined
|
|
425
|
+
)
|
|
426
|
+
}
|
|
451
427
|
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
428
|
+
function hasOptionalProperty(obj, key) {
|
|
429
|
+
return (
|
|
430
|
+
typeof obj === 'object' &&
|
|
431
|
+
obj !== null &&
|
|
432
|
+
key in obj &&
|
|
433
|
+
obj[key] !== null
|
|
434
|
+
)
|
|
435
|
+
}
|
|
455
436
|
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
437
|
+
const generateWAMessageContent = async (message, options) => {
|
|
438
|
+
const hasMedia = [
|
|
439
|
+
"image",
|
|
440
|
+
"video",
|
|
441
|
+
"audio",
|
|
442
|
+
"sticker",
|
|
443
|
+
"document",
|
|
444
|
+
].some((key) => hasNonNullishProperty(message, key))
|
|
460
445
|
|
|
461
|
-
|
|
462
|
-
}
|
|
446
|
+
let m = {}
|
|
463
447
|
|
|
464
|
-
|
|
448
|
+
if (hasNonNullishProperty(message, "contacts")) {
|
|
465
449
|
const contactLen = message.contacts.contacts.length
|
|
466
450
|
|
|
467
451
|
let contactMessage
|
|
468
452
|
|
|
469
453
|
if (!contactLen) {
|
|
470
|
-
throw new Boom(
|
|
454
|
+
throw new Boom("require atleast 1 contact", { statusCode: 400 })
|
|
471
455
|
}
|
|
472
456
|
|
|
473
457
|
if (contactLen === 1) {
|
|
474
458
|
contactMessage = {
|
|
475
|
-
|
|
459
|
+
contactMessage: WAProto.Message.ContactMessage.fromObject(
|
|
460
|
+
message.contacts.contacts[0]
|
|
461
|
+
),
|
|
476
462
|
}
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
else {
|
|
463
|
+
} else {
|
|
480
464
|
contactMessage = {
|
|
481
|
-
|
|
465
|
+
contactsArrayMessage: WAProto.Message.ContactsArrayMessage.fromObject(
|
|
466
|
+
message.contacts
|
|
467
|
+
),
|
|
482
468
|
}
|
|
483
469
|
}
|
|
484
470
|
|
|
485
|
-
const [type] = Object.keys(contactMessage)
|
|
486
|
-
|
|
487
|
-
contactMessage[type].contextInfo = {
|
|
488
|
-
...(message.contextInfo || {}),
|
|
489
|
-
...(message.mentions ? { mentionedJid: message.mentions } : {})
|
|
490
|
-
}
|
|
491
|
-
|
|
492
471
|
m = contactMessage
|
|
493
|
-
}
|
|
472
|
+
} else if (hasNonNullishProperty(message, "contacts")) {
|
|
473
|
+
const contactLen = message.contacts.contacts.length
|
|
494
474
|
|
|
495
|
-
|
|
496
|
-
let locationMessage
|
|
475
|
+
let contactMessage
|
|
497
476
|
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
liveLocationMessage: WAProto.Message.LiveLocationMessage.fromObject(message.location)
|
|
501
|
-
}
|
|
477
|
+
if (!contactLen) {
|
|
478
|
+
throw new Boom("require atleast 1 contact", { statusCode: 400 })
|
|
502
479
|
}
|
|
503
480
|
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
481
|
+
if (contactLen === 1) {
|
|
482
|
+
contactMessage = {
|
|
483
|
+
contactMessage: WAProto.Message.ContactMessage.fromObject(
|
|
484
|
+
message.contacts.contacts[0]
|
|
485
|
+
),
|
|
486
|
+
}
|
|
487
|
+
} else {
|
|
488
|
+
contactMessage = {
|
|
489
|
+
contactsArrayMessage: WAProto.Message.ContactsArrayMessage.fromObject(
|
|
490
|
+
message.contacts
|
|
491
|
+
),
|
|
507
492
|
}
|
|
508
493
|
}
|
|
509
494
|
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
locationMessage
|
|
513
|
-
|
|
514
|
-
|
|
495
|
+
m = contactMessage
|
|
496
|
+
} else if (hasNonNullishProperty(message, "location")) {
|
|
497
|
+
let locationMessage
|
|
498
|
+
|
|
499
|
+
if (message.live) {
|
|
500
|
+
locationMessage = {
|
|
501
|
+
liveLocationMessage: WAProto.Message.LiveLocationMessage.fromObject(
|
|
502
|
+
message.location
|
|
503
|
+
),
|
|
504
|
+
}
|
|
505
|
+
} else {
|
|
506
|
+
locationMessage = {
|
|
507
|
+
locationMessage: WAProto.Message.LocationMessage.fromObject(
|
|
508
|
+
message.location
|
|
509
|
+
),
|
|
510
|
+
}
|
|
515
511
|
}
|
|
516
512
|
|
|
517
513
|
m = locationMessage
|
|
518
|
-
}
|
|
519
|
-
|
|
520
|
-
else if ('react' in message) {
|
|
514
|
+
} else if (hasNonNullishProperty(message, "react")) {
|
|
521
515
|
if (!message.react.senderTimestampMs) {
|
|
522
516
|
message.react.senderTimestampMs = Date.now()
|
|
523
517
|
}
|
|
524
518
|
|
|
525
|
-
m.reactionMessage = WAProto.Message.ReactionMessage.fromObject(
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
else if (
|
|
519
|
+
m.reactionMessage = WAProto.Message.ReactionMessage.fromObject(
|
|
520
|
+
message.react
|
|
521
|
+
)
|
|
522
|
+
} else if (hasNonNullishProperty(message, "delete")) {
|
|
529
523
|
m.protocolMessage = {
|
|
530
524
|
key: message.delete,
|
|
531
|
-
type: WAProto.Message.ProtocolMessage.Type.REVOKE
|
|
525
|
+
type: WAProto.Message.ProtocolMessage.Type.REVOKE,
|
|
532
526
|
}
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
const mess = generateForwardMessageContent(message.forward, message.force)
|
|
537
|
-
const [type] = Object.keys(mess)
|
|
538
|
-
|
|
539
|
-
mess[type].contextInfo = {
|
|
540
|
-
...(message.contextInfo || {}),
|
|
541
|
-
...(message.mentions ? { mentionedJid: message.mentions } : {})
|
|
527
|
+
} else if (hasNonNullishProperty(message, "sharePhoneNumber")) {
|
|
528
|
+
m.protocolMessage = {
|
|
529
|
+
type: WAProto.Message.ProtocolMessage.Type.SHARE_PHONE_NUMBER,
|
|
542
530
|
}
|
|
543
|
-
|
|
544
|
-
m =
|
|
545
|
-
}
|
|
546
|
-
|
|
547
|
-
else if (
|
|
548
|
-
const exp =
|
|
549
|
-
|
|
550
|
-
|
|
531
|
+
} else if (hasNonNullishProperty(message, "requestPhoneNumber")) {
|
|
532
|
+
m.requestPhoneNumberMessage = {}
|
|
533
|
+
} else if (hasNonNullishProperty(message, "forward")) {
|
|
534
|
+
m = generateForwardMessageContent(message.forward, message.force)
|
|
535
|
+
} else if (hasNonNullishProperty(message, "disappearingMessagesInChat")) {
|
|
536
|
+
const exp =
|
|
537
|
+
typeof message.disappearingMessagesInChat === "boolean"
|
|
538
|
+
? message.disappearingMessagesInChat
|
|
539
|
+
? WA_DEFAULT_EPHEMERAL
|
|
540
|
+
: 0
|
|
541
|
+
: message.disappearingMessagesInChat
|
|
551
542
|
m = prepareDisappearingMessageSettingContent(exp)
|
|
552
|
-
}
|
|
553
|
-
|
|
554
|
-
else if ('groupInvite' in message) {
|
|
555
|
-
m.groupInviteMessage = {}
|
|
543
|
+
} else if (hasNonNullishProperty(message, "groupInvite")) {
|
|
544
|
+
m.groupInviteMessage = {}
|
|
556
545
|
|
|
557
546
|
m.groupInviteMessage.inviteCode = message.groupInvite.code
|
|
558
547
|
m.groupInviteMessage.inviteExpiration = message.groupInvite.expiration
|
|
559
548
|
m.groupInviteMessage.caption = message.groupInvite.caption
|
|
560
549
|
m.groupInviteMessage.groupJid = message.groupInvite.jid
|
|
561
|
-
m.groupInviteMessage.groupName = message.groupInvite.name
|
|
562
|
-
m.groupInviteMessage.contextInfo = message.contextInfo
|
|
550
|
+
m.groupInviteMessage.groupName = message.groupInvite.name
|
|
551
|
+
m.groupInviteMessage.contextInfo = message.contextInfo
|
|
563
552
|
|
|
564
553
|
if (options.getProfilePicUrl) {
|
|
565
|
-
const pfpUrl = await options.getProfilePicUrl(
|
|
566
|
-
|
|
554
|
+
const pfpUrl = await options.getProfilePicUrl(
|
|
555
|
+
message.groupInvite.jid
|
|
556
|
+
)
|
|
557
|
+
const { thumbnail } = await generateThumbnail(pfpUrl, "image")
|
|
567
558
|
m.groupInviteMessage.jpegThumbnail = thumbnail
|
|
568
559
|
}
|
|
569
|
-
|
|
570
|
-
m.
|
|
571
|
-
...(message.contextInfo || {}),
|
|
572
|
-
...(message.mentions ? { mentionedJid: message.mentions } : {})
|
|
573
|
-
}
|
|
574
|
-
}
|
|
575
|
-
|
|
576
|
-
else if ('adminInvite' in message) {
|
|
577
|
-
m.newsletterAdminInviteMessage = {}
|
|
560
|
+
} else if (hasNonNullishProperty(message, "adminInvite")) {
|
|
561
|
+
m.newsletterAdminInviteMessage = {}
|
|
578
562
|
|
|
579
563
|
m.newsletterAdminInviteMessage.newsletterJid = message.adminInvite.jid
|
|
580
|
-
m.newsletterAdminInviteMessage.newsletterName=
|
|
564
|
+
m.newsletterAdminInviteMessage.newsletterName =
|
|
565
|
+
message.adminInvite.name
|
|
581
566
|
m.newsletterAdminInviteMessage.caption = message.adminInvite.caption
|
|
582
|
-
m.newsletterAdminInviteMessage.inviteExpiration =
|
|
583
|
-
|
|
567
|
+
m.newsletterAdminInviteMessage.inviteExpiration =
|
|
568
|
+
message.adminInvite.expiration
|
|
569
|
+
m.newsletterAdminInviteMessage.contextInfo = message.contextInfo
|
|
584
570
|
|
|
585
571
|
if (options.getProfilePicUrl) {
|
|
586
|
-
const pfpUrl = await options.getProfilePicUrl(
|
|
587
|
-
|
|
572
|
+
const pfpUrl = await options.getProfilePicUrl(
|
|
573
|
+
message.adminInvite.jid
|
|
574
|
+
)
|
|
575
|
+
const { thumbnail } = await generateThumbnail(pfpUrl, "image")
|
|
588
576
|
m.newsletterAdminInviteMessage.jpegThumbnail = thumbnail
|
|
589
577
|
}
|
|
590
|
-
|
|
591
|
-
m.newsletterAdminInviteMessage.contextInfo = {
|
|
592
|
-
...(message.contextInfo || {}),
|
|
593
|
-
...(message.mentions ? { mentionedJid: message.mentions } : {})
|
|
594
|
-
}
|
|
595
|
-
}
|
|
596
|
-
|
|
597
|
-
else if ('pin' in message) {
|
|
598
|
-
m.pinInChatMessage = {}
|
|
599
|
-
m.messageContextInfo = {}
|
|
600
|
-
|
|
601
|
-
m.pinInChatMessage.key = message.pin.key
|
|
602
|
-
m.pinInChatMessage.type = message.pin?.type || 1
|
|
603
|
-
m.pinInChatMessage.senderTimestampMs = message.pin?.time || Date.now()
|
|
604
|
-
m.messageContextInfo.messageAddOnDurationInSecs = message.pin.type === 1 ? message.pin.time || 86400 : 0
|
|
605
|
-
m.messageContextInfo.messageAddOnExpiryType = proto.MessageContextInfo.MessageAddonExpiryType.STATIC
|
|
606
|
-
}
|
|
607
|
-
|
|
608
|
-
else if ('keep' in message) {
|
|
578
|
+
} else if (hasNonNullishProperty(message, "keep")) {
|
|
609
579
|
m.keepInChatMessage = {}
|
|
610
580
|
|
|
611
581
|
m.keepInChatMessage.key = message.keep.key
|
|
612
582
|
m.keepInChatMessage.keepType = message.keep?.type || 1
|
|
613
583
|
m.keepInChatMessage.timestampMs = message.keep?.time || Date.now()
|
|
614
|
-
}
|
|
615
|
-
|
|
616
|
-
else if ('call' in message) {
|
|
584
|
+
} else if (hasNonNullishProperty(message, "call")) {
|
|
617
585
|
m.scheduledCallCreationMessage = {}
|
|
618
586
|
|
|
619
|
-
m.scheduledCallCreationMessage.scheduledTimestampMs =
|
|
587
|
+
m.scheduledCallCreationMessage.scheduledTimestampMs =
|
|
588
|
+
message.call?.time || Date.now()
|
|
620
589
|
m.scheduledCallCreationMessage.callType = message.call?.type || 1
|
|
621
|
-
m.scheduledCallCreationMessage.title =
|
|
590
|
+
m.scheduledCallCreationMessage.title =
|
|
591
|
+
message.call?.name || "Call Creation"
|
|
592
|
+
} else if (hasNonNullishProperty(message, "paymentInvite")) {
|
|
593
|
+
m.messageContextInfo = {}
|
|
594
|
+
m.paymentInviteMessage = {}
|
|
622
595
|
|
|
623
|
-
m.
|
|
624
|
-
|
|
625
|
-
|
|
596
|
+
m.paymentInviteMessage.expiryTimestamp =
|
|
597
|
+
message.paymentInvite?.expiry || 0
|
|
598
|
+
m.paymentInviteMessage.serviceType = message.paymentInvite?.type || 2
|
|
599
|
+
} else if (hasNonNullishProperty(message, "ptv")) {
|
|
600
|
+
const { videoMessage } = await prepareWAMessageMedia(
|
|
601
|
+
{ video: message.video },
|
|
602
|
+
options
|
|
603
|
+
)
|
|
604
|
+
|
|
605
|
+
m.ptvMessage = videoMessage
|
|
606
|
+
} else if (hasNonNullishProperty(message, "order")) {
|
|
607
|
+
m.orderMessage = WAProto.Message.OrderMessage.fromObject(message.order)
|
|
608
|
+
} else if (hasNonNullishProperty(message, "product")) {
|
|
609
|
+
const { imageMessage } = await prepareWAMessageMedia(
|
|
610
|
+
{ image: message.product.productImage },
|
|
611
|
+
options
|
|
612
|
+
)
|
|
613
|
+
|
|
614
|
+
m.productMessage = WAProto.Message.ProductMessage.fromObject({
|
|
615
|
+
...message,
|
|
616
|
+
product: {
|
|
617
|
+
...message.product,
|
|
618
|
+
productImage: imageMessage,
|
|
619
|
+
},
|
|
620
|
+
})
|
|
621
|
+
} else if (hasNonNullishProperty(message, "album")) {
|
|
622
|
+
const imageMessages = message.album.filter((item) => "image" in item)
|
|
623
|
+
const videoMessages = message.album.filter((item) => "video" in item)
|
|
624
|
+
|
|
625
|
+
m.albumMessage = WAProto.Message.AlbumMessage.fromObject({
|
|
626
|
+
expectedImageCount: imageMessages.length,
|
|
627
|
+
expectedVideoCount: videoMessages.length,
|
|
628
|
+
})
|
|
629
|
+
} else if (hasNonNullishProperty(message, "event")) {
|
|
630
|
+
m.eventMessage = WAProto.Message.EventMessage.fromObject(message.event)
|
|
631
|
+
|
|
632
|
+
if (!message.event.startTime) {
|
|
633
|
+
m.eventMessage.startTime = unixTimestampSeconds() + 86400
|
|
634
|
+
}
|
|
635
|
+
|
|
636
|
+
if (options.getCallLink && message.event.call) {
|
|
637
|
+
const link = await options.getCallLink(
|
|
638
|
+
message.event.call,
|
|
639
|
+
m.eventMessage.startTime
|
|
640
|
+
)
|
|
641
|
+
m.eventMessage.joinLink = link
|
|
642
|
+
}
|
|
643
|
+
} else if (hasNonNullishProperty(message, "pollResult")) {
|
|
644
|
+
if (!Array.isArray(message.pollResult.values)) {
|
|
645
|
+
throw new Boom("Invalid pollResult values", { statusCode: 400 })
|
|
626
646
|
}
|
|
627
|
-
}
|
|
628
647
|
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
648
|
+
const pollResultSnapshotMessage = {
|
|
649
|
+
name: message.pollResult.name,
|
|
650
|
+
pollVotes: message.pollResult.values.map(
|
|
651
|
+
([optionName, optionVoteCount]) => ({
|
|
652
|
+
optionName,
|
|
653
|
+
optionVoteCount,
|
|
654
|
+
})
|
|
655
|
+
),
|
|
656
|
+
}
|
|
632
657
|
|
|
633
|
-
m.
|
|
634
|
-
|
|
658
|
+
m.pollResultSnapshotMessage = pollResultSnapshotMessage
|
|
659
|
+
} else if (hasNonNullishProperty(message, "poll")) {
|
|
660
|
+
if (!Array.isArray(message.poll.values)) {
|
|
661
|
+
throw new Boom("Invalid poll values", { statusCode: 400 })
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
if (
|
|
665
|
+
message.poll.selectableCount < 0 ||
|
|
666
|
+
message.poll.selectableCount > message.poll.values.length
|
|
667
|
+
) {
|
|
668
|
+
throw new Boom(
|
|
669
|
+
`poll.selectableCount in poll should be >= 0 and <= ${message.poll.values.length}`,
|
|
670
|
+
{ statusCode: 400 }
|
|
671
|
+
)
|
|
672
|
+
}
|
|
635
673
|
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
674
|
+
const pollCreationMessage = {
|
|
675
|
+
name: message.poll.name,
|
|
676
|
+
selectableOptionsCount: message.poll?.selectableCount || 0,
|
|
677
|
+
options: message.poll.values.map((optionName) => ({ optionName })),
|
|
639
678
|
}
|
|
640
|
-
}
|
|
641
679
|
|
|
642
|
-
|
|
680
|
+
if (message.poll?.toAnnouncementGroup) {
|
|
681
|
+
m.pollCreationMessageV2 = pollCreationMessage
|
|
682
|
+
} else {
|
|
683
|
+
if (message.poll.selectableCount > 0) {
|
|
684
|
+
m.pollCreationMessageV3 = pollCreationMessage
|
|
685
|
+
} else {
|
|
686
|
+
m.pollCreationMessage = pollCreationMessage
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
} else if (hasNonNullishProperty(message, "payment")) {
|
|
690
|
+
const requestPaymentMessage = {
|
|
691
|
+
amount: {
|
|
692
|
+
currencyCode: message.payment?.currency || "IDR",
|
|
693
|
+
offset: message.payment?.offset || 0,
|
|
694
|
+
value: message.payment?.amount || 999999999,
|
|
695
|
+
},
|
|
696
|
+
expiryTimestamp: message.payment?.expiry || 0,
|
|
697
|
+
amount1000: message.payment?.amount || 999999999 * 1000,
|
|
698
|
+
currencyCodeIso4217: message.payment?.currency || "IDR",
|
|
699
|
+
requestFrom: message.payment?.from || "0@s.whatsapp.net",
|
|
700
|
+
noteMessage: {
|
|
701
|
+
extendedTextMessage: {
|
|
702
|
+
text: message.payment?.note || "Notes",
|
|
703
|
+
},
|
|
704
|
+
},
|
|
705
|
+
background: {
|
|
706
|
+
placeholderArgb:
|
|
707
|
+
message.payment?.image?.placeholderArgb || 4278190080,
|
|
708
|
+
textArgb: message.payment?.image?.textArgb || 4294967295,
|
|
709
|
+
subtextArgb: message.payment?.image?.subtextArgb || 4294967295,
|
|
710
|
+
type: 1,
|
|
711
|
+
},
|
|
712
|
+
}
|
|
713
|
+
|
|
714
|
+
m.requestPaymentMessage = requestPaymentMessage
|
|
715
|
+
} else if (hasNonNullishProperty(message, "stickerPack")) {
|
|
716
|
+
const {
|
|
717
|
+
stickers,
|
|
718
|
+
cover,
|
|
719
|
+
name,
|
|
720
|
+
publisher,
|
|
721
|
+
packId,
|
|
722
|
+
description,
|
|
723
|
+
} = message.stickerPack
|
|
724
|
+
|
|
725
|
+
const { zip } = require("fflate")
|
|
726
|
+
|
|
727
|
+
const stickerData = {}
|
|
728
|
+
const stickerPromises = stickers.map(async (s, i) => {
|
|
729
|
+
const { stream } = await getStream(s.sticker)
|
|
730
|
+
const buffer = await toBuffer(stream)
|
|
731
|
+
const hash = sha256(buffer).toString("base64url")
|
|
732
|
+
const fileName = `${i.toString().padStart(2, "0")}_${hash}.webp`
|
|
733
|
+
|
|
734
|
+
stickerData[fileName] = [new Uint8Array(buffer), { level: 0 }]
|
|
735
|
+
|
|
736
|
+
return {
|
|
737
|
+
fileName,
|
|
738
|
+
mimetype: "image/webp",
|
|
739
|
+
isAnimated: s.isAnimated || false,
|
|
740
|
+
isLottie: s.isLottie || false,
|
|
741
|
+
emojis: s.emojis || [],
|
|
742
|
+
accessibilityLabel: s.accessibilityLabel || "",
|
|
743
|
+
}
|
|
744
|
+
})
|
|
745
|
+
|
|
746
|
+
const stickerMetadata = await Promise.all(stickerPromises)
|
|
747
|
+
|
|
748
|
+
const zipBuffer = await new Promise((resolve, reject) => {
|
|
749
|
+
zip(stickerData, (err, data) => {
|
|
750
|
+
if (err) {
|
|
751
|
+
reject(err)
|
|
752
|
+
} else {
|
|
753
|
+
resolve(Buffer.from(data))
|
|
754
|
+
}
|
|
755
|
+
})
|
|
756
|
+
})
|
|
757
|
+
|
|
758
|
+
const coverBuffer = await toBuffer((await getStream(cover)).stream)
|
|
759
|
+
|
|
760
|
+
const [stickerPackUpload, coverUpload] = await Promise.all([
|
|
761
|
+
encryptedStream(zipBuffer, "sticker-pack", {
|
|
762
|
+
logger: options.logger,
|
|
763
|
+
opts: options.options,
|
|
764
|
+
}),
|
|
765
|
+
prepareWAMessageMedia(
|
|
766
|
+
{ image: coverBuffer },
|
|
767
|
+
{ ...options, mediaTypeOverride: "image" }
|
|
768
|
+
),
|
|
769
|
+
])
|
|
770
|
+
|
|
771
|
+
const stickerPackUploadResult = await options.upload(
|
|
772
|
+
stickerPackUpload.encFilePath,
|
|
773
|
+
{
|
|
774
|
+
fileEncSha256B64: stickerPackUpload.fileEncSha256.toString(
|
|
775
|
+
"base64"
|
|
776
|
+
),
|
|
777
|
+
mediaType: "sticker-pack",
|
|
778
|
+
timeoutMs: options.mediaUploadTimeoutMs,
|
|
779
|
+
}
|
|
780
|
+
)
|
|
781
|
+
|
|
782
|
+
const coverImage = coverUpload.imageMessage
|
|
783
|
+
const imageDataHash = sha256(coverBuffer).toString("base64")
|
|
784
|
+
const stickerPackId = packId || generateMessageID()
|
|
785
|
+
|
|
786
|
+
m.stickerPackMessage = {
|
|
787
|
+
name,
|
|
788
|
+
publisher,
|
|
789
|
+
stickerPackId,
|
|
790
|
+
packDescription: description,
|
|
791
|
+
stickerPackOrigin:
|
|
792
|
+
proto.Message.StickerPackMessage.StickerPackOrigin.THIRD_PARTY,
|
|
793
|
+
stickerPackSize: stickerPackUpload.fileLength,
|
|
794
|
+
stickers: stickerMetadata,
|
|
795
|
+
fileSha256: stickerPackUpload.fileSha256,
|
|
796
|
+
fileEncSha256: stickerPackUpload.fileEncSha256,
|
|
797
|
+
mediaKey: stickerPackUpload.mediaKey,
|
|
798
|
+
directPath: stickerPackUploadResult.directPath,
|
|
799
|
+
fileLength: stickerPackUpload.fileLength,
|
|
800
|
+
mediaKeyTimestamp: unixTimestampSeconds(),
|
|
801
|
+
trayIconFileName: `${stickerPackId}.png`,
|
|
802
|
+
imageDataHash,
|
|
803
|
+
thumbnailDirectPath: coverImage.directPath,
|
|
804
|
+
thumbnailFileSha256: coverImage.fileSha256,
|
|
805
|
+
thumbnailFileEncSha256: coverImage.fileEncSha256,
|
|
806
|
+
thumbnailHeight: coverImage.height,
|
|
807
|
+
thumbnailWidth: coverImage.width,
|
|
808
|
+
}
|
|
809
|
+
} else if (hasNonNullishProperty(message, "buttonReply")) {
|
|
643
810
|
switch (message.type) {
|
|
644
|
-
|
|
811
|
+
case "list":
|
|
645
812
|
m.listResponseMessage = {
|
|
646
813
|
title: message.buttonReply.title,
|
|
647
814
|
description: message.buttonReply.description,
|
|
648
815
|
singleSelectReply: {
|
|
649
|
-
|
|
650
|
-
},
|
|
651
|
-
lisType:
|
|
816
|
+
selectedRowId: message.buttonReply.rowId,
|
|
817
|
+
},
|
|
818
|
+
lisType:
|
|
819
|
+
proto.Message.ListResponseMessage.ListType
|
|
820
|
+
.SINGLE_SELECT,
|
|
652
821
|
}
|
|
653
822
|
break
|
|
654
|
-
case
|
|
823
|
+
case "template":
|
|
655
824
|
m.templateButtonReplyMessage = {
|
|
656
825
|
selectedDisplayText: message.buttonReply.displayText,
|
|
657
826
|
selectedId: message.buttonReply.id,
|
|
658
|
-
selectedIndex: message.buttonReply.index
|
|
827
|
+
selectedIndex: message.buttonReply.index,
|
|
659
828
|
}
|
|
660
829
|
break
|
|
661
|
-
case
|
|
830
|
+
case "plain":
|
|
662
831
|
m.buttonsResponseMessage = {
|
|
663
832
|
selectedButtonId: message.buttonReply.id,
|
|
664
833
|
selectedDisplayText: message.buttonReply.displayText,
|
|
665
|
-
type:
|
|
834
|
+
type:
|
|
835
|
+
proto.Message.ButtonsResponseMessage.Type.DISPLAY_TEXT,
|
|
666
836
|
}
|
|
667
837
|
break
|
|
668
|
-
case
|
|
838
|
+
case "interactive":
|
|
669
839
|
m.interactiveResponseMessage = {
|
|
670
840
|
body: {
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
841
|
+
text: message.buttonReply.displayText,
|
|
842
|
+
format:
|
|
843
|
+
proto.Message.InteractiveResponseMessage.Body.Format
|
|
844
|
+
.EXTENSIONS_1,
|
|
845
|
+
},
|
|
674
846
|
nativeFlowResponseMessage: {
|
|
675
|
-
|
|
676
|
-
paramsJson: message.buttonReply.nativeFlows.paramsJson,
|
|
677
|
-
version: message.buttonReply.nativeFlows.version
|
|
678
|
-
}
|
|
847
|
+
name: message.buttonReply.nativeFlows.name,
|
|
848
|
+
paramsJson: message.buttonReply.nativeFlows.paramsJson,
|
|
849
|
+
version: message.buttonReply.nativeFlows.version,
|
|
850
|
+
},
|
|
679
851
|
}
|
|
680
|
-
break
|
|
852
|
+
break
|
|
853
|
+
}
|
|
854
|
+
} else if (hasNonNullishProperty(message, "sections")) {
|
|
855
|
+
m.listMessage = {
|
|
856
|
+
title: message.title,
|
|
857
|
+
buttonText: message.buttonText,
|
|
858
|
+
footerText: message.footer,
|
|
859
|
+
description: message.text,
|
|
860
|
+
sections: message.sections,
|
|
861
|
+
listType: proto.Message.ListMessage.ListType.SINGLE_SELECT,
|
|
862
|
+
}
|
|
863
|
+
} else if (hasNonNullishProperty(message, "productList")) {
|
|
864
|
+
const thumbnail = message.thumbnail
|
|
865
|
+
? await generateThumbnail(message.thumbnail, "image")
|
|
866
|
+
: null
|
|
867
|
+
|
|
868
|
+
m.listMessage = {
|
|
869
|
+
title: message.title,
|
|
870
|
+
buttonText: message.buttonText,
|
|
871
|
+
footerText: message.footer,
|
|
872
|
+
description: message.text,
|
|
873
|
+
productListInfo: {
|
|
874
|
+
productSections: message.productList,
|
|
875
|
+
headerImage: {
|
|
876
|
+
productId: message.productList[0].products[0].productId,
|
|
877
|
+
jpegThumbnail: thumbnail?.thumbnail || null,
|
|
878
|
+
},
|
|
879
|
+
businessOwnerJid: message.businessOwnerJid,
|
|
880
|
+
},
|
|
881
|
+
listType: proto.Message.ListMessage.ListType.PRODUCT_LIST,
|
|
882
|
+
}
|
|
883
|
+
} else if (hasNonNullishProperty(message, "buttons")) {
|
|
884
|
+
const buttonsMessage = {
|
|
885
|
+
buttons: message.buttons.map((b) => ({
|
|
886
|
+
...b,
|
|
887
|
+
type: proto.Message.ButtonsMessage.Button.Type.RESPONSE,
|
|
888
|
+
})),
|
|
681
889
|
}
|
|
682
|
-
}
|
|
683
|
-
|
|
684
|
-
else if ('ptv' in message && message.ptv) {
|
|
685
|
-
const { videoMessage } = await prepareWAMessageMedia({ video: message.video }, options)
|
|
686
|
-
|
|
687
|
-
m.ptvMessage = videoMessage
|
|
688
|
-
}
|
|
689
890
|
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
891
|
+
if (hasNonNullishProperty(message, "text")) {
|
|
892
|
+
buttonsMessage.contentText = message.text
|
|
893
|
+
buttonsMessage.headerType =
|
|
894
|
+
proto.Message.ButtonsMessage.HeaderType.EMPTY
|
|
895
|
+
} else {
|
|
896
|
+
if (hasNonNullishProperty(message, "caption")) {
|
|
897
|
+
buttonsMessage.contentText = message.caption
|
|
898
|
+
}
|
|
693
899
|
|
|
694
|
-
|
|
695
|
-
expectedImageCount: imageMessages.length,
|
|
696
|
-
expectedVideoCount: videoMessages.length
|
|
697
|
-
})
|
|
698
|
-
}
|
|
900
|
+
const type = Object.keys(m)[0].replace("Message", "").toUpperCase()
|
|
699
901
|
|
|
700
|
-
|
|
701
|
-
|
|
902
|
+
buttonsMessage.headerType =
|
|
903
|
+
proto.Message.ButtonsMessage.HeaderType[type]
|
|
702
904
|
|
|
703
|
-
|
|
704
|
-
...(message.contextInfo || {}),
|
|
705
|
-
...(message.mentions ? { mentionedJid: message.mentions } : {})
|
|
905
|
+
Object.assign(buttonsMessage, m)
|
|
706
906
|
}
|
|
707
|
-
}
|
|
708
|
-
|
|
709
|
-
else if ('event' in message) {
|
|
710
|
-
m.eventMessage = WAProto.Message.EventMessage.fromObject(message.event)
|
|
711
|
-
|
|
712
|
-
if (!message.event.startTime) {
|
|
713
|
-
m.eventMessage.startTime = unixTimestampSeconds() + 86400
|
|
714
|
-
}
|
|
715
|
-
|
|
716
|
-
if (options.getCallLink && message.event.call) {
|
|
717
|
-
const link = await options.getCallLink(message.event.call, m.eventMessage.startTime)
|
|
718
|
-
m.eventMessage.joinLink = link
|
|
719
|
-
}
|
|
720
907
|
|
|
908
|
+
if (hasNonNullishProperty(message, "title")) {
|
|
909
|
+
buttonsMessage.text = message.title
|
|
910
|
+
buttonsMessage.headerType =
|
|
911
|
+
proto.Message.ButtonsMessage.HeaderType.TEXT
|
|
912
|
+
}
|
|
721
913
|
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
...(message.mentions ? { mentionedJid: message.mentions } : {})
|
|
914
|
+
if (hasNonNullishProperty(message, "footer")) {
|
|
915
|
+
buttonsMessage.footerText = message.footer
|
|
725
916
|
}
|
|
726
|
-
}
|
|
727
917
|
|
|
728
|
-
|
|
729
|
-
|
|
918
|
+
m = { buttonsMessage }
|
|
919
|
+
} else if (hasNonNullishProperty(message, "templateButtons")) {
|
|
920
|
+
const hydratedTemplate = {
|
|
921
|
+
hydratedButtons: message.templateButtons,
|
|
922
|
+
}
|
|
730
923
|
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
924
|
+
if (hasNonNullishProperty(message, "text")) {
|
|
925
|
+
hydratedTemplate.hydratedContentText = message.text
|
|
926
|
+
} else {
|
|
927
|
+
if (hasNonNullishProperty(message, "caption")) {
|
|
928
|
+
hydratedTemplate.hydratedContentText = message.caption
|
|
736
929
|
}
|
|
737
|
-
})
|
|
738
930
|
|
|
739
|
-
|
|
740
|
-
...(message.contextInfo || {}),
|
|
741
|
-
...(message.mentions ? { mentionedJid: message.mentions } : {})
|
|
931
|
+
Object.assign(msg, m)
|
|
742
932
|
}
|
|
743
|
-
}
|
|
744
933
|
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
throw new Boom('Invalid pollResult values', { statusCode: 400 })
|
|
934
|
+
if (hasNonNullishProperty(message, "footer")) {
|
|
935
|
+
hydratedTemplate.hydratedFooterText = message.footer
|
|
748
936
|
}
|
|
749
937
|
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
}
|
|
757
|
-
|
|
758
|
-
pollResultSnapshotMessage.contextInfo = {
|
|
759
|
-
...(message.contextInfo || {}),
|
|
760
|
-
...(message.mentions ? { mentionedJid: message.mentions } : {})
|
|
938
|
+
m = { templateMessage: { hydratedTemplate } }
|
|
939
|
+
} else if (hasNonNullishProperty(message, "interactiveButtons")) {
|
|
940
|
+
const interactiveMessage = {
|
|
941
|
+
nativeFlowMessage: {
|
|
942
|
+
buttons: message.interactiveButtons,
|
|
943
|
+
},
|
|
761
944
|
}
|
|
762
945
|
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
if (!Array.isArray(message.poll.values)) {
|
|
768
|
-
throw new Boom('Invalid poll values', { statusCode: 400 })
|
|
946
|
+
if (hasNonNullishProperty(message, "text")) {
|
|
947
|
+
interactiveMessage.body = {
|
|
948
|
+
text: message.text,
|
|
949
|
+
}
|
|
769
950
|
}
|
|
770
951
|
|
|
771
|
-
if (message
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
952
|
+
if (hasNonNullishProperty(message, "title")) {
|
|
953
|
+
interactiveMessage.header = {
|
|
954
|
+
title: message.title,
|
|
955
|
+
subtitle: null,
|
|
956
|
+
hasMediaAttachment: false,
|
|
957
|
+
}
|
|
775
958
|
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
959
|
+
if (hasNonNullishProperty(message, "subtitle")) {
|
|
960
|
+
interactiveMessage.header.subtitle = message.subtitle
|
|
961
|
+
}
|
|
962
|
+
} else {
|
|
963
|
+
if (hasNonNullishProperty(message, "caption")) {
|
|
964
|
+
interactiveMessage.body = {
|
|
965
|
+
text: message.caption,
|
|
966
|
+
}
|
|
781
967
|
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
968
|
+
interactiveMessage.header = {
|
|
969
|
+
title: null,
|
|
970
|
+
subtitle: null,
|
|
971
|
+
hasMediaAttachment: false,
|
|
972
|
+
...Object.assign(interactiveMessage, m),
|
|
973
|
+
}
|
|
786
974
|
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
} else {
|
|
790
|
-
if(message.poll.selectableCount > 0) {
|
|
791
|
-
m.pollCreationMessageV3 = pollCreationMessage
|
|
792
|
-
} else {
|
|
793
|
-
m.pollCreationMessage = pollCreationMessage
|
|
794
|
-
}
|
|
975
|
+
if (hasNonNullishProperty(message, "title")) {
|
|
976
|
+
interactiveMessage.header.title = message.title
|
|
795
977
|
}
|
|
796
|
-
}
|
|
797
|
-
|
|
798
|
-
else if ('payment' in message) {
|
|
799
|
-
const requestPaymentMessage = {
|
|
800
|
-
amount: {
|
|
801
|
-
currencyCode: message.payment?.currency || 'IDR',
|
|
802
|
-
offset: message.payment?.offset || 0,
|
|
803
|
-
value: message.payment?.amount || 999999999
|
|
804
|
-
},
|
|
805
|
-
expiryTimestamp: message.payment?.expiry || 0,
|
|
806
|
-
amount1000: message.payment?.amount || 999999999 * 1000,
|
|
807
|
-
currencyCodeIso4217: message.payment?.currency || 'IDR',
|
|
808
|
-
requestFrom: message.payment?.from || '0@s.whatsapp.net',
|
|
809
|
-
noteMessage: {
|
|
810
|
-
extendedTextMessage: {
|
|
811
|
-
text: message.payment?.note || 'Notes'
|
|
812
|
-
}
|
|
813
|
-
},
|
|
814
|
-
background: {
|
|
815
|
-
placeholderArgb: message.payment?.image?.placeholderArgb || 4278190080,
|
|
816
|
-
textArgb: message.payment?.image?.textArgb || 4294967295,
|
|
817
|
-
subtextArgb: message.payment?.image?.subtextArgb || 4294967295,
|
|
818
|
-
type: 1
|
|
819
|
-
}
|
|
820
|
-
}
|
|
821
978
|
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
}
|
|
979
|
+
if (hasNonNullishProperty(message, "subtitle")) {
|
|
980
|
+
interactiveMessage.header.subtitle = message.subtitle
|
|
981
|
+
}
|
|
826
982
|
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
const { zip } = require('fflate')
|
|
834
|
-
|
|
835
|
-
const stickerData = {}
|
|
836
|
-
const stickerPromises = stickers.map(async (s, i) => {
|
|
837
|
-
const { stream } = await getStream(s.sticker)
|
|
838
|
-
const buffer = await toBuffer(stream)
|
|
839
|
-
const hash = sha256(buffer).toString('base64url')
|
|
840
|
-
const fileName = `${i.toString().padStart(2, '0')}_${hash}.webp`
|
|
841
|
-
stickerData[fileName] = [new Uint8Array(buffer), { level: 0 }]
|
|
842
|
-
|
|
843
|
-
return {
|
|
844
|
-
fileName,
|
|
845
|
-
mimetype: 'image/webp',
|
|
846
|
-
isAnimated: s.isAnimated || false,
|
|
847
|
-
isLottie: s.isLottie || false,
|
|
848
|
-
emojis: s.emojis || [],
|
|
849
|
-
accessibilityLabel: s.accessibilityLabel || ''
|
|
850
|
-
}
|
|
851
|
-
})
|
|
852
|
-
|
|
853
|
-
const stickerMetadata = await Promise.all(stickerPromises)
|
|
854
|
-
|
|
855
|
-
const zipBuffer = await new Promise((resolve, reject) => {
|
|
856
|
-
zip(stickerData, (err, data) => {
|
|
857
|
-
if (err) {
|
|
858
|
-
reject(err)
|
|
859
|
-
} else {
|
|
860
|
-
resolve(Buffer.from(data))
|
|
861
|
-
}
|
|
862
|
-
})
|
|
863
|
-
})
|
|
864
|
-
|
|
865
|
-
const coverBuffer = await toBuffer((await getStream(cover)).stream)
|
|
866
|
-
|
|
867
|
-
const [stickerPackUpload, coverUpload] = await Promise.all([
|
|
868
|
-
encryptedStream(zipBuffer, 'sticker-pack', { logger: options.logger, opts: options.options }),
|
|
869
|
-
prepareWAMessageMedia({ image: coverBuffer }, { ...options, mediaTypeOverride: 'image' })
|
|
870
|
-
])
|
|
871
|
-
|
|
872
|
-
const stickerPackUploadResult = await options.upload(stickerPackUpload.encFilePath, {
|
|
873
|
-
fileEncSha256B64: stickerPackUpload.fileEncSha256.toString('base64'),
|
|
874
|
-
mediaType: 'sticker-pack',
|
|
875
|
-
timeoutMs: options.mediaUploadTimeoutMs
|
|
876
|
-
})
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
const coverImage = coverUpload.imageMessage
|
|
880
|
-
const imageDataHash = sha256(coverBuffer).toString('base64')
|
|
881
|
-
const stickerPackId = packId || generateMessageID()
|
|
882
|
-
|
|
883
|
-
m.stickerPackMessage = {
|
|
884
|
-
name,
|
|
885
|
-
publisher,
|
|
886
|
-
stickerPackId,
|
|
887
|
-
packDescription: description,
|
|
888
|
-
stickerPackOrigin: proto.Message.StickerPackMessage.StickerPackOrigin.THIRD_PARTY,
|
|
889
|
-
stickerPackSize: stickerPackUpload.fileLength,
|
|
890
|
-
stickers: stickerMetadata,
|
|
891
|
-
fileSha256: stickerPackUpload.fileSha256,
|
|
892
|
-
fileEncSha256: stickerPackUpload.fileEncSha256,
|
|
893
|
-
mediaKey: stickerPackUpload.mediaKey,
|
|
894
|
-
directPath: stickerPackUploadResult.directPath,
|
|
895
|
-
fileLength: stickerPackUpload.fileLength,
|
|
896
|
-
mediaKeyTimestamp: unixTimestampSeconds(),
|
|
897
|
-
trayIconFileName: `${stickerPackId}.png`,
|
|
898
|
-
imageDataHash,
|
|
899
|
-
thumbnailDirectPath: coverImage.directPath,
|
|
900
|
-
thumbnailFileSha256: coverImage.fileSha256,
|
|
901
|
-
thumbnailFileEncSha256: coverImage.fileEncSha256,
|
|
902
|
-
thumbnailHeight: coverImage.height,
|
|
903
|
-
thumbnailWidth: coverImage.width
|
|
904
|
-
}
|
|
905
|
-
|
|
906
|
-
m.stickerPackMessage.contextInfo = {
|
|
907
|
-
...(message.contextInfo || {}),
|
|
908
|
-
...(message.mentions ? { mentionedJid: message.mentions } : {})
|
|
909
|
-
}
|
|
910
|
-
}
|
|
911
|
-
|
|
912
|
-
else if ('sharePhoneNumber' in message) {
|
|
913
|
-
m.protocolMessage = {
|
|
914
|
-
type: WAProto.Message.ProtocolMessage.Type.SHARE_PHONE_NUMBER
|
|
983
|
+
if (hasNonNullishProperty(message, "hasMediaAttachment")) {
|
|
984
|
+
interactiveMessage.header.hasMediaAttachment = Boolean(
|
|
985
|
+
message.hasMediaAttachment
|
|
986
|
+
)
|
|
987
|
+
}
|
|
988
|
+
}
|
|
915
989
|
}
|
|
916
|
-
}
|
|
917
990
|
|
|
918
|
-
|
|
919
|
-
|
|
920
|
-
|
|
991
|
+
if (hasNonNullishProperty(message, "footer")) {
|
|
992
|
+
interactiveMessage.footer = {
|
|
993
|
+
text: message.footer,
|
|
994
|
+
}
|
|
995
|
+
}
|
|
921
996
|
|
|
922
|
-
|
|
923
|
-
|
|
924
|
-
const
|
|
997
|
+
m = { interactiveMessage }
|
|
998
|
+
} else if (hasNonNullishProperty(message, "shop")) {
|
|
999
|
+
const interactiveMessage = {
|
|
1000
|
+
shopStorefrontMessage: {
|
|
1001
|
+
surface: message.shop.surface,
|
|
1002
|
+
id: message.shop.id,
|
|
1003
|
+
},
|
|
1004
|
+
}
|
|
925
1005
|
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
1006
|
+
if (hasNonNullishProperty(message, "text")) {
|
|
1007
|
+
interactiveMessage.body = {
|
|
1008
|
+
text: message.text,
|
|
1009
|
+
}
|
|
929
1010
|
}
|
|
930
1011
|
|
|
931
|
-
|
|
932
|
-
|
|
1012
|
+
if (hasNonNullishProperty(message, "title")) {
|
|
1013
|
+
interactiveMessage.header = {
|
|
1014
|
+
title: message.title,
|
|
1015
|
+
subtitle: null,
|
|
1016
|
+
hasMediaAttachment: false,
|
|
1017
|
+
}
|
|
933
1018
|
|
|
934
|
-
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
|
|
941
|
-
|
|
942
|
-
}
|
|
1019
|
+
if (hasNonNullishProperty(message, "subtitle")) {
|
|
1020
|
+
interactiveMessage.header.subtitle = message.subtitle
|
|
1021
|
+
}
|
|
1022
|
+
} else {
|
|
1023
|
+
if (hasNonNullishProperty(message, "caption")) {
|
|
1024
|
+
interactiveMessage.body = {
|
|
1025
|
+
text: message.caption,
|
|
1026
|
+
}
|
|
943
1027
|
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
|
|
1028
|
+
interactiveMessage.header = {
|
|
1029
|
+
title: null,
|
|
1030
|
+
subtitle: null,
|
|
1031
|
+
hasMediaAttachment: false,
|
|
1032
|
+
...Object.assign(interactiveMessage, m),
|
|
1033
|
+
}
|
|
948
1034
|
|
|
949
|
-
|
|
950
|
-
|
|
1035
|
+
if (hasNonNullishProperty(message, "title")) {
|
|
1036
|
+
interactiveMessage.header.title = message.title
|
|
1037
|
+
}
|
|
951
1038
|
|
|
952
|
-
|
|
953
|
-
|
|
1039
|
+
if (hasNonNullishProperty(message, "subtitle")) {
|
|
1040
|
+
interactiveMessage.header.subtitle = message.subtitle
|
|
1041
|
+
}
|
|
954
1042
|
|
|
955
|
-
|
|
956
|
-
|
|
957
|
-
|
|
958
|
-
|
|
959
|
-
|
|
960
|
-
|
|
961
|
-
productSections: message.productList,
|
|
962
|
-
headerImage: {
|
|
963
|
-
productId: message.productList[0].products[0].productId,
|
|
964
|
-
jpegThumbnail: thumbnail?.thumbnail || null
|
|
965
|
-
},
|
|
966
|
-
businessOwnerJid: message.businessOwnerJid
|
|
967
|
-
},
|
|
968
|
-
listType: proto.Message.ListMessage.ListType.PRODUCT_LIST
|
|
1043
|
+
if (hasNonNullishProperty(message, "hasMediaAttachment")) {
|
|
1044
|
+
interactiveMessage.header.hasMediaAttachment = Boolean(
|
|
1045
|
+
message.hasMediaAttachment
|
|
1046
|
+
)
|
|
1047
|
+
}
|
|
1048
|
+
}
|
|
969
1049
|
}
|
|
970
1050
|
|
|
971
|
-
|
|
972
|
-
|
|
973
|
-
|
|
1051
|
+
if (hasNonNullishProperty(message, "footer")) {
|
|
1052
|
+
interactiveMessage.footer = {
|
|
1053
|
+
text: message.footer,
|
|
1054
|
+
}
|
|
974
1055
|
}
|
|
975
1056
|
|
|
976
|
-
m = {
|
|
977
|
-
}
|
|
978
|
-
|
|
979
|
-
|
|
980
|
-
|
|
981
|
-
|
|
1057
|
+
m = { interactiveMessage }
|
|
1058
|
+
} else if (hasNonNullishProperty(message, "collection")) {
|
|
1059
|
+
const interactiveMessage = {
|
|
1060
|
+
collectionMessage: {
|
|
1061
|
+
bizJid: message.collection.bizJid,
|
|
1062
|
+
id: message.collection.id,
|
|
1063
|
+
messageVersion: message?.collection?.version,
|
|
1064
|
+
},
|
|
982
1065
|
}
|
|
983
1066
|
|
|
984
|
-
if (
|
|
985
|
-
|
|
986
|
-
|
|
1067
|
+
if (hasNonNullishProperty(message, "text")) {
|
|
1068
|
+
interactiveMessage.body = {
|
|
1069
|
+
text: message.text,
|
|
1070
|
+
}
|
|
987
1071
|
}
|
|
988
1072
|
|
|
989
|
-
|
|
990
|
-
|
|
991
|
-
|
|
1073
|
+
if (hasNonNullishProperty(message, "title")) {
|
|
1074
|
+
interactiveMessage.header = {
|
|
1075
|
+
title: message.title,
|
|
1076
|
+
subtitle: null,
|
|
1077
|
+
hasMediaAttachment: false,
|
|
992
1078
|
}
|
|
993
1079
|
|
|
994
|
-
|
|
1080
|
+
if (hasNonNullishProperty(message, "subtitle")) {
|
|
1081
|
+
interactiveMessage.header.subtitle = message.subtitle
|
|
1082
|
+
}
|
|
1083
|
+
} else {
|
|
1084
|
+
if (hasNonNullishProperty(message, "caption")) {
|
|
1085
|
+
interactiveMessage.body = {
|
|
1086
|
+
text: message.caption,
|
|
1087
|
+
}
|
|
995
1088
|
|
|
996
|
-
|
|
1089
|
+
interactiveMessage.header = {
|
|
1090
|
+
title: null,
|
|
1091
|
+
subtitle: null,
|
|
1092
|
+
hasMediaAttachment: false,
|
|
1093
|
+
...Object.assign(interactiveMessage, m),
|
|
1094
|
+
}
|
|
997
1095
|
|
|
998
|
-
|
|
999
|
-
|
|
1096
|
+
if (hasNonNullishProperty(message, "title")) {
|
|
1097
|
+
interactiveMessage.header.title = message.title
|
|
1098
|
+
}
|
|
1000
1099
|
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1100
|
+
if (hasNonNullishProperty(message, "subtitle")) {
|
|
1101
|
+
interactiveMessage.header.subtitle = message.subtitle
|
|
1102
|
+
}
|
|
1004
1103
|
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1104
|
+
if (hasNonNullishProperty(message, "hasMediaAttachment")) {
|
|
1105
|
+
interactiveMessage.header.hasMediaAttachment = Boolean(
|
|
1106
|
+
message.hasMediaAttachment
|
|
1107
|
+
)
|
|
1108
|
+
}
|
|
1109
|
+
}
|
|
1008
1110
|
}
|
|
1009
1111
|
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1112
|
+
if (hasNonNullishProperty(message, "footer")) {
|
|
1113
|
+
interactiveMessage.footer = {
|
|
1114
|
+
text: message.footer,
|
|
1115
|
+
}
|
|
1013
1116
|
}
|
|
1014
1117
|
|
|
1015
|
-
m = {
|
|
1016
|
-
}
|
|
1118
|
+
m = { interactiveMessage }
|
|
1119
|
+
} else if (hasNonNullishProperty(message, "cards")) {
|
|
1120
|
+
const slides = await Promise.all(
|
|
1121
|
+
message.cards.map(async (slide) => {
|
|
1122
|
+
const {
|
|
1123
|
+
image,
|
|
1124
|
+
video,
|
|
1125
|
+
product,
|
|
1126
|
+
title,
|
|
1127
|
+
body,
|
|
1128
|
+
footer,
|
|
1129
|
+
buttons,
|
|
1130
|
+
} = slide
|
|
1017
1131
|
|
|
1018
|
-
|
|
1019
|
-
const hydratedTemplate = {
|
|
1020
|
-
hydratedButtons: message.templateButtons
|
|
1021
|
-
}
|
|
1132
|
+
let header
|
|
1022
1133
|
|
|
1023
|
-
|
|
1024
|
-
|
|
1025
|
-
|
|
1134
|
+
if (product) {
|
|
1135
|
+
const { imageMessage } = await prepareWAMessageMedia(
|
|
1136
|
+
{ image: product.productImage, ...options },
|
|
1137
|
+
options
|
|
1138
|
+
)
|
|
1139
|
+
header = {
|
|
1140
|
+
productMessage: {
|
|
1141
|
+
product: {
|
|
1142
|
+
...product,
|
|
1143
|
+
productImage: imageMessage,
|
|
1144
|
+
},
|
|
1145
|
+
...slide,
|
|
1146
|
+
},
|
|
1147
|
+
}
|
|
1148
|
+
} else if (image) {
|
|
1149
|
+
header = await prepareWAMessageMedia(
|
|
1150
|
+
{ image: image, ...options },
|
|
1151
|
+
options
|
|
1152
|
+
)
|
|
1153
|
+
} else if (video) {
|
|
1154
|
+
header = await prepareWAMessageMedia(
|
|
1155
|
+
{ video: video, ...options },
|
|
1156
|
+
options
|
|
1157
|
+
)
|
|
1158
|
+
}
|
|
1026
1159
|
|
|
1027
|
-
|
|
1028
|
-
|
|
1029
|
-
|
|
1030
|
-
|
|
1160
|
+
const msg = {
|
|
1161
|
+
header: {
|
|
1162
|
+
title,
|
|
1163
|
+
hasMediaAttachment: true,
|
|
1164
|
+
...header,
|
|
1165
|
+
},
|
|
1166
|
+
body: {
|
|
1167
|
+
text: body,
|
|
1168
|
+
},
|
|
1169
|
+
footer: {
|
|
1170
|
+
text: footer,
|
|
1171
|
+
},
|
|
1172
|
+
nativeFlowMessage: {
|
|
1173
|
+
buttons,
|
|
1174
|
+
},
|
|
1175
|
+
}
|
|
1031
1176
|
|
|
1032
|
-
|
|
1033
|
-
|
|
1177
|
+
return msg
|
|
1178
|
+
})
|
|
1179
|
+
)
|
|
1034
1180
|
|
|
1035
|
-
|
|
1036
|
-
|
|
1181
|
+
const interactiveMessage = {
|
|
1182
|
+
carouselMessage: {
|
|
1183
|
+
cards: slides,
|
|
1184
|
+
},
|
|
1037
1185
|
}
|
|
1038
1186
|
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
|
|
1187
|
+
if (hasNonNullishProperty(message, "text")) {
|
|
1188
|
+
interactiveMessage.body = {
|
|
1189
|
+
text: message.text,
|
|
1190
|
+
}
|
|
1042
1191
|
}
|
|
1043
1192
|
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
nativeFlowMessage: {
|
|
1050
|
-
buttons: message.interactiveButtons
|
|
1051
|
-
}
|
|
1052
|
-
}
|
|
1053
|
-
|
|
1054
|
-
if ('text' in message) {
|
|
1055
|
-
interactiveMessage.body = {
|
|
1056
|
-
text: message.text
|
|
1057
|
-
},
|
|
1058
|
-
interactiveMessage.header = {
|
|
1059
|
-
title: message.title,
|
|
1060
|
-
subtitle: message.subtitle,
|
|
1061
|
-
hasMediaAttachment: false
|
|
1062
|
-
}
|
|
1063
|
-
}
|
|
1064
|
-
|
|
1065
|
-
else {
|
|
1066
|
-
if ('caption' in message) {
|
|
1067
|
-
interactiveMessage.body = {
|
|
1068
|
-
text: message.caption
|
|
1069
|
-
}
|
|
1070
|
-
|
|
1071
|
-
interactiveMessage.header = {
|
|
1072
|
-
title: message.title,
|
|
1073
|
-
subtitle: message.subtitle,
|
|
1074
|
-
hasMediaAttachment: message.hasMediaAttachment ? message.hasMediaAttachment : false,
|
|
1075
|
-
...Object.assign(interactiveMessage, m)
|
|
1076
|
-
}
|
|
1077
|
-
}
|
|
1078
|
-
}
|
|
1079
|
-
|
|
1080
|
-
if ('footer' in message && !!message.footer) {
|
|
1081
|
-
interactiveMessage.footer = {
|
|
1082
|
-
text: message.footer
|
|
1083
|
-
}
|
|
1084
|
-
}
|
|
1085
|
-
|
|
1086
|
-
interactiveMessage.contextInfo = {
|
|
1087
|
-
...(message.contextInfo || {}),
|
|
1088
|
-
...(message.mentions ? { mentionedJid: message.mentions } : {})
|
|
1089
|
-
}
|
|
1090
|
-
|
|
1091
|
-
m = { interactiveMessage }
|
|
1092
|
-
}
|
|
1093
|
-
|
|
1094
|
-
else if ('shop' in message && !!message.shop) {
|
|
1095
|
-
const interactiveMessage = {
|
|
1096
|
-
shopStorefrontMessage: {
|
|
1097
|
-
surface: message.shop.surface,
|
|
1098
|
-
id: message.shop.id
|
|
1099
|
-
}
|
|
1100
|
-
}
|
|
1101
|
-
|
|
1102
|
-
if ('text' in message) {
|
|
1103
|
-
interactiveMessage.body = {
|
|
1104
|
-
text: message.text
|
|
1105
|
-
},
|
|
1106
|
-
interactiveMessage.header = {
|
|
1107
|
-
title: message.title,
|
|
1108
|
-
subtitle: message.subtitle,
|
|
1109
|
-
hasMediaAttachment: false
|
|
1110
|
-
}
|
|
1111
|
-
}
|
|
1112
|
-
|
|
1113
|
-
else {
|
|
1114
|
-
if ('caption' in message) {
|
|
1115
|
-
interactiveMessage.body = {
|
|
1116
|
-
text: message.caption
|
|
1117
|
-
}
|
|
1118
|
-
|
|
1119
|
-
interactiveMessage.header = {
|
|
1120
|
-
title: message.title,
|
|
1121
|
-
subtitle: message.subtitle,
|
|
1122
|
-
hasMediaAttachment: message.hasMediaAttachment ? message.hasMediaAttachment : false,
|
|
1123
|
-
...Object.assign(interactiveMessage, m)
|
|
1193
|
+
if (hasNonNullishProperty(message, "title")) {
|
|
1194
|
+
interactiveMessage.header = {
|
|
1195
|
+
title: message.title,
|
|
1196
|
+
subtitle: null,
|
|
1197
|
+
hasMediaAttachment: false,
|
|
1124
1198
|
}
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
if ('footer' in message && !!message.footer) {
|
|
1129
|
-
interactiveMessage.footer = {
|
|
1130
|
-
text: message.footer
|
|
1131
|
-
}
|
|
1132
|
-
}
|
|
1133
|
-
|
|
1134
|
-
interactiveMessage.contextInfo = {
|
|
1135
|
-
...(message.contextInfo || {}),
|
|
1136
|
-
...(message.mentions ? { mentionedJid: message.mentions } : {})
|
|
1137
|
-
}
|
|
1138
|
-
|
|
1139
|
-
m = { interactiveMessage }
|
|
1140
|
-
}
|
|
1141
|
-
|
|
1142
|
-
else if ('collection' in message && !!message.collection) {
|
|
1143
|
-
const interactiveMessage = {
|
|
1144
|
-
collectionMessage: {
|
|
1145
|
-
bizJid: message.collection.bizJid,
|
|
1146
|
-
id: message.collection.id,
|
|
1147
|
-
messageVersion: message?.collection?.version
|
|
1148
|
-
}
|
|
1149
|
-
}
|
|
1150
|
-
|
|
1151
|
-
if ('text' in message) {
|
|
1152
|
-
interactiveMessage.body = {
|
|
1153
|
-
text: message.text
|
|
1154
|
-
},
|
|
1155
|
-
interactiveMessage.header = {
|
|
1156
|
-
title: message.title,
|
|
1157
|
-
subtitle: message.subtitle,
|
|
1158
|
-
hasMediaAttachment: false
|
|
1159
|
-
}
|
|
1160
|
-
}
|
|
1161
|
-
|
|
1162
|
-
else {
|
|
1163
|
-
if ('caption' in message) {
|
|
1164
|
-
interactiveMessage.body = {
|
|
1165
|
-
text: message.caption
|
|
1166
|
-
}
|
|
1167
|
-
interactiveMessage.header = {
|
|
1168
|
-
title: message.title,
|
|
1169
|
-
subtitle: message.subtitle,
|
|
1170
|
-
hasMediaAttachment: message.hasMediaAttachment ? message.hasMediaAttachment : false,
|
|
1171
|
-
...Object.assign(interactiveMessage, m)
|
|
1199
|
+
|
|
1200
|
+
if (hasNonNullishProperty(message, "subtitle")) {
|
|
1201
|
+
interactiveMessage.header.subtitle = message.subtitle
|
|
1172
1202
|
}
|
|
1173
|
-
|
|
1174
|
-
|
|
1203
|
+
} else {
|
|
1204
|
+
if (hasNonNullishProperty(message, "caption")) {
|
|
1205
|
+
interactiveMessage.body = {
|
|
1206
|
+
text: message.caption,
|
|
1207
|
+
}
|
|
1175
1208
|
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
|
|
1209
|
+
interactiveMessage.header = {
|
|
1210
|
+
title: null,
|
|
1211
|
+
subtitle: null,
|
|
1212
|
+
hasMediaAttachment: false,
|
|
1213
|
+
...Object.assign(interactiveMessage, m),
|
|
1214
|
+
}
|
|
1181
1215
|
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
|
|
1185
|
-
}
|
|
1216
|
+
if (hasNonNullishProperty(message, "title")) {
|
|
1217
|
+
interactiveMessage.header.title = message.title
|
|
1218
|
+
}
|
|
1186
1219
|
|
|
1187
|
-
|
|
1188
|
-
|
|
1220
|
+
if (hasNonNullishProperty(message, "subtitle")) {
|
|
1221
|
+
interactiveMessage.header.subtitle = message.subtitle
|
|
1222
|
+
}
|
|
1189
1223
|
|
|
1190
|
-
|
|
1191
|
-
|
|
1192
|
-
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
if (product) {
|
|
1196
|
-
const { imageMessage } = await prepareWAMessageMedia({ image: product.productImage, ...options }, options)
|
|
1197
|
-
header = {
|
|
1198
|
-
productMessage: {
|
|
1199
|
-
product: {
|
|
1200
|
-
...product,
|
|
1201
|
-
productImage: imageMessage,
|
|
1202
|
-
},
|
|
1203
|
-
...slide
|
|
1204
|
-
}
|
|
1224
|
+
if (hasNonNullishProperty(message, "hasMediaAttachment")) {
|
|
1225
|
+
interactiveMessage.header.hasMediaAttachment = Boolean(
|
|
1226
|
+
message.hasMediaAttachment
|
|
1227
|
+
)
|
|
1205
1228
|
}
|
|
1206
1229
|
}
|
|
1230
|
+
}
|
|
1207
1231
|
|
|
1208
|
-
|
|
1209
|
-
|
|
1232
|
+
if (hasNonNullishProperty(message, "footer")) {
|
|
1233
|
+
interactiveMessage.footer = {
|
|
1234
|
+
text: message.footer,
|
|
1210
1235
|
}
|
|
1236
|
+
}
|
|
1211
1237
|
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1238
|
+
m = { interactiveMessage }
|
|
1239
|
+
} else if (hasNonNullishProperty(message, "text")) {
|
|
1240
|
+
const extContent = { text: message.text }
|
|
1215
1241
|
|
|
1216
|
-
|
|
1217
|
-
header: {
|
|
1218
|
-
title,
|
|
1219
|
-
hasMediaAttachment: true,
|
|
1220
|
-
...header
|
|
1221
|
-
},
|
|
1222
|
-
body: {
|
|
1223
|
-
text: body
|
|
1224
|
-
},
|
|
1225
|
-
footer: {
|
|
1226
|
-
text: footer
|
|
1227
|
-
},
|
|
1228
|
-
nativeFlowMessage: {
|
|
1229
|
-
buttons,
|
|
1230
|
-
}
|
|
1231
|
-
}
|
|
1242
|
+
let urlInfo = message.linkPreview
|
|
1232
1243
|
|
|
1233
|
-
|
|
1234
|
-
|
|
1244
|
+
if (typeof urlInfo === "undefined") {
|
|
1245
|
+
urlInfo = await generateLinkPreviewIfRequired(
|
|
1246
|
+
message.text,
|
|
1247
|
+
options.getUrlInfo,
|
|
1248
|
+
options.logger
|
|
1249
|
+
)
|
|
1250
|
+
}
|
|
1235
1251
|
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1252
|
+
if (urlInfo) {
|
|
1253
|
+
extContent.canonicalUrl = urlInfo["canonical-url"]
|
|
1254
|
+
extContent.matchedText = urlInfo["matched-text"]
|
|
1255
|
+
extContent.jpegThumbnail = urlInfo.jpegThumbnail
|
|
1256
|
+
extContent.description = urlInfo.description
|
|
1257
|
+
extContent.title = urlInfo.title
|
|
1258
|
+
extContent.previewType = 0
|
|
1259
|
+
|
|
1260
|
+
const img = urlInfo.highQualityThumbnail
|
|
1261
|
+
|
|
1262
|
+
if (img) {
|
|
1263
|
+
extContent.thumbnailDirectPath = img.directPath
|
|
1264
|
+
extContent.mediaKey = img.mediaKey
|
|
1265
|
+
extContent.mediaKeyTimestamp = img.mediaKeyTimestamp
|
|
1266
|
+
extContent.thumbnailWidth = img.width
|
|
1267
|
+
extContent.thumbnailHeight = img.height
|
|
1268
|
+
extContent.thumbnailSha256 = img.fileSha256
|
|
1269
|
+
extContent.thumbnailEncSha256 = img.fileEncSha256
|
|
1239
1270
|
}
|
|
1240
1271
|
}
|
|
1241
1272
|
|
|
1242
|
-
if (
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
interactiveMessage.header = {
|
|
1247
|
-
title: message.title,
|
|
1248
|
-
subtitle: message.subtitle,
|
|
1249
|
-
hasMediaAttachment: false
|
|
1250
|
-
}
|
|
1273
|
+
if (options.backgroundColor) {
|
|
1274
|
+
extContent.backgroundArgb = await assertColor(
|
|
1275
|
+
options.backgroundColor
|
|
1276
|
+
)
|
|
1251
1277
|
}
|
|
1252
1278
|
|
|
1253
|
-
if (
|
|
1254
|
-
|
|
1255
|
-
text: message.footer
|
|
1256
|
-
}
|
|
1279
|
+
if (options.textColor) {
|
|
1280
|
+
extContent.textArgb = await assertColor(options.textColor)
|
|
1257
1281
|
}
|
|
1258
1282
|
|
|
1259
|
-
|
|
1260
|
-
|
|
1261
|
-
...(message.mentions ? { mentionedJid: message.mentions } : {})
|
|
1283
|
+
if (options.font) {
|
|
1284
|
+
extContent.font = options.font
|
|
1262
1285
|
}
|
|
1263
1286
|
|
|
1264
|
-
m =
|
|
1287
|
+
m.extendedTextMessage = extContent
|
|
1288
|
+
} else if (hasMedia) {
|
|
1289
|
+
m = await prepareWAMessageMedia(message, options)
|
|
1290
|
+
}
|
|
1291
|
+
|
|
1292
|
+
if (hasOptionalProperty(message, "ephemeral")) {
|
|
1293
|
+
m = { ephemeralMessage: { message: m } }
|
|
1265
1294
|
}
|
|
1266
1295
|
|
|
1267
|
-
if (
|
|
1268
|
-
|
|
1269
|
-
|
|
1296
|
+
if (hasOptionalProperty(message, "mentions") && message.mentions?.length) {
|
|
1297
|
+
const messageType = Object.keys(m)[0]
|
|
1298
|
+
const key = m[messageType]
|
|
1270
1299
|
|
|
1271
|
-
|
|
1272
|
-
|
|
1300
|
+
if ("contextInfo" in key && !!key.contextInfo) {
|
|
1301
|
+
key.contextInfo.mentionedJid = message.mentions
|
|
1302
|
+
} else if (key) {
|
|
1303
|
+
key.contextInfo = {
|
|
1304
|
+
mentionedJid: message.mentions,
|
|
1305
|
+
}
|
|
1306
|
+
}
|
|
1273
1307
|
}
|
|
1274
1308
|
|
|
1275
|
-
if (
|
|
1276
|
-
|
|
1309
|
+
if (hasOptionalProperty(message, "contextInfo") && !!message.contextInfo) {
|
|
1310
|
+
const messageType = Object.keys(m)[0]
|
|
1311
|
+
const key = m[messageType]
|
|
1312
|
+
|
|
1313
|
+
if ("contextInfo" in key && !!key.contextInfo) {
|
|
1314
|
+
key.contextInfo = { ...key.contextInfo, ...message.contextInfo }
|
|
1315
|
+
} else if (key) {
|
|
1316
|
+
key.contextInfo = message.contextInfo
|
|
1317
|
+
}
|
|
1277
1318
|
}
|
|
1278
1319
|
|
|
1279
|
-
if (
|
|
1320
|
+
if (hasOptionalProperty(message, "edit")) {
|
|
1280
1321
|
m = {
|
|
1281
1322
|
protocolMessage: {
|
|
1282
1323
|
key: message.edit,
|
|
1283
1324
|
editedMessage: m,
|
|
1284
1325
|
timestampMs: Date.now(),
|
|
1285
|
-
type: WAProto.Message.ProtocolMessage.Type.MESSAGE_EDIT
|
|
1286
|
-
}
|
|
1326
|
+
type: WAProto.Message.ProtocolMessage.Type.MESSAGE_EDIT,
|
|
1327
|
+
},
|
|
1287
1328
|
}
|
|
1288
1329
|
}
|
|
1289
1330
|
|
|
@@ -1401,7 +1442,7 @@ const generateWAMessage = async (jid, content, options) => {
|
|
|
1401
1442
|
const getContentType = (content) => {
|
|
1402
1443
|
if (content) {
|
|
1403
1444
|
const keys = Object.keys(content)
|
|
1404
|
-
const key = keys.find(k => (k === 'conversation' || k.endsWith('Message') || k.endsWith('V2') || k.endsWith('V3') || k.endsWith('V4')
|
|
1445
|
+
const key = keys.find(k => (k === 'conversation' || k.endsWith('Message') || k.endsWith('V2') || k.endsWith('V3') || k.endsWith('V4')) && k !== 'senderKeyDistributionMessage' && k !== 'messageContextInfo')
|
|
1405
1446
|
|
|
1406
1447
|
return key
|
|
1407
1448
|
}
|
|
@@ -1448,7 +1489,6 @@ const normalizeMessageContent = (content) => {
|
|
|
1448
1489
|
|| (message?.statusMentionMessage)
|
|
1449
1490
|
|| (message?.groupStatusMessageV2)
|
|
1450
1491
|
|| (message?.pollCreationMessageV4)
|
|
1451
|
-
|| (message?.pollCreationMessageV5)
|
|
1452
1492
|
|| (message?.associatedChildMessage)
|
|
1453
1493
|
|| (message?.groupMentionedMessage)
|
|
1454
1494
|
|| (message?.groupStatusMentionMessage)
|
|
@@ -1575,8 +1615,8 @@ const updateMessageWithPollUpdate = (msg, update) => {
|
|
|
1575
1615
|
const updateMessageWithEventResponse = (msg, update) => {
|
|
1576
1616
|
const authorID = getKeyAuthor(update.eventResponseMessageKey)
|
|
1577
1617
|
const responses = (msg.eventResponses || [])
|
|
1578
|
-
|
|
1579
|
-
|
|
1618
|
+
.filter(r => getKeyAuthor(r.eventResponseMessageKey) !== authorID)
|
|
1619
|
+
|
|
1580
1620
|
responses.push(update)
|
|
1581
1621
|
msg.eventResponses = responses
|
|
1582
1622
|
}
|
|
@@ -1640,18 +1680,18 @@ function getAggregateResponsesInEventMessage({ eventResponses }, meLid) {
|
|
|
1640
1680
|
const responseMap = {}
|
|
1641
1681
|
|
|
1642
1682
|
for (const type of responseTypes) {
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1683
|
+
responseMap[type] = {
|
|
1684
|
+
response: type,
|
|
1685
|
+
responders: []
|
|
1686
|
+
}
|
|
1647
1687
|
}
|
|
1648
|
-
|
|
1688
|
+
|
|
1649
1689
|
for (const update of eventResponses) {
|
|
1650
|
-
|
|
1651
|
-
|
|
1652
|
-
|
|
1653
|
-
|
|
1654
|
-
|
|
1690
|
+
const { response } = update.response || 0
|
|
1691
|
+
const responseType = proto.Message.EventResponseMessage.EventResponseType[response]
|
|
1692
|
+
if (responseType !== 'UNKNOWN' && responseMap[responseType]) {
|
|
1693
|
+
responseMap[responseType].responders.push(getKeyAuthor(update.eventResponseMessageKey, meLid))
|
|
1694
|
+
}
|
|
1655
1695
|
}
|
|
1656
1696
|
|
|
1657
1697
|
return Object.values(responseMap)
|
|
@@ -1687,40 +1727,42 @@ const REUPLOAD_REQUIRED_STATUS = [410, 404]
|
|
|
1687
1727
|
*/
|
|
1688
1728
|
const downloadMediaMessage = async (message, type, options, ctx) => {
|
|
1689
1729
|
const result = await downloadMsg().catch(async (error) => {
|
|
1690
|
-
if (ctx &&
|
|
1691
|
-
|
|
1730
|
+
if (ctx &&
|
|
1731
|
+
typeof error?.status === 'number' && // treat errors with status as HTTP failures requiring reupload
|
|
1732
|
+
REUPLOAD_REQUIRED_STATUS.includes(error.status)) {
|
|
1692
1733
|
ctx.logger.info({ key: message.key }, 'sending reupload media request...')
|
|
1693
|
-
|
|
1734
|
+
|
|
1694
1735
|
// request reupload
|
|
1695
1736
|
message = await ctx.reuploadRequest(message)
|
|
1696
|
-
|
|
1737
|
+
|
|
1697
1738
|
const result = await downloadMsg()
|
|
1698
|
-
|
|
1699
1739
|
return result
|
|
1700
1740
|
}
|
|
1701
|
-
|
|
1741
|
+
|
|
1702
1742
|
throw error
|
|
1703
1743
|
})
|
|
1704
|
-
|
|
1744
|
+
|
|
1705
1745
|
return result
|
|
1706
|
-
|
|
1746
|
+
|
|
1707
1747
|
async function downloadMsg() {
|
|
1708
1748
|
const mContent = extractMessageContent(message.message)
|
|
1709
|
-
|
|
1749
|
+
|
|
1710
1750
|
if (!mContent) {
|
|
1711
1751
|
throw new Boom('No message present', { statusCode: 400, data: message })
|
|
1712
1752
|
}
|
|
1713
|
-
|
|
1753
|
+
|
|
1714
1754
|
const contentType = getContentType(mContent)
|
|
1755
|
+
|
|
1715
1756
|
let mediaType = contentType?.replace('Message', '')
|
|
1757
|
+
|
|
1716
1758
|
const media = contentType === 'productMessage' ? mContent[contentType]?.product?.productImage : mContent[contentType]
|
|
1717
|
-
|
|
1759
|
+
|
|
1718
1760
|
if (!media || typeof media !== 'object' || (!('url' in media) && !('thumbnailDirectPath' in media))) {
|
|
1719
1761
|
throw new Boom(`"${contentType}" message is not a media message`)
|
|
1720
1762
|
}
|
|
1721
|
-
|
|
1763
|
+
|
|
1722
1764
|
let download
|
|
1723
|
-
|
|
1765
|
+
|
|
1724
1766
|
if ('thumbnailDirectPath' in media && !('url' in media)) {
|
|
1725
1767
|
download = {
|
|
1726
1768
|
directPath: media.thumbnailDirectPath,
|
|
@@ -1728,68 +1770,40 @@ const downloadMediaMessage = async (message, type, options, ctx) => {
|
|
|
1728
1770
|
}
|
|
1729
1771
|
mediaType = 'thumbnail-link'
|
|
1730
1772
|
}
|
|
1731
|
-
|
|
1732
1773
|
else {
|
|
1733
1774
|
download = media
|
|
1734
1775
|
}
|
|
1735
|
-
|
|
1776
|
+
|
|
1736
1777
|
const stream = await downloadContentFromMessage(download, mediaType, options)
|
|
1737
|
-
|
|
1778
|
+
|
|
1738
1779
|
if (type === 'buffer') {
|
|
1739
1780
|
const bufferArray = []
|
|
1740
|
-
|
|
1741
1781
|
for await (const chunk of stream) {
|
|
1742
|
-
bufferArray.push(chunk)
|
|
1782
|
+
bufferArray.push(chunk);
|
|
1743
1783
|
}
|
|
1744
|
-
|
|
1745
|
-
return Buffer.concat(bufferArray)
|
|
1784
|
+
return Buffer.concat(bufferArray);
|
|
1746
1785
|
}
|
|
1747
|
-
|
|
1748
1786
|
return stream
|
|
1749
1787
|
}
|
|
1750
1788
|
}
|
|
1751
1789
|
|
|
1752
|
-
/** Checks whether the given message is a media message if it is returns the inner content */
|
|
1790
|
+
/** Checks whether the given message is a media message; if it is returns the inner content */
|
|
1753
1791
|
const assertMediaContent = (content) => {
|
|
1754
1792
|
content = extractMessageContent(content)
|
|
1755
|
-
|
|
1756
|
-
const mediaContent = content?.documentMessage
|
|
1757
|
-
|
|
1758
|
-
|
|
1759
|
-
|
|
1760
|
-
|
|
1761
|
-
|
|
1793
|
+
|
|
1794
|
+
const mediaContent = content?.documentMessage ||
|
|
1795
|
+
content?.imageMessage ||
|
|
1796
|
+
content?.videoMessage ||
|
|
1797
|
+
content?.audioMessage ||
|
|
1798
|
+
content?.stickerMessage
|
|
1799
|
+
|
|
1762
1800
|
if (!mediaContent) {
|
|
1763
|
-
throw new Boom('given message is not a media message', { statusCode: 400, data: content })
|
|
1801
|
+
throw new Boom('given message is not a media message', { statusCode: 400, data: content });
|
|
1764
1802
|
}
|
|
1803
|
+
|
|
1765
1804
|
return mediaContent
|
|
1766
1805
|
}
|
|
1767
1806
|
|
|
1768
|
-
/**
|
|
1769
|
-
* this is an experimental patch to make buttons work
|
|
1770
|
-
* Don't know how it works, but it does for now
|
|
1771
|
-
*/
|
|
1772
|
-
const patchMessageForMdIfRequired = (message) => {
|
|
1773
|
-
if (message?.buttonsMessage ||
|
|
1774
|
-
message?.templateMessage ||
|
|
1775
|
-
message?.listMessage ||
|
|
1776
|
-
message?.interactiveMessage?.nativeFlowMesaage
|
|
1777
|
-
) {
|
|
1778
|
-
message = {
|
|
1779
|
-
viewOnceMessageV2Extension: {
|
|
1780
|
-
message: {
|
|
1781
|
-
messageContextInfo: {
|
|
1782
|
-
deviceListMetadataVersion: 2,
|
|
1783
|
-
deviceListMetadata: {}
|
|
1784
|
-
},
|
|
1785
|
-
...message
|
|
1786
|
-
}
|
|
1787
|
-
}
|
|
1788
|
-
}
|
|
1789
|
-
}
|
|
1790
|
-
return message
|
|
1791
|
-
}
|
|
1792
|
-
|
|
1793
1807
|
module.exports = {
|
|
1794
1808
|
extractUrlFromText,
|
|
1795
1809
|
generateLinkPreviewIfRequired,
|
|
@@ -1801,6 +1815,7 @@ module.exports = {
|
|
|
1801
1815
|
generateWAMessageFromContent,
|
|
1802
1816
|
generateWAMessage,
|
|
1803
1817
|
getContentType,
|
|
1818
|
+
hasNonNullishProperty,
|
|
1804
1819
|
normalizeMessageContent,
|
|
1805
1820
|
extractMessageContent,
|
|
1806
1821
|
getDevice,
|
|
@@ -1812,6 +1827,5 @@ module.exports = {
|
|
|
1812
1827
|
getAggregateResponsesInEventMessage,
|
|
1813
1828
|
aggregateMessageKeysNotFromMe,
|
|
1814
1829
|
downloadMediaMessage,
|
|
1815
|
-
assertMediaContent
|
|
1816
|
-
patchMessageForMdIfRequired
|
|
1830
|
+
assertMediaContent
|
|
1817
1831
|
}
|