@cexy/hoonfca 1.0.7 → 2.0.1
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.
- package/LICENSE +3 -0
- package/examples/login-with-cookies.js +102 -0
- package/examples/verify.js +70 -0
- package/index.js +2 -8
- package/package.json +82 -61
- package/src/{api/action → apis}/addExternalModule.js +24 -25
- package/src/apis/addUserToGroup.js +108 -0
- package/src/apis/changeAdminStatus.js +148 -0
- package/src/apis/changeArchivedStatus.js +61 -0
- package/src/apis/changeAvatar.js +103 -0
- package/src/apis/changeBio.js +69 -0
- package/src/apis/changeBlockedStatus.js +54 -0
- package/src/apis/changeGroupImage.js +136 -0
- package/src/apis/changeThreadColor.js +116 -0
- package/src/apis/changeThreadEmoji.js +53 -0
- package/src/apis/comment.js +207 -0
- package/src/apis/createAITheme.js +129 -0
- package/src/apis/createNewGroup.js +79 -0
- package/src/apis/createPoll.js +73 -0
- package/src/apis/deleteMessage.js +44 -0
- package/src/apis/deleteThread.js +52 -0
- package/src/apis/e2ee.js +17 -0
- package/src/apis/editMessage.js +70 -0
- package/src/apis/emoji.js +124 -0
- package/src/apis/fetchThemeData.js +82 -0
- package/src/apis/follow.js +81 -0
- package/src/apis/forwardMessage.js +52 -0
- package/src/apis/friend.js +243 -0
- package/src/apis/gcmember.js +122 -0
- package/src/apis/gcname.js +123 -0
- package/src/apis/gcrule.js +119 -0
- package/src/apis/getAccess.js +111 -0
- package/src/apis/getBotInfo.js +88 -0
- package/src/apis/getBotInitialData.js +43 -0
- package/src/apis/getFriendsList.js +79 -0
- package/src/apis/getMessage.js +423 -0
- package/src/apis/getTheme.js +95 -0
- package/src/apis/getThemeInfo.js +116 -0
- package/src/apis/getThreadHistory.js +239 -0
- package/src/apis/getThreadInfo.js +267 -0
- package/src/apis/getThreadList.js +232 -0
- package/src/apis/getThreadPictures.js +58 -0
- package/src/apis/getUserID.js +117 -0
- package/src/apis/getUserInfo.js +513 -0
- package/src/{api/users → apis}/getUserInfoV2.js +146 -134
- package/src/apis/handleMessageRequest.js +50 -0
- package/src/apis/httpGet.js +63 -0
- package/src/apis/httpPost.js +89 -0
- package/src/apis/httpPostFormData.js +69 -0
- package/src/apis/listenMqtt.js +1236 -0
- package/src/apis/listenSpeed.js +179 -0
- package/src/apis/logout.js +87 -0
- package/src/apis/markAsDelivered.js +47 -0
- package/src/{api/messaging → apis}/markAsRead.js +99 -88
- package/src/apis/markAsReadAll.js +40 -0
- package/src/apis/markAsSeen.js +70 -0
- package/src/apis/mqttDeltaValue.js +278 -0
- package/src/apis/muteThread.js +45 -0
- package/src/apis/nickname.js +132 -0
- package/src/apis/notes.js +163 -0
- package/src/apis/pinMessage.js +150 -0
- package/src/apis/produceMetaTheme.js +180 -0
- package/src/apis/realtime.js +182 -0
- package/src/apis/removeUserFromGroup.js +117 -0
- package/src/apis/resolvePhotoUrl.js +58 -0
- package/src/apis/searchForThread.js +154 -0
- package/src/apis/sendMessage.js +354 -0
- package/src/apis/sendMessageMqtt.js +249 -0
- package/src/apis/sendTypingIndicator.js +91 -0
- package/src/apis/setMessageReaction.js +27 -0
- package/src/apis/setMessageReactionMqtt.js +61 -0
- package/src/apis/setThreadTheme.js +260 -0
- package/src/apis/setThreadThemeMqtt.js +94 -0
- package/src/apis/share.js +107 -0
- package/src/apis/shareContact.js +66 -0
- package/src/apis/stickers.js +257 -0
- package/src/apis/story.js +181 -0
- package/src/apis/theme.js +233 -0
- package/src/apis/unfriend.js +47 -0
- package/src/apis/unsendMessage.js +17 -0
- package/src/engine/client.js +92 -0
- package/src/engine/models/buildAPI.js +152 -0
- package/src/engine/models/loginHelper.js +519 -0
- package/src/engine/models/setOptions.js +88 -0
- package/src/security/e2ee.js +109 -0
- package/src/types/index.d.ts +498 -0
- package/src/utils/antiSuspension.js +506 -0
- package/src/utils/auth-helpers.js +149 -0
- package/src/utils/autoReLogin.js +336 -0
- package/src/utils/axios.js +436 -0
- package/src/utils/cache.js +54 -0
- package/src/utils/clients.js +282 -0
- package/src/utils/constants.js +410 -23
- package/src/utils/formatters/data/formatAttachment.js +370 -0
- package/src/utils/formatters/data/formatDelta.js +109 -0
- package/src/utils/formatters/index.js +159 -0
- package/src/utils/formatters/value/formatCookie.js +91 -0
- package/src/utils/formatters/value/formatDate.js +36 -0
- package/src/utils/formatters/value/formatID.js +16 -0
- package/src/utils/formatters.js +1373 -0
- package/src/utils/headers.js +214 -99
- package/src/utils/index.js +153 -0
- package/src/utils/monitoring.js +333 -0
- package/src/utils/rateLimiter.js +319 -0
- package/src/utils/tokenRefresh.js +657 -0
- package/src/utils/user-agents.js +238 -0
- package/src/utils/validation.js +157 -0
- package/CHANGELOG.md +0 -181
- package/DOCS.md +0 -2636
- package/LICENSE-MIT +0 -21
- package/README.md +0 -632
- package/func/checkUpdate.js +0 -233
- package/func/logger.js +0 -48
- package/index.d.ts +0 -746
- package/module/config.js +0 -67
- package/module/login.js +0 -154
- package/module/loginHelper.js +0 -1034
- package/module/options.js +0 -54
- package/src/api/action/changeAvatar.js +0 -137
- package/src/api/action/changeBio.js +0 -75
- package/src/api/action/enableAutoSaveAppState.js +0 -73
- package/src/api/action/getCurrentUserID.js +0 -7
- package/src/api/action/handleFriendRequest.js +0 -57
- package/src/api/action/logout.js +0 -76
- package/src/api/action/refreshFb_dtsg.js +0 -48
- package/src/api/action/setPostReaction.js +0 -106
- package/src/api/action/unfriend.js +0 -54
- package/src/api/http/httpGet.js +0 -46
- package/src/api/http/httpPost.js +0 -52
- package/src/api/http/postFormData.js +0 -47
- package/src/api/messaging/addUserToGroup.js +0 -68
- package/src/api/messaging/changeAdminStatus.js +0 -122
- package/src/api/messaging/changeArchivedStatus.js +0 -55
- package/src/api/messaging/changeBlockedStatus.js +0 -48
- package/src/api/messaging/changeGroupImage.js +0 -90
- package/src/api/messaging/changeNickname.js +0 -70
- package/src/api/messaging/changeThreadColor.js +0 -79
- package/src/api/messaging/changeThreadEmoji.js +0 -106
- package/src/api/messaging/createNewGroup.js +0 -88
- package/src/api/messaging/createPoll.js +0 -43
- package/src/api/messaging/createThemeAI.js +0 -98
- package/src/api/messaging/deleteMessage.js +0 -56
- package/src/api/messaging/deleteThread.js +0 -56
- package/src/api/messaging/editMessage.js +0 -68
- package/src/api/messaging/forwardAttachment.js +0 -51
- package/src/api/messaging/getEmojiUrl.js +0 -29
- package/src/api/messaging/getFriendsList.js +0 -82
- package/src/api/messaging/getMessage.js +0 -829
- package/src/api/messaging/getThemePictures.js +0 -62
- package/src/api/messaging/handleMessageRequest.js +0 -65
- package/src/api/messaging/markAsDelivered.js +0 -57
- package/src/api/messaging/markAsReadAll.js +0 -49
- package/src/api/messaging/markAsSeen.js +0 -61
- package/src/api/messaging/muteThread.js +0 -50
- package/src/api/messaging/removeUserFromGroup.js +0 -106
- package/src/api/messaging/resolvePhotoUrl.js +0 -43
- package/src/api/messaging/scheduler.js +0 -264
- package/src/api/messaging/searchForThread.js +0 -52
- package/src/api/messaging/sendMessage.js +0 -272
- package/src/api/messaging/sendTypingIndicator.js +0 -67
- package/src/api/messaging/setMessageReaction.js +0 -76
- package/src/api/messaging/setTitle.js +0 -119
- package/src/api/messaging/shareContact.js +0 -49
- package/src/api/messaging/threadColors.js +0 -128
- package/src/api/messaging/unsendMessage.js +0 -81
- package/src/api/messaging/uploadAttachment.js +0 -94
- package/src/api/socket/core/connectMqtt.js +0 -255
- package/src/api/socket/core/emitAuth.js +0 -106
- package/src/api/socket/core/getSeqID.js +0 -40
- package/src/api/socket/core/getTaskResponseData.js +0 -22
- package/src/api/socket/core/markDelivery.js +0 -12
- package/src/api/socket/core/parseDelta.js +0 -391
- package/src/api/socket/detail/buildStream.js +0 -208
- package/src/api/socket/detail/constants.js +0 -24
- package/src/api/socket/listenMqtt.js +0 -364
- package/src/api/socket/middleware/index.js +0 -216
- package/src/api/threads/getThreadHistory.js +0 -664
- package/src/api/threads/getThreadInfo.js +0 -438
- package/src/api/threads/getThreadList.js +0 -293
- package/src/api/threads/getThreadPictures.js +0 -78
- package/src/api/users/getUserID.js +0 -65
- package/src/api/users/getUserInfo.js +0 -327
- package/src/core/sendReqMqtt.js +0 -96
- package/src/database/models/index.js +0 -87
- package/src/database/models/thread.js +0 -45
- package/src/database/models/user.js +0 -46
- package/src/database/threadData.js +0 -98
- package/src/database/userData.js +0 -89
- package/src/utils/client.js +0 -320
- package/src/utils/format.js +0 -1115
- package/src/utils/request.js +0 -305
package/LICENSE
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Example: Login with Cookie Array
|
|
6
|
+
*
|
|
7
|
+
* This demonstrates how to login to Facebook Chat API using a cookie array
|
|
8
|
+
* instead of email/password credentials.
|
|
9
|
+
*
|
|
10
|
+
* Cookie Format:
|
|
11
|
+
* - Array of objects with 'name' (or 'key') and 'value' properties
|
|
12
|
+
* - Extracted from browser cookies or previous session
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
const login = require('../index.js');
|
|
16
|
+
|
|
17
|
+
// Method 1: Cookie Array with 'name' property
|
|
18
|
+
const cookieArray = [
|
|
19
|
+
{
|
|
20
|
+
name: 'c_user',
|
|
21
|
+
value: 'YOUR_USER_ID_HERE'
|
|
22
|
+
},
|
|
23
|
+
{
|
|
24
|
+
name: 'xs',
|
|
25
|
+
value: 'YOUR_XS_TOKEN_HERE'
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
name: 'fr',
|
|
29
|
+
value: 'YOUR_FR_TOKEN_HERE'
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
name: 'datr',
|
|
33
|
+
value: 'YOUR_DATR_TOKEN_HERE'
|
|
34
|
+
}
|
|
35
|
+
];
|
|
36
|
+
|
|
37
|
+
// Method 2: Cookie Array with 'key' property (alternative)
|
|
38
|
+
const cookieArrayAlt = [
|
|
39
|
+
{
|
|
40
|
+
key: 'c_user',
|
|
41
|
+
value: 'YOUR_USER_ID_HERE'
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
key: 'xs',
|
|
45
|
+
value: 'YOUR_XS_TOKEN_HERE'
|
|
46
|
+
}
|
|
47
|
+
];
|
|
48
|
+
|
|
49
|
+
// Method 3: Cookie String format (semicolon-separated)
|
|
50
|
+
const cookieString = 'c_user=YOUR_USER_ID_HERE; xs=YOUR_XS_TOKEN_HERE; fr=YOUR_FR_TOKEN_HERE; datr=YOUR_DATR_TOKEN_HERE';
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Login using cookie array
|
|
54
|
+
*/
|
|
55
|
+
async function loginWithCookies() {
|
|
56
|
+
try {
|
|
57
|
+
const api = await login.login({
|
|
58
|
+
appState: cookieArray // Pass the cookie array here
|
|
59
|
+
}, {
|
|
60
|
+
logging: true,
|
|
61
|
+
listenEvents: true,
|
|
62
|
+
autoMarkRead: true,
|
|
63
|
+
selfListen: false
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
console.log('✓ Successfully logged in using cookies!');
|
|
67
|
+
console.log('✓ User ID:', api.getCurrentUserID());
|
|
68
|
+
|
|
69
|
+
// Now you can use the API normally
|
|
70
|
+
// Example: Send a message
|
|
71
|
+
// api.sendMessage("Hello World!", threadID);
|
|
72
|
+
|
|
73
|
+
// Clean up
|
|
74
|
+
api.stopListening();
|
|
75
|
+
process.exit(0);
|
|
76
|
+
|
|
77
|
+
} catch (error) {
|
|
78
|
+
console.error('✗ Login failed:', error.message);
|
|
79
|
+
process.exit(1);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* How to extract cookies from your browser:
|
|
85
|
+
*
|
|
86
|
+
* 1. Open Facebook in your browser
|
|
87
|
+
* 2. Open Developer Tools (F12)
|
|
88
|
+
* 3. Go to Application → Cookies → facebook.com
|
|
89
|
+
* 4. Copy the critical cookies:
|
|
90
|
+
* - c_user: Your user ID
|
|
91
|
+
* - xs: Session token
|
|
92
|
+
* - fr: Fraud detection
|
|
93
|
+
* - datr: Device fingerprint
|
|
94
|
+
*
|
|
95
|
+
* 5. Replace the values in cookieArray above
|
|
96
|
+
* 6. Run: node examples/login-with-cookies.js
|
|
97
|
+
*/
|
|
98
|
+
|
|
99
|
+
// Uncomment to run:
|
|
100
|
+
// loginWithCookies();
|
|
101
|
+
|
|
102
|
+
module.exports = { loginWithCookies, cookieArray };
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Quick sanity check — verifies the library loads correctly and
|
|
6
|
+
* prints the anti-suspension configuration. Run with:
|
|
7
|
+
* node examples/verify.js
|
|
8
|
+
*/
|
|
9
|
+
|
|
10
|
+
const fca = require('../index.js');
|
|
11
|
+
const { globalAntiSuspension } = require('../src/utils/antiSuspension');
|
|
12
|
+
const { globalRateLimiter } = require('../src/utils/rateLimiter');
|
|
13
|
+
|
|
14
|
+
console.log('nkxfca Library Verification');
|
|
15
|
+
console.log('================================\n');
|
|
16
|
+
|
|
17
|
+
console.log('Library entry point:', typeof fca.login === 'function' ? 'OK' : 'FAIL');
|
|
18
|
+
|
|
19
|
+
const config = globalAntiSuspension.getConfig();
|
|
20
|
+
console.log('\nAnti-Suspension Configuration:');
|
|
21
|
+
console.log(` Message Delay : ${config.messageDelayMs}ms`);
|
|
22
|
+
console.log(` Thread Delay : ${config.threadDelayMs}ms`);
|
|
23
|
+
console.log(` Max Login Tries : ${config.maxLoginAttempts}`);
|
|
24
|
+
console.log(` Login Cooldown : ${config.loginCooldownMs}ms`);
|
|
25
|
+
console.log(` Daily Msg Limit : ${config.dailyStats.maxDailyMessages}`);
|
|
26
|
+
console.log(` Hourly Msg Limit : ${config.hourlyStats.maxPerHour}`);
|
|
27
|
+
|
|
28
|
+
console.log('\nEnabled Features:');
|
|
29
|
+
Object.entries(config.features).forEach(([feature, enabled]) => {
|
|
30
|
+
console.log(` ${enabled ? '[x]' : '[ ]'} ${feature}`);
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
const activityPattern = globalAntiSuspension.getRealisticActivityPattern();
|
|
34
|
+
console.log('\nActivity Pattern:');
|
|
35
|
+
console.log(` Current activity : ${activityPattern.messageFrequency}`);
|
|
36
|
+
console.log(` Next action delay : ${activityPattern.nextActionDelayMs.toFixed(0)}ms`);
|
|
37
|
+
console.log(` Is active hours : ${activityPattern.isActiveHours}`);
|
|
38
|
+
|
|
39
|
+
console.log('\nCircuit Breaker:');
|
|
40
|
+
console.log(` Tripped : ${globalAntiSuspension.isCircuitBreakerTripped()}`);
|
|
41
|
+
console.log(` Signal count : ${globalAntiSuspension.suspensionCircuitBreaker.signalCount}`);
|
|
42
|
+
|
|
43
|
+
const rateLimiterStats = globalRateLimiter.getStats();
|
|
44
|
+
console.log('\nRate Limiter:');
|
|
45
|
+
console.log(` Max concurrent : ${rateLimiterStats.maxConcurrentRequests}`);
|
|
46
|
+
console.log(` Max per minute : ${rateLimiterStats.maxRequestsPerMinute}`);
|
|
47
|
+
console.log(` Requests (1 min) : ${rateLimiterStats.requestsInLastMinute}`);
|
|
48
|
+
|
|
49
|
+
// Test suspension signal detection
|
|
50
|
+
const testSignals = [
|
|
51
|
+
{ text: 'Everything is fine, message sent', expectSuspicion: false },
|
|
52
|
+
{ text: 'Your account has been suspended due to policy violation', expectSuspicion: true },
|
|
53
|
+
{ text: 'checkpoint required to verify identity', expectSuspicion: true },
|
|
54
|
+
{ text: 'Too many requests - rate limited', expectSuspicion: true },
|
|
55
|
+
{ text: 'Unusual activity detected on your account', expectSuspicion: true },
|
|
56
|
+
];
|
|
57
|
+
console.log('\nSuspension Signal Detection:');
|
|
58
|
+
testSignals.forEach(({ text, expectSuspicion }) => {
|
|
59
|
+
globalAntiSuspension.resetCircuitBreaker();
|
|
60
|
+
const detected = globalAntiSuspension.detectSuspensionSignal(text);
|
|
61
|
+
const passed = detected === expectSuspicion;
|
|
62
|
+
globalAntiSuspension.resetCircuitBreaker();
|
|
63
|
+
console.log(` ${passed ? '[x]' : '[!]'} "${text.substring(0, 40)}" → ${detected ? 'SUSPICIOUS' : 'CLEAN'}`);
|
|
64
|
+
});
|
|
65
|
+
globalAntiSuspension.resetCircuitBreaker();
|
|
66
|
+
|
|
67
|
+
console.log('\nAll checks passed. Library is ready to use.');
|
|
68
|
+
console.log('============================\n');
|
|
69
|
+
|
|
70
|
+
process.exit(0);
|
package/index.js
CHANGED
|
@@ -1,8 +1,2 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
// CommonJS default export
|
|
4
|
-
module.exports = login;
|
|
5
|
-
// Support require('{ login }') named import pattern
|
|
6
|
-
module.exports.login = login;
|
|
7
|
-
// Support ESM default import interop
|
|
8
|
-
module.exports.default = login;
|
|
1
|
+
"use strict";
|
|
2
|
+
module.exports = require('./src/engine/client');
|
package/package.json
CHANGED
|
@@ -1,82 +1,103 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cexy/hoonfca",
|
|
3
|
-
"version": "
|
|
4
|
-
"
|
|
3
|
+
"version": "2.0.1",
|
|
4
|
+
"type": "commonjs",
|
|
5
|
+
"types": "src/types/index.d.ts",
|
|
6
|
+
"description": "Rakib FCA - Advanced Facebook Chat API",
|
|
5
7
|
"main": "index.js",
|
|
6
|
-
"
|
|
7
|
-
|
|
8
|
-
"
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
13
|
-
},
|
|
14
|
-
"scripts": {
|
|
15
|
-
"test": "mocha",
|
|
16
|
-
"lint": "eslint ."
|
|
17
|
-
},
|
|
8
|
+
"files": [
|
|
9
|
+
"index.js",
|
|
10
|
+
"src/",
|
|
11
|
+
"examples/",
|
|
12
|
+
"LICENSE"
|
|
13
|
+
],
|
|
18
14
|
"repository": {
|
|
19
15
|
"type": "git",
|
|
20
|
-
"url": "git+https://github.com/
|
|
16
|
+
"url": "git+https://github.com/bdrakib123/rakibfca.git"
|
|
17
|
+
},
|
|
18
|
+
"author": "Rakib Hasan",
|
|
19
|
+
"contributors": [
|
|
20
|
+
"Rakib Hasan"
|
|
21
|
+
],
|
|
22
|
+
"license": "MIT",
|
|
23
|
+
"bugs": {
|
|
24
|
+
"url": "https://github.com/bdrakib123/rakibfca/issues"
|
|
21
25
|
},
|
|
26
|
+
"homepage": "https://github.com/bdrakib123/rakibfca#readme",
|
|
22
27
|
"keywords": [
|
|
23
28
|
"facebook",
|
|
24
|
-
"chat",
|
|
25
|
-
"api",
|
|
26
29
|
"messenger",
|
|
30
|
+
"chat",
|
|
27
31
|
"bot",
|
|
28
|
-
"
|
|
32
|
+
"fca",
|
|
33
|
+
"mqtt",
|
|
34
|
+
"messaging",
|
|
35
|
+
"api",
|
|
29
36
|
"automation",
|
|
30
|
-
"facebook-api",
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"fca"
|
|
37
|
+
"facebook-chat-api",
|
|
38
|
+
"rakibfca",
|
|
39
|
+
"rakib",
|
|
40
|
+
"anti-suspension",
|
|
41
|
+
"e2ee"
|
|
36
42
|
],
|
|
37
|
-
"author": {
|
|
38
|
-
"name": "DongDev",
|
|
39
|
-
"url": "https://www.facebook.com/mdong.dev"
|
|
40
|
-
},
|
|
41
|
-
"contributors": [
|
|
42
|
-
{
|
|
43
|
-
"name": "DongDev",
|
|
44
|
-
"url": "https://github.com/Donix-VN"
|
|
45
|
-
}
|
|
46
|
-
],
|
|
47
|
-
"license": "MIT",
|
|
48
|
-
"bugs": {
|
|
49
|
-
"url": "https://github.com/Donix-VN/fca-unofficial/issues"
|
|
50
|
-
},
|
|
51
|
-
"homepage": "https://github.com/Donix-VN/fca-unofficial#readme",
|
|
52
|
-
"engines": {
|
|
53
|
-
"node": ">=12.0.0"
|
|
54
|
-
},
|
|
55
43
|
"dependencies": {
|
|
56
|
-
"axios": "
|
|
57
|
-
"axios-cookiejar-support": "^
|
|
44
|
+
"axios": "^1.9.0",
|
|
45
|
+
"axios-cookiejar-support": "^4.0.7",
|
|
58
46
|
"bluebird": "^3.7.2",
|
|
59
|
-
"
|
|
60
|
-
"
|
|
47
|
+
"cheerio": "^1.0.0",
|
|
48
|
+
"deepdash": "^5.3.9",
|
|
61
49
|
"duplexify": "^4.1.3",
|
|
62
|
-
"
|
|
63
|
-
"https-proxy-agent": "^
|
|
50
|
+
"form-data": "^4.0.4",
|
|
51
|
+
"https-proxy-agent": "^7.0.6",
|
|
52
|
+
"jsonpath-plus": "^10.3.0",
|
|
53
|
+
"lodash": "^4.17.21",
|
|
64
54
|
"mqtt": "^4.3.8",
|
|
65
|
-
"
|
|
66
|
-
"
|
|
67
|
-
"
|
|
68
|
-
"
|
|
69
|
-
"
|
|
70
|
-
"
|
|
55
|
+
"node-cron": "^3.0.3",
|
|
56
|
+
"npmlog": "^7.0.1",
|
|
57
|
+
"totp-generator": "^2.0.1",
|
|
58
|
+
"tough-cookie": "^5.1.2",
|
|
59
|
+
"undici": "^7.8.0",
|
|
60
|
+
"uuid": "^11.1.0",
|
|
61
|
+
"ws": "^8.18.2"
|
|
71
62
|
},
|
|
72
63
|
"devDependencies": {
|
|
73
|
-
"
|
|
74
|
-
"
|
|
64
|
+
"@types/node": "^22.15.17",
|
|
65
|
+
"eslint": "^9.26.0",
|
|
66
|
+
"mocha": "^11.3.0",
|
|
67
|
+
"prettier": "^3.5.3",
|
|
68
|
+
"ts-node": "^10.9.2",
|
|
69
|
+
"typescript": "^5.8.3"
|
|
70
|
+
},
|
|
71
|
+
"engines": {
|
|
72
|
+
"node": ">=22.0.0"
|
|
75
73
|
},
|
|
76
|
-
"
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
"
|
|
80
|
-
"
|
|
74
|
+
"scripts": {
|
|
75
|
+
"validate": "npm pack --dry-run",
|
|
76
|
+
"prepack": "echo 'Preparing package for npm...'",
|
|
77
|
+
"test": "echo 'No tests configured yet'",
|
|
78
|
+
"lint": "eslint src/",
|
|
79
|
+
"format": "prettier --write src/**/*.js"
|
|
80
|
+
},
|
|
81
|
+
"overrides": {
|
|
82
|
+
"undici": "^7.8.0",
|
|
83
|
+
"ws": "^8.18.2",
|
|
84
|
+
"tough-cookie": "^5.1.2",
|
|
85
|
+
"glob": "^11.0.2",
|
|
86
|
+
"prebuild-install": "^7.1.3",
|
|
87
|
+
"npmlog": "^7.0.1",
|
|
88
|
+
"are-we-there-yet": "^4.0.2",
|
|
89
|
+
"gauge": "^5.0.2",
|
|
90
|
+
"serialize-javascript": "^6.0.2",
|
|
91
|
+
"cacache": "^18.0.4",
|
|
92
|
+
"make-fetch-happen": "^13.0.3",
|
|
93
|
+
"@tootallnate/once": "^3.0.1",
|
|
94
|
+
"mocha": {
|
|
95
|
+
"serialize-javascript": "^6.0.2",
|
|
96
|
+
"debug": "^4.4.0",
|
|
97
|
+
"diff": "^7.0.0",
|
|
98
|
+
"js-yaml": "^4.1.0",
|
|
99
|
+
"minimatch": "^10.0.1",
|
|
100
|
+
"glob": "^11.0.2"
|
|
101
|
+
}
|
|
81
102
|
}
|
|
82
103
|
}
|
|
@@ -1,25 +1,24 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
};
|
|
1
|
+
"use strict";
|
|
2
|
+
const utils = require('../utils');
|
|
3
|
+
|
|
4
|
+
module.exports = function (defaultFuncs, api, ctx) {
|
|
5
|
+
return function addExternalModule(moduleObj) {
|
|
6
|
+
if (utils.getType(moduleObj) == "Object") {
|
|
7
|
+
for (const apiName in moduleObj) {
|
|
8
|
+
if (utils.getType(moduleObj[apiName]) == "Function") {
|
|
9
|
+
api[apiName] = moduleObj[apiName](defaultFuncs, api, ctx);
|
|
10
|
+
} else {
|
|
11
|
+
throw new Error(
|
|
12
|
+
`Item "${apiName}" in moduleObj must be a function, not ${utils.getType(
|
|
13
|
+
moduleObj[apiName],
|
|
14
|
+
)}!`,
|
|
15
|
+
);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
} else {
|
|
19
|
+
throw new Error(
|
|
20
|
+
`moduleObj must be an object, not ${utils.getType(moduleObj)}!`,
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
};
|
|
24
|
+
};
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const utils = require('../utils');
|
|
4
|
+
|
|
5
|
+
module.exports = (defaultFuncs, api, ctx) => {
|
|
6
|
+
return async function addUserToGroup(userID, threadID, callback) {
|
|
7
|
+
let resolveFunc = () => {};
|
|
8
|
+
let rejectFunc = () => {};
|
|
9
|
+
const returnPromise = new Promise((resolve, reject) => {
|
|
10
|
+
resolveFunc = resolve;
|
|
11
|
+
rejectFunc = reject;
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
if (!callback) {
|
|
15
|
+
callback = (err, result) => {
|
|
16
|
+
if (err) return rejectFunc(err);
|
|
17
|
+
resolveFunc(result);
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
try {
|
|
22
|
+
if (!ctx.mqttClient) {
|
|
23
|
+
throw new Error("Not connected to MQTT. Please use listenMqtt first.");
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
if (utils.getType(threadID) !== "Number" && utils.getType(threadID) !== "String") {
|
|
27
|
+
throw new Error("ThreadID should be of type Number or String");
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (utils.getType(userID) !== "Array") {
|
|
31
|
+
userID = [userID];
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
const reqID = ++ctx.wsReqNumber;
|
|
35
|
+
const taskID = ++ctx.wsTaskNumber;
|
|
36
|
+
|
|
37
|
+
const payload = {
|
|
38
|
+
epoch_id: utils.generateOfflineThreadingID(),
|
|
39
|
+
tasks: [
|
|
40
|
+
{
|
|
41
|
+
failure_count: null,
|
|
42
|
+
label: "23",
|
|
43
|
+
payload: JSON.stringify({
|
|
44
|
+
thread_key: threadID,
|
|
45
|
+
contact_ids: userID,
|
|
46
|
+
sync_group: 1
|
|
47
|
+
}),
|
|
48
|
+
queue_name: threadID.toString(),
|
|
49
|
+
task_id: taskID
|
|
50
|
+
}
|
|
51
|
+
],
|
|
52
|
+
version_id: "24502707779384158"
|
|
53
|
+
};
|
|
54
|
+
|
|
55
|
+
const form = JSON.stringify({
|
|
56
|
+
app_id: "772021112871879",
|
|
57
|
+
payload: JSON.stringify(payload),
|
|
58
|
+
request_id: reqID,
|
|
59
|
+
type: 3
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
let responseHandled = false;
|
|
63
|
+
const handleRes = (topic, message) => {
|
|
64
|
+
if (topic !== "/ls_resp" || responseHandled) return;
|
|
65
|
+
let jsonMsg;
|
|
66
|
+
try {
|
|
67
|
+
jsonMsg = JSON.parse(message.toString());
|
|
68
|
+
jsonMsg.payload = JSON.parse(jsonMsg.payload);
|
|
69
|
+
} catch {
|
|
70
|
+
return;
|
|
71
|
+
}
|
|
72
|
+
if (jsonMsg.request_id !== reqID) return;
|
|
73
|
+
responseHandled = true;
|
|
74
|
+
clearTimeout(timeout);
|
|
75
|
+
ctx.mqttClient.removeListener("message", handleRes);
|
|
76
|
+
callback(null, { success: true, response: jsonMsg.payload });
|
|
77
|
+
resolveFunc({ success: true, response: jsonMsg.payload });
|
|
78
|
+
};
|
|
79
|
+
|
|
80
|
+
const timeout = setTimeout(() => {
|
|
81
|
+
if (!responseHandled) {
|
|
82
|
+
responseHandled = true;
|
|
83
|
+
ctx.mqttClient.removeListener("message", handleRes);
|
|
84
|
+
const err = new Error("MQTT request timeout");
|
|
85
|
+
callback(err);
|
|
86
|
+
rejectFunc(err);
|
|
87
|
+
}
|
|
88
|
+
}, 30000);
|
|
89
|
+
|
|
90
|
+
ctx.mqttClient.on("message", handleRes);
|
|
91
|
+
ctx.mqttClient.publish("/ls_req", form, { qos: 1, retain: false }, (err) => {
|
|
92
|
+
if (err && !responseHandled) {
|
|
93
|
+
responseHandled = true;
|
|
94
|
+
clearTimeout(timeout);
|
|
95
|
+
ctx.mqttClient.removeListener("message", handleRes);
|
|
96
|
+
callback(err);
|
|
97
|
+
rejectFunc(err);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
} catch (err) {
|
|
101
|
+
utils.error("addUserToGroup", err);
|
|
102
|
+
callback(err);
|
|
103
|
+
rejectFunc(err);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
return returnPromise;
|
|
107
|
+
};
|
|
108
|
+
};
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const utils = require('../utils');
|
|
4
|
+
|
|
5
|
+
function generateOfflineThreadingID() {
|
|
6
|
+
return Date.now().toString() + Math.floor(Math.random() * 1000000).toString();
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
function getType(obj) {
|
|
10
|
+
return Object.prototype.toString.call(obj).slice(8, -1);
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
module.exports = function (defaultFuncs, api, ctx) {
|
|
14
|
+
return function changeAdminStatus(threadID, adminID, adminStatus, callback) {
|
|
15
|
+
let resolveFunc = function() {};
|
|
16
|
+
let rejectFunc = function() {};
|
|
17
|
+
const returnPromise = new Promise(function(resolve, reject) {
|
|
18
|
+
resolveFunc = resolve;
|
|
19
|
+
rejectFunc = reject;
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
if (!callback) {
|
|
23
|
+
callback = function(err, data) {
|
|
24
|
+
if (err) return rejectFunc(err);
|
|
25
|
+
resolveFunc(data);
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (getType(threadID) !== "String") {
|
|
30
|
+
return callback({ error: "changeAdminStatus: threadID must be a string" });
|
|
31
|
+
}
|
|
32
|
+
if (getType(adminID) !== "String" && getType(adminID) !== "Array") {
|
|
33
|
+
return callback({ error: "changeAdminStatus: adminID must be a string or an array" });
|
|
34
|
+
}
|
|
35
|
+
if (getType(adminStatus) !== "Boolean") {
|
|
36
|
+
return callback({ error: "changeAdminStatus: adminStatus must be true or false" });
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (ctx.mqttClient) {
|
|
40
|
+
const tasks = [];
|
|
41
|
+
const isAdmin = adminStatus ? 1 : 0;
|
|
42
|
+
const epochID = generateOfflineThreadingID();
|
|
43
|
+
|
|
44
|
+
if (getType(adminID) === "Array") {
|
|
45
|
+
adminID.forEach((id, index) => {
|
|
46
|
+
tasks.push({
|
|
47
|
+
failure_count: null,
|
|
48
|
+
label: "25",
|
|
49
|
+
payload: JSON.stringify({
|
|
50
|
+
thread_key: threadID,
|
|
51
|
+
contact_id: id,
|
|
52
|
+
is_admin: isAdmin
|
|
53
|
+
}),
|
|
54
|
+
queue_name: "admin_status",
|
|
55
|
+
task_id: index + 1
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
} else {
|
|
59
|
+
tasks.push({
|
|
60
|
+
failure_count: null,
|
|
61
|
+
label: "25",
|
|
62
|
+
payload: JSON.stringify({
|
|
63
|
+
thread_key: threadID,
|
|
64
|
+
contact_id: adminID,
|
|
65
|
+
is_admin: isAdmin
|
|
66
|
+
}),
|
|
67
|
+
queue_name: "admin_status",
|
|
68
|
+
task_id: 1
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
let count_req = 0;
|
|
73
|
+
const form = JSON.stringify({
|
|
74
|
+
app_id: "2220391788200892",
|
|
75
|
+
payload: JSON.stringify({
|
|
76
|
+
epoch_id: epochID,
|
|
77
|
+
tasks: tasks,
|
|
78
|
+
version_id: "8798795233522156"
|
|
79
|
+
}),
|
|
80
|
+
request_id: ++count_req,
|
|
81
|
+
type: 3
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
ctx.mqttClient.publish("/ls_req", form, {}, (err, _packet) => {
|
|
85
|
+
if (err) {
|
|
86
|
+
utils.error("changeAdminStatus (MQTT)", err);
|
|
87
|
+
return callback(err);
|
|
88
|
+
} else {
|
|
89
|
+
utils.log("Admin status changed successfully via MQTT");
|
|
90
|
+
return callback(null, { success: true });
|
|
91
|
+
}
|
|
92
|
+
});
|
|
93
|
+
} else {
|
|
94
|
+
utils.warn("MQTT client not available, using HTTP fallback for changeAdminStatus");
|
|
95
|
+
const tasks = [];
|
|
96
|
+
const epochID = generateOfflineThreadingID();
|
|
97
|
+
|
|
98
|
+
if (getType(adminID) === "Array") {
|
|
99
|
+
adminID.forEach((id, index) => {
|
|
100
|
+
tasks.push({
|
|
101
|
+
label: '25',
|
|
102
|
+
payload: JSON.stringify({ thread_key: threadID, contact_id: id, is_admin: adminStatus }),
|
|
103
|
+
queue_name: 'admin_status',
|
|
104
|
+
task_id: index + 1,
|
|
105
|
+
failure_count: null
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
} else {
|
|
109
|
+
tasks.push({
|
|
110
|
+
label: '25',
|
|
111
|
+
payload: JSON.stringify({ thread_key: threadID, contact_id: adminID, is_admin: adminStatus }),
|
|
112
|
+
queue_name: 'admin_status',
|
|
113
|
+
task_id: 1,
|
|
114
|
+
failure_count: null
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
const form = {
|
|
119
|
+
fb_dtsg: ctx.fb_dtsg,
|
|
120
|
+
request_id: 1,
|
|
121
|
+
type: 3,
|
|
122
|
+
payload: {
|
|
123
|
+
version_id: '3816854585040595',
|
|
124
|
+
tasks: tasks,
|
|
125
|
+
epoch_id: epochID,
|
|
126
|
+
data_trace_id: null
|
|
127
|
+
},
|
|
128
|
+
app_id: '772021112871879'
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
form.payload = JSON.stringify(form.payload);
|
|
132
|
+
|
|
133
|
+
defaultFuncs
|
|
134
|
+
.post("https://www.facebook.com/api/graphqlbatch/", ctx.jar, form)
|
|
135
|
+
.then(utils.parseAndCheckLogin(ctx, defaultFuncs))
|
|
136
|
+
.then(() => {
|
|
137
|
+
utils.log("Admin status changed successfully via HTTP");
|
|
138
|
+
callback(null, { success: true });
|
|
139
|
+
})
|
|
140
|
+
.catch(err => {
|
|
141
|
+
utils.error("changeAdminStatus (HTTP)", err);
|
|
142
|
+
callback(err);
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
return returnPromise;
|
|
147
|
+
};
|
|
148
|
+
};
|