@badzz88/baileys 8.5.4 → 8.5.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (269) hide show
  1. package/README.md +2 -2
  2. package/WAProto/fix-imports.js +69 -79
  3. package/WAProto/index.d.ts +15305 -87935
  4. package/WAProto/index.js +41109 -194076
  5. package/engine-requirements.js +15 -8
  6. package/package.json +23 -19
  7. package/src/Defaults/index.js +186 -0
  8. package/src/Signal/Group/ciphertext-message.js +15 -0
  9. package/src/Signal/Group/group-session-builder.js +86 -0
  10. package/src/Signal/Group/group_cipher.js +82 -0
  11. package/src/Signal/Group/index.js +140 -0
  12. package/src/Signal/Group/keyhelper.js +77 -0
  13. package/src/Signal/Group/sender-chain-key.js +29 -0
  14. package/src/Signal/Group/sender-key-distribution-message.js +66 -0
  15. package/src/Signal/Group/sender-key-message.js +69 -0
  16. package/src/Signal/Group/sender-key-name.js +51 -0
  17. package/src/Signal/Group/sender-key-record.js +44 -0
  18. package/src/Signal/Group/sender-key-state.js +87 -0
  19. package/src/Signal/Group/sender-message-key.js +29 -0
  20. package/src/Signal/libsignal.js +455 -0
  21. package/src/Signal/lid-mapping.js +273 -0
  22. package/src/Socket/Client/index.js +31 -0
  23. package/src/Socket/Client/types.js +13 -0
  24. package/src/Socket/Client/websocket.js +61 -0
  25. package/src/Socket/aigroups.js +221 -0
  26. package/src/Socket/business.js +411 -0
  27. package/src/Socket/chats.js +1449 -0
  28. package/src/Socket/communities.js +463 -0
  29. package/src/Socket/graphql.js +523 -0
  30. package/src/Socket/groups.js +516 -0
  31. package/src/Socket/index.js +31 -0
  32. package/src/Socket/interactive-handler.js +527 -0
  33. package/src/Socket/interop.js +339 -0
  34. package/src/Socket/luxu.js +349 -0
  35. package/src/Socket/managed-account.js +98 -0
  36. package/src/Socket/messages-recv.js +2685 -0
  37. package/src/Socket/messages-send.js +2047 -0
  38. package/src/Socket/mex.js +57 -0
  39. package/src/Socket/newsletter.js +455 -0
  40. package/src/Socket/privacy.js +125 -0
  41. package/src/Socket/registration.js +236 -0
  42. package/src/Socket/socket.js +983 -0
  43. package/src/Socket/text-router.js +65 -0
  44. package/src/Socket/username.js +130 -0
  45. package/src/Store/index.js +33 -0
  46. package/src/Store/keyed-db.js +118 -0
  47. package/src/Store/make-cache-manager-store.js +84 -0
  48. package/src/Store/make-in-memory-store.js +551 -0
  49. package/src/Store/make-ordered-dictionary.js +81 -0
  50. package/src/Store/object-repository.js +26 -0
  51. package/src/Types/Auth.js +31 -0
  52. package/src/Types/Bussines.js +2 -0
  53. package/src/Types/Call.js +2 -0
  54. package/src/Types/Chat.js +4 -0
  55. package/src/Types/Contact.js +2 -0
  56. package/src/Types/Events.js +2 -0
  57. package/src/Types/GroupMetadata.js +2 -0
  58. package/src/Types/Label.js +26 -0
  59. package/src/Types/LabelAssociation.js +8 -0
  60. package/src/Types/Message.js +93 -0
  61. package/src/Types/Mex.js +112 -0
  62. package/src/Types/Newsletter.js +109 -0
  63. package/src/Types/Product.js +2 -0
  64. package/src/Types/Signal.js +2 -0
  65. package/src/Types/Socket.js +2 -0
  66. package/src/Types/State.js +62 -0
  67. package/src/Types/USync.js +2 -0
  68. package/src/Types/index.js +56 -0
  69. package/src/Utils/auth-utils.js +254 -0
  70. package/src/Utils/browser-utils.js +112 -0
  71. package/src/Utils/business.js +240 -0
  72. package/src/Utils/chat-utils.js +1230 -0
  73. package/src/Utils/command-loader.d.ts +27 -0
  74. package/src/Utils/command-loader.js +89 -0
  75. package/src/Utils/companion-reg-client-utils.js +40 -0
  76. package/src/Utils/consumer-application.js +105 -0
  77. package/src/Utils/crypto.js +118 -0
  78. package/src/Utils/curve25519-js.js +242 -0
  79. package/src/Utils/decode-wa-message.js +529 -0
  80. package/src/Utils/event-buffer.js +580 -0
  81. package/src/Utils/generics.js +483 -0
  82. package/src/Utils/group-history.js +44 -0
  83. package/src/Utils/history.js +232 -0
  84. package/src/Utils/identity-change-handler.js +52 -0
  85. package/src/Utils/index.js +58 -0
  86. package/src/Utils/jid-display-normalization.js +195 -0
  87. package/src/Utils/link-preview.js +135 -0
  88. package/src/Utils/logger.js +8 -0
  89. package/src/Utils/lt-hash.js +25 -0
  90. package/src/Utils/make-mutex.js +36 -0
  91. package/src/Utils/message-composer.js +471 -0
  92. package/src/Utils/message-retry-manager.js +217 -0
  93. package/src/Utils/messages-media.js +843 -0
  94. package/src/Utils/messages.js +2817 -0
  95. package/src/Utils/meta-ai-msmsg.js +222 -0
  96. package/src/Utils/native-bridge.js +68 -0
  97. package/src/Utils/noise-handler.js +169 -0
  98. package/src/Utils/offline-node-processor.js +34 -0
  99. package/src/Utils/pre-key-manager.js +90 -0
  100. package/src/Utils/process-message.js +950 -0
  101. package/src/Utils/reporting-utils.js +261 -0
  102. package/src/Utils/session-pool.d.ts +14 -0
  103. package/src/Utils/session-pool.js +70 -0
  104. package/src/Utils/signal.js +217 -0
  105. package/src/Utils/stanza-ack.js +30 -0
  106. package/src/Utils/sticker.d.ts +13 -0
  107. package/src/Utils/sticker.js +123 -0
  108. package/src/Utils/sync-action-utils.js +45 -0
  109. package/src/Utils/tc-token-utils.js +158 -0
  110. package/src/Utils/use-multi-file-auth-state.js +111 -0
  111. package/src/Utils/validate-connection.js +209 -0
  112. package/src/Utils/view-once-cache.d.ts +12 -0
  113. package/src/Utils/view-once-cache.js +63 -0
  114. package/src/Utils/voip-rekey.js +22 -0
  115. package/src/WABinary/constants.js +1304 -0
  116. package/src/WABinary/decode.js +342 -0
  117. package/src/WABinary/encode.js +225 -0
  118. package/src/WABinary/generic-utils.js +238 -0
  119. package/src/WABinary/index.js +34 -0
  120. package/src/WABinary/jid-utils.js +351 -0
  121. package/src/WABinary/types.js +2 -0
  122. package/src/WAM/BinaryInfo.js +13 -0
  123. package/src/WAM/constants.js +39484 -0
  124. package/src/WAM/encode.js +149 -0
  125. package/src/WAM/index.js +32 -0
  126. package/src/WAUSync/Protocols/USyncBotProfileProtocol.js +53 -0
  127. package/src/WAUSync/Protocols/USyncBusinessProtocol.js +44 -0
  128. package/src/WAUSync/Protocols/USyncContactProtocol.js +55 -0
  129. package/src/WAUSync/Protocols/USyncDeviceProtocol.js +55 -0
  130. package/src/WAUSync/Protocols/USyncDisappearingModeProtocol.js +31 -0
  131. package/src/WAUSync/Protocols/USyncFeatureProtocol.js +54 -0
  132. package/src/WAUSync/Protocols/USyncLIDProtocol.js +32 -0
  133. package/src/WAUSync/Protocols/USyncNewsletterProtocol.js +473 -0
  134. package/src/WAUSync/Protocols/USyncPictureProtocol.js +34 -0
  135. package/src/WAUSync/Protocols/USyncSidelistProtocol.js +29 -0
  136. package/src/WAUSync/Protocols/USyncStatusProtocol.js +42 -0
  137. package/src/WAUSync/Protocols/USyncTextStatusProtocol.js +38 -0
  138. package/src/WAUSync/Protocols/USyncUsernameProtocol.js +28 -0
  139. package/src/WAUSync/Protocols/index.js +40 -0
  140. package/src/WAUSync/USyncQuery.js +126 -0
  141. package/src/WAUSync/USyncUser.js +50 -0
  142. package/src/WAUSync/index.js +32 -0
  143. package/src/antiban.js +4152 -0
  144. package/{lib → src}/index.js +51 -49
  145. package/lib/Defaults/index.js +0 -195
  146. package/lib/Signal/Group/ciphertext-message.js +0 -15
  147. package/lib/Signal/Group/group-session-builder.js +0 -92
  148. package/lib/Signal/Group/group_cipher.js +0 -89
  149. package/lib/Signal/Group/index.js +0 -136
  150. package/lib/Signal/Group/keyhelper.js +0 -73
  151. package/lib/Signal/Group/sender-chain-key.js +0 -32
  152. package/lib/Signal/Group/sender-key-distribution-message.js +0 -66
  153. package/lib/Signal/Group/sender-key-message.js +0 -69
  154. package/lib/Signal/Group/sender-key-name.js +0 -50
  155. package/lib/Signal/Group/sender-key-record.js +0 -44
  156. package/lib/Signal/Group/sender-key-state.js +0 -97
  157. package/lib/Signal/Group/sender-message-key.js +0 -30
  158. package/lib/Signal/libsignal.js +0 -470
  159. package/lib/Signal/lid-mapping.js +0 -280
  160. package/lib/Socket/Client/index.js +0 -30
  161. package/lib/Socket/Client/types.js +0 -13
  162. package/lib/Socket/Client/websocket.js +0 -62
  163. package/lib/Socket/aigroups.js +0 -240
  164. package/lib/Socket/business.js +0 -414
  165. package/lib/Socket/chats.js +0 -2165
  166. package/lib/Socket/communities.js +0 -545
  167. package/lib/Socket/graphql.js +0 -863
  168. package/lib/Socket/groups.js +0 -685
  169. package/lib/Socket/index.js +0 -41
  170. package/lib/Socket/interactive-handler.js +0 -579
  171. package/lib/Socket/interop.js +0 -430
  172. package/lib/Socket/managed-account.js +0 -214
  173. package/lib/Socket/messages-recv.js +0 -3000
  174. package/lib/Socket/messages-send.js +0 -2155
  175. package/lib/Socket/mex.js +0 -47
  176. package/lib/Socket/newsletter.js +0 -814
  177. package/lib/Socket/privacy.js +0 -261
  178. package/lib/Socket/registration.js +0 -434
  179. package/lib/Socket/socket.js +0 -1074
  180. package/lib/Socket/username.js +0 -160
  181. package/lib/Store/index.js +0 -36
  182. package/lib/Store/make-cache-manager-store.js +0 -90
  183. package/lib/Store/make-in-memory-store.js +0 -488
  184. package/lib/Store/make-ordered-dictionary.js +0 -81
  185. package/lib/Store/object-repository.js +0 -29
  186. package/lib/Types/Auth.js +0 -38
  187. package/lib/Types/Bussines.js +0 -2
  188. package/lib/Types/Call.js +0 -2
  189. package/lib/Types/Chat.js +0 -4
  190. package/lib/Types/Contact.js +0 -2
  191. package/lib/Types/Events.js +0 -2
  192. package/lib/Types/GroupMetadata.js +0 -2
  193. package/lib/Types/Label.js +0 -27
  194. package/lib/Types/LabelAssociation.js +0 -9
  195. package/lib/Types/Message.js +0 -95
  196. package/lib/Types/Newsletter.js +0 -152
  197. package/lib/Types/Product.js +0 -2
  198. package/lib/Types/Signal.js +0 -2
  199. package/lib/Types/Socket.js +0 -2
  200. package/lib/Types/State.js +0 -70
  201. package/lib/Types/USync.js +0 -2
  202. package/lib/Types/index.js +0 -55
  203. package/lib/Utils/auth-utils.js +0 -301
  204. package/lib/Utils/browser-utils.js +0 -114
  205. package/lib/Utils/business.js +0 -243
  206. package/lib/Utils/chat-utils.js +0 -1272
  207. package/lib/Utils/consumer-application.js +0 -107
  208. package/lib/Utils/crypto.js +0 -125
  209. package/lib/Utils/decode-wa-message.js +0 -793
  210. package/lib/Utils/event-buffer.js +0 -583
  211. package/lib/Utils/generics.js +0 -617
  212. package/lib/Utils/group-history.js +0 -51
  213. package/lib/Utils/history.js +0 -244
  214. package/lib/Utils/identity-change-handler.js +0 -52
  215. package/lib/Utils/index.js +0 -53
  216. package/lib/Utils/jid-display-normalization.js +0 -218
  217. package/lib/Utils/link-preview.js +0 -138
  218. package/lib/Utils/logger.js +0 -9
  219. package/lib/Utils/lt-hash.js +0 -6
  220. package/lib/Utils/make-mutex.js +0 -36
  221. package/lib/Utils/message-composer.js +0 -479
  222. package/lib/Utils/message-inspect.js +0 -393
  223. package/lib/Utils/message-retry-manager.js +0 -205
  224. package/lib/Utils/messages-media.js +0 -925
  225. package/lib/Utils/messages.js +0 -2482
  226. package/lib/Utils/meta-ai-msmsg.js +0 -122
  227. package/lib/Utils/noise-handler.js +0 -194
  228. package/lib/Utils/offline-node-processor.js +0 -37
  229. package/lib/Utils/pre-key-manager.js +0 -97
  230. package/lib/Utils/process-message.js +0 -1139
  231. package/lib/Utils/reporting-utils.js +0 -262
  232. package/lib/Utils/signal.js +0 -189
  233. package/lib/Utils/stanza-ack.js +0 -67
  234. package/lib/Utils/sync-action-utils.js +0 -51
  235. package/lib/Utils/tc-token-utils.js +0 -156
  236. package/lib/Utils/use-multi-file-auth-state.js +0 -137
  237. package/lib/Utils/validate-connection.js +0 -259
  238. package/lib/Utils/voip-rekey.js +0 -22
  239. package/lib/WABinary/constants.js +0 -1304
  240. package/lib/WABinary/decode.js +0 -377
  241. package/lib/WABinary/encode.js +0 -58
  242. package/lib/WABinary/generic-utils.js +0 -150
  243. package/lib/WABinary/index.js +0 -33
  244. package/lib/WABinary/jid-utils.js +0 -374
  245. package/lib/WABinary/types.js +0 -2
  246. package/lib/WAM/BinaryInfo.js +0 -13
  247. package/lib/WAM/constants.js +0 -39486
  248. package/lib/WAM/encode.js +0 -142
  249. package/lib/WAM/index.js +0 -31
  250. package/lib/WAUSync/Protocols/USyncBotProfileProtocol.js +0 -55
  251. package/lib/WAUSync/Protocols/USyncBusinessProtocol.js +0 -100
  252. package/lib/WAUSync/Protocols/USyncContactProtocol.js +0 -60
  253. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +0 -65
  254. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +0 -27
  255. package/lib/WAUSync/Protocols/USyncFeatureProtocol.js +0 -72
  256. package/lib/WAUSync/Protocols/USyncLIDProtocol.js +0 -31
  257. package/lib/WAUSync/Protocols/USyncNewsletterProtocol.js +0 -865
  258. package/lib/WAUSync/Protocols/USyncPictureProtocol.js +0 -32
  259. package/lib/WAUSync/Protocols/USyncSidelistProtocol.js +0 -29
  260. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +0 -44
  261. package/lib/WAUSync/Protocols/USyncTextStatusProtocol.js +0 -38
  262. package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +0 -28
  263. package/lib/WAUSync/Protocols/index.js +0 -40
  264. package/lib/WAUSync/USyncBackoff.js +0 -26
  265. package/lib/WAUSync/USyncQuery.js +0 -204
  266. package/lib/WAUSync/USyncUser.js +0 -58
  267. package/lib/WAUSync/index.js +0 -32
  268. package/lib/antiban.js +0 -4391
  269. /package/{lib → src}/Defaults/phonenumber-mcc.json +0 -0
@@ -1,2165 +0,0 @@
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 node_cache_1 = __importDefault(require('@cacheable/node-cache'))
10
- const boom_1 = require('@hapi/boom')
11
- const index_js_1 = require('../../WAProto/index.js')
12
- const Defaults_1 = require('../Defaults')
13
- const Types_1 = require('../Types')
14
- const State_1 = require('../Types/State')
15
- const Utils_1 = require('../Utils')
16
- const make_mutex_1 = require('../Utils/make-mutex')
17
- const process_message_1 = __importDefault(require('../Utils/process-message'))
18
- const { unwrapSecretEncryptedMessage } = require('../Utils/process-message')
19
- const tc_token_utils_1 = require('../Utils/tc-token-utils')
20
- const WABinary_1 = require('../WABinary')
21
- const WAUSync_1 = require('../WAUSync')
22
- const socket_js_1 = require('./socket.js')
23
- const interop_js_1 = require('./interop.js')
24
- const makeChatsSocket = config => {
25
- const {
26
- logger,
27
- markOnlineOnConnect,
28
- fireInitQueries,
29
- appStateMacVerification,
30
- shouldIgnoreJid,
31
- shouldSyncHistoryMessage,
32
- getMessage
33
- } = config
34
- const sock = (0, interop_js_1.makeInteropSocket)((0, socket_js_1.makeSocket)(config))
35
- const {
36
- ev,
37
- ws,
38
- authState,
39
- generateMessageTag,
40
- sendNode,
41
- query,
42
- signalRepository,
43
- onUnexpectedError,
44
- sendUnifiedSession,
45
- initInterop,
46
- fetchIntegrators,
47
- acceptInteropTOS,
48
- optInIntegrators,
49
- optOutIntegrators,
50
- resolveInteropUser,
51
- resolveInteropUsers,
52
- getReachabilitySettings,
53
- setReachabilitySettings,
54
- blockInteropUser,
55
- unblockInteropUser,
56
- reportInteropSpam,
57
- trustInteropContact,
58
- createInteropGroup,
59
- leaveInteropGroup,
60
- getInteropGroupAddPrivacy,
61
- INTEGRATOR_BIRDYCHAT,
62
- INTEGRATOR_HAIKET
63
- } = sock
64
- const getLIDForPN = signalRepository.lidMapping.getLIDForPN.bind(signalRepository.lidMapping)
65
- let privacySettings
66
-
67
- const serverProps = {
68
-
69
- privacyTokenOn1to1: true,
70
-
71
- profilePicPrivacyToken: true,
72
-
73
- lidTrustedTokenIssueToLid: false
74
- }
75
- let syncState = State_1.SyncState.Connecting
76
-
77
- const messageMutex = (0, make_mutex_1.makeMutex)()
78
-
79
- const receiptMutex = (0, make_mutex_1.makeMutex)()
80
-
81
- const appStatePatchMutex = (0, make_mutex_1.makeMutex)()
82
-
83
- const notificationMutex = (0, make_mutex_1.makeMutex)()
84
-
85
- let awaitingSyncTimeout
86
-
87
- const historySyncStatus = {
88
- initialBootstrapComplete: false,
89
- recentSyncComplete: false
90
- }
91
- let historySyncPausedTimeout
92
-
93
-
94
- const blockedCollections = new Set()
95
-
96
- const _nlServerIdCache = new Map()
97
- const placeholderResendCache =
98
- config.placeholderResendCache ||
99
- new node_cache_1.default({
100
- stdTTL: Defaults_1.DEFAULT_CACHE_TTLS.MSG_RETRY,
101
- useClones: false
102
- })
103
- if (!config.placeholderResendCache) {
104
- config.placeholderResendCache = placeholderResendCache
105
- }
106
-
107
- const getAppStateSyncKey = async keyId => {
108
- const { [keyId]: key } = await authState.keys.get('app-state-sync-key', [keyId])
109
- return key
110
- }
111
- const fetchPrivacySettings = async (force = false) => {
112
- if (!privacySettings || force) {
113
- const { content } = await query({
114
- tag: 'iq',
115
- attrs: {
116
- xmlns: 'privacy',
117
- to: WABinary_1.S_WHATSAPP_NET,
118
- type: 'get'
119
- },
120
- content: [{ tag: 'privacy', attrs: {} }]
121
- })
122
- const privacyNode = content?.[0]
123
- privacySettings = (0, WABinary_1.reduceBinaryNodeToDictionary)(privacyNode, 'category')
124
-
125
-
126
-
127
- const onlinePrivacy =
128
- privacySettings['online'] ||
129
- (0, WABinary_1.getBinaryNodeChild)(privacyNode, 'online_privacy_setting')?.attrs?.value ||
130
- 'all'
131
-
132
-
133
- const enhancedBlockEnabled =
134
- privacyNode?.attrs?.enhanced_block_enabled === 'true' ||
135
- (0, WABinary_1.getBinaryNodeChild)(privacyNode, 'enhanced_block')?.attrs?.enabled === 'true'
136
-
137
-
138
- const mdPrivacyV2 =
139
- privacyNode?.attrs?.md_privacy_v2 === 'true' ||
140
- (0, WABinary_1.getBinaryNodeChild)(privacyNode, 'md_privacy_v2')?.attrs?.value === 'true'
141
-
142
-
143
- const syncdClearChatDeleteChatEnabled =
144
- privacyNode?.attrs?.syncd_clear_chat_delete_chat_enabled === 'true' ||
145
- (0, WABinary_1.getBinaryNodeChild)(privacyNode, 'syncd_clear_chat')?.attrs?.delete_chat_enabled === 'true'
146
-
147
-
148
- const syncdAntiTamperingEnabled =
149
- privacyNode?.attrs?.syncd_anti_tampering_fatal_exception_enabled === 'true' ||
150
- (0, WABinary_1.getBinaryNodeChild)(privacyNode, 'syncd_anti_tampering')?.attrs?.fatal_exception_enabled ===
151
- 'true'
152
-
153
-
154
- const keyRotationEnabled =
155
- privacyNode?.attrs?.syncd_key_rotation_enabled === 'true' ||
156
- (0, WABinary_1.getBinaryNodeChild)(privacyNode, 'syncd_key_rotation')?.attrs?.enabled === 'true'
157
-
158
-
159
- ev.emit('settings.update', {
160
- onlinePrivacy,
161
- enhancedBlockEnabled,
162
- mdPrivacyV2,
163
- syncdClearChatDeleteChatEnabled,
164
- ...(syncdAntiTamperingEnabled ? { syncdAntiTamperingEnabled: true } : {}),
165
- keyRotationEnabled
166
- })
167
-
168
-
169
- ev.emit('creds.update', {
170
- privacySettings: {
171
- onlinePrivacy,
172
- enhancedBlockEnabled,
173
- mdPrivacyV2,
174
- syncdClearChatDeleteChatEnabled,
175
- syncdAntiTamperingEnabled,
176
- keyRotationEnabled
177
- }
178
- })
179
- }
180
- return privacySettings
181
- }
182
-
183
- const privacyQuery = async (name, value) => {
184
- await query({
185
- tag: 'iq',
186
- attrs: {
187
- xmlns: 'privacy',
188
- to: WABinary_1.S_WHATSAPP_NET,
189
- type: 'set'
190
- },
191
- content: [
192
- {
193
- tag: 'privacy',
194
- attrs: {},
195
- content: [
196
- {
197
- tag: 'category',
198
- attrs: { name, value }
199
- }
200
- ]
201
- }
202
- ]
203
- })
204
- }
205
- const updateMessagesPrivacy = async value => {
206
- await privacyQuery('messages', value)
207
- }
208
- const updateCallPrivacy = async value => {
209
- await privacyQuery('calladd', value)
210
- }
211
- const updateLastSeenPrivacy = async value => {
212
- await privacyQuery('last', value)
213
- }
214
- const updateOnlinePrivacy = async value => {
215
- await privacyQuery('online', value)
216
- }
217
- const updateProfilePicturePrivacy = async value => {
218
- await privacyQuery('profile', value)
219
- }
220
- const updateStatusPrivacy = async value => {
221
- await privacyQuery('status', value)
222
- }
223
-
224
- const getStatusPrivacy = async () => {
225
- const result = await query({
226
- tag: 'iq',
227
- attrs: {
228
- xmlns: 'status',
229
- to: WABinary_1.S_WHATSAPP_NET,
230
- type: 'get'
231
- },
232
- content: [{ tag: 'privacy', attrs: {} }]
233
- })
234
- const privacyNode = result?.content?.[0]
235
- if (!privacyNode) return null
236
- const lists = []
237
- for (const listNode of privacyNode.content || []) {
238
- const { type, id, listname, emoji, selected, deleted } = listNode.attrs || {}
239
- const members = (listNode.content || []).map(u => u.attrs?.jid).filter(Boolean)
240
- lists.push({ type, id, listname, emoji, selected: selected === 'true', deleted: deleted === 'true', members })
241
- }
242
- return lists
243
- }
244
-
245
- const setStatusPrivacy = async (type, jids = [], customLists = []) => {
246
- const content = []
247
-
248
- const mainList = {
249
- tag: 'list',
250
- attrs: { type },
251
- content: jids.map(jid => ({ tag: 'user', attrs: { jid }, content: [] }))
252
- }
253
- content.push(mainList)
254
-
255
- for (const cl of customLists) {
256
- const attrs = { type: 'customlist', id: cl.id, listname: cl.listname }
257
- if (cl.emoji) attrs.emoji = cl.emoji
258
- if (cl.selected) attrs.selected = 'true'
259
- if (cl.deleted) attrs.deleted = 'true'
260
- content.push({
261
- tag: 'list',
262
- attrs,
263
- content: (cl.members || []).map(jid => ({ tag: 'user', attrs: { jid }, content: [] }))
264
- })
265
- }
266
- await query({
267
- tag: 'iq',
268
- attrs: {
269
- xmlns: 'status',
270
- to: WABinary_1.S_WHATSAPP_NET,
271
- type: 'set'
272
- },
273
- content: [{ tag: 'privacy', attrs: {}, content }]
274
- })
275
- }
276
- const updateReadReceiptsPrivacy = async value => {
277
- await privacyQuery('readreceipts', value)
278
- }
279
- const updateGroupsAddPrivacy = async value => {
280
- await privacyQuery('groupadd', value)
281
- }
282
- const updateDefaultDisappearingMode = async duration => {
283
- await query({
284
- tag: 'iq',
285
- attrs: {
286
- xmlns: 'disappearing_mode',
287
- to: WABinary_1.S_WHATSAPP_NET,
288
- type: 'set'
289
- },
290
- content: [
291
- {
292
- tag: 'disappearing_mode',
293
- attrs: {
294
- duration: duration.toString()
295
- }
296
- }
297
- ]
298
- })
299
- }
300
-
301
- const fetchBroadcastListQuota = async () => {
302
- const result = await query(
303
- {
304
- tag: 'iq',
305
- attrs: {
306
- xmlns: 'w:biz',
307
- to: WABinary_1.S_WHATSAPP_NET,
308
- type: 'get'
309
- },
310
- content: [{ tag: 'broadcast_list_quota', attrs: {}, content: [] }]
311
- },
312
- 32000
313
- )
314
- const limitsNode = (0, WABinary_1.getBinaryNodeChild)(result, 'limits')
315
- const timeframeNode = (0, WABinary_1.getBinaryNodeChild)(result, 'timeframe')
316
- if (!limitsNode) return null
317
- return {
318
- messagesLeft: parseInt(
319
- limitsNode.attrs?.messages_left ??
320
- (0, WABinary_1.getBinaryNodeChild)(limitsNode, 'messages_left')?.content ??
321
- '0',
322
- 10
323
- ),
324
- totalLimit: parseInt(
325
- limitsNode.attrs?.total_limit ?? (0, WABinary_1.getBinaryNodeChild)(limitsNode, 'total_limit')?.content ?? '0',
326
- 10
327
- ),
328
- isHeavySender:
329
- (limitsNode.attrs?.is_heavy_sender ??
330
- (0, WABinary_1.getBinaryNodeChild)(limitsNode, 'is_heavy_sender')?.content) === 'true',
331
- startTs: parseInt(
332
- timeframeNode?.attrs?.start_ts_s ??
333
- (0, WABinary_1.getBinaryNodeChild)(timeframeNode, 'start_ts_s')?.content ??
334
- '0',
335
- 10
336
- ),
337
- endTs: parseInt(
338
- timeframeNode?.attrs?.end_ts_s ?? (0, WABinary_1.getBinaryNodeChild)(timeframeNode, 'end_ts_s')?.content ?? '0',
339
- 10
340
- ),
341
- resetTs: parseInt(
342
- timeframeNode?.attrs?.reset_ts_s ??
343
- (0, WABinary_1.getBinaryNodeChild)(timeframeNode, 'reset_ts_s')?.content ??
344
- '0',
345
- 10
346
- )
347
- }
348
- }
349
-
350
- const getBotListV2 = async () => {
351
- const resp = await query({
352
- tag: 'iq',
353
- attrs: {
354
- xmlns: 'bot',
355
- to: WABinary_1.S_WHATSAPP_NET,
356
- type: 'get'
357
- },
358
- content: [
359
- {
360
- tag: 'bot',
361
- attrs: {
362
- v: '2'
363
- }
364
- }
365
- ]
366
- })
367
- const botNode = (0, WABinary_1.getBinaryNodeChild)(resp, 'bot')
368
- const botList = []
369
- for (const section of (0, WABinary_1.getBinaryNodeChildren)(botNode, 'section')) {
370
- if (section.attrs.type === 'all') {
371
- for (const bot of (0, WABinary_1.getBinaryNodeChildren)(section, 'bot')) {
372
- botList.push({
373
- jid: bot.attrs.jid,
374
- personaId: bot.attrs['persona_id']
375
- })
376
- }
377
- }
378
- }
379
- return botList
380
- }
381
-
382
- const getChatBlockingStatus = async () => {
383
- const result = await query({
384
- tag: 'iq',
385
- attrs: {
386
- to: WABinary_1.S_WHATSAPP_NET,
387
- xmlns: 'w:comms:chat',
388
- type: 'get'
389
- },
390
- content: [{ tag: 'query', attrs: {}, content: [{ tag: 'blocking_status', attrs: {} }] }]
391
- })
392
- const blocking =
393
- (0, WABinary_1.getBinaryNodeChild)(result, 'blocking') ||
394
- (0, WABinary_1.getBinaryNodeChild)((0, WABinary_1.getBinaryNodeChild)(result, 'query'), 'blocking')
395
- return blocking?.attrs?.status
396
- }
397
-
398
- const updateChatBlockingStatus = async action => {
399
- const result = await query({
400
- tag: 'iq',
401
- attrs: {
402
- to: WABinary_1.S_WHATSAPP_NET,
403
- xmlns: 'w:comms:chat',
404
- type: 'set'
405
- },
406
- content: [{ tag: 'blocking', attrs: { action } }]
407
- })
408
- const blocking = (0, WABinary_1.getBinaryNodeChild)(result, 'blocking')
409
- return blocking?.attrs?.status
410
- }
411
-
412
- const getUserDisclosures = async (t = 0) => {
413
- const result = await query({
414
- tag: 'iq',
415
- attrs: { to: WABinary_1.S_WHATSAPP_NET, xmlns: 'tos', type: 'get' },
416
- content: [{ tag: 'get_user_disclosures', attrs: { t: String(t) } }]
417
- })
418
- return (0, WABinary_1.getBinaryNodeChildren)(result, 'notice').map(n => ({ ...n.attrs }))
419
- }
420
-
421
- const acceptTosNotice = async (noticeId, result = '105') => {
422
- await query({
423
- tag: 'iq',
424
- attrs: { to: WABinary_1.S_WHATSAPP_NET, xmlns: 'tos', type: 'set' },
425
- content: [{ tag: 'trackable', attrs: { id: String(noticeId), result: String(result) } }]
426
- })
427
- }
428
-
429
- const reportSpam = async (jid, messages, spamFlow = 'contact_info_report', subject) => {
430
- const msgNodes = (messages || []).map(m => ({
431
- tag: 'message',
432
- attrs: {
433
- from: String(jid),
434
- t: String(m.t),
435
- id: String(m.id)
436
- }
437
- }))
438
- await query({
439
- tag: 'iq',
440
- attrs: { to: WABinary_1.S_WHATSAPP_NET, xmlns: 'spam', type: 'set' },
441
- content: [
442
- {
443
- tag: 'spam_list',
444
- attrs: {
445
- jid: String(jid),
446
- spam_flow: String(spamFlow),
447
- ...(subject ? { subject: String(subject) } : {})
448
- },
449
- content: msgNodes
450
- }
451
- ]
452
- })
453
- }
454
-
455
- const getOptOutList = async () => {
456
- return query({
457
- tag: 'iq',
458
- attrs: { to: WABinary_1.S_WHATSAPP_NET, xmlns: 'optoutlist', type: 'get' }
459
- })
460
- }
461
-
462
- const signPrivateCredential = async blindedCredential => {
463
- const result = await query({
464
- tag: 'iq',
465
- attrs: { to: WABinary_1.S_WHATSAPP_NET, xmlns: 'privatestats', type: 'get' },
466
- content: [
467
- {
468
- tag: 'sign_credential',
469
- attrs: { version: '1' },
470
- content: [{ tag: 'blinded_credential', attrs: {}, content: blindedCredential }]
471
- }
472
- ]
473
- })
474
- const signedNode = (0, WABinary_1.getBinaryNodeChild)(result, 'sign_credential')
475
- const signedBytes = (0, WABinary_1.getBinaryNodeChild)(signedNode, 'signed_credential')
476
- return signedBytes?.content instanceof Uint8Array ? Buffer.from(signedBytes.content) : undefined
477
- }
478
-
479
- const getPushConfig = async () => {
480
- const result = await query({
481
- tag: 'iq',
482
- attrs: { to: WABinary_1.S_WHATSAPP_NET, xmlns: 'urn:xmpp:whatsapp:push', type: 'get' },
483
- content: [{ tag: 'settings', attrs: {} }]
484
- })
485
- return (0, WABinary_1.getBinaryNodeChild)(result, 'settings')
486
- }
487
-
488
- const setPushConfig = async config => {
489
- await query({
490
- tag: 'iq',
491
- attrs: { to: WABinary_1.S_WHATSAPP_NET, xmlns: 'urn:xmpp:whatsapp:push', type: 'set' },
492
- content: [{ tag: 'config', attrs: config }]
493
- })
494
- }
495
- const fetchStatus = async (...jids) => {
496
- const usyncQuery = new WAUSync_1.USyncQuery().withStatusProtocol()
497
- for (const jid of jids) {
498
- usyncQuery.withUser(new WAUSync_1.USyncUser().withId(jid))
499
- }
500
- const result = await executeUSyncQuery(usyncQuery)
501
- if (result) {
502
- return result.list
503
- }
504
- }
505
- const fetchDisappearingDuration = async (...jids) => {
506
- const usyncQuery = new WAUSync_1.USyncQuery().withDisappearingModeProtocol()
507
- for (const jid of jids) {
508
- usyncQuery.withUser(new WAUSync_1.USyncUser().withId(jid))
509
- }
510
- const result = await executeUSyncQuery(usyncQuery)
511
- if (result) {
512
- return result.list
513
- }
514
- }
515
-
516
- const updateProfilePicture = async (jid, content, dimensions) => {
517
- let targetJid
518
- if (!jid) {
519
- throw new boom_1.Boom(
520
- 'Illegal no-jid profile update. Please specify either your ID or the ID of the chat you wish to update'
521
- )
522
- }
523
- if ((0, WABinary_1.jidNormalizedUser)(jid) !== (0, WABinary_1.jidNormalizedUser)(authState.creds.me.id)) {
524
- targetJid = (0, WABinary_1.jidNormalizedUser)(jid)
525
- } else {
526
- targetJid = undefined
527
- }
528
- const { img } = await (0, Utils_1.generateProfilePicture)(content, dimensions)
529
- await query({
530
- tag: 'iq',
531
- attrs: {
532
- to: WABinary_1.S_WHATSAPP_NET,
533
- type: 'set',
534
- xmlns: 'w:profile:picture',
535
- ...(targetJid ? { target: targetJid } : {})
536
- },
537
- content: [
538
- {
539
- tag: 'picture',
540
- attrs: { type: 'image' },
541
- content: img
542
- }
543
- ]
544
- })
545
- }
546
-
547
- const removeProfilePicture = async jid => {
548
- let targetJid
549
- if (!jid) {
550
- throw new boom_1.Boom(
551
- 'Illegal no-jid profile update. Please specify either your ID or the ID of the chat you wish to update'
552
- )
553
- }
554
- if ((0, WABinary_1.jidNormalizedUser)(jid) !== (0, WABinary_1.jidNormalizedUser)(authState.creds.me.id)) {
555
- targetJid = (0, WABinary_1.jidNormalizedUser)(jid)
556
- } else {
557
- targetJid = undefined
558
- }
559
- await query({
560
- tag: 'iq',
561
- attrs: {
562
- to: WABinary_1.S_WHATSAPP_NET,
563
- type: 'set',
564
- xmlns: 'w:profile:picture',
565
- ...(targetJid ? { target: targetJid } : {})
566
- }
567
- })
568
- }
569
-
570
- const updateProfileStatus = async status => {
571
- await query({
572
- tag: 'iq',
573
- attrs: {
574
- to: WABinary_1.S_WHATSAPP_NET,
575
- type: 'set',
576
- xmlns: 'status'
577
- },
578
- content: [
579
- {
580
- tag: 'status',
581
- attrs: {},
582
- content: Buffer.from(status, 'utf-8')
583
- }
584
- ]
585
- })
586
- }
587
- const updateProfileName = async name => {
588
- await chatModify({ pushNameSetting: name }, '')
589
- }
590
-
591
-
592
-
593
-
594
- const fetchBlocklist = async (dhash = null) => {
595
- const result = await query({
596
- tag: 'iq',
597
- attrs: {
598
- xmlns: 'blocklist',
599
- to: WABinary_1.S_WHATSAPP_NET,
600
- type: 'get'
601
- },
602
- content: dhash ? [{ tag: 'item', attrs: { dhash } }] : null
603
- })
604
- const listNode = (0, WABinary_1.getBinaryNodeChild)(result, 'list')
605
- const jids = (0, WABinary_1.getBinaryNodeChildren)(listNode, 'item').map(n => n.attrs.jid)
606
- ev.emit('blocklist.set', { blocklist: jids })
607
- return jids
608
- }
609
- const updateBlockStatus = async (jid, action) => {
610
- await query({
611
- tag: 'iq',
612
- attrs: {
613
- xmlns: 'blocklist',
614
- to: WABinary_1.S_WHATSAPP_NET,
615
- type: 'set'
616
- },
617
- content: [
618
- {
619
- tag: 'item',
620
- attrs: {
621
- action,
622
- jid
623
- }
624
- }
625
- ]
626
- })
627
- }
628
- const getBusinessProfile = async jid => {
629
-
630
-
631
-
632
- const [results, verifiedNameResult] = await Promise.all([
633
- query({
634
- tag: 'iq',
635
- attrs: {
636
- to: 's.whatsapp.net',
637
- xmlns: 'w:biz',
638
- type: 'get'
639
- },
640
- content: [
641
- {
642
- tag: 'business_profile',
643
- attrs: { v: '116' },
644
- content: [
645
- {
646
- tag: 'profile',
647
- attrs: { jid }
648
- }
649
- ]
650
- }
651
- ]
652
- }),
653
- query({
654
- tag: 'iq',
655
- attrs: {
656
- to: 's.whatsapp.net',
657
- xmlns: 'w:biz',
658
- type: 'get'
659
- },
660
- content: [
661
- {
662
- tag: 'verified_name',
663
- attrs: { jid }
664
- }
665
- ]
666
- })
667
- ])
668
-
669
- const verifiedNameNode = (0, WABinary_1.getBinaryNodeChild)(verifiedNameResult, 'verified_name')
670
- let verifiedNameCert
671
- if (verifiedNameNode) {
672
- const certNode = (0, WABinary_1.getBinaryNodeChild)(verifiedNameNode, 'certificate')
673
- if (certNode) {
674
- const detailsNode = (0, WABinary_1.getBinaryNodeChild)(certNode, 'details')
675
- const localizedNames = (0, WABinary_1.getBinaryNodeChildren)(certNode, 'localized_name').map(n => ({
676
- lg: n.attrs?.lg,
677
- lc: n.attrs?.lc,
678
- verifiedName: n.attrs?.verified_name || n.content?.toString()
679
- }))
680
- verifiedNameCert = {
681
- certSerial: certNode.attrs?.serial ? +certNode.attrs.serial : undefined,
682
- issuer: certNode.attrs?.issuer,
683
- details: {
684
- verifiedName: detailsNode?.attrs?.verified_name || detailsNode?.content?.toString(),
685
- localizedNames
686
- }
687
- }
688
- }
689
- }
690
- const profileNode = (0, WABinary_1.getBinaryNodeChild)(results, 'business_profile')
691
- const profiles = (0, WABinary_1.getBinaryNodeChild)(profileNode, 'profile')
692
- if (profiles) {
693
- const address = (0, WABinary_1.getBinaryNodeChild)(profiles, 'address')
694
- const description = (0, WABinary_1.getBinaryNodeChild)(profiles, 'description')
695
- const website = (0, WABinary_1.getBinaryNodeChild)(profiles, 'website')
696
- const email = (0, WABinary_1.getBinaryNodeChild)(profiles, 'email')
697
- const category = (0, WABinary_1.getBinaryNodeChild)(
698
- (0, WABinary_1.getBinaryNodeChild)(profiles, 'categories'),
699
- 'category'
700
- )
701
- const businessHours = (0, WABinary_1.getBinaryNodeChild)(profiles, 'business_hours')
702
- const businessHoursConfig = businessHours
703
- ? (0, WABinary_1.getBinaryNodeChildren)(businessHours, 'business_hours_config')
704
- : undefined
705
- const websiteStr = website?.content?.toString()
706
-
707
-
708
- const catalogStatus = {
709
- exists: profiles.attrs?.catalog_exists === 'true' || profiles.attrs?.catalog_exists === true || false,
710
- sendAll: profiles.attrs?.catalog_send_all === 'true' || profiles.attrs?.catalog_send_all === true || false
711
- }
712
-
713
-
714
- const cartEnabled =
715
- profiles.attrs?.cart_enabled !== undefined
716
- ? profiles.attrs.cart_enabled === 'true' || profiles.attrs.cart_enabled === true
717
- : undefined
718
- const webCartEnabled =
719
- profiles.attrs?.web_cart_enabled !== undefined
720
- ? profiles.attrs.web_cart_enabled === 'true' || profiles.attrs.web_cart_enabled === true
721
- : undefined
722
- const webCartOnOff = profiles.attrs?.web_cart_on_off
723
-
724
-
725
- const commerceExperience = profiles.attrs?.commerce_experience
726
-
727
- return {
728
- wid: profiles.attrs?.jid,
729
- address: address?.content?.toString(),
730
- businessAddress: address?.content?.toString(),
731
- description: description?.content?.toString() || '',
732
- website: websiteStr ? [websiteStr] : [],
733
- email: email?.content?.toString(),
734
- category: category?.content?.toString(),
735
- business_hours: {
736
- timezone: businessHours?.attrs?.timezone,
737
- business_config: businessHoursConfig?.map(({ attrs }) => attrs)
738
- },
739
- businessHours: businessHoursConfig
740
- ? {
741
- timezone: businessHours?.attrs?.timezone ?? null,
742
- config: businessHoursConfig.map(({ attrs }) => ({
743
- dayOfWeek: attrs?.day_of_week ?? null,
744
- openTime: attrs?.open_time ?? null,
745
- closeTime: attrs?.close_time ?? null,
746
- mode: attrs?.mode ?? null
747
- }))
748
- }
749
- : null,
750
- catalogStatus,
751
- cartEnabled,
752
- webCartEnabled,
753
- webCartOnOff,
754
- commerceExperience,
755
- verifiedNameCert
756
- }
757
- }
758
- }
759
- const cleanDirtyBits = async (type, fromTimestamp) => {
760
- logger.info({ fromTimestamp }, 'clean dirty bits ' + type)
761
- await sendNode({
762
- tag: 'iq',
763
- attrs: {
764
- to: WABinary_1.S_WHATSAPP_NET,
765
- type: 'set',
766
- xmlns: 'urn:xmpp:whatsapp:dirty',
767
- id: generateMessageTag()
768
- },
769
- content: [
770
- {
771
- tag: 'clean',
772
- attrs: {
773
- type,
774
- ...(fromTimestamp ? { timestamp: fromTimestamp.toString() } : null)
775
- }
776
- }
777
- ]
778
- })
779
- }
780
- const newAppStateChunkHandler = isInitialSync => {
781
- return {
782
- onMutation(mutation) {
783
- ;(0, Utils_1.processSyncAction)(
784
- mutation,
785
- ev,
786
- authState.creds.me,
787
- isInitialSync ? { accountSettings: authState.creds.accountSettings } : undefined,
788
- logger
789
- )
790
-
791
- const _nctSalt = mutation?.syncAction?.value?.nctSaltSyncAction?.salt
792
- if (_nctSalt?.length) {
793
- authState.keys
794
- .set({ 'nct-salt': { default: Buffer.from(_nctSalt) } })
795
- .catch(err => logger.debug({ err: err?.message }, 'nct: failed to persist salt'))
796
- }
797
- }
798
- }
799
- }
800
- const resyncAppState = ev.createBufferedFunction(async (collections, isInitialSync) => {
801
- const appStateSyncKeyCache = new Map()
802
- const getCachedAppStateSyncKey = async keyId => {
803
- if (appStateSyncKeyCache.has(keyId)) {
804
- return appStateSyncKeyCache.get(keyId)
805
- }
806
- const key = await getAppStateSyncKey(keyId)
807
- appStateSyncKeyCache.set(keyId, key ?? null)
808
- return key
809
- }
810
-
811
-
812
- const initialVersionMap = {}
813
- const globalMutationMap = {}
814
- await authState.keys.transaction(async () => {
815
- const collectionsToHandle = new Set(collections)
816
-
817
- const attemptsMap = {}
818
- const forceSnapshotCollections = new Set()
819
-
820
-
821
-
822
- while (collectionsToHandle.size) {
823
- const states = {}
824
- const nodes = []
825
- for (const name of collectionsToHandle) {
826
- const result = await authState.keys.get('app-state-sync-version', [name])
827
- let state = result[name]
828
- if (state) {
829
- if (initialVersionMap[name] === undefined) {
830
- initialVersionMap[name] = state.version
831
- }
832
- } else {
833
- state = (0, Utils_1.newLTHashState)()
834
- }
835
- states[name] = state
836
- const shouldForceSnapshot = forceSnapshotCollections.has(name)
837
- if (shouldForceSnapshot) {
838
- forceSnapshotCollections.delete(name)
839
- }
840
- logger.info(`resyncing ${name} from v${state.version}${shouldForceSnapshot ? ' (forcing snapshot)' : ''}`)
841
- nodes.push({
842
- tag: 'collection',
843
- attrs: {
844
- name,
845
- version: state.version.toString(),
846
-
847
- return_snapshot: (shouldForceSnapshot || !state.version).toString()
848
- }
849
- })
850
- }
851
- const result = await query({
852
- tag: 'iq',
853
- attrs: {
854
- to: WABinary_1.S_WHATSAPP_NET,
855
- xmlns: 'w:sync:app:state',
856
- type: 'set'
857
- },
858
- content: [
859
- {
860
- tag: 'sync',
861
- attrs: {},
862
- content: nodes
863
- }
864
- ]
865
- })
866
-
867
- const decoded = await (0, Utils_1.extractSyncdPatches)(result, config?.options)
868
- for (const key in decoded) {
869
- const name = key
870
- const { patches, hasMorePatches, snapshot } = decoded[name]
871
- try {
872
- if (snapshot) {
873
- const { state: newState, mutationMap } = await (0, Utils_1.decodeSyncdSnapshot)(
874
- name,
875
- snapshot,
876
- getCachedAppStateSyncKey,
877
- initialVersionMap[name],
878
- appStateMacVerification.snapshot
879
- )
880
- states[name] = newState
881
- Object.assign(globalMutationMap, mutationMap)
882
- logger.info(`restored state of ${name} from snapshot to v${newState.version} with mutations`)
883
- await authState.keys.set({ 'app-state-sync-version': { [name]: newState } })
884
- }
885
-
886
- if (patches.length) {
887
- const { state: newState, mutationMap } = await (0, Utils_1.decodePatches)(
888
- name,
889
- patches,
890
- states[name],
891
- getCachedAppStateSyncKey,
892
- config.options,
893
- initialVersionMap[name],
894
- logger,
895
- appStateMacVerification.patch
896
- )
897
- await authState.keys.set({ 'app-state-sync-version': { [name]: newState } })
898
- logger.info(`synced ${name} to v${newState.version}`)
899
- initialVersionMap[name] = newState.version
900
- Object.assign(globalMutationMap, mutationMap)
901
- }
902
- if (hasMorePatches) {
903
- logger.info(`${name} has more patches...`)
904
- } else {
905
-
906
- collectionsToHandle.delete(name)
907
- }
908
- } catch (error) {
909
- attemptsMap[name] = (attemptsMap[name] || 0) + 1
910
- const logData = {
911
- name,
912
- attempt: attemptsMap[name],
913
- version: states[name].version,
914
- statusCode: error.output?.statusCode,
915
- errorType: error.name,
916
- error: error.stack
917
- }
918
- if ((0, Utils_1.isMissingKeyError)(error) && attemptsMap[name] >= Utils_1.MAX_SYNC_ATTEMPTS) {
919
- logger.warn(
920
- logData,
921
- `${name} blocked on missing key from v${states[name].version}, parking after ${attemptsMap[name]} attempts`
922
- )
923
- blockedCollections.add(name)
924
- collectionsToHandle.delete(name)
925
- } else if ((0, Utils_1.isMissingKeyError)(error)) {
926
- logger.info(
927
- logData,
928
- `${name} blocked on missing key from v${states[name].version}, retrying with snapshot`
929
- )
930
- forceSnapshotCollections.add(name)
931
- } else if ((0, Utils_1.isAppStateSyncIrrecoverable)(error, attemptsMap[name])) {
932
- logger.warn(logData, `failed to sync ${name} from v${states[name].version}, giving up`)
933
- collectionsToHandle.delete(name)
934
- } else {
935
- logger.info(logData, `failed to sync ${name} from v${states[name].version}, forcing snapshot retry`)
936
- forceSnapshotCollections.add(name)
937
- }
938
- }
939
- }
940
- }
941
- }, authState?.creds?.me?.id || 'resync-app-state')
942
- const { onMutation } = newAppStateChunkHandler(isInitialSync)
943
- for (const key in globalMutationMap) {
944
- onMutation(globalMutationMap[key])
945
- }
946
- })
947
-
948
- const profilePictureUrl = async (jid, type = 'preview', timeoutMs) => {
949
-
950
-
951
- const picAttrs = { type, query: 'url' }
952
- const baseContent = [{ tag: 'picture', attrs: picAttrs }]
953
-
954
-
955
-
956
- const normalizedJid = (0, WABinary_1.jidNormalizedUser)(jid)
957
- const isUserJid = (0, WABinary_1.isPnUser)(normalizedJid) || (0, WABinary_1.isLidUser)(normalizedJid)
958
- const me = authState.creds.me
959
- const isSelf =
960
- me &&
961
- (normalizedJid === (0, WABinary_1.jidNormalizedUser)(me.id) ||
962
- (me.lid && normalizedJid === (0, WABinary_1.jidNormalizedUser)(me.lid)))
963
- let content = baseContent
964
- if (serverProps.profilePicPrivacyToken && isUserJid && !isSelf) {
965
- content = await (0, tc_token_utils_1.buildTcTokenFromJid)({
966
- authState,
967
- jid: normalizedJid,
968
- baseContent,
969
- getLIDForPN
970
- })
971
- }
972
- jid = (0, WABinary_1.jidNormalizedUser)(jid)
973
- const result = await query(
974
- {
975
- tag: 'iq',
976
- attrs: {
977
- target: jid,
978
- to: WABinary_1.S_WHATSAPP_NET,
979
- type: 'get',
980
- xmlns: 'w:profile:picture'
981
- },
982
- content
983
- },
984
- timeoutMs
985
- )
986
- const child = (0, WABinary_1.getBinaryNodeChild)(result, 'picture')
987
- return child?.attrs?.url
988
- }
989
- const createCallLink = async (type, event, timeoutMs) => {
990
- const result = await query(
991
- {
992
- tag: 'call',
993
- attrs: {
994
- id: generateMessageTag(),
995
- to: '@call'
996
- },
997
- content: [
998
- {
999
- tag: 'link_create',
1000
- attrs: { media: type },
1001
- content: event ? [{ tag: 'event', attrs: { start_time: String(event.startTime) } }] : undefined
1002
- }
1003
- ]
1004
- },
1005
- timeoutMs
1006
- )
1007
- const child = (0, WABinary_1.getBinaryNodeChild)(result, 'link_create')
1008
- return child?.attrs?.token
1009
- }
1010
-
1011
- const toggleCallLinkWaitingRoom = async (linkToken, enabled, media = 'audio') => {
1012
- const result = await query({
1013
- tag: 'call',
1014
- attrs: { id: generateMessageTag(), to: '@call' },
1015
- content: [
1016
- {
1017
- tag: 'waiting_room_toggle',
1018
- attrs: { enabled: enabled ? '1' : '0', 'link-token': linkToken, media }
1019
- }
1020
- ]
1021
- })
1022
- const child = (0, WABinary_1.getBinaryNodeChild)(result, 'waiting_room_toggle')
1023
- return child?.attrs
1024
- }
1025
- const sendPresenceUpdate = async (type, toJid) => {
1026
- const me = authState.creds.me
1027
- const isAvailableType = type === 'available'
1028
- if (isAvailableType || type === 'unavailable') {
1029
- if (!me.name) {
1030
- logger.warn('no name present, ignoring presence update request...')
1031
- return
1032
- }
1033
- ev.emit('connection.update', { isOnline: isAvailableType })
1034
- if (isAvailableType) {
1035
- void sendUnifiedSession()
1036
- }
1037
- await sendNode({
1038
- tag: 'presence',
1039
- attrs: {
1040
- name: me.name.replace(/@/g, ''),
1041
- type
1042
- }
1043
- })
1044
- } else {
1045
- const { server } = (0, WABinary_1.jidDecode)(toJid)
1046
- const isLid = server === 'lid'
1047
- await sendNode({
1048
- tag: 'chatstate',
1049
- attrs: {
1050
- from: isLid ? me.lid : me.id,
1051
- to: toJid
1052
- },
1053
- content: [
1054
- {
1055
- tag: type === 'recording' ? 'composing' : type,
1056
- attrs: type === 'recording' ? { media: 'audio' } : {}
1057
- }
1058
- ]
1059
- })
1060
- }
1061
- }
1062
-
1063
- const storePrivacyTokens = async entries => {
1064
- if (!entries?.length) return
1065
- const write = {}
1066
- for (const { jid, privacyToken, privacyModeTs } of entries) {
1067
- if (!jid || !privacyToken?.length) continue
1068
- write[jid] = {
1069
- token: Buffer.isBuffer(privacyToken) ? privacyToken : Buffer.from(privacyToken),
1070
- ts: String(privacyModeTs || '')
1071
- }
1072
- }
1073
- if (Object.keys(write).length) {
1074
- await authState.keys.set({ 'privacy-token': write })
1075
- }
1076
- }
1077
-
1078
-
1079
- const executeUSyncQuery = async usyncQuery => {
1080
- const result = await sock.executeUSyncQuery(usyncQuery)
1081
- if (!result) return result
1082
-
1083
-
1084
- const privacyEntries = []
1085
- const blockedContacts = []
1086
- for (const entry of [...(result.list || []), ...(result.sideList || [])]) {
1087
- if (entry.privacy?.token) {
1088
- privacyEntries.push({
1089
- jid: entry.id,
1090
- privacyToken: entry.privacy.token,
1091
- privacyModeTs: entry.privacy.modeTs
1092
- })
1093
- }
1094
-
1095
- if (entry.isBlockedByContact) {
1096
- blockedContacts.push({ id: entry.id, isBlockedByContact: true })
1097
- }
1098
- }
1099
- if (privacyEntries.length) {
1100
- storePrivacyTokens(privacyEntries).catch(err => logger.warn({ err }, 'failed to store privacy tokens from usync'))
1101
- }
1102
- if (blockedContacts.length) {
1103
- ev.emit('contacts.update', blockedContacts)
1104
- }
1105
- return result
1106
- }
1107
-
1108
-
1109
- const presenceSubscribe = async (toJid, { presenceType, presenceName, groupJid } = {}) => {
1110
-
1111
- const normalizedToJid = (0, WABinary_1.jidNormalizedUser)(toJid)
1112
- const isUserJid = (0, WABinary_1.isPnUser)(normalizedToJid) || (0, WABinary_1.isLidUser)(normalizedToJid)
1113
-
1114
-
1115
- const presenceAttrs = {
1116
- to: toJid,
1117
- id: generateMessageTag(),
1118
- type: 'subscribe'
1119
- }
1120
-
1121
-
1122
- const presenceContent = []
1123
-
1124
-
1125
- if (isUserJid) {
1126
- try {
1127
- const storageJid = await (0, tc_token_utils_1.resolveTcTokenJid)(normalizedToJid, getLIDForPN)
1128
- const tcTokenData = await authState.keys.get('tctoken', [storageJid])
1129
- const entry = tcTokenData?.[storageJid]
1130
- const tcTokenBuffer = entry?.token
1131
- if (tcTokenBuffer?.length && !(0, tc_token_utils_1.isTcTokenExpired)(entry?.timestamp)) {
1132
- presenceAttrs.tc_token = tcTokenBuffer.toString('base64')
1133
- }
1134
- } catch (e) {
1135
-
1136
- }
1137
-
1138
-
1139
-
1140
-
1141
- try {
1142
- const privTokenData = await authState.keys.get('privacy-token', [normalizedToJid])
1143
- const privEntry = privTokenData?.[normalizedToJid]
1144
- if (privEntry?.token?.length) {
1145
- const privTokenAttrs = {}
1146
- if (privEntry.ts) privTokenAttrs.t = privEntry.ts
1147
- presenceContent.push({
1148
- tag: 'privacy_token',
1149
- attrs: privTokenAttrs,
1150
- content: privEntry.token
1151
- })
1152
- }
1153
- } catch (e) {
1154
-
1155
- }
1156
- }
1157
-
1158
-
1159
- if (presenceType) {
1160
- presenceAttrs.presenceType = presenceType
1161
- }
1162
- if (presenceName) {
1163
- presenceAttrs.presenceName = presenceName
1164
- }
1165
-
1166
-
1167
- if (groupJid) {
1168
- presenceAttrs.context = 'group'
1169
- presenceAttrs.group_jid = (0, WABinary_1.jidNormalizedUser)(groupJid)
1170
- }
1171
-
1172
- return sendNode({
1173
- tag: 'presence',
1174
- attrs: presenceAttrs,
1175
- content: presenceContent.length ? presenceContent : undefined
1176
- })
1177
- }
1178
- const handlePresenceUpdate = ({ tag, attrs, content }) => {
1179
- let presence
1180
- const jid = attrs.from
1181
- const participant = attrs.participant || attrs.from
1182
- if (shouldIgnoreJid(jid) && jid !== WABinary_1.S_WHATSAPP_NET) {
1183
- return
1184
- }
1185
- if (tag === 'presence') {
1186
- presence = {
1187
- lastKnownPresence: attrs.type === 'unavailable' ? 'unavailable' : 'available',
1188
- lastSeen: attrs.last && attrs.last !== 'deny' ? +attrs.last : undefined
1189
- }
1190
- } else if (Array.isArray(content)) {
1191
- const [firstChild] = content
1192
- let type = firstChild.tag
1193
- if (type === 'paused') {
1194
- type = 'available'
1195
- }
1196
- if (firstChild.attrs?.media === 'audio') {
1197
- type = 'recording'
1198
- }
1199
- presence = { lastKnownPresence: type }
1200
- } else {
1201
- logger.error({ tag, attrs, content }, 'recv invalid presence node')
1202
- }
1203
- if (presence) {
1204
- ev.emit('presence.update', { id: jid, presences: { [participant]: presence } })
1205
- }
1206
- }
1207
- const appPatch = async patchCreate => {
1208
- const name = patchCreate.type
1209
- const myAppStateKeyId = authState.creds.myAppStateKeyId
1210
- if (!myAppStateKeyId) {
1211
- throw new boom_1.Boom('App state key not present!', { statusCode: 400 })
1212
- }
1213
- let initial
1214
- let encodeResult
1215
- await appStatePatchMutex.mutex(async () => {
1216
- await authState.keys.transaction(async () => {
1217
- logger.debug({ patch: patchCreate }, 'applying app patch')
1218
- await resyncAppState([name], false)
1219
- const { [name]: currentSyncVersion } = await authState.keys.get('app-state-sync-version', [name])
1220
- initial = currentSyncVersion || (0, Utils_1.newLTHashState)()
1221
- encodeResult = await (0, Utils_1.encodeSyncdPatch)(patchCreate, myAppStateKeyId, initial, getAppStateSyncKey)
1222
- const { patch, state } = encodeResult
1223
- const node = {
1224
- tag: 'iq',
1225
- attrs: {
1226
- to: WABinary_1.S_WHATSAPP_NET,
1227
- type: 'set',
1228
- xmlns: 'w:sync:app:state'
1229
- },
1230
- content: [
1231
- {
1232
- tag: 'sync',
1233
- attrs: {},
1234
- content: [
1235
- {
1236
- tag: 'collection',
1237
- attrs: {
1238
- name,
1239
- version: (state.version - 1).toString(),
1240
- return_snapshot: 'false'
1241
- },
1242
- content: [
1243
- {
1244
- tag: 'patch',
1245
- attrs: {},
1246
- content: index_js_1.proto.SyncdPatch.encode(patch).finish()
1247
- }
1248
- ]
1249
- }
1250
- ]
1251
- }
1252
- ]
1253
- }
1254
- await query(node)
1255
- await authState.keys.set({ 'app-state-sync-version': { [name]: state } })
1256
- }, authState?.creds?.me?.id || 'app-patch')
1257
- })
1258
- if (config.emitOwnEvents) {
1259
- const { onMutation } = newAppStateChunkHandler(false)
1260
- const { mutationMap } = await (0, Utils_1.decodePatches)(
1261
- name,
1262
- [{ ...encodeResult.patch, version: { version: encodeResult.state.version } }],
1263
- initial,
1264
- getAppStateSyncKey,
1265
- config.options,
1266
- undefined,
1267
- logger
1268
- )
1269
- for (const key in mutationMap) {
1270
- onMutation(mutationMap[key])
1271
- }
1272
- }
1273
- }
1274
-
1275
- const fetchProps = async () => {
1276
-
1277
- const resultNode = await query({
1278
- tag: 'iq',
1279
- attrs: {
1280
- to: WABinary_1.S_WHATSAPP_NET,
1281
- xmlns: 'w',
1282
- type: 'get'
1283
- },
1284
- content: [
1285
- {
1286
- tag: 'props',
1287
- attrs: {
1288
- protocol: '2',
1289
- hash: authState?.creds?.lastPropHash || ''
1290
- }
1291
- }
1292
- ]
1293
- })
1294
- const propsNode = (0, WABinary_1.getBinaryNodeChild)(resultNode, 'props')
1295
- let props = {}
1296
- if (propsNode) {
1297
- if (propsNode.attrs?.hash) {
1298
-
1299
- authState.creds.lastPropHash = propsNode?.attrs?.hash
1300
- ev.emit('creds.update', authState.creds)
1301
- }
1302
- props = (0, WABinary_1.reduceBinaryNodeToDictionary)(propsNode, 'prop')
1303
- }
1304
-
1305
- const privacyTokenProp = props['10518'] ?? props['privacy_token_sending_on_all_1_on_1_messages']
1306
- if (privacyTokenProp !== undefined) {
1307
- serverProps.privacyTokenOn1to1 = privacyTokenProp === 'true' || privacyTokenProp === '1'
1308
- }
1309
- const profilePicProp = props['9666'] ?? props['profile_scraping_privacy_token_in_photo_iq']
1310
- if (profilePicProp !== undefined) {
1311
- serverProps.profilePicPrivacyToken = profilePicProp === 'true' || profilePicProp === '1'
1312
- }
1313
- const lidIssueProp = props['14303'] ?? props['lid_trusted_token_issue_to_lid']
1314
- if (lidIssueProp !== undefined) {
1315
- serverProps.lidTrustedTokenIssueToLid = lidIssueProp === 'true' || lidIssueProp === '1'
1316
- }
1317
- logger.debug({ serverProps }, 'fetched props')
1318
- return props
1319
- }
1320
-
1321
- const chatModify = (mod, jid) => {
1322
- const patch = (0, Utils_1.chatModificationToAppPatch)(mod, jid)
1323
- return appPatch(patch)
1324
- }
1325
-
1326
- const updateDisableLinkPreviewsPrivacy = isPreviewsDisabled => {
1327
- return chatModify(
1328
- {
1329
- disableLinkPreviews: { isPreviewsDisabled }
1330
- },
1331
- ''
1332
- )
1333
- }
1334
-
1335
- const star = (jid, messages, star) => {
1336
- return chatModify(
1337
- {
1338
- star: {
1339
- messages,
1340
- star
1341
- }
1342
- },
1343
- jid
1344
- )
1345
- }
1346
-
1347
- const addOrEditContact = (jid, contact) => {
1348
- return chatModify(
1349
- {
1350
- contact
1351
- },
1352
- jid
1353
- )
1354
- }
1355
-
1356
- const removeContact = jid => {
1357
- return chatModify(
1358
- {
1359
- contact: null
1360
- },
1361
- jid
1362
- )
1363
- }
1364
-
1365
- const addLabel = (jid, labels) => {
1366
- return chatModify(
1367
- {
1368
- addLabel: {
1369
- ...labels
1370
- }
1371
- },
1372
- jid
1373
- )
1374
- }
1375
-
1376
- const addChatLabel = (jid, labelId) => {
1377
- return chatModify(
1378
- {
1379
- addChatLabel: {
1380
- labelId
1381
- }
1382
- },
1383
- jid
1384
- )
1385
- }
1386
-
1387
- const removeChatLabel = (jid, labelId) => {
1388
- return chatModify(
1389
- {
1390
- removeChatLabel: {
1391
- labelId
1392
- }
1393
- },
1394
- jid
1395
- )
1396
- }
1397
-
1398
- const addMessageLabel = (jid, messageId, labelId) => {
1399
- return chatModify(
1400
- {
1401
- addMessageLabel: {
1402
- messageId,
1403
- labelId
1404
- }
1405
- },
1406
- jid
1407
- )
1408
- }
1409
-
1410
- const removeMessageLabel = (jid, messageId, labelId) => {
1411
- return chatModify(
1412
- {
1413
- removeMessageLabel: {
1414
- messageId,
1415
- labelId
1416
- }
1417
- },
1418
- jid
1419
- )
1420
- }
1421
-
1422
- const addOrEditQuickReply = quickReply => {
1423
- return chatModify(
1424
- {
1425
- quickReply
1426
- },
1427
- ''
1428
- )
1429
- }
1430
-
1431
- const removeQuickReply = timestamp => {
1432
- return chatModify(
1433
- {
1434
- quickReply: { timestamp, deleted: true }
1435
- },
1436
- ''
1437
- )
1438
- }
1439
-
1440
- const renameAIThread = (jid, title) => {
1441
- return chatModify({ aiThreadRename: { title } }, jid)
1442
- }
1443
-
1444
- const pinThreadMessage = (jid, messageId, pinned = true) => {
1445
- return chatModify({ threadPin: { pinned, messageId } }, jid)
1446
- }
1447
-
1448
- const updatePrivateProcessingSetting = enabled => {
1449
- return chatModify({ privateProcessingSetting: enabled ? 'enabled' : 'disabled' }, '')
1450
- }
1451
-
1452
- const updateAIFeatures = (status = 'enabled', replyMode = 'suggestions') => {
1453
- const statusEnum =
1454
- require('../../WAProto/index.js').proto.SyncActionValue.MaibaAIFeaturesControlAction.MaibaAIFeatureStatus
1455
- const replyModeEnum =
1456
- require('../../WAProto/index.js').proto.SyncActionValue.MaibaAIFeaturesControlAction.MaibaAIReplyMode
1457
- const statusMap = {
1458
- enabled: statusEnum.ENABLED,
1459
- enabled_has_learning: statusEnum.ENABLED_HAS_LEARNING,
1460
- disabled: statusEnum.DISABLED
1461
- }
1462
- const replyModeMap = {
1463
- muted: replyModeEnum.MUTED,
1464
- ai_agent: replyModeEnum.AI_AGENT,
1465
- suggestions: replyModeEnum.SUGGESTIONS
1466
- }
1467
- return chatModify(
1468
- {
1469
- maibaAIFeatures: {
1470
- status: statusMap[status] ?? statusEnum.ENABLED,
1471
- replyMode: replyModeMap[replyMode] ?? replyModeEnum.SUGGESTIONS
1472
- }
1473
- },
1474
- ''
1475
- )
1476
- }
1477
-
1478
- const updateBioPrivacy = async value => {
1479
- await privacyQuery('about', value)
1480
- }
1481
-
1482
- const blockBot = async botJid => {
1483
- await query({
1484
- tag: 'iq',
1485
- attrs: {
1486
- xmlns: 'disappearing_mode',
1487
- to: WABinary_1.S_WHATSAPP_NET,
1488
- type: 'set'
1489
- },
1490
- content: [
1491
- {
1492
- tag: 'block',
1493
- attrs: { jid: botJid }
1494
- }
1495
- ]
1496
- })
1497
- }
1498
-
1499
- const unblockBot = async botJid => {
1500
- await updateBlockStatus(botJid, 'unblock')
1501
- }
1502
-
1503
- const muteContactStatus = (jid, muted = true) => {
1504
- return chatModify({ muteStatus: { muted } }, jid)
1505
- }
1506
-
1507
- const toggleFavorite = (jid, isFavorite = true) => {
1508
- return chatModify({ favorite: { isFavorite } }, jid)
1509
- }
1510
-
1511
- const reorderLabels = sortedLabelIds => {
1512
- return chatModify({ reorderLabel: { sortedLabelIds } }, '')
1513
- }
1514
-
1515
- const deleteCallLog = (callId, jid = '') => {
1516
- return chatModify({ deleteCallLog: { callId } }, jid)
1517
- }
1518
-
1519
- const setChatNote = (jid, note) => {
1520
- return chatModify({ noteEdit: { note } }, jid)
1521
- }
1522
-
1523
- const deleteChatNote = jid => {
1524
- return chatModify({ noteEdit: { note: '', deleted: true } }, jid)
1525
- }
1526
-
1527
- const markChatAsUnread = (jid, lastMessages) => {
1528
- return chatModify({ markAsUnread: true, lastMessages }, jid)
1529
- }
1530
-
1531
- const setChatEphemeral = (jid, duration) => {
1532
- return chatModify({ setChatEphemeral: duration }, jid)
1533
- }
1534
-
1535
- const silenceChat = (jid, silent = true, until = null) => {
1536
- return chatModify({ silenceChat: { silent, until } }, jid)
1537
- }
1538
-
1539
- const clearChat = (jid, lastMessages) => {
1540
- return chatModify({ clear: true, lastMessages }, jid)
1541
- }
1542
-
1543
- const pinChat = (jid, pinned = true) => {
1544
- return chatModify({ pin: { pinned } }, jid)
1545
- }
1546
-
1547
- const starMessages = (jid, messageIds, starred = true) => {
1548
- return chatModify({ star: { messages: messageIds, star: starred } }, jid)
1549
- }
1550
-
1551
- const setQuickReply = (text, shortcut) => {
1552
- return chatModify({ quickReply: { text, shortcut } }, '')
1553
- }
1554
-
1555
- const fetchBotProfiles = async jids => {
1556
- const { USyncQuery, USyncUser, USyncBotProfileProtocol } = require('../WAUSync')
1557
- const q = new USyncQuery()
1558
- q.protocols.push(new USyncBotProfileProtocol())
1559
- for (const jid of jids) {
1560
- q.withUser(new USyncUser().withId(jid))
1561
- }
1562
- const result = await executeUSyncQuery(q)
1563
- return result?.list || []
1564
- }
1565
-
1566
- const updateChatLock = (jid, locked) => {
1567
- return chatModify({ chatLock: { locked } }, jid)
1568
- }
1569
-
1570
- const updateChatWallpaper = (jid, wallpaper) => {
1571
- if (!wallpaper) {
1572
- return chatModify({ wallpaper: { remove: true } }, jid)
1573
- }
1574
- return chatModify({ wallpaper }, jid)
1575
- }
1576
-
1577
- const updateChatMediaVisibility = (jid, visibility) => {
1578
- return chatModify({ mediaVisibility: visibility }, jid)
1579
- }
1580
-
1581
- const getBotProfile = async botJid => {
1582
- const resp = await query({
1583
- tag: 'iq',
1584
- attrs: {
1585
- xmlns: 'bot',
1586
- to: WABinary_1.S_WHATSAPP_NET,
1587
- type: 'get'
1588
- },
1589
- content: [
1590
- {
1591
- tag: 'bot',
1592
- attrs: { v: '2', jid: botJid }
1593
- }
1594
- ]
1595
- })
1596
- const botNode = (0, WABinary_1.getBinaryNodeChild)(resp, 'bot')
1597
- if (!botNode) return null
1598
- return {
1599
- jid: botNode.attrs.jid,
1600
- personaId: botNode.attrs['persona_id'],
1601
- name: botNode.attrs.name,
1602
- description: botNode.attrs.description
1603
- }
1604
- }
1605
-
1606
- const fetchABProps = async (protocol = '1', hash = '', refreshId = null, group = null) => {
1607
- const propAttrs =
1608
- group != null
1609
- ? { group: String(group) }
1610
- : {
1611
- protocol,
1612
- ...(hash ? { hash } : {}),
1613
- ...(refreshId != null ? { refresh_id: String(refreshId) } : {})
1614
- }
1615
- const result = await query({
1616
- tag: 'iq',
1617
- attrs: { to: WABinary_1.S_WHATSAPP_NET, xmlns: 'abt', type: 'get' },
1618
- content: [{ tag: 'props', attrs: propAttrs }]
1619
- })
1620
- const propsNode = (0, WABinary_1.getBinaryNodeChild)(result, 'props')
1621
- if (!propsNode) return {}
1622
- return (0, WABinary_1.reduceBinaryNodeToDictionary)(propsNode, 'prop')
1623
- }
1624
-
1625
- const removeCompanionDevice = async (jid, reason = 'user_initiated') => {
1626
- await query({
1627
- tag: 'iq',
1628
- attrs: { to: WABinary_1.S_WHATSAPP_NET, xmlns: 'md', type: 'set' },
1629
- content: [
1630
- {
1631
- tag: 'remove-companion-device',
1632
- attrs: { jid, reason }
1633
- }
1634
- ]
1635
- })
1636
- }
1637
-
1638
- const updateKeyIndexList = async (ts, content) => {
1639
- await query({
1640
- tag: 'iq',
1641
- attrs: { to: WABinary_1.S_WHATSAPP_NET, xmlns: 'md', type: 'set' },
1642
- content: [
1643
- {
1644
- tag: 'key-index-list',
1645
- attrs: { ts: String(ts) },
1646
- content
1647
- }
1648
- ]
1649
- })
1650
- }
1651
-
1652
- const sendKeyIndexList = async () => {
1653
- const account = authState.creds.account
1654
- const signedIdentityKey = authState.creds.signedIdentityKey
1655
- if (!account?.details || !signedIdentityKey?.private) {
1656
- logger.debug('no ADV account / signed identity key, skipping key-index-list')
1657
- return
1658
- }
1659
- const deviceIdentity = index_js_1.proto.ADVDeviceIdentity.decode(account.details)
1660
- const keyIndex = deviceIdentity.keyIndex || 0
1661
- const accountType = deviceIdentity.accountType ?? index_js_1.proto.ADVEncryptionType.E2EE
1662
- const isHosted = accountType === index_js_1.proto.ADVEncryptionType.HOSTED
1663
- const ts = Math.floor(Date.now() / 1000)
1664
- const details = index_js_1.proto.ADVKeyIndexList.encode({
1665
- rawId: deviceIdentity.rawId || 0,
1666
- timestamp: ts,
1667
- currentIndex: keyIndex,
1668
- validIndexes: [keyIndex],
1669
- accountType
1670
- }).finish()
1671
- const sigPrefix = isHosted
1672
- ? Defaults_1.WA_ADV_HOSTED_KEY_INDEX_LIST_SIG_PREFIX
1673
- : Defaults_1.WA_ADV_KEY_INDEX_LIST_SIG_PREFIX
1674
- const accountSignature = Utils_1.Curve.sign(signedIdentityKey.private, Buffer.concat([sigPrefix, details]))
1675
- const signedKeyIndexList = { details, accountSignature }
1676
- if (isHosted && account.accountSignatureKey?.length) {
1677
- signedKeyIndexList.accountSignatureKey = account.accountSignatureKey
1678
- }
1679
- const content = index_js_1.proto.ADVSignedKeyIndexList.encode(signedKeyIndexList).finish()
1680
- await updateKeyIndexList(ts, Buffer.from(content))
1681
- logger.info({ ts, keyIndex }, 'sent key-index-list')
1682
- }
1683
-
1684
- const fetchMediaConn = async (lastId = null) => {
1685
- const attrs = {}
1686
- if (lastId != null) attrs.last_id = String(lastId)
1687
- const result = await query({
1688
- tag: 'iq',
1689
- attrs: { to: WABinary_1.S_WHATSAPP_NET, xmlns: 'w:m', type: 'set' },
1690
- content: [{ tag: 'media_conn', attrs }]
1691
- })
1692
- return (0, WABinary_1.getBinaryNodeChild)(result, 'media_conn') || null
1693
- }
1694
-
1695
- const deleteBroadcastList = async listId => {
1696
- await query({
1697
- tag: 'iq',
1698
- attrs: { to: WABinary_1.S_WHATSAPP_NET, xmlns: 'w:b', type: 'set' },
1699
- content: [
1700
- {
1701
- tag: 'delete',
1702
- attrs: {},
1703
- content: [{ tag: 'list', attrs: { id: String(listId) } }]
1704
- }
1705
- ]
1706
- })
1707
- }
1708
-
1709
- const fetchQRCode = async (code, addressingMode = null) => {
1710
- const attrs = { code }
1711
- if (addressingMode) attrs.addressing_mode = addressingMode
1712
- const result = await query({
1713
- tag: 'iq',
1714
- attrs: { to: WABinary_1.S_WHATSAPP_NET, xmlns: 'w:qr', type: 'get' },
1715
- content: [{ tag: 'qr', attrs }]
1716
- })
1717
- return (0, WABinary_1.getBinaryNodeChild)(result, 'qr') || null
1718
- }
1719
-
1720
- const confirmDeviceLogout = async (id, approve = true) => {
1721
- await query({
1722
- tag: 'iq',
1723
- attrs: {
1724
-
1725
- id: String(id),
1726
- to: WABinary_1.S_WHATSAPP_NET,
1727
- xmlns: 'w:account_defence',
1728
- type: 'set',
1729
- smax_id: '87'
1730
- },
1731
- content: [
1732
- {
1733
- tag: 'device_logout',
1734
- attrs: { approve: approve ? 'true' : 'false', id: String(id) }
1735
- }
1736
- ]
1737
- })
1738
- }
1739
-
1740
- const executeInitQueries = async () => {
1741
-
1742
-
1743
- const shouldInitInterop = authState.creds.interopEnabled !== false
1744
- const [, , , abProps] = await Promise.all([
1745
- fetchProps(),
1746
- fetchBlocklist(),
1747
- fetchPrivacySettings(),
1748
- fetchABProps(),
1749
- ...(shouldInitInterop ? [initInterop()] : [])
1750
- ])
1751
- const INTEROP_FLAGS = ['stella_interop_enabled', 'stella_ios_enabled']
1752
- for (const flag of INTEROP_FLAGS) {
1753
- if (flag in abProps) {
1754
- const enabled = abProps[flag] === 'true' || abProps[flag] === '1'
1755
- ev.emit('interop.feature-update', { feature: flag, enabled })
1756
- }
1757
- }
1758
-
1759
- const abCredsUpdate = {}
1760
- if ('stella_interop_enabled' in abProps) {
1761
- abCredsUpdate.interopEnabled =
1762
- abProps['stella_interop_enabled'] === 'true' || abProps['stella_interop_enabled'] === '1'
1763
- }
1764
- if ('stella_ios_enabled' in abProps) {
1765
- abCredsUpdate.interopIosEnabled =
1766
- abProps['stella_ios_enabled'] === 'true' || abProps['stella_ios_enabled'] === '1'
1767
- }
1768
- if ('md_privacy_v2' in abProps) {
1769
- abCredsUpdate.mdPrivacyV2 = abProps['md_privacy_v2'] === 'true' || abProps['md_privacy_v2'] === '1'
1770
- }
1771
-
1772
- const MEDIA_AB_PROPS = [
1773
- 'hd_image_dual_upload',
1774
- 'hd_video_dual_upload',
1775
- 'hevc_video_dual_upload',
1776
- 'partial_pjpeg_enabled',
1777
- 'multi_scan_pjpeg',
1778
- 'media_poll'
1779
- ]
1780
- const mediaAbProps = {}
1781
- for (const prop of MEDIA_AB_PROPS) {
1782
- if (prop in abProps) {
1783
- mediaAbProps[prop] = abProps[prop] === 'true' || abProps[prop] === '1'
1784
- }
1785
- }
1786
- if (Object.keys(mediaAbProps).length) {
1787
- abCredsUpdate.mediaAbProps = { ...(authState.creds.mediaAbProps || {}), ...mediaAbProps }
1788
- }
1789
- if (Object.keys(abCredsUpdate).length) {
1790
- ev.emit('creds.update', abCredsUpdate)
1791
- }
1792
- }
1793
- const upsertMessage = ev.createBufferedFunction(async (msg, type) => {
1794
-
1795
- if (msg.newsletter && msg.newsletter_server_id && msg.key?.id) {
1796
- _nlServerIdCache.set(msg.key.id, msg.newsletter_server_id)
1797
- }
1798
-
1799
- if (msg.message) {
1800
- const ci = Object.values(msg.message).find(v => v?.contextInfo)?.contextInfo
1801
- if (ci?.stanzaId && (0, WABinary_1.isJidNewsletter)(ci.remoteJid)) {
1802
- const sid = _nlServerIdCache.get(ci.stanzaId)
1803
- if (sid != null) msg.quotedNewsletterServerId = sid
1804
- }
1805
- }
1806
- if (msg.message?.secretEncryptedMessage || msg.message?.editedMessage?.message?.secretEncryptedMessage) {
1807
-
1808
-
1809
- await unwrapSecretEncryptedMessage(msg, { creds: authState.creds, getMessage, logger })
1810
- }
1811
- ev.emit('messages.upsert', { messages: [msg], type })
1812
- if (!!msg.pushName) {
1813
- let jid = msg.key.fromMe ? authState.creds.me.id : msg.key.participant || msg.key.remoteJid
1814
- jid = (0, WABinary_1.jidNormalizedUser)(jid)
1815
- if (!msg.key.fromMe) {
1816
- ev.emit('contacts.update', [{ id: jid, notify: msg.pushName, verifiedName: msg.verifiedBizName }])
1817
- }
1818
-
1819
- if (msg.key.fromMe && msg.pushName && authState.creds.me?.name !== msg.pushName) {
1820
- ev.emit('creds.update', { me: { ...authState.creds.me, name: msg.pushName } })
1821
- }
1822
- }
1823
- const historyMsg = (0, Utils_1.getHistoryMsg)(msg.message)
1824
- const shouldProcessHistoryMsg = historyMsg
1825
- ? shouldSyncHistoryMessage(historyMsg) && Defaults_1.PROCESSABLE_HISTORY_TYPES.includes(historyMsg.syncType)
1826
- : false
1827
- if (historyMsg && shouldProcessHistoryMsg) {
1828
- const syncType = historyMsg.syncType
1829
-
1830
- if (
1831
- syncType === index_js_1.proto.HistorySync.HistorySyncType.INITIAL_BOOTSTRAP &&
1832
- !historySyncStatus.initialBootstrapComplete
1833
- ) {
1834
- historySyncStatus.initialBootstrapComplete = true
1835
- ev.emit('messaging-history.status', {
1836
- syncType,
1837
- status: 'complete',
1838
- explicit: true
1839
- })
1840
- }
1841
-
1842
- if (
1843
- syncType === index_js_1.proto.HistorySync.HistorySyncType.RECENT &&
1844
- historyMsg.progress === 100 &&
1845
- !historySyncStatus.recentSyncComplete
1846
- ) {
1847
- historySyncStatus.recentSyncComplete = true
1848
- clearTimeout(historySyncPausedTimeout)
1849
- historySyncPausedTimeout = undefined
1850
- ev.emit('messaging-history.status', {
1851
- syncType,
1852
- status: 'complete',
1853
- explicit: true
1854
- })
1855
- }
1856
-
1857
- if (syncType === index_js_1.proto.HistorySync.HistorySyncType.RECENT && !historySyncStatus.recentSyncComplete) {
1858
- clearTimeout(historySyncPausedTimeout)
1859
- historySyncPausedTimeout = setTimeout(() => {
1860
- if (!historySyncStatus.recentSyncComplete) {
1861
- historySyncStatus.recentSyncComplete = true
1862
- ev.emit('messaging-history.status', {
1863
- syncType: index_js_1.proto.HistorySync.HistorySyncType.RECENT,
1864
- status: 'paused',
1865
- explicit: false
1866
- })
1867
- }
1868
- historySyncPausedTimeout = undefined
1869
- }, Defaults_1.HISTORY_SYNC_PAUSED_TIMEOUT_MS)
1870
- }
1871
- }
1872
-
1873
- if (historyMsg && syncState === State_1.SyncState.AwaitingInitialSync) {
1874
- if (awaitingSyncTimeout) {
1875
- clearTimeout(awaitingSyncTimeout)
1876
- awaitingSyncTimeout = undefined
1877
- }
1878
- if (shouldProcessHistoryMsg) {
1879
- syncState = State_1.SyncState.Syncing
1880
- logger.info('Transitioned to Syncing state')
1881
-
1882
- } else {
1883
- syncState = State_1.SyncState.Online
1884
- logger.info('History sync skipped, transitioning to Online state and flushing buffer')
1885
- ev.flush()
1886
- }
1887
- }
1888
- const doAppStateSync = async () => {
1889
- if (syncState === State_1.SyncState.Syncing) {
1890
-
1891
- blockedCollections.clear()
1892
- logger.info('Doing app state sync')
1893
- await resyncAppState(Types_1.ALL_WA_PATCH_NAMES, true)
1894
-
1895
- syncState = State_1.SyncState.Online
1896
- logger.info('App state sync complete, transitioning to Online state and flushing buffer')
1897
- ev.flush()
1898
- const accountSyncCounter = (authState.creds.accountSyncCounter || 0) + 1
1899
- ev.emit('creds.update', { accountSyncCounter })
1900
- }
1901
- }
1902
- await Promise.all([
1903
- (async () => {
1904
- if (shouldProcessHistoryMsg) {
1905
- await doAppStateSync()
1906
- }
1907
- })(),
1908
- (0, process_message_1.default)(msg, {
1909
- signalRepository,
1910
- shouldProcessHistoryMsg,
1911
- placeholderResendCache,
1912
- ev,
1913
- creds: authState.creds,
1914
- keyStore: authState.keys,
1915
- logger,
1916
- options: config.options,
1917
- getMessage
1918
- })
1919
- ])
1920
-
1921
- if (msg.message?.protocolMessage?.appStateSyncKeyShare && syncState === State_1.SyncState.Syncing) {
1922
- logger.info('App state sync key arrived, triggering app state sync')
1923
- await doAppStateSync()
1924
- }
1925
- })
1926
- ws.on('CB:presence', handlePresenceUpdate)
1927
- ws.on('CB:chatstate', handlePresenceUpdate)
1928
-
1929
-
1930
-
1931
- ws.on('CB:iq,xmlns:w:account_defence', async node => {
1932
- const deviceLogout = (0, WABinary_1.getBinaryNodeChild)(node, 'device_logout')
1933
- if (!deviceLogout) return
1934
- const id = node.attrs.id
1935
- logger.info({ id }, 'received account_defence device_logout challenge, approving')
1936
- try {
1937
- await confirmDeviceLogout(id, true)
1938
- } catch (error) {
1939
- onUnexpectedError(error, 'account_defence device_logout approve')
1940
- }
1941
- })
1942
- ws.on('CB:ib,,dirty', async node => {
1943
- const { attrs } = (0, WABinary_1.getBinaryNodeChild)(node, 'dirty')
1944
- const type = attrs.type
1945
- switch (type) {
1946
- case 'account_sync':
1947
- if (attrs.timestamp) {
1948
- let { lastAccountSyncTimestamp } = authState.creds
1949
- if (lastAccountSyncTimestamp) {
1950
- await cleanDirtyBits('account_sync', lastAccountSyncTimestamp)
1951
- }
1952
- lastAccountSyncTimestamp = +attrs.timestamp
1953
- ev.emit('creds.update', { lastAccountSyncTimestamp })
1954
- }
1955
- break
1956
- case 'groups':
1957
-
1958
- break
1959
- default:
1960
- logger.info({ node }, 'received unknown sync')
1961
- break
1962
- }
1963
- })
1964
- ev.on('connection.update', ({ connection, receivedPendingNotifications }) => {
1965
- if (connection === 'close') {
1966
- blockedCollections.clear()
1967
- clearTimeout(historySyncPausedTimeout)
1968
- historySyncPausedTimeout = undefined
1969
- }
1970
- if (connection === 'open') {
1971
- if (fireInitQueries) {
1972
- executeInitQueries().catch(error => onUnexpectedError(error, 'init queries'))
1973
- }
1974
- sendPresenceUpdate(markOnlineOnConnect ? 'available' : 'unavailable').catch(error =>
1975
- onUnexpectedError(error, 'presence update requests')
1976
- )
1977
-
1978
-
1979
- sendKeyIndexList().catch(error => onUnexpectedError(error, 'send key-index-list'))
1980
- }
1981
- if (!receivedPendingNotifications || syncState !== State_1.SyncState.Connecting) {
1982
- return
1983
- }
1984
- historySyncStatus.initialBootstrapComplete = false
1985
- historySyncStatus.recentSyncComplete = false
1986
- clearTimeout(historySyncPausedTimeout)
1987
- historySyncPausedTimeout = undefined
1988
- syncState = State_1.SyncState.AwaitingInitialSync
1989
- logger.info('Connection is now AwaitingInitialSync, buffering events')
1990
- ev.buffer()
1991
- const willSyncHistory = shouldSyncHistoryMessage(
1992
- index_js_1.proto.Message.HistorySyncNotification.create({
1993
- syncType: index_js_1.proto.HistorySync.HistorySyncType.RECENT
1994
- })
1995
- )
1996
- if (!willSyncHistory) {
1997
- logger.info('History sync is disabled by config, not waiting for notification. Transitioning to Online.')
1998
- syncState = State_1.SyncState.Online
1999
- setTimeout(() => ev.flush(), 0)
2000
- return
2001
- }
2002
-
2003
-
2004
-
2005
- if (authState.creds.accountSyncCounter > 0) {
2006
- logger.info('Reconnection with existing sync data, skipping history sync wait. Transitioning to Online.')
2007
- syncState = State_1.SyncState.Online
2008
- setTimeout(() => ev.flush(), 0)
2009
- return
2010
- }
2011
- logger.info('First connection, awaiting history sync notification with a 20s timeout.')
2012
- if (awaitingSyncTimeout) {
2013
- clearTimeout(awaitingSyncTimeout)
2014
- }
2015
- awaitingSyncTimeout = setTimeout(() => {
2016
- if (syncState === State_1.SyncState.AwaitingInitialSync) {
2017
- logger.warn('Timeout in AwaitingInitialSync, forcing state to Online and flushing buffer')
2018
- syncState = State_1.SyncState.Online
2019
- ev.flush()
2020
-
2021
- const accountSyncCounter = (authState.creds.accountSyncCounter || 0) + 1
2022
- ev.emit('creds.update', { accountSyncCounter })
2023
- }
2024
- }, 20000)
2025
- })
2026
-
2027
- ev.on('creds.update', ({ myAppStateKeyId }) => {
2028
- if (!myAppStateKeyId || blockedCollections.size === 0) {
2029
- return
2030
- }
2031
-
2032
- if (syncState === State_1.SyncState.Syncing) {
2033
- blockedCollections.clear()
2034
- return
2035
- }
2036
- const collections = [...blockedCollections]
2037
- blockedCollections.clear()
2038
- logger.info({ collections }, 'app state sync key arrived, re-syncing blocked collections')
2039
- resyncAppState(collections, false).catch(error => onUnexpectedError(error, 'blocked collections resync'))
2040
- })
2041
- ev.on('lid-mapping.update', async ({ lid, pn }) => {
2042
- try {
2043
- await signalRepository.lidMapping.storeLIDPNMappings([{ lid, pn }])
2044
- } catch (error) {
2045
- logger.warn({ lid, pn, error }, 'Failed to store LID-PN mapping')
2046
- }
2047
- })
2048
- return {
2049
- ...sock,
2050
- serverProps,
2051
- createCallLink,
2052
- toggleCallLinkWaitingRoom,
2053
- getBotListV2,
2054
- getChatBlockingStatus,
2055
- updateChatBlockingStatus,
2056
- getUserDisclosures,
2057
- acceptTosNotice,
2058
- reportSpam,
2059
- getOptOutList,
2060
- getPushConfig,
2061
- setPushConfig,
2062
- signPrivateCredential,
2063
- messageMutex,
2064
- receiptMutex,
2065
- appStatePatchMutex,
2066
- notificationMutex,
2067
- fetchPrivacySettings,
2068
- upsertMessage,
2069
- appPatch,
2070
- sendPresenceUpdate,
2071
- presenceSubscribe,
2072
- profilePictureUrl,
2073
- fetchBlocklist,
2074
- fetchStatus,
2075
- fetchDisappearingDuration,
2076
- updateProfilePicture,
2077
- removeProfilePicture,
2078
- updateProfileStatus,
2079
- updateProfileName,
2080
- updateBlockStatus,
2081
- updateDisableLinkPreviewsPrivacy,
2082
- updateCallPrivacy,
2083
- updateMessagesPrivacy,
2084
- updateLastSeenPrivacy,
2085
- updateOnlinePrivacy,
2086
- updateProfilePicturePrivacy,
2087
- updateStatusPrivacy,
2088
- getStatusPrivacy,
2089
- setStatusPrivacy,
2090
- updateReadReceiptsPrivacy,
2091
- updateGroupsAddPrivacy,
2092
- updateDefaultDisappearingMode,
2093
- fetchBroadcastListQuota,
2094
- getBusinessProfile,
2095
- resyncAppState,
2096
- chatModify,
2097
- cleanDirtyBits,
2098
- addOrEditContact,
2099
- removeContact,
2100
- addLabel,
2101
- addChatLabel,
2102
- removeChatLabel,
2103
- addMessageLabel,
2104
- removeMessageLabel,
2105
- star,
2106
- addOrEditQuickReply,
2107
- removeQuickReply,
2108
- renameAIThread,
2109
- pinThreadMessage,
2110
- updatePrivateProcessingSetting,
2111
- updateAIFeatures,
2112
- updateBioPrivacy,
2113
- blockBot,
2114
- unblockBot,
2115
- getBotProfile,
2116
- muteContactStatus,
2117
- toggleFavorite,
2118
- reorderLabels,
2119
- deleteCallLog,
2120
- setChatNote,
2121
- deleteChatNote,
2122
- markChatAsUnread,
2123
- setChatEphemeral,
2124
- silenceChat,
2125
- clearChat,
2126
- pinChat,
2127
- starMessages,
2128
- setQuickReply,
2129
- fetchBotProfiles,
2130
- updateChatLock,
2131
- updateChatWallpaper,
2132
- updateChatMediaVisibility,
2133
- fetchIntegrators,
2134
- acceptInteropTOS,
2135
- optInIntegrators,
2136
- optOutIntegrators,
2137
- resolveInteropUser,
2138
- resolveInteropUsers,
2139
- getReachabilitySettings,
2140
- setReachabilitySettings,
2141
- blockInteropUser,
2142
- unblockInteropUser,
2143
- reportInteropSpam,
2144
- trustInteropContact,
2145
- initInterop,
2146
- createInteropGroup,
2147
- leaveInteropGroup,
2148
- getInteropGroupAddPrivacy,
2149
- INTEGRATOR_BIRDYCHAT,
2150
- INTEGRATOR_HAIKET,
2151
- fetchABProps,
2152
- removeCompanionDevice,
2153
- updateKeyIndexList,
2154
- fetchMediaConn,
2155
- deleteBroadcastList,
2156
- fetchQRCode,
2157
- confirmDeviceLogout,
2158
- updateKeyIndexList,
2159
- sendKeyIndexList,
2160
- storePrivacyTokens,
2161
- executeUSyncQuery,
2162
- newsletterServerIdCache: _nlServerIdCache
2163
- }
2164
- }
2165
- exports.makeChatsSocket = makeChatsSocket