@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.
- package/WAProto/GenerateStatics.sh +3 -0
- package/WAProto/WAProto.proto +8083 -0
- package/WAProto/fix-imports.js +85 -0
- package/WAProto/index.d.ts +29095 -0
- package/WAProto/index.js +172336 -0
- package/engine-requirements.js +10 -0
- package/lib/Defaults/index.js +194 -0
- package/lib/Signal/Group/ciphertext-message.js +12 -0
- package/lib/Signal/Group/group-session-builder.js +30 -0
- package/lib/Signal/Group/group_cipher.js +82 -0
- package/lib/Signal/Group/index.js +12 -0
- package/lib/Signal/Group/keyhelper.js +18 -0
- package/lib/Signal/Group/sender-chain-key.js +26 -0
- package/lib/Signal/Group/sender-key-distribution-message.js +63 -0
- package/lib/Signal/Group/sender-key-message.js +66 -0
- package/lib/Signal/Group/sender-key-name.js +48 -0
- package/lib/Signal/Group/sender-key-record.js +41 -0
- package/lib/Signal/Group/sender-key-state.js +84 -0
- package/lib/Signal/Group/sender-message-key.js +26 -0
- package/lib/Signal/libsignal.js +431 -0
- package/lib/Signal/lid-mapping.js +277 -0
- package/lib/Socket/Client/index.js +3 -0
- package/lib/Socket/Client/types.js +11 -0
- package/lib/Socket/Client/websocket.js +102 -0
- package/lib/Socket/aigroups.js +221 -0
- package/lib/Socket/business.js +379 -0
- package/lib/Socket/chats.js +1193 -0
- package/lib/Socket/communities.js +431 -0
- package/lib/Socket/graphql.js +524 -0
- package/lib/Socket/groups.js +408 -0
- package/lib/Socket/index.js +49 -0
- package/lib/Socket/interop.js +341 -0
- package/lib/Socket/luxu.js +510 -0
- package/lib/Socket/managed-account.js +99 -0
- package/lib/Socket/messages-recv.js +2009 -0
- package/lib/Socket/messages-send.js +1608 -0
- package/lib/Socket/mex.js +41 -0
- package/lib/Socket/newsletter.js +399 -0
- package/lib/Socket/privacy.js +128 -0
- package/lib/Socket/registration.js +238 -0
- package/lib/Socket/socket.js +1000 -0
- package/lib/Socket/text-router.js +67 -0
- package/lib/Socket/username.js +234 -0
- package/lib/Store/index.js +10 -0
- package/lib/Store/keyed-db.js +108 -0
- package/lib/Store/make-cache-manager-store.js +85 -0
- package/lib/Store/make-in-memory-store.js +198 -0
- package/lib/Store/make-ordered-dictionary.js +75 -0
- package/lib/Store/object-repository.js +32 -0
- package/lib/Types/Auth.js +2 -0
- package/lib/Types/Bussines.js +2 -0
- package/lib/Types/Call.js +2 -0
- package/lib/Types/Chat.js +8 -0
- package/lib/Types/Contact.js +2 -0
- package/lib/Types/Events.js +2 -0
- package/lib/Types/GroupMetadata.js +2 -0
- package/lib/Types/Label.js +25 -0
- package/lib/Types/LabelAssociation.js +7 -0
- package/lib/Types/Message.js +11 -0
- package/lib/Types/Mex.js +114 -0
- package/lib/Types/Product.js +2 -0
- package/lib/Types/Signal.js +2 -0
- package/lib/Types/Socket.js +3 -0
- package/lib/Types/State.js +56 -0
- package/lib/Types/USync.js +2 -0
- package/lib/Types/index.js +26 -0
- package/lib/Utils/adaptive-healing.js +53 -0
- package/lib/Utils/auth-utils.js +302 -0
- package/lib/Utils/browser-utils.js +50 -0
- package/lib/Utils/business.js +231 -0
- package/lib/Utils/chat-utils.js +872 -0
- package/lib/Utils/command-loader.js +108 -0
- package/lib/Utils/companion-reg-client-utils.js +35 -0
- package/lib/Utils/consumer-application.js +106 -0
- package/lib/Utils/crypto.js +137 -0
- package/lib/Utils/curve25519-js.js +262 -0
- package/lib/Utils/decode-wa-message.js +498 -0
- package/lib/Utils/event-buffer.js +622 -0
- package/lib/Utils/generics.js +403 -0
- package/lib/Utils/group-history.js +47 -0
- package/lib/Utils/history.js +134 -0
- package/lib/Utils/identity-change-handler.js +50 -0
- package/lib/Utils/index.js +38 -0
- package/lib/Utils/jid-display-normalization.js +198 -0
- package/lib/Utils/link-preview.js +85 -0
- package/lib/Utils/logger.js +3 -0
- package/lib/Utils/lt-hash.js +8 -0
- package/lib/Utils/make-mutex.js +33 -0
- package/lib/Utils/message-composer.js +273 -0
- package/lib/Utils/message-retry-manager.js +267 -0
- package/lib/Utils/messages-media.js +791 -0
- package/lib/Utils/messages.js +1260 -0
- package/lib/Utils/meta-ai-msmsg.js +271 -0
- package/lib/Utils/native-bridge.js +77 -0
- package/lib/Utils/noise-handler.js +201 -0
- package/lib/Utils/offline-node-processor.js +40 -0
- package/lib/Utils/optimizer.js +90 -0
- package/lib/Utils/pre-key-manager.js +106 -0
- package/lib/Utils/process-message.js +630 -0
- package/lib/Utils/reporting-utils.js +258 -0
- package/lib/Utils/session-pool.js +73 -0
- package/lib/Utils/signal.js +207 -0
- package/lib/Utils/stanza-ack.js +38 -0
- package/lib/Utils/sticker.js +139 -0
- package/lib/Utils/sync-action-utils.js +49 -0
- package/lib/Utils/tc-token-utils.js +163 -0
- package/lib/Utils/use-multi-file-auth-state.js +121 -0
- package/lib/Utils/use-sqlite-auth-state.js +168 -0
- package/lib/Utils/validate-connection.js +203 -0
- package/lib/Utils/view-once-cache.js +79 -0
- package/lib/Utils/voip-rekey.js +25 -0
- package/lib/Utils/warmup.js +117 -0
- package/lib/WABinary/constants.js +1301 -0
- package/lib/WABinary/decode.js +262 -0
- package/lib/WABinary/encode.js +220 -0
- package/lib/WABinary/generic-utils.js +204 -0
- package/lib/WABinary/index.js +6 -0
- package/lib/WABinary/jid-utils.js +98 -0
- package/lib/WABinary/types.js +2 -0
- package/lib/WAM/BinaryInfo.js +10 -0
- package/lib/WAM/constants.js +22853 -0
- package/lib/WAM/encode.js +150 -0
- package/lib/WAM/index.js +4 -0
- package/lib/WAUSync/Protocols/USyncBusinessProtocol.js +41 -0
- package/lib/WAUSync/Protocols/USyncContactProtocol.js +52 -0
- package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +54 -0
- package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +27 -0
- package/lib/WAUSync/Protocols/USyncFeatureProtocol.js +52 -0
- package/lib/WAUSync/Protocols/USyncPictureProtocol.js +31 -0
- package/lib/WAUSync/Protocols/USyncSidelistProtocol.js +26 -0
- package/lib/WAUSync/Protocols/USyncStatusProtocol.js +38 -0
- package/lib/WAUSync/Protocols/USyncTextStatusProtocol.js +35 -0
- package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +25 -0
- package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +51 -0
- package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +29 -0
- package/lib/WAUSync/Protocols/index.js +13 -0
- package/lib/WAUSync/USyncQuery.js +127 -0
- package/lib/WAUSync/USyncUser.js +31 -0
- package/lib/WAUSync/index.js +4 -0
- package/lib/antiban.js +4083 -0
- package/lib/index.js +24 -0
- 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
|
+
};
|