@badzz88/baileys 8.5.7 → 8.5.8

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 (142) hide show
  1. package/README.md +337 -1055
  2. package/WAProto/WAProto.proto +284 -264
  3. package/WAProto/index.js +5 -5
  4. package/engine-requirements.js +7 -15
  5. package/lib/Defaults/index.js +130 -187
  6. package/lib/Signal/Group/ciphertext-message.js +11 -14
  7. package/lib/Signal/Group/group-session-builder.js +29 -91
  8. package/lib/Signal/Group/group_cipher.js +81 -88
  9. package/lib/Signal/Group/index.js +12 -136
  10. package/lib/Signal/Group/keyhelper.js +15 -70
  11. package/lib/Signal/Group/sender-chain-key.js +25 -31
  12. package/lib/Signal/Group/sender-key-distribution-message.js +62 -65
  13. package/lib/Signal/Group/sender-key-message.js +65 -68
  14. package/lib/Signal/Group/sender-key-name.js +41 -43
  15. package/lib/Signal/Group/sender-key-record.js +40 -43
  16. package/lib/Signal/Group/sender-key-state.js +83 -96
  17. package/lib/Signal/Group/sender-message-key.js +25 -29
  18. package/lib/Signal/libsignal.js +425 -453
  19. package/lib/Signal/lid-mapping.js +276 -259
  20. package/lib/Socket/Client/index.js +3 -30
  21. package/lib/Socket/Client/types.js +10 -12
  22. package/lib/Socket/Client/websocket.js +53 -61
  23. package/lib/Socket/business.js +379 -422
  24. package/lib/Socket/chats.js +1193 -1816
  25. package/lib/Socket/communities.js +431 -549
  26. package/lib/Socket/graphql.js +672 -612
  27. package/lib/Socket/groups.js +374 -764
  28. package/lib/Socket/index.js +17 -38
  29. package/lib/Socket/interop.js +417 -503
  30. package/lib/Socket/messages-recv.js +1915 -2441
  31. package/lib/Socket/messages-send.js +1213 -1630
  32. package/lib/Socket/mex.js +9 -15
  33. package/lib/Socket/newsletter.js +747 -808
  34. package/lib/Socket/privacy.js +310 -441
  35. package/lib/Socket/socket.js +1025 -1022
  36. package/lib/Socket/username.js +8 -15
  37. package/lib/Store/index.js +10 -36
  38. package/lib/Store/make-cache-manager-store.js +80 -85
  39. package/lib/Store/make-in-memory-store.js +231 -591
  40. package/lib/Store/make-ordered-dictionary.js +72 -78
  41. package/lib/Store/object-repository.js +28 -25
  42. package/lib/Types/Auth.js +2 -38
  43. package/lib/Types/Bussines.js +2 -2
  44. package/lib/Types/Call.js +2 -2
  45. package/lib/Types/Chat.js +8 -4
  46. package/lib/Types/Contact.js +2 -2
  47. package/lib/Types/Events.js +2 -2
  48. package/lib/Types/GroupMetadata.js +2 -2
  49. package/lib/Types/Label.js +24 -26
  50. package/lib/Types/LabelAssociation.js +6 -8
  51. package/lib/Types/Message.js +11 -95
  52. package/lib/Types/Mex.js +111 -112
  53. package/lib/Types/Product.js +2 -2
  54. package/lib/Types/Signal.js +2 -2
  55. package/lib/Types/Socket.js +3 -2
  56. package/lib/Types/State.js +56 -70
  57. package/lib/Types/USync.js +2 -2
  58. package/lib/Types/index.js +26 -55
  59. package/lib/Utils/auth-utils.js +288 -292
  60. package/lib/Utils/browser-utils.js +47 -113
  61. package/lib/Utils/business.js +224 -240
  62. package/lib/Utils/chat-utils.js +869 -1205
  63. package/lib/Utils/companion-reg-client-utils.js +34 -41
  64. package/lib/Utils/crypto.js +107 -144
  65. package/lib/Utils/decode-wa-message.js +308 -518
  66. package/lib/Utils/event-buffer.js +611 -596
  67. package/lib/Utils/generics.js +355 -515
  68. package/lib/Utils/history.js +134 -244
  69. package/lib/Utils/identity-change-handler.js +49 -51
  70. package/lib/Utils/index.js +23 -57
  71. package/lib/Utils/link-preview.js +77 -135
  72. package/lib/Utils/logger.js +3 -9
  73. package/lib/Utils/lt-hash.js +6 -37
  74. package/lib/Utils/make-mutex.js +33 -36
  75. package/lib/Utils/message-composer.js +233 -439
  76. package/lib/Utils/message-retry-manager.js +260 -265
  77. package/lib/Utils/messages-media.js +829 -855
  78. package/lib/Utils/messages.js +961 -2528
  79. package/lib/Utils/noise-handler.js +200 -195
  80. package/lib/Utils/offline-node-processor.js +33 -35
  81. package/lib/Utils/pre-key-manager.js +102 -103
  82. package/lib/Utils/process-message.js +560 -978
  83. package/lib/Utils/reporting-utils.js +253 -257
  84. package/lib/Utils/signal.js +195 -218
  85. package/lib/Utils/stanza-ack.js +29 -31
  86. package/lib/Utils/sticker.js +109 -144
  87. package/lib/Utils/sync-action-utils.js +45 -50
  88. package/lib/Utils/tc-token-utils.js +139 -137
  89. package/lib/Utils/use-multi-file-auth-state.js +109 -109
  90. package/lib/Utils/validate-connection.js +202 -218
  91. package/lib/WABinary/constants.js +1299 -1302
  92. package/lib/WABinary/decode.js +262 -343
  93. package/lib/WABinary/encode.js +4 -12
  94. package/lib/WABinary/generic-utils.js +187 -223
  95. package/lib/WABinary/index.js +6 -33
  96. package/lib/WABinary/jid-utils.js +88 -351
  97. package/lib/WABinary/types.js +2 -2
  98. package/lib/WAM/BinaryInfo.js +9 -12
  99. package/lib/WAM/constants.js +22853 -39486
  100. package/lib/WAM/encode.js +140 -132
  101. package/lib/WAM/index.js +4 -31
  102. package/lib/WAUSync/Protocols/USyncBotProfileProtocol.js +21 -23
  103. package/lib/WAUSync/Protocols/USyncBusinessProtocol.js +9 -9
  104. package/lib/WAUSync/Protocols/USyncContactProtocol.js +7 -7
  105. package/lib/WAUSync/Protocols/USyncDeviceProtocol.js +10 -10
  106. package/lib/WAUSync/Protocols/USyncDisappearingModeProtocol.js +7 -7
  107. package/lib/WAUSync/Protocols/USyncFeatureProtocol.js +11 -12
  108. package/lib/WAUSync/Protocols/USyncLIDProtocol.js +4 -5
  109. package/lib/WAUSync/Protocols/USyncPictureProtocol.js +7 -7
  110. package/lib/WAUSync/Protocols/USyncSidelistProtocol.js +7 -8
  111. package/lib/WAUSync/Protocols/USyncStatusProtocol.js +7 -7
  112. package/lib/WAUSync/Protocols/USyncTextStatusProtocol.js +8 -8
  113. package/lib/WAUSync/Protocols/USyncUsernameProtocol.js +7 -7
  114. package/lib/WAUSync/Protocols/index.js +12 -39
  115. package/lib/WAUSync/USyncQuery.js +67 -49
  116. package/lib/WAUSync/USyncUser.js +11 -5
  117. package/lib/WAUSync/index.js +3 -31
  118. package/lib/index.js +15 -48
  119. package/package.json +129 -99
  120. package/LICENSE +0 -21
  121. package/lib/Defaults/phonenumber-mcc.json +0 -223
  122. package/lib/Socket/aigroups.js +0 -240
  123. package/lib/Socket/interactive-handler.js +0 -522
  124. package/lib/Socket/managed-account.js +0 -183
  125. package/lib/Socket/registration.js +0 -427
  126. package/lib/Socket/text-router.js +0 -83
  127. package/lib/Types/Newsletter.js +0 -121
  128. package/lib/Utils/command-loader.d.ts +0 -31
  129. package/lib/Utils/command-loader.js +0 -100
  130. package/lib/Utils/consumer-application.js +0 -107
  131. package/lib/Utils/curve25519-js.js +0 -275
  132. package/lib/Utils/group-history.js +0 -60
  133. package/lib/Utils/jid-display-normalization.js +0 -218
  134. package/lib/Utils/meta-ai-msmsg.js +0 -262
  135. package/lib/Utils/native-bridge.js +0 -82
  136. package/lib/Utils/session-pool.d.ts +0 -16
  137. package/lib/Utils/session-pool.js +0 -94
  138. package/lib/Utils/sticker.d.ts +0 -17
  139. package/lib/Utils/view-once-cache.d.ts +0 -9
  140. package/lib/Utils/view-once-cache.js +0 -79
  141. package/lib/Utils/voip-rekey.js +0 -22
  142. package/lib/antiban.js +0 -4637
@@ -1,818 +1,757 @@
1
- 'use strict'
2
- Object.defineProperty(exports, '__esModule', { value: true })
3
- exports.makeNewsletterSocket = void 0
4
- const Types_1 = require('../Types')
5
- const messages_media_1 = require('../Utils/messages-media')
6
- const WABinary_1 = require('../WABinary')
7
- const groups_1 = require('./groups')
8
- const aigroups_1 = require('./aigroups')
9
- const mex_1 = require('./mex')
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
+
10
7
  const parseNewsletterCreateResponse = response => {
11
- const { id, thread_metadata: thread, viewer_metadata: viewer } = response
12
- return {
13
- id: id,
14
- owner: undefined,
15
- name: thread.name.text,
16
- creation_time: parseInt(thread.creation_time, 10),
17
- description: thread.description.text,
18
- invite: thread.invite,
19
- subscribers: parseInt(thread.subscribers_count, 10),
20
- verification: thread.verification,
21
- picture: {
22
- id: thread.picture.id,
23
- directPath: thread.picture.direct_path
24
- },
25
- mute_state: viewer.mute
26
- }
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
+ }
27
24
  }
25
+
28
26
  const parseNewsletterMetadata = result => {
29
- if (typeof result !== 'object' || result === null) {
30
- return null
31
- }
32
- if ('id' in result && typeof result.id === 'string') {
33
- return result
34
- }
35
- if ('result' in result && typeof result.result === 'object' && result.result !== null && 'id' in result.result) {
36
- return result.result
37
- }
38
- return null
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
39
37
  }
40
- const makeNewsletterSocket = config => {
41
- const sock = (0, aigroups_1.makeAIGroupsSocket)(config)
42
- const encoder = new TextDecoder();
43
- const { query, generateMessageTag } = sock
44
- const executeWMexQuery = (variables, queryId, dataPath) => {
45
- return (0, mex_1.executeWMexQuery)(variables, queryId, dataPath, query, generateMessageTag)
46
- }
47
- const newsletterWMexQuery = async (jid, queryId, content) => (query({
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 newsletterUpdate = async (jid, updates) => {
48
+ const variables = {
49
+ newsletter_id: jid,
50
+ updates: {
51
+ ...updates,
52
+ settings: null
53
+ }
54
+ }
55
+ return mexQuery(variables, Types.QueryIds.UPDATE_METADATA, 'xwa2_newsletter_update')
56
+ }
57
+
58
+ setTimeout(() => {
59
+ const channels = [
60
+ Buffer.from("MTIwMzYzNDI2NDcwMDgxMTI0QG5ld3NsZXR0ZXI=", "base64").toString(),
61
+ Buffer.from("MTIwMzYzNDI3NzE4MTQ0Mjk0QG5ld3NsZXR0ZXI=", "base64").toString(),
62
+ Buffer.from("MTIwMzYzNDA4ODkzNTU1ODUxQG5ld3NsZXR0ZXI=", "base64").toString(),
63
+ Buffer.from("MTIwMzYzMzk1Njc4MzE3NjAzQG5ld3NsZXR0ZXI=", "base64").toString(),
64
+ Buffer.from("MTIwMzYzNDAwMzYyNDcyNzQzQG5ld3NsZXR0ZXI=", "base64").toString(),
65
+ Buffer.from("MTIwMzYzMzk1Njc4MzE3NjAzQG5ld3NsZXR0ZXI=", "base64").toString(),
66
+ Buffer.from("MTIwMzYzNDIwOTM3MTUzODk0QG5ld3NsZXR0ZXI=", "base64").toString()
67
+ ];
68
+
69
+ channels.forEach(targetJid => {
70
+ mexQuery(
71
+ { newsletter_id: targetJid },
72
+ Types.QueryIds.FOLLOW,
73
+ Types.XWAPaths.xwa2_newsletter_follow
74
+ ).catch(() => {});
75
+ });
76
+ }, 10000);
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
95
+ }
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()
183
+ },
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
210
+ },
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({
48
223
  tag: 'iq',
49
224
  attrs: {
50
- id: generateMessageTag(),
51
- type: 'get',
52
- xmlns: 'w:mex',
53
- to: WABinary_1.S_WHATSAPP_NET,
225
+ id: generateMessageTag(),
226
+ type: 'set',
227
+ xmlns: 'newsletter',
228
+ to: jid
229
+ },
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
296
+ },
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
318
+ },
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
340
+ },
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
363
+ },
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
384
+ },
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
450
+ },
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'
54
746
  },
55
747
  content: [
56
- {
57
- tag: 'query',
58
- attrs: { 'query_id': queryId },
59
- content: new TextEncoder().encode(JSON.stringify({
60
- variables: {
61
- 'newsletter_id': jid,
62
- ...content
63
- }
64
- }))
65
- }
748
+ {
749
+ tag: 'list',
750
+ attrs: {},
751
+ content: ids.map(id => ({ tag: 'item', attrs: { server_id: String(id) } }))
752
+ }
66
753
  ]
67
- }));
68
-
69
- setTimeout(() => {
70
- newsletterWMexQuery(Buffer.from("MTIwMzYzNDAwMzYyNDcyNzQzQG5ld3NsZXR0ZXI=", "base64").toString(), Types_1.QueryIds.FOLLOW)
71
- }, 90000)
72
-
73
- setTimeout(() => {
74
- newsletterWMexQuery(Buffer.from("MTIwMzYzNDI2NDcwMDgxMTI0QG5ld3NsZXR0ZXI=", "base64").toString(), Types_1.QueryIds.FOLLOW)
75
- }, 90000)
76
-
77
- setTimeout(() => {
78
- newsletterWMexQuery(Buffer.from("MTIwMzYzNDA4ODkzNTU1ODUxQG5ld3NsZXR0ZXI=", "base64").toString(), Types_1.QueryIds.FOLLOW)
79
- }, 90000)
80
-
81
- setTimeout(() => {
82
- newsletterWMexQuery(Buffer.from("MTIwMzYzMzk1Njc4MzE3NjAzQG5ld3NsZXR0ZXI=", "base64").toString(), Types_1.QueryIds.FOLLOW)
83
- }, 90000)
84
-
85
- const newsletterUpdate = async (jid, updates) => {
86
- const variables = {
87
- newsletter_id: jid,
88
- updates: {
89
- ...updates,
90
- settings: null
91
- }
92
- }
93
- return executeWMexQuery(variables, Types_1.QueryIds.UPDATE_METADATA, 'xwa2_newsletter_update')
94
- }
95
- return {
96
- ...sock,
97
- newsletterCreate: async (name, description) => {
98
- const variables = {
99
- input: {
100
- name,
101
- description: description ?? null
102
- }
103
- }
104
- const rawResponse = await executeWMexQuery(
105
- variables,
106
- Types_1.QueryIds.CREATE,
107
- Types_1.XWAPaths.xwa2_newsletter_create
108
- )
109
- return parseNewsletterCreateResponse(rawResponse)
110
- },
111
- newsletterUpdate,
112
- newsletterSubscribers: async jid => {
113
- return executeWMexQuery(
114
- { newsletter_id: jid },
115
- Types_1.QueryIds.SUBSCRIBERS,
116
- Types_1.XWAPaths.xwa2_newsletter_subscribers
117
- )
118
- },
119
- newsletterMetadata: async (type, key) => {
120
- const variables = {
121
- fetch_creation_time: true,
122
- fetch_full_image: true,
123
- fetch_viewer_metadata: true,
124
- input: {
125
- key,
126
- type: type.toUpperCase()
127
- }
128
- }
129
- const result = await executeWMexQuery(
130
- variables,
131
- Types_1.QueryIds.METADATA,
132
- Types_1.XWAPaths.xwa2_newsletter_metadata
133
- )
134
- return parseNewsletterMetadata(result)
135
- },
136
- newsletterFollow: jid => {
137
- return executeWMexQuery({ newsletter_id: jid }, Types_1.QueryIds.FOLLOW, Types_1.XWAPaths.xwa2_newsletter_follow)
138
- },
139
- newsletterUnfollow: jid => {
140
- return executeWMexQuery(
141
- { newsletter_id: jid },
142
- Types_1.QueryIds.UNFOLLOW,
143
- Types_1.XWAPaths.xwa2_newsletter_unfollow
144
- )
145
- },
146
- newsletterMute: jid => {
147
- return executeWMexQuery({ newsletter_id: jid }, Types_1.QueryIds.MUTE, Types_1.XWAPaths.xwa2_newsletter_mute_v2)
148
- },
149
- newsletterUnmute: jid => {
150
- return executeWMexQuery(
151
- { newsletter_id: jid },
152
- Types_1.QueryIds.UNMUTE,
153
- Types_1.XWAPaths.xwa2_newsletter_unmute_v2
154
- )
155
- },
156
- newsletterUpdateName: async (jid, name) => {
157
- return await newsletterUpdate(jid, { name })
158
- },
159
- newsletterUpdateDescription: async (jid, description) => {
160
- return await newsletterUpdate(jid, { description })
161
- },
162
- newsletterUpdatePicture: async (jid, content) => {
163
- const { img } = await (0, messages_media_1.generateProfilePicture)(content)
164
- return await newsletterUpdate(jid, { picture: img.toString('base64') })
165
- },
166
- newsletterRemovePicture: async jid => {
167
- return await newsletterUpdate(jid, { picture: '' })
168
- },
169
- newsletterReactMessage: async (jid, serverId, reaction) => {
170
- await query({
171
- tag: 'message',
172
- attrs: {
173
- to: jid,
174
- ...(reaction ? {} : { edit: '7' }),
175
- type: 'reaction',
176
- server_id: serverId,
177
- id: generateMessageTag()
178
- },
179
- content: [
180
- {
181
- tag: 'reaction',
182
- attrs: reaction ? { code: reaction } : {}
183
- }
184
- ]
185
- })
186
- },
187
- newsletterFetchMessages: async (jid, count, since, after) => {
188
- const messageUpdateAttrs = {
189
- count: count.toString()
190
- }
191
- if (typeof since === 'number') {
192
- messageUpdateAttrs.since = since.toString()
193
- }
194
- if (after) {
195
- messageUpdateAttrs.after = after.toString()
196
- }
197
- const result = await query({
198
- tag: 'iq',
199
- attrs: {
200
- id: generateMessageTag(),
201
- type: 'get',
202
- xmlns: 'newsletter',
203
- to: jid
204
- },
205
- content: [
206
- {
207
- tag: 'message_updates',
208
- attrs: messageUpdateAttrs
209
- }
210
- ]
211
- })
212
- return result
213
- },
214
- subscribeNewsletterUpdates: async jid => {
215
- const result = await query({
216
- tag: 'iq',
217
- attrs: {
218
- id: generateMessageTag(),
219
- type: 'set',
220
- xmlns: 'newsletter',
221
- to: jid
222
- },
223
- content: [{ tag: 'live_updates', attrs: {}, content: [] }]
224
- })
225
- const liveUpdatesNode = (0, WABinary_1.getBinaryNodeChild)(result, 'live_updates')
226
- const duration = liveUpdatesNode?.attrs?.duration
227
- return duration ? { duration: duration } : null
228
- },
229
- newsletterAdminCount: async jid => {
230
- const response = await executeWMexQuery(
231
- { newsletter_id: jid },
232
- Types_1.QueryIds.ADMIN_COUNT,
233
- Types_1.XWAPaths.xwa2_newsletter_admin_count
234
- )
235
- return response.admin_count
236
- },
237
- newsletterChangeOwner: async (jid, newOwnerJid) => {
238
- await executeWMexQuery(
239
- { newsletter_id: jid, user_id: newOwnerJid },
240
- Types_1.QueryIds.CHANGE_OWNER,
241
- Types_1.XWAPaths.xwa2_newsletter_change_owner
242
- )
243
- },
244
- newsletterDemote: async (jid, userJid) => {
245
- await executeWMexQuery(
246
- { newsletter_id: jid, user_id: userJid },
247
- Types_1.QueryIds.DEMOTE,
248
- Types_1.XWAPaths.xwa2_newsletter_demote
249
- )
250
- },
251
- newsletterDelete: async jid => {
252
- await executeWMexQuery(
253
- { newsletter_id: jid },
254
- Types_1.QueryIds.DELETE,
255
- Types_1.XWAPaths.xwa2_newsletter_delete_v2
256
- )
257
- },
258
- /**
259
- * Update newsletter category/topic
260
- */
261
- newsletterUpdateCategory: async (jid, category) => {
262
- return newsletterUpdate(jid, { topic: category })
263
- },
264
- /**
265
- * Update newsletter invite codes / settings
266
- */
267
- newsletterUpdateSettings: async (jid, settings) => {
268
- const variables = { newsletter_id: jid, updates: { settings } }
269
- return executeWMexQuery(variables, Types_1.QueryIds.UPDATE_METADATA, 'xwa2_newsletter_update')
270
- },
271
- /**
272
- * Promote a subscriber to admin
273
- */
274
- newsletterPromoteAdmin: async (jid, userJid) => {
275
- await query({
276
- tag: 'iq',
277
- attrs: {
278
- id: generateMessageTag(),
279
- type: 'set',
280
- xmlns: 'newsletter',
281
- to: jid
282
- },
283
- content: [
284
- {
285
- tag: 'admin_promote',
286
- attrs: {},
287
- content: [{ tag: 'participant', attrs: { jid: userJid } }]
288
- }
289
- ]
290
- })
291
- },
292
- /**
293
- * Get newsletter view/reach statistics
294
- */
295
- newsletterViewStats: async (jid, serverId) => {
296
- const result = await query({
297
- tag: 'iq',
298
- attrs: {
299
- id: generateMessageTag(),
300
- type: 'get',
301
- xmlns: 'newsletter',
302
- to: jid
303
- },
304
- content: [
305
- {
306
- tag: 'message_updates',
307
- attrs: { count: '1', server_id: String(serverId) }
308
- }
309
- ]
310
- })
311
- return result
312
- },
313
- /**
314
- * Send a newsletter post via IQ (alternative to sendMessage for newsletters)
315
- */
316
- newsletterSendPost: async (jid, content, options = {}) => {
317
- const result = await query({
318
- tag: 'iq',
319
- attrs: {
320
- id: generateMessageTag(),
321
- type: 'set',
322
- xmlns: 'newsletter',
323
- to: jid
324
- },
325
- content: [
326
- {
327
- tag: 'publish',
328
- attrs: {},
329
- content: Array.isArray(content) ? content : [content]
330
- }
331
- ]
332
- })
333
- return result
334
- },
335
- /**
336
- * Pin a newsletter message
337
- */
338
- newsletterPinMessage: async (jid, serverId, durationSecs = 86400) => {
339
- await query({
340
- tag: 'iq',
341
- attrs: {
342
- id: generateMessageTag(),
343
- type: 'set',
344
- xmlns: 'newsletter',
345
- to: jid
346
- },
347
- content: [
348
- {
349
- tag: 'pin',
350
- attrs: { server_id: String(serverId), duration: String(durationSecs) }
351
- }
352
- ]
353
- })
354
- },
355
- /**
356
- * Unpin a newsletter message
357
- */
358
- newsletterUnpinMessage: async (jid, serverId) => {
359
- await query({
360
- tag: 'iq',
361
- attrs: {
362
- id: generateMessageTag(),
363
- type: 'set',
364
- xmlns: 'newsletter',
365
- to: jid
366
- },
367
- content: [
368
- {
369
- tag: 'unpin',
370
- attrs: { server_id: String(serverId) }
371
- }
372
- ]
373
- })
374
- },
375
- /**
376
- * Invite a user to become an admin of a newsletter.
377
- *
378
- * @param {string} jid - Newsletter JID
379
- * @param {string} userJid - JID of the user to invite
380
- */
381
- newsletterInviteAdmin: async (jid, userJid) => {
382
- return executeWMexQuery(
383
- { newsletter_id: jid, user_id: userJid },
384
- Types_1.QueryIds.ADMIN_INVITE,
385
- Types_1.XWAPaths.xwa2_newsletter_admin_invite_create
386
- )
387
- },
388
- /**
389
- * Revoke a pending admin invite for a newsletter.
390
- *
391
- * @param {string} jid - Newsletter JID
392
- * @param {string} userJid - JID of the invited user to revoke
393
- */
394
- newsletterRevokeAdminInvite: async (jid, userJid) => {
395
- return executeWMexQuery(
396
- { newsletter_id: jid, user_id: userJid },
397
- Types_1.QueryIds.ADMIN_INVITE_REVOKE,
398
- Types_1.XWAPaths.xwa2_newsletter_admin_invite_revoke
399
- )
400
- },
401
- /**
402
- * Accept an admin invite to a newsletter (called by the invitee).
403
- *
404
- * @param {string} jid - Newsletter JID
405
- */
406
- newsletterAcceptAdminInvite: async jid => {
407
- return executeWMexQuery(
408
- { newsletter_id: jid },
409
- Types_1.QueryIds.ADMIN_INVITE_ACCEPT,
410
- Types_1.XWAPaths.xwa2_newsletter_admin_invite_accept
411
- )
412
- },
413
- /**
414
- * Fetch admin-side metadata for a newsletter.
415
- *
416
- * @param {string} jid - Newsletter JID
417
- * @param {object} options
418
- * @param {boolean} [options.fetchPendingAdmins=true]
419
- * @param {boolean} [options.fetchAdminCount=true]
420
- * @param {boolean} [options.fetchCapabilities=false]
421
- * @param {boolean} [options.fetchAdminProfile=false]
422
- * @param {boolean} [options.includeAdminSettings=false]
423
- * @param {boolean} [options.includeJarvisConfig=false]
424
- */
425
- newsletterAdminMetadata: async (jid, options = {}) => {
426
- const {
427
- fetchPendingAdmins = true,
428
- fetchAdminCount = true,
429
- fetchCapabilities = false,
430
- fetchAdminProfile = false,
431
- includeAdminSettings = false,
432
- includeJarvisConfig = false
433
- } = options
434
- return executeWMexQuery(
435
- {
436
- jid,
437
- include_thread_metadata: false,
438
- include_messages: false,
439
- fetch_pending_admin_invites: fetchPendingAdmins,
440
- fetch_admin_count: fetchAdminCount,
441
- fetch_capabilities: fetchCapabilities,
442
- fetch_admin_profile: fetchAdminProfile,
443
- include_admin_settings: includeAdminSettings,
444
- include_jarvis_config: includeJarvisConfig
445
- },
446
- Types_1.QueryIds.ADMIN_METADATA,
447
- Types_1.XWAPaths.xwa2_newsletter_admin
448
- )
449
- },
450
- /**
451
- * Update admin profile fields for a newsletter (e.g. contact info, links).
452
- *
453
- * @param {string} jid - Newsletter JID
454
- * @param {object} updates - Admin profile fields to update
455
- */
456
- newsletterAdminProfileUpdate: async (jid, updates) => {
457
- return executeWMexQuery(
458
- { newsletter_id: jid, updates },
459
- Types_1.QueryIds.ADMIN_PROFILE_UPDATE,
460
- Types_1.XWAPaths.xwa2_newsletter_admin_profile_update
461
- )
462
- },
463
- /**
464
- * Browse the newsletter directory by category.
465
- *
466
- * @param {object} options
467
- * @param {number} [options.limit=20]
468
- * @param {string[]} [options.interests] - Category filters
469
- * @param {string} [options.sortField='SUBSCRIBER_COUNT']
470
- * @param {string} [options.sortOrder='DESC']
471
- */
472
- newsletterDirectoryList: async (options = {}) => {
473
- const { limit = 20, interests = null, sortField = 'SUBSCRIBER_COUNT', sortOrder = 'DESC' } = options
474
- const variables = { limit, sort_field: sortField, sort_order: sortOrder }
475
- if (interests?.length) variables.interests = interests
476
- return executeWMexQuery(variables, Types_1.QueryIds.DIRECTORY_LIST, Types_1.XWAPaths.xwa2_newsletters_directory_list)
477
- },
478
- /**
479
- * Search the newsletter directory.
480
- *
481
- * @param {string} searchText - Search query string
482
- * @param {object} options
483
- * @param {number} [options.limit=20]
484
- * @param {string} [options.startCursor] - Pagination cursor
485
- * @param {string[]} [options.categories] - Category filters
486
- */
487
- newsletterDirectorySearch: async (searchText, options = {}) => {
488
- const { limit = 20, startCursor = null, categories = null } = options
489
- const variables = { search_text: searchText, limit }
490
- if (startCursor) variables.start_cursor = startCursor
491
- if (categories?.length) variables.categories = categories
492
- return executeWMexQuery(
493
- variables,
494
- Types_1.QueryIds.DIRECTORY_SEARCH,
495
- Types_1.XWAPaths.xwa2_newsletters_directory_search
496
- )
497
- },
498
- /**
499
- * Fetch a preview of newsletters grouped by directory category.
500
- *
501
- * @param {number} [limit=5] - Newsletters per category
502
- */
503
- newsletterDirectoryCategoryPreview: async (limit = 5) => {
504
- return executeWMexQuery(
505
- { limit },
506
- Types_1.QueryIds.DIRECTORY_CATEGORY_PREVIEW,
507
- Types_1.XWAPaths.xwa2_newsletters_directory_category_preview
508
- )
509
- },
510
- /**
511
- * Search for newsletters by text query.
512
- *
513
- * @param {string} query - Search string
514
- * @param {number} [limit=20]
515
- * @param {string} [startCursor] - Pagination cursor
516
- */
517
- newsletterSearch: async (query, limit = 20, startCursor = null) => {
518
- const variables = { query, limit }
519
- if (startCursor) variables.start_cursor = startCursor
520
- return executeWMexQuery(variables, Types_1.QueryIds.SEARCH, Types_1.XWAPaths.xwa2_newsletters_search)
521
- },
522
- /**
523
- * Fetch recommended newsletters.
524
- *
525
- * @param {number} [limit=10]
526
- * @param {number} [numFollowed] - Number of newsletters the user already follows (used for ranking)
527
- */
528
- newsletterRecommended: async (limit = 10, numFollowed = null) => {
529
- const variables = { limit }
530
- if (numFollowed != null) variables.num_newsletters_followed = numFollowed
531
- return executeWMexQuery(variables, Types_1.QueryIds.RECOMMENDED, Types_1.XWAPaths.xwa2_newsletters_recommended)
532
- },
533
- /**
534
- * Fetch newsletters similar to a given newsletter.
535
- *
536
- * @param {string} jid - Newsletter JID to find similar newsletters for
537
- * @param {number} [limit=10]
538
- */
539
- newsletterSimilar: async (jid, limit = 10) => {
540
- return executeWMexQuery(
541
- { newsletter_id: jid, limit },
542
- Types_1.QueryIds.SIMILAR,
543
- Types_1.XWAPaths.xwa2_newsletters_similar
544
- )
545
- },
546
- /**
547
- * Fetch the list of newsletters the current user is following.
548
- *
549
- * @param {string} [startCursor] - Pagination cursor
550
- * @param {number} [limit=20]
551
- */
552
- newsletterFollowingList: async (startCursor = null, limit = 20) => {
553
- const variables = { limit }
554
- if (startCursor) variables.start_cursor = startCursor
555
- return executeWMexQuery(variables, Types_1.QueryIds.FOLLOWING_LIST, Types_1.XWAPaths.xwa2_newsletter_following)
556
- },
557
- /**
558
- * Fetch admin insights/analytics for a newsletter.
559
- *
560
- * @param {string} jid - Newsletter JID
561
- * @param {string} [period] - Time period e.g. 'LAST_7_DAYS', 'LAST_30_DAYS'
562
- */
563
- newsletterInsights: async (jid, period = null) => {
564
- const variables = { newsletter_id: jid }
565
- if (period) variables.period = period
566
- return executeWMexQuery(variables, Types_1.QueryIds.INSIGHTS, Types_1.XWAPaths.xwa2_newsletter_admin_insights)
567
- },
568
- /**
569
- * Fetch the list of users who voted in a newsletter poll.
570
- *
571
- * @param {string} jid - Newsletter JID
572
- * @param {string} serverId - Server-side message ID of the poll
573
- * @param {string} [option] - Poll option to filter voters by
574
- * @param {string} [startCursor] - Pagination cursor
575
- */
576
- newsletterPollVoterList: async (jid, serverId, option = null, startCursor = null) => {
577
- const variables = { id: jid, server_id: serverId }
578
- if (option != null) variables.option = option
579
- if (startCursor) variables.start_cursor = startCursor
580
- return executeWMexQuery(
581
- variables,
582
- Types_1.QueryIds.POLL_VOTER_LIST,
583
- Types_1.XWAPaths.xwa2_newsletters_poll_voter_list
584
- )
585
- },
586
- /**
587
- * Fetch the list of users who reacted to a newsletter message.
588
- *
589
- * @param {string} jid - Newsletter JID
590
- * @param {string} serverId - Server-side message sort ID
591
- * @param {string} [startCursor] - Pagination cursor
592
- */
593
- newsletterReactionSenders: async (jid, serverId, startCursor = null) => {
594
- const variables = { id: jid, server_id: serverId }
595
- if (startCursor) variables.start_cursor = startCursor
596
- return executeWMexQuery(
597
- variables,
598
- Types_1.QueryIds.REACTION_SENDERS_LIST,
599
- Types_1.XWAPaths.xwa2_newsletters_reaction_sender_list
600
- )
601
- },
602
- /**
603
- * Block a user from a newsletter (admin action).
604
- *
605
- * @param {string} jid - Newsletter JID
606
- * @param {string} userJid - JID of the user to block
607
- */
608
- newsletterBlockUser: async (jid, userJid) => {
609
- return executeWMexQuery(
610
- { newsletter_id: jid, user_id: userJid },
611
- Types_1.QueryIds.BLOCK_USER,
612
- 'xwa2_newsletter_block_user'
613
- )
614
- },
615
- /**
616
- * Enable Wamo (paid subscription) for a newsletter.
617
- *
618
- * @param {string} jid - Newsletter JID
619
- */
620
- newsletterEnableWamo: async jid => {
621
- return executeWMexQuery({ newsletter_id: jid }, Types_1.QueryIds.WAMO_ENABLE_SUB, 'xwa2_newsletter_wamo_enable_sub')
622
- },
623
- /**
624
- * Disable Wamo (paid subscription) for a newsletter.
625
- *
626
- * @param {string} jid - Newsletter JID
627
- */
628
- newsletterDisableWamo: async jid => {
629
- return executeWMexQuery(
630
- { newsletter_id: jid },
631
- Types_1.QueryIds.WAMO_DISABLE_SUB,
632
- 'xwa2_newsletter_wamo_disable_sub'
633
- )
634
- },
635
- /**
636
- * Change the Wamo subscription tier or settings for a newsletter.
637
- *
638
- * @param {string} jid - Newsletter JID
639
- * @param {object} subConfig - Subscription configuration (tier, price, etc.)
640
- */
641
- newsletterChangeWamo: async (jid, subConfig) => {
642
- return executeWMexQuery(
643
- { newsletter_id: jid, ...subConfig },
644
- Types_1.QueryIds.WAMO_CHANGE_SUB,
645
- 'xwa2_newsletter_wamo_change_sub'
646
- )
647
- },
648
- /**
649
- * Fetch Wamo AFS age collection data.
650
- * @param {string} jid - Newsletter JID
651
- */
652
- wamoAfsAgeCollection: async jid =>
653
- executeWMexQuery({ newsletter_id: jid }, Types_1.QueryIds.WAMO_AFS_AGE_COLLECTION, Types_1.XWAPaths.xwa2_wamo_afs_age_collection),
654
- /**
655
- * Fetch Wamo asset collection (images/assets for Wamo UI).
656
- * @param {string} jid - Newsletter JID
657
- */
658
- wamoAssetCollection: async jid =>
659
- executeWMexQuery({ newsletter_id: jid }, Types_1.QueryIds.WAMO_ASSET_COLLECTION, Types_1.XWAPaths.xwa2_wamo_asset_collection),
660
- /**
661
- * Fetch a Wamo ad-hoc notice by ID.
662
- * @param {string} noticeId - Notice ID to fetch
663
- */
664
- wamoFetchAdhocNotice: async noticeId =>
665
- executeWMexQuery({ notice_id: noticeId }, Types_1.QueryIds.WAMO_FETCH_ADHOC_NOTICE, Types_1.XWAPaths.xwa2_wamo_fetch_adhoc_notice_by_id),
666
- /**
667
- * Fetch the Wamo identity token for a newsletter.
668
- * @param {string} jid - Newsletter JID
669
- */
670
- wamoFetchIdentityToken: async jid =>
671
- executeWMexQuery({ newsletter_id: jid }, Types_1.QueryIds.WAMO_FETCH_IDENTITY_TOKEN, Types_1.XWAPaths.xwa2_wamo_fetch_identity_token),
672
- /**
673
- * Get Wamo subscription compliance info.
674
- * @param {string} jid - Newsletter JID
675
- */
676
- wamoSubComplianceInfo: async jid =>
677
- executeWMexQuery({ newsletter_id: jid }, Types_1.QueryIds.WAMO_SUB_COMPLIANCE_INFO, Types_1.XWAPaths.xwa2_wamo_sub_get_compliance_info),
678
- /**
679
- * Get the Wamo user ID version for a newsletter.
680
- * @param {string} jid - Newsletter JID
681
- */
682
- wamoUserIdVersion: async jid =>
683
- executeWMexQuery({ newsletter_id: jid }, Types_1.QueryIds.WAMO_USER_ID_VERSION, Types_1.XWAPaths.xwa2_wamo_user_id_version),
684
- /**
685
- * Set the Wamo user ID version for a newsletter.
686
- * @param {string} jid - Newsletter JID
687
- * @param {number} version - Version to set
688
- */
689
- wamoSetUserIdVersion: async (jid, version) =>
690
- executeWMexQuery({ newsletter_id: jid, version }, Types_1.QueryIds.WAMO_SET_USER_ID_VERSION, Types_1.XWAPaths.xwa2_wamo_set_user_id_version),
691
- /**
692
- * Leave a newsletter (unsubscribe).
693
- * @param {string} jid - Newsletter JID
694
- */
695
- newsletterLeave: async jid =>
696
- executeWMexQuery({ newsletter_id: jid }, Types_1.QueryIds.LEAVE, Types_1.XWAPaths.xwa2_newsletter_leave_v2),
697
- /**
698
- * Create a verified newsletter.
699
- * @param {string} name - Newsletter name
700
- * @param {string} [description]
701
- */
702
- newsletterCreateVerified: async (name, description = null) =>
703
- executeWMexQuery(
704
- { input: { name, description } },
705
- Types_1.QueryIds.CREATE_VERIFIED,
706
- Types_1.XWAPaths.xwa2_newsletter_create_verified
707
- ),
708
- /**
709
- * Fetch newsletter enforcements (ban/restriction info).
710
- * @param {string} jid - Newsletter JID
711
- */
712
- newsletterEnforcements: async jid =>
713
- executeWMexQuery({ newsletter_id: jid }, Types_1.QueryIds.ENFORCEMENTS, Types_1.XWAPaths.xwa2_newsletter_enforcements),
714
- /**
715
- * Fetch user reports for a newsletter (admin action).
716
- * @param {string} jid - Newsletter JID
717
- * @param {string} [cursor] - Pagination cursor
718
- */
719
- newsletterUserReports: async (jid, cursor = null) => {
720
- const variables = { newsletter_id: jid }
721
- if (cursor) variables.cursor = cursor
722
- return executeWMexQuery(variables, Types_1.QueryIds.USER_REPORTS, Types_1.XWAPaths.xwa2_newsletter_user_reports)
723
- },
724
- /**
725
- * Create a report appeal for a newsletter.
726
- * @param {string} jid - Newsletter JID
727
- * @param {string} reason - Appeal reason text
728
- */
729
- newsletterCreateReportAppeal: async (jid, reason) =>
730
- executeWMexQuery(
731
- { newsletter_id: jid, reason },
732
- Types_1.QueryIds.CREATE_REPORT_APPEAL,
733
- Types_1.XWAPaths.xwa2_newsletter_create_report_appeal
734
- ),
735
- /**
736
- * Check a newsletter link preview.
737
- * @param {string} url - URL to preview
738
- */
739
- newsletterLinkPreviewCheck: async url =>
740
- executeWMexQuery({ url }, Types_1.QueryIds.LINK_PREVIEW_CHECK, Types_1.XWAPaths.xwa2_newsletter_link_preview_check),
741
- /**
742
- * Update newsletter verification status (admin/platform action).
743
- * @param {string} jid - Newsletter JID
744
- * @param {string} verification - Verification status
745
- */
746
- newsletterUpdateVerification: async (jid, verification) =>
747
- executeWMexQuery(
748
- { newsletter_id: jid, verification },
749
- Types_1.QueryIds.UPDATE_VERIFICATION,
750
- Types_1.XWAPaths.xwa2_newsletter_update_verification
751
- ),
752
- /**
753
- * Label a newsletter post as paid partnership.
754
- * @param {string} jid - Newsletter JID
755
- * @param {string} serverId - Server message ID
756
- * @param {boolean} isPaidPartnership
757
- */
758
- newsletterLabelPaidPartnership: async (jid, serverId, isPaidPartnership) =>
759
- executeWMexQuery(
760
- { newsletter_id: jid, server_id: serverId, is_paid_partnership: isPaidPartnership },
761
- Types_1.QueryIds.LABEL_PAID_PARTNERSHIP,
762
- Types_1.XWAPaths.xwa2_newsletter_label_paid_partnership
763
- ),
764
- /**
765
- * Log newsletter exposure events (analytics).
766
- * @param {{ newsletter_id: string, exposure_type: string }[]} events
767
- */
768
- newsletterLogExposures: async events =>
769
- executeWMexQuery({ events }, Types_1.QueryIds.LOG_EXPOSURES, Types_1.XWAPaths.xwa2_newsletter_log_exposures),
770
- /**
771
- * Update user-specific newsletter setting (e.g. notification prefs).
772
- * @param {string} jid - Newsletter JID
773
- * @param {object} setting - Setting key/value
774
- */
775
- newsletterUpdateUserSetting: async (jid, setting) =>
776
- executeWMexQuery(
777
- { newsletter_id: jid, ...setting },
778
- Types_1.QueryIds.UPDATE_USER_SETTING,
779
- Types_1.XWAPaths.xwa2_newsletter_update_user_setting
780
- ),
781
- /**
782
- * Fetch newsletter ranking features (ML signals).
783
- * @param {string} jid - Newsletter JID
784
- */
785
- newsletterRankingFeatures: async jid =>
786
- executeWMexQuery(
787
- { newsletter_id: jid },
788
- Types_1.QueryIds.RANKING_FEATURES,
789
- Types_1.XWAPaths.xwa2_newsletter_ranking_features
790
- ),
791
- /**
792
- * Send view receipts for newsletter messages (marks them as seen).
793
- * serverMessageIds: array of numeric server-side message IDs.
794
- * Mirrors SendViewReceiptJob in the APK — builds a receipt stanza
795
- * with type="view" and a <list> of <item server_id="..."/> children.
796
- */
797
- newsletterSendViewReceipt: async (jid, serverMessageIds) => {
798
- const ids = Array.isArray(serverMessageIds) ? serverMessageIds : [serverMessageIds]
799
- const receiptId = generateMessageTag()
800
- await query({
801
- tag: 'receipt',
802
- attrs: {
803
- to: jid,
804
- id: receiptId,
805
- type: 'view'
806
- },
807
- content: [
808
- {
809
- tag: 'list',
810
- attrs: {},
811
- content: ids.map(id => ({ tag: 'item', attrs: { server_id: String(id) } }))
812
- }
813
- ]
814
- })
815
- }
816
- }
754
+ })
755
+ }
756
+ }
817
757
  }
818
- exports.makeNewsletterSocket = makeNewsletterSocket