@ikyyjee/ikyysinggle 1.7.7

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.
Files changed (142) hide show
  1. package/WAProto/GenerateStatics.sh +3 -0
  2. package/WAProto/WAProto.proto +8083 -0
  3. package/WAProto/fix-imports.js +85 -0
  4. package/WAProto/index.d.ts +29095 -0
  5. package/WAProto/index.js +172336 -0
  6. package/engine-requirements.js +10 -0
  7. package/lib/Defaults/index.js +194 -0
  8. package/lib/Signal/Group/ciphertext-message.js +12 -0
  9. package/lib/Signal/Group/group-session-builder.js +30 -0
  10. package/lib/Signal/Group/group_cipher.js +82 -0
  11. package/lib/Signal/Group/index.js +12 -0
  12. package/lib/Signal/Group/keyhelper.js +18 -0
  13. package/lib/Signal/Group/sender-chain-key.js +26 -0
  14. package/lib/Signal/Group/sender-key-distribution-message.js +63 -0
  15. package/lib/Signal/Group/sender-key-message.js +66 -0
  16. package/lib/Signal/Group/sender-key-name.js +48 -0
  17. package/lib/Signal/Group/sender-key-record.js +41 -0
  18. package/lib/Signal/Group/sender-key-state.js +84 -0
  19. package/lib/Signal/Group/sender-message-key.js +26 -0
  20. package/lib/Signal/libsignal.js +431 -0
  21. package/lib/Signal/lid-mapping.js +277 -0
  22. package/lib/Socket/Client/index.js +3 -0
  23. package/lib/Socket/Client/types.js +11 -0
  24. package/lib/Socket/Client/websocket.js +102 -0
  25. package/lib/Socket/aigroups.js +221 -0
  26. package/lib/Socket/business.js +379 -0
  27. package/lib/Socket/chats.js +1193 -0
  28. package/lib/Socket/communities.js +431 -0
  29. package/lib/Socket/graphql.js +524 -0
  30. package/lib/Socket/groups.js +408 -0
  31. package/lib/Socket/index.js +49 -0
  32. package/lib/Socket/interop.js +341 -0
  33. package/lib/Socket/luxu.js +510 -0
  34. package/lib/Socket/managed-account.js +99 -0
  35. package/lib/Socket/messages-recv.js +2009 -0
  36. package/lib/Socket/messages-send.js +1608 -0
  37. package/lib/Socket/mex.js +41 -0
  38. package/lib/Socket/newsletter.js +399 -0
  39. package/lib/Socket/privacy.js +128 -0
  40. package/lib/Socket/registration.js +238 -0
  41. package/lib/Socket/socket.js +1000 -0
  42. package/lib/Socket/text-router.js +67 -0
  43. package/lib/Socket/username.js +234 -0
  44. package/lib/Store/index.js +10 -0
  45. package/lib/Store/keyed-db.js +108 -0
  46. package/lib/Store/make-cache-manager-store.js +85 -0
  47. package/lib/Store/make-in-memory-store.js +198 -0
  48. package/lib/Store/make-ordered-dictionary.js +75 -0
  49. package/lib/Store/object-repository.js +32 -0
  50. package/lib/Types/Auth.js +2 -0
  51. package/lib/Types/Bussines.js +2 -0
  52. package/lib/Types/Call.js +2 -0
  53. package/lib/Types/Chat.js +8 -0
  54. package/lib/Types/Contact.js +2 -0
  55. package/lib/Types/Events.js +2 -0
  56. package/lib/Types/GroupMetadata.js +2 -0
  57. package/lib/Types/Label.js +25 -0
  58. package/lib/Types/LabelAssociation.js +7 -0
  59. package/lib/Types/Message.js +11 -0
  60. package/lib/Types/Mex.js +114 -0
  61. package/lib/Types/Product.js +2 -0
  62. package/lib/Types/Signal.js +2 -0
  63. package/lib/Types/Socket.js +3 -0
  64. package/lib/Types/State.js +56 -0
  65. package/lib/Types/USync.js +2 -0
  66. package/lib/Types/index.js +26 -0
  67. package/lib/Utils/adaptive-healing.js +53 -0
  68. package/lib/Utils/auth-utils.js +302 -0
  69. package/lib/Utils/browser-utils.js +50 -0
  70. package/lib/Utils/business.js +231 -0
  71. package/lib/Utils/chat-utils.js +872 -0
  72. package/lib/Utils/command-loader.js +108 -0
  73. package/lib/Utils/companion-reg-client-utils.js +35 -0
  74. package/lib/Utils/consumer-application.js +106 -0
  75. package/lib/Utils/crypto.js +137 -0
  76. package/lib/Utils/curve25519-js.js +262 -0
  77. package/lib/Utils/decode-wa-message.js +498 -0
  78. package/lib/Utils/event-buffer.js +622 -0
  79. package/lib/Utils/generics.js +403 -0
  80. package/lib/Utils/group-history.js +47 -0
  81. package/lib/Utils/history.js +134 -0
  82. package/lib/Utils/identity-change-handler.js +50 -0
  83. package/lib/Utils/index.js +38 -0
  84. package/lib/Utils/jid-display-normalization.js +198 -0
  85. package/lib/Utils/link-preview.js +85 -0
  86. package/lib/Utils/logger.js +3 -0
  87. package/lib/Utils/lt-hash.js +8 -0
  88. package/lib/Utils/make-mutex.js +33 -0
  89. package/lib/Utils/message-composer.js +273 -0
  90. package/lib/Utils/message-retry-manager.js +267 -0
  91. package/lib/Utils/messages-media.js +791 -0
  92. package/lib/Utils/messages.js +1260 -0
  93. package/lib/Utils/meta-ai-msmsg.js +271 -0
  94. package/lib/Utils/native-bridge.js +77 -0
  95. package/lib/Utils/noise-handler.js +201 -0
  96. package/lib/Utils/offline-node-processor.js +40 -0
  97. package/lib/Utils/optimizer.js +90 -0
  98. package/lib/Utils/pre-key-manager.js +106 -0
  99. package/lib/Utils/process-message.js +630 -0
  100. package/lib/Utils/reporting-utils.js +258 -0
  101. package/lib/Utils/session-pool.js +73 -0
  102. package/lib/Utils/signal.js +207 -0
  103. package/lib/Utils/stanza-ack.js +38 -0
  104. package/lib/Utils/sticker.js +139 -0
  105. package/lib/Utils/sync-action-utils.js +49 -0
  106. package/lib/Utils/tc-token-utils.js +163 -0
  107. package/lib/Utils/use-multi-file-auth-state.js +121 -0
  108. package/lib/Utils/use-sqlite-auth-state.js +168 -0
  109. package/lib/Utils/validate-connection.js +203 -0
  110. package/lib/Utils/view-once-cache.js +79 -0
  111. package/lib/Utils/voip-rekey.js +25 -0
  112. package/lib/Utils/warmup.js +117 -0
  113. package/lib/WABinary/constants.js +1301 -0
  114. package/lib/WABinary/decode.js +262 -0
  115. package/lib/WABinary/encode.js +220 -0
  116. package/lib/WABinary/generic-utils.js +204 -0
  117. package/lib/WABinary/index.js +6 -0
  118. package/lib/WABinary/jid-utils.js +98 -0
  119. package/lib/WABinary/types.js +2 -0
  120. package/lib/WAM/BinaryInfo.js +10 -0
  121. package/lib/WAM/constants.js +22853 -0
  122. package/lib/WAM/encode.js +150 -0
  123. package/lib/WAM/index.js +4 -0
  124. package/lib/WAUSync/Protocols/USyncBusinessProtocol.js +41 -0
  125. package/lib/WAUSync/Protocols/USyncContactProtocol.js +52 -0
  126. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +54 -0
  127. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +27 -0
  128. package/lib/WAUSync/Protocols/USyncFeatureProtocol.js +52 -0
  129. package/lib/WAUSync/Protocols/USyncPictureProtocol.js +31 -0
  130. package/lib/WAUSync/Protocols/USyncSidelistProtocol.js +26 -0
  131. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +38 -0
  132. package/lib/WAUSync/Protocols/USyncTextStatusProtocol.js +35 -0
  133. package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +25 -0
  134. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +51 -0
  135. package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +29 -0
  136. package/lib/WAUSync/Protocols/index.js +13 -0
  137. package/lib/WAUSync/USyncQuery.js +127 -0
  138. package/lib/WAUSync/USyncUser.js +31 -0
  139. package/lib/WAUSync/index.js +4 -0
  140. package/lib/antiban.js +4083 -0
  141. package/lib/index.js +24 -0
  142. package/package.json +147 -0
@@ -0,0 +1,510 @@
1
+ import { proto } from '../../WAProto/index.js'
2
+ import * as Utils from '../Utils/index.js'
3
+ import crypto from 'crypto'
4
+ import { isJidGroup, isPnUser, jidNormalizedUser, STORIES_JID } from '../WABinary/index.js'
5
+
6
+ export default class imup {
7
+ constructor(utils, waUploadToServer, relayMessageFn, context) {
8
+ this.utils = utils
9
+ this.relayMessage = relayMessageFn
10
+ this.waUploadToServer = waUploadToServer
11
+ // `context` is optional so existing 3-arg call sites keep working
12
+ // unchanged. Only sendStatusWhatsApp() below needs it.
13
+ this.context = context || {}
14
+ }
15
+
16
+ detectType(content) {
17
+ if (content.requestPaymentMessage) return 'PAYMENT'
18
+ if (content.productMessage) return 'PRODUCT'
19
+ if (content.albumMessage) return 'ALBUM'
20
+ if (content.eventMessage) return 'EVENT'
21
+ if (content.pollResultMessage) return 'POLL_RESULT'
22
+ if (content.orderMessage) return 'ORDER'
23
+ if (content.groupStatus) return 'GROUP_STATUS'
24
+ if (content.groupLabel) return 'GROUP_LABEL'
25
+ return null
26
+ }
27
+
28
+ async handlePayment(content, quoted) {
29
+ const data = content.requestPaymentMessage
30
+ let notes = {}
31
+
32
+ if (data.sticker?.stickerMessage) {
33
+ notes = {
34
+ stickerMessage: {
35
+ ...data.sticker.stickerMessage,
36
+ contextInfo: {
37
+ stanzaId: quoted?.key?.id,
38
+ participant: quoted?.key?.participant || content.sender,
39
+ quotedMessage: quoted?.message
40
+ }
41
+ }
42
+ }
43
+ } else if (data.note) {
44
+ notes = {
45
+ extendedTextMessage: {
46
+ text: data.note,
47
+ contextInfo: {
48
+ stanzaId: quoted?.key?.id,
49
+ participant: quoted?.key?.participant || content.sender,
50
+ quotedMessage: quoted?.message
51
+ }
52
+ }
53
+ }
54
+ }
55
+
56
+ return {
57
+ requestPaymentMessage: proto.Message.RequestPaymentMessage.fromObject({
58
+ expiryTimestamp: data.expiry || 0,
59
+ amount1000: data.amount || 0,
60
+ currencyCodeIso4217: data.currency || "IDR",
61
+ requestFrom: data.from || "0@s.whatsapp.net",
62
+ noteMessage: notes,
63
+ background: data.background?? {
64
+ id: "DEFAULT",
65
+ placeholderArgb: 0xFFF0F0F0
66
+ }
67
+ })
68
+ }
69
+ }
70
+
71
+ async handleProduct(content, jid, quoted) {
72
+ const {
73
+ title,
74
+ description,
75
+ thumbnail,
76
+ productId,
77
+ retailerId,
78
+ url,
79
+ body = "",
80
+ footer = "",
81
+ buttons = [],
82
+ priceAmount1000 = null,
83
+ currencyCode = "IDR"
84
+ } = content.productMessage
85
+
86
+ let productImage
87
+
88
+ if (Buffer.isBuffer(thumbnail)) {
89
+ const { imageMessage } = await this.utils.generateWAMessageContent(
90
+ { image: thumbnail },
91
+ { upload: this.waUploadToServer }
92
+ )
93
+ productImage = imageMessage
94
+ } else if (typeof thumbnail === 'object' && thumbnail.url) {
95
+ const { imageMessage } = await this.utils.generateWAMessageContent(
96
+ { image: { url: thumbnail.url } },
97
+ { upload: this.waUploadToServer }
98
+ )
99
+ productImage = imageMessage
100
+ }
101
+
102
+ return {
103
+ viewOnceMessage: {
104
+ message: {
105
+ interactiveMessage: {
106
+ body: { text: body },
107
+ footer: { text: footer },
108
+ header: {
109
+ title,
110
+ hasMediaAttachment: true,
111
+ productMessage: {
112
+ product: {
113
+ productImage,
114
+ productId,
115
+ title,
116
+ description,
117
+ currencyCode,
118
+ priceAmount1000,
119
+ retailerId,
120
+ url,
121
+ productImageCount: 1
122
+ },
123
+ businessOwnerJid: "0@s.whatsapp.net"
124
+ }
125
+ },
126
+ nativeFlowMessage: { buttons }
127
+ }
128
+ }
129
+ }
130
+ }
131
+ }
132
+
133
+ async handleAlbum(content, jid, quoted) {
134
+ const array = content.albumMessage
135
+ const album = await this.utils.generateWAMessageFromContent(jid, {
136
+ messageContextInfo: {
137
+ messageSecret: crypto.randomBytes(32),
138
+ },
139
+ albumMessage: {
140
+ expectedImageCount: array.filter((a) => a.hasOwnProperty("image")).length,
141
+ expectedVideoCount: array.filter((a) => a.hasOwnProperty("video")).length,
142
+ },
143
+ }, {
144
+ userJid: this.utils.generateMessageID().split('@')[0] + '@s.whatsapp.net',
145
+ quoted,
146
+ upload: this.waUploadToServer
147
+ })
148
+
149
+ await this.relayMessage(jid, album.message, {
150
+ messageId: album.key.id,
151
+ noSelfSync: true
152
+ })
153
+
154
+ for (let content of array) {
155
+ const img = await this.utils.generateWAMessage(jid, content, {
156
+ upload: this.waUploadToServer,
157
+ })
158
+
159
+ img.message.messageContextInfo = {
160
+ messageSecret: crypto.randomBytes(32),
161
+ messageAssociation: {
162
+ associationType: 1,
163
+ parentMessageKey: album.key,
164
+ },
165
+ participant: "0@s.whatsapp.net",
166
+ remoteJid: "status@broadcast",
167
+ forwardingScore: 99999,
168
+ isForwarded: true,
169
+ mentionedJid: [jid],
170
+ starred: true,
171
+ labels: ["Y", "Important"],
172
+ isHighlighted: true,
173
+ businessMessageForwardInfo: {
174
+ businessOwnerJid: jid,
175
+ },
176
+ dataSharingContext: {
177
+ showMmDisclosure: true,
178
+ },
179
+ }
180
+
181
+ img.message.forwardedNewsletterMessageInfo = {
182
+ newsletterJid: "0@newsletter",
183
+ serverMessageId: 1,
184
+ newsletterName: `WhatsApp`,
185
+ timestamp: new Date().toISOString(),
186
+ senderName: "7-Yuukey",
187
+ contentType: "UPDATE_CARD",
188
+ priority: "high",
189
+ status: "sent",
190
+ }
191
+
192
+ img.message.disappearingMode = {
193
+ initiator: 3,
194
+ trigger: 4,
195
+ initiatorDeviceJid: jid,
196
+ initiatedByExternalService: true,
197
+ initiatedByUserDevice: true,
198
+ initiatedBySystem: true,
199
+ initiatedByServer: true,
200
+ initiatedByAdmin: true,
201
+ initiatedByUser: true,
202
+ initiatedByApp: true,
203
+ initiatedByBot: true,
204
+ initiatedByMe: true,
205
+ }
206
+
207
+ await this.relayMessage(jid, img.message, {
208
+ messageId: img.key.id,
209
+ quoted: {
210
+ key: {
211
+ remoteJid: album.key.remoteJid,
212
+ id: album.key.id,
213
+ fromMe: true,
214
+ participant: this.utils.generateMessageID().split('@')[0] + '@s.whatsapp.net',
215
+ },
216
+ message: album.message,
217
+ },
218
+ })
219
+ }
220
+ return album
221
+ }
222
+
223
+ async handleEvent(content, jid, quoted) {
224
+ const eventData = content.eventMessage
225
+
226
+ const msg = await this.utils.generateWAMessageFromContent(jid, {
227
+ viewOnceMessage: {
228
+ message: {
229
+ messageContextInfo: {
230
+ deviceListMetadata: {},
231
+ deviceListMetadataVersion: 2,
232
+ messageSecret: crypto.randomBytes(32),
233
+ supportPayload: JSON.stringify({
234
+ version: 2,
235
+ is_ai_message: true,
236
+ should_show_system_message: true,
237
+ ticket_id: crypto.randomBytes(16).toString('hex')
238
+ })
239
+ },
240
+ eventMessage: {
241
+ contextInfo: {
242
+ mentionedJid: [jid],
243
+ participant: jid,
244
+ remoteJid: "status@broadcast",
245
+ forwardedNewsletterMessageInfo: {
246
+ newsletterName: "XYCoolcraft",
247
+ newsletterJid: "120363421563597486@newsletter",
248
+ serverMessageId: 1
249
+ }
250
+ },
251
+ isCanceled: eventData.isCanceled || false,
252
+ name: eventData.name,
253
+ description: eventData.description,
254
+ location: eventData.location || {
255
+ degreesLatitude: 0,
256
+ degreesLongitude: 0,
257
+ name: "Location"
258
+ },
259
+ joinLink: eventData.joinLink || '',
260
+ startTime: typeof eventData.startTime === 'string'? parseInt(eventData.startTime) : eventData.startTime || Date.now(),
261
+ endTime: typeof eventData.endTime === 'string'? parseInt(eventData.endTime) : eventData.endTime || Date.now() + 3600000,
262
+ extraGuestsAllowed: eventData.extraGuestsAllowed!== false
263
+ }
264
+ }
265
+ }
266
+ }, { quoted })
267
+
268
+ await this.relayMessage(jid, msg.message, {
269
+ messageId: msg.key.id,
270
+ noSelfSync: true
271
+ })
272
+ return msg
273
+ }
274
+
275
+ async handlePollResult(content, jid, quoted) {
276
+ const pollData = content.pollResultMessage
277
+ const msg = await this.utils.generateWAMessageFromContent(jid, {
278
+ pollResultSnapshotMessage: {
279
+ name: pollData.name,
280
+ pollVotes: pollData.pollVotes.map(vote => ({
281
+ optionName: vote.optionName,
282
+ optionVoteCount: typeof vote.optionVoteCount === 'number'
283
+ ? vote.optionVoteCount.toString()
284
+ : vote.optionVoteCount
285
+ })),
286
+ contextInfo: {
287
+ isForwarded: true,
288
+ forwardingScore: 1,
289
+ forwardedNewsletterMessageInfo: {
290
+ newsletterName: pollData.newsletter.newsletterName || "Newsletter",
291
+ newsletterJid: pollData.newsletter.newsletterJid || "120363421563597486@newsletter",
292
+ serverMessageId: 1000,
293
+ contentType: "UPDATE"
294
+ }
295
+ }
296
+ }
297
+ }, {
298
+ userJid: this.utils.generateMessageID().split('@')[0] + '@s.whatsapp.net',
299
+ quoted
300
+ })
301
+
302
+ await this.relayMessage(jid, msg.message, {
303
+ messageId: msg.key.id,
304
+ noSelfSync: true
305
+ })
306
+
307
+ return msg
308
+ }
309
+
310
+ async handleOrderMessage(content, jid, quoted) {
311
+ const orderData = content.orderMessage
312
+
313
+ const Haha = await this.utils.generateWAMessageFromContent(jid, {
314
+ orderMessage: {
315
+ orderId: orderData.orderId || ("XYCOOLCRAFT" + Date.now()),
316
+ thumbnail: orderData.thumbnail || null,
317
+ itemCount: orderData.itemCount || 0,
318
+ status: "ACCEPTED",
319
+ surface: "CATALOG",
320
+ message: orderData.message,
321
+ orderTitle: orderData.orderTitle,
322
+ sellerJid: "0@whatsapp.net",
323
+ token: orderData.token || "XYCOOLCRAFT_EXAMPLE_TOKEN",
324
+ totalAmount1000: orderData.totalAmount1000 || 0,
325
+ totalCurrencyCode: orderData.totalCurrencyCode || "IDR",
326
+ messageVersion: 2
327
+ }
328
+ }, { quoted: quoted })
329
+
330
+ await this.relayMessage(jid, Haha.message, {})
331
+ return Haha
332
+ }
333
+
334
+ async handleGroupStory(content, jid, quoted) {
335
+ const storyData = content.groupStatus
336
+ let messageContent
337
+
338
+ if (storyData.message) {
339
+ messageContent = storyData
340
+ } else {
341
+ if (typeof this.utils?.generateWAMessageContent === "function") {
342
+ messageContent = await this.utils.generateWAMessageContent(storyData, {
343
+ upload: this.waUploadToServer
344
+ })
345
+ } else {
346
+ messageContent = await Utils.generateWAMessageContent(storyData, {
347
+ upload: this.waUploadToServer
348
+ })
349
+ }
350
+ }
351
+
352
+ let msg = {
353
+ message: {
354
+ groupStatusMessageV2: {
355
+ message: messageContent.message || messageContent
356
+ }
357
+ }
358
+ }
359
+
360
+ return await this.relayMessage(jid, msg.message, {
361
+ messageId: this.utils.generateMessageID(),
362
+ noSelfSync: true
363
+ })
364
+ }
365
+
366
+ async handleGbLabel(content, jid) {
367
+ const x = content.groupLabel
368
+ if (!jid.endsWith('@g.us')) {
369
+ throw new Error('group required!')
370
+ }
371
+
372
+ const msg = await this.utils.generateWAMessageFromContent(jid, {
373
+ protocolMessage: {
374
+ type: "GROUP_MEMBER_LABEL_CHANGE",
375
+ memberLabel: {
376
+ label: x.labelText.slice(0, 30)
377
+ }
378
+ }
379
+ }, {})
380
+
381
+ await this.relayMessage(jid, msg.message, {
382
+ additionalNodes: [
383
+ {
384
+ tag: 'meta',
385
+ attrs: {
386
+ tag_reason: 'user_update',
387
+ appdata: 'member_tag'
388
+ },
389
+ content: undefined
390
+ }
391
+ ]
392
+ })
393
+ }
394
+
395
+ /**
396
+ * Post a WhatsApp Status (story) and notify specific people that they were
397
+ * mentioned in it — including expanding a group JID into its members.
398
+ * Requires `context` to have been passed to the constructor (authState,
399
+ * groupMetadata, logger, and the usual link-preview/media config).
400
+ *
401
+ * @param content Same shape as sendMessage's content (text/image/video/audio/etc).
402
+ * @param jids JIDs (user or group) to notify as "mentioned in this status".
403
+ */
404
+ async sendStatusWhatsApp(content, jids = []) {
405
+ const { authState, groupMetadata, logger, linkPreviewImageThumbnailWidth, generateHighQualityLinkPreview, mediaCache, options } = this.context
406
+ if (!authState) {
407
+ throw new Error('sendStatusWhatsApp requires this.context.authState — pass it to the imup constructor.')
408
+ }
409
+ const userJid = jidNormalizedUser(authState.creds.me.id)
410
+ const allUsers = new Set()
411
+ allUsers.add(userJid)
412
+ for (const id of jids) {
413
+ if (isJidGroup(id)) {
414
+ try {
415
+ const metadata = groupMetadata ? await groupMetadata(id) : null
416
+ metadata?.participants?.forEach(p => allUsers.add(jidNormalizedUser(p.id)))
417
+ }
418
+ catch (error) {
419
+ logger?.error?.({ error, id }, 'sendStatusWhatsApp: failed to get group metadata')
420
+ }
421
+ }
422
+ else if (isPnUser(id)) {
423
+ allUsers.add(jidNormalizedUser(id))
424
+ }
425
+ }
426
+ const uniqueUsers = Array.from(allUsers)
427
+ const getRandomHexColor = () => '#' + Math.floor(Math.random() * 16777215).toString(16).padStart(6, '0')
428
+ const isMedia = !!(content.image || content.video || content.audio)
429
+ const isAudio = !!content.audio
430
+ const messageContent = { ...content }
431
+ if (isMedia && !isAudio) {
432
+ if (messageContent.text) {
433
+ messageContent.caption = messageContent.text
434
+ delete messageContent.text
435
+ }
436
+ delete messageContent.ptt
437
+ delete messageContent.font
438
+ delete messageContent.backgroundColor
439
+ delete messageContent.textColor
440
+ }
441
+ if (isAudio) {
442
+ delete messageContent.text
443
+ delete messageContent.caption
444
+ delete messageContent.font
445
+ delete messageContent.textColor
446
+ }
447
+ const font = !isMedia ? (content.font ?? Math.floor(Math.random() * 9)) : undefined
448
+ const textColor = !isMedia ? (content.textColor || getRandomHexColor()) : undefined
449
+ const backgroundColor = (!isMedia || isAudio) ? (content.backgroundColor || getRandomHexColor()) : undefined
450
+ const ptt = isAudio ? (typeof content.ptt === 'boolean' ? content.ptt : true) : undefined
451
+
452
+ const msg = await this.utils.generateWAMessage(STORIES_JID, messageContent, {
453
+ logger,
454
+ userJid,
455
+ getUrlInfo: text => this.utils.getUrlInfo(text, {
456
+ thumbnailWidth: linkPreviewImageThumbnailWidth,
457
+ fetchOpts: { timeout: 3000, ...(options || {}) },
458
+ logger,
459
+ uploadImage: generateHighQualityLinkPreview ? this.waUploadToServer : undefined
460
+ }),
461
+ upload: this.waUploadToServer,
462
+ mediaCache,
463
+ options,
464
+ font,
465
+ textColor,
466
+ backgroundColor,
467
+ ptt
468
+ })
469
+
470
+ await this.relayMessage(STORIES_JID, msg.message, {
471
+ messageId: msg.key.id,
472
+ statusJidList: uniqueUsers,
473
+ additionalNodes: [{
474
+ tag: 'meta',
475
+ attrs: {},
476
+ content: [{
477
+ tag: 'mentioned_users',
478
+ attrs: {},
479
+ content: jids.map(jid => ({ tag: 'to', attrs: { jid: jidNormalizedUser(jid) } }))
480
+ }]
481
+ }]
482
+ })
483
+
484
+ for (const id of jids) {
485
+ try {
486
+ const normalizedId = jidNormalizedUser(id)
487
+ const isPrivate = isPnUser(normalizedId)
488
+ const type = isPrivate ? 'statusMentionMessage' : 'groupStatusMentionMessage'
489
+ const protocolMessage = {
490
+ [type]: {
491
+ message: { protocolMessage: { key: msg.key, type: 25 } }
492
+ },
493
+ messageContextInfo: { messageSecret: crypto.randomBytes(32) }
494
+ }
495
+ const statusMsg = await this.utils.generateWAMessageFromContent(normalizedId, protocolMessage, { userJid })
496
+ await this.relayMessage(normalizedId, statusMsg.message, {
497
+ additionalNodes: [{
498
+ tag: 'meta',
499
+ attrs: isPrivate ? { is_status_mention: 'true' } : { is_group_status_mention: 'true' }
500
+ }]
501
+ })
502
+ await this.utils.delay(2000)
503
+ }
504
+ catch (error) {
505
+ logger?.error?.({ error, id }, 'sendStatusWhatsApp: failed to notify recipient')
506
+ }
507
+ }
508
+ return msg
509
+ }
510
+ }
@@ -0,0 +1,99 @@
1
+ /**
2
+ * lib/Socket/managed-account.js — account-linking/sponsorship, PIN, and
3
+ * WhatsApp Payments passkey flows. Every call acts on your own account via
4
+ * the standard mex query mechanism; nothing here targets other users.
5
+ */
6
+ import { executeWMexQuery } from './mex.js';
7
+ const MANAGED_ACCOUNT_MEX_IDS = {
8
+ QUERY: '27232244463035264',
9
+ INITIATE_LINKING: '26671873552498548',
10
+ VALIDATE_LINKING: '35449808311284430',
11
+ ACCEPT_LINKING: '26708926155457676',
12
+ COMPLETE_LINKING: '26866501363013204',
13
+ REVOKE_LINKING: '27435058196100676',
14
+ SYNC_ACTIVITIES: '26594352680227840',
15
+ UPDATE_PIN: '27653949584193080',
16
+ GET_SPONSOR_AGE_VERIFICATION: '26433623289634520',
17
+ PAYMENTS_PASSKEY_HAS_CREDENTIAL: '26328228500182424',
18
+ PAYMENTS_PASSKEY_ENROLL_CHALLENGE: '25233109079721000',
19
+ PAYMENTS_PASSKEY_ENROLL_VERIFY: '26563835863283056',
20
+ PAYMENTS_PASSKEY_REGISTER_FINISH: '26658791263822236',
21
+ PAYMENTS_PASSKEY_AUTH_CHALLENGE: '26425370627105628',
22
+ PAYMENTS_PASSKEY_TOGGLE_ON: '25841989828834576',
23
+ PAYMENTS_PASSKEY_TOGGLE_OFF: '26267673096201390',
24
+ PAYMENTS_PASSKEY_TOGGLE_CHALLENGE: '26133062322993190',
25
+ PAYMENTS_PASSKEY_TOGGLE_CLEANUP: '26492078607084840',
26
+ PAYMENTS_PASSKEY_CLEANUP: '26538338805859092',
27
+ PAYMENTS_IS_RECOVERABLE: '26524118810513490',
28
+ UPI_SEND_OTP: '25829794080022468',
29
+ UPI_VERIFY_OTP: '34104109149204668',
30
+ IPLS_HANDSHAKE_INIT: '25523747957257184',
31
+ IPLS_CLIENT_HELLO: '25376330595367716',
32
+ IPLSD_CLIENT_HELLO_V2: '26561780580105680',
33
+ IPLSD_CLIENT_INIT_V2: '26547193874915344'
34
+ };
35
+ export const makeManagedAccountSocket = (sock) => {
36
+ const { query, generateMessageTag } = sock;
37
+ const mexQuery = (variables, queryId, dataPath) => executeWMexQuery(variables, queryId, dataPath, query, generateMessageTag);
38
+ const managedAccountQuery = jid => mexQuery({ jid }, MANAGED_ACCOUNT_MEX_IDS.QUERY, 'xwa2_managed_account');
39
+ const managedAccountInitiateLinking = phoneNumber => mexQuery({ phone_number: phoneNumber }, MANAGED_ACCOUNT_MEX_IDS.INITIATE_LINKING, 'xwa2_managed_account_initiate_linking');
40
+ const managedAccountValidateLinking = (linkingToken, sponsorJid) => mexQuery({ linking_token: linkingToken, sponsor_jid: sponsorJid }, MANAGED_ACCOUNT_MEX_IDS.VALIDATE_LINKING, 'xwa2_managed_account_validate_linking');
41
+ const managedAccountAcceptLinking = linkingToken => mexQuery({ linking_token: linkingToken }, MANAGED_ACCOUNT_MEX_IDS.ACCEPT_LINKING, 'xwa2_managed_account_accept_linking');
42
+ const managedAccountCompleteLinking = linkingToken => mexQuery({ linking_token: linkingToken }, MANAGED_ACCOUNT_MEX_IDS.COMPLETE_LINKING, 'xwa2_managed_account_complete_linking');
43
+ const managedAccountRevokeLinking = sponsoredJid => mexQuery({ sponsored_jid: sponsoredJid }, MANAGED_ACCOUNT_MEX_IDS.REVOKE_LINKING, 'xwa2_managed_account_revoke_linking');
44
+ const managedAccountSyncActivities = (jid, lastSyncTime = null) => {
45
+ const variables = { jid };
46
+ if (lastSyncTime != null)
47
+ variables.last_sync_time = lastSyncTime;
48
+ return mexQuery(variables, MANAGED_ACCOUNT_MEX_IDS.SYNC_ACTIVITIES, 'xwa2_managed_account_sync_activities');
49
+ };
50
+ const managedAccountUpdatePin = (oldPin, newPin) => mexQuery({ input: { old_pin: oldPin, new_pin: newPin } }, MANAGED_ACCOUNT_MEX_IDS.UPDATE_PIN, 'xwa2_managed_account_update_pin');
51
+ const managedAccountGetSponsorAgeVerification = sponsorJid => mexQuery({ sponsor_jid: sponsorJid }, MANAGED_ACCOUNT_MEX_IDS.GET_SPONSOR_AGE_VERIFICATION, 'xwa2_managed_account_sponsor_age_verification');
52
+ const paymentsPasskeyHasCredential = () => mexQuery({}, MANAGED_ACCOUNT_MEX_IDS.PAYMENTS_PASSKEY_HAS_CREDENTIAL, 'xwa2_payments_passkey_has_credential');
53
+ const paymentsPasskeyEnrollChallenge = () => mexQuery({}, MANAGED_ACCOUNT_MEX_IDS.PAYMENTS_PASSKEY_ENROLL_CHALLENGE, 'xwa2_payments_passkey_enroll_challenge');
54
+ const paymentsPasskeyEnrollVerify = (credentialId, attestationObject, clientDataJson) => mexQuery({ credential_id: credentialId, attestation_object: attestationObject, client_data_json: clientDataJson }, MANAGED_ACCOUNT_MEX_IDS.PAYMENTS_PASSKEY_ENROLL_VERIFY, 'xwa2_payments_passkey_enroll_verify');
55
+ const paymentsPasskeyRegisterFinish = (credentialId, attestationObject, clientDataJson) => mexQuery({ credential_id: credentialId, attestation_object: attestationObject, client_data_json: clientDataJson }, MANAGED_ACCOUNT_MEX_IDS.PAYMENTS_PASSKEY_REGISTER_FINISH, 'xwa2_payments_passkey_register_finish');
56
+ const paymentsPasskeyAuthChallenge = credentialId => mexQuery({ credential_id: credentialId }, MANAGED_ACCOUNT_MEX_IDS.PAYMENTS_PASSKEY_AUTH_CHALLENGE, 'xwa2_payments_passkey_auth_challenge');
57
+ const paymentsPasskeyToggleOn = () => mexQuery({}, MANAGED_ACCOUNT_MEX_IDS.PAYMENTS_PASSKEY_TOGGLE_ON, 'xwa2_payments_passkey_toggle_on');
58
+ const paymentsPasskeyToggleOff = () => mexQuery({}, MANAGED_ACCOUNT_MEX_IDS.PAYMENTS_PASSKEY_TOGGLE_OFF, 'xwa2_payments_passkey_toggle_off');
59
+ const paymentsPasskeyToggleChallenge = credentialId => mexQuery({ credential_id: credentialId }, MANAGED_ACCOUNT_MEX_IDS.PAYMENTS_PASSKEY_TOGGLE_CHALLENGE, 'xwa2_payments_passkey_toggle_challenge');
60
+ const paymentsPasskeyToggleCleanup = () => mexQuery({}, MANAGED_ACCOUNT_MEX_IDS.PAYMENTS_PASSKEY_TOGGLE_CLEANUP, 'xwa2_payments_passkey_toggle_cleanup');
61
+ const paymentsPasskeyCleanup = () => mexQuery({}, MANAGED_ACCOUNT_MEX_IDS.PAYMENTS_PASSKEY_CLEANUP, 'xwa2_payments_passkey_cleanup');
62
+ const paymentsIsAccountRecoverable = () => mexQuery({}, MANAGED_ACCOUNT_MEX_IDS.PAYMENTS_IS_RECOVERABLE, 'xwa2_payments_is_account_recoverable');
63
+ const upiSendOtp = phoneNumber => mexQuery({ phone_number: phoneNumber }, MANAGED_ACCOUNT_MEX_IDS.UPI_SEND_OTP, 'xwa2_upi_send_otp');
64
+ const upiVerifyOtp = (phoneNumber, otp) => mexQuery({ phone_number: phoneNumber, otp }, MANAGED_ACCOUNT_MEX_IDS.UPI_VERIFY_OTP, 'xwa2_upi_verify_otp');
65
+ const iplsHandshakeInit = payload => mexQuery({ payload }, MANAGED_ACCOUNT_MEX_IDS.IPLS_HANDSHAKE_INIT, 'xwa2_ipls_handshake_init');
66
+ const iplsClientHello = payload => mexQuery({ payload }, MANAGED_ACCOUNT_MEX_IDS.IPLS_CLIENT_HELLO, 'xwa2_ipls_client_hello');
67
+ const iplsdClientHelloV2 = payload => mexQuery({ payload }, MANAGED_ACCOUNT_MEX_IDS.IPLSD_CLIENT_HELLO_V2, 'xwa2_iplsd_client_hello_v2');
68
+ const iplsdClientInitV2 = payload => mexQuery({ payload }, MANAGED_ACCOUNT_MEX_IDS.IPLSD_CLIENT_INIT_V2, 'xwa2_iplsd_client_init_v2');
69
+ return {
70
+ ...sock,
71
+ managedAccountQuery,
72
+ managedAccountInitiateLinking,
73
+ managedAccountValidateLinking,
74
+ managedAccountAcceptLinking,
75
+ managedAccountCompleteLinking,
76
+ managedAccountRevokeLinking,
77
+ managedAccountSyncActivities,
78
+ managedAccountUpdatePin,
79
+ managedAccountGetSponsorAgeVerification,
80
+ paymentsPasskeyHasCredential,
81
+ paymentsPasskeyEnrollChallenge,
82
+ paymentsPasskeyEnrollVerify,
83
+ paymentsPasskeyRegisterFinish,
84
+ paymentsPasskeyAuthChallenge,
85
+ paymentsPasskeyToggleOn,
86
+ paymentsPasskeyToggleOff,
87
+ paymentsPasskeyToggleChallenge,
88
+ paymentsPasskeyToggleCleanup,
89
+ paymentsPasskeyCleanup,
90
+ paymentsIsAccountRecoverable,
91
+ upiSendOtp,
92
+ upiVerifyOtp,
93
+ iplsHandshakeInit,
94
+ iplsClientHello,
95
+ iplsdClientHelloV2,
96
+ iplsdClientInitV2,
97
+ MANAGED_ACCOUNT_MEX_IDS
98
+ };
99
+ };