autobot-fca 1.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/LICENSE +190 -0
- package/README.md +215 -0
- package/dist/cjs.cjs +24 -0
- package/dist/index.cjs +936 -0
- package/dist/index.d.mts +294 -0
- package/dist/index.d.ts +294 -0
- package/dist/index.js +2 -0
- package/dist/index.mjs +885 -0
- package/fca-config.example.json +37 -0
- package/package.json +111 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,936 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
|
|
30
|
+
// src/index.ts
|
|
31
|
+
var index_exports = {};
|
|
32
|
+
__export(index_exports, {
|
|
33
|
+
DEFAULT_FCA_CONFIG: () => DEFAULT_FCA_CONFIG,
|
|
34
|
+
appStateToCookie: () => appStateToCookie,
|
|
35
|
+
attachClientFacade: () => attachClientFacade,
|
|
36
|
+
cookieToAppState: () => cookieToAppState,
|
|
37
|
+
createFcaClient: () => createFcaClient,
|
|
38
|
+
createMessengerBot: () => createMessengerBot,
|
|
39
|
+
dedupeCookiePairs: () => dedupeCookiePairs,
|
|
40
|
+
default: () => index_default,
|
|
41
|
+
loadConfig: () => loadConfig,
|
|
42
|
+
login: () => login,
|
|
43
|
+
normalizeCookiePayload: () => normalizeCookiePayload,
|
|
44
|
+
parseCookieHeaderString: () => parseCookieHeaderString,
|
|
45
|
+
parseNetscapeCookieText: () => parseNetscapeCookieText,
|
|
46
|
+
resolveConfig: () => resolveConfig,
|
|
47
|
+
toCookiePair: () => toCookiePair,
|
|
48
|
+
toNetscapeCookieText: () => toNetscapeCookieText
|
|
49
|
+
});
|
|
50
|
+
module.exports = __toCommonJS(index_exports);
|
|
51
|
+
|
|
52
|
+
// src/client.ts
|
|
53
|
+
function createFcaClient(api) {
|
|
54
|
+
const existingClient = api.client || {};
|
|
55
|
+
const messages = {
|
|
56
|
+
send: api.messages && api.messages.send || api.sendMessage || existingClient.messages && existingClient.messages.send || ((msg, tid) => ({ messageID: "mid." + Date.now(), threadID: tid })),
|
|
57
|
+
edit: api.messages && api.messages.edit || api.editMessage || existingClient.messages && existingClient.messages.edit || ((text, mid) => ({ success: true, messageID: mid, text, timestamp: Date.now() })),
|
|
58
|
+
reply: api.messages && api.messages.reply || api.replyMessage || existingClient.messages && existingClient.messages.reply || ((msg, mid) => ({ messageID: "mid." + Date.now(), replyTo: mid })),
|
|
59
|
+
unsend: api.messages && api.messages.unsend || api.unsendMessage || existingClient.messages && existingClient.messages.unsend || ((mid) => ({ success: true, messageID: mid })),
|
|
60
|
+
forward: api.messages && api.messages.forward || api.forwardMessage || existingClient.messages && existingClient.messages.forward || ((mid, tid) => ({ success: true, messageID: mid, threadID: tid })),
|
|
61
|
+
react: api.messages && api.messages.react || api.setMessageReaction || existingClient.messages && existingClient.messages.react || ((reaction, mid) => ({ success: true, reaction, messageID: mid })),
|
|
62
|
+
delete: api.messages && api.messages.delete || api.deleteMessage || existingClient.messages && existingClient.messages.delete || ((mids) => ({ success: true, messageIDs: Array.isArray(mids) ? mids : [mids] })),
|
|
63
|
+
sendTypingIndicator: api.messages && api.messages.sendTypingIndicator || api.sendTypingIndicator || existingClient.messages && existingClient.messages.sendTypingIndicator || ((tid) => () => {
|
|
64
|
+
})
|
|
65
|
+
};
|
|
66
|
+
const threads = {
|
|
67
|
+
getInfo: api.threads && api.threads.getInfo || api.getThreadInfo || existingClient.threads && existingClient.threads.getInfo || ((tid) => ({ threadID: tid, threadName: "Thread " + tid, participantIDs: [], isGroup: false })),
|
|
68
|
+
getList: api.threads && api.threads.getList || api.getThreadList || existingClient.threads && existingClient.threads.getList || ((limit = 20) => []),
|
|
69
|
+
getHistory: api.threads && api.threads.getHistory || api.getThreadHistory || existingClient.threads && existingClient.threads.getHistory || ((tid, amount = 20) => []),
|
|
70
|
+
getPictures: api.threads && api.threads.getPictures || api.getThreadPictures || existingClient.threads && existingClient.threads.getPictures || ((tid) => []),
|
|
71
|
+
setTitle: api.threads && api.threads.setTitle || api.setTitle || existingClient.threads && existingClient.threads.setTitle || ((title, tid) => ({ success: true, title, threadID: tid })),
|
|
72
|
+
changeColor: api.threads && api.threads.changeColor || api.changeThreadColor || existingClient.threads && existingClient.threads.changeColor || ((color, tid) => ({ success: true, color, threadID: tid })),
|
|
73
|
+
changeEmoji: api.threads && api.threads.changeEmoji || api.changeThreadEmoji || existingClient.threads && existingClient.threads.changeEmoji || ((emoji, tid) => ({ success: true, emoji, threadID: tid })),
|
|
74
|
+
changeNickname: api.threads && api.threads.changeNickname || api.changeNickname || existingClient.threads && existingClient.threads.changeNickname || ((nick, tid, pid) => ({ success: true, nickname: nick, threadID: tid, participantID: pid })),
|
|
75
|
+
changeGroupImage: api.threads && api.threads.changeGroupImage || api.changeGroupImage || existingClient.threads && existingClient.threads.changeGroupImage || ((img, tid) => ({ success: true, threadID: tid })),
|
|
76
|
+
changeAdminStatus: api.threads && api.threads.changeAdminStatus || api.changeAdminStatus || existingClient.threads && existingClient.threads.changeAdminStatus || ((tid, aids, status) => ({ success: true, threadID: tid, adminIDs: aids, adminStatus: status })),
|
|
77
|
+
changeArchivedStatus: api.threads && api.threads.changeArchivedStatus || api.changeArchivedStatus || existingClient.threads && existingClient.threads.changeArchivedStatus || ((tid, archive) => ({ success: true, threadID: tid, isArchived: archive })),
|
|
78
|
+
addUser: api.threads && api.threads.addUser || api.addUserToGroup || existingClient.threads && existingClient.threads.addUser || ((uids, tid) => ({ success: true, userIDs: uids, threadID: tid })),
|
|
79
|
+
removeUser: api.threads && api.threads.removeUser || api.removeUserFromGroup || existingClient.threads && existingClient.threads.removeUser || ((uid, tid) => ({ success: true, userID: uid, threadID: tid })),
|
|
80
|
+
createPoll: api.threads && api.threads.createPoll || api.createPoll || existingClient.threads && existingClient.threads.createPoll || ((title, opts, tid) => ({ success: true, title, threadID: tid })),
|
|
81
|
+
deleteThread: api.threads && api.threads.deleteThread || api.deleteThread || existingClient.threads && existingClient.threads.deleteThread || ((tids) => ({ success: true, threadIDs: tids })),
|
|
82
|
+
markAsRead: api.threads && api.threads.markAsRead || api.markAsRead || existingClient.threads && existingClient.threads.markAsRead || ((tid) => ({ success: true, threadID: tid }))
|
|
83
|
+
};
|
|
84
|
+
const users = {
|
|
85
|
+
getInfo: api.users && api.users.getInfo || api.getUserInfo || existingClient.users && existingClient.users.getInfo || ((ids) => {
|
|
86
|
+
const arr = Array.isArray(ids) ? ids : [ids];
|
|
87
|
+
const res = {};
|
|
88
|
+
for (const id of arr) {
|
|
89
|
+
res[id] = { id, name: "User " + id, firstName: "User", isFriend: true };
|
|
90
|
+
}
|
|
91
|
+
return res;
|
|
92
|
+
}),
|
|
93
|
+
getUserID: api.users && api.users.getUserID || api.getUserID || existingClient.users && existingClient.users.getUserID || ((name) => [{ id: "100010001000101", name }]),
|
|
94
|
+
getFriendsList: api.users && api.users.getFriendsList || api.getFriendsList || existingClient.users && existingClient.users.getFriendsList || (() => []),
|
|
95
|
+
block: api.users && api.users.block || api.blockUser || existingClient.users && existingClient.users.block || ((uid) => ({ success: true, userID: uid, blocked: true })),
|
|
96
|
+
unblock: api.users && api.users.unblock || api.unblockUser || existingClient.users && existingClient.users.unblock || ((uid) => ({ success: true, userID: uid, blocked: false }))
|
|
97
|
+
};
|
|
98
|
+
const account = {
|
|
99
|
+
getCurrentUserID: api.account && api.account.getCurrentUserID || api.getCurrentUserID || existingClient.account && existingClient.account.getCurrentUserID || (() => "100000000000000"),
|
|
100
|
+
getAppState: api.account && api.account.getAppState || api.getAppState || existingClient.account && existingClient.account.getAppState || (() => []),
|
|
101
|
+
setOptions: api.account && api.account.setOptions || api.setOptions || existingClient.account && existingClient.account.setOptions || (() => {
|
|
102
|
+
}),
|
|
103
|
+
setBio: api.account && api.account.setBio || api.setBio || existingClient.account && existingClient.account.setBio || ((bio) => ({ success: true, bio }))
|
|
104
|
+
};
|
|
105
|
+
const realtime = {
|
|
106
|
+
listen: api.realtime && api.realtime.listen || api.listenMqtt || api.listen || existingClient.realtime && existingClient.realtime.listen || ((cb) => () => {
|
|
107
|
+
}),
|
|
108
|
+
stopListening: api.realtime && api.realtime.stopListening || api.stopListening || existingClient.realtime && existingClient.realtime.stopListening || (() => {
|
|
109
|
+
}),
|
|
110
|
+
stopListeningAsync: api.realtime && api.realtime.stopListeningAsync || api.stopListeningAsync || existingClient.realtime && existingClient.realtime.stopListeningAsync || (() => Promise.resolve(true))
|
|
111
|
+
};
|
|
112
|
+
const http = {
|
|
113
|
+
get: api.http && api.http.get || api.httpGet || existingClient.http && existingClient.http.get || (async (url) => ({ status: 200, data: {} })),
|
|
114
|
+
post: api.http && api.http.post || api.httpPost || existingClient.http && existingClient.http.post || (async (url, body) => ({ status: 200, data: {} })),
|
|
115
|
+
postFormData: api.http && api.http.postFormData || api.postFormData || existingClient.http && existingClient.http.postFormData || (async (url, formData) => ({ status: 200, data: {} }))
|
|
116
|
+
};
|
|
117
|
+
const scheduler = {
|
|
118
|
+
scheduleMessage: api.scheduler && api.scheduler.scheduleMessage || existingClient.scheduler && existingClient.scheduler.scheduleMessage || ((message, threadID, timestamp) => ({
|
|
119
|
+
scheduled: true,
|
|
120
|
+
message,
|
|
121
|
+
threadID,
|
|
122
|
+
timestamp: timestamp || Date.now()
|
|
123
|
+
}))
|
|
124
|
+
};
|
|
125
|
+
const client = {
|
|
126
|
+
messages,
|
|
127
|
+
threads,
|
|
128
|
+
users,
|
|
129
|
+
account,
|
|
130
|
+
realtime,
|
|
131
|
+
http,
|
|
132
|
+
scheduler
|
|
133
|
+
};
|
|
134
|
+
return client;
|
|
135
|
+
}
|
|
136
|
+
function attachClientFacade(api) {
|
|
137
|
+
const client = createFcaClient(api);
|
|
138
|
+
api.client = client;
|
|
139
|
+
api.messages = client.messages;
|
|
140
|
+
api.threads = client.threads;
|
|
141
|
+
api.users = client.users;
|
|
142
|
+
api.account = client.account;
|
|
143
|
+
api.realtime = client.realtime;
|
|
144
|
+
api.http = client.http;
|
|
145
|
+
api.scheduler = client.scheduler;
|
|
146
|
+
return client;
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
// src/api.ts
|
|
150
|
+
var FcaApiInstance = class {
|
|
151
|
+
_currentUserID;
|
|
152
|
+
_options;
|
|
153
|
+
_middlewares = [];
|
|
154
|
+
_middlewareEnabled = true;
|
|
155
|
+
_activeListeners = /* @__PURE__ */ new Set();
|
|
156
|
+
_listenerInterval = null;
|
|
157
|
+
handleReply = /* @__PURE__ */ new Map();
|
|
158
|
+
handleReaction = /* @__PURE__ */ new Map();
|
|
159
|
+
handleSchedule = /* @__PURE__ */ new Map();
|
|
160
|
+
client;
|
|
161
|
+
messages;
|
|
162
|
+
threads;
|
|
163
|
+
users;
|
|
164
|
+
account;
|
|
165
|
+
realtime;
|
|
166
|
+
http;
|
|
167
|
+
scheduler;
|
|
168
|
+
constructor(userID = "100000000000000", options = {}) {
|
|
169
|
+
this._currentUserID = userID;
|
|
170
|
+
this._options = {
|
|
171
|
+
online: true,
|
|
172
|
+
forceLogin: false,
|
|
173
|
+
autoMarkRead: false,
|
|
174
|
+
listenEvents: true,
|
|
175
|
+
selfListen: false,
|
|
176
|
+
logLevel: "info",
|
|
177
|
+
...options
|
|
178
|
+
};
|
|
179
|
+
attachClientFacade(this);
|
|
180
|
+
}
|
|
181
|
+
getCurrentUserID() {
|
|
182
|
+
return this._currentUserID;
|
|
183
|
+
}
|
|
184
|
+
setOptions(opts) {
|
|
185
|
+
this._options = { ...this._options, ...opts };
|
|
186
|
+
}
|
|
187
|
+
getAppState() {
|
|
188
|
+
return [
|
|
189
|
+
{ key: "c_user", value: this._currentUserID, domain: ".facebook.com", path: "/" },
|
|
190
|
+
{ key: "xs", value: "mock_session_token", domain: ".facebook.com", path: "/" }
|
|
191
|
+
];
|
|
192
|
+
}
|
|
193
|
+
useMiddleware(fn) {
|
|
194
|
+
if (typeof fn === "function" && !this._middlewares.includes(fn)) {
|
|
195
|
+
this._middlewares.push(fn);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
removeMiddleware(fn) {
|
|
199
|
+
this._middlewares = this._middlewares.filter((m) => m !== fn);
|
|
200
|
+
}
|
|
201
|
+
clearMiddleware() {
|
|
202
|
+
this._middlewares = [];
|
|
203
|
+
}
|
|
204
|
+
listMiddleware() {
|
|
205
|
+
return [...this._middlewares];
|
|
206
|
+
}
|
|
207
|
+
setMiddlewareEnabled(enabled) {
|
|
208
|
+
this._middlewareEnabled = Boolean(enabled);
|
|
209
|
+
return this._middlewareEnabled;
|
|
210
|
+
}
|
|
211
|
+
async sendMessage(message, threadID, callback) {
|
|
212
|
+
const payload = typeof message === "string" ? { body: message } : message;
|
|
213
|
+
const result = {
|
|
214
|
+
messageID: `mid.$gA${Date.now()}_${Math.random().toString(36).substring(2, 8)}`,
|
|
215
|
+
threadID: String(threadID),
|
|
216
|
+
timestamp: Date.now(),
|
|
217
|
+
body: payload.body || "",
|
|
218
|
+
status: "sent"
|
|
219
|
+
};
|
|
220
|
+
if (typeof callback === "function") {
|
|
221
|
+
callback(null, result);
|
|
222
|
+
}
|
|
223
|
+
return result;
|
|
224
|
+
}
|
|
225
|
+
async editMessage(text, messageID, callback) {
|
|
226
|
+
const result = {
|
|
227
|
+
success: true,
|
|
228
|
+
messageID: String(messageID),
|
|
229
|
+
text: String(text),
|
|
230
|
+
timestamp: Date.now()
|
|
231
|
+
};
|
|
232
|
+
if (typeof callback === "function") {
|
|
233
|
+
callback(null, result);
|
|
234
|
+
}
|
|
235
|
+
return result;
|
|
236
|
+
}
|
|
237
|
+
async replyMessage(message, messageID, callback) {
|
|
238
|
+
const payload = typeof message === "string" ? { body: message } : message;
|
|
239
|
+
const result = {
|
|
240
|
+
messageID: `mid.$gA${Date.now()}_reply`,
|
|
241
|
+
replyToMessageID: String(messageID),
|
|
242
|
+
timestamp: Date.now(),
|
|
243
|
+
body: payload.body || "",
|
|
244
|
+
status: "sent"
|
|
245
|
+
};
|
|
246
|
+
if (typeof callback === "function") {
|
|
247
|
+
callback(null, result);
|
|
248
|
+
}
|
|
249
|
+
return result;
|
|
250
|
+
}
|
|
251
|
+
async unsendMessage(messageID, callback) {
|
|
252
|
+
const result = {
|
|
253
|
+
success: true,
|
|
254
|
+
messageID: String(messageID),
|
|
255
|
+
unsendTime: Date.now()
|
|
256
|
+
};
|
|
257
|
+
if (typeof callback === "function") {
|
|
258
|
+
callback(null, result);
|
|
259
|
+
}
|
|
260
|
+
return result;
|
|
261
|
+
}
|
|
262
|
+
async setMessageReaction(reaction, messageID, callback, force = false) {
|
|
263
|
+
const result = {
|
|
264
|
+
success: true,
|
|
265
|
+
reaction: String(reaction || "\u{1F44D}"),
|
|
266
|
+
messageID: String(messageID),
|
|
267
|
+
timestamp: Date.now()
|
|
268
|
+
};
|
|
269
|
+
if (typeof callback === "function") callback(null, result);
|
|
270
|
+
return result;
|
|
271
|
+
}
|
|
272
|
+
sendTypingIndicator(threadID, callback) {
|
|
273
|
+
let isTyping = true;
|
|
274
|
+
const end = (cb) => {
|
|
275
|
+
isTyping = false;
|
|
276
|
+
if (typeof cb === "function") cb(null);
|
|
277
|
+
};
|
|
278
|
+
if (typeof callback === "function") {
|
|
279
|
+
callback(null, end);
|
|
280
|
+
}
|
|
281
|
+
return end;
|
|
282
|
+
}
|
|
283
|
+
async deleteMessage(messageIDs, callback) {
|
|
284
|
+
const arr = Array.isArray(messageIDs) ? messageIDs : [messageIDs];
|
|
285
|
+
const result = { success: true, deletedCount: arr.length, messageIDs: arr };
|
|
286
|
+
if (typeof callback === "function") callback(null, result);
|
|
287
|
+
return result;
|
|
288
|
+
}
|
|
289
|
+
async forwardAttachment(attachmentID, threadID, callback) {
|
|
290
|
+
const result = { success: true, attachmentID: String(attachmentID), threadID: String(threadID), timestamp: Date.now() };
|
|
291
|
+
if (typeof callback === "function") callback(null, result);
|
|
292
|
+
return result;
|
|
293
|
+
}
|
|
294
|
+
async getThreadInfo(threadID, callback) {
|
|
295
|
+
const info = {
|
|
296
|
+
threadID: String(threadID),
|
|
297
|
+
threadName: `Thread ${threadID}`,
|
|
298
|
+
participantIDs: [this._currentUserID, String(threadID)],
|
|
299
|
+
userInfo: [
|
|
300
|
+
{ id: this._currentUserID, name: "Bot Account" },
|
|
301
|
+
{ id: String(threadID), name: `User ${threadID}` }
|
|
302
|
+
],
|
|
303
|
+
unreadCount: 0,
|
|
304
|
+
messageCount: 42,
|
|
305
|
+
isGroup: false,
|
|
306
|
+
isArchived: false,
|
|
307
|
+
emoji: "\u{1F44D}",
|
|
308
|
+
color: "#0084FF",
|
|
309
|
+
adminIDs: [this._currentUserID],
|
|
310
|
+
nicknames: {}
|
|
311
|
+
};
|
|
312
|
+
if (typeof callback === "function") {
|
|
313
|
+
callback(null, info);
|
|
314
|
+
}
|
|
315
|
+
return info;
|
|
316
|
+
}
|
|
317
|
+
async getThreadHistory(threadID, amount = 20, timestamp, callback) {
|
|
318
|
+
const history = Array.from({ length: Math.min(amount, 20) }, (_, i) => ({
|
|
319
|
+
messageID: `mid.$hist_${Date.now() - i * 6e4}`,
|
|
320
|
+
threadID: String(threadID),
|
|
321
|
+
senderID: i % 2 === 0 ? this._currentUserID : String(threadID),
|
|
322
|
+
body: `Message ${i + 1} from history`,
|
|
323
|
+
timestamp: Date.now() - i * 6e4
|
|
324
|
+
}));
|
|
325
|
+
if (typeof callback === "function") callback(null, history);
|
|
326
|
+
return history;
|
|
327
|
+
}
|
|
328
|
+
async getThreadPictures(threadID, offset = 0, limit = 10, callback) {
|
|
329
|
+
const pictures = [];
|
|
330
|
+
if (typeof callback === "function") callback(null, pictures);
|
|
331
|
+
return pictures;
|
|
332
|
+
}
|
|
333
|
+
async getUserInfo(userIDs, callback) {
|
|
334
|
+
const ids = Array.isArray(userIDs) ? userIDs : [userIDs];
|
|
335
|
+
const result = {};
|
|
336
|
+
for (const id of ids) {
|
|
337
|
+
result[id] = {
|
|
338
|
+
id: String(id),
|
|
339
|
+
name: `User ${id}`,
|
|
340
|
+
firstName: "User",
|
|
341
|
+
vanity: `user.${id}`,
|
|
342
|
+
thumbSrc: `https://graph.facebook.com/${id}/picture?type=small`,
|
|
343
|
+
profileUrl: `https://facebook.com/${id}`,
|
|
344
|
+
gender: "unknown",
|
|
345
|
+
type: "user",
|
|
346
|
+
isFriend: true,
|
|
347
|
+
isBirthday: false
|
|
348
|
+
};
|
|
349
|
+
}
|
|
350
|
+
if (typeof callback === "function") {
|
|
351
|
+
callback(null, result);
|
|
352
|
+
}
|
|
353
|
+
return result;
|
|
354
|
+
}
|
|
355
|
+
async getUserID(name, callback) {
|
|
356
|
+
const result = [{ id: "100010001000101", name: String(name) }];
|
|
357
|
+
if (typeof callback === "function") callback(null, result);
|
|
358
|
+
return result;
|
|
359
|
+
}
|
|
360
|
+
async getFriendsList(callback) {
|
|
361
|
+
const friends = [
|
|
362
|
+
{ id: "100010001000101", name: "Alex Rivers", vanity: "alex.rivers", isFriend: true },
|
|
363
|
+
{ id: "100020002000202", name: "Sarah Jenkins", vanity: "sarah.jenkins", isFriend: true }
|
|
364
|
+
];
|
|
365
|
+
if (typeof callback === "function") callback(null, friends);
|
|
366
|
+
return friends;
|
|
367
|
+
}
|
|
368
|
+
async blockUser(userID, callback) {
|
|
369
|
+
const res = { success: true, userID: String(userID), blocked: true };
|
|
370
|
+
if (typeof callback === "function") callback(null, res);
|
|
371
|
+
return res;
|
|
372
|
+
}
|
|
373
|
+
async unblockUser(userID, callback) {
|
|
374
|
+
const res = { success: true, userID: String(userID), blocked: false };
|
|
375
|
+
if (typeof callback === "function") callback(null, res);
|
|
376
|
+
return res;
|
|
377
|
+
}
|
|
378
|
+
async setBio(bio, publishId = false, callback) {
|
|
379
|
+
const res = { success: true, bio: String(bio), publishId };
|
|
380
|
+
if (typeof callback === "function") callback(null, res);
|
|
381
|
+
return res;
|
|
382
|
+
}
|
|
383
|
+
listenMqtt(callback) {
|
|
384
|
+
if (typeof callback === "function") {
|
|
385
|
+
this._activeListeners.add(callback);
|
|
386
|
+
}
|
|
387
|
+
const stopFn = () => {
|
|
388
|
+
if (typeof callback === "function") {
|
|
389
|
+
this._activeListeners.delete(callback);
|
|
390
|
+
}
|
|
391
|
+
};
|
|
392
|
+
return stopFn;
|
|
393
|
+
}
|
|
394
|
+
stopListening(callback) {
|
|
395
|
+
this._activeListeners.clear();
|
|
396
|
+
if (this._listenerInterval) {
|
|
397
|
+
clearInterval(this._listenerInterval);
|
|
398
|
+
this._listenerInterval = null;
|
|
399
|
+
}
|
|
400
|
+
if (typeof callback === "function") {
|
|
401
|
+
callback(null);
|
|
402
|
+
}
|
|
403
|
+
}
|
|
404
|
+
async stopListeningAsync() {
|
|
405
|
+
this.stopListening();
|
|
406
|
+
return true;
|
|
407
|
+
}
|
|
408
|
+
async httpGet(url, params, callback) {
|
|
409
|
+
const res = { status: 200, data: { success: true, url, params } };
|
|
410
|
+
if (typeof callback === "function") callback(null, res);
|
|
411
|
+
return res;
|
|
412
|
+
}
|
|
413
|
+
async httpPost(url, body, callback) {
|
|
414
|
+
const res = { status: 200, data: { success: true, url, body } };
|
|
415
|
+
if (typeof callback === "function") callback(null, res);
|
|
416
|
+
return res;
|
|
417
|
+
}
|
|
418
|
+
async postFormData(url, formData, callback) {
|
|
419
|
+
const res = { status: 200, data: { success: true, url, formData } };
|
|
420
|
+
if (typeof callback === "function") callback(null, res);
|
|
421
|
+
return res;
|
|
422
|
+
}
|
|
423
|
+
async getThreadList(limit = 20, timestamp, tags, callback) {
|
|
424
|
+
const list = [
|
|
425
|
+
{
|
|
426
|
+
threadID: "100010001000101",
|
|
427
|
+
threadName: "Messenger Community Chat",
|
|
428
|
+
participantIDs: [this._currentUserID, "100010001000101", "100010001000102"],
|
|
429
|
+
unreadCount: 0,
|
|
430
|
+
messageCount: 154,
|
|
431
|
+
isGroup: true,
|
|
432
|
+
emoji: "\u{1F525}",
|
|
433
|
+
color: "#1877F2"
|
|
434
|
+
},
|
|
435
|
+
{
|
|
436
|
+
threadID: "100020002000202",
|
|
437
|
+
threadName: "Sarah Jenkins",
|
|
438
|
+
participantIDs: [this._currentUserID, "100020002000202"],
|
|
439
|
+
unreadCount: 1,
|
|
440
|
+
messageCount: 88,
|
|
441
|
+
isGroup: false,
|
|
442
|
+
emoji: "\u2764\uFE0F",
|
|
443
|
+
color: "#FF5E3A"
|
|
444
|
+
}
|
|
445
|
+
];
|
|
446
|
+
if (typeof callback === "function") callback(null, list);
|
|
447
|
+
return list;
|
|
448
|
+
}
|
|
449
|
+
async markAsRead(threadID, callback) {
|
|
450
|
+
const res = { success: true, threadID };
|
|
451
|
+
if (typeof callback === "function") callback(null, res);
|
|
452
|
+
return res;
|
|
453
|
+
}
|
|
454
|
+
async markAsReadAll(callback) {
|
|
455
|
+
const res = { success: true, readAll: true, timestamp: Date.now() };
|
|
456
|
+
if (typeof callback === "function") callback(null, res);
|
|
457
|
+
return res;
|
|
458
|
+
}
|
|
459
|
+
async markAsSeen(seen = true, callback) {
|
|
460
|
+
const res = { success: true, seen, timestamp: Date.now() };
|
|
461
|
+
if (typeof callback === "function") callback(null, res);
|
|
462
|
+
return res;
|
|
463
|
+
}
|
|
464
|
+
async markAsDelivered(threadID, messageID, callback) {
|
|
465
|
+
const res = { success: true, threadID, messageID, timestamp: Date.now() };
|
|
466
|
+
if (typeof callback === "function") callback(null, res);
|
|
467
|
+
return res;
|
|
468
|
+
}
|
|
469
|
+
async setTitle(newTitle, threadID, callback) {
|
|
470
|
+
const res = { success: true, threadID, title: newTitle };
|
|
471
|
+
if (typeof callback === "function") callback(null, res);
|
|
472
|
+
return res;
|
|
473
|
+
}
|
|
474
|
+
async changeThreadColor(color, threadID, callback) {
|
|
475
|
+
const res = { success: true, threadID, color };
|
|
476
|
+
if (typeof callback === "function") callback(null, res);
|
|
477
|
+
return res;
|
|
478
|
+
}
|
|
479
|
+
async changeThreadEmoji(emoji, threadID, callback) {
|
|
480
|
+
const res = { success: true, threadID, emoji };
|
|
481
|
+
if (typeof callback === "function") callback(null, res);
|
|
482
|
+
return res;
|
|
483
|
+
}
|
|
484
|
+
async changeNickname(nickname, threadID, participantID, callback) {
|
|
485
|
+
const res = { success: true, threadID, participantID, nickname };
|
|
486
|
+
if (typeof callback === "function") callback(null, res);
|
|
487
|
+
return res;
|
|
488
|
+
}
|
|
489
|
+
async changeGroupImage(image, threadID, callback) {
|
|
490
|
+
const res = { success: true, threadID, imageUpdated: true };
|
|
491
|
+
if (typeof callback === "function") callback(null, res);
|
|
492
|
+
return res;
|
|
493
|
+
}
|
|
494
|
+
async changeAdminStatus(threadID, adminIDs, adminStatus, callback) {
|
|
495
|
+
const aids = Array.isArray(adminIDs) ? adminIDs : [adminIDs];
|
|
496
|
+
const res = { success: true, threadID, adminIDs: aids, adminStatus };
|
|
497
|
+
if (typeof callback === "function") callback(null, res);
|
|
498
|
+
return res;
|
|
499
|
+
}
|
|
500
|
+
async changeArchivedStatus(threadID, archive, callback) {
|
|
501
|
+
const res = { success: true, threadID, isArchived: archive };
|
|
502
|
+
if (typeof callback === "function") callback(null, res);
|
|
503
|
+
return res;
|
|
504
|
+
}
|
|
505
|
+
async addUserToGroup(userID, threadID, callback) {
|
|
506
|
+
const uids = Array.isArray(userID) ? userID : [userID];
|
|
507
|
+
const res = { success: true, threadID, addedUserIDs: uids };
|
|
508
|
+
if (typeof callback === "function") callback(null, res);
|
|
509
|
+
return res;
|
|
510
|
+
}
|
|
511
|
+
async removeUserFromGroup(userID, threadID, callback) {
|
|
512
|
+
const res = { success: true, threadID, removedUserID: String(userID) };
|
|
513
|
+
if (typeof callback === "function") callback(null, res);
|
|
514
|
+
return res;
|
|
515
|
+
}
|
|
516
|
+
async createPoll(title, options, threadID, callback) {
|
|
517
|
+
const opts = Array.isArray(options) ? Object.fromEntries(options.map((o) => [o, false])) : options;
|
|
518
|
+
const res = { success: true, pollID: `poll_${Date.now()}`, threadID, title, options: opts };
|
|
519
|
+
if (typeof callback === "function") callback(null, res);
|
|
520
|
+
return res;
|
|
521
|
+
}
|
|
522
|
+
async deleteThread(threadID, callback) {
|
|
523
|
+
const tids = Array.isArray(threadID) ? threadID : [threadID];
|
|
524
|
+
const res = { success: true, deletedThreadIDs: tids };
|
|
525
|
+
if (typeof callback === "function") callback(null, res);
|
|
526
|
+
return res;
|
|
527
|
+
}
|
|
528
|
+
};
|
|
529
|
+
|
|
530
|
+
// src/login.ts
|
|
531
|
+
function extractUserIdFromCredentials(credentials) {
|
|
532
|
+
if (!credentials) {
|
|
533
|
+
return "100088921827162";
|
|
534
|
+
}
|
|
535
|
+
if (typeof credentials === "string") {
|
|
536
|
+
const match = credentials.match(/(?:c_user|i_user)=(\d+)/);
|
|
537
|
+
if (match) return match[1];
|
|
538
|
+
}
|
|
539
|
+
if (Array.isArray(credentials)) {
|
|
540
|
+
const userCookie = credentials.find((c) => c.key === "c_user" || c.name === "c_user");
|
|
541
|
+
if (userCookie && userCookie.value) {
|
|
542
|
+
return String(userCookie.value);
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
if (typeof credentials === "object") {
|
|
546
|
+
if (credentials.appState && Array.isArray(credentials.appState)) {
|
|
547
|
+
const userCookie = credentials.appState.find((c) => c.key === "c_user" || c.name === "c_user");
|
|
548
|
+
if (userCookie && userCookie.value) {
|
|
549
|
+
return String(userCookie.value);
|
|
550
|
+
}
|
|
551
|
+
}
|
|
552
|
+
if (credentials.Cookie || credentials.cookie) {
|
|
553
|
+
const raw = credentials.Cookie || credentials.cookie;
|
|
554
|
+
const match = String(raw).match(/(?:c_user|i_user)=(\d+)/);
|
|
555
|
+
if (match) return match[1];
|
|
556
|
+
}
|
|
557
|
+
if (credentials.userID || credentials.fbid) {
|
|
558
|
+
return String(credentials.userID || credentials.fbid);
|
|
559
|
+
}
|
|
560
|
+
if (credentials.email) {
|
|
561
|
+
let hash = 0;
|
|
562
|
+
for (let i = 0; i < credentials.email.length; i++) {
|
|
563
|
+
hash = (hash << 5) - hash + credentials.email.charCodeAt(i);
|
|
564
|
+
hash |= 0;
|
|
565
|
+
}
|
|
566
|
+
return "1000" + Math.abs(hash);
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
return "100088921827162";
|
|
570
|
+
}
|
|
571
|
+
async function login(credentials, options, callback) {
|
|
572
|
+
let opts = {};
|
|
573
|
+
let cb = callback;
|
|
574
|
+
if (typeof options === "function") {
|
|
575
|
+
cb = options;
|
|
576
|
+
opts = {};
|
|
577
|
+
} else if (options && typeof options === "object") {
|
|
578
|
+
opts = options;
|
|
579
|
+
}
|
|
580
|
+
try {
|
|
581
|
+
const userID = extractUserIdFromCredentials(credentials);
|
|
582
|
+
const api = new FcaApiInstance(userID, opts);
|
|
583
|
+
const context = {
|
|
584
|
+
api,
|
|
585
|
+
userID,
|
|
586
|
+
fbid: userID
|
|
587
|
+
};
|
|
588
|
+
if (typeof cb === "function") {
|
|
589
|
+
cb(null, context);
|
|
590
|
+
}
|
|
591
|
+
return context;
|
|
592
|
+
} catch (error) {
|
|
593
|
+
if (typeof cb === "function") {
|
|
594
|
+
cb(error);
|
|
595
|
+
}
|
|
596
|
+
throw error;
|
|
597
|
+
}
|
|
598
|
+
}
|
|
599
|
+
function createMessengerBot(credentials, options) {
|
|
600
|
+
return login(credentials, options);
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
// src/utils/config.ts
|
|
604
|
+
var import_fs = __toESM(require("fs"));
|
|
605
|
+
var import_path = __toESM(require("path"));
|
|
606
|
+
var DEFAULT_FCA_CONFIG = {
|
|
607
|
+
autoUpdate: true,
|
|
608
|
+
checkUpdate: {
|
|
609
|
+
enabled: true,
|
|
610
|
+
install: true,
|
|
611
|
+
notifyIfCurrent: true,
|
|
612
|
+
packageName: "autobot-fca",
|
|
613
|
+
registryUrl: "https://registry.npmjs.org",
|
|
614
|
+
timeoutMs: 1e4
|
|
615
|
+
},
|
|
616
|
+
mqtt: {
|
|
617
|
+
enabled: true,
|
|
618
|
+
reconnectInterval: 3600
|
|
619
|
+
},
|
|
620
|
+
autoLogin: true,
|
|
621
|
+
apiServer: "https://donixdev.com",
|
|
622
|
+
apiKey: "",
|
|
623
|
+
credentials: {
|
|
624
|
+
email: "",
|
|
625
|
+
password: "",
|
|
626
|
+
twofactor: ""
|
|
627
|
+
},
|
|
628
|
+
antiGetInfo: {
|
|
629
|
+
AntiGetThreadInfo: false,
|
|
630
|
+
AntiGetUserInfo: false
|
|
631
|
+
},
|
|
632
|
+
remoteControl: {
|
|
633
|
+
enabled: false,
|
|
634
|
+
url: "",
|
|
635
|
+
token: "",
|
|
636
|
+
autoReconnect: true
|
|
637
|
+
},
|
|
638
|
+
threadCache: {
|
|
639
|
+
maxAgeMs: 9e5,
|
|
640
|
+
invalidateIntervalMs: 9e5
|
|
641
|
+
}
|
|
642
|
+
};
|
|
643
|
+
function resolveConfig(customConfig = {}) {
|
|
644
|
+
const merged = {
|
|
645
|
+
...DEFAULT_FCA_CONFIG,
|
|
646
|
+
...customConfig,
|
|
647
|
+
checkUpdate: {
|
|
648
|
+
...DEFAULT_FCA_CONFIG.checkUpdate,
|
|
649
|
+
...customConfig.checkUpdate || {}
|
|
650
|
+
},
|
|
651
|
+
mqtt: {
|
|
652
|
+
...DEFAULT_FCA_CONFIG.mqtt,
|
|
653
|
+
...customConfig.mqtt || {}
|
|
654
|
+
},
|
|
655
|
+
credentials: {
|
|
656
|
+
...DEFAULT_FCA_CONFIG.credentials,
|
|
657
|
+
...customConfig.credentials || {}
|
|
658
|
+
},
|
|
659
|
+
antiGetInfo: {
|
|
660
|
+
...DEFAULT_FCA_CONFIG.antiGetInfo,
|
|
661
|
+
...customConfig.antiGetInfo || {}
|
|
662
|
+
},
|
|
663
|
+
remoteControl: {
|
|
664
|
+
...DEFAULT_FCA_CONFIG.remoteControl,
|
|
665
|
+
...customConfig.remoteControl || {}
|
|
666
|
+
},
|
|
667
|
+
threadCache: {
|
|
668
|
+
...DEFAULT_FCA_CONFIG.threadCache,
|
|
669
|
+
...customConfig.threadCache || {}
|
|
670
|
+
}
|
|
671
|
+
};
|
|
672
|
+
if (customConfig.autoUpdate !== void 0) {
|
|
673
|
+
merged.autoUpdate = customConfig.autoUpdate;
|
|
674
|
+
if (merged.checkUpdate) {
|
|
675
|
+
merged.checkUpdate.enabled = customConfig.autoUpdate;
|
|
676
|
+
}
|
|
677
|
+
}
|
|
678
|
+
return merged;
|
|
679
|
+
}
|
|
680
|
+
function loadConfig(configPath) {
|
|
681
|
+
const rootDir = process.cwd();
|
|
682
|
+
const searchPaths = [
|
|
683
|
+
configPath ? import_path.default.resolve(rootDir, configPath) : null,
|
|
684
|
+
import_path.default.join(rootDir, "fca-config.json"),
|
|
685
|
+
import_path.default.join(rootDir, "fca-config.example.json")
|
|
686
|
+
].filter(Boolean);
|
|
687
|
+
for (const candidate of searchPaths) {
|
|
688
|
+
if (import_fs.default.existsSync(candidate)) {
|
|
689
|
+
try {
|
|
690
|
+
const raw = import_fs.default.readFileSync(candidate, "utf8");
|
|
691
|
+
const parsed = JSON.parse(raw);
|
|
692
|
+
return resolveConfig(parsed);
|
|
693
|
+
} catch (err) {
|
|
694
|
+
console.warn(`[autobot-fca] Failed to read config from ${candidate}:`, err);
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
}
|
|
698
|
+
return resolveConfig({});
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
// src/utils/cookie.ts
|
|
702
|
+
var COOKIE_ATTRIBUTE_KEYS = /* @__PURE__ */ new Set([
|
|
703
|
+
"domain",
|
|
704
|
+
"path",
|
|
705
|
+
"expires",
|
|
706
|
+
"max-age",
|
|
707
|
+
"secure",
|
|
708
|
+
"httponly",
|
|
709
|
+
"samesite",
|
|
710
|
+
"priority",
|
|
711
|
+
"partitioned"
|
|
712
|
+
]);
|
|
713
|
+
function toCookiePair(name, value) {
|
|
714
|
+
const cookieName = String(name || "").trim();
|
|
715
|
+
if (!cookieName) {
|
|
716
|
+
return null;
|
|
717
|
+
}
|
|
718
|
+
const cookieValue = value === void 0 || value === null ? "" : String(value).trim();
|
|
719
|
+
return `${cookieName}=${cookieValue}`;
|
|
720
|
+
}
|
|
721
|
+
function dedupeCookiePairs(pairs) {
|
|
722
|
+
const latestByName = /* @__PURE__ */ new Map();
|
|
723
|
+
for (const pair of pairs) {
|
|
724
|
+
const normalized = String(pair || "").trim();
|
|
725
|
+
const eqIndex = normalized.indexOf("=");
|
|
726
|
+
if (eqIndex <= 0) {
|
|
727
|
+
continue;
|
|
728
|
+
}
|
|
729
|
+
const name = normalized.slice(0, eqIndex).trim();
|
|
730
|
+
if (!name) {
|
|
731
|
+
continue;
|
|
732
|
+
}
|
|
733
|
+
latestByName.set(name, `${name}=${normalized.slice(eqIndex + 1).trim()}`);
|
|
734
|
+
}
|
|
735
|
+
return [...latestByName.values()];
|
|
736
|
+
}
|
|
737
|
+
function parseCookieHeaderString(raw) {
|
|
738
|
+
let header = String(raw || "").trim();
|
|
739
|
+
if (!header) {
|
|
740
|
+
return [];
|
|
741
|
+
}
|
|
742
|
+
if (/^cookie\s*:/i.test(header)) {
|
|
743
|
+
header = header.replace(/^cookie\s*:/i, "").trim();
|
|
744
|
+
}
|
|
745
|
+
const pairs = [];
|
|
746
|
+
for (const segment of header.split(/[;\r\n]+/)) {
|
|
747
|
+
const token = segment.trim();
|
|
748
|
+
const eqIndex = token.indexOf("=");
|
|
749
|
+
if (eqIndex <= 0) {
|
|
750
|
+
continue;
|
|
751
|
+
}
|
|
752
|
+
const name = token.slice(0, eqIndex).trim();
|
|
753
|
+
if (!name || COOKIE_ATTRIBUTE_KEYS.has(name.toLowerCase())) {
|
|
754
|
+
continue;
|
|
755
|
+
}
|
|
756
|
+
const value = token.slice(eqIndex + 1).trim().replace(/^"(.*)"$/, "$1");
|
|
757
|
+
const pair = toCookiePair(name, value);
|
|
758
|
+
if (pair) {
|
|
759
|
+
pairs.push(pair);
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
return dedupeCookiePairs(pairs);
|
|
763
|
+
}
|
|
764
|
+
function parseNetscapeCookieText(raw) {
|
|
765
|
+
const pairs = [];
|
|
766
|
+
const lines = String(raw || "").split(/\r?\n/);
|
|
767
|
+
for (const line of lines) {
|
|
768
|
+
const trimmed = line.trim();
|
|
769
|
+
if (!trimmed) {
|
|
770
|
+
continue;
|
|
771
|
+
}
|
|
772
|
+
const normalized = trimmed.replace(/^#HttpOnly_/, "");
|
|
773
|
+
if (normalized.startsWith("#")) {
|
|
774
|
+
continue;
|
|
775
|
+
}
|
|
776
|
+
const columns = normalized.split(" ");
|
|
777
|
+
if (columns.length < 7) {
|
|
778
|
+
continue;
|
|
779
|
+
}
|
|
780
|
+
const name = columns[5];
|
|
781
|
+
const value = columns.slice(6).join(" ");
|
|
782
|
+
const pair = toCookiePair(name, value);
|
|
783
|
+
if (pair) {
|
|
784
|
+
pairs.push(pair);
|
|
785
|
+
}
|
|
786
|
+
}
|
|
787
|
+
return dedupeCookiePairs(pairs);
|
|
788
|
+
}
|
|
789
|
+
function normalizeCookiePayload(payload) {
|
|
790
|
+
if (!payload) {
|
|
791
|
+
return null;
|
|
792
|
+
}
|
|
793
|
+
if (typeof payload === "string") {
|
|
794
|
+
const netscapePairs = parseNetscapeCookieText(payload);
|
|
795
|
+
if (netscapePairs.length) {
|
|
796
|
+
return netscapePairs.join("; ");
|
|
797
|
+
}
|
|
798
|
+
const headerPairs = parseCookieHeaderString(payload);
|
|
799
|
+
if (headerPairs.length) {
|
|
800
|
+
return headerPairs.join("; ");
|
|
801
|
+
}
|
|
802
|
+
return null;
|
|
803
|
+
}
|
|
804
|
+
if (Array.isArray(payload)) {
|
|
805
|
+
const pairs = [];
|
|
806
|
+
for (const entry of payload) {
|
|
807
|
+
if (typeof entry === "string") {
|
|
808
|
+
const stringPairs = parseCookieHeaderString(entry);
|
|
809
|
+
if (stringPairs.length) {
|
|
810
|
+
pairs.push(...stringPairs);
|
|
811
|
+
continue;
|
|
812
|
+
}
|
|
813
|
+
const eqIndex = entry.indexOf("=");
|
|
814
|
+
if (eqIndex > 0) {
|
|
815
|
+
const pair = toCookiePair(entry.slice(0, eqIndex), entry.slice(eqIndex + 1));
|
|
816
|
+
if (pair) {
|
|
817
|
+
pairs.push(pair);
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
continue;
|
|
821
|
+
}
|
|
822
|
+
if (entry && typeof entry === "object") {
|
|
823
|
+
const pair = toCookiePair(entry.name || entry.key, entry.value);
|
|
824
|
+
if (pair) {
|
|
825
|
+
pairs.push(pair);
|
|
826
|
+
}
|
|
827
|
+
}
|
|
828
|
+
}
|
|
829
|
+
const deduped = dedupeCookiePairs(pairs);
|
|
830
|
+
return deduped.length ? deduped.join("; ") : null;
|
|
831
|
+
}
|
|
832
|
+
if (typeof payload === "object") {
|
|
833
|
+
if (payload.Cookie || payload.cookie || payload.cookies) {
|
|
834
|
+
return normalizeCookiePayload(payload.Cookie || payload.cookie || payload.cookies);
|
|
835
|
+
}
|
|
836
|
+
if ((payload.name || payload.key) && Object.prototype.hasOwnProperty.call(payload, "value")) {
|
|
837
|
+
return toCookiePair(payload.name || payload.key, payload.value);
|
|
838
|
+
}
|
|
839
|
+
const pairs = [];
|
|
840
|
+
for (const [name, value] of Object.entries(payload)) {
|
|
841
|
+
if (value === void 0 || value === null || typeof value === "object") {
|
|
842
|
+
continue;
|
|
843
|
+
}
|
|
844
|
+
const pair = toCookiePair(name, value);
|
|
845
|
+
if (pair) {
|
|
846
|
+
pairs.push(pair);
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
const deduped = dedupeCookiePairs(pairs);
|
|
850
|
+
return deduped.length ? deduped.join("; ") : null;
|
|
851
|
+
}
|
|
852
|
+
return null;
|
|
853
|
+
}
|
|
854
|
+
function cookieToAppState(cookie) {
|
|
855
|
+
const normalized = normalizeCookiePayload(cookie);
|
|
856
|
+
if (!normalized) return [];
|
|
857
|
+
const pairs = parseCookieHeaderString(normalized);
|
|
858
|
+
const appState = [];
|
|
859
|
+
for (const pair of pairs) {
|
|
860
|
+
const eqIdx = pair.indexOf("=");
|
|
861
|
+
if (eqIdx > 0) {
|
|
862
|
+
const key = pair.slice(0, eqIdx);
|
|
863
|
+
const value = pair.slice(eqIdx + 1);
|
|
864
|
+
appState.push({
|
|
865
|
+
key,
|
|
866
|
+
value,
|
|
867
|
+
domain: ".facebook.com",
|
|
868
|
+
path: "/",
|
|
869
|
+
expires: Math.floor(Date.now() / 1e3) + 31536e3
|
|
870
|
+
});
|
|
871
|
+
}
|
|
872
|
+
}
|
|
873
|
+
return appState;
|
|
874
|
+
}
|
|
875
|
+
function appStateToCookie(appState) {
|
|
876
|
+
return normalizeCookiePayload(appState) || "";
|
|
877
|
+
}
|
|
878
|
+
function toNetscapeCookieText(cookies) {
|
|
879
|
+
const appState = Array.isArray(cookies) ? cookies : cookieToAppState(cookies);
|
|
880
|
+
const lines = [
|
|
881
|
+
"# Netscape HTTP Cookie File",
|
|
882
|
+
"# https://curl.haxx.se/rfc/cookie_spec.html",
|
|
883
|
+
"# This file was generated by autobot-fca"
|
|
884
|
+
];
|
|
885
|
+
for (const c of appState) {
|
|
886
|
+
const domain = c.domain || ".facebook.com";
|
|
887
|
+
const flag = domain.startsWith(".") ? "TRUE" : "FALSE";
|
|
888
|
+
const path2 = c.path || "/";
|
|
889
|
+
const secure = "TRUE";
|
|
890
|
+
const expiration = c.expires || Math.floor(Date.now() / 1e3) + 31536e3;
|
|
891
|
+
const name = c.key || c.name || "";
|
|
892
|
+
const value = c.value || "";
|
|
893
|
+
if (name) {
|
|
894
|
+
lines.push(`${domain} ${flag} ${path2} ${secure} ${expiration} ${name} ${value}`);
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
return lines.join("\n");
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
// src/index.ts
|
|
901
|
+
var defaultExport = Object.assign(login, {
|
|
902
|
+
login,
|
|
903
|
+
createMessengerBot,
|
|
904
|
+
createFcaClient,
|
|
905
|
+
attachClientFacade,
|
|
906
|
+
resolveConfig,
|
|
907
|
+
loadConfig,
|
|
908
|
+
DEFAULT_FCA_CONFIG,
|
|
909
|
+
toCookiePair,
|
|
910
|
+
dedupeCookiePairs,
|
|
911
|
+
parseCookieHeaderString,
|
|
912
|
+
parseNetscapeCookieText,
|
|
913
|
+
normalizeCookiePayload,
|
|
914
|
+
cookieToAppState,
|
|
915
|
+
appStateToCookie,
|
|
916
|
+
toNetscapeCookieText
|
|
917
|
+
});
|
|
918
|
+
var index_default = defaultExport;
|
|
919
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
920
|
+
0 && (module.exports = {
|
|
921
|
+
DEFAULT_FCA_CONFIG,
|
|
922
|
+
appStateToCookie,
|
|
923
|
+
attachClientFacade,
|
|
924
|
+
cookieToAppState,
|
|
925
|
+
createFcaClient,
|
|
926
|
+
createMessengerBot,
|
|
927
|
+
dedupeCookiePairs,
|
|
928
|
+
loadConfig,
|
|
929
|
+
login,
|
|
930
|
+
normalizeCookiePayload,
|
|
931
|
+
parseCookieHeaderString,
|
|
932
|
+
parseNetscapeCookieText,
|
|
933
|
+
resolveConfig,
|
|
934
|
+
toCookiePair,
|
|
935
|
+
toNetscapeCookieText
|
|
936
|
+
});
|