stfca 1.0.18 → 1.0.20
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/package.json +1 -1
- package/src/setThreadTheme.js +88 -261
- package/src/suggestFriend.js +133 -0
package/package.json
CHANGED
package/src/setThreadTheme.js
CHANGED
|
@@ -8,269 +8,96 @@
|
|
|
8
8
|
* 🕊️ Respect the creator & give proper credits if reused.
|
|
9
9
|
* ===========================================================
|
|
10
10
|
*/
|
|
11
|
-
|
|
11
|
+
'use strict';
|
|
12
12
|
|
|
13
|
-
|
|
14
|
-
|
|
13
|
+
const utils = require('../utils');
|
|
14
|
+
const log = require('npmlog');
|
|
15
15
|
|
|
16
16
|
module.exports = function (defaultFuncs, api, ctx) {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
.then(utils.parseAndCheckLogin(ctx, defaultFuncs));
|
|
103
|
-
|
|
104
|
-
if (themeResult && themeResult.data && themeResult.data.messenger_thread_themes) {
|
|
105
|
-
availableThemes = themeResult.data.messenger_thread_themes;
|
|
106
|
-
}
|
|
107
|
-
} catch (e) {
|
|
108
|
-
log.warn("setThreadTheme", "Could not fetch available themes, proceeding with theme update");
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
// Step 3: Determine theme ID based on input
|
|
112
|
-
let themeId = null;
|
|
113
|
-
let customEmoji = "👍";
|
|
114
|
-
|
|
115
|
-
if (typeof themeData === "string") {
|
|
116
|
-
// If it's a string, try to find matching theme
|
|
117
|
-
if (themeData.match(/^[0-9]+$/)) {
|
|
118
|
-
// Numeric theme ID
|
|
119
|
-
themeId = themeData;
|
|
120
|
-
} else {
|
|
121
|
-
// Search by theme name/description
|
|
122
|
-
const foundTheme = availableThemes.find(theme =>
|
|
123
|
-
theme.accessibility_label &&
|
|
124
|
-
theme.accessibility_label.toLowerCase().includes(themeData.toLowerCase())
|
|
125
|
-
);
|
|
126
|
-
if (foundTheme) {
|
|
127
|
-
themeId = foundTheme.id;
|
|
128
|
-
} else {
|
|
129
|
-
// Fallback color mapping
|
|
130
|
-
const colorMap = {
|
|
131
|
-
blue: "196241301102133",
|
|
132
|
-
purple: "370940413392601",
|
|
133
|
-
green: "169463077092846",
|
|
134
|
-
pink: "230032715012014",
|
|
135
|
-
orange: "175615189761153",
|
|
136
|
-
red: "2136751179887052",
|
|
137
|
-
yellow: "2058653964378557",
|
|
138
|
-
teal: "417639218648241",
|
|
139
|
-
black: "539927563794799",
|
|
140
|
-
white: "2873642392710980",
|
|
141
|
-
default: "196241301102133"
|
|
142
|
-
};
|
|
143
|
-
themeId = colorMap[themeData.toLowerCase()] || colorMap.default;
|
|
144
|
-
}
|
|
145
|
-
}
|
|
146
|
-
} else if (typeof themeData === "object" && themeData !== null) {
|
|
147
|
-
themeId = themeData.themeId || themeData.theme_id || themeData.id;
|
|
148
|
-
customEmoji = themeData.emoji || themeData.customEmoji || "👍";
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
if (!themeId) {
|
|
152
|
-
themeId = "196241301102133"; // Default blue theme
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
// Step 4: Use direct bootloader approach for theme update
|
|
156
|
-
try {
|
|
157
|
-
// First try with the legacy changeThreadColor approach
|
|
158
|
-
const legacyForm = {
|
|
159
|
-
dpr: 1,
|
|
160
|
-
queries: JSON.stringify({
|
|
161
|
-
o0: {
|
|
162
|
-
doc_id: "1727493033983591",
|
|
163
|
-
query_params: {
|
|
164
|
-
data: {
|
|
165
|
-
actor_id: ctx.userID,
|
|
166
|
-
client_mutation_id: "0",
|
|
167
|
-
source: "SETTINGS",
|
|
168
|
-
theme_id: themeId,
|
|
169
|
-
thread_id: threadID,
|
|
170
|
-
},
|
|
171
|
-
},
|
|
172
|
-
},
|
|
173
|
-
}),
|
|
174
|
-
};
|
|
175
|
-
|
|
176
|
-
const legacyResult = await defaultFuncs
|
|
177
|
-
.post("https://www.facebook.com/api/graphqlbatch/", ctx.jar, legacyForm)
|
|
178
|
-
.then(utils.parseAndCheckLogin(ctx, defaultFuncs));
|
|
179
|
-
|
|
180
|
-
if (legacyResult && !legacyResult[0]?.o0?.errors) {
|
|
181
|
-
return callback(null, {
|
|
182
|
-
threadID: threadID,
|
|
183
|
-
themeId: themeId,
|
|
184
|
-
customEmoji: customEmoji,
|
|
185
|
-
timestamp: timestamp,
|
|
186
|
-
success: true,
|
|
187
|
-
method: "legacy",
|
|
188
|
-
availableThemes: availableThemes.length > 0 ? availableThemes.map(t => ({
|
|
189
|
-
id: t.id,
|
|
190
|
-
name: t.accessibility_label,
|
|
191
|
-
description: t.description
|
|
192
|
-
})) : null
|
|
193
|
-
});
|
|
194
|
-
}
|
|
195
|
-
} catch (legacyErr) {
|
|
196
|
-
log.warn("setThreadTheme", "Legacy method failed, trying alternative approach");
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
// Step 5: Try alternative GraphQL mutation with updated doc_id
|
|
200
|
-
const alternativeForm = {
|
|
201
|
-
av: ctx.userID,
|
|
202
|
-
__aaid: 0,
|
|
203
|
-
__user: ctx.userID,
|
|
204
|
-
__a: 1,
|
|
205
|
-
__req: utils.getSignatureID(),
|
|
206
|
-
__hs: "20352.HYP:comet_pkg.2.1...0",
|
|
207
|
-
dpr: 1,
|
|
208
|
-
__ccg: "EXCELLENT",
|
|
209
|
-
__rev: "1027396270",
|
|
210
|
-
__s: utils.getSignatureID(),
|
|
211
|
-
__hsi: "7552524636527201016",
|
|
212
|
-
__comet_req: 15,
|
|
213
|
-
fb_dtsg: ctx.fb_dtsg,
|
|
214
|
-
jazoest: ctx.ttstamp,
|
|
215
|
-
lsd: ctx.fb_dtsg,
|
|
216
|
-
__spin_r: "1027396270",
|
|
217
|
-
__spin_b: "trunk",
|
|
218
|
-
__spin_t: timestamp,
|
|
219
|
-
__crn: "comet.fbweb.MWInboxHomeRoute",
|
|
220
|
-
fb_api_caller_class: "RelayModern",
|
|
221
|
-
fb_api_req_friendly_name: "MessengerThreadThemeUpdateMutation",
|
|
222
|
-
variables: JSON.stringify({
|
|
223
|
-
"input": {
|
|
224
|
-
"actor_id": ctx.userID,
|
|
225
|
-
"client_mutation_id": Math.floor(Math.random() * 10000).toString(),
|
|
226
|
-
"source": "SETTINGS",
|
|
227
|
-
"thread_id": threadID.toString(),
|
|
228
|
-
"theme_id": themeId.toString(),
|
|
229
|
-
"custom_emoji": customEmoji
|
|
230
|
-
}
|
|
231
|
-
}),
|
|
232
|
-
server_timestamps: true,
|
|
233
|
-
doc_id: "9734829906576883" // Updated doc_id based on working API
|
|
234
|
-
};
|
|
235
|
-
|
|
236
|
-
const result = await defaultFuncs
|
|
237
|
-
.post("https://www.facebook.com/api/graphql/", ctx.jar, alternativeForm)
|
|
238
|
-
.then(utils.parseAndCheckLogin(ctx, defaultFuncs));
|
|
239
|
-
|
|
240
|
-
if (result && result.errors && result.errors.length > 0) {
|
|
241
|
-
throw new Error("GraphQL Error: " + JSON.stringify(result.errors));
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
// Check if the mutation was successful
|
|
245
|
-
if (result && result.data && result.data.messenger_thread_theme_update) {
|
|
246
|
-
const updateResult = result.data.messenger_thread_theme_update;
|
|
247
|
-
if (updateResult.errors && updateResult.errors.length > 0) {
|
|
248
|
-
throw new Error("Theme Update Error: " + JSON.stringify(updateResult.errors));
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
return callback(null, {
|
|
253
|
-
threadID: threadID,
|
|
254
|
-
themeId: themeId,
|
|
255
|
-
customEmoji: customEmoji,
|
|
256
|
-
timestamp: timestamp,
|
|
257
|
-
success: true,
|
|
258
|
-
method: "graphql",
|
|
259
|
-
availableThemes: availableThemes.length > 0 ? availableThemes.map(t => ({
|
|
260
|
-
id: t.id,
|
|
261
|
-
name: t.accessibility_label,
|
|
262
|
-
description: t.description
|
|
263
|
-
})) : null
|
|
264
|
-
});
|
|
265
|
-
|
|
266
|
-
} catch (err) {
|
|
267
|
-
log.error("setThreadTheme", err);
|
|
268
|
-
return callback(err);
|
|
269
|
-
}
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
updateThreadTheme();
|
|
273
|
-
return returnPromise;
|
|
274
|
-
};
|
|
17
|
+
/** Developed by Sheikh Tamim | GitHub: sheikhtamimlover | Instagram: @sheikh.tamim_lover */
|
|
18
|
+
return function setThreadTheme(threadID, themeFBID, callback) {
|
|
19
|
+
var resolveFunc = function () { };
|
|
20
|
+
var rejectFunc = function () { };
|
|
21
|
+
var returnPromise = new Promise(function (resolve, reject) {
|
|
22
|
+
resolveFunc = resolve;
|
|
23
|
+
rejectFunc = reject;
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
if (!callback) {
|
|
27
|
+
callback = function (err, data) {
|
|
28
|
+
if (err) return rejectFunc(err);
|
|
29
|
+
resolveFunc(data);
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
if (!ctx.mqttClient) {
|
|
34
|
+
return callback(new Error('Not connected to MQTT'));
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
ctx.wsReqNumber += 1;
|
|
38
|
+
let baseTaskNumber = ++ctx.wsTaskNumber;
|
|
39
|
+
|
|
40
|
+
const makeTask = (label, queueName, extraPayload = {}) => ({
|
|
41
|
+
failure_count: null,
|
|
42
|
+
label: String(label),
|
|
43
|
+
payload: JSON.stringify({
|
|
44
|
+
thread_key: threadID,
|
|
45
|
+
theme_fbid: themeFBID,
|
|
46
|
+
sync_group: 1,
|
|
47
|
+
...extraPayload,
|
|
48
|
+
}),
|
|
49
|
+
queue_name: typeof queueName === 'string' ? queueName : JSON.stringify(queueName),
|
|
50
|
+
task_id: baseTaskNumber++,
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
const messages = [
|
|
54
|
+
{
|
|
55
|
+
label: 1013,
|
|
56
|
+
queue: ['ai_generated_theme', String(threadID)],
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
label: 1037,
|
|
60
|
+
queue: ['msgr_custom_thread_theme', String(threadID)],
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
label: 1028,
|
|
64
|
+
queue: ['thread_theme_writer', String(threadID)],
|
|
65
|
+
},
|
|
66
|
+
{
|
|
67
|
+
label: 43,
|
|
68
|
+
queue: 'thread_theme',
|
|
69
|
+
extra: { source: null, payload: null },
|
|
70
|
+
},
|
|
71
|
+
].map(({ label, queue, extra }) => {
|
|
72
|
+
ctx.wsReqNumber += 1;
|
|
73
|
+
return {
|
|
74
|
+
app_id: '772021112871879',
|
|
75
|
+
payload: JSON.stringify({
|
|
76
|
+
epoch_id: parseInt(utils.generateOfflineThreadingID()),
|
|
77
|
+
tasks: [makeTask(label, queue, extra)],
|
|
78
|
+
version_id: '24227364673632991',
|
|
79
|
+
}),
|
|
80
|
+
//pwa_version: '1',
|
|
81
|
+
request_id: ctx.wsReqNumber,
|
|
82
|
+
type: 3,
|
|
83
|
+
};
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
try {
|
|
87
|
+
messages.forEach((msg, idx) => {
|
|
88
|
+
ctx.mqttClient.publish(
|
|
89
|
+
'/ls_req',
|
|
90
|
+
JSON.stringify(msg),
|
|
91
|
+
{ qos: 1, retain: false },
|
|
92
|
+
idx === messages.length - 1 && callback ? callback : undefined
|
|
93
|
+
);
|
|
94
|
+
});
|
|
95
|
+
} catch (err) {
|
|
96
|
+
if (callback) callback(err);
|
|
97
|
+
else throw err;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return returnPromise;
|
|
101
|
+
};
|
|
275
102
|
};
|
|
276
103
|
/** Developed by Sheikh Tamim | GitHub: sheikhtamimlover | Please give credits if reused. */
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ===========================================================
|
|
3
|
+
* 💫 META THEME GENERATOR MODULE 💫
|
|
4
|
+
* ===========================================================
|
|
5
|
+
* 🧑💻 Author: Sheikh Tamim (ST | Sheikh Tamim)
|
|
6
|
+
* 🔰 Owner & Developer
|
|
7
|
+
* 🌐 GitHub: https://github.com/sheikhtamimlover
|
|
8
|
+
* 📸 Instagram: https://instagram.com/sheikh.tamim_lover
|
|
9
|
+
* 🧠 Description:
|
|
10
|
+
* This module generates beautiful Messenger AI themes
|
|
11
|
+
* using Meta's hidden GraphQL endpoints. It allows you to
|
|
12
|
+
* create unique chat themes based on your custom prompt
|
|
13
|
+
* or optional image inspiration.
|
|
14
|
+
* -----------------------------------------------------------
|
|
15
|
+
* ⚙️ Features:
|
|
16
|
+
* • Generate AI-based Messenger chat themes.
|
|
17
|
+
* • Custom prompt & optional image URL input.
|
|
18
|
+
* • Returns structured theme data with full color mapping.
|
|
19
|
+
* -----------------------------------------------------------
|
|
20
|
+
* 🕊️ Respect the creator & give proper credits if reused.
|
|
21
|
+
* ===========================================================
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
"use strict";
|
|
25
|
+
|
|
26
|
+
var utils = require("../utils");
|
|
27
|
+
var log = require("npmlog");
|
|
28
|
+
|
|
29
|
+
module.exports = function (defaultFuncs, api, ctx) {
|
|
30
|
+
/** Developed by Sheikh Tamim | GitHub: sheikhtamimlover | Instagram: @sheikh.tamim_lover */
|
|
31
|
+
return function suggestFriend(count, cursor, callback) {
|
|
32
|
+
var resolveFunc = function () { };
|
|
33
|
+
var rejectFunc = function () { };
|
|
34
|
+
var returnPromise = new Promise(function (resolve, reject) {
|
|
35
|
+
resolveFunc = resolve;
|
|
36
|
+
rejectFunc = reject;
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
if (!callback) {
|
|
40
|
+
callback = function (err, data) {
|
|
41
|
+
if (err) return rejectFunc(err);
|
|
42
|
+
resolveFunc(data);
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
if (typeof count === 'function') {
|
|
47
|
+
callback = count;
|
|
48
|
+
count = 30;
|
|
49
|
+
cursor = null;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (typeof cursor === 'function') {
|
|
53
|
+
callback = cursor;
|
|
54
|
+
cursor = null;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
count = count || 30;
|
|
58
|
+
|
|
59
|
+
var form = {
|
|
60
|
+
av: ctx.userID,
|
|
61
|
+
__aaid: 0,
|
|
62
|
+
__user: ctx.userID,
|
|
63
|
+
__a: 1,
|
|
64
|
+
__req: utils.getSignatureID(),
|
|
65
|
+
__hs: "20405.HYP:comet_pkg.2.1...0",
|
|
66
|
+
dpr: 1,
|
|
67
|
+
__ccg: "EXCELLENT",
|
|
68
|
+
__rev: "1029835515",
|
|
69
|
+
__s: utils.getSignatureID(),
|
|
70
|
+
__hsi: Date.now(),
|
|
71
|
+
__comet_req: 15,
|
|
72
|
+
fb_dtsg: ctx.fb_dtsg,
|
|
73
|
+
jazoest: ctx.ttstamp,
|
|
74
|
+
lsd: ctx.fb_dtsg,
|
|
75
|
+
__spin_r: "1029835515",
|
|
76
|
+
__spin_b: "trunk",
|
|
77
|
+
__spin_t: Date.now(),
|
|
78
|
+
__crn: "comet.fbweb.CometPYMKSuggestionsRoute",
|
|
79
|
+
fb_api_caller_class: "RelayModern",
|
|
80
|
+
fb_api_req_friendly_name: "FriendingCometPYMKPanelPaginationQuery",
|
|
81
|
+
server_timestamps: true,
|
|
82
|
+
variables: JSON.stringify({
|
|
83
|
+
count: count,
|
|
84
|
+
cursor: cursor,
|
|
85
|
+
location: "FRIENDS_HOME_MAIN",
|
|
86
|
+
scale: 3
|
|
87
|
+
}),
|
|
88
|
+
doc_id: "9917809191634193"
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
defaultFuncs
|
|
92
|
+
.post("https://www.facebook.com/api/graphql/", ctx.jar, form)
|
|
93
|
+
.then(utils.parseAndCheckLogin(ctx, defaultFuncs))
|
|
94
|
+
.then(function (resData) {
|
|
95
|
+
if (resData.error) {
|
|
96
|
+
throw resData;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (resData.data && resData.data.viewer && resData.data.viewer.people_you_may_know) {
|
|
100
|
+
var pymkData = resData.data.viewer.people_you_may_know;
|
|
101
|
+
var suggestions = pymkData.edges.map(function (edge) {
|
|
102
|
+
var node = edge.node;
|
|
103
|
+
return {
|
|
104
|
+
id: node.id,
|
|
105
|
+
name: node.name,
|
|
106
|
+
url: node.url,
|
|
107
|
+
friendshipStatus: node.friendship_status,
|
|
108
|
+
profilePicture: node.profile_picture ? node.profile_picture.uri : null,
|
|
109
|
+
mutualFriends: node.social_context ? node.social_context.text : "",
|
|
110
|
+
topMutualFriends: node.social_context_top_mutual_friends || []
|
|
111
|
+
};
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
var result = {
|
|
115
|
+
suggestions: suggestions,
|
|
116
|
+
hasNextPage: pymkData.page_info.has_next_page,
|
|
117
|
+
endCursor: pymkData.page_info.end_cursor
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
return callback(null, result);
|
|
121
|
+
} else {
|
|
122
|
+
return callback({ error: "Invalid response format" });
|
|
123
|
+
}
|
|
124
|
+
})
|
|
125
|
+
.catch(function (err) {
|
|
126
|
+
log.error("suggestFriend", err);
|
|
127
|
+
return callback(err);
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
return returnPromise;
|
|
131
|
+
};
|
|
132
|
+
};
|
|
133
|
+
/** Developed by Sheikh Tamim | GitHub: sheikhtamimlover | Please give credits if reused. */
|