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.
- package/README.md +1066 -0
- package/build/messagix.dll +0 -0
- package/build/messagix.so +0 -0
- package/checkUpdate.js +393 -0
- package/config.json +17 -0
- package/e2ee.js +563 -0
- package/e2eetest.js +356 -0
- package/index.js +611 -0
- package/lib/index.mjs +1412 -0
- package/logger.js +500 -0
- package/package.json +65 -0
- package/src/GetBotInfo.js +66 -0
- package/src/OldMessage.js +182 -0
- package/src/Screenshot.js +83 -0
- package/src/addExternalModule.js +13 -0
- package/src/addUserToGroup.js +33 -0
- package/src/approveGroupJoinRequests.js +18 -0
- package/src/changeAdminStatus.js +16 -0
- package/src/changeArchivedStatus.js +17 -0
- package/src/changeAvatar.js +136 -0
- package/src/changeAvatarV2.js +86 -0
- package/src/changeAvt.js +85 -0
- package/src/changeBio.js +76 -0
- package/src/changeBlockedStatus.js +20 -0
- package/src/changeBlockedStatusMqtt.js +80 -0
- package/src/changeCover.js +72 -0
- package/src/changeGroupImage.js +16 -0
- package/src/changeName.js +79 -0
- package/src/changeNickname.js +16 -0
- package/src/changeThreadColor.js +15 -0
- package/src/changeThreadEmoji.js +15 -0
- package/src/changeThreadMemberNickname.js +6 -0
- package/src/changeUsername.js +59 -0
- package/src/createCommentPost.js +230 -0
- package/src/createNewGroup.js +38 -0
- package/src/createNote.js +35 -0
- package/src/createPoll.js +27 -0
- package/src/createPost.js +276 -0
- package/src/createThemeAI.js +129 -0
- package/src/data/cache/system/data.json +4 -0
- package/src/data/cache/system/datahandle.js +21 -0
- package/src/data/getThreadInfo.json +1 -0
- package/src/deleteComment.js +23 -0
- package/src/deleteMessage.js +15 -0
- package/src/deleteThread.js +15 -0
- package/src/denyGroupJoinRequests.js +18 -0
- package/src/e2ee/crypto.js +173 -0
- package/src/e2ee/index.js +144 -0
- package/src/e2ee/proto/ArmadilloApplication.proto +281 -0
- package/src/e2ee/proto/ArmadilloICDC.proto +14 -0
- package/src/e2ee/proto/ConsumerApplication.proto +232 -0
- package/src/e2ee/proto/MessageApplication.proto +82 -0
- package/src/e2ee/proto/MessageTransport.proto +77 -0
- package/src/e2ee/proto/WACommon.proto +66 -0
- package/src/e2ee/proto/WAMediaTransport.proto +176 -0
- package/src/e2ee/proto/proto-writer.ts +76 -0
- package/src/e2ee/protocol.js +196 -0
- package/src/e2ee/ratchet.js +219 -0
- package/src/e2ee/store.js +182 -0
- package/src/e2ee.js +8 -0
- package/src/editMessage.js +56 -0
- package/src/editMessageOld.js +67 -0
- package/src/enableReactions.js +24 -0
- package/src/follow.js +74 -0
- package/src/followUser.js +23 -0
- package/src/forwardAttachment.js +16 -0
- package/src/friendList.js +98 -0
- package/src/getAccess.js +112 -0
- package/src/getAppState.js +13 -0
- package/src/getAvatarUser.js +11 -0
- package/src/getBio.js +24 -0
- package/src/getBotInitialData.js +42 -0
- package/src/getCtx.js +5 -0
- package/src/getCurrentUserID.js +6 -0
- package/src/getEmojiUrl.js +29 -0
- package/src/getFriendsList.js +36 -0
- package/src/getMessage.js +37 -0
- package/src/getNotes.js +17 -0
- package/src/getOptions.js +5 -0
- package/src/getPinnedMessages.js +33 -0
- package/src/getPostInfo.js +17 -0
- package/src/getProfileInfo.js +17 -0
- package/src/getPublicData.js +25 -0
- package/src/getRegion.js +7 -0
- package/src/getRepInfo.js +17 -0
- package/src/getStickerPacks.js +25 -0
- package/src/getStickers.js +39 -0
- package/src/getStoryReactions.js +18 -0
- package/src/getThreadHistory.js +45 -0
- package/src/getThreadHistoryDeprecated.js +71 -0
- package/src/getThreadInfo.js +73 -0
- package/src/getThreadInfoDeprecated.js +56 -0
- package/src/getThreadList.js +76 -0
- package/src/getThreadListDeprecated.js +46 -0
- package/src/getThreadPictures.js +59 -0
- package/src/getThreadTheme.js +77 -0
- package/src/getUID.js +17 -0
- package/src/getUserID.js +17 -0
- package/src/getUserInfo.js +28 -0
- package/src/handleFriendRequest.js +21 -0
- package/src/handleMessageRequest.js +15 -0
- package/src/httpGet.js +13 -0
- package/src/httpPost.js +12 -0
- package/src/httpPostFormData.js +12 -0
- package/src/listenE2EE.js +75 -0
- package/src/listenMqtt.js +802 -0
- package/src/listenNotification.js +85 -0
- package/src/logout.js +22 -0
- package/src/markAsDelivered.js +17 -0
- package/src/markAsRead.js +14 -0
- package/src/markAsReadAll.js +15 -0
- package/src/markAsSeen.js +15 -0
- package/src/metaTheme.js +185 -0
- package/src/muteThread.js +52 -0
- package/src/note.js +228 -0
- package/src/pin.js +53 -0
- package/src/pinMessage.js +6 -0
- package/src/postComment.js +29 -0
- package/src/postFormData.js +46 -0
- package/src/reactToComment.js +31 -0
- package/src/reactToPost.js +32 -0
- package/src/refreshFb_dtsg.js +31 -0
- package/src/removeSuspiciousAccount.js +74 -0
- package/src/removeUserFromGroup.js +15 -0
- package/src/reply.js +442 -0
- package/src/resolvePhotoUrl.js +15 -0
- package/src/searchForThread.js +20 -0
- package/src/searchFriends.js +28 -0
- package/src/searchStickers.js +53 -0
- package/src/send.js +46 -0
- package/src/sendAudio.js +8 -0
- package/src/sendBroadcast.js +93 -0
- package/src/sendButtons.js +161 -0
- package/src/sendComment.js +159 -0
- package/src/sendEmoji.js +10 -0
- package/src/sendFile.js +9 -0
- package/src/sendFriendRequest.js +33 -0
- package/src/sendGif.js +24 -0
- package/src/sendImage.js +9 -0
- package/src/sendLocation.js +9 -0
- package/src/sendMessage.js +487 -0
- package/src/sendMessage1.js +309 -0
- package/src/sendMessageMqtt.js +68 -0
- package/src/sendSticker.js +8 -0
- package/src/sendTypingIndicator.js +36 -0
- package/src/sendTypingIndicatorV2.js +28 -0
- package/src/sendVideo.js +9 -0
- package/src/sessionGuard.js +130 -0
- package/src/setActiveStatus.js +16 -0
- package/src/setMessageReaction.js +61 -0
- package/src/setMessageReactionMqtt.js +62 -0
- package/src/setOptions.js +22 -0
- package/src/setPollVote.js +17 -0
- package/src/setPostReaction.js +112 -0
- package/src/setProfileGuard.js +44 -0
- package/src/setProfileLock.js +93 -0
- package/src/setStoryReaction.js +129 -0
- package/src/setStorySeen.js +99 -0
- package/src/setThreadTheme.js +17 -0
- package/src/setTitle.js +15 -0
- package/src/shareContact.js +33 -0
- package/src/shareLink.js +8 -0
- package/src/sharePost.js +31 -0
- package/src/stopListenMqtt.js +23 -0
- package/src/storyManager.js +353 -0
- package/src/suggestFriend.js +128 -0
- package/src/threadColors.js +131 -0
- package/src/unfollowUser.js +23 -0
- package/src/unfriend.js +15 -0
- package/src/unpinMessage.js +6 -0
- package/src/unsendMessage.js +14 -0
- package/src/uploadAttachment.js +58 -0
- package/src/uploadImageToImgbb.js +29 -0
- package/utils.js +2945 -0
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var utils = require('../utils');
|
|
4
|
+
//NethWs3Dev
|
|
5
|
+
var EventEmitter = require('node:events');
|
|
6
|
+
|
|
7
|
+
function format(res, globalCallback) {
|
|
8
|
+
var checkMinutes = (date_1, date_2) => {
|
|
9
|
+
let ms_1 = date_1.getTime();
|
|
10
|
+
let ms_2 = date_2.getTime();
|
|
11
|
+
return Math.ceil((ms_2 - ms_1) / (60 * 1000));
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
for (let index of res.notifications_page.edges) {
|
|
15
|
+
if (index.node.row_type !== 'NOTIFICATION') continue;
|
|
16
|
+
|
|
17
|
+
var timestamp = index.node.notif.creation_time.timestamp;
|
|
18
|
+
if (checkMinutes(new Date(timestamp * 1000), new Date()) <= 1)
|
|
19
|
+
globalCallback(null, {
|
|
20
|
+
id: res.node.notif.id,
|
|
21
|
+
noti_id: res.node.notif.notif_id,
|
|
22
|
+
body: index.node.notif.body.text,
|
|
23
|
+
url: index.node.notif.url,
|
|
24
|
+
timestamp: timestamp * 1000
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
module.exports = function (defaultFuncs, api, ctx) {
|
|
30
|
+
let globalCallback, interval;
|
|
31
|
+
|
|
32
|
+
function MessageRepeat() {
|
|
33
|
+
interval = setInterval(function () {
|
|
34
|
+
return defaultFuncs
|
|
35
|
+
.post('https://www.facebook.com/api/graphql/', ctx.jar, {
|
|
36
|
+
fb_api_req_friendly_name: 'CometNotificationsRootQuery',
|
|
37
|
+
doc_id: 6663491207045267,
|
|
38
|
+
variables: JSON.stringify({
|
|
39
|
+
count: 5,
|
|
40
|
+
environment: 'MAIN_SURFACE',
|
|
41
|
+
filter_tokens: ['Cg8CZnQPA2FsbAE='],
|
|
42
|
+
scale: 1
|
|
43
|
+
}),
|
|
44
|
+
server_timestamps: !0
|
|
45
|
+
})
|
|
46
|
+
.then(utils.parseAndCheckLogin(ctx, defaultFuncs))
|
|
47
|
+
.then(function (res) {
|
|
48
|
+
if (res.error || res.errors)
|
|
49
|
+
throw res;
|
|
50
|
+
|
|
51
|
+
return format(res.data.viewer, globalCallback);
|
|
52
|
+
})
|
|
53
|
+
.catch(function (err) {
|
|
54
|
+
utils.error('listenNotification', err);
|
|
55
|
+
clearInterval(interval);
|
|
56
|
+
interval = void 0;
|
|
57
|
+
return globalCallback(err);
|
|
58
|
+
});
|
|
59
|
+
}, 60 * 1000);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
return function notification(callback) {
|
|
63
|
+
class MessageEmitter extends EventEmitter {
|
|
64
|
+
stop() {
|
|
65
|
+
globalCallback = () => {}
|
|
66
|
+
|
|
67
|
+
if (interval) {
|
|
68
|
+
clearInterval(interval);
|
|
69
|
+
interval = void 0;
|
|
70
|
+
}
|
|
71
|
+
Message.emit('stop', new Date());
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
var Message = new MessageEmitter();
|
|
76
|
+
|
|
77
|
+
if (typeof callback == 'function')
|
|
78
|
+
globalCallback = callback;
|
|
79
|
+
else
|
|
80
|
+
globalCallback = (error, message) => error ? Message.emit('error', error) : Message.emit('message', message);
|
|
81
|
+
|
|
82
|
+
MessageRepeat();
|
|
83
|
+
return Message;
|
|
84
|
+
}
|
|
85
|
+
}
|
package/src/logout.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var utils = require("../utils");
|
|
3
|
+
var logger = require("../logger");
|
|
4
|
+
module.exports = function (defaultFuncs, api, ctx) {
|
|
5
|
+
return function logout(callback) {
|
|
6
|
+
var { promise, callback: cb } = utils.wrapCallback(callback);
|
|
7
|
+
if (api.stopListening) {
|
|
8
|
+
try { api.stopListening(); } catch (_) { }
|
|
9
|
+
}
|
|
10
|
+
defaultFuncs.post("https://www.facebook.com/logout.php", ctx.jar, {
|
|
11
|
+
ref: "mb",
|
|
12
|
+
h: ctx.fb_dtsg || ""
|
|
13
|
+
})
|
|
14
|
+
.then(() => {
|
|
15
|
+
ctx.loggedIn = false;
|
|
16
|
+
logger.info("SHADOWX", "Logged out successfully.");
|
|
17
|
+
cb(null, true);
|
|
18
|
+
})
|
|
19
|
+
.catch(err => cb(err));
|
|
20
|
+
return promise;
|
|
21
|
+
};
|
|
22
|
+
};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var utils = require("../utils");
|
|
3
|
+
module.exports = function (defaultFuncs, api, ctx) {
|
|
4
|
+
return function markAsDelivered(threadID, messageID, callback) {
|
|
5
|
+
var { promise, callback: cb } = utils.wrapCallback(callback);
|
|
6
|
+
var form = {
|
|
7
|
+
"message_ids[0]": messageID,
|
|
8
|
+
"status": 1,
|
|
9
|
+
"thread_fbid": threadID
|
|
10
|
+
};
|
|
11
|
+
defaultFuncs.post("https://www.facebook.com/ajax/mercury/delivery_receipts.php", ctx.jar, form)
|
|
12
|
+
.then(utils.parseAndCheckLogin(ctx, defaultFuncs))
|
|
13
|
+
.then(resData => { if (resData.error) throw resData; cb(null, true); })
|
|
14
|
+
.catch(err => cb(err));
|
|
15
|
+
return promise;
|
|
16
|
+
};
|
|
17
|
+
};
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var utils = require("../utils");
|
|
3
|
+
module.exports = function (defaultFuncs, api, ctx) {
|
|
4
|
+
return function markAsRead(threadID, callback) {
|
|
5
|
+
var { promise, callback: cb } = utils.wrapCallback(callback);
|
|
6
|
+
var form = { ids: {} };
|
|
7
|
+
form.ids[threadID] = true;
|
|
8
|
+
defaultFuncs.post("https://www.facebook.com/ajax/mercury/change_read_status.php", ctx.jar, form)
|
|
9
|
+
.then(utils.parseAndCheckLogin(ctx, defaultFuncs))
|
|
10
|
+
.then(resData => { if (resData.error) throw resData; cb(null, true); })
|
|
11
|
+
.catch(err => cb(err));
|
|
12
|
+
return promise;
|
|
13
|
+
};
|
|
14
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var utils = require("../utils");
|
|
3
|
+
module.exports = function (defaultFuncs, api, ctx) {
|
|
4
|
+
return function markAsReadAll(callback) {
|
|
5
|
+
var { promise, callback: cb } = utils.wrapCallback(callback);
|
|
6
|
+
defaultFuncs.post("https://www.facebook.com/ajax/mercury/mark_folder_as_read.php", ctx.jar, {
|
|
7
|
+
folder: "inbox",
|
|
8
|
+
__user: ctx.userID
|
|
9
|
+
})
|
|
10
|
+
.then(utils.parseAndCheckLogin(ctx, defaultFuncs))
|
|
11
|
+
.then(resData => { if (resData.error) throw resData; cb(null, true); })
|
|
12
|
+
.catch(err => cb(err));
|
|
13
|
+
return promise;
|
|
14
|
+
};
|
|
15
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var utils = require("../utils");
|
|
3
|
+
module.exports = function (defaultFuncs, api, ctx) {
|
|
4
|
+
return function markAsSeen(seen_timestamp, callback) {
|
|
5
|
+
var { promise, callback: cb } = utils.wrapCallback(callback);
|
|
6
|
+
seen_timestamp = seen_timestamp || Date.now();
|
|
7
|
+
defaultFuncs.post("https://www.facebook.com/ajax/mercury/mark_seen.php", ctx.jar, {
|
|
8
|
+
seen_timestamp: seen_timestamp
|
|
9
|
+
})
|
|
10
|
+
.then(utils.parseAndCheckLogin(ctx, defaultFuncs))
|
|
11
|
+
.then(resData => { if (resData.error) throw resData; cb(null, true); })
|
|
12
|
+
.catch(err => cb(err));
|
|
13
|
+
return promise;
|
|
14
|
+
};
|
|
15
|
+
};
|
package/src/metaTheme.js
ADDED
|
@@ -0,0 +1,185 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ===========================================================
|
|
3
|
+
* 💫 META THEME GENERATOR MODULE 💫
|
|
4
|
+
* ===========================================================
|
|
5
|
+
* 🔰 Owner & Developer
|
|
6
|
+
* 🧠 Description:
|
|
7
|
+
* This module generates beautiful Messenger AI themes
|
|
8
|
+
* using Meta's hidden GraphQL endpoints. It allows you to
|
|
9
|
+
* create unique chat themes based on your custom prompt
|
|
10
|
+
* or optional image inspiration.
|
|
11
|
+
* -----------------------------------------------------------
|
|
12
|
+
* ⚙️ Features:
|
|
13
|
+
* • Generate AI-based Messenger chat themes.
|
|
14
|
+
* • Custom prompt & optional image URL input.
|
|
15
|
+
* • Returns structured theme data with full color mapping.
|
|
16
|
+
* -----------------------------------------------------------
|
|
17
|
+
* 🕊️ Respect the creator & give proper credits if reused.
|
|
18
|
+
* ===========================================================
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
"use strict";
|
|
22
|
+
|
|
23
|
+
const utils = require("../utils");
|
|
24
|
+
const log = require("npmlog");
|
|
25
|
+
module.exports = function (defaultFuncs, api, ctx) {
|
|
26
|
+
return function metaTheme(prompt, options, callback) {
|
|
27
|
+
var resolveFunc = function () { };
|
|
28
|
+
var rejectFunc = function () { };
|
|
29
|
+
var returnPromise = new Promise(function (resolve, reject) {
|
|
30
|
+
resolveFunc = resolve;
|
|
31
|
+
rejectFunc = reject;
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
// Handle optional parameters
|
|
35
|
+
if (typeof options === 'function') {
|
|
36
|
+
callback = options;
|
|
37
|
+
options = {};
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
if (!callback) {
|
|
41
|
+
callback = function (err, data) {
|
|
42
|
+
if (err) return rejectFunc(err);
|
|
43
|
+
resolveFunc(data);
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
if (!prompt || typeof prompt !== 'string') {
|
|
48
|
+
return callback({ error: "Prompt is required and must be a string" });
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
// Parse options
|
|
52
|
+
const numThemes = options.numThemes || 1;
|
|
53
|
+
const imageUrl = options.imageUrl || null;
|
|
54
|
+
|
|
55
|
+
const inputData = {
|
|
56
|
+
client_mutation_id: Math.floor(Math.random() * 10).toString(),
|
|
57
|
+
actor_id: ctx.userID,
|
|
58
|
+
bypass_cache: true,
|
|
59
|
+
caller: "MESSENGER",
|
|
60
|
+
num_themes: Math.min(numThemes, 5), // Limit to max 5 themes
|
|
61
|
+
prompt: prompt
|
|
62
|
+
};
|
|
63
|
+
|
|
64
|
+
// Add image URL if provided
|
|
65
|
+
if (imageUrl) {
|
|
66
|
+
inputData.image_url = imageUrl;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const form = {
|
|
70
|
+
av: ctx.userID,
|
|
71
|
+
__aaid: 0,
|
|
72
|
+
__user: ctx.userID,
|
|
73
|
+
__a: 1,
|
|
74
|
+
__req: utils.getSignatureID(),
|
|
75
|
+
__hs: "20358.HYP:comet_pkg.2.1...0",
|
|
76
|
+
dpr: 1,
|
|
77
|
+
__ccg: "EXCELLENT",
|
|
78
|
+
__rev: "1027673511",
|
|
79
|
+
__s: utils.getSignatureID(),
|
|
80
|
+
__hsi: "7554561631547849479",
|
|
81
|
+
__comet_req: 15,
|
|
82
|
+
fb_dtsg: ctx.fb_dtsg,
|
|
83
|
+
jazoest: ctx.ttstamp,
|
|
84
|
+
lsd: ctx.fb_dtsg,
|
|
85
|
+
__spin_r: "1027673511",
|
|
86
|
+
__spin_b: "trunk",
|
|
87
|
+
__spin_t: Date.now(),
|
|
88
|
+
__crn: "comet.fbweb.MWInboxHomeRoute",
|
|
89
|
+
qpl_active_flow_ids: "25309433,521485406",
|
|
90
|
+
fb_api_caller_class: "RelayModern",
|
|
91
|
+
fb_api_req_friendly_name: "useGenerateAIThemeMutation",
|
|
92
|
+
variables: JSON.stringify({ input: inputData }),
|
|
93
|
+
server_timestamps: true,
|
|
94
|
+
doc_id: "23873748445608673",
|
|
95
|
+
fb_api_analytics_tags: JSON.stringify(["qpl_active_flow_ids=25309433,521485406"])
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
defaultFuncs
|
|
99
|
+
.post("https://www.facebook.com/api/graphql/", ctx.jar, form)
|
|
100
|
+
.then(utils.parseAndCheckLogin(ctx, defaultFuncs))
|
|
101
|
+
.then(function (resData) {
|
|
102
|
+
if (resData.errors) {
|
|
103
|
+
throw resData.errors;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (resData.data && resData.data.xfb_generate_ai_themes_from_prompt) {
|
|
107
|
+
const themeData = resData.data.xfb_generate_ai_themes_from_prompt;
|
|
108
|
+
if (themeData.success && themeData.themes && themeData.themes.length > 0) {
|
|
109
|
+
const themes = themeData.themes.map((theme, index) => ({
|
|
110
|
+
success: true,
|
|
111
|
+
themeId: theme.id,
|
|
112
|
+
name: theme.accessibility_label,
|
|
113
|
+
description: theme.description,
|
|
114
|
+
serialNumber: index + 1,
|
|
115
|
+
colors: {
|
|
116
|
+
composerBackground: theme.composer_background_color,
|
|
117
|
+
backgroundGradient: theme.background_gradient_colors,
|
|
118
|
+
titleBarButton: theme.title_bar_button_tint_color,
|
|
119
|
+
inboundMessageGradient: theme.inbound_message_gradient_colors,
|
|
120
|
+
titleBarText: theme.title_bar_text_color,
|
|
121
|
+
composerTint: theme.composer_tint_color,
|
|
122
|
+
messageText: theme.message_text_color,
|
|
123
|
+
primaryButton: theme.primary_button_background_color,
|
|
124
|
+
titleBarBackground: theme.title_bar_background_color,
|
|
125
|
+
fallback: theme.fallback_color,
|
|
126
|
+
gradient: theme.gradient_colors
|
|
127
|
+
},
|
|
128
|
+
backgroundImage: theme.background_asset ? theme.background_asset.image.uri : null,
|
|
129
|
+
iconImage: theme.icon_asset ? theme.icon_asset.image.uri : null,
|
|
130
|
+
images: {
|
|
131
|
+
background: theme.background_asset ? theme.background_asset.image.uri : null,
|
|
132
|
+
icon: theme.icon_asset ? theme.icon_asset.image.uri : null
|
|
133
|
+
},
|
|
134
|
+
alternativeThemes: theme.alternative_themes ? theme.alternative_themes.map(alt => ({
|
|
135
|
+
id: alt.id,
|
|
136
|
+
name: alt.accessibility_label,
|
|
137
|
+
backgroundImage: alt.background_asset ? alt.background_asset.image.uri : null,
|
|
138
|
+
iconImage: alt.icon_asset ? alt.icon_asset.image.uri : null
|
|
139
|
+
})) : []
|
|
140
|
+
}));
|
|
141
|
+
|
|
142
|
+
const result = {
|
|
143
|
+
success: true,
|
|
144
|
+
count: themes.length,
|
|
145
|
+
themes: themes,
|
|
146
|
+
// For backward compatibility, include first theme data at root level
|
|
147
|
+
...themes[0]
|
|
148
|
+
};
|
|
149
|
+
return callback(null, result);
|
|
150
|
+
} else {
|
|
151
|
+
throw new Error("No themes generated for the given prompt");
|
|
152
|
+
}
|
|
153
|
+
} else {
|
|
154
|
+
throw new Error("Invalid response from AI theme generation");
|
|
155
|
+
}
|
|
156
|
+
})
|
|
157
|
+
.catch(function (err) {
|
|
158
|
+
log.error("metaTheme", err);
|
|
159
|
+
|
|
160
|
+
// Check for specific error conditions
|
|
161
|
+
let errorMessage = "An error occurred while generating themes";
|
|
162
|
+
|
|
163
|
+
if (err.message && err.message.includes("not authorized")) {
|
|
164
|
+
errorMessage = "Your account is not authorized to generate AI themes. This feature may not be available for your account type.";
|
|
165
|
+
} else if (err.message && err.message.includes("rate limit")) {
|
|
166
|
+
errorMessage = "Rate limit exceeded. Please wait a moment before trying again.";
|
|
167
|
+
} else if (err.message && err.message.includes("Invalid")) {
|
|
168
|
+
errorMessage = "Invalid request parameters. Please check your input.";
|
|
169
|
+
} else if (err.statusCode === 403) {
|
|
170
|
+
errorMessage = "Access denied. Your account may not support Meta AI theme generation.";
|
|
171
|
+
} else if (err.statusCode === 429) {
|
|
172
|
+
errorMessage = "Too many requests. Please wait before trying again.";
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return callback({
|
|
176
|
+
error: errorMessage,
|
|
177
|
+
originalError: err.message || err,
|
|
178
|
+
statusCode: err.statusCode || null
|
|
179
|
+
});
|
|
180
|
+
});
|
|
181
|
+
|
|
182
|
+
return returnPromise;
|
|
183
|
+
};
|
|
184
|
+
};
|
|
185
|
+
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var utils = require("../utils");
|
|
3
|
+
module.exports = function (defaultFuncs, api, ctx) {
|
|
4
|
+
return function muteThread(threadID, muteSeconds, callback) {
|
|
5
|
+
var { promise, callback: cb } = utils.wrapCallback(callback);
|
|
6
|
+
var mqttClient = ctx.mqttClient || global.mqttClient;
|
|
7
|
+
|
|
8
|
+
if (mqttClient) {
|
|
9
|
+
ctx.wsReqNumber = (ctx.wsReqNumber || 0) + 1;
|
|
10
|
+
ctx.wsTaskNumber = (ctx.wsTaskNumber || 0) + 1;
|
|
11
|
+
var muteExpireTime = muteSeconds === 0
|
|
12
|
+
? 0
|
|
13
|
+
: muteSeconds === -1
|
|
14
|
+
? -1
|
|
15
|
+
: Math.floor(Date.now() / 1000) + muteSeconds;
|
|
16
|
+
var payload = {
|
|
17
|
+
thread_key: String(threadID),
|
|
18
|
+
mute_expire_time_ms: muteExpireTime === -1 ? -1 : muteExpireTime * 1000,
|
|
19
|
+
sync_group: 1
|
|
20
|
+
};
|
|
21
|
+
var content = {
|
|
22
|
+
app_id: '2220391788200892',
|
|
23
|
+
payload: JSON.stringify({
|
|
24
|
+
data_trace_id: null,
|
|
25
|
+
epoch_id: parseInt(utils.generateOfflineThreadingID()),
|
|
26
|
+
tasks: [{
|
|
27
|
+
failure_count: null,
|
|
28
|
+
label: '52',
|
|
29
|
+
payload: JSON.stringify(payload),
|
|
30
|
+
queue_name: String(threadID),
|
|
31
|
+
task_id: ctx.wsTaskNumber
|
|
32
|
+
}],
|
|
33
|
+
version_id: '7158486590867448'
|
|
34
|
+
}),
|
|
35
|
+
request_id: ctx.wsReqNumber,
|
|
36
|
+
type: 3
|
|
37
|
+
};
|
|
38
|
+
mqttClient.publish('/ls_req', JSON.stringify(content), { qos: 1, retain: false });
|
|
39
|
+
cb(null, true);
|
|
40
|
+
return promise;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
defaultFuncs.post("https://www.facebook.com/ajax/mercury/change_mute_thread.php", ctx.jar, {
|
|
44
|
+
thread_fbid: threadID,
|
|
45
|
+
mute_settings: typeof muteSeconds === "number" ? muteSeconds : -1
|
|
46
|
+
})
|
|
47
|
+
.then(utils.parseAndCheckLogin(ctx, defaultFuncs))
|
|
48
|
+
.then(resData => { if (resData && resData.error) throw resData; cb(null, true); })
|
|
49
|
+
.catch(err => cb(err));
|
|
50
|
+
return promise;
|
|
51
|
+
};
|
|
52
|
+
};
|
package/src/note.js
ADDED
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
|
|
2
|
+
"use strict";
|
|
3
|
+
|
|
4
|
+
const utils = require('../utils');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @description Enhanced module for interacting with Facebook Messenger Notes with additional features
|
|
8
|
+
* @param {Object} defaultFuncs The default functions provided by the API wrapper
|
|
9
|
+
* @param {Object} api The full API object
|
|
10
|
+
* @param {Object} ctx The context object containing the user's session state
|
|
11
|
+
* @returns {Object} An object containing enhanced methods for note management
|
|
12
|
+
*/
|
|
13
|
+
module.exports = function(defaultFuncs, api, ctx) {
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @callback notesCallback
|
|
17
|
+
* @param {Error|null} error An error object if the request fails, otherwise null
|
|
18
|
+
* @param {Object} [data] The data returned from the API
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Enhanced check note function with additional user info
|
|
23
|
+
*/
|
|
24
|
+
function checkNoteAdvanced(callback) {
|
|
25
|
+
if (typeof callback !== 'function') {
|
|
26
|
+
callback = () => {};
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const form = {
|
|
30
|
+
fb_api_caller_class: "RelayModern",
|
|
31
|
+
fb_api_req_friendly_name: "MWInboxTrayNoteCreationDialogQuery",
|
|
32
|
+
variables: JSON.stringify({ scale: 2 }),
|
|
33
|
+
doc_id: "30899655739648624",
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
defaultFuncs
|
|
37
|
+
.post("https://www.facebook.com/api/graphql/", ctx.jar, form)
|
|
38
|
+
.then(utils.parseAndCheckLogin(ctx, defaultFuncs))
|
|
39
|
+
.then(resData => {
|
|
40
|
+
if (resData && resData.errors) throw resData.errors[0];
|
|
41
|
+
const currentNote = resData?.data?.viewer?.actor?.msgr_user_rich_status;
|
|
42
|
+
|
|
43
|
+
// Enhanced response with additional metadata
|
|
44
|
+
const enhancedResponse = {
|
|
45
|
+
note: currentNote,
|
|
46
|
+
hasActiveNote: !!currentNote,
|
|
47
|
+
userId: ctx.userID,
|
|
48
|
+
timestamp: Date.now(),
|
|
49
|
+
expiresAt: currentNote ? (currentNote.created_time * 1000) + (24 * 60 * 60 * 1000) : null
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
callback(null, enhancedResponse);
|
|
53
|
+
})
|
|
54
|
+
.catch(err => {
|
|
55
|
+
utils.error && utils.error("notesv2.checkNoteAdvanced", err);
|
|
56
|
+
callback(err);
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Create note with enhanced privacy options and validation
|
|
62
|
+
*/
|
|
63
|
+
function createNoteAdvanced(text, options = {}, callback) {
|
|
64
|
+
if (typeof options === 'function') {
|
|
65
|
+
callback = options;
|
|
66
|
+
options = {};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (typeof callback !== 'function') {
|
|
70
|
+
callback = () => {};
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
// Validate input
|
|
74
|
+
if (!text || text.trim().length === 0) {
|
|
75
|
+
return callback(new Error("Note text cannot be empty"));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
if (text.length > 280) {
|
|
79
|
+
return callback(new Error("Note text cannot exceed 280 characters"));
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const {
|
|
83
|
+
privacy = "FRIENDS",
|
|
84
|
+
duration = 86400,
|
|
85
|
+
noteType = "TEXT_NOTE"
|
|
86
|
+
} = options;
|
|
87
|
+
|
|
88
|
+
const variables = {
|
|
89
|
+
input: {
|
|
90
|
+
client_mutation_id: Math.round(Math.random() * 1000000).toString(),
|
|
91
|
+
actor_id: ctx.userID,
|
|
92
|
+
description: text.trim(),
|
|
93
|
+
duration: duration,
|
|
94
|
+
note_type: noteType,
|
|
95
|
+
privacy: privacy,
|
|
96
|
+
session_id: utils.getGUID(),
|
|
97
|
+
},
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
const form = {
|
|
101
|
+
fb_api_caller_class: "RelayModern",
|
|
102
|
+
fb_api_req_friendly_name: "MWInboxTrayNoteCreationDialogCreationStepContentMutation",
|
|
103
|
+
variables: JSON.stringify(variables),
|
|
104
|
+
doc_id: "24060573783603122",
|
|
105
|
+
};
|
|
106
|
+
|
|
107
|
+
defaultFuncs
|
|
108
|
+
.post("https://www.facebook.com/api/graphql/", ctx.jar, form)
|
|
109
|
+
.then(utils.parseAndCheckLogin(ctx, defaultFuncs))
|
|
110
|
+
.then(resData => {
|
|
111
|
+
if (resData && resData.errors) throw resData.errors[0];
|
|
112
|
+
const status = resData?.data?.xfb_rich_status_create?.status;
|
|
113
|
+
if (!status) throw new Error("Could not find note status in the server response.");
|
|
114
|
+
|
|
115
|
+
// Enhanced response
|
|
116
|
+
const enhancedResponse = {
|
|
117
|
+
...status,
|
|
118
|
+
createdAt: Date.now(),
|
|
119
|
+
expiresAt: Date.now() + (duration * 1000),
|
|
120
|
+
characterCount: text.trim().length,
|
|
121
|
+
privacy: privacy
|
|
122
|
+
};
|
|
123
|
+
|
|
124
|
+
callback(null, enhancedResponse);
|
|
125
|
+
})
|
|
126
|
+
.catch(err => {
|
|
127
|
+
utils.error && utils.error("notesv2.createNoteAdvanced", err);
|
|
128
|
+
callback(err);
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* Delete note with confirmation
|
|
134
|
+
*/
|
|
135
|
+
function deleteNoteAdvanced(noteID, callback) {
|
|
136
|
+
if (typeof callback !== 'function') {
|
|
137
|
+
callback = () => {};
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
if (!noteID) {
|
|
141
|
+
return callback(new Error("Note ID is required"));
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
const variables = {
|
|
145
|
+
input: {
|
|
146
|
+
client_mutation_id: Math.round(Math.random() * 1000000).toString(),
|
|
147
|
+
actor_id: ctx.userID,
|
|
148
|
+
rich_status_id: noteID,
|
|
149
|
+
},
|
|
150
|
+
};
|
|
151
|
+
|
|
152
|
+
const form = {
|
|
153
|
+
fb_api_caller_class: "RelayModern",
|
|
154
|
+
fb_api_req_friendly_name: "useMWInboxTrayDeleteNoteMutation",
|
|
155
|
+
variables: JSON.stringify(variables),
|
|
156
|
+
doc_id: "9532619970198958",
|
|
157
|
+
};
|
|
158
|
+
|
|
159
|
+
defaultFuncs
|
|
160
|
+
.post("https://www.facebook.com/api/graphql/", ctx.jar, form)
|
|
161
|
+
.then(utils.parseAndCheckLogin(ctx, defaultFuncs))
|
|
162
|
+
.then(resData => {
|
|
163
|
+
if (resData && resData.errors) throw resData.errors[0];
|
|
164
|
+
const deletedStatus = resData?.data?.xfb_rich_status_delete;
|
|
165
|
+
if (!deletedStatus) throw new Error("Could not find deletion status in the server response.");
|
|
166
|
+
|
|
167
|
+
const enhancedResponse = {
|
|
168
|
+
...deletedStatus,
|
|
169
|
+
deletedAt: Date.now(),
|
|
170
|
+
noteId: noteID
|
|
171
|
+
};
|
|
172
|
+
|
|
173
|
+
callback(null, enhancedResponse);
|
|
174
|
+
})
|
|
175
|
+
.catch(err => {
|
|
176
|
+
utils.error && utils.error("notesv2.deleteNoteAdvanced", err);
|
|
177
|
+
callback(err);
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Update existing note (delete old and create new)
|
|
183
|
+
*/
|
|
184
|
+
function updateNote(oldNoteID, newText, options = {}, callback) {
|
|
185
|
+
if (typeof options === 'function') {
|
|
186
|
+
callback = options;
|
|
187
|
+
options = {};
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
if (typeof callback !== 'function') {
|
|
191
|
+
callback = () => {};
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
deleteNoteAdvanced(oldNoteID, (err, deleted) => {
|
|
195
|
+
if (err) {
|
|
196
|
+
return callback(err);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
// Wait a bit before creating new note
|
|
200
|
+
setTimeout(() => {
|
|
201
|
+
createNoteAdvanced(newText, options, (err, created) => {
|
|
202
|
+
if (err) {
|
|
203
|
+
return callback(err);
|
|
204
|
+
}
|
|
205
|
+
callback(null, {
|
|
206
|
+
deleted,
|
|
207
|
+
created,
|
|
208
|
+
updatedAt: Date.now()
|
|
209
|
+
});
|
|
210
|
+
});
|
|
211
|
+
}, 1000);
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
return {
|
|
216
|
+
// Enhanced functions
|
|
217
|
+
checkAdvanced: checkNoteAdvanced,
|
|
218
|
+
createAdvanced: createNoteAdvanced,
|
|
219
|
+
deleteAdvanced: deleteNoteAdvanced,
|
|
220
|
+
update: updateNote,
|
|
221
|
+
|
|
222
|
+
// Backward compatibility
|
|
223
|
+
check: checkNoteAdvanced,
|
|
224
|
+
create: createNoteAdvanced,
|
|
225
|
+
delete: deleteNoteAdvanced,
|
|
226
|
+
recreate: updateNote
|
|
227
|
+
};
|
|
228
|
+
};
|
package/src/pin.js
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var utils = require("../utils");
|
|
4
|
+
|
|
5
|
+
module.exports = function (defaultFuncs, api, ctx) {
|
|
6
|
+
return function pin(action, threadID, messageID, callback) {
|
|
7
|
+
var { promise, callback: cb } = utils.wrapCallback(callback);
|
|
8
|
+
|
|
9
|
+
var mqttClient = ctx.mqttClient || global.mqttClient;
|
|
10
|
+
if (!mqttClient) {
|
|
11
|
+
cb({ error: "MQTT not connected. Call api.listen() first." });
|
|
12
|
+
return promise;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
ctx.wsReqNumber = (ctx.wsReqNumber || 0) + 1;
|
|
16
|
+
ctx.wsTaskNumber = (ctx.wsTaskNumber || 0) + 1;
|
|
17
|
+
|
|
18
|
+
var isPinning = action === "pin" || action === true || action === 1;
|
|
19
|
+
|
|
20
|
+
var taskPayload = {
|
|
21
|
+
thread_key: String(threadID),
|
|
22
|
+
message_id: String(messageID),
|
|
23
|
+
timestamp_ms: Date.now(),
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
var envelope = {
|
|
27
|
+
app_id: "2220391788200892",
|
|
28
|
+
payload: JSON.stringify({
|
|
29
|
+
data_trace_id: null,
|
|
30
|
+
epoch_id: parseInt(utils.generateOfflineThreadingID()),
|
|
31
|
+
tasks: [{
|
|
32
|
+
failure_count: null,
|
|
33
|
+
label: isPinning ? "430" : "431",
|
|
34
|
+
payload: JSON.stringify(taskPayload),
|
|
35
|
+
queue_name: (isPinning ? "pin_msg_v2_" : "unpin_msg_v2_") + String(threadID),
|
|
36
|
+
task_id: ctx.wsTaskNumber,
|
|
37
|
+
}],
|
|
38
|
+
version_id: "25095469420099952",
|
|
39
|
+
}),
|
|
40
|
+
request_id: ctx.wsReqNumber,
|
|
41
|
+
type: 3,
|
|
42
|
+
};
|
|
43
|
+
|
|
44
|
+
try {
|
|
45
|
+
mqttClient.publish("/ls_req", JSON.stringify(envelope), { qos: 1 });
|
|
46
|
+
cb(null, true);
|
|
47
|
+
} catch (e) {
|
|
48
|
+
cb(e);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
return promise;
|
|
52
|
+
};
|
|
53
|
+
};
|