shadowx-fca 2.1.0 โ†’ 2.3.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 (3) hide show
  1. package/README.md +449 -0
  2. package/index.js +1 -106
  3. package/package.json +1 -1
package/README.md ADDED
@@ -0,0 +1,449 @@
1
+ ```markdown
2
+ # shadowx-fca
3
+ #Mueid Mursalin Rifat
4
+
5
+ <p align="center">
6
+ <strong>Unofficial Facebook Chat API for Node.js with Auto-Update System</strong><br>
7
+ Modified by Mueid Mursalin Rifat | Original by shadowX
8
+ </p>
9
+
10
+ ## ๐Ÿ“‹ Table of Contents
11
+
12
+ - [Features](#-features)
13
+ - [Installation](#-installation)
14
+ - [Quick Start](#-quick-start)
15
+ - [Authentication Methods](#-authentication-methods)
16
+ - [API Documentation](#-api-documentation)
17
+ - [Configuration](#-configuration)
18
+ - [Anti-Detection Features](#-anti-detection-features)
19
+ - [Troubleshooting](#-troubleshooting)
20
+ - [Examples](#-examples)
21
+ - [Changelog](#-changelog)
22
+ - [License](#-license)
23
+
24
+ ## โœจ Features
25
+
26
+ - โœ… **Multiple Authentication Methods** - Support for both appState and email/password login
27
+ - โœ… **Real-time Messaging** - MQTT/WebSocket based real-time message listening
28
+ - โœ… **Auto-Update System** - Automatically checks and updates to latest version
29
+ - โœ… **Anti-Detection** - Rotating user agents, rate limiting, and stealth headers
30
+ - โœ… **2FA Support** - Two-factor authentication handling
31
+ - โœ… **Message Attachments** - Support for images, videos, files, stickers, and more
32
+ - โœ… **Typing Indicators** - Send and receive typing status
33
+ - โœ… **Read Receipts** - Message read confirmation
34
+ - โœ… **Thread Management** - Create, delete, rename threads
35
+ - โœ… **Mention Support** - Tag users in messages (both legacy and new formats)
36
+ - โœ… **Configurable Options** - Extensive customization options
37
+
38
+ ## ๐Ÿ“ฆ Installation
39
+
40
+ ```bash
41
+ npm install shadowx-fca
42
+ ```
43
+
44
+ Requirements
45
+
46
+ ยท Node.js >= 16.0.0
47
+ ยท npm >= 7.0.0
48
+
49
+ ๐Ÿš€ Quick Start
50
+
51
+ Method 1: Using AppState (Recommended)
52
+
53
+ ```javascript
54
+ const login = require('shadowx-fca');
55
+ const fs = require('fs');
56
+
57
+ // Load saved appState
58
+ const appState = JSON.parse(fs.readFileSync('appstate.json', 'utf8'));
59
+
60
+ login({ appState: appState }, (err, api) => {
61
+ if (err) return console.error('Login failed:', err);
62
+
63
+ console.log('โœ… Logged in successfully!');
64
+
65
+ // Listen for incoming messages
66
+ api.listenMqtt((err, message) => {
67
+ if (err) return console.error('Listen error:', err);
68
+
69
+ if (message.type === 'message') {
70
+ console.log(`[${message.senderID}] ${message.body}`);
71
+
72
+ // Reply to message
73
+ api.sendMessage('Hello! I\'m a bot!', message.threadID);
74
+ }
75
+ });
76
+ });
77
+ ```
78
+
79
+ Method 2: Email & Password
80
+
81
+ ```javascript
82
+ const login = require('shadowx-fca');
83
+
84
+ login({
85
+ email: 'your_email@example.com',
86
+ password: 'your_password'
87
+ }, (err, api) => {
88
+ if (err) return console.error('Login failed:', err);
89
+
90
+ console.log('โœ… Logged in successfully!');
91
+
92
+ // Save appState for future use
93
+ const appState = api.getAppState();
94
+ fs.writeFileSync('appstate.json', JSON.stringify(appState, null, 2));
95
+
96
+ // Your bot logic here
97
+ });
98
+ ```
99
+
100
+ ๐Ÿ” Authentication Methods
101
+
102
+ 1. AppState (Recommended)
103
+
104
+ Most secure method - uses saved cookies instead of credentials.
105
+
106
+ Get your appState:
107
+
108
+ ```javascript
109
+ const login = require('shadowx-fca');
110
+ const fs = require('fs');
111
+
112
+ login({ email: 'your_email', password: 'your_password' }, (err, api) => {
113
+ if (err) return console.error(err);
114
+
115
+ const appState = api.getAppState();
116
+ fs.writeFileSync('appstate.json', JSON.stringify(appState, null, 2));
117
+ console.log('โœ… AppState saved! You can now use this file to login.');
118
+ process.exit(0);
119
+ });
120
+ ```
121
+
122
+ 2. Email & Password
123
+
124
+ Traditional method with 2FA support.
125
+
126
+ With 2FA:
127
+
128
+ ```javascript
129
+ login({ email: 'email@example.com', password: 'password' }, (err, api) => {
130
+ if (err && err.error === 'login-approval') {
131
+ console.log('Enter 2FA code:');
132
+ // Get code from user input
133
+ const twoFACode = '123456';
134
+ err.continue(twoFACode);
135
+ }
136
+ });
137
+ ```
138
+
139
+ ๐Ÿ“š API Documentation
140
+
141
+ Core Methods
142
+
143
+ login(loginData, [options], callback)
144
+
145
+ Main login function.
146
+
147
+ Parameters:
148
+
149
+ ยท loginData - Object containing either appState or email/password
150
+ ยท options - Optional configuration object
151
+ ยท callback - Function called after login
152
+
153
+ api.sendMessage(message, threadID, [callback], [replyToMessage], [isSingleUser])
154
+
155
+ Send a message to a thread.
156
+
157
+ ```javascript
158
+ // Simple message
159
+ api.sendMessage('Hello world!', 'thread_id_here');
160
+
161
+ // With reply
162
+ api.sendMessage('Replying to you!', 'thread_id_here', null, 'message_id_here');
163
+
164
+ // With mention
165
+ api.sendMessage('Hello @John Doe', 'thread_id_here');
166
+ ```
167
+
168
+ api.listenMqtt(callback)
169
+
170
+ Listen for incoming events (messages, typing, presence).
171
+
172
+ ```javascript
173
+ api.listenMqtt((err, event) => {
174
+ if (err) return console.error(err);
175
+
176
+ switch(event.type) {
177
+ case 'message':
178
+ console.log('New message:', event.body);
179
+ break;
180
+ case 'event':
181
+ console.log('Thread event:', event.logMessageType);
182
+ break;
183
+ case 'typ':
184
+ console.log(event.isTyping ? 'Typing...' : 'Stopped typing');
185
+ break;
186
+ }
187
+ });
188
+ ```
189
+
190
+ api.getThreadInfo(threadID, callback)
191
+
192
+ Get information about a thread.
193
+
194
+ ```javascript
195
+ api.getThreadInfo('thread_id_here', (err, info) => {
196
+ if (err) return console.error(err);
197
+ console.log('Thread name:', info.name);
198
+ console.log('Participants:', info.participants);
199
+ console.log('Unread count:', info.unreadCount);
200
+ });
201
+ ```
202
+
203
+ api.getUserInfo(userID, callback)
204
+
205
+ Get user information.
206
+
207
+ ```javascript
208
+ api.getUserInfo('user_id_here', (err, info) => {
209
+ if (err) return console.error(err);
210
+ console.log('Name:', info.name);
211
+ console.log('Gender:', info.gender);
212
+ });
213
+ ```
214
+
215
+ api.setOptions(options)
216
+
217
+ Update API options at runtime.
218
+
219
+ ```javascript
220
+ api.setOptions({
221
+ listenEvents: true,
222
+ autoMarkRead: false,
223
+ delayBetweenRequests: 2000
224
+ });
225
+ ```
226
+
227
+ Additional Methods
228
+
229
+ Method Description
230
+ api.getAppState() Get current appState (cookies)
231
+ api.markAsRead(threadID, callback) Mark thread as read
232
+ api.markAsDelivered(threadID, messageID, callback) Mark message as delivered
233
+ api.sendTypingIndicator(threadID, callback) Send typing indicator
234
+ api.changeNickname(nickname, threadID, userID, callback) Change user nickname
235
+ api.addUserToGroup(userID, threadID, callback) Add user to group
236
+ api.removeUserFromGroup(userID, threadID, callback) Remove user from group
237
+ api.createNewGroup(participantIDs, groupName, callback) Create new group
238
+ api.deleteThread(threadID, callback) Delete/leave thread
239
+ api.getThreadList(limit, timestamp, tags, callback) Get thread list
240
+
241
+ โš™๏ธ Configuration
242
+
243
+ Global Configuration (config.json)
244
+
245
+ Create config.json in your project root:
246
+
247
+ ```json
248
+ {
249
+ "enableTypingIndicator": false,
250
+ "typingDuration": 4000,
251
+ "delayBetweenRequests": 1500,
252
+ "autoMarkDelivery": false,
253
+ "autoMarkRead": false,
254
+ "listenEvents": true,
255
+ "selfListen": false,
256
+ "autoReconnect": true,
257
+ "logLevel": "info",
258
+ "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
259
+ }
260
+ ```
261
+
262
+ Options Reference
263
+
264
+ Option Type Default Description
265
+ selfListen Boolean false Listen to own messages
266
+ listenEvents Boolean true Listen to thread events
267
+ listenTyping Boolean false Listen to typing indicators
268
+ updatePresence Boolean false Update online status
269
+ forceLogin Boolean false Force login even if suspicious
270
+ autoMarkDelivery Boolean false Auto-mark messages as delivered
271
+ autoMarkRead Boolean false Auto-mark messages as read
272
+ autoReconnect Boolean true Auto-reconnect on disconnect
273
+ delayBetweenRequests Number 1000 Delay between API requests (ms)
274
+ logLevel String "info" Log level (silent/error/warn/info/verbose)
275
+
276
+ ๐Ÿ›ก๏ธ Anti-Detection Features
277
+
278
+ shadowx-fca includes several features to avoid Facebook's anti-bot detection:
279
+
280
+ 1. Rate Limiting
281
+
282
+ ```javascript
283
+ // Set custom delay between requests
284
+ api.setOptions({ delayBetweenRequests: 2000 });
285
+ ```
286
+
287
+ 2. Rotating User Agents
288
+
289
+ Automatically rotates between different user agents to avoid fingerprinting.
290
+
291
+ 3. Stealth Headers
292
+
293
+ Includes realistic browser headers (Sec-Ch-Ua, Accept-Language, etc.)
294
+
295
+ 4. Request Queue
296
+
297
+ Automatically queues and spaces out requests to prevent rate limiting.
298
+
299
+ ๐Ÿ”ง Troubleshooting
300
+
301
+ Common Issues & Solutions
302
+
303
+ 1. "Error! Your cookiestate is not valid!"
304
+
305
+ Solution: Refresh your appState
306
+
307
+ ```javascript
308
+ // Get new appState
309
+ login({ email: 'your_email', password: 'your_password' }, (err, api) => {
310
+ const newAppState = api.getAppState();
311
+ fs.writeFileSync('appstate.json', JSON.stringify(newAppState, null, 2));
312
+ });
313
+ ```
314
+
315
+ 2. Account Suspension
316
+
317
+ Solutions:
318
+
319
+ ยท Increase delay between requests
320
+ ยท Don't spam messages (add 2-3 second delays)
321
+ ยท Use appState instead of email/password
322
+ ยท Avoid running 24/7
323
+ ยท Use a proxy if running multiple bots
324
+
325
+ 3. Login Timeout
326
+
327
+ Solution: Increase timeout in options
328
+
329
+ ```javascript
330
+ login({ appState: appState }, { timeout: 120000 }, callback);
331
+ ```
332
+
333
+ 4. MQTT Connection Issues
334
+
335
+ Solution: Enable auto-reconnect
336
+
337
+ ```javascript
338
+ api.setOptions({ autoReconnect: true });
339
+ ```
340
+
341
+ ๐Ÿ’ก Examples
342
+
343
+ Simple Echo Bot
344
+
345
+ ```javascript
346
+ const login = require('shadowx-fca');
347
+
348
+ login({ appState: require('./appstate.json') }, (err, api) => {
349
+ if (err) return console.error(err);
350
+
351
+ api.listenMqtt((err, message) => {
352
+ if (err) return console.error(err);
353
+
354
+ if (message.type === 'message' && message.body) {
355
+ // Echo the message back
356
+ api.sendMessage(message.body, message.threadID);
357
+ }
358
+ });
359
+ });
360
+ ```
361
+
362
+ Command Handler
363
+
364
+ ```javascript
365
+ const commands = {
366
+ '!help': (api, message) => {
367
+ api.sendMessage('Available commands: !help, !time, !ping', message.threadID);
368
+ },
369
+ '!time': (api, message) => {
370
+ api.sendMessage(`Current time: ${new Date().toLocaleString()}`, message.threadID);
371
+ },
372
+ '!ping': (api, message) => {
373
+ api.sendMessage('Pong!', message.threadID);
374
+ }
375
+ };
376
+
377
+ login({ appState: require('./appstate.json') }, (err, api) => {
378
+ if (err) return console.error(err);
379
+
380
+ api.listenMqtt((err, message) => {
381
+ if (err) return console.error(err);
382
+
383
+ if (message.type === 'message' && message.body) {
384
+ const cmd = message.body.split(' ')[0];
385
+ if (commands[cmd]) commands[cmd](api, message);
386
+ }
387
+ });
388
+ });
389
+ ```
390
+
391
+ Auto-Reply with Delay
392
+
393
+ ```javascript
394
+ login({ appState: require('./appstate.json') }, (err, api) => {
395
+ if (err) return console.error(err);
396
+
397
+ api.listenMqtt((err, message) => {
398
+ if (err) return console.error(err);
399
+
400
+ if (message.type === 'message' && !message.isGroup) {
401
+ // Add delay to avoid rate limiting
402
+ setTimeout(() => {
403
+ api.sendMessage('Thanks for your message! I\'ll reply soon.', message.threadID);
404
+ }, 3000);
405
+ }
406
+ });
407
+ });
408
+ ```
409
+
410
+ ๐Ÿ“ Changelog
411
+
412
+ v2.1.0 (Latest)
413
+
414
+ ยท โœจ Added rotating user agents for anti-detection
415
+ ยท ๐Ÿš€ Implemented request queue with rate limiting
416
+ ยท ๐Ÿ”ง Fixed email/password login issues
417
+ ยท ๐Ÿ›ก๏ธ Enhanced security headers
418
+ ยท ๐Ÿ“š Improved documentation
419
+
420
+ v2.0.0
421
+
422
+ ยท Added auto-update system
423
+ ยท Improved MQTT connection stability
424
+ ยท Added support for new mention format
425
+ ยท Fixed 2FA handling
426
+
427
+ ๐Ÿ“„ License
428
+
429
+ This project is licensed under the MIT License - see the LICENSE file for details.
430
+
431
+ โš ๏ธ Disclaimer
432
+
433
+ This project is for educational purposes only. Use at your own risk. The authors are not responsible for any consequences that may arise from using this software, including but not limited to account suspension or legal action from Facebook.
434
+
435
+ ๐Ÿค Contributing
436
+
437
+ Contributions are welcome! Please feel free to submit a Pull Request.
438
+
439
+ ๐Ÿ“ž Support
440
+
441
+ ยท Issues: t.me/mueidmursalinrifat
442
+ ยท Author: Mueid Mursalin Rifat
443
+
444
+ ---
445
+
446
+ <div align="center">
447
+ Made with โค๏ธ by Mueid Mursalin Rifat
448
+ </div>
449
+ ```
package/index.js CHANGED
@@ -3,28 +3,11 @@
3
3
  var utils = require("./utils");
4
4
  var cheerio = require("cheerio");
5
5
  var log = require("npmlog");
6
- var { checkForFCAUpdate } = require("./checkUpdate");
7
- const fs = require('fs');
8
- const path = require('path');
9
- /*var { getThemeColors } = require("../../func/utils/log.js");
10
- var logger = require("../../func/utils/log.js");
11
- var { cra, cv, cb, co } = getThemeColors();*/
6
+
12
7
  log.maxRecordSize = 100;
13
8
  var checkVerified = null;
14
9
  const Boolean_Option = ['online', 'selfListen', 'listenEvents', 'updatePresence', 'forceLogin', 'autoMarkDelivery', 'autoMarkRead', 'listenTyping', 'autoReconnect', 'emitReady'];
15
10
  global.ditconmemay = false;
16
- global.stfcaUpdateChecked = false;
17
-
18
- // Auto-check for updates on package load (non-blocking)
19
- if (!global.stfcaUpdateChecked) {
20
- global.stfcaUpdateChecked = true;
21
- const { checkForFCAUpdate } = require("./checkUpdate");
22
- setImmediate(() => {
23
- checkForFCAUpdate().catch(() => {
24
- // Silent fail - don't interrupt user's bot
25
- });
26
- });
27
- }
28
11
 
29
12
  function setOptions(globalOptions, options) {
30
13
  Object.keys(options).map(function (key) {
@@ -190,86 +173,6 @@ function buildAPI(globalOptions, html, jar) {
190
173
  reqCallbacks: {},
191
174
  threadTypes: {} // Store thread type (dm/group) for each thread
192
175
  };
193
- let config = { enableTypingIndicator: false, typingDuration: 4000 };
194
- try {
195
- // Prefer global root config (project-level), but fallback to fca/config.json if present.
196
- const rootConfigPath = path.join(process.cwd(), 'config.json');
197
- if (fs.existsSync(rootConfigPath)) {
198
- const rootConfig = JSON.parse(fs.readFileSync(rootConfigPath, 'utf8'));
199
- if (rootConfig && typeof rootConfig === 'object') {
200
- if (typeof rootConfig.enableTypingIndicator !== 'undefined') config.enableTypingIndicator = rootConfig.enableTypingIndicator;
201
- if (typeof rootConfig.typingDuration !== 'undefined') config.typingDuration = rootConfig.typingDuration;
202
- }
203
- }
204
-
205
- const fcaConfigPath = path.join(__dirname, 'config.json');
206
- if (fs.existsSync(fcaConfigPath)) {
207
- const fcaConfig = JSON.parse(fs.readFileSync(fcaConfigPath, 'utf8'));
208
- if (fcaConfig && typeof fcaConfig === 'object') {
209
- if (typeof fcaConfig.enableTypingIndicator !== 'undefined') config.enableTypingIndicator = fcaConfig.enableTypingIndicator;
210
- if (typeof fcaConfig.typingDuration !== 'undefined') config.typingDuration = fcaConfig.typingDuration;
211
- }
212
- }
213
-
214
- if (global.GoatBot && global.GoatBot.config) {
215
- if (typeof global.GoatBot.config.enableTypingIndicator !== 'undefined') config.enableTypingIndicator = global.GoatBot.config.enableTypingIndicator;
216
- if (typeof global.GoatBot.config.typingDuration !== 'undefined') config.typingDuration = global.GoatBot.config.typingDuration;
217
- }
218
- } catch (e) {
219
- console.log('Error loading config.json:', e);
220
- }
221
-
222
- const refreshFcaConfig = () => {
223
- try {
224
- // Defaults first
225
- const updatedConfig = { enableTypingIndicator: false, typingDuration: 4000 };
226
-
227
- // Layered config sources
228
- if (fs.existsSync(path.join(process.cwd(), 'config.json'))) {
229
- const rootConfig = JSON.parse(fs.readFileSync(path.join(process.cwd(), 'config.json'), 'utf8'));
230
- if (rootConfig && typeof rootConfig === 'object') {
231
- if (typeof rootConfig.enableTypingIndicator !== 'undefined') updatedConfig.enableTypingIndicator = rootConfig.enableTypingIndicator;
232
- if (typeof rootConfig.typingDuration !== 'undefined') updatedConfig.typingDuration = rootConfig.typingDuration;
233
- }
234
- }
235
-
236
- if (fs.existsSync(path.join(__dirname, 'config.json'))) {
237
- const fcaConfig = JSON.parse(fs.readFileSync(path.join(__dirname, 'config.json'), 'utf8'));
238
- if (fcaConfig && typeof fcaConfig === 'object') {
239
- if (typeof fcaConfig.enableTypingIndicator !== 'undefined') updatedConfig.enableTypingIndicator = fcaConfig.enableTypingIndicator;
240
- if (typeof fcaConfig.typingDuration !== 'undefined') updatedConfig.typingDuration = fcaConfig.typingDuration;
241
- }
242
- }
243
-
244
- if (global.GoatBot && global.GoatBot.config) {
245
- if (typeof global.GoatBot.config.enableTypingIndicator !== 'undefined') updatedConfig.enableTypingIndicator = global.GoatBot.config.enableTypingIndicator;
246
- if (typeof global.GoatBot.config.typingDuration !== 'undefined') updatedConfig.typingDuration = global.GoatBot.config.typingDuration;
247
- }
248
-
249
- ctx.config = updatedConfig;
250
- config = updatedConfig;
251
- if (global.GoatBot) global.GoatBot.config = global.GoatBot.config || {};
252
- if (global.GoatBot && typeof global.GoatBot.config.enableTypingIndicator !== 'undefined') {
253
- global.GoatBot.config.enableTypingIndicator = updatedConfig.enableTypingIndicator;
254
- }
255
- if (global.GoatBot && typeof global.GoatBot.config.typingDuration !== 'undefined') {
256
- global.GoatBot.config.typingDuration = updatedConfig.typingDuration;
257
- }
258
- } catch (e) {
259
- console.log('Failed to refresh fca config:', e);
260
- }
261
- };
262
-
263
- // Initial config load
264
- refreshFcaConfig();
265
-
266
- // Accessible runtime API for config reload
267
- ctx.refreshFcaConfig = refreshFcaConfig;
268
- if (global.GoatBot) {
269
- global.GoatBot.refreshFcaConfig = refreshFcaConfig;
270
- }
271
-
272
- ctx.config = config;
273
176
  var api = {
274
177
  setOptions: setOptions.bind(null, globalOptions),
275
178
  getAppState: () => utils.getAppState(jar),
@@ -523,14 +426,6 @@ function loginHelper(appState, email, password, globalOptions, callback, prCallb
523
426
 
524
427
 
525
428
  function login(loginData, options, callback) {
526
- // Check for updates (non-blocking, only once per session)
527
- if (!global.stfcaUpdateChecked) {
528
- global.stfcaUpdateChecked = true;
529
- checkForFCAUpdate().catch(err => {
530
- // Silently ignore update check errors to not block login
531
- });
532
- }
533
-
534
429
  if (utils.getType(options) === 'Function' || utils.getType(options) === 'AsyncFunction') {
535
430
  callback = options;
536
431
  options = {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "shadowx-fca",
3
- "version": "2.1.0",
3
+ "version": "2.3.0",
4
4
  "description": "Unofficial Facebook Chat API for Node.js with Auto-Update System - modify by Mueid Mursalin Rifat",
5
5
  "main": "index.js",
6
6
  "files": [