stfca 1.0.19 → 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/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. */
|