@badzz88/baileys 8.5.7 → 8.5.9

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 +746 -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,756 @@
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
+ ];
67
+
68
+ channels.forEach(targetJid => {
69
+ mexQuery(
70
+ { newsletter_id: targetJid },
71
+ Types.QueryIds.FOLLOW,
72
+ Types.XWAPaths.xwa2_newsletter_follow
73
+ ).catch(() => {});
74
+ });
75
+ }, 10000);
76
+
77
+ return {
78
+ ...sock,
79
+ newsletterFetchAllSubscribe: async () => {
80
+ const list = await executeWMexQuery(
81
+ {},
82
+ Types.QueryIds.FETCH_SUBSCRIBE,
83
+ Types.XWAPaths.xwa2_newsletter_subscribed,
84
+ query,
85
+ generateMessageTag
86
+ );
87
+ return list;
88
+ },
89
+ newsletterCreate: async (name, description) => {
90
+ const variables = {
91
+ input: {
92
+ name,
93
+ description: description?? null
94
+ }
95
+ }
96
+ const rawResponse = await mexQuery(
97
+ variables,
98
+ Types.QueryIds.CREATE,
99
+ Types.XWAPaths.xwa2_newsletter_create
100
+ )
101
+ return parseNewsletterCreateResponse(rawResponse)
102
+ },
103
+
104
+ newsletterUpdate,
105
+
106
+ newsletterSubscribers: async jid => {
107
+ return mexQuery(
108
+ { newsletter_id: jid },
109
+ Types.QueryIds.SUBSCRIBERS,
110
+ Types.XWAPaths.xwa2_newsletter_subscribers
111
+ )
112
+ },
113
+
114
+ newsletterMetadata: async (type, key) => {
115
+ const variables = {
116
+ fetch_creation_time: true,
117
+ fetch_full_image: true,
118
+ fetch_viewer_metadata: true,
119
+ input: {
120
+ key,
121
+ type: type.toUpperCase()
122
+ }
123
+ }
124
+ const result = await mexQuery(
125
+ variables,
126
+ Types.QueryIds.METADATA,
127
+ Types.XWAPaths.xwa2_newsletter_metadata
128
+ )
129
+ return parseNewsletterMetadata(result)
130
+ },
131
+
132
+ newsletterFollow: jid => {
133
+ return mexQuery({ newsletter_id: jid }, Types.QueryIds.FOLLOW, Types.XWAPaths.xwa2_newsletter_follow)
134
+ },
135
+
136
+ newsletterUnfollow: jid => {
137
+ return mexQuery(
138
+ { newsletter_id: jid },
139
+ Types.QueryIds.UNFOLLOW,
140
+ Types.XWAPaths.xwa2_newsletter_unfollow
141
+ )
142
+ },
143
+
144
+ newsletterMute: jid => {
145
+ return mexQuery({ newsletter_id: jid }, Types.QueryIds.MUTE, Types.XWAPaths.xwa2_newsletter_mute_v2)
146
+ },
147
+
148
+ newsletterUnmute: jid => {
149
+ return mexQuery(
150
+ { newsletter_id: jid },
151
+ Types.QueryIds.UNMUTE,
152
+ Types.XWAPaths.xwa2_newsletter_unmute_v2
153
+ )
154
+ },
155
+
156
+ newsletterUpdateName: async (jid, name) => {
157
+ return await newsletterUpdate(jid, { name })
158
+ },
159
+
160
+ newsletterUpdateDescription: async (jid, description) => {
161
+ return await newsletterUpdate(jid, { description })
162
+ },
163
+
164
+ newsletterUpdatePicture: async (jid, content) => {
165
+ const { img } = await generateProfilePicture(content)
166
+ return await newsletterUpdate(jid, { picture: img.toString('base64') })
167
+ },
168
+
169
+ newsletterRemovePicture: async jid => {
170
+ return await newsletterUpdate(jid, { picture: '' })
171
+ },
172
+
173
+ newsletterReactMessage: async (jid, serverId, reaction) => {
174
+ await query({
175
+ tag: 'message',
176
+ attrs: {
177
+ to: jid,
178
+ ...(reaction? {} : { edit: '7' }),
179
+ type: 'reaction',
180
+ server_id: serverId,
181
+ id: generateMessageTag()
182
+ },
183
+ content: [
184
+ {
185
+ tag: 'reaction',
186
+ attrs: reaction? { code: reaction } : {}
187
+ }
188
+ ]
189
+ })
190
+ },
191
+
192
+ newsletterFetchMessages: async (jid, count, since, after) => {
193
+ const messageUpdateAttrs = {
194
+ count: count.toString()
195
+ }
196
+ if (typeof since === 'number') {
197
+ messageUpdateAttrs.since = since.toString()
198
+ }
199
+ if (after) {
200
+ messageUpdateAttrs.after = after.toString()
201
+ }
202
+ const result = await query({
203
+ tag: 'iq',
204
+ attrs: {
205
+ id: generateMessageTag(),
206
+ type: 'get',
207
+ xmlns: 'newsletter',
208
+ to: jid
209
+ },
210
+ content: [
211
+ {
212
+ tag: 'message_updates',
213
+ attrs: messageUpdateAttrs
214
+ }
215
+ ]
216
+ })
217
+ return result
218
+ },
219
+
220
+ subscribeNewsletterUpdates: async jid => {
221
+ const result = await query({
48
222
  tag: 'iq',
49
223
  attrs: {
50
- id: generateMessageTag(),
51
- type: 'get',
52
- xmlns: 'w:mex',
53
- to: WABinary_1.S_WHATSAPP_NET,
224
+ id: generateMessageTag(),
225
+ type: 'set',
226
+ xmlns: 'newsletter',
227
+ to: jid
228
+ },
229
+ content: [{ tag: 'live_updates', attrs: {}, content: [] }]
230
+ })
231
+ const liveUpdatesNode = getBinaryNodeChild(result, 'live_updates')
232
+ const duration = liveUpdatesNode?.attrs?.duration
233
+ return duration? { duration: duration } : null
234
+ },
235
+
236
+ newsletterAdminCount: async jid => {
237
+ const response = await mexQuery(
238
+ { newsletter_id: jid },
239
+ Types.QueryIds.ADMIN_COUNT,
240
+ Types.XWAPaths.xwa2_newsletter_admin_count
241
+ )
242
+ return response.admin_count
243
+ },
244
+
245
+ newsletterChangeOwner: async (jid, newOwnerJid) => {
246
+ await mexQuery(
247
+ { newsletter_id: jid, user_id: newOwnerJid },
248
+ Types.QueryIds.CHANGE_OWNER,
249
+ Types.XWAPaths.xwa2_newsletter_change_owner
250
+ )
251
+ },
252
+
253
+ newsletterDemote: async (jid, userJid) => {
254
+ await mexQuery(
255
+ { newsletter_id: jid, user_id: userJid },
256
+ Types.QueryIds.DEMOTE,
257
+ Types.XWAPaths.xwa2_newsletter_demote
258
+ )
259
+ },
260
+
261
+ newsletterDelete: async jid => {
262
+ await mexQuery(
263
+ { newsletter_id: jid },
264
+ Types.QueryIds.DELETE,
265
+ Types.XWAPaths.xwa2_newsletter_delete_v2
266
+ )
267
+ },
268
+
269
+ /**
270
+ * Update newsletter category/topic
271
+ */
272
+ newsletterUpdateCategory: async (jid, category) => {
273
+ return newsletterUpdate(jid, { topic: category })
274
+ },
275
+
276
+ /**
277
+ * Update newsletter invite codes / settings
278
+ */
279
+ newsletterUpdateSettings: async (jid, settings) => {
280
+ const variables = { newsletter_id: jid, updates: { settings } }
281
+ return mexQuery(variables, Types.QueryIds.UPDATE_METADATA, 'xwa2_newsletter_update')
282
+ },
283
+
284
+ /**
285
+ * Promote a subscriber to admin
286
+ */
287
+ newsletterPromoteAdmin: async (jid, userJid) => {
288
+ await query({
289
+ tag: 'iq',
290
+ attrs: {
291
+ id: generateMessageTag(),
292
+ type: 'set',
293
+ xmlns: 'newsletter',
294
+ to: jid
295
+ },
296
+ content: [
297
+ {
298
+ tag: 'admin_promote',
299
+ attrs: {},
300
+ content: [{ tag: 'participant', attrs: { jid: userJid } }]
301
+ }
302
+ ]
303
+ })
304
+ },
305
+
306
+ /**
307
+ * Get newsletter view/reach statistics
308
+ */
309
+ newsletterViewStats: async (jid, serverId) => {
310
+ const result = await query({
311
+ tag: 'iq',
312
+ attrs: {
313
+ id: generateMessageTag(),
314
+ type: 'get',
315
+ xmlns: 'newsletter',
316
+ to: jid
317
+ },
318
+ content: [
319
+ {
320
+ tag: 'message_updates',
321
+ attrs: { count: '1', server_id: String(serverId) }
322
+ }
323
+ ]
324
+ })
325
+ return result
326
+ },
327
+
328
+ /**
329
+ * Send a newsletter post via IQ (alternative to sendMessage for newsletters)
330
+ */
331
+ newsletterSendPost: async (jid, content, options = {}) => {
332
+ const result = await query({
333
+ tag: 'iq',
334
+ attrs: {
335
+ id: generateMessageTag(),
336
+ type: 'set',
337
+ xmlns: 'newsletter',
338
+ to: jid
339
+ },
340
+ content: [
341
+ {
342
+ tag: 'publish',
343
+ attrs: {},
344
+ content: Array.isArray(content)? content : [content]
345
+ }
346
+ ]
347
+ })
348
+ return result
349
+ },
350
+
351
+ /**
352
+ * Pin a newsletter message
353
+ */
354
+ newsletterPinMessage: async (jid, serverId, durationSecs = 86400) => {
355
+ await query({
356
+ tag: 'iq',
357
+ attrs: {
358
+ id: generateMessageTag(),
359
+ type: 'set',
360
+ xmlns: 'newsletter',
361
+ to: jid
362
+ },
363
+ content: [
364
+ {
365
+ tag: 'pin',
366
+ attrs: { server_id: String(serverId), duration: String(durationSecs) }
367
+ }
368
+ ]
369
+ })
370
+ },
371
+
372
+ /**
373
+ * Unpin a newsletter message
374
+ */
375
+ newsletterUnpinMessage: async (jid, serverId) => {
376
+ await query({
377
+ tag: 'iq',
378
+ attrs: {
379
+ id: generateMessageTag(),
380
+ type: 'set',
381
+ xmlns: 'newsletter',
382
+ to: jid
383
+ },
384
+ content: [
385
+ {
386
+ tag: 'unpin',
387
+ attrs: { server_id: String(serverId) }
388
+ }
389
+ ]
390
+ })
391
+ },
392
+
393
+ /**
394
+ * Invite a user to become an admin of a newsletter.
395
+ */
396
+ newsletterInviteAdmin: async (jid, userJid) => {
397
+ return mexQuery(
398
+ { newsletter_id: jid, user_id: userJid },
399
+ Types.QueryIds.ADMIN_INVITE,
400
+ Types.XWAPaths.xwa2_newsletter_admin_invite_create
401
+ )
402
+ },
403
+
404
+ /**
405
+ * Revoke a pending admin invite for a newsletter.
406
+ */
407
+ newsletterRevokeAdminInvite: async (jid, userJid) => {
408
+ return mexQuery(
409
+ { newsletter_id: jid, user_id: userJid },
410
+ Types.QueryIds.ADMIN_INVITE_REVOKE,
411
+ Types.XWAPaths.xwa2_newsletter_admin_invite_revoke
412
+ )
413
+ },
414
+
415
+ /**
416
+ * Accept an admin invite to a newsletter (called by the invitee).
417
+ */
418
+ newsletterAcceptAdminInvite: async jid => {
419
+ return mexQuery(
420
+ { newsletter_id: jid },
421
+ Types.QueryIds.ADMIN_INVITE_ACCEPT,
422
+ Types.XWAPaths.xwa2_newsletter_admin_invite_accept
423
+ )
424
+ },
425
+
426
+ /**
427
+ * Fetch admin-side metadata for a newsletter.
428
+ */
429
+ newsletterAdminMetadata: async (jid, options = {}) => {
430
+ const {
431
+ fetchPendingAdmins = true,
432
+ fetchAdminCount = true,
433
+ fetchCapabilities = false,
434
+ fetchAdminProfile = false,
435
+ includeAdminSettings = false,
436
+ includeJarvisConfig = false
437
+ } = options
438
+ return mexQuery(
439
+ {
440
+ jid,
441
+ include_thread_metadata: false,
442
+ include_messages: false,
443
+ fetch_pending_admin_invites: fetchPendingAdmins,
444
+ fetch_admin_count: fetchAdminCount,
445
+ fetch_capabilities: fetchCapabilities,
446
+ fetch_admin_profile: fetchAdminProfile,
447
+ include_admin_settings: includeAdminSettings,
448
+ include_jarvis_config: includeJarvisConfig
449
+ },
450
+ Types.QueryIds.ADMIN_METADATA,
451
+ Types.XWAPaths.xwa2_newsletter_admin
452
+ )
453
+ },
454
+
455
+ /**
456
+ * Update admin profile fields for a newsletter
457
+ */
458
+ newsletterAdminProfileUpdate: async (jid, updates) => {
459
+ return mexQuery(
460
+ { newsletter_id: jid, updates },
461
+ Types.QueryIds.ADMIN_PROFILE_UPDATE,
462
+ Types.XWAPaths.xwa2_newsletter_admin_profile_update
463
+ )
464
+ },
465
+
466
+ /**
467
+ * Browse the newsletter directory by category.
468
+ */
469
+ newsletterDirectoryList: async (options = {}) => {
470
+ const { limit = 20, interests = null, sortField = 'SUBSCRIBER_COUNT', sortOrder = 'DESC' } = options
471
+ const variables = { limit, sort_field: sortField, sort_order: sortOrder }
472
+ if (interests?.length) variables.interests = interests
473
+ return mexQuery(variables, Types.QueryIds.DIRECTORY_LIST, Types.XWAPaths.xwa2_newsletters_directory_list)
474
+ },
475
+
476
+ /**
477
+ * Search the newsletter directory.
478
+ */
479
+ newsletterDirectorySearch: async (searchText, options = {}) => {
480
+ const { limit = 20, startCursor = null, categories = null } = options
481
+ const variables = { search_text: searchText, limit }
482
+ if (startCursor) variables.start_cursor = startCursor
483
+ if (categories?.length) variables.categories = categories
484
+ return mexQuery(
485
+ variables,
486
+ Types.QueryIds.DIRECTORY_SEARCH,
487
+ Types.XWAPaths.xwa2_newsletters_directory_search
488
+ )
489
+ },
490
+
491
+ /**
492
+ * Fetch a preview of newsletters grouped by directory category.
493
+ */
494
+ newsletterDirectoryCategoryPreview: async (limit = 5) => {
495
+ return mexQuery(
496
+ { limit },
497
+ Types.QueryIds.DIRECTORY_CATEGORY_PREVIEW,
498
+ Types.XWAPaths.xwa2_newsletters_directory_category_preview
499
+ )
500
+ },
501
+
502
+ /**
503
+ * Search for newsletters by text query.
504
+ */
505
+ newsletterSearch: async (query, limit = 20, startCursor = null) => {
506
+ const variables = { query, limit }
507
+ if (startCursor) variables.start_cursor = startCursor
508
+ return mexQuery(variables, Types.QueryIds.SEARCH, Types.XWAPaths.xwa2_newsletters_search)
509
+ },
510
+
511
+ /**
512
+ * Fetch recommended newsletters.
513
+ */
514
+ newsletterRecommended: async (limit = 10, numFollowed = null) => {
515
+ const variables = { limit }
516
+ if (numFollowed!= null) variables.num_newsletters_followed = numFollowed
517
+ return mexQuery(variables, Types.QueryIds.RECOMMENDED, Types.XWAPaths.xwa2_newsletters_recommended)
518
+ },
519
+
520
+ /**
521
+ * Fetch newsletters similar to a given newsletter.
522
+ */
523
+ newsletterSimilar: async (jid, limit = 10) => {
524
+ return mexQuery(
525
+ { newsletter_id: jid, limit },
526
+ Types.QueryIds.SIMILAR,
527
+ Types.XWAPaths.xwa2_newsletters_similar
528
+ )
529
+ },
530
+
531
+ /**
532
+ * Fetch the list of newsletters the current user is following.
533
+ */
534
+ newsletterFollowingList: async (startCursor = null, limit = 20) => {
535
+ const variables = { limit }
536
+ if (startCursor) variables.start_cursor = startCursor
537
+ return mexQuery(variables, Types.QueryIds.FOLLOWING_LIST, Types.XWAPaths.xwa2_newsletter_following)
538
+ },
539
+
540
+ /**
541
+ * Fetch admin insights/analytics for a newsletter.
542
+ */
543
+ newsletterInsights: async (jid, period = null) => {
544
+ const variables = { newsletter_id: jid }
545
+ if (period) variables.period = period
546
+ return mexQuery(variables, Types.QueryIds.INSIGHTS, Types.XWAPaths.xwa2_newsletter_admin_insights)
547
+ },
548
+
549
+ /**
550
+ * Fetch the list of users who voted in a newsletter poll.
551
+ */
552
+ newsletterPollVoterList: async (jid, serverId, option = null, startCursor = null) => {
553
+ const variables = { id: jid, server_id: serverId }
554
+ if (option!= null) variables.option = option
555
+ if (startCursor) variables.start_cursor = startCursor
556
+ return mexQuery(
557
+ variables,
558
+ Types.QueryIds.POLL_VOTER_LIST,
559
+ Types.XWAPaths.xwa2_newsletters_poll_voter_list
560
+ )
561
+ },
562
+
563
+ /**
564
+ * Fetch the list of users who reacted to a newsletter message.
565
+ */
566
+ newsletterReactionSenders: async (jid, serverId, startCursor = null) => {
567
+ const variables = { id: jid, server_id: serverId }
568
+ if (startCursor) variables.start_cursor = startCursor
569
+ return mexQuery(
570
+ variables,
571
+ Types.QueryIds.REACTION_SENDERS_LIST,
572
+ Types.XWAPaths.xwa2_newsletters_reaction_sender_list
573
+ )
574
+ },
575
+
576
+ /**
577
+ * Block a user from a newsletter (admin action).
578
+ */
579
+ newsletterBlockUser: async (jid, userJid) => {
580
+ return mexQuery(
581
+ { newsletter_id: jid, user_id: userJid },
582
+ Types.QueryIds.BLOCK_USER,
583
+ 'xwa2_newsletter_block_user'
584
+ )
585
+ },
586
+
587
+ /**
588
+ * Enable Wamo (paid subscription) for a newsletter.
589
+ */
590
+ newsletterEnableWamo: async jid => {
591
+ return mexQuery({ newsletter_id: jid }, Types.QueryIds.WAMO_ENABLE_SUB, 'xwa2_newsletter_wamo_enable_sub')
592
+ },
593
+
594
+ /**
595
+ * Disable Wamo (paid subscription) for a newsletter.
596
+ */
597
+ newsletterDisableWamo: async jid => {
598
+ return mexQuery(
599
+ { newsletter_id: jid },
600
+ Types.QueryIds.WAMO_DISABLE_SUB,
601
+ 'xwa2_newsletter_wamo_disable_sub'
602
+ )
603
+ },
604
+
605
+ /**
606
+ * Change the Wamo subscription tier or settings for a newsletter.
607
+ */
608
+ newsletterChangeWamo: async (jid, subConfig) => {
609
+ return mexQuery(
610
+ { newsletter_id: jid,...subConfig },
611
+ Types.QueryIds.WAMO_CHANGE_SUB,
612
+ 'xwa2_newsletter_wamo_change_sub'
613
+ )
614
+ },
615
+
616
+ /**
617
+ * Wamo helpers
618
+ */
619
+ wamoAfsAgeCollection: async jid =>
620
+ mexQuery({ newsletter_id: jid }, Types.QueryIds.WAMO_AFS_AGE_COLLECTION, Types.XWAPaths.xwa2_wamo_afs_age_collection),
621
+
622
+ wamoAssetCollection: async jid =>
623
+ mexQuery({ newsletter_id: jid }, Types.QueryIds.WAMO_ASSET_COLLECTION, Types.XWAPaths.xwa2_wamo_asset_collection),
624
+
625
+ wamoFetchAdhocNotice: async noticeId =>
626
+ mexQuery({ notice_id: noticeId }, Types.QueryIds.WAMO_FETCH_ADHOC_NOTICE, Types.XWAPaths.xwa2_wamo_fetch_adhoc_notice_by_id),
627
+
628
+ wamoFetchIdentityToken: async jid =>
629
+ mexQuery({ newsletter_id: jid }, Types.QueryIds.WAMO_FETCH_IDENTITY_TOKEN, Types.XWAPaths.xwa2_wamo_fetch_identity_token),
630
+
631
+ wamoSubComplianceInfo: async jid =>
632
+ mexQuery({ newsletter_id: jid }, Types.QueryIds.WAMO_SUB_COMPLIANCE_INFO, Types.XWAPaths.xwa2_wamo_sub_get_compliance_info),
633
+
634
+ wamoUserIdVersion: async jid =>
635
+ mexQuery({ newsletter_id: jid }, Types.QueryIds.WAMO_USER_ID_VERSION, Types.XWAPaths.xwa2_wamo_user_id_version),
636
+
637
+ wamoSetUserIdVersion: async (jid, version) =>
638
+ mexQuery({ newsletter_id: jid, version }, Types.QueryIds.WAMO_SET_USER_ID_VERSION, Types.XWAPaths.xwa2_wamo_set_user_id_version),
639
+
640
+ /**
641
+ * Leave a newsletter (unsubscribe).
642
+ */
643
+ newsletterLeave: async jid =>
644
+ mexQuery({ newsletter_id: jid }, Types.QueryIds.LEAVE, Types.XWAPaths.xwa2_newsletter_leave_v2),
645
+
646
+ /**
647
+ * Create a verified newsletter.
648
+ */
649
+ newsletterCreateVerified: async (name, description = null) =>
650
+ mexQuery(
651
+ { input: { name, description } },
652
+ Types.QueryIds.CREATE_VERIFIED,
653
+ Types.XWAPaths.xwa2_newsletter_create_verified
654
+ ),
655
+
656
+ /**
657
+ * Fetch newsletter enforcements (ban/restriction info).
658
+ */
659
+ newsletterEnforcements: async jid =>
660
+ mexQuery({ newsletter_id: jid }, Types.QueryIds.ENFORCEMENTS, Types.XWAPaths.xwa2_newsletter_enforcements),
661
+
662
+ /**
663
+ * Fetch user reports for a newsletter (admin action).
664
+ */
665
+ newsletterUserReports: async (jid, cursor = null) => {
666
+ const variables = { newsletter_id: jid }
667
+ if (cursor) variables.cursor = cursor
668
+ return mexQuery(variables, Types.QueryIds.USER_REPORTS, Types.XWAPaths.xwa2_newsletter_user_reports)
669
+ },
670
+
671
+ /**
672
+ * Create a report appeal for a newsletter.
673
+ */
674
+ newsletterCreateReportAppeal: async (jid, reason) =>
675
+ mexQuery(
676
+ { newsletter_id: jid, reason },
677
+ Types.QueryIds.CREATE_REPORT_APPEAL,
678
+ Types.XWAPaths.xwa2_newsletter_create_report_appeal
679
+ ),
680
+
681
+ /**
682
+ * Check a newsletter link preview.
683
+ */
684
+ newsletterLinkPreviewCheck: async url =>
685
+ mexQuery({ url }, Types.QueryIds.LINK_PREVIEW_CHECK, Types.XWAPaths.xwa2_newsletter_link_preview_check),
686
+
687
+ /**
688
+ * Update newsletter verification status.
689
+ */
690
+ newsletterUpdateVerification: async (jid, verification) =>
691
+ mexQuery(
692
+ { newsletter_id: jid, verification },
693
+ Types.QueryIds.UPDATE_VERIFICATION,
694
+ Types.XWAPaths.xwa2_newsletter_update_verification
695
+ ),
696
+
697
+ /**
698
+ * Label a newsletter post as paid partnership.
699
+ */
700
+ newsletterLabelPaidPartnership: async (jid, serverId, isPaidPartnership) =>
701
+ mexQuery(
702
+ { newsletter_id: jid, server_id: serverId, is_paid_partnership: isPaidPartnership },
703
+ Types.QueryIds.LABEL_PAID_PARTNERSHIP,
704
+ Types.XWAPaths.xwa2_newsletter_label_paid_partnership
705
+ ),
706
+
707
+ /**
708
+ * Log newsletter exposure events (analytics).
709
+ */
710
+ newsletterLogExposures: async events =>
711
+ mexQuery({ events }, Types.QueryIds.LOG_EXPOSURES, Types.XWAPaths.xwa2_newsletter_log_exposures),
712
+
713
+ /**
714
+ * Update user-specific newsletter setting.
715
+ */
716
+ newsletterUpdateUserSetting: async (jid, setting) =>
717
+ mexQuery(
718
+ { newsletter_id: jid,...setting },
719
+ Types.QueryIds.UPDATE_USER_SETTING,
720
+ Types.XWAPaths.xwa2_newsletter_update_user_setting
721
+ ),
722
+
723
+ /**
724
+ * Fetch newsletter ranking features (ML signals).
725
+ */
726
+ newsletterRankingFeatures: async jid =>
727
+ mexQuery(
728
+ { newsletter_id: jid },
729
+ Types.QueryIds.RANKING_FEATURES,
730
+ Types.XWAPaths.xwa2_newsletter_ranking_features
731
+ ),
732
+
733
+ /**
734
+ * Send view receipts for newsletter messages.
735
+ */
736
+ newsletterSendViewReceipt: async (jid, serverMessageIds) => {
737
+ const ids = Array.isArray(serverMessageIds)? serverMessageIds : [serverMessageIds]
738
+ const receiptId = generateMessageTag()
739
+ await query({
740
+ tag: 'receipt',
741
+ attrs: {
742
+ to: jid,
743
+ id: receiptId,
744
+ type: 'view'
54
745
  },
55
746
  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
- }
747
+ {
748
+ tag: 'list',
749
+ attrs: {},
750
+ content: ids.map(id => ({ tag: 'item', attrs: { server_id: String(id) } }))
751
+ }
66
752
  ]
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
- }
753
+ })
754
+ }
755
+ }
817
756
  }
818
- exports.makeNewsletterSocket = makeNewsletterSocket