@hansaka02/baileys 7.3.4 → 7.3.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 (50) hide show
  1. package/README.md +203 -247
  2. package/lib/Defaults/baileys-version.json +2 -2
  3. package/lib/Defaults/connection.js +1 -1
  4. package/lib/Defaults/constants.js +13 -1
  5. package/lib/Defaults/history.js +3 -1
  6. package/lib/Signal/Group/sender-chain-key.js +1 -14
  7. package/lib/Signal/Group/sender-key-distribution-message.js +2 -2
  8. package/lib/Signal/Group/sender-key-record.js +2 -11
  9. package/lib/Signal/Group/sender-key-state.js +11 -57
  10. package/lib/Signal/libsignal.js +200 -116
  11. package/lib/Signal/lid-mapping.js +121 -68
  12. package/lib/Socket/Client/websocket.js +9 -2
  13. package/lib/Socket/business.js +5 -1
  14. package/lib/Socket/chats.js +180 -89
  15. package/lib/Socket/community.js +169 -41
  16. package/lib/Socket/groups.js +25 -21
  17. package/lib/Socket/messages-recv.js +458 -333
  18. package/lib/Socket/messages-send.js +517 -572
  19. package/lib/Socket/mex.js +61 -0
  20. package/lib/Socket/newsletter.js +159 -252
  21. package/lib/Socket/socket.js +283 -100
  22. package/lib/Types/Newsletter.js +32 -25
  23. package/lib/Utils/auth-utils.js +189 -354
  24. package/lib/Utils/browser-utils.js +43 -0
  25. package/lib/Utils/chat-utils.js +166 -41
  26. package/lib/Utils/decode-wa-message.js +77 -35
  27. package/lib/Utils/event-buffer.js +80 -24
  28. package/lib/Utils/generics.js +28 -128
  29. package/lib/Utils/history.js +10 -8
  30. package/lib/Utils/index.js +1 -1
  31. package/lib/Utils/link-preview.js +17 -32
  32. package/lib/Utils/lt-hash.js +28 -22
  33. package/lib/Utils/make-mutex.js +26 -28
  34. package/lib/Utils/message-retry-manager.js +51 -3
  35. package/lib/Utils/messages-media.js +343 -151
  36. package/lib/Utils/messages.js +806 -792
  37. package/lib/Utils/noise-handler.js +33 -2
  38. package/lib/Utils/pre-key-manager.js +126 -0
  39. package/lib/Utils/process-message.js +115 -55
  40. package/lib/Utils/signal.js +45 -18
  41. package/lib/Utils/validate-connection.js +52 -29
  42. package/lib/WABinary/constants.js +1268 -1268
  43. package/lib/WABinary/decode.js +58 -4
  44. package/lib/WABinary/encode.js +54 -7
  45. package/lib/WABinary/jid-utils.js +58 -11
  46. package/lib/WAM/constants.js +19064 -11563
  47. package/lib/WAM/encode.js +57 -8
  48. package/lib/WAUSync/USyncQuery.js +35 -19
  49. package/package.json +9 -8
  50. package/lib/Socket/usync.js +0 -83
@@ -0,0 +1,61 @@
1
+ "use strict"
2
+
3
+ Object.defineProperty(exports, "__esModule", { value: true })
4
+
5
+ const { Boom } = require("@hapi/boom")
6
+ const {
7
+ getBinaryNodeChild,
8
+ S_WHATSAPP_NET
9
+ } = require("../WABinary")
10
+
11
+ const wMexQuery = (variables, queryId, query, generateMessageTag) => {
12
+ return query({
13
+ tag: 'iq',
14
+ attrs: {
15
+ id: generateMessageTag(),
16
+ type: 'get',
17
+ to: S_WHATSAPP_NET,
18
+ xmlns: 'w:mex'
19
+ },
20
+ content: [
21
+ {
22
+ tag: 'query',
23
+ attrs: { query_id: queryId },
24
+ content: Buffer.from(JSON.stringify({ variables }), 'utf-8')
25
+ }
26
+ ]
27
+ })
28
+ }
29
+
30
+ const executeWMexQuery = async (variables, queryId, dataPath, query, generateMessageTag) => {
31
+ const result = await wMexQuery(variables, queryId, query, generateMessageTag)
32
+ const child = getBinaryNodeChild(result, 'result')
33
+
34
+ if (child?.content) {
35
+ const data = JSON.parse(child.content.toString())
36
+
37
+ if (data.errors && data.errors.length > 0) {
38
+ const errorMessages = data.errors.map((err) => err.message || 'Unknown error').join(', ')
39
+ const firstError = data.errors[0]
40
+ const errorCode = firstError.extensions?.error_code || 400
41
+
42
+ throw new Boom(`GraphQL server error: ${errorMessages}`, { statusCode: errorCode, data: firstError })
43
+ }
44
+
45
+ const response = dataPath ? data?.data?.[dataPath] : data?.data
46
+
47
+ if (typeof response !== 'undefined') {
48
+ return response
49
+ }
50
+ }
51
+
52
+ const action = (dataPath || '').startsWith('xwa2_')
53
+ ? dataPath.substring(5).replace(/_/g, ' ')
54
+ : dataPath?.replace(/_/g, ' ')
55
+
56
+ throw new Boom(`Failed to ${action}, unexpected response structure.`, { statusCode: 400, data: result })
57
+ }
58
+
59
+ module.exports = {
60
+ executeWMexQuery
61
+ }
@@ -6,304 +6,211 @@ const {
6
6
  QueryIds,
7
7
  XWAPaths
8
8
  } = require("../Types")
9
- const {
10
- decryptMessageNode,
11
- generateProfilePicture,
12
- getUrlFromDirectPath,
13
- generateMessageID
14
- } = require("../Utils")
15
- const {
16
- getAllBinaryNodeChildren,
17
- getBinaryNodeChildren,
18
- getBinaryNodeChild,
19
- isJidNewsletter,
20
- S_WHATSAPP_NET
21
- } = require("../WABinary")
9
+ const { generateProfilePicture } = require("../Utils")
10
+ const { getBinaryNodeChild } = require("../WABinary")
22
11
  const { makeGroupsSocket } = require("./groups")
12
+ const { executeWMexQuery: genericExecuteWMexQuery } = require("./mex")
13
+
14
+ const parseNewsletterCreateResponse = (response) => {
15
+ const { id, thread_metadata: thread, viewer_metadata: viewer } = response
16
+ return {
17
+ id: id,
18
+ owner: undefined,
19
+ name: thread.name.text,
20
+ creation_time: parseInt(thread.creation_time, 10),
21
+ description: thread.description.text,
22
+ invite: thread.invite,
23
+ subscribers: parseInt(thread.subscribers_count, 10),
24
+ verification: thread.verification,
25
+ picture: {
26
+ id: thread.picture.id,
27
+ directPath: thread.picture.direct_path
28
+ },
29
+ mute_state: viewer.mute
30
+ }
31
+ }
32
+
33
+ const parseNewsletterMetadata = (result) => {
34
+ if (typeof result !== 'object' || result === null) {
35
+ return null
36
+ }
37
+
38
+ if ('id' in result && typeof result.id === 'string') {
39
+ return result
40
+ }
41
+
42
+ if ('result' in result && typeof result.result === 'object' && result.result !== null && 'id' in result.result) {
43
+ return result.result
44
+ }
45
+
46
+ return null
47
+ }
23
48
 
24
49
  const makeNewsletterSocket = (config) => {
25
50
  const suki = makeGroupsSocket(config)
26
- const { authState, signalRepository, query, generateMessageTag } = suki
27
- const encoder = new TextEncoder()
51
+ const {
52
+ query,
53
+ generateMessageTag
54
+ } = suki
28
55
 
29
- const newsletterQuery = async (jid, type, content) => (query({
30
- tag: 'iq',
31
- attrs: {
32
- id: generateMessageTag(),
33
- type,
34
- xmlns: 'newsletter',
35
- to: jid,
36
- },
37
- content
38
- }))
56
+ const executeWMexQuery = (variables, queryId, dataPath) => {
57
+ return genericExecuteWMexQuery(variables, queryId, dataPath, query, generateMessageTag)
58
+ }
39
59
 
40
- const newsletterWMexQuery = async (jid, queryId, content) => (query({
41
- tag: 'iq',
42
- attrs: {
43
- id: generateMessageTag(),
44
- type: 'get',
45
- xmlns: 'w:mex',
46
- to: S_WHATSAPP_NET,
47
- },
48
- content: [
49
- {
50
- tag: 'query',
51
- attrs: { 'query_id': queryId },
52
- content: encoder.encode(JSON.stringify({
53
- variables: {
54
- 'newsletter_id': jid,
55
- ...content
56
- }
57
- }))
60
+ const newsletterUpdate = async (jid, updates) => {
61
+ const variables = {
62
+ newsletter_id: jid,
63
+ updates: {
64
+ ...updates,
65
+ settings: null
58
66
  }
59
- ]
60
- }))
61
-
62
- const parseFetchedUpdates = async (node, type) => {
63
- let child
64
- if (type === 'messages') {
65
- child = getBinaryNodeChild(node, 'messages')
66
67
  }
67
68
 
68
- else {
69
- const parent = getBinaryNodeChild(node, 'message_updates')
70
- child = getBinaryNodeChild(parent, 'messages')
71
- }
72
-
73
- return await Promise.all(getAllBinaryNodeChildren(child).map(async (messageNode) => {
74
- messageNode.attrs.from = child?.attrs.jid
75
-
76
- const views = parseInt(getBinaryNodeChild(messageNode, 'views_count')?.attrs?.count || '0')
77
- const reactionNode = getBinaryNodeChild(messageNode, 'reactions')
78
- const reactions = getBinaryNodeChildren(reactionNode, 'reaction')
79
- .map(({ attrs }) => ({ count: +attrs.count, code: attrs.code }))
80
-
81
- const data = {
82
- 'server_id': messageNode.attrs.server_id,
83
- views,
84
- reactions
85
- }
86
-
87
- if (type === 'messages') {
88
- const { fullMessage: message, decrypt } = await decryptMessageNode(messageNode, authState.creds.me.id, authState.creds.me.lid || '', signalRepository, config.logger)
89
- await decrypt()
90
- data.message = message
91
- }
92
-
93
- return data
94
- }))
95
- }
96
-
97
- const newsletterMetadata = async (type, key, role) => {
98
- const result = await newsletterWMexQuery(undefined, QueryIds.METADATA, {
99
- input: {
100
- key,
101
- type: type.toUpperCase(),
102
- view_role: role || 'GUEST'
103
- },
104
- fetch_viewer_metadata: true,
105
- fetch_full_image: true,
106
- fetch_creation_time: true
107
- })
108
-
109
- return extractNewsletterMetadata(result)
69
+ return executeWMexQuery(variables, QueryIds.UPDATE_METADATA, XWAPaths.UPDATE)
110
70
  }
111
71
 
112
72
  return {
113
73
  ...suki,
114
- newsletterQuery,
115
- newsletterWMexQuery,
116
- subscribeNewsletterUpdates: async (jid) => {
117
- const result = await newsletterQuery(jid, 'set', [{ tag: 'live_updates', attrs: {}, content: [] }])
74
+ executeWMexQuery,
75
+ newsletterCreate: async (name, description) => {
76
+ const variables = {
77
+ input: {
78
+ name,
79
+ description: description ?? null
80
+ }
81
+ }
118
82
 
119
- return getBinaryNodeChild(result, 'live_updates')?.attrs
83
+ const rawResponse = await executeWMexQuery(variables, QueryIds.CREATE, XWAPaths.CREATE)
84
+
85
+ return parseNewsletterCreateResponse(rawResponse)
86
+ },
87
+ newsletterUpdate,
88
+ newsletterSubscribers: async (jid) => {
89
+ return executeWMexQuery({ newsletter_id: jid }, QueryIds.SUBSCRIBERS, XWAPaths.SUBSCRIBERS)
90
+ },
91
+ newsletterMetadata: async (type, key) => {
92
+ const variables = {
93
+ fetch_creation_time: true,
94
+ fetch_full_image: true,
95
+ fetch_viewer_metadata: true,
96
+ input: {
97
+ key,
98
+ type: type.toUpperCase()
99
+ }
100
+ }
101
+
102
+ const result = await executeWMexQuery(variables, QueryIds.METADATA, XWAPaths.METADATA)
103
+
104
+ return parseNewsletterMetadata(result)
120
105
  },
121
- newsletterReactionMode: async (jid, mode) => {
122
- await newsletterWMexQuery(jid, QueryIds.JOB_MUTATION, {
123
- updates: { settings: { 'reaction_codes': { value: mode } } }
124
- })
106
+ newsletterFollow: (jid) => {
107
+ return executeWMexQuery({ newsletter_id: jid }, QueryIds.FOLLOW, XWAPaths.FOLLOW)
125
108
  },
126
- newsletterUpdateDescription: async (jid, description) => {
127
- await newsletterWMexQuery(jid, QueryIds.JOB_MUTATION, {
128
- updates: { description: description || '', settings: null }
129
- })
109
+ newsletterUnfollow: (jid) => {
110
+ return executeWMexQuery({ newsletter_id: jid }, QueryIds.UNFOLLOW, XWAPaths.UNFOLLOW)
111
+ },
112
+ newsletterMute: (jid) => {
113
+ return executeWMexQuery({ newsletter_id: jid }, QueryIds.MUTE, XWAPaths.MUTE_V2)
114
+ },
115
+ newsletterUnmute: (jid) => {
116
+ return executeWMexQuery({ newsletter_id: jid }, QueryIds.UNMUTE, XWAPaths.UNMUTE_V2)
130
117
  },
131
118
  newsletterUpdateName: async (jid, name) => {
132
- await newsletterWMexQuery(jid, QueryIds.JOB_MUTATION, {
133
- updates: { name, settings: null }
134
- })
119
+ return await newsletterUpdate(jid, { name })
120
+ },
121
+ newsletterUpdateDescription: async (jid, description) => {
122
+ return await newsletterUpdate(jid, { description })
135
123
  },
136
124
  newsletterUpdatePicture: async (jid, content) => {
137
125
  const { img } = await generateProfilePicture(content)
138
-
139
- await newsletterWMexQuery(jid, QueryIds.JOB_MUTATION, {
140
- updates: { picture: img.toString('base64'), settings: null }
141
- })
126
+ return await newsletterUpdate(jid, { picture: img.toString('base64') })
142
127
  },
143
128
  newsletterRemovePicture: async (jid) => {
144
- await newsletterWMexQuery(jid, QueryIds.JOB_MUTATION, {
145
- updates: { picture: '', settings: null }
146
- })
147
- },
148
- newsletterUnfollow: async (jid) => {
149
- await newsletterWMexQuery(jid, QueryIds.UNFOLLOW)
150
- },
151
- newsletterFollow: async (jid) => {
152
- await newsletterWMexQuery(jid, QueryIds.FOLLOW)
129
+ return await newsletterUpdate(jid, { picture: '' })
153
130
  },
154
- newsletterUnmute: async (jid) => {
155
- await newsletterWMexQuery(jid, QueryIds.UNMUTE)
156
- },
157
- newsletterMute: async (jid) => {
158
- await newsletterWMexQuery(jid, QueryIds.MUTE)
159
- },
160
- newsletterAction: async (jid, type) => {
161
- await newsletterWMexQuery(jid, QueryIds[type.toUpperCase()])
162
- },
163
- newsletterCreate: async (name, description, picture) => {
164
- //TODO: Implement TOS system wide for Meta AI, communities, and here etc.
165
- /**tos query */
131
+ newsletterReactMessage: async (jid, serverId, reaction) => {
166
132
  await query({
167
- tag: 'iq',
133
+ tag: 'message',
168
134
  attrs: {
169
- to: S_WHATSAPP_NET,
170
- xmlns: 'tos',
171
- id: generateMessageTag(),
172
- type: 'set'
135
+ to: jid,
136
+ ...(reaction ? {} : { edit: '7' }),
137
+ type: 'reaction',
138
+ server_id: serverId,
139
+ id: generateMessageTag()
173
140
  },
174
141
  content: [
175
142
  {
176
- tag: 'notice',
177
- attrs: {
178
- id: '20601218',
179
- stage: '5'
180
- },
181
- content: []
143
+ tag: 'reaction',
144
+ attrs: reaction ? { code: reaction } : {}
182
145
  }
183
146
  ]
184
147
  })
148
+ },
149
+ newsletterFetchMessages: async (jid, count, since, after) => {
150
+ const messageUpdateAttrs = {
151
+ count: count.toString()
152
+ }
153
+
154
+ if (typeof since === 'number') {
155
+ messageUpdateAttrs.since = since.toString()
156
+ }
157
+
158
+ if (after) {
159
+ messageUpdateAttrs.after = after.toString()
160
+ }
185
161
 
186
- const result = await newsletterWMexQuery(undefined, QueryIds.CREATE, {
187
- input: {
188
- name,
189
- description: description || null,
190
- picture: picture ? (await generateProfilePicture(picture)).img.toString('base64') : null,
191
- settings: {
192
- reaction_codes: {
193
- value: 'ALL'
194
- }
162
+ const result = await query({
163
+ tag: 'iq',
164
+ attrs: {
165
+ id: generateMessageTag(),
166
+ type: 'get',
167
+ xmlns: 'newsletter',
168
+ to: jid
169
+ },
170
+ content: [
171
+ {
172
+ tag: 'message_updates',
173
+ attrs: messageUpdateAttrs
195
174
  }
196
- }
175
+ ]
197
176
  })
198
177
 
199
- return extractNewsletterMetadata(result, true)
178
+ return result
200
179
  },
201
- newsletterMetadata,
202
- newsletterFetchAllParticipating: async () => {
203
- const data = {}
204
-
205
- const result = await newsletterWMexQuery(undefined, QueryIds.SUBSCRIBED)
206
- const child = JSON.parse(getBinaryNodeChild(result, 'result')?.content?.toString())
207
- const newsletters = child.data[XWAPaths.SUBSCRIBED]
208
-
209
- for (const i of newsletters) {
210
- if (!isJidNewsletter(i.id)) {
211
- continue
212
- }
213
-
214
- const metadata = await newsletterMetadata('JID', i.id)
215
- data[metadata.id] = metadata
216
- }
217
-
218
- return data
219
- },
220
- newsletterFetchAllParticipating: async () => {
221
- const result = await newsletterWMexQuery(undefined, QueryIds.SUBSCRIBED)
222
- const child = JSON.parse(getBinaryNodeChild(result, 'result')?.content?.toString())
223
- const newsletters = child.data[XWAPaths.SUBSCRIBED] || []
224
-
225
- const data = {}
226
-
227
- for (const { id } of newsletters) {
228
- if (!isJidNewsletter(id)) continue
229
- const metadata = await newsletterMetadata('JID', id)
230
- data[metadata.id] = metadata
231
- }
232
-
233
- return data
234
- },
235
- newsletterChangeOwner: async (jid, userLid) => {
236
- await newsletterWMexQuery(jid, QueryIds.CHANGE_OWNER, {
237
- user_id: userLid
238
- })
239
- },
240
- newsletterDemote: async (jid, userLid) => {
241
- await newsletterWMexQuery(jid, QueryIds.DEMOTE, {
242
- user_id: userLid
180
+ subscribeNewsletterUpdates: async (jid) => {
181
+ const result = await query({
182
+ tag: 'iq',
183
+ attrs: {
184
+ id: generateMessageTag(),
185
+ type: 'set',
186
+ xmlns: 'newsletter',
187
+ to: jid
188
+ },
189
+ content: [{ tag: 'live_updates', attrs: {}, content: [] }]
243
190
  })
191
+
192
+ const liveUpdatesNode = getBinaryNodeChild(result, 'live_updates')
193
+ const duration = liveUpdatesNode?.attrs?.duration
194
+
195
+ return duration ? { duration: duration } : null
244
196
  },
245
- newsletterDelete: async (jid) => {
246
- await newsletterWMexQuery(jid, QueryIds.DELETE)
197
+ newsletterAdminCount: async (jid) => {
198
+ const response = await executeWMexQuery({ newsletter_id: jid }, QueryIds.ADMIN_COUNT, XWAPaths.ADMIN_COUNT)
199
+ return response.admin_count
247
200
  },
248
- /**if code wasn't passed, the reaction will be removed (if is reacted) */
249
- newsletterReactMessage: async (jid, serverId, code) => {
250
- await query({
251
- tag: 'message',
252
- attrs: { to: jid, ...(!code ? { edit: '7' } : {}), type: 'reaction', server_id: serverId, id: generateMessageID() },
253
- content: [{
254
- tag: 'reaction',
255
- attrs: code ? { code } : {}
256
- }]
257
- })
201
+ newsletterChangeOwner: async (jid, newOwnerJid) => {
202
+ await executeWMexQuery({ newsletter_id: jid, user_id: newOwnerJid }, QueryIds.CHANGE_OWNER, XWAPaths.CHANGE_OWNER)
258
203
  },
259
- newsletterFetchMessages: async (type, key, count, after) => {
260
- const result = await newsletterQuery(S_WHATSAPP_NET, 'get', [
261
- {
262
- tag: 'messages',
263
- attrs: { type, ...(type === 'invite' ? { key } : { jid: key }), count: count.toString(), after: after?.toString() || '100' }
264
- }
265
- ])
266
-
267
- return await parseFetchedUpdates(result, 'messages')
204
+ newsletterDemote: async (jid, userJid) => {
205
+ await executeWMexQuery({ newsletter_id: jid, user_id: userJid }, QueryIds.DEMOTE, XWAPaths.DEMOTE)
268
206
  },
269
- newsletterFetchUpdates: async (jid, count, after, since) => {
270
- const result = await newsletterQuery(jid, 'get', [
271
- {
272
- tag: 'message_updates',
273
- attrs: { count: count.toString(), after: after?.toString() || '100', since: since?.toString() || '0' }
274
- }
275
- ])
276
-
277
- return await parseFetchedUpdates(result, 'updates')
207
+ newsletterDelete: async (jid) => {
208
+ await executeWMexQuery({ newsletter_id: jid }, QueryIds.DELETE, XWAPaths.DELETE_V2)
278
209
  }
279
210
  }
280
211
  }
281
212
 
282
- const extractNewsletterMetadata = (node, isCreate) => {
283
- const result = getBinaryNodeChild(node, 'result')?.content?.toString()
284
- const metadataPath = JSON.parse(result).data[isCreate ? XWAPaths.CREATE : XWAPaths.NEWSLETTER]
285
-
286
- const metadata = {
287
- id: metadataPath?.id,
288
- state: metadataPath?.state?.type,
289
- creation_time: +metadataPath?.thread_metadata?.creation_time,
290
- name: metadataPath?.thread_metadata?.name?.text,
291
- nameTime: +metadataPath?.thread_metadata?.name?.update_time,
292
- description: metadataPath?.thread_metadata?.description?.text,
293
- descriptionTime: +metadataPath?.thread_metadata?.description?.update_time,
294
- invite: metadataPath?.thread_metadata?.invite,
295
- handle: metadataPath?.thread_metadata?.handle,
296
- picture: getUrlFromDirectPath(metadataPath?.thread_metadata?.picture?.direct_path || ''),
297
- preview: getUrlFromDirectPath(metadataPath?.thread_metadata?.preview?.direct_path || ''),
298
- reaction_codes: metadataPath?.thread_metadata?.settings?.reaction_codes?.value,
299
- subscribers: +metadataPath?.thread_metadata?.subscribers_count,
300
- verification: metadataPath?.thread_metadata?.verification,
301
- viewer_metadata: metadataPath?.viewer_metadata
302
- }
303
- return metadata
304
- }
305
-
306
213
  module.exports = {
307
214
  makeNewsletterSocket,
308
- extractNewsletterMetadata
215
+ parseNewsletterMetadata
309
216
  }