ishumdz-bail 1.0.0

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 (118) hide show
  1. package/README.md +772 -0
  2. package/WAProto/fix-imports.js +85 -0
  3. package/WAProto/index.d.ts +79257 -0
  4. package/WAProto/index.js +242946 -0
  5. package/engine-requirements.js +10 -0
  6. package/lib/Defaults/index.js +142 -0
  7. package/lib/Games/index.js +497 -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 +93 -0
  11. package/lib/Signal/Group/index.js +12 -0
  12. package/lib/Signal/Group/keyhelper.js +18 -0
  13. package/lib/Signal/Group/queue-job.js +53 -0
  14. package/lib/Signal/Group/sender-chain-key.js +26 -0
  15. package/lib/Signal/Group/sender-key-distribution-message.js +63 -0
  16. package/lib/Signal/Group/sender-key-message.js +66 -0
  17. package/lib/Signal/Group/sender-key-name.js +48 -0
  18. package/lib/Signal/Group/sender-key-record.js +41 -0
  19. package/lib/Signal/Group/sender-key-state.js +84 -0
  20. package/lib/Signal/Group/sender-message-key.js +26 -0
  21. package/lib/Signal/libsignal.js +431 -0
  22. package/lib/Signal/lid-mapping.js +277 -0
  23. package/lib/Socket/Client/index.js +3 -0
  24. package/lib/Socket/Client/types.js +11 -0
  25. package/lib/Socket/Client/websocket.js +84 -0
  26. package/lib/Socket/ban-checker.js +265 -0
  27. package/lib/Socket/business.js +379 -0
  28. package/lib/Socket/chats.js +1193 -0
  29. package/lib/Socket/communities.js +431 -0
  30. package/lib/Socket/groups.js +374 -0
  31. package/lib/Socket/index.js +13 -0
  32. package/lib/Socket/luxu.js +460 -0
  33. package/lib/Socket/messages-recv.js +1916 -0
  34. package/lib/Socket/messages-send.js +1469 -0
  35. package/lib/Socket/mex.js +41 -0
  36. package/lib/Socket/newsletter.js +261 -0
  37. package/lib/Socket/socket.js +988 -0
  38. package/lib/Socket/username.js +234 -0
  39. package/lib/Store/index.js +10 -0
  40. package/lib/Store/keyed-db.js +108 -0
  41. package/lib/Store/make-cache-manager-store.js +85 -0
  42. package/lib/Store/make-in-memory-store.js +198 -0
  43. package/lib/Store/make-ordered-dictionary.js +75 -0
  44. package/lib/Store/object-repository.js +32 -0
  45. package/lib/Types/Auth.js +2 -0
  46. package/lib/Types/Bussines.js +2 -0
  47. package/lib/Types/Call.js +2 -0
  48. package/lib/Types/Chat.js +8 -0
  49. package/lib/Types/Contact.js +2 -0
  50. package/lib/Types/Events.js +2 -0
  51. package/lib/Types/GroupMetadata.js +2 -0
  52. package/lib/Types/Label.js +25 -0
  53. package/lib/Types/LabelAssociation.js +7 -0
  54. package/lib/Types/Message.js +11 -0
  55. package/lib/Types/Mex.js +37 -0
  56. package/lib/Types/Product.js +2 -0
  57. package/lib/Types/Signal.js +2 -0
  58. package/lib/Types/Socket.js +3 -0
  59. package/lib/Types/State.js +56 -0
  60. package/lib/Types/USync.js +2 -0
  61. package/lib/Types/index.js +26 -0
  62. package/lib/Utils/auth-utils.js +302 -0
  63. package/lib/Utils/browser-utils.js +49 -0
  64. package/lib/Utils/business.js +231 -0
  65. package/lib/Utils/chat-utils.js +872 -0
  66. package/lib/Utils/classify-disconnect.js +126 -0
  67. package/lib/Utils/companion-reg-client-utils.js +35 -0
  68. package/lib/Utils/crypto.js +118 -0
  69. package/lib/Utils/decode-wa-message.js +350 -0
  70. package/lib/Utils/event-buffer.js +622 -0
  71. package/lib/Utils/generics.js +403 -0
  72. package/lib/Utils/history.js +134 -0
  73. package/lib/Utils/identity-change-handler.js +50 -0
  74. package/lib/Utils/index.js +23 -0
  75. package/lib/Utils/link-preview.js +85 -0
  76. package/lib/Utils/logger.js +3 -0
  77. package/lib/Utils/lt-hash.js +8 -0
  78. package/lib/Utils/make-mutex.js +33 -0
  79. package/lib/Utils/message-composer.js +273 -0
  80. package/lib/Utils/message-retry-manager.js +265 -0
  81. package/lib/Utils/messages-media.js +793 -0
  82. package/lib/Utils/messages.js +1586 -0
  83. package/lib/Utils/noise-handler.js +201 -0
  84. package/lib/Utils/offline-node-processor.js +40 -0
  85. package/lib/Utils/pre-key-manager.js +106 -0
  86. package/lib/Utils/process-message.js +630 -0
  87. package/lib/Utils/rate-limiter.js +228 -0
  88. package/lib/Utils/reporting-utils.js +258 -0
  89. package/lib/Utils/signal.js +201 -0
  90. package/lib/Utils/stanza-ack.js +38 -0
  91. package/lib/Utils/sync-action-utils.js +49 -0
  92. package/lib/Utils/tc-token-utils.js +163 -0
  93. package/lib/Utils/use-multi-file-auth-state.js +121 -0
  94. package/lib/Utils/validate-connection.js +203 -0
  95. package/lib/WABinary/constants.js +1301 -0
  96. package/lib/WABinary/decode.js +262 -0
  97. package/lib/WABinary/encode.js +220 -0
  98. package/lib/WABinary/generic-utils.js +204 -0
  99. package/lib/WABinary/index.js +6 -0
  100. package/lib/WABinary/jid-utils.js +98 -0
  101. package/lib/WABinary/types.js +2 -0
  102. package/lib/WAM/BinaryInfo.js +10 -0
  103. package/lib/WAM/constants.js +22853 -0
  104. package/lib/WAM/encode.js +150 -0
  105. package/lib/WAM/index.js +4 -0
  106. package/lib/WAUSync/Protocols/USyncContactProtocol.js +52 -0
  107. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +54 -0
  108. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +27 -0
  109. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +38 -0
  110. package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +25 -0
  111. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +51 -0
  112. package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +29 -0
  113. package/lib/WAUSync/Protocols/index.js +6 -0
  114. package/lib/WAUSync/USyncQuery.js +98 -0
  115. package/lib/WAUSync/USyncUser.js +31 -0
  116. package/lib/WAUSync/index.js +4 -0
  117. package/lib/index.js +37 -0
  118. package/package.json +150 -0
@@ -0,0 +1,460 @@
1
+ import { proto } from '../../WAProto/index.js'
2
+ import * as Utils from '../Utils/index.js'
3
+ import crypto from 'crypto'
4
+
5
+ export default class imup {
6
+ constructor(utils, waUploadToServer, relayMessageFn) {
7
+ this.utils = utils
8
+ this.relayMessage = relayMessageFn
9
+ this.waUploadToServer = waUploadToServer
10
+ }
11
+
12
+ detectType(content) {
13
+ if (content.requestPaymentMessage) return 'PAYMENT'
14
+ if (content.productMessage) return 'PRODUCT'
15
+ if (content.album) return 'ALBUM_V2' // levvleys-style: { album: [...], caption }
16
+ if (content.albumMessage) return 'ALBUM' // edgar legacy: { albumMessage: [...] }
17
+ if (content.eventMessage) return 'EVENT'
18
+ if (content.pollResultMessage) return 'POLL_RESULT'
19
+ if (content.orderMessage) return 'ORDER'
20
+ if (content.groupStatus) return 'GROUP_STATUS'
21
+ if (content.groupLabel) return 'GROUP_LABEL'
22
+ return null
23
+ }
24
+
25
+ async handlePayment(content, quoted) {
26
+ const data = content.requestPaymentMessage
27
+ let notes = {}
28
+
29
+ if (data.sticker?.stickerMessage) {
30
+ notes = {
31
+ stickerMessage: {
32
+ ...data.sticker.stickerMessage,
33
+ contextInfo: {
34
+ stanzaId: quoted?.key?.id,
35
+ participant: quoted?.key?.participant || content.sender,
36
+ quotedMessage: quoted?.message
37
+ }
38
+ }
39
+ }
40
+ } else if (data.note) {
41
+ notes = {
42
+ extendedTextMessage: {
43
+ text: data.note,
44
+ contextInfo: {
45
+ stanzaId: quoted?.key?.id,
46
+ participant: quoted?.key?.participant || content.sender,
47
+ quotedMessage: quoted?.message
48
+ }
49
+ }
50
+ }
51
+ }
52
+
53
+ return {
54
+ requestPaymentMessage: proto.Message.RequestPaymentMessage.fromObject({
55
+ expiryTimestamp: data.expiry || 0,
56
+ amount1000: data.amount || 0,
57
+ currencyCodeIso4217: data.currency || "IDR",
58
+ requestFrom: data.from || "0@s.whatsapp.net",
59
+ noteMessage: notes,
60
+ background: data.background?? {
61
+ id: "DEFAULT",
62
+ placeholderArgb: 0xFFF0F0F0
63
+ }
64
+ })
65
+ }
66
+ }
67
+
68
+ async handleProduct(content, jid, quoted) {
69
+ const {
70
+ title,
71
+ description,
72
+ thumbnail,
73
+ productId,
74
+ retailerId,
75
+ url,
76
+ body = "",
77
+ footer = "",
78
+ buttons = [],
79
+ priceAmount1000 = null,
80
+ currencyCode = "IDR"
81
+ } = content.productMessage
82
+
83
+ let productImage
84
+
85
+ if (Buffer.isBuffer(thumbnail)) {
86
+ const { imageMessage } = await this.utils.generateWAMessageContent(
87
+ { image: thumbnail },
88
+ { upload: this.waUploadToServer }
89
+ )
90
+ productImage = imageMessage
91
+ } else if (typeof thumbnail === 'object' && thumbnail.url) {
92
+ const { imageMessage } = await this.utils.generateWAMessageContent(
93
+ { image: { url: thumbnail.url } },
94
+ { upload: this.waUploadToServer }
95
+ )
96
+ productImage = imageMessage
97
+ }
98
+
99
+ return {
100
+ viewOnceMessage: {
101
+ message: {
102
+ interactiveMessage: {
103
+ body: { text: body },
104
+ footer: { text: footer },
105
+ header: {
106
+ title,
107
+ hasMediaAttachment: true,
108
+ productMessage: {
109
+ product: {
110
+ productImage,
111
+ productId,
112
+ title,
113
+ description,
114
+ currencyCode,
115
+ priceAmount1000,
116
+ retailerId,
117
+ url,
118
+ productImageCount: 1
119
+ },
120
+ businessOwnerJid: "0@s.whatsapp.net"
121
+ }
122
+ },
123
+ nativeFlowMessage: { buttons }
124
+ }
125
+ }
126
+ }
127
+ }
128
+ }
129
+
130
+ async handleAlbum(content, jid, quoted) {
131
+ const array = content.albumMessage
132
+ const album = await this.utils.generateWAMessageFromContent(jid, {
133
+ messageContextInfo: {
134
+ messageSecret: crypto.randomBytes(32),
135
+ },
136
+ albumMessage: {
137
+ expectedImageCount: array.filter((a) => a.hasOwnProperty("image")).length,
138
+ expectedVideoCount: array.filter((a) => a.hasOwnProperty("video")).length,
139
+ },
140
+ }, {
141
+ userJid: this.utils.generateMessageID().split('@')[0] + '@s.whatsapp.net',
142
+ quoted,
143
+ upload: this.waUploadToServer
144
+ })
145
+
146
+ await this.relayMessage(jid, album.message, {
147
+ messageId: album.key.id,
148
+ })
149
+
150
+ for (let content of array) {
151
+ const img = await this.utils.generateWAMessage(jid, content, {
152
+ upload: this.waUploadToServer,
153
+ })
154
+
155
+ img.message.messageContextInfo = {
156
+ messageSecret: crypto.randomBytes(32),
157
+ messageAssociation: {
158
+ associationType: 1,
159
+ parentMessageKey: album.key,
160
+ },
161
+ participant: "0@s.whatsapp.net",
162
+ remoteJid: "status@broadcast",
163
+ forwardingScore: 99999,
164
+ isForwarded: true,
165
+ mentionedJid: [jid],
166
+ starred: true,
167
+ labels: ["Y", "Important"],
168
+ isHighlighted: true,
169
+ businessMessageForwardInfo: {
170
+ businessOwnerJid: jid,
171
+ },
172
+ dataSharingContext: {
173
+ showMmDisclosure: true,
174
+ },
175
+ }
176
+
177
+ img.message.forwardedNewsletterMessageInfo = {
178
+ newsletterJid: "0@newsletter",
179
+ serverMessageId: 1,
180
+ newsletterName: `WhatsApp`,
181
+ timestamp: new Date().toISOString(),
182
+ senderName: "48-Edgar",
183
+ contentType: "UPDATE_CARD",
184
+ priority: "high",
185
+ status: "sent",
186
+ }
187
+
188
+ img.message.disappearingMode = {
189
+ initiator: 3,
190
+ trigger: 4,
191
+ initiatorDeviceJid: jid,
192
+ initiatedByExternalService: true,
193
+ initiatedByUserDevice: true,
194
+ initiatedBySystem: true,
195
+ initiatedByServer: true,
196
+ initiatedByAdmin: true,
197
+ initiatedByUser: true,
198
+ initiatedByApp: true,
199
+ initiatedByBot: true,
200
+ initiatedByMe: true,
201
+ }
202
+
203
+ await this.relayMessage(jid, img.message, {
204
+ messageId: img.key.id,
205
+ quoted: {
206
+ key: {
207
+ remoteJid: album.key.remoteJid,
208
+ id: album.key.id,
209
+ fromMe: true,
210
+ participant: this.utils.generateMessageID().split('@')[0] + '@s.whatsapp.net',
211
+ },
212
+ message: album.message,
213
+ },
214
+ })
215
+ }
216
+ return album
217
+ }
218
+
219
+ /**
220
+ * Levvleys-style album send.
221
+ * Usage: sock.sendMessage(jid, { album: [{ image }, { video }], caption: 'text' })
222
+ * Caption diauto assign ke item pertama kalau belum ada caption-nya sendiri.
223
+ */
224
+ async handleAlbumV2(content, jid, userJid, options = {}) {
225
+ const { album, caption } = content
226
+ if (!Array.isArray(album) || album.length === 0) {
227
+ throw new Error('album harus array dan tidak boleh kosong')
228
+ }
229
+ // caption top-level → otomatis masuk item pertama kalau belum ada
230
+ if (caption && !album[0].caption) {
231
+ album[0].caption = caption
232
+ }
233
+ let mediaHandle
234
+ // Kirim container albumMessage dulu
235
+ const albumMsg = this.utils.generateWAMessageFromContent(jid, {
236
+ albumMessage: {
237
+ expectedImageCount: album.filter(m => 'image' in m).length,
238
+ expectedVideoCount: album.filter(m => 'video' in m).length,
239
+ }
240
+ }, { userJid, ...options })
241
+ await this.relayMessage(jid, albumMsg.message, {
242
+ messageId: albumMsg.key.id
243
+ })
244
+ // Loop tiap media, generate + relay satu-satu
245
+ for (const media of album) {
246
+ let msgContent = {}
247
+ if ('image' in media) {
248
+ msgContent = {
249
+ image: media.image,
250
+ ...(media.caption ? { caption: media.caption } : {}),
251
+ }
252
+ } else if ('video' in media) {
253
+ msgContent = {
254
+ video: media.video,
255
+ ...(media.caption ? { caption: media.caption } : {}),
256
+ ...(media.gifPlayback !== undefined ? { gifPlayback: media.gifPlayback } : {}),
257
+ }
258
+ } else {
259
+ continue
260
+ }
261
+ const mediaMsg = await this.utils.generateWAMessage(jid, msgContent, {
262
+ userJid,
263
+ upload: async (readStream, opts) => {
264
+ const up = await this.waUploadToServer(readStream, {
265
+ ...opts,
266
+ newsletter: jid.endsWith('@newsletter')
267
+ })
268
+ mediaHandle = up.handle
269
+ return up
270
+ },
271
+ ...options
272
+ })
273
+ if (mediaMsg) {
274
+ mediaMsg.message.messageContextInfo = {
275
+ messageSecret: crypto.randomBytes(32),
276
+ messageAssociation: {
277
+ associationType: proto.MessageAssociation.AssociationType.MEDIA_ALBUM,
278
+ parentMessageKey: albumMsg.key
279
+ }
280
+ }
281
+ }
282
+ await this.relayMessage(jid, mediaMsg.message, {
283
+ messageId: mediaMsg.key.id,
284
+ ...(mediaHandle ? { additionalAttributes: { media_id: mediaHandle } } : {})
285
+ })
286
+ }
287
+ return albumMsg
288
+ }
289
+
290
+ async handleEvent(content, jid, quoted) {
291
+ const eventData = content.eventMessage
292
+
293
+ const msg = await this.utils.generateWAMessageFromContent(jid, {
294
+ viewOnceMessage: {
295
+ message: {
296
+ messageContextInfo: {
297
+ deviceListMetadata: {},
298
+ deviceListMetadataVersion: 2,
299
+ messageSecret: crypto.randomBytes(32),
300
+ supportPayload: JSON.stringify({
301
+ version: 2,
302
+ is_ai_message: true,
303
+ should_show_system_message: true,
304
+ ticket_id: crypto.randomBytes(16).toString('hex')
305
+ })
306
+ },
307
+ eventMessage: {
308
+ contextInfo: {
309
+ mentionedJid: [jid],
310
+ participant: jid,
311
+ remoteJid: "status@broadcast",
312
+ forwardedNewsletterMessageInfo: {
313
+ newsletterName: "Edgar",
314
+ newsletterJid: "120363421563597486@newsletter",
315
+ serverMessageId: 1
316
+ }
317
+ },
318
+ isCanceled: eventData.isCanceled || false,
319
+ name: eventData.name,
320
+ description: eventData.description,
321
+ location: eventData.location || {
322
+ degreesLatitude: 0,
323
+ degreesLongitude: 0,
324
+ name: "Location"
325
+ },
326
+ joinLink: eventData.joinLink || '',
327
+ startTime: typeof eventData.startTime === 'string'? parseInt(eventData.startTime) : eventData.startTime || Date.now(),
328
+ endTime: typeof eventData.endTime === 'string'? parseInt(eventData.endTime) : eventData.endTime || Date.now() + 3600000,
329
+ extraGuestsAllowed: eventData.extraGuestsAllowed!== false
330
+ }
331
+ }
332
+ }
333
+ }, { quoted })
334
+
335
+ await this.relayMessage(jid, msg.message, {
336
+ messageId: msg.key.id
337
+ })
338
+ return msg
339
+ }
340
+
341
+ async handlePollResult(content, jid, quoted) {
342
+ const pollData = content.pollResultMessage
343
+ const msg = await this.utils.generateWAMessageFromContent(jid, {
344
+ pollResultSnapshotMessage: {
345
+ name: pollData.name,
346
+ pollVotes: pollData.pollVotes.map(vote => ({
347
+ optionName: vote.optionName,
348
+ optionVoteCount: typeof vote.optionVoteCount === 'number'
349
+ ? vote.optionVoteCount.toString()
350
+ : vote.optionVoteCount
351
+ })),
352
+ contextInfo: {
353
+ isForwarded: true,
354
+ forwardingScore: 1,
355
+ forwardedNewsletterMessageInfo: {
356
+ newsletterName: pollData.newsletter?.newsletterName || "Newsletter",
357
+ newsletterJid: pollData.newsletter?.newsletterJid || "120363399602691477@newsletter",
358
+ serverMessageId: 1000,
359
+ contentType: "UPDATE"
360
+ }
361
+ }
362
+ }
363
+ }, {
364
+ userJid: this.utils.generateMessageID().split('@')[0] + '@s.whatsapp.net',
365
+ quoted
366
+ })
367
+
368
+ await this.relayMessage(jid, msg.message, {
369
+ messageId: msg.key.id
370
+ })
371
+
372
+ return msg
373
+ }
374
+
375
+ async handleOrderMessage(content, jid, quoted) {
376
+ const orderData = content.orderMessage
377
+
378
+ const Haha = await this.utils.generateWAMessageFromContent(jid, {
379
+ orderMessage: {
380
+ orderId: orderData.orderId || ("EDGAR" + Date.now()),
381
+ thumbnail: orderData.thumbnail || null,
382
+ itemCount: orderData.itemCount || 0,
383
+ status: "ACCEPTED",
384
+ surface: "CATALOG",
385
+ message: orderData.message,
386
+ orderTitle: orderData.orderTitle,
387
+ sellerJid: "0@whatsapp.net",
388
+ token: orderData.token || "EDGAR_EXAMPLE_TOKEN",
389
+ totalAmount1000: orderData.totalAmount1000 || 0,
390
+ totalCurrencyCode: orderData.totalCurrencyCode || "IDR",
391
+ messageVersion: 2
392
+ }
393
+ }, { quoted: quoted })
394
+
395
+ await this.relayMessage(jid, Haha.message, {
396
+ messageId: Haha.key.id
397
+ })
398
+ return Haha
399
+ }
400
+
401
+ async handleGroupStory(content, jid, quoted) {
402
+ const storyData = content.groupStatus
403
+ let messageContent
404
+
405
+ if (storyData.message) {
406
+ messageContent = storyData
407
+ } else {
408
+ if (typeof this.utils?.generateWAMessageContent === "function") {
409
+ messageContent = await this.utils.generateWAMessageContent(storyData, {
410
+ upload: this.waUploadToServer
411
+ })
412
+ } else {
413
+ messageContent = await Utils.generateWAMessageContent(storyData, {
414
+ upload: this.waUploadToServer
415
+ })
416
+ }
417
+ }
418
+
419
+ let msg = {
420
+ message: {
421
+ groupStatusMessageV2: {
422
+ message: messageContent.message || messageContent
423
+ }
424
+ }
425
+ }
426
+
427
+ return await this.relayMessage(jid, msg.message, {
428
+ messageId: this.utils.generateMessageID()
429
+ })
430
+ }
431
+
432
+ async handleGbLabel(content, jid) {
433
+ const x = content.groupLabel
434
+ if (!jid.endsWith('@g.us')) {
435
+ throw new Error('group required!')
436
+ }
437
+
438
+ const msg = await this.utils.generateWAMessageFromContent(jid, {
439
+ protocolMessage: {
440
+ type: proto.Message.ProtocolMessage.Type.GROUP_MEMBER_LABEL_CHANGE,
441
+ memberLabel: {
442
+ label: x.labelText.slice(0, 30)
443
+ }
444
+ }
445
+ }, {})
446
+
447
+ await this.relayMessage(jid, msg.message, {
448
+ additionalNodes: [
449
+ {
450
+ tag: 'meta',
451
+ attrs: {
452
+ tag_reason: 'user_update',
453
+ appdata: 'member_tag'
454
+ },
455
+ content: undefined
456
+ }
457
+ ]
458
+ })
459
+ }
460
+ }