shadowx-fca 8.0.0

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 (174) hide show
  1. package/README.md +1066 -0
  2. package/build/messagix.dll +0 -0
  3. package/build/messagix.so +0 -0
  4. package/checkUpdate.js +393 -0
  5. package/config.json +17 -0
  6. package/e2ee.js +563 -0
  7. package/e2eetest.js +356 -0
  8. package/index.js +611 -0
  9. package/lib/index.mjs +1412 -0
  10. package/logger.js +500 -0
  11. package/package.json +65 -0
  12. package/src/GetBotInfo.js +66 -0
  13. package/src/OldMessage.js +182 -0
  14. package/src/Screenshot.js +83 -0
  15. package/src/addExternalModule.js +13 -0
  16. package/src/addUserToGroup.js +33 -0
  17. package/src/approveGroupJoinRequests.js +18 -0
  18. package/src/changeAdminStatus.js +16 -0
  19. package/src/changeArchivedStatus.js +17 -0
  20. package/src/changeAvatar.js +136 -0
  21. package/src/changeAvatarV2.js +86 -0
  22. package/src/changeAvt.js +85 -0
  23. package/src/changeBio.js +76 -0
  24. package/src/changeBlockedStatus.js +20 -0
  25. package/src/changeBlockedStatusMqtt.js +80 -0
  26. package/src/changeCover.js +72 -0
  27. package/src/changeGroupImage.js +16 -0
  28. package/src/changeName.js +79 -0
  29. package/src/changeNickname.js +16 -0
  30. package/src/changeThreadColor.js +15 -0
  31. package/src/changeThreadEmoji.js +15 -0
  32. package/src/changeThreadMemberNickname.js +6 -0
  33. package/src/changeUsername.js +59 -0
  34. package/src/createCommentPost.js +230 -0
  35. package/src/createNewGroup.js +38 -0
  36. package/src/createNote.js +35 -0
  37. package/src/createPoll.js +27 -0
  38. package/src/createPost.js +276 -0
  39. package/src/createThemeAI.js +129 -0
  40. package/src/data/cache/system/data.json +4 -0
  41. package/src/data/cache/system/datahandle.js +21 -0
  42. package/src/data/getThreadInfo.json +1 -0
  43. package/src/deleteComment.js +23 -0
  44. package/src/deleteMessage.js +15 -0
  45. package/src/deleteThread.js +15 -0
  46. package/src/denyGroupJoinRequests.js +18 -0
  47. package/src/e2ee/crypto.js +173 -0
  48. package/src/e2ee/index.js +144 -0
  49. package/src/e2ee/proto/ArmadilloApplication.proto +281 -0
  50. package/src/e2ee/proto/ArmadilloICDC.proto +14 -0
  51. package/src/e2ee/proto/ConsumerApplication.proto +232 -0
  52. package/src/e2ee/proto/MessageApplication.proto +82 -0
  53. package/src/e2ee/proto/MessageTransport.proto +77 -0
  54. package/src/e2ee/proto/WACommon.proto +66 -0
  55. package/src/e2ee/proto/WAMediaTransport.proto +176 -0
  56. package/src/e2ee/proto/proto-writer.ts +76 -0
  57. package/src/e2ee/protocol.js +196 -0
  58. package/src/e2ee/ratchet.js +219 -0
  59. package/src/e2ee/store.js +182 -0
  60. package/src/e2ee.js +8 -0
  61. package/src/editMessage.js +56 -0
  62. package/src/editMessageOld.js +67 -0
  63. package/src/enableReactions.js +24 -0
  64. package/src/follow.js +74 -0
  65. package/src/followUser.js +23 -0
  66. package/src/forwardAttachment.js +16 -0
  67. package/src/friendList.js +98 -0
  68. package/src/getAccess.js +112 -0
  69. package/src/getAppState.js +13 -0
  70. package/src/getAvatarUser.js +11 -0
  71. package/src/getBio.js +24 -0
  72. package/src/getBotInitialData.js +42 -0
  73. package/src/getCtx.js +5 -0
  74. package/src/getCurrentUserID.js +6 -0
  75. package/src/getEmojiUrl.js +29 -0
  76. package/src/getFriendsList.js +36 -0
  77. package/src/getMessage.js +37 -0
  78. package/src/getNotes.js +17 -0
  79. package/src/getOptions.js +5 -0
  80. package/src/getPinnedMessages.js +33 -0
  81. package/src/getPostInfo.js +17 -0
  82. package/src/getProfileInfo.js +17 -0
  83. package/src/getPublicData.js +25 -0
  84. package/src/getRegion.js +7 -0
  85. package/src/getRepInfo.js +17 -0
  86. package/src/getStickerPacks.js +25 -0
  87. package/src/getStickers.js +39 -0
  88. package/src/getStoryReactions.js +18 -0
  89. package/src/getThreadHistory.js +45 -0
  90. package/src/getThreadHistoryDeprecated.js +71 -0
  91. package/src/getThreadInfo.js +73 -0
  92. package/src/getThreadInfoDeprecated.js +56 -0
  93. package/src/getThreadList.js +76 -0
  94. package/src/getThreadListDeprecated.js +46 -0
  95. package/src/getThreadPictures.js +59 -0
  96. package/src/getThreadTheme.js +77 -0
  97. package/src/getUID.js +17 -0
  98. package/src/getUserID.js +17 -0
  99. package/src/getUserInfo.js +28 -0
  100. package/src/handleFriendRequest.js +21 -0
  101. package/src/handleMessageRequest.js +15 -0
  102. package/src/httpGet.js +13 -0
  103. package/src/httpPost.js +12 -0
  104. package/src/httpPostFormData.js +12 -0
  105. package/src/listenE2EE.js +75 -0
  106. package/src/listenMqtt.js +802 -0
  107. package/src/listenNotification.js +85 -0
  108. package/src/logout.js +22 -0
  109. package/src/markAsDelivered.js +17 -0
  110. package/src/markAsRead.js +14 -0
  111. package/src/markAsReadAll.js +15 -0
  112. package/src/markAsSeen.js +15 -0
  113. package/src/metaTheme.js +185 -0
  114. package/src/muteThread.js +52 -0
  115. package/src/note.js +228 -0
  116. package/src/pin.js +53 -0
  117. package/src/pinMessage.js +6 -0
  118. package/src/postComment.js +29 -0
  119. package/src/postFormData.js +46 -0
  120. package/src/reactToComment.js +31 -0
  121. package/src/reactToPost.js +32 -0
  122. package/src/refreshFb_dtsg.js +31 -0
  123. package/src/removeSuspiciousAccount.js +74 -0
  124. package/src/removeUserFromGroup.js +15 -0
  125. package/src/reply.js +442 -0
  126. package/src/resolvePhotoUrl.js +15 -0
  127. package/src/searchForThread.js +20 -0
  128. package/src/searchFriends.js +28 -0
  129. package/src/searchStickers.js +53 -0
  130. package/src/send.js +46 -0
  131. package/src/sendAudio.js +8 -0
  132. package/src/sendBroadcast.js +93 -0
  133. package/src/sendButtons.js +161 -0
  134. package/src/sendComment.js +159 -0
  135. package/src/sendEmoji.js +10 -0
  136. package/src/sendFile.js +9 -0
  137. package/src/sendFriendRequest.js +33 -0
  138. package/src/sendGif.js +24 -0
  139. package/src/sendImage.js +9 -0
  140. package/src/sendLocation.js +9 -0
  141. package/src/sendMessage.js +487 -0
  142. package/src/sendMessage1.js +309 -0
  143. package/src/sendMessageMqtt.js +68 -0
  144. package/src/sendSticker.js +8 -0
  145. package/src/sendTypingIndicator.js +36 -0
  146. package/src/sendTypingIndicatorV2.js +28 -0
  147. package/src/sendVideo.js +9 -0
  148. package/src/sessionGuard.js +130 -0
  149. package/src/setActiveStatus.js +16 -0
  150. package/src/setMessageReaction.js +61 -0
  151. package/src/setMessageReactionMqtt.js +62 -0
  152. package/src/setOptions.js +22 -0
  153. package/src/setPollVote.js +17 -0
  154. package/src/setPostReaction.js +112 -0
  155. package/src/setProfileGuard.js +44 -0
  156. package/src/setProfileLock.js +93 -0
  157. package/src/setStoryReaction.js +129 -0
  158. package/src/setStorySeen.js +99 -0
  159. package/src/setThreadTheme.js +17 -0
  160. package/src/setTitle.js +15 -0
  161. package/src/shareContact.js +33 -0
  162. package/src/shareLink.js +8 -0
  163. package/src/sharePost.js +31 -0
  164. package/src/stopListenMqtt.js +23 -0
  165. package/src/storyManager.js +353 -0
  166. package/src/suggestFriend.js +128 -0
  167. package/src/threadColors.js +131 -0
  168. package/src/unfollowUser.js +23 -0
  169. package/src/unfriend.js +15 -0
  170. package/src/unpinMessage.js +6 -0
  171. package/src/unsendMessage.js +14 -0
  172. package/src/uploadAttachment.js +58 -0
  173. package/src/uploadImageToImgbb.js +29 -0
  174. package/utils.js +2945 -0
package/logger.js ADDED
@@ -0,0 +1,500 @@
1
+ "use strict";
2
+
3
+ const fs = require('fs');
4
+ const path = require('path');
5
+
6
+ const C = {
7
+ reset: '\x1b[0m',
8
+ bold: '\x1b[1m',
9
+ dim: '\x1b[2m',
10
+ italic: '\x1b[3m',
11
+ underline:'\x1b[4m',
12
+ blink: '\x1b[5m',
13
+ reverse: '\x1b[7m',
14
+ hidden: '\x1b[8m',
15
+ strike: '\x1b[9m',
16
+ black: '\x1b[30m',
17
+ red: '\x1b[31m',
18
+ green: '\x1b[32m',
19
+ yellow: '\x1b[33m',
20
+ blue: '\x1b[34m',
21
+ magenta: '\x1b[35m',
22
+ cyan: '\x1b[36m',
23
+ white: '\x1b[37m',
24
+ bBlack: '\x1b[90m',
25
+ bRed: '\x1b[91m',
26
+ bGreen: '\x1b[92m',
27
+ bYellow: '\x1b[93m',
28
+ bBlue: '\x1b[94m',
29
+ bMagenta: '\x1b[95m',
30
+ bCyan: '\x1b[96m',
31
+ bWhite: '\x1b[97m',
32
+ bgRed: '\x1b[41m',
33
+ bgGreen: '\x1b[42m',
34
+ bgYellow: '\x1b[43m',
35
+ bgBlue: '\x1b[44m',
36
+ bgMagenta:'\x1b[45m',
37
+ bgCyan: '\x1b[46m',
38
+ bgWhite: '\x1b[47m',
39
+ bgBlack: '\x1b[40m',
40
+ };
41
+
42
+ // Emoji constants for different log types
43
+ const EMOJI = {
44
+ info: 'ℹ️ ',
45
+ success: '✅',
46
+ warn: '⚠️ ',
47
+ error: '❌',
48
+ debug: '🔍',
49
+ trace: '📍',
50
+ event: '🎯',
51
+ progress: '📊',
52
+ box: '📦',
53
+ group: '📂',
54
+ mqtt: '🔌',
55
+ bot: '🤖',
56
+ region: '🌍',
57
+ e2ee: '🔐',
58
+ transport: '📡',
59
+ shield: '🛡️',
60
+ key: '🔑',
61
+ lock: '🔒',
62
+ unlock: '🔓',
63
+ gear: '⚙️ ',
64
+ rocket: '🚀',
65
+ star: '⭐',
66
+ spark: '✨',
67
+ fire: '🔥',
68
+ zap: '⚡',
69
+ check: '✔️ ',
70
+ cross: '✖️ ',
71
+ dot: '◈',
72
+ arrow: '➜',
73
+ pointer: '👉',
74
+ clock: '🕐',
75
+ bell: '🔔',
76
+ mute: '🔕',
77
+ mail: '📧',
78
+ chat: '💬',
79
+ users: '👥',
80
+ user: '👤',
81
+ globe: '🌐',
82
+ cloud: '☁️ ',
83
+ server: '🖥️ ',
84
+ database: '🗄️ ',
85
+ file: '📄',
86
+ folder: '📁',
87
+ pin: '📌',
88
+ link: '🔗',
89
+ heart: '❤️ ',
90
+ thumbsUp: '👍',
91
+ thumbsDown: '👎',
92
+ wave: '👋',
93
+ eyes: '👀',
94
+ bulb: '💡',
95
+ target: '🎯',
96
+ megaphone: '📣',
97
+ speaker: '🔊',
98
+ microphone: '🎤',
99
+ camera: '📷',
100
+ image: '🖼️ ',
101
+ video: '🎬',
102
+ music: '🎵',
103
+ gift: '🎁',
104
+ package: '📦',
105
+ wrench: '🔧',
106
+ hammer: '🔨',
107
+ magnet: '🧲',
108
+ battery: '🔋',
109
+ plug: '🔌',
110
+ cable: '🔗',
111
+ signal: '📶',
112
+ wifi: '📶',
113
+ antenna: '📡',
114
+ satellite: '🛰️ ',
115
+ };
116
+
117
+ // Log levels with numeric priority
118
+ const LEVELS = {
119
+ SILENT: 0,
120
+ ERROR: 1,
121
+ WARN: 2,
122
+ INFO: 3,
123
+ SUCCESS: 4,
124
+ EVENT: 5,
125
+ DEBUG: 6,
126
+ TRACE: 7,
127
+ };
128
+
129
+ // Default configuration
130
+ const config = {
131
+ level: 'INFO',
132
+ fileLogging: false,
133
+ logDir: path.join(process.cwd(), 'logs'),
134
+ maxFileSize: 10 * 1024 * 1024, // 10MB
135
+ maxFiles: 5,
136
+ showTimestamp: true,
137
+ showLevel: true,
138
+ showEmoji: true,
139
+ colorize: true,
140
+ json: false,
141
+ callerInfo: false,
142
+ };
143
+
144
+ let currentLogFile = null;
145
+ let currentFileSize = 0;
146
+
147
+ function setConfig(newConfig) {
148
+ Object.assign(config, newConfig);
149
+ if (config.fileLogging && !fs.existsSync(config.logDir)) {
150
+ fs.mkdirSync(config.logDir, { recursive: true });
151
+ }
152
+ }
153
+
154
+ function getCallerInfo() {
155
+ if (!config.callerInfo) return '';
156
+ const err = new Error();
157
+ const stack = err.stack.split('\n');
158
+ const caller = stack[4] || stack[3] || '';
159
+ const match = caller.match(/at\s+(.+?)\s+\((.+?):(\d+):(\d+)\)/) ||
160
+ caller.match(/at\s+(.+?):(\d+):(\d+)/);
161
+ if (match) {
162
+ const [_, func, file, line] = match;
163
+ const fileName = file ? path.basename(file) : 'unknown';
164
+ return `${C.dim}(${fileName}:${line})${C.reset} `;
165
+ }
166
+ return '';
167
+ }
168
+
169
+ function ts() {
170
+ if (!config.showTimestamp) return '';
171
+ const d = new Date();
172
+ const hh = String(d.getHours()).padStart(2, '0');
173
+ const mm = String(d.getMinutes()).padStart(2, '0');
174
+ const ss = String(d.getSeconds()).padStart(2, '0');
175
+ const ms = String(d.getMilliseconds()).padStart(3, '0');
176
+ return `${C.dim}${hh}:${mm}:${ss}.${ms}${C.reset}`;
177
+ }
178
+
179
+ function tag(label, color, emoji = '') {
180
+ if (!config.showLevel) return '';
181
+ const emojiStr = config.showEmoji && emoji ? `${emoji} ` : '';
182
+ return `${color}${C.bold}${emojiStr}[ ${label.padEnd(5)} ]${C.reset}`;
183
+ }
184
+
185
+ function fmt(msg) {
186
+ if (msg instanceof Error) {
187
+ return msg.stack || msg.message;
188
+ }
189
+ if (typeof msg === 'object' && msg !== null) {
190
+ try {
191
+ return JSON.stringify(msg, null, 2);
192
+ } catch (_) {
193
+ return String(msg);
194
+ }
195
+ }
196
+ return String(msg);
197
+ }
198
+
199
+ function rotateLogFile() {
200
+ if (!config.fileLogging) return;
201
+
202
+ const logFile = path.join(config.logDir, 'shadowx-fca.log');
203
+
204
+ if (fs.existsSync(logFile)) {
205
+ const stats = fs.statSync(logFile);
206
+ if (stats.size >= config.maxFileSize) {
207
+ for (let i = config.maxFiles - 1; i >= 0; i--) {
208
+ const oldFile = i === 0 ? logFile : `${logFile}.${i}`;
209
+ const newFile = `${logFile}.${i + 1}`;
210
+ if (fs.existsSync(oldFile)) {
211
+ if (i === config.maxFiles - 1) {
212
+ fs.unlinkSync(oldFile);
213
+ } else {
214
+ fs.renameSync(oldFile, newFile);
215
+ }
216
+ }
217
+ }
218
+ }
219
+ }
220
+
221
+ currentLogFile = logFile;
222
+ currentFileSize = fs.existsSync(logFile) ? fs.statSync(logFile).size : 0;
223
+ }
224
+
225
+ function writeToFile(level, label, msg) {
226
+ if (!config.fileLogging) return;
227
+ if (!currentLogFile) rotateLogFile();
228
+
229
+ const d = new Date();
230
+ const timestamp = d.toISOString();
231
+ const logEntry = `[${timestamp}] [${level}] [${label}] ${msg}\n`;
232
+
233
+ try {
234
+ fs.appendFileSync(currentLogFile, logEntry);
235
+ currentFileSize += Buffer.byteLength(logEntry);
236
+
237
+ if (currentFileSize >= config.maxFileSize) {
238
+ rotateLogFile();
239
+ }
240
+ } catch (err) {
241
+ console.error(`Failed to write to log file: ${err.message}`);
242
+ }
243
+ }
244
+
245
+ function shouldLog(level) {
246
+ const currentLevel = LEVELS[config.level] || LEVELS.INFO;
247
+ const messageLevel = LEVELS[level] || LEVELS.INFO;
248
+ return messageLevel <= currentLevel;
249
+ }
250
+
251
+ const logger = {
252
+ LEVELS,
253
+ EMOJI,
254
+ config,
255
+ setConfig,
256
+
257
+ info(label, msg) {
258
+ if (!shouldLog('INFO')) return;
259
+ if (msg === undefined) { msg = label; label = 'INFO'; }
260
+ const caller = getCallerInfo();
261
+ const output = `${ts()} ${tag(label, C.bCyan, EMOJI.info)} ${caller}${C.white}${fmt(msg)}${C.reset}`;
262
+ console.log(output);
263
+ writeToFile('INFO', label, fmt(msg));
264
+ },
265
+
266
+ success(label, msg) {
267
+ if (!shouldLog('SUCCESS')) return;
268
+ if (msg === undefined) { msg = label; label = 'OK'; }
269
+ const caller = getCallerInfo();
270
+ const output = `${ts()} ${tag(label, C.bGreen, EMOJI.success)} ${caller}${C.bWhite}${fmt(msg)}${C.reset}`;
271
+ console.log(output);
272
+ writeToFile('SUCCESS', label, fmt(msg));
273
+ },
274
+
275
+ warn(label, msg) {
276
+ if (!shouldLog('WARN')) return;
277
+ if (msg === undefined) { msg = label; label = 'WARN'; }
278
+ const caller = getCallerInfo();
279
+ const output = `${ts()} ${tag(label, C.bYellow, EMOJI.warn)} ${caller}${C.yellow}${fmt(msg)}${C.reset}`;
280
+ console.warn(output);
281
+ writeToFile('WARN', label, fmt(msg));
282
+ },
283
+
284
+ error(label, msg) {
285
+ if (!shouldLog('ERROR')) return;
286
+ if (msg === undefined) { msg = label; label = 'ERROR'; }
287
+ const caller = getCallerInfo();
288
+ const body = msg instanceof Error ? msg.stack || msg.message : fmt(msg);
289
+ const output = `${ts()} ${tag(label, C.bRed, EMOJI.error)} ${caller}${C.red}${body}${C.reset}`;
290
+ console.error(output);
291
+ writeToFile('ERROR', label, body);
292
+ },
293
+
294
+ debug(label, msg) {
295
+ if (!shouldLog('DEBUG')) return;
296
+ if (msg === undefined) { msg = label; label = 'DEBUG'; }
297
+ const caller = getCallerInfo();
298
+ const output = `${ts()} ${tag(label, C.bBlack, EMOJI.debug)} ${caller}${C.dim}${fmt(msg)}${C.reset}`;
299
+ console.log(output);
300
+ writeToFile('DEBUG', label, fmt(msg));
301
+ },
302
+
303
+ trace(label, msg) {
304
+ if (!shouldLog('TRACE')) return;
305
+ if (msg === undefined) { msg = label; label = 'TRACE'; }
306
+ const caller = getCallerInfo();
307
+ const output = `${ts()} ${tag(label, C.bBlue, EMOJI.trace)} ${caller}${C.dim}${C.italic}${fmt(msg)}${C.reset}`;
308
+ console.log(output);
309
+ writeToFile('TRACE', label, fmt(msg));
310
+ },
311
+
312
+ event(label, msg) {
313
+ if (!shouldLog('EVENT')) return;
314
+ if (msg === undefined) { msg = label; label = 'EVENT'; }
315
+ const caller = getCallerInfo();
316
+ const output = `${ts()} ${tag(label, C.bMagenta, EMOJI.event)} ${caller}${C.magenta}${fmt(msg)}${C.reset}`;
317
+ console.log(output);
318
+ writeToFile('EVENT', label, fmt(msg));
319
+ },
320
+
321
+ // Progress bar
322
+ progress(current, total, label = '') {
323
+ if (!shouldLog('INFO')) return;
324
+ const percentage = Math.round((current / total) * 100);
325
+ const barWidth = 30;
326
+ const filled = Math.round((barWidth * current) / total);
327
+ const empty = barWidth - filled;
328
+ const bar = '█'.repeat(filled) + '░'.repeat(empty);
329
+ const percentStr = `${percentage}%`.padStart(4);
330
+
331
+ const emoji = percentage === 100 ? EMOJI.success : EMOJI.progress;
332
+
333
+ process.stdout.write(
334
+ `\r${ts()} ${tag(label || 'PROG', C.bCyan, emoji)} ${C.bold}${bar}${C.reset} ${C.bWhite}${percentStr}${C.reset} ${C.dim}${current}/${total}${C.reset}`
335
+ );
336
+
337
+ if (current === total) {
338
+ process.stdout.write('\n');
339
+ }
340
+ },
341
+
342
+ // Table logging
343
+ table(data, columns = null) {
344
+ if (!shouldLog('INFO')) return;
345
+ if (!Array.isArray(data) || data.length === 0) return;
346
+
347
+ const keys = columns || Object.keys(data[0]);
348
+ const colWidths = keys.map(key => {
349
+ const maxDataWidth = Math.max(...data.map(row => String(row[key] || '').length));
350
+ return Math.max(key.length, maxDataWidth) + 2;
351
+ });
352
+
353
+ // Header
354
+ const header = keys.map((key, i) =>
355
+ `${C.bold}${C.bCyan}${String(key).padEnd(colWidths[i])}${C.reset}`
356
+ ).join('');
357
+ console.log(`\n${EMOJI.table} ${header}`);
358
+
359
+ // Separator
360
+ const separator = colWidths.map(w => '─'.repeat(w)).join('');
361
+ console.log(`${C.dim}${separator}${C.reset}`);
362
+
363
+ // Rows
364
+ data.forEach(row => {
365
+ const line = keys.map((key, i) =>
366
+ `${C.white}${String(row[key] || '').padEnd(colWidths[i])}${C.reset}`
367
+ ).join('');
368
+ console.log(line);
369
+ });
370
+ console.log('');
371
+ },
372
+
373
+ // Boxed message
374
+ box(msg, type = 'info') {
375
+ if (!shouldLog('INFO')) return;
376
+ const colors = {
377
+ info: C.bCyan,
378
+ success: C.bGreen,
379
+ warn: C.bYellow,
380
+ error: C.bRed,
381
+ };
382
+ const emojis = {
383
+ info: EMOJI.info,
384
+ success: EMOJI.success,
385
+ warn: EMOJI.warn,
386
+ error: EMOJI.error,
387
+ };
388
+ const color = colors[type] || C.bCyan;
389
+ const emoji = emojis[type] || EMOJI.box;
390
+ const lines = msg.split('\n');
391
+ const maxLen = Math.max(...lines.map(l => l.length));
392
+ const top = `┌${'─'.repeat(maxLen + 2)}┐`;
393
+ const bottom = `└${'─'.repeat(maxLen + 2)}┘`;
394
+
395
+ console.log(`${color}${emoji} ${top}${C.reset}`);
396
+ lines.forEach(line => {
397
+ const padding = ' '.repeat(maxLen - line.length);
398
+ console.log(`${color}│ ${C.white}${line}${padding} ${color}│${C.reset}`);
399
+ });
400
+ console.log(`${color}${bottom}${C.reset}`);
401
+ },
402
+
403
+ // Group related logs
404
+ group(label, fn) {
405
+ if (!shouldLog('INFO')) return;
406
+ console.log(`\n${C.bold}${C.bCyan}${EMOJI.group} ${label}${C.reset}`);
407
+ console.log(`${C.dim}${'─'.repeat(50)}${C.reset}`);
408
+ if (typeof fn === 'function') {
409
+ fn();
410
+ }
411
+ console.log(`${C.dim}${'─'.repeat(50)}${C.reset}\n`);
412
+ },
413
+
414
+ // Clear console
415
+ clear() {
416
+ process.stdout.write('\x1b[2J\x1b[H');
417
+ },
418
+
419
+ banner(name, version, userID, botName, region, e2ee) {
420
+ const SEP = `${C.bBlack}${'━'.repeat(54)}${C.reset}`;
421
+ const dot = `${C.bBlack}${EMOJI.dot}${C.reset}`;
422
+ const label = (s) => `${C.bold}${C.white}${s.padEnd(10)}${C.reset}`;
423
+
424
+ const displayName = botName
425
+ ? `${C.bWhite}${botName}${C.reset} ${C.bBlack}(${userID})${C.reset}`
426
+ : `${C.bYellow}${userID}${C.reset}`;
427
+
428
+ const e2eeStr = e2ee
429
+ ? `${C.bGreen}${EMOJI.lock} Active${C.reset}`
430
+ : `${C.bBlack}${EMOJI.unlock} Inactive${C.reset}`;
431
+
432
+ const rows = [
433
+ '',
434
+ ` ${C.bold}${C.bCyan}${EMOJI.zap} ${name}${C.reset} ${C.bBlack}v${version}${C.reset}`,
435
+ ` ${SEP}`,
436
+ ` ${dot} ${label('Bot ')} ${EMOJI.bot} ${displayName}`,
437
+ ` ${dot} ${label('Region ')} ${EMOJI.globe} ${C.bGreen}${(region || 'AUTO').toUpperCase()}${C.reset}`,
438
+ ` ${dot} ${label('E2EE ')} ${EMOJI.shield} ${e2eeStr}`,
439
+ ` ${dot} ${label('Transport')} ${EMOJI.transport} ${C.bCyan}MQTT / WebSocket${C.reset}`,
440
+ ` ${SEP}`,
441
+ ` ${C.dim} Developed by ${C.bMagenta}Mueid Mursalin Rifat${C.reset}`,
442
+ ` ${C.dim} ${EMOJI.heart} ${C.bRed}Made with love for the community${C.reset}`,
443
+ '',
444
+ ];
445
+ rows.forEach(r => console.log(r));
446
+ },
447
+
448
+ mqttSpinner: null,
449
+
450
+ startSpinner(region) {
451
+ const frames = ['⠋','⠙','⠹','⠸','⠴','⠦','⠧','⠇','⠏'];
452
+ let fi = 0;
453
+ const regionStr = region ? ` ${C.dim}${C.bCyan}[${region.toUpperCase()}]${C.reset}` : '';
454
+ process.stdout.write('\n');
455
+ logger.mqttSpinner = setInterval(() => {
456
+ const f = frames[fi++ % frames.length];
457
+ process.stdout.write(
458
+ `\r ${C.bold}${C.bCyan}${f}${C.reset} ${C.cyan}SHADOWX${C.reset} ` +
459
+ `${C.dim}${EMOJI.mqtt} connecting to MQTT${C.reset}${regionStr}${C.dim} ...${C.reset} `
460
+ );
461
+ }, 80);
462
+ },
463
+
464
+ stopSpinner(success = true) {
465
+ if (logger.mqttSpinner) {
466
+ clearInterval(logger.mqttSpinner);
467
+ logger.mqttSpinner = null;
468
+ }
469
+ process.stdout.write('\r\x1b[2K');
470
+ const icon = success ? `${C.bGreen}${EMOJI.check}${C.reset}` : `${C.bRed}${EMOJI.cross}${C.reset}`;
471
+ const statusMsg = success ? 'established' : 'failed';
472
+ const statusIcon = success ? EMOJI.success : EMOJI.error;
473
+ process.stdout.write(`\r ${icon} ${C.cyan}SHADOWX${C.reset} ${C.dim}${EMOJI.mqtt} MQTT connection ${statusMsg}${C.reset} ${statusIcon}\n`);
474
+ },
475
+
476
+ // Additional utility methods with emojis
477
+ connected(msg) {
478
+ this.success('CONNECT', `${EMOJI.plug} ${msg || 'Connected successfully'}`);
479
+ },
480
+
481
+ disconnected(msg) {
482
+ this.warn('DISCON', `${EMOJI.cable} ${msg || 'Disconnected'}`);
483
+ },
484
+
485
+ message(msg) {
486
+ this.info('MSG', `${EMOJI.chat} ${msg}`);
487
+ },
488
+
489
+ userAction(msg) {
490
+ this.event('USER', `${EMOJI.user} ${msg}`);
491
+ },
492
+
493
+ system(msg) {
494
+ this.info('SYS', `${EMOJI.gear} ${msg}`);
495
+ },
496
+ };
497
+
498
+ module.exports = logger;
499
+ module.exports.C = C;
500
+ module.exports.EMOJI = EMOJI;
package/package.json ADDED
@@ -0,0 +1,65 @@
1
+ {
2
+ "name": "shadowx-fca",
3
+ "version": "8.0.0",
4
+ "description": "SHADOWX-FCA - Ultimate Facebook Chat API for Node.js. Dev by Dev by Mueid Mursalin Rifat",
5
+ "main": "index.js",
6
+ "files": [
7
+ "src/",
8
+ "build/",
9
+ "lib/",
10
+ "assets/",
11
+ "index.js",
12
+ "utils.js",
13
+ "checkUpdate.js",
14
+ "logger.js",
15
+ "e2ee.js",
16
+ "e2eetest.js",
17
+ "config.json"
18
+ ],
19
+ "scripts": {
20
+ "test": "echo \"Error: no test specified\" && exit 1",
21
+ "start": "node index.js"
22
+ },
23
+ "repository": {
24
+ "type": "git",
25
+ "url": "git+https://github.com/mueidmursalinrifat/shadowx-fca.git"
26
+ },
27
+ "keywords": [
28
+ "facebook", "chat", "api", "bot", "messenger", "unofficial",
29
+ "signal-protocol", "mqtt", "facebook-chat-api"
30
+ ],
31
+ "author": "Mueid Mursalin Rifat",
32
+ "license": "MIT",
33
+ "bugs": {
34
+ "url": "https://github.com/mueidmursalinrifat/shadowx-fca/issues"
35
+ },
36
+ "homepage": "https://github.com/mueidmursalinrifat/shadowx-fca#readme",
37
+ "dependencies": {
38
+ "@noble/curves": "^2.2.0",
39
+ "@noble/hashes": "^2.2.0",
40
+ "@signalapp/libsignal-client": "0.70.0",
41
+ "axios": "^1.8.4",
42
+ "bluebird": "^3.7.2",
43
+ "chalk": "^4.1.2",
44
+ "cheerio": "^1.0.0-rc.10",
45
+ "duplexify": "^4.1.3",
46
+ "form-data": "^4.0.0",
47
+ "gradient-string": "^2.0.2",
48
+ "https-proxy-agent": "^7.0.6",
49
+ "koffi": "^3.0.2",
50
+ "mime": "^3.0.0",
51
+ "mqtt": "^5.10.1",
52
+ "npmlog": "^1.2.0",
53
+ "protobufjs": "^8.4.0",
54
+ "request": "^2.88.2",
55
+ "sequelize": "^6.37.6",
56
+ "sqlite3": "^5.1.7",
57
+ "totp-generator": "^1.0.0",
58
+ "undici": "^8.4.0",
59
+ "ws": "^8.18.1",
60
+ "yumi-json-bigint": "^1.0.0"
61
+ },
62
+ "engines": {
63
+ "node": ">=16.0.0"
64
+ }
65
+ }
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ // shadowx-fca — GetBotInfo
3
+ // Author: Modified for shadowx-fca
4
+
5
+ const utils = require('../utils');
6
+
7
+ module.exports = (defaultFuncs, api, ctx) => {
8
+ /**
9
+ * Returns bot's current login info, tokens, and context accessor functions.
10
+ * @param {Array<object>} netData - JSON blobs extracted from Facebook HTML
11
+ * @returns {object|null}
12
+ */
13
+ return function GetBotInfo(netData) {
14
+ if (!netData || !Array.isArray(netData)) {
15
+ utils.log("GetBotInfo", "netData is not a valid array.");
16
+ return null;
17
+ }
18
+
19
+ const findConfig = (key) => {
20
+ for (const scriptData of netData) {
21
+ if (!scriptData.require) continue;
22
+ for (const req of scriptData.require) {
23
+ if (Array.isArray(req) && req[0] === key && req[2]) {
24
+ return req[2];
25
+ }
26
+ if (Array.isArray(req) && req[3] && req[3][0] && req[3][0].__bbox && req[3][0].__bbox.define) {
27
+ for (const def of req[3][0].__bbox.define) {
28
+ if (Array.isArray(def) && def[0] && def[0].endsWith(key) && def[2]) {
29
+ return def[2];
30
+ }
31
+ }
32
+ }
33
+ }
34
+ }
35
+ return null;
36
+ };
37
+
38
+ const currentUserData = findConfig("CurrentUserInitialData");
39
+ const dtsgInitialData = findConfig("DTSGInitialData");
40
+ const dtsgInitData = findConfig("DTSGInitData");
41
+ const lsdData = findConfig("LSD");
42
+
43
+ if (!currentUserData || !dtsgInitialData) {
44
+ utils.log("GetBotInfo", "Could not find required data (CurrentUserInitialData or DTSGInitialData).");
45
+ return null;
46
+ }
47
+
48
+ return {
49
+ name: currentUserData.NAME || null,
50
+ firstName: currentUserData.SHORT_NAME || null,
51
+ uid: currentUserData.USER_ID || null,
52
+ appID: currentUserData.APP_ID || null,
53
+ dtsgToken: dtsgInitialData.token || null,
54
+ lsdToken: lsdData?.token || null,
55
+ dtsgInit: dtsgInitData ? {
56
+ token: dtsgInitData.token,
57
+ async_get_token: dtsgInitData.async_get_token
58
+ } : undefined,
59
+ getCtx: (key) => ctx ? ctx[key] : null,
60
+ getOptions: (key) => ctx && ctx.globalOptions ? ctx.globalOptions[key] : null,
61
+ getRegion: () => ctx?.region || null,
62
+ getUserID: () => ctx?.userID || currentUserData?.USER_ID || null,
63
+ getJar: () => ctx?.jar || null
64
+ };
65
+ };
66
+ };