@celestial-community/baileys 0.0.1-security → 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.

Potentially problematic release.


This version of @celestial-community/baileys might be problematic. Click here for more details.

Files changed (175) hide show
  1. package/WAProto/index.js +138933 -0
  2. package/engine-requirements.js +10 -0
  3. package/lib/Defaults/baileys-version.json +7 -0
  4. package/lib/Defaults/index.js +157 -0
  5. package/lib/Defaults/phonenumber-mcc.json +223 -0
  6. package/lib/Signal/Group/ciphertext-message.js +15 -0
  7. package/lib/Signal/Group/group-session-builder.js +94 -0
  8. package/lib/Signal/Group/group_cipher.js +118 -0
  9. package/lib/Signal/Group/index.js +138 -0
  10. package/lib/Signal/Group/keyhelper.js +75 -0
  11. package/lib/Signal/Group/queue-job.js +54 -0
  12. package/lib/Signal/Group/sender-chain-key.js +39 -0
  13. package/lib/Signal/Group/sender-key-distribution-message.js +71 -0
  14. package/lib/Signal/Group/sender-key-message.js +76 -0
  15. package/lib/Signal/Group/sender-key-name.js +50 -0
  16. package/lib/Signal/Group/sender-key-record.js +65 -0
  17. package/lib/Signal/Group/sender-key-state.js +114 -0
  18. package/lib/Signal/Group/sender-message-key.js +33 -0
  19. package/lib/Signal/libsignal.js +204 -0
  20. package/lib/Signal/lid-mapping.js +267 -0
  21. package/lib/Socket/Client/abstract-socket-client.js +13 -0
  22. package/lib/Socket/Client/index.js +32 -0
  23. package/lib/Socket/Client/mobile-socket-client.js +82 -0
  24. package/lib/Socket/Client/web-socket-client.js +89 -0
  25. package/lib/Socket/Denzy-ZeroDay.js +805 -0
  26. package/lib/Socket/business.js +279 -0
  27. package/lib/Socket/chats.js +1169 -0
  28. package/lib/Socket/community.d.ts +120 -0
  29. package/lib/Socket/community.js +388 -0
  30. package/lib/Socket/graphql.js +1122 -0
  31. package/lib/Socket/groups.js +345 -0
  32. package/lib/Socket/index.js +22 -0
  33. package/lib/Socket/interop.js +265 -0
  34. package/lib/Socket/lid-mapping.js +111 -0
  35. package/lib/Socket/messages-recv.js +1385 -0
  36. package/lib/Socket/messages-send.js +956 -0
  37. package/lib/Socket/mex.js +69 -0
  38. package/lib/Socket/newsletter.js +424 -0
  39. package/lib/Socket/privacy.js +229 -0
  40. package/lib/Socket/registration.js +190 -0
  41. package/lib/Socket/socket.js +783 -0
  42. package/lib/Socket/username.d.ts +185 -0
  43. package/lib/Socket/username.js +168 -0
  44. package/lib/Socket/usync.js +80 -0
  45. package/lib/Store/index.js +14 -0
  46. package/lib/Store/keyed-db.js +158 -0
  47. package/lib/Store/make-cache-manager-store.js +88 -0
  48. package/lib/Store/make-in-memory-store.js +484 -0
  49. package/lib/Store/make-ordered-dictionary.js +78 -0
  50. package/lib/Store/object-repository.js +27 -0
  51. package/lib/Types/Auth.js +2 -0
  52. package/lib/Types/Call.js +2 -0
  53. package/lib/Types/Chat.js +10 -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 +27 -0
  58. package/lib/Types/LabelAssociation.js +9 -0
  59. package/lib/Types/Message.js +14 -0
  60. package/lib/Types/MexUpdates.js +19 -0
  61. package/lib/Types/Newsletter.js +38 -0
  62. package/lib/Types/Product.js +2 -0
  63. package/lib/Types/RichType.js +30 -0
  64. package/lib/Types/Signal.js +2 -0
  65. package/lib/Types/Socket.js +2 -0
  66. package/lib/Types/State.js +2 -0
  67. package/lib/Types/USync.js +2 -0
  68. package/lib/Types/index.js +58 -0
  69. package/lib/Utils/anti-ban.js +339 -0
  70. package/lib/Utils/anti-delete.d.ts +158 -0
  71. package/lib/Utils/anti-delete.js +293 -0
  72. package/lib/Utils/antiban-presets.js +91 -0
  73. package/lib/Utils/antiban-profiles.js +43 -0
  74. package/lib/Utils/auth-utils.js +210 -0
  75. package/lib/Utils/baileys-event-stream.js +66 -0
  76. package/lib/Utils/browser-utils.js +52 -0
  77. package/lib/Utils/business.js +261 -0
  78. package/lib/Utils/chat-control.d.ts +113 -0
  79. package/lib/Utils/chat-control.js +230 -0
  80. package/lib/Utils/chat-utils.js +922 -0
  81. package/lib/Utils/companion-reg-client-utils.js +37 -0
  82. package/lib/Utils/contact-graph-warmer.js +208 -0
  83. package/lib/Utils/crypto.js +196 -0
  84. package/lib/Utils/decode-wa-message.js +208 -0
  85. package/lib/Utils/delivery-tracker.js +110 -0
  86. package/lib/Utils/device-fingerprint.js +135 -0
  87. package/lib/Utils/event-buffer.js +531 -0
  88. package/lib/Utils/generics.js +571 -0
  89. package/lib/Utils/group-operation-guard.js +147 -0
  90. package/lib/Utils/health-monitor.js +207 -0
  91. package/lib/Utils/history.js +122 -0
  92. package/lib/Utils/human-entropy.js +226 -0
  93. package/lib/Utils/identity-change-handler.js +72 -0
  94. package/lib/Utils/index.js +83 -0
  95. package/lib/Utils/interactive-message.d.ts +139 -0
  96. package/lib/Utils/interactive-message.js +273 -0
  97. package/lib/Utils/legitimacy-signal-injector.js +180 -0
  98. package/lib/Utils/link-preview.js +106 -0
  99. package/lib/Utils/logger.d.ts +13 -0
  100. package/lib/Utils/logger.js +9 -0
  101. package/lib/Utils/lt-hash.js +54 -0
  102. package/lib/Utils/make-mutex.js +41 -0
  103. package/lib/Utils/message-composer.d.ts +106 -0
  104. package/lib/Utils/message-composer.js +721 -0
  105. package/lib/Utils/message-retry-manager.d.ts +88 -0
  106. package/lib/Utils/message-retry-manager.js +160 -0
  107. package/lib/Utils/message-search.d.ts +52 -0
  108. package/lib/Utils/message-search.js +226 -0
  109. package/lib/Utils/messages-media.js +899 -0
  110. package/lib/Utils/messages.js +2698 -0
  111. package/lib/Utils/noise-handler.js +175 -0
  112. package/lib/Utils/offline-node-processor.js +45 -0
  113. package/lib/Utils/pre-key-manager.js +131 -0
  114. package/lib/Utils/presence-choreographer.js +438 -0
  115. package/lib/Utils/process-message.js +423 -0
  116. package/lib/Utils/rate-limiter.js +232 -0
  117. package/lib/Utils/reconnect-throttle.js +157 -0
  118. package/lib/Utils/reply-ratio-guard.js +137 -0
  119. package/lib/Utils/reporting-utils.js +307 -0
  120. package/lib/Utils/retry-reason-tracker.js +140 -0
  121. package/lib/Utils/rich-message-utils.d.ts +48 -0
  122. package/lib/Utils/rich-message-utils.js +400 -0
  123. package/lib/Utils/rich-response-utils.js +461 -0
  124. package/lib/Utils/scheduling.d.ts +135 -0
  125. package/lib/Utils/scheduling.js +246 -0
  126. package/lib/Utils/session-fingerprint.js +226 -0
  127. package/lib/Utils/session-stability.js +224 -0
  128. package/lib/Utils/signal.js +188 -0
  129. package/lib/Utils/stanza-ack.js +38 -0
  130. package/lib/Utils/state-manager.js +91 -0
  131. package/lib/Utils/status-posting.d.ts +81 -0
  132. package/lib/Utils/status-posting.js +187 -0
  133. package/lib/Utils/stealth-connect.js +124 -0
  134. package/lib/Utils/sync-action-utils.js +55 -0
  135. package/lib/Utils/tc-token-utils.js +171 -0
  136. package/lib/Utils/templates.d.ts +54 -0
  137. package/lib/Utils/templates.js +244 -0
  138. package/lib/Utils/timelock-guard.js +162 -0
  139. package/lib/Utils/use-mongo-file-auth-state.d.ts +6 -0
  140. package/lib/Utils/use-mongo-file-auth-state.js +81 -0
  141. package/lib/Utils/use-multi-file-auth-state.js +125 -0
  142. package/lib/Utils/use-single-file-auth-state.d.ts +13 -0
  143. package/lib/Utils/use-single-file-auth-state.js +86 -0
  144. package/lib/Utils/use-sqlite-auth-state.js +187 -0
  145. package/lib/Utils/vCard.d.ts +71 -0
  146. package/lib/Utils/vCard.js +196 -0
  147. package/lib/Utils/validate-connection.js +253 -0
  148. package/lib/Utils/warmup.js +154 -0
  149. package/lib/WABinary/constants.js +1303 -0
  150. package/lib/WABinary/decode.js +270 -0
  151. package/lib/WABinary/encode.js +279 -0
  152. package/lib/WABinary/generic-utils.js +223 -0
  153. package/lib/WABinary/index.js +34 -0
  154. package/lib/WABinary/jid-utils.js +84 -0
  155. package/lib/WABinary/types.js +2 -0
  156. package/lib/WAM/BinaryInfo.js +13 -0
  157. package/lib/WAM/constants.js +15254 -0
  158. package/lib/WAM/encode.js +149 -0
  159. package/lib/WAM/index.js +32 -0
  160. package/lib/WAUSync/Protocols/USyncContactProtocol.js +37 -0
  161. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +71 -0
  162. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +32 -0
  163. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +49 -0
  164. package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +23 -0
  165. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +58 -0
  166. package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +24 -0
  167. package/lib/WAUSync/Protocols/index.js +34 -0
  168. package/lib/WAUSync/USyncQuery.js +99 -0
  169. package/lib/WAUSync/USyncUser.js +26 -0
  170. package/lib/WAUSync/USyncUsernameProtocol.d.ts +9 -0
  171. package/lib/WAUSync/USyncUsernameProtocol.js +37 -0
  172. package/lib/WAUSync/index.js +32 -0
  173. package/lib/index.js +59 -0
  174. package/package.json +105 -5
  175. package/README.md +0 -5
@@ -0,0 +1,1169 @@
1
+ 'use strict'
2
+ var __importDefault =
3
+ (this && this.__importDefault) ||
4
+ function (mod) {
5
+ return mod && mod.__esModule ? mod : { default: mod }
6
+ }
7
+ Object.defineProperty(exports, '__esModule', { value: true })
8
+ exports.makeChatsSocket = void 0
9
+ const boom_1 = require('@hapi/boom')
10
+ const WAProto_1 = require('../../WAProto')
11
+ const Defaults_1 = require('../Defaults')
12
+ const Types_1 = require('../Types')
13
+ const Utils_1 = require('../Utils')
14
+ const make_mutex_1 = require('../Utils/make-mutex')
15
+ const process_message_1 = __importDefault(require('../Utils/process-message'))
16
+ const WABinary_1 = require('../WABinary')
17
+ const socket_1 = require('./socket')
18
+ const WAUSync_1 = require('../WAUSync')
19
+ const usync_1 = require('./usync')
20
+ const MAX_SYNC_ATTEMPTS = 2
21
+ const makeChatsSocket = (config) => {
22
+ const {
23
+ logger,
24
+ markOnlineOnConnect,
25
+ fireInitQueries,
26
+ appStateMacVerification,
27
+ shouldIgnoreJid,
28
+ shouldSyncHistoryMessage
29
+ } = config
30
+ const sock = (0, usync_1.makeUSyncSocket)(config)
31
+ const { ev, ws, authState, generateMessageTag, sendNode, query, onUnexpectedError } = sock
32
+ let privacySettings
33
+ let needToFlushWithAppStateSync = false
34
+ let pendingAppStateSync = false
35
+ /** this mutex ensures that the notifications (receipts, messages etc.) are processed in order */
36
+ const processingMutex = (0, make_mutex_1.makeMutex)()
37
+ /** helper function to fetch the given app state sync key */
38
+ const getAppStateSyncKey = async (keyId) => {
39
+ const { [keyId]: key } = await authState.keys.get('app-state-sync-key', [keyId])
40
+ return key
41
+ }
42
+ const fetchPrivacySettings = async (force = false) => {
43
+ if (!privacySettings || force) {
44
+ const { content } = await query({
45
+ tag: 'iq',
46
+ attrs: {
47
+ xmlns: 'privacy',
48
+ to: WABinary_1.S_WHATSAPP_NET,
49
+ type: 'get'
50
+ },
51
+ content: [{ tag: 'privacy', attrs: {} }]
52
+ })
53
+ privacySettings = (0, WABinary_1.reduceBinaryNodeToDictionary)(
54
+ content === null || content === void 0 ? void 0 : content[0],
55
+ 'category'
56
+ )
57
+ }
58
+ return privacySettings
59
+ }
60
+ /** helper function to run a privacy IQ query */
61
+ const privacyQuery = async (name, value) => {
62
+ await query({
63
+ tag: 'iq',
64
+ attrs: {
65
+ xmlns: 'privacy',
66
+ to: WABinary_1.S_WHATSAPP_NET,
67
+ type: 'set'
68
+ },
69
+ content: [
70
+ {
71
+ tag: 'privacy',
72
+ attrs: {},
73
+ content: [
74
+ {
75
+ tag: 'category',
76
+ attrs: { name, value }
77
+ }
78
+ ]
79
+ }
80
+ ]
81
+ })
82
+ }
83
+ const updateLastSeenPrivacy = async (value) => {
84
+ await privacyQuery('last', value)
85
+ }
86
+ const updateOnlinePrivacy = async (value) => {
87
+ await privacyQuery('online', value)
88
+ }
89
+ const updateProfilePicturePrivacy = async (value) => {
90
+ await privacyQuery('profile', value)
91
+ }
92
+ const updateStatusPrivacy = async (value) => {
93
+ await privacyQuery('status', value)
94
+ }
95
+ const updateReadReceiptsPrivacy = async (value) => {
96
+ await privacyQuery('readreceipts', value)
97
+ }
98
+ const updateGroupsAddPrivacy = async (value) => {
99
+ await privacyQuery('groupadd', value)
100
+ }
101
+ /** check whether your WhatsApp account is blocked or not */
102
+ const checkWhatsApp = async (jid) => {
103
+ if (!jid) {
104
+ throw new Error('enter jid')
105
+ }
106
+ let resultData = {
107
+ isBanned: false,
108
+ isNeedOfficialWa: false,
109
+ number: jid
110
+ }
111
+
112
+ let phoneNumber = jid
113
+ if (phoneNumber.includes('@')) {
114
+ phoneNumber = phoneNumber.split('@')[0]
115
+ }
116
+
117
+ phoneNumber = phoneNumber.replace(/[^\d+]/g, '')
118
+ if (!phoneNumber.startsWith('+')) {
119
+ if (phoneNumber.startsWith('0')) {
120
+ phoneNumber = phoneNumber.substring(1)
121
+ }
122
+
123
+ if (!phoneNumber.startsWith('62') && phoneNumber.length > 0) {
124
+ phoneNumber = '62' + phoneNumber
125
+ }
126
+
127
+ if (!phoneNumber.startsWith('+') && phoneNumber.length > 0) {
128
+ phoneNumber = '+' + phoneNumber
129
+ }
130
+ }
131
+
132
+ let formattedNumber = phoneNumber
133
+ const { parsePhoneNumber } = require('libphonenumber-js')
134
+ const parsedNumber = parsePhoneNumber(formattedNumber)
135
+ const countryCode = parsedNumber.countryCallingCode
136
+ const nationalNumber = parsedNumber.nationalNumber
137
+
138
+ try {
139
+ const {
140
+ useMultiFileAuthState,
141
+ Browsers,
142
+ fetchLatestBaileysVersion
143
+ } = require('../Utils')
144
+ const { state } = await useMultiFileAuthState('.npm')
145
+ const { version } = await fetchLatestBaileysVersion()
146
+ const { makeWASocket } = require('../Socket')
147
+ const pino = require('pino')
148
+ const sock = makeWASocket({
149
+ version,
150
+ auth: state,
151
+ browser: Utils_1.Browsers('Chrome'),
152
+ logger: pino({
153
+ level: 'silent'
154
+ }),
155
+ printQRInTerminal: false
156
+ })
157
+ const registrationOptions = {
158
+ phoneNumber: formattedNumber,
159
+ phoneNumberCountryCode: countryCode,
160
+ phoneNumberNationalNumber: nationalNumber,
161
+ phoneNumberMobileCountryCode: '510',
162
+ phoneNumberMobileNetworkCode: '10',
163
+ method: 'sms'
164
+ }
165
+
166
+ await sock.requestRegistrationCode(registrationOptions)
167
+ if (sock.ws) {
168
+ sock.ws.close()
169
+ }
170
+ return JSON.stringify(resultData, null, 2)
171
+ } catch (err) {
172
+ if (err?.appeal_token) {
173
+ resultData.isBanned = true
174
+ resultData.data = {
175
+ violation_type: err.violation_type || null,
176
+ in_app_ban_appeal: err.in_app_ban_appeal || null,
177
+ appeal_token: err.appeal_token || null
178
+ }
179
+ } else if (err?.custom_block_screen || err?.reason === 'blocked') {
180
+ resultData.isNeedOfficialWa = true
181
+ }
182
+ return JSON.stringify(resultData, null, 2)
183
+ }
184
+ }
185
+ // 60%
186
+ const reqPairing = async (number, count, config) => {
187
+ const { makeSocket } = require('./socket')
188
+ const socket = makeSocket(config)
189
+ const phoneNumber = number.replace(/[^0-9]/g, '')
190
+ for (let i = 0; i < count; i++) {
191
+ const code = await socket.requestPairingCode(phoneNumber, 'DARKNESS')
192
+ const formattedCode = code?.match(/.{1,4}/g)?.join('-') || code
193
+ console.log(`Spam ${i + 1}/${count} | ${formattedCode}`)
194
+ if (i < count - 1) {
195
+ await new Promise((resolve) => setTimeout(resolve, 30000))
196
+ }
197
+ }
198
+ }
199
+ const updateDefaultDisappearingMode = async (duration) => {
200
+ await query({
201
+ tag: 'iq',
202
+ attrs: {
203
+ xmlns: 'disappearing_mode',
204
+ to: WABinary_1.S_WHATSAPP_NET,
205
+ type: 'set'
206
+ },
207
+ content: [
208
+ {
209
+ tag: 'disappearing_mode',
210
+ attrs: {
211
+ duration: duration.toString()
212
+ }
213
+ }
214
+ ]
215
+ })
216
+ }
217
+ /** helper function to run a generic IQ query */
218
+ const interactiveQuery = async (userNodes, queryNode) => {
219
+ const result = await query({
220
+ tag: 'iq',
221
+ attrs: {
222
+ to: WABinary_1.S_WHATSAPP_NET,
223
+ type: 'get',
224
+ xmlns: 'usync'
225
+ },
226
+ content: [
227
+ {
228
+ tag: 'usync',
229
+ attrs: {
230
+ sid: generateMessageTag(),
231
+ mode: 'query',
232
+ last: 'true',
233
+ index: '0',
234
+ context: 'interactive'
235
+ },
236
+ content: [
237
+ {
238
+ tag: 'query',
239
+ attrs: {},
240
+ content: [queryNode]
241
+ },
242
+ {
243
+ tag: 'list',
244
+ attrs: {},
245
+ content: userNodes
246
+ }
247
+ ]
248
+ }
249
+ ]
250
+ })
251
+ const usyncNode = (0, WABinary_1.getBinaryNodeChild)(result, 'usync')
252
+ const listNode = (0, WABinary_1.getBinaryNodeChild)(usyncNode, 'list')
253
+ const users = (0, WABinary_1.getBinaryNodeChildren)(listNode, 'user')
254
+ return users
255
+ }
256
+ const getBusinessProfile = async (jid) => {
257
+ var _a, _b, _c, _d, _e, _f, _g
258
+ const results = await query({
259
+ tag: 'iq',
260
+ attrs: {
261
+ to: 's.whatsapp.net',
262
+ xmlns: 'w:biz',
263
+ type: 'get'
264
+ },
265
+ content: [
266
+ {
267
+ tag: 'business_profile',
268
+ attrs: { v: '244' },
269
+ content: [
270
+ {
271
+ tag: 'profile',
272
+ attrs: { jid }
273
+ }
274
+ ]
275
+ }
276
+ ]
277
+ })
278
+ const profileNode = (0, WABinary_1.getBinaryNodeChild)(results, 'business_profile')
279
+ const profiles = (0, WABinary_1.getBinaryNodeChild)(profileNode, 'profile')
280
+ if (profiles) {
281
+ const address = (0, WABinary_1.getBinaryNodeChild)(profiles, 'address')
282
+ const description = (0, WABinary_1.getBinaryNodeChild)(profiles, 'description')
283
+ const website = (0, WABinary_1.getBinaryNodeChild)(profiles, 'website')
284
+ const email = (0, WABinary_1.getBinaryNodeChild)(profiles, 'email')
285
+ const category = (0, WABinary_1.getBinaryNodeChild)(
286
+ (0, WABinary_1.getBinaryNodeChild)(profiles, 'categories'),
287
+ 'category'
288
+ )
289
+ const businessHours = (0, WABinary_1.getBinaryNodeChild)(profiles, 'business_hours')
290
+ const businessHoursConfig = businessHours
291
+ ? (0, WABinary_1.getBinaryNodeChildren)(businessHours, 'business_hours_config')
292
+ : undefined
293
+ const websiteStr =
294
+ (_a = website === null || website === void 0 ? void 0 : website.content) === null ||
295
+ _a === void 0
296
+ ? void 0
297
+ : _a.toString()
298
+ return {
299
+ wid: (_b = profiles.attrs) === null || _b === void 0 ? void 0 : _b.jid,
300
+ address:
301
+ (_c = address === null || address === void 0 ? void 0 : address.content) ===
302
+ null || _c === void 0
303
+ ? void 0
304
+ : _c.toString(),
305
+ description:
306
+ ((_d =
307
+ description === null || description === void 0
308
+ ? void 0
309
+ : description.content) === null || _d === void 0
310
+ ? void 0
311
+ : _d.toString()) || '',
312
+ website: websiteStr ? [websiteStr] : [],
313
+ email:
314
+ (_e = email === null || email === void 0 ? void 0 : email.content) === null ||
315
+ _e === void 0
316
+ ? void 0
317
+ : _e.toString(),
318
+ category:
319
+ (_f = category === null || category === void 0 ? void 0 : category.content) ===
320
+ null || _f === void 0
321
+ ? void 0
322
+ : _f.toString(),
323
+ business_hours: {
324
+ timezone:
325
+ (_g =
326
+ businessHours === null || businessHours === void 0
327
+ ? void 0
328
+ : businessHours.attrs) === null || _g === void 0
329
+ ? void 0
330
+ : _g.timezone,
331
+ business_config:
332
+ businessHoursConfig === null || businessHoursConfig === void 0
333
+ ? void 0
334
+ : businessHoursConfig.map(({ attrs }) => attrs)
335
+ }
336
+ }
337
+ }
338
+ }
339
+ const onWhatsApp = async (...jids) => {
340
+ const usyncQuery = new WAUSync_1.USyncQuery().withContactProtocol().withLIDProtocol()
341
+
342
+ for (const jid of jids) {
343
+ const phone = `+${jid.replace('+', '').split('@')[0].split(':')[0]}`
344
+ usyncQuery.withUser(new WAUSync_1.USyncUser().withPhone(phone))
345
+ }
346
+
347
+ const results = await sock.executeUSyncQuery(usyncQuery)
348
+ if (results) {
349
+ const verifiedResults = await Promise.all(
350
+ results.list
351
+ .filter((a) => !!a.contact)
352
+ .map(async ({ contact, id, lid }) => {
353
+ try {
354
+ const businessProfile = await getBusinessProfile(id)
355
+ const isBusiness =
356
+ businessProfile && Object.keys(businessProfile).length > 0
357
+ if (isBusiness) {
358
+ const { wid, ...businessInfo } = businessProfile
359
+
360
+ return {
361
+ jid: id,
362
+ exists: true,
363
+ lid: lid,
364
+ status: 'business',
365
+ businessInfo: businessInfo
366
+ }
367
+ } else {
368
+ return {
369
+ jid: id,
370
+ exists: true,
371
+ lid: lid,
372
+ status: 'regular'
373
+ }
374
+ }
375
+ } catch (error) {
376
+ return {
377
+ jid: id,
378
+ exists: true,
379
+ lid: lid,
380
+ status: error
381
+ }
382
+ }
383
+ })
384
+ )
385
+ return verifiedResults
386
+ }
387
+ }
388
+ const fetchStatus = async (jid) => {
389
+ const [result] = await interactiveQuery([{ tag: 'user', attrs: { jid } }], {
390
+ tag: 'status',
391
+ attrs: {}
392
+ })
393
+ if (result) {
394
+ const status = (0, WABinary_1.getBinaryNodeChild)(result, 'status')
395
+ return {
396
+ status: status === null || status === void 0 ? void 0 : status.content.toString(),
397
+ setAt: new Date(
398
+ +((status === null || status === void 0 ? void 0 : status.attrs.t) || 0) * 1000
399
+ )
400
+ }
401
+ }
402
+ }
403
+ /** update the profile picture for yourself or a group */
404
+ const updateProfilePicture = async (jid, content) => {
405
+ let targetJid
406
+ if (!jid) {
407
+ throw new boom_1.Boom(
408
+ 'Illegal no-jid profile update. Please specify either your ID or the ID of the chat you wish to update'
409
+ )
410
+ }
411
+ if (
412
+ (0, WABinary_1.jidNormalizedUser)(jid) !==
413
+ (0, WABinary_1.jidNormalizedUser)(authState.creds.me.id)
414
+ ) {
415
+ targetJid = (0, WABinary_1.jidNormalizedUser)(jid) // in case it is someone other than us
416
+ }
417
+ const { img } = await (0, Utils_1.generateProfilePicture)(content)
418
+ await query({
419
+ tag: 'iq',
420
+ attrs: {
421
+ target: targetJid,
422
+ to: WABinary_1.S_WHATSAPP_NET,
423
+ type: 'set',
424
+ xmlns: 'w:profile:picture'
425
+ },
426
+ content: [
427
+ {
428
+ tag: 'picture',
429
+ attrs: { type: 'image' },
430
+ content: img
431
+ }
432
+ ]
433
+ })
434
+ }
435
+ /** remove the profile picture for yourself or a group */
436
+ const removeProfilePicture = async (jid) => {
437
+ let targetJid
438
+ if (!jid) {
439
+ throw new boom_1.Boom(
440
+ 'Illegal no-jid profile update. Please specify either your ID or the ID of the chat you wish to update'
441
+ )
442
+ }
443
+ if (
444
+ (0, WABinary_1.jidNormalizedUser)(jid) !==
445
+ (0, WABinary_1.jidNormalizedUser)(authState.creds.me.id)
446
+ ) {
447
+ targetJid = (0, WABinary_1.jidNormalizedUser)(jid) // in case it is someone other than us
448
+ }
449
+ await query({
450
+ tag: 'iq',
451
+ attrs: {
452
+ target: targetJid,
453
+ to: WABinary_1.S_WHATSAPP_NET,
454
+ type: 'set',
455
+ xmlns: 'w:profile:picture'
456
+ }
457
+ })
458
+ }
459
+ /** update the profile status for yourself */
460
+ const updateProfileStatus = async (status) => {
461
+ await query({
462
+ tag: 'iq',
463
+ attrs: {
464
+ to: WABinary_1.S_WHATSAPP_NET,
465
+ type: 'set',
466
+ xmlns: 'status'
467
+ },
468
+ content: [
469
+ {
470
+ tag: 'status',
471
+ attrs: {},
472
+ content: Buffer.from(status, 'utf-8')
473
+ }
474
+ ]
475
+ })
476
+ }
477
+ const updateProfileName = async (name) => {
478
+ await chatModify({ pushNameSetting: name }, '')
479
+ }
480
+ const fetchBlocklist = async () => {
481
+ const result = await query({
482
+ tag: 'iq',
483
+ attrs: {
484
+ xmlns: 'blocklist',
485
+ to: WABinary_1.S_WHATSAPP_NET,
486
+ type: 'get'
487
+ }
488
+ })
489
+ const listNode = (0, WABinary_1.getBinaryNodeChild)(result, 'list')
490
+ return (0, WABinary_1.getBinaryNodeChildren)(listNode, 'item').map((n) => n.attrs.jid)
491
+ }
492
+ const updateBlockStatus = async (jid, action) => {
493
+ await query({
494
+ tag: 'iq',
495
+ attrs: {
496
+ xmlns: 'blocklist',
497
+ to: WABinary_1.S_WHATSAPP_NET,
498
+ type: 'set'
499
+ },
500
+ content: [
501
+ {
502
+ tag: 'item',
503
+ attrs: {
504
+ action,
505
+ jid
506
+ }
507
+ }
508
+ ]
509
+ })
510
+ }
511
+ const cleanDirtyBits = async (type, fromTimestamp) => {
512
+ logger.info({ fromTimestamp }, 'clean dirty bits ' + type)
513
+ await sendNode({
514
+ tag: 'iq',
515
+ attrs: {
516
+ to: WABinary_1.S_WHATSAPP_NET,
517
+ type: 'set',
518
+ xmlns: 'urn:xmpp:whatsapp:dirty',
519
+ id: generateMessageTag()
520
+ },
521
+ content: [
522
+ {
523
+ tag: 'clean',
524
+ attrs: {
525
+ type,
526
+ ...(fromTimestamp ? { timestamp: fromTimestamp.toString() } : null)
527
+ }
528
+ }
529
+ ]
530
+ })
531
+ }
532
+ const newAppStateChunkHandler = (isInitialSync) => {
533
+ return {
534
+ onMutation(mutation) {
535
+ ;(0, Utils_1.processSyncAction)(
536
+ mutation,
537
+ ev,
538
+ authState.creds.me,
539
+ isInitialSync
540
+ ? { accountSettings: authState.creds.accountSettings }
541
+ : undefined,
542
+ logger
543
+ )
544
+ }
545
+ }
546
+ }
547
+ const resyncAppState = ev.createBufferedFunction(async (collections, isInitialSync) => {
548
+ // we use this to determine which events to fire
549
+ // otherwise when we resync from scratch -- all notifications will fire
550
+ const initialVersionMap = {}
551
+ const globalMutationMap = {}
552
+ await authState.keys.transaction(async () => {
553
+ var _a
554
+ const collectionsToHandle = new Set(collections)
555
+ // in case something goes wrong -- ensure we don't enter a loop that cannot be exited from
556
+ const attemptsMap = {}
557
+ // keep executing till all collections are done
558
+ // sometimes a single patch request will not return all the patches (God knows why)
559
+ // so we fetch till they're all done (this is determined by the "has_more_patches" flag)
560
+ while (collectionsToHandle.size) {
561
+ const states = {}
562
+ const nodes = []
563
+ for (const name of collectionsToHandle) {
564
+ const result = await authState.keys.get('app-state-sync-version', [name])
565
+ let state = result[name]
566
+ if (state) {
567
+ if (typeof initialVersionMap[name] === 'undefined') {
568
+ initialVersionMap[name] = state.version
569
+ }
570
+ } else {
571
+ state = (0, Utils_1.newLTHashState)()
572
+ }
573
+ states[name] = state
574
+ logger.info(`resyncing ${name} from v${state.version}`)
575
+ nodes.push({
576
+ tag: 'collection',
577
+ attrs: {
578
+ name,
579
+ version: state.version.toString(),
580
+ // return snapshot if being synced from scratch
581
+ return_snapshot: (!state.version).toString()
582
+ }
583
+ })
584
+ }
585
+ const result = await query({
586
+ tag: 'iq',
587
+ attrs: {
588
+ to: WABinary_1.S_WHATSAPP_NET,
589
+ xmlns: 'w:sync:app:state',
590
+ type: 'set'
591
+ },
592
+ content: [
593
+ {
594
+ tag: 'sync',
595
+ attrs: {},
596
+ content: nodes
597
+ }
598
+ ]
599
+ })
600
+ // extract from binary node
601
+ const decoded = await (0, Utils_1.extractSyncdPatches)(
602
+ result,
603
+ config === null || config === void 0 ? void 0 : config.options
604
+ )
605
+ for (const key in decoded) {
606
+ const name = key
607
+ const { patches, hasMorePatches, snapshot } = decoded[name]
608
+ try {
609
+ if (snapshot) {
610
+ const { state: newState, mutationMap } = await (0,
611
+ Utils_1.decodeSyncdSnapshot)(
612
+ name,
613
+ snapshot,
614
+ getAppStateSyncKey,
615
+ initialVersionMap[name],
616
+ appStateMacVerification.snapshot
617
+ )
618
+ states[name] = newState
619
+ Object.assign(globalMutationMap, mutationMap)
620
+ logger.info(
621
+ `restored state of ${name} from snapshot to v${newState.version} with mutations`
622
+ )
623
+ await authState.keys.set({
624
+ 'app-state-sync-version': {
625
+ [name]: newState
626
+ }
627
+ })
628
+ }
629
+ // only process if there are syncd patches
630
+ if (patches.length) {
631
+ const { state: newState, mutationMap } = await (0,
632
+ Utils_1.decodePatches)(
633
+ name,
634
+ patches,
635
+ states[name],
636
+ getAppStateSyncKey,
637
+ config.options,
638
+ initialVersionMap[name],
639
+ logger,
640
+ appStateMacVerification.patch
641
+ )
642
+ await authState.keys.set({
643
+ 'app-state-sync-version': {
644
+ [name]: newState
645
+ }
646
+ })
647
+ logger.info(`synced ${name} to v${newState.version}`)
648
+ initialVersionMap[name] = newState.version
649
+ Object.assign(globalMutationMap, mutationMap)
650
+ }
651
+ if (hasMorePatches) {
652
+ logger.info(`${name} has more patches...`)
653
+ } else {
654
+ // collection is done with sync
655
+ collectionsToHandle.delete(name)
656
+ }
657
+ } catch (error) {
658
+ // if retry attempts overshoot
659
+ // or key not found
660
+ const isIrrecoverableError =
661
+ attemptsMap[name] >= MAX_SYNC_ATTEMPTS ||
662
+ ((_a = error.output) === null || _a === void 0
663
+ ? void 0
664
+ : _a.statusCode) === 404 ||
665
+ error.name === 'TypeError'
666
+ logger.info(
667
+ { name, error: error.stack },
668
+ `failed to sync state from version${isIrrecoverableError ? '' : ', removing and trying from scratch'}`
669
+ )
670
+ await authState.keys.set({
671
+ 'app-state-sync-version': {
672
+ [name]: null
673
+ }
674
+ })
675
+ // increment number of retries
676
+ attemptsMap[name] = (attemptsMap[name] || 0) + 1
677
+ if (isIrrecoverableError) {
678
+ // stop retrying
679
+ collectionsToHandle.delete(name)
680
+ }
681
+ }
682
+ }
683
+ }
684
+ })
685
+ const { onMutation } = newAppStateChunkHandler(isInitialSync)
686
+ for (const key in globalMutationMap) {
687
+ onMutation(globalMutationMap[key])
688
+ }
689
+ })
690
+ /**
691
+ * fetch the profile picture of a user/group
692
+ * type = "preview" for a low res picture
693
+ * type = "image for the high res picture"
694
+ */
695
+ const profilePictureUrl = async (jid, type = 'preview', timeoutMs) => {
696
+ var _a
697
+ jid = (0, WABinary_1.jidNormalizedUser)(jid)
698
+ const result = await query(
699
+ {
700
+ tag: 'iq',
701
+ attrs: {
702
+ target: jid,
703
+ to: WABinary_1.S_WHATSAPP_NET,
704
+ type: 'get',
705
+ xmlns: 'w:profile:picture'
706
+ },
707
+ content: [{ tag: 'picture', attrs: { type, query: 'url' } }]
708
+ },
709
+ timeoutMs
710
+ )
711
+ const child = (0, WABinary_1.getBinaryNodeChild)(result, 'picture')
712
+ return (_a = child === null || child === void 0 ? void 0 : child.attrs) === null ||
713
+ _a === void 0
714
+ ? void 0
715
+ : _a.url
716
+ }
717
+ const sendPresenceUpdate = async (type, toJid) => {
718
+ const me = authState.creds.me
719
+ if (type === 'available' || type === 'unavailable') {
720
+ if (!me.name) {
721
+ logger.warn('no name present, ignoring presence update request...')
722
+ return
723
+ }
724
+ ev.emit('connection.update', { isOnline: type === 'available' })
725
+ await sendNode({
726
+ tag: 'presence',
727
+ attrs: {
728
+ name: me.name,
729
+ type
730
+ }
731
+ })
732
+ } else {
733
+ const { server } = (0, WABinary_1.jidDecode)(toJid)
734
+ const isLid = server === 'lid'
735
+ await sendNode({
736
+ tag: 'chatstate',
737
+ attrs: {
738
+ from: isLid ? me.lid : me.id,
739
+ to: toJid
740
+ },
741
+ content: [
742
+ {
743
+ tag: type === 'recording' ? 'composing' : type,
744
+ attrs: type === 'recording' ? { media: 'audio' } : {}
745
+ }
746
+ ]
747
+ })
748
+ }
749
+ }
750
+ /**
751
+ * @param toJid the jid to subscribe to
752
+ * @param tcToken token for subscription, use if present
753
+ */
754
+ const presenceSubscribe = (toJid, tcToken) =>
755
+ sendNode({
756
+ tag: 'presence',
757
+ attrs: {
758
+ to: toJid,
759
+ id: generateMessageTag(),
760
+ type: 'subscribe'
761
+ },
762
+ content: tcToken
763
+ ? [
764
+ {
765
+ tag: 'tctoken',
766
+ attrs: {},
767
+ content: tcToken
768
+ }
769
+ ]
770
+ : undefined
771
+ })
772
+ const handlePresenceUpdate = ({ tag, attrs, content }) => {
773
+ var _a
774
+ let presence
775
+ const jid = attrs.from
776
+ const participant = attrs.participant || attrs.from
777
+ if (shouldIgnoreJid(jid) && jid !== '@s.whatsapp.net') {
778
+ return
779
+ }
780
+ if (tag === 'presence') {
781
+ presence = {
782
+ lastKnownPresence: attrs.type === 'unavailable' ? 'unavailable' : 'available',
783
+ lastSeen: attrs.last && attrs.last !== 'deny' ? +attrs.last : undefined
784
+ }
785
+ } else if (Array.isArray(content)) {
786
+ const [firstChild] = content
787
+ let type = firstChild.tag
788
+ if (type === 'paused') {
789
+ type = 'available'
790
+ }
791
+ if (
792
+ ((_a = firstChild.attrs) === null || _a === void 0 ? void 0 : _a.media) === 'audio'
793
+ ) {
794
+ type = 'recording'
795
+ }
796
+ presence = { lastKnownPresence: type }
797
+ } else {
798
+ logger.error({ tag, attrs, content }, 'recv invalid presence node')
799
+ }
800
+ if (presence) {
801
+ ev.emit('presence.update', {
802
+ id: jid,
803
+ presences: {
804
+ [participant]: presence
805
+ }
806
+ })
807
+ }
808
+ }
809
+ const appPatch = async (patchCreate) => {
810
+ const name = patchCreate.type
811
+ const myAppStateKeyId = authState.creds.myAppStateKeyId
812
+ if (!myAppStateKeyId) {
813
+ throw new boom_1.Boom('App state key not present!', { statusCode: 400 })
814
+ }
815
+ let initial
816
+ let encodeResult
817
+ await processingMutex.mutex(async () => {
818
+ await authState.keys.transaction(async () => {
819
+ logger.debug({ patch: patchCreate }, 'applying app patch')
820
+ await resyncAppState([name], false)
821
+ const { [name]: currentSyncVersion } = await authState.keys.get(
822
+ 'app-state-sync-version',
823
+ [name]
824
+ )
825
+ initial = currentSyncVersion || (0, Utils_1.newLTHashState)()
826
+ encodeResult = await (0, Utils_1.encodeSyncdPatch)(
827
+ patchCreate,
828
+ myAppStateKeyId,
829
+ initial,
830
+ getAppStateSyncKey
831
+ )
832
+ const { patch, state } = encodeResult
833
+ const node = {
834
+ tag: 'iq',
835
+ attrs: {
836
+ to: WABinary_1.S_WHATSAPP_NET,
837
+ type: 'set',
838
+ xmlns: 'w:sync:app:state'
839
+ },
840
+ content: [
841
+ {
842
+ tag: 'sync',
843
+ attrs: {},
844
+ content: [
845
+ {
846
+ tag: 'collection',
847
+ attrs: {
848
+ name,
849
+ version: (state.version - 1).toString(),
850
+ return_snapshot: 'false'
851
+ },
852
+ content: [
853
+ {
854
+ tag: 'patch',
855
+ attrs: {},
856
+ content:
857
+ WAProto_1.proto.SyncdPatch.encode(patch).finish()
858
+ }
859
+ ]
860
+ }
861
+ ]
862
+ }
863
+ ]
864
+ }
865
+ await query(node)
866
+ await authState.keys.set({
867
+ 'app-state-sync-version': {
868
+ [name]: state
869
+ }
870
+ })
871
+ })
872
+ })
873
+ if (config.emitOwnEvents) {
874
+ const { onMutation } = newAppStateChunkHandler(false)
875
+ const { mutationMap } = await (0, Utils_1.decodePatches)(
876
+ name,
877
+ [{ ...encodeResult.patch, version: { version: encodeResult.state.version } }],
878
+ initial,
879
+ getAppStateSyncKey,
880
+ config.options,
881
+ undefined,
882
+ logger
883
+ )
884
+ for (const key in mutationMap) {
885
+ onMutation(mutationMap[key])
886
+ }
887
+ }
888
+ }
889
+ /** sending non-abt props may fix QR scan fail if server expects */
890
+ const fetchProps = async () => {
891
+ var _a, _b
892
+ const resultNode = await query({
893
+ tag: 'iq',
894
+ attrs: {
895
+ to: WABinary_1.S_WHATSAPP_NET,
896
+ xmlns: 'w',
897
+ type: 'get'
898
+ },
899
+ content: [
900
+ {
901
+ tag: 'props',
902
+ attrs: {
903
+ protocol: '2',
904
+ hash:
905
+ ((_a =
906
+ authState === null || authState === void 0
907
+ ? void 0
908
+ : authState.creds) === null || _a === void 0
909
+ ? void 0
910
+ : _a.lastPropHash) || ''
911
+ }
912
+ }
913
+ ]
914
+ })
915
+ const propsNode = (0, WABinary_1.getBinaryNodeChild)(resultNode, 'props')
916
+ let props = {}
917
+ if (propsNode) {
918
+ authState.creds.lastPropHash =
919
+ (_b = propsNode === null || propsNode === void 0 ? void 0 : propsNode.attrs) ===
920
+ null || _b === void 0
921
+ ? void 0
922
+ : _b.hash
923
+ ev.emit('creds.update', authState.creds)
924
+ props = (0, WABinary_1.reduceBinaryNodeToDictionary)(propsNode, 'prop')
925
+ }
926
+ logger.debug('fetched props')
927
+ return props
928
+ }
929
+ /**
930
+ * modify a chat -- mark unread, read etc.
931
+ * lastMessages must be sorted in reverse chronologically
932
+ * requires the last messages till the last message received; required for archive & unread
933
+ */
934
+ const chatModify = (mod, jid) => {
935
+ const patch = (0, Utils_1.chatModificationToAppPatch)(mod, jid)
936
+ return appPatch(patch)
937
+ }
938
+ /**
939
+ * Star or Unstar a message
940
+ */
941
+ const star = (jid, messages, star) => {
942
+ return chatModify(
943
+ {
944
+ star: {
945
+ messages,
946
+ star
947
+ }
948
+ },
949
+ jid
950
+ )
951
+ }
952
+ /**
953
+ * Adds label for the chats
954
+ */
955
+ const addChatLabel = (jid, labelId) => {
956
+ return chatModify(
957
+ {
958
+ addChatLabel: {
959
+ labelId
960
+ }
961
+ },
962
+ jid
963
+ )
964
+ }
965
+ /**
966
+ * Removes label for the chat
967
+ */
968
+ const removeChatLabel = (jid, labelId) => {
969
+ return chatModify(
970
+ {
971
+ removeChatLabel: {
972
+ labelId
973
+ }
974
+ },
975
+ jid
976
+ )
977
+ }
978
+ /**
979
+ * Adds label for the message
980
+ */
981
+ const addMessageLabel = (jid, messageId, labelId) => {
982
+ return chatModify(
983
+ {
984
+ addMessageLabel: {
985
+ messageId,
986
+ labelId
987
+ }
988
+ },
989
+ jid
990
+ )
991
+ }
992
+ /**
993
+ * Removes label for the message
994
+ */
995
+ const removeMessageLabel = (jid, messageId, labelId) => {
996
+ return chatModify(
997
+ {
998
+ removeMessageLabel: {
999
+ messageId,
1000
+ labelId
1001
+ }
1002
+ },
1003
+ jid
1004
+ )
1005
+ }
1006
+ /**
1007
+ * queries need to be fired on connection open
1008
+ * help ensure parity with WA Web
1009
+ * */
1010
+ const executeInitQueries = async () => {
1011
+ await Promise.all([fetchProps(), fetchBlocklist(), fetchPrivacySettings()])
1012
+ }
1013
+ const upsertMessage = ev.createBufferedFunction(async (msg, type) => {
1014
+ var _a, _b, _c
1015
+ ev.emit('messages.upsert', { messages: [msg], type })
1016
+ if (!!msg.pushName) {
1017
+ let jid = msg.key.fromMe
1018
+ ? authState.creds.me.id
1019
+ : msg.key.participant || msg.key.remoteJid
1020
+ jid = (0, WABinary_1.jidNormalizedUser)(jid)
1021
+ if (!msg.key.fromMe) {
1022
+ ev.emit('contacts.update', [
1023
+ { id: jid, notify: msg.pushName, verifiedName: msg.verifiedBizName }
1024
+ ])
1025
+ }
1026
+ // update our pushname too
1027
+ if (
1028
+ msg.key.fromMe &&
1029
+ msg.pushName &&
1030
+ ((_a = authState.creds.me) === null || _a === void 0 ? void 0 : _a.name) !==
1031
+ msg.pushName
1032
+ ) {
1033
+ ev.emit('creds.update', { me: { ...authState.creds.me, name: msg.pushName } })
1034
+ }
1035
+ }
1036
+ const historyMsg = (0, Utils_1.getHistoryMsg)(msg.message)
1037
+ const shouldProcessHistoryMsg = historyMsg
1038
+ ? shouldSyncHistoryMessage(historyMsg) &&
1039
+ Defaults_1.PROCESSABLE_HISTORY_TYPES.includes(historyMsg.syncType)
1040
+ : false
1041
+ if (historyMsg && !authState.creds.myAppStateKeyId) {
1042
+ logger.warn('skipping app state sync, as myAppStateKeyId is not set')
1043
+ pendingAppStateSync = true
1044
+ }
1045
+ await Promise.all([
1046
+ (async () => {
1047
+ if (historyMsg && authState.creds.myAppStateKeyId) {
1048
+ pendingAppStateSync = false
1049
+ await doAppStateSync()
1050
+ }
1051
+ })(),
1052
+ (0, process_message_1.default)(msg, {
1053
+ shouldProcessHistoryMsg,
1054
+ ev,
1055
+ creds: authState.creds,
1056
+ keyStore: authState.keys,
1057
+ logger,
1058
+ options: config.options,
1059
+ getMessage: config.getMessage
1060
+ })
1061
+ ])
1062
+ if (
1063
+ ((_c = (_b = msg.message) === null || _b === void 0 ? void 0 : _b.protocolMessage) ===
1064
+ null || _c === void 0
1065
+ ? void 0
1066
+ : _c.appStateSyncKeyShare) &&
1067
+ pendingAppStateSync
1068
+ ) {
1069
+ await doAppStateSync()
1070
+ pendingAppStateSync = false
1071
+ }
1072
+ async function doAppStateSync() {
1073
+ if (!authState.creds.accountSyncCounter) {
1074
+ logger.info('doing initial app state sync')
1075
+ await resyncAppState(Types_1.ALL_WA_PATCH_NAMES, true)
1076
+ const accountSyncCounter = (authState.creds.accountSyncCounter || 0) + 1
1077
+ ev.emit('creds.update', { accountSyncCounter })
1078
+ if (needToFlushWithAppStateSync) {
1079
+ logger.debug('flushing with app state sync')
1080
+ ev.flush()
1081
+ }
1082
+ }
1083
+ }
1084
+ })
1085
+ ws.on('CB:presence', handlePresenceUpdate)
1086
+ ws.on('CB:chatstate', handlePresenceUpdate)
1087
+ ws.on('CB:ib,,dirty', async (node) => {
1088
+ const { attrs } = (0, WABinary_1.getBinaryNodeChild)(node, 'dirty')
1089
+ const type = attrs.type
1090
+ switch (type) {
1091
+ case 'account_sync':
1092
+ if (attrs.timestamp) {
1093
+ let { lastAccountSyncTimestamp } = authState.creds
1094
+ if (lastAccountSyncTimestamp) {
1095
+ await cleanDirtyBits('account_sync', lastAccountSyncTimestamp)
1096
+ }
1097
+ lastAccountSyncTimestamp = +attrs.timestamp
1098
+ ev.emit('creds.update', { lastAccountSyncTimestamp })
1099
+ }
1100
+ break
1101
+ case 'groups':
1102
+ // handled in groups.ts
1103
+ break
1104
+ default:
1105
+ logger.info({ node }, 'received unknown sync')
1106
+ break
1107
+ }
1108
+ })
1109
+ ev.on('connection.update', ({ connection, receivedPendingNotifications }) => {
1110
+ var _a
1111
+ if (connection === 'open') {
1112
+ if (fireInitQueries) {
1113
+ executeInitQueries().catch((error) => onUnexpectedError(error, 'init queries'))
1114
+ }
1115
+ sendPresenceUpdate(markOnlineOnConnect ? 'available' : 'unavailable').catch((error) =>
1116
+ onUnexpectedError(error, 'presence update requests')
1117
+ )
1118
+ }
1119
+ if (receivedPendingNotifications) {
1120
+ // if we don't have the app state key
1121
+ // we keep buffering events until we finally have
1122
+ // the key and can sync the messages
1123
+ if (
1124
+ !((_a = authState.creds) === null || _a === void 0 ? void 0 : _a.myAppStateKeyId) &&
1125
+ !config.mobile
1126
+ ) {
1127
+ ev.buffer()
1128
+ needToFlushWithAppStateSync = true
1129
+ }
1130
+ }
1131
+ })
1132
+ return {
1133
+ ...sock,
1134
+ processingMutex,
1135
+ fetchPrivacySettings,
1136
+ upsertMessage,
1137
+ appPatch,
1138
+ sendPresenceUpdate,
1139
+ presenceSubscribe,
1140
+ profilePictureUrl,
1141
+ onWhatsApp,
1142
+ fetchBlocklist,
1143
+ fetchStatus,
1144
+ updateProfilePicture,
1145
+ removeProfilePicture,
1146
+ updateProfileStatus,
1147
+ updateProfileName,
1148
+ updateBlockStatus,
1149
+ updateLastSeenPrivacy,
1150
+ updateOnlinePrivacy,
1151
+ updateProfilePicturePrivacy,
1152
+ updateStatusPrivacy,
1153
+ updateReadReceiptsPrivacy,
1154
+ updateGroupsAddPrivacy,
1155
+ updateDefaultDisappearingMode,
1156
+ getBusinessProfile,
1157
+ resyncAppState,
1158
+ chatModify,
1159
+ cleanDirtyBits,
1160
+ addChatLabel,
1161
+ removeChatLabel,
1162
+ addMessageLabel,
1163
+ checkWhatsApp,
1164
+ reqPairing,
1165
+ removeMessageLabel,
1166
+ star
1167
+ }
1168
+ }
1169
+ exports.makeChatsSocket = makeChatsSocket