@dongdev/fca-unofficial
Version:
Unofficial Facebook Chat API for Node.js - Interact with Facebook Messenger programmatically
1,396 lines (1,381 loc) • 1.03 MB
JavaScript
var __create = Object.create;
var __defProp = Object.defineProperty;
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
var __getOwnPropNames = Object.getOwnPropertyNames;
var __getProtoOf = Object.getPrototypeOf;
var __hasOwnProp = Object.prototype.hasOwnProperty;
var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
}) : x)(function(x) {
if (typeof require !== "undefined") return require.apply(this, arguments);
throw Error('Dynamic require of "' + x + '" is not supported');
});
var __esm = (fn, res) => function __init() {
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
};
var __commonJS = (cb, mod) => function __require2() {
return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
};
var __export = (target, all) => {
for (var name in all)
__defProp(target, name, { get: all[name], enumerable: true });
};
var __copyProps = (to, from, except, desc) => {
if (from && typeof from === "object" || typeof from === "function") {
for (let key of __getOwnPropNames(from))
if (!__hasOwnProp.call(to, key) && key !== except)
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
}
return to;
};
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
// If the importer is in node compatibility mode or this is not an ESM
// file that has been converted to a CommonJS file using a Babel-
// compatible transform (i.e. "__esModule" has not been set), then set
// "default" to the CommonJS "module.exports" for node compatibility.
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
mod
));
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
// src/func/logger.ts
import pc from "picocolors";
import gradient from "gradient-string";
function writeStdout(message) {
process.stdout.write(`${message}
`);
}
function writeStderr(message) {
process.stderr.write(`${message}
`);
}
function padLabel(label, width = 8) {
return label.length >= width ? label : `${label}${" ".repeat(width - label.length)}`;
}
function getTimestamp() {
const now = /* @__PURE__ */ new Date();
const hh = String(now.getHours()).padStart(2, "0");
const mm = String(now.getMinutes()).padStart(2, "0");
const ss = String(now.getSeconds()).padStart(2, "0");
return `${hh}:${mm}:${ss}`;
}
function getTheme() {
const fromEnv = String(process.env.FCA_LOG_THEME || "").toLowerCase();
if (fromEnv === "minimal") return "minimal";
return "cyberpunk";
}
function makeStyles(theme) {
if (theme === "minimal") {
return {
time: (v) => pc.dim(v),
text: (v) => pc.white(v),
info: (v) => pc.cyan(v),
warn: (v) => pc.yellow(v),
error: (v) => pc.red(v),
sys: (v) => pc.blue(v)
};
}
return {
time: (v) => pc.dim(v),
text: (v) => pc.white(v),
info: (v) => pc.cyan(v),
warn: (v) => pc.yellow(v),
error: (v) => pc.red(v),
sys: (v) => pc.blue(v)
};
}
function parseLabel(message, fallback) {
const m = message.match(/^([A-Z][A-Z0-9 _-]{1,14})\s*:\s*(.+)$/);
if (!m) return { label: fallback, body: message };
return { label: m[1].trim(), body: m[2] };
}
function loadGradientFns() {
if (gradientFns !== void 0) return gradientFns;
try {
const g3 = typeof gradient === "function" ? gradient : gradient.default;
if (typeof g3 !== "function") {
gradientFns = null;
return gradientFns;
}
gradientFns = {
cyberpunk: g3("magenta", "cyan"),
blueToRed: g3("#3b82f6", "#ef4444"),
coolStatus: g3("#86efac", "#22d3ee")
};
} catch {
gradientFns = null;
}
return gradientFns;
}
function formatSuccessBody(body, grad, fallbackPaint) {
const m = body.match(/^Loaded (\d+) API methods(.*)$/i);
if (m && grad) {
return `${pc.dim("Loaded ")}${grad.blueToRed(m[1])}${pc.dim(` API methods${m[2]}`)}`;
}
return fallbackPaint(body);
}
async function ensureUiLibs() {
if (!oraFactory) {
try {
const oraMod = await import("ora");
oraFactory = oraMod.default ?? oraMod;
} catch {
}
}
if (!progressCtor || !progressPreset) {
try {
const progressMod = await import("cli-progress");
progressCtor = progressMod.SingleBar ?? progressMod.default?.SingleBar;
progressPreset = progressMod.Presets?.shades_classic ?? progressMod.default?.Presets?.shades_classic ?? null;
} catch {
}
}
}
function logLine(text, type) {
const level = String(type || "info").toLowerCase();
const message = String(text ?? "");
const styles = makeStyles(getTheme());
const ts = styles.time(`[${getTimestamp()}]`);
const theme = getTheme();
const grad = theme === "cyberpunk" ? loadGradientFns() : null;
if (level === "success") {
const parts2 = parseLabel(message, "READY");
const bodyOut2 = parts2.label === "READY" ? formatSuccessBody(parts2.body, grad, styles.text) : grad ? grad.coolStatus(parts2.body) : styles.text(parts2.body);
const labelOut2 = grad ? grad.coolStatus(padLabel(parts2.label)) : styles.text(padLabel(parts2.label));
writeStdout(`${ts} ${pc.bgGreen(pc.black(pc.bold(" SUCCESS ")))} ${labelOut2} : ${bodyOut2}`);
return;
}
if (level === "warn") {
const parts2 = parseLabel(message, "WARN");
writeStderr(`${ts} ${styles.text(padLabel(parts2.label))} : ${styles.warn(parts2.body)}`);
return;
}
if (level === "error") {
const parts2 = parseLabel(message, "ERROR");
writeStderr(`${ts} ${styles.text(padLabel(parts2.label))} : ${styles.error(parts2.body)}`);
return;
}
if (level === "sys" || level === "system" || level === "core") {
const parts2 = parseLabel(message, "SYSTEM");
const labelOut2 = grad ? grad.blueToRed(padLabel(parts2.label)) : styles.text(padLabel(parts2.label));
const bodyOut2 = grad ? pc.dim(pc.blue(parts2.body)) : styles.sys(parts2.body);
writeStdout(`${ts} ${labelOut2} : ${bodyOut2}`);
return;
}
const parts = parseLabel(message, "SESSION");
const labelOut = grad ? grad.coolStatus(padLabel(parts.label)) : styles.text(padLabel(parts.label));
const bodyOut = grad ? grad.coolStatus(parts.body) : styles.info(parts.body);
writeStdout(`${ts} ${labelOut} : ${bodyOut}`);
}
var oraFactory, progressCtor, progressPreset, gradientFns, baseLogger, logger_default;
var init_logger = __esm({
"src/func/logger.ts"() {
"use strict";
oraFactory = null;
progressCtor = null;
progressPreset = null;
baseLogger = logLine;
baseLogger.fca = (text) => baseLogger(`SESSION: ${text}`, "info");
baseLogger.sys = (text) => baseLogger(`SYSTEM: ${text}`, "sys");
baseLogger.success = (text) => baseLogger(text, "success");
baseLogger.warn = (text) => baseLogger(text, "warn");
baseLogger.error = (text) => baseLogger(text, "error");
baseLogger.showBanner = async () => {
};
baseLogger.startSpinner = async (text) => {
await ensureUiLibs();
if (!oraFactory || !process.stdout.isTTY) return null;
const grad = getTheme() === "cyberpunk" ? loadGradientFns() : null;
const line = grad ? grad.cyberpunk(text) : pc.cyan(text);
const spinner = oraFactory({
text: line,
color: "cyan"
});
return typeof spinner.start === "function" ? spinner.start() : spinner;
};
baseLogger.runMethodLoadProgress = async (loaded) => {
await ensureUiLibs();
if (!progressCtor || !process.stdout.isTTY || loaded <= 0) return;
const grad = getTheme() === "cyberpunk" ? loadGradientFns() : null;
const prefix = grad ? grad.cyberpunk("fca \xB7 methods") : pc.cyan("fca \xB7 methods");
const bar = new progressCtor(
{
format: `${prefix} |{bar}| {percentage}% | {value}/{total}`,
barCompleteChar: "\u2588",
barIncompleteChar: "\u2591",
hideCursor: true
},
progressPreset ?? void 0
);
bar.start(loaded, 0);
for (let i = 1; i <= loaded; i += 1) {
bar.update(i);
}
bar.stop();
};
baseLogger.persistCheckpointOk = (spinner) => {
if (spinner && typeof spinner.stop === "function") {
spinner.stop();
}
baseLogger("SESSION: No checkpoint detected", "info");
};
baseLogger.persistLoginSuccess = (spinner) => {
if (spinner && typeof spinner.stop === "function") {
spinner.stop();
}
};
baseLogger.persistLoginFail = (spinner) => {
if (spinner && typeof spinner.stop === "function") {
spinner.stop();
}
};
logger_default = baseLogger;
}
});
// src/utils/format/attachment.ts
import querystring from "querystring";
import url from "url";
var require_attachment = __commonJS({
"src/utils/format/attachment.ts"(exports, module) {
"use strict";
function _formatAttachment2(attachment1, attachment2) {
attachment2 = attachment2 || { id: "", image_data: {} };
attachment1 = attachment1.mercury ? attachment1.mercury : attachment1;
var blob = attachment1.blob_attachment;
var type = blob && blob.__typename ? blob.__typename : attachment1.attach_type;
if (!type && attachment1.sticker_attachment) {
type = "StickerAttachment";
blob = attachment1.sticker_attachment;
} else if (!type && attachment1.extensible_attachment) {
if (attachment1.extensible_attachment.story_attachment && attachment1.extensible_attachment.story_attachment.target && attachment1.extensible_attachment.story_attachment.target.__typename && attachment1.extensible_attachment.story_attachment.target.__typename === "MessageLocation")
type = "MessageLocation";
else type = "ExtensibleAttachment";
blob = attachment1.extensible_attachment;
}
if (blob && blob.real_metadata) {
const realMetadata = blob.real_metadata;
if (realMetadata.Src) {
attachment2.src = realMetadata.Src;
}
if (realMetadata.ThumbnailSrc) {
attachment2.thumbnailSrc = realMetadata.ThumbnailSrc;
}
}
switch (type) {
case "sticker":
return {
type: "sticker",
ID: attachment1.metadata.stickerID.toString(),
url: attachment1.url,
packID: attachment1.metadata.packID.toString(),
spriteUrl: attachment1.metadata.spriteURI,
spriteUrl2x: attachment1.metadata.spriteURI2x,
width: attachment1.metadata.width,
height: attachment1.metadata.height,
caption: attachment2.caption,
description: attachment2.description,
frameCount: attachment1.metadata.frameCount,
frameRate: attachment1.metadata.frameRate,
framesPerRow: attachment1.metadata.framesPerRow,
framesPerCol: attachment1.metadata.framesPerCol,
stickerID: attachment1.metadata.stickerID.toString(),
spriteURI: attachment1.metadata.spriteURI,
spriteURI2x: attachment1.metadata.spriteURI2x
};
case "file":
return {
type: "file",
filename: attachment1.name,
ID: attachment2.id.toString(),
url: attachment1.url,
isMalicious: attachment2.is_malicious,
contentType: attachment2.mime_type,
name: attachment1.name,
mimeType: attachment2.mime_type,
fileSize: attachment2.file_size
};
case "photo":
return {
type: "photo",
ID: attachment1.metadata.fbid.toString(),
filename: attachment1.fileName,
thumbnailUrl: attachment1.thumbnail_url,
previewUrl: attachment1.preview_url,
previewWidth: attachment1.preview_width,
previewHeight: attachment1.preview_height,
largePreviewUrl: attachment1.large_preview_url,
largePreviewWidth: attachment1.large_preview_width,
largePreviewHeight: attachment1.large_preview_height,
url: attachment1.metadata.url,
width: attachment1.metadata.dimensions.split(",")[0],
height: attachment1.metadata.dimensions.split(",")[1],
name: attachment1.fileName
};
case "animated_image":
return {
type: "animated_image",
ID: attachment2.id.toString(),
filename: attachment2.filename,
previewUrl: attachment1.preview_url,
previewWidth: attachment1.preview_width,
previewHeight: attachment1.preview_height,
url: attachment2.image_data.url,
width: attachment2.image_data.width,
height: attachment2.image_data.height,
name: attachment1.name,
facebookUrl: attachment1.url,
thumbnailUrl: attachment1.thumbnail_url,
mimeType: attachment2.mime_type,
rawGifImage: attachment2.image_data.raw_gif_image,
rawWebpImage: attachment2.image_data.raw_webp_image,
animatedGifUrl: attachment2.image_data.animated_gif_url,
animatedGifPreviewUrl: attachment2.image_data.animated_gif_preview_url,
animatedWebpUrl: attachment2.image_data.animated_webp_url,
animatedWebpPreviewUrl: attachment2.image_data.animated_webp_preview_url
};
case "share":
return {
type: "share",
ID: attachment1.share.share_id.toString(),
url: attachment2.href,
title: attachment1.share.title,
description: attachment1.share.description,
source: attachment1.share.source,
image: attachment1.share.media.image,
width: attachment1.share.media.image_size.width,
height: attachment1.share.media.image_size.height,
playable: attachment1.share.media.playable,
duration: attachment1.share.media.duration,
subattachments: attachment1.share.subattachments,
properties: {},
animatedImageSize: attachment1.share.media.animated_image_size,
facebookUrl: attachment1.share.uri,
target: attachment1.share.target,
styleList: attachment1.share.style_list
};
case "video":
return {
type: "video",
ID: attachment1.metadata.fbid.toString(),
filename: attachment1.name,
previewUrl: attachment1.preview_url,
previewWidth: attachment1.preview_width,
previewHeight: attachment1.preview_height,
url: attachment1.url,
width: attachment1.metadata.dimensions.width,
height: attachment1.metadata.dimensions.height,
duration: attachment1.metadata.duration,
videoType: "unknown",
thumbnailUrl: attachment1.thumbnail_url
};
case "error":
return {
type: "error",
attachment1,
attachment2
};
case "MessageImage":
return {
type: "photo",
ID: blob.legacy_attachment_id,
filename: blob.filename,
thumbnailUrl: blob.thumbnail.uri,
previewUrl: blob.preview.uri,
previewWidth: blob.preview.width,
previewHeight: blob.preview.height,
largePreviewUrl: blob.large_preview.uri,
largePreviewWidth: blob.large_preview.width,
largePreviewHeight: blob.large_preview.height,
url: blob.large_preview.uri,
width: blob.original_dimensions.x,
height: blob.original_dimensions.y,
name: blob.filename
};
case "MessageAnimatedImage":
return {
type: "animated_image",
ID: blob.legacy_attachment_id,
filename: blob.filename,
previewUrl: blob.preview_image.uri,
previewWidth: blob.preview_image.width,
previewHeight: blob.preview_image.height,
url: blob.animated_image.uri,
width: blob.animated_image.width,
height: blob.animated_image.height,
thumbnailUrl: blob.preview_image.uri,
name: blob.filename,
facebookUrl: blob.animated_image.uri,
rawGifImage: blob.animated_image.uri,
animatedGifUrl: blob.animated_image.uri,
animatedGifPreviewUrl: blob.preview_image.uri,
animatedWebpUrl: blob.animated_image.uri,
animatedWebpPreviewUrl: blob.preview_image.uri
};
case "MessageVideo":
return {
type: "video",
filename: blob.filename,
ID: blob.legacy_attachment_id,
previewUrl: blob.large_image.uri,
previewWidth: blob.large_image.width,
previewHeight: blob.large_image.height,
url: blob.playable_url,
width: blob.original_dimensions.x,
height: blob.original_dimensions.y,
duration: blob.playable_duration_in_ms,
videoType: blob.video_type.toLowerCase(),
thumbnailUrl: blob.large_image.uri
};
case "MessageAudio":
return {
type: "audio",
filename: blob.filename,
ID: blob.url_shimhash,
audioType: blob.audio_type,
duration: blob.playable_duration_in_ms,
url: blob.playable_url,
isVoiceMail: blob.is_voicemail
};
case "StickerAttachment":
return {
type: "sticker",
ID: blob.id,
url: blob.url,
packID: blob.pack ? blob.pack.id : null,
spriteUrl: blob.sprite_image,
spriteUrl2x: blob.sprite_image_2x,
width: blob.width,
height: blob.height,
caption: blob.label,
description: blob.label,
frameCount: blob.frame_count,
frameRate: blob.frame_rate,
framesPerRow: blob.frames_per_row,
framesPerCol: blob.frames_per_column,
stickerID: blob.id,
spriteURI: blob.sprite_image,
spriteURI2x: blob.sprite_image_2x
};
case "MessageLocation": {
var urlAttach = blob.story_attachment.url;
var mediaAttach = blob.story_attachment.media;
const q0 = url.parse(String(urlAttach)).query;
const uRaw = querystring.parse(typeof q0 === "string" ? q0 : "").u;
const uPart = Array.isArray(uRaw) ? uRaw[0] : uRaw;
const u = uPart != null ? String(uPart) : "";
const q1 = url.parse(u).query;
const where1Raw = querystring.parse(typeof q1 === "string" ? q1 : "").where1;
const where1 = Array.isArray(where1Raw) ? where1Raw[0] : where1Raw;
const whereStr = typeof where1 === "string" ? where1 : "";
var address = whereStr.split(", ");
var latitude;
var longitude;
try {
latitude = Number.parseFloat(address[0]);
longitude = Number.parseFloat(address[1]);
} catch (err) {
}
var imageUrl;
var width;
var height;
if (mediaAttach && mediaAttach.image) {
imageUrl = mediaAttach.image.uri;
width = mediaAttach.image.width;
height = mediaAttach.image.height;
}
return {
type: "location",
ID: blob.legacy_attachment_id,
latitude,
longitude,
image: imageUrl,
width,
height,
url: u || urlAttach,
address: whereStr,
facebookUrl: blob.story_attachment.url,
target: blob.story_attachment.target,
styleList: blob.story_attachment.style_list
};
}
case "ExtensibleAttachment":
return {
type: "share",
ID: blob.legacy_attachment_id,
url: blob.story_attachment.url,
title: blob.story_attachment.title_with_entities.text,
description: blob.story_attachment.description && blob.story_attachment.description.text,
source: blob.story_attachment.source ? blob.story_attachment.source.text : null,
image: blob.story_attachment.media && blob.story_attachment.media.image && blob.story_attachment.media.image.uri,
width: blob.story_attachment.media && blob.story_attachment.media.image && blob.story_attachment.media.image.width,
height: blob.story_attachment.media && blob.story_attachment.media.image && blob.story_attachment.media.image.height,
playable: blob.story_attachment.media && blob.story_attachment.media.is_playable,
duration: blob.story_attachment.media && blob.story_attachment.media.playable_duration_in_ms,
playableUrl: blob.story_attachment.media == null ? null : blob.story_attachment.media.playable_url,
subattachments: blob.story_attachment.subattachments,
properties: blob.story_attachment.properties.reduce(
function(obj, cur) {
const row = cur;
if (row.key) obj[row.key] = row.value?.text;
return obj;
},
{}
),
facebookUrl: blob.story_attachment.url,
target: blob.story_attachment.target,
styleList: blob.story_attachment.style_list
};
case "MessageFile":
return {
type: "file",
filename: blob.filename,
ID: blob.message_file_fbid,
url: blob.url,
isMalicious: blob.is_malicious,
contentType: blob.content_type,
name: blob.filename,
mimeType: "",
fileSize: -1
};
default:
throw new Error(
"unrecognized attach_file of type " + type + "`" + JSON.stringify(attachment1, null, 4) + " attachment2: " + JSON.stringify(attachment2, null, 4) + "`"
);
}
}
function formatAttachment(attachments, attachmentIds, attachmentMap, shareMap) {
const map = shareMap || attachmentMap;
return attachments ? attachments.map(function(att, idx) {
if (!map || !attachmentIds || !map[attachmentIds[idx]]) {
return _formatAttachment2(att, void 0);
}
return _formatAttachment2(att, map[attachmentIds[idx]]);
}) : [];
}
module.exports = {
_formatAttachment: _formatAttachment2,
formatAttachment
};
}
});
// src/utils/format/cookie.ts
var require_cookie = __commonJS({
"src/utils/format/cookie.ts"(exports, module) {
"use strict";
function formatCookie2(arr, urlBase) {
return `${arr[0]}=${arr[1]}; Path=${arr[3]}; Domain=${urlBase}.com`;
}
module.exports = {
formatCookie: formatCookie2
};
}
});
// src/utils/format/date.ts
var require_date = __commonJS({
"src/utils/format/date.ts"(exports, module) {
"use strict";
var NUM_TO_MONTH = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"];
var NUM_TO_DAY = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
function formatDate(date) {
let d = date.getUTCDate();
d = d >= 10 ? d : "0" + d;
let h = date.getUTCHours();
h = h >= 10 ? h : "0" + h;
let m = date.getUTCMinutes();
m = m >= 10 ? m : "0" + m;
let s = date.getUTCSeconds();
s = s >= 10 ? s : "0" + s;
return `${NUM_TO_DAY[date.getUTCDay()]}, ${d} ${NUM_TO_MONTH[date.getUTCMonth()]} ${date.getUTCFullYear()} ${h}:${m}:${s} GMT`;
}
module.exports = {
NUM_TO_MONTH,
NUM_TO_DAY,
formatDate
};
}
});
// src/utils/format/decode.ts
var require_decode = __commonJS({
"src/utils/format/decode.ts"(exports, module) {
"use strict";
function decodeClientPayload(payload) {
function utf8ArrayToStr(array) {
let out = "";
const len = array.length;
let i = 0;
while (i < len) {
const c = array[i++];
let char2;
let char3;
switch (c >> 4) {
case 0:
case 1:
case 2:
case 3:
case 4:
case 5:
case 6:
case 7:
out += String.fromCharCode(c);
break;
case 12:
case 13:
char2 = array[i++];
out += String.fromCharCode((c & 31) << 6 | char2 & 63);
break;
case 14:
char2 = array[i++];
char3 = array[i++];
out += String.fromCharCode((c & 15) << 12 | (char2 & 63) << 6 | char3 & 63);
break;
}
}
return out;
}
return JSON.parse(utf8ArrayToStr(payload));
}
module.exports = {
decodeClientPayload
};
}
});
// src/utils/format/utils.ts
function getType(obj) {
return Object.prototype.toString.call(obj).slice(8, -1);
}
function formatID(id) {
if (id !== void 0 && id !== null) return id.replace(/(fb)?id[:.]/, "");
return id;
}
function padZeros(val, len = 2) {
let out = String(val);
while (out.length < len) out = "0" + out;
return out;
}
function arrayToObject(arr, getKey, getValue) {
return arr.reduce((acc, val) => {
acc[getKey(val)] = getValue(val);
return acc;
}, {});
}
function arrToForm(form) {
return arrayToObject(
form,
(v) => v.name,
(v) => v.val
);
}
function getData_Path(Obj, Arr, Stt) {
if (Arr.length === 0 && Obj !== void 0) {
return Obj;
}
if (Obj === void 0) {
return Stt;
}
const head = Arr[0];
if (head === void 0) {
return Stt;
}
const tail = Arr.slice(1);
return getData_Path(Obj[head], tail, Stt++);
}
function setData_Path(obj, path5, value) {
if (!path5.length) {
return obj;
}
const currentKey = path5[0];
let currentObj = obj[currentKey];
if (!currentObj) {
obj[currentKey] = value;
currentObj = obj[currentKey];
}
path5.shift();
if (!path5.length) {
currentObj = value;
} else {
currentObj = setData_Path(currentObj, path5, value);
}
return obj;
}
function getPaths(obj, parentPath = []) {
let paths = [];
for (const prop in obj) {
if (typeof obj[prop] === "object" && obj[prop] !== null) {
paths = paths.concat(getPaths(obj[prop], [...parentPath, prop]));
} else {
paths.push([...parentPath, prop]);
}
}
return paths;
}
function cleanHTML(text) {
let out = text;
out = out.replace(
/(<br>)|(<\/?i>)|(<\/?em>)|(<\/?b>)|(!?~)|(&)|(')|(<)|(>)|(")/g,
(match) => {
switch (match) {
case "<br>":
return "\n";
case "<i>":
case "<em>":
case "</i>":
case "</em>":
return "*";
case "<b>":
case "</b>":
return "**";
case "~!":
case "!~":
return "||";
case "&":
return "&";
case "'":
return "'";
case "<":
return "<";
case ">":
return ">";
case """:
return '"';
default:
return match;
}
}
);
return out;
}
function getCurrentTimestamp() {
return Date.now();
}
function getSignatureID() {
return Math.floor(Math.random() * 2147483648).toString(16);
}
var init_utils = __esm({
"src/utils/format/utils.ts"() {
"use strict";
}
});
// src/utils/format/delta.ts
var require_delta = __commonJS({
"src/utils/format/delta.ts"(exports, module) {
"use strict";
var import_attachment = __toESM(require_attachment());
init_utils();
var { _formatAttachment: _formatAttachment2 } = import_attachment.default;
function getAdminTextMessageType2(m) {
const type = m && (m.type || m);
switch (type) {
case "joinable_group_link_mode_change":
return "log:link-status";
case "magic_words":
return "log:magic-words";
case "change_thread_theme":
return "log:thread-color";
case "change_thread_icon":
case "change_thread_quick_reaction":
return "log:thread-icon";
case "change_thread_nickname":
return "log:user-nickname";
case "change_thread_admins":
return "log:thread-admins";
case "group_poll":
return "log:thread-poll";
case "change_thread_approval_mode":
return "log:thread-approval-mode";
case "messenger_call_log":
case "participant_joined_group_call":
return "log:thread-call";
case "pin_messages_v2":
return "log:thread-pinned";
case "unpin_messages_v2":
return "log:unpin-message";
default:
return m && m.type != null ? m.type : type;
}
}
function formatDeltaEvent(m) {
var logMessageType;
var logMessageData;
switch (m.class) {
case "AdminTextMessage":
logMessageType = getAdminTextMessageType2(m);
logMessageData = m.untypedData;
break;
case "ThreadName":
logMessageType = "log:thread-name";
logMessageData = { name: m.name };
break;
case "ParticipantsAddedToGroupThread":
logMessageType = "log:subscribe";
logMessageData = { addedParticipants: m.addedParticipants };
break;
case "ParticipantLeftGroupThread":
logMessageType = "log:unsubscribe";
logMessageData = { leftParticipantFbId: m.leftParticipantFbId };
break;
case "UserLocation": {
logMessageType = "log:user-location";
logMessageData = {
Image: m.attachments[0].mercury.extensible_attachment.story_attachment.media.image,
Location: m.attachments[0].mercury.extensible_attachment.story_attachment.target.location_title,
coordinates: m.attachments[0].mercury.extensible_attachment.story_attachment.target.coordinate,
url: m.attachments[0].mercury.extensible_attachment.story_attachment.url
};
}
case "ApprovalQueue":
logMessageType = "log:approval-queue";
logMessageData = {
approvalQueue: {
action: m.action,
recipientFbId: m.recipientFbId,
requestSource: m.requestSource,
...m.messageMetadata
}
};
}
return {
type: "event",
threadID: formatID(
(m.messageMetadata.threadKey.threadFbId || m.messageMetadata.threadKey.otherUserFbId).toString()
),
logMessageType,
logMessageData,
logMessageBody: m.messageMetadata.adminText,
author: m.messageMetadata.actorFbId,
participantIDs: (m?.participants || []).map((e) => String(e))
};
}
function getMentionsFromDeltaMessage(m) {
var body = m.body || "";
var mentions = {};
var mdata = [];
if (m.data && m.data.prng) {
try {
mdata = JSON.parse(m.data.prng);
} catch (e) {
mdata = [];
}
}
if (mdata.length > 0) {
for (var i = 0; i < mdata.length; i++) {
const row = mdata[i];
var mentionId = row.i;
var o = parseInt(String(row.o ?? ""), 10) || 0;
var l = parseInt(String(row.l ?? ""), 10) || 0;
mentions[String(mentionId)] = body.substring(o, o + l);
}
return mentions;
}
var md = m.messageMetadata;
if (md && md.data && md.data.data && md.data.data.Gb && md.data.data.Gb.asMap && md.data.data.Gb.asMap.data) {
var gbData = md.data.data.Gb.asMap.data;
for (var key in gbData) {
if (!Object.prototype.hasOwnProperty.call(gbData, key)) continue;
var entry = gbData[key];
if (entry && entry.asMap && entry.asMap.data) {
var d = entry.asMap.data;
var midId = d.id && d.id.asLong ? String(d.id.asLong) : null;
var offset = parseInt(
String(d.offset && d.offset.asLong ? d.offset.asLong : 0),
10
);
var len = parseInt(
String(d.length && d.length.asLong ? d.length.asLong : 0),
10
);
if (midId != null) {
mentions[midId] = body.substring(offset, offset + len);
}
}
}
}
return mentions;
}
function formatDeltaMessage(m) {
var md = m.messageMetadata;
var body = m.body || "";
var mentions = getMentionsFromDeltaMessage(m);
var args = body === "" ? [] : body.trim().split(/\s+/);
return {
type: "message",
senderID: formatID(md.actorFbId.toString()),
threadID: formatID(
(md.threadKey.threadFbId || md.threadKey.otherUserFbId).toString()
),
messageID: md.messageId,
args,
body,
attachments: (m.attachments || []).map((v) => _formatAttachment2(v, void 0)),
mentions,
timestamp: md.timestamp,
isGroup: !!md.threadKey.threadFbId,
participantIDs: (m.participants || []).map((p) => formatID(p.toString())),
isUnread: md.isUnread !== void 0 ? md.isUnread : false
};
}
function formatDeltaReadReceipt(delta) {
return {
reader: (delta.threadKey.otherUserFbId || delta.actorFbId).toString(),
time: delta.actionTimestampMs,
threadID: formatID(
(delta.threadKey.otherUserFbId || delta.threadKey.threadFbId).toString()
),
type: "read_receipt"
};
}
module.exports = {
getAdminTextMessageType: getAdminTextMessageType2,
formatDeltaEvent,
formatDeltaMessage,
getMentionsFromDeltaMessage,
formatDeltaReadReceipt
};
}
});
// src/utils/format/ids.ts
var require_ids = __commonJS({
"src/utils/format/ids.ts"(exports, module) {
"use strict";
init_utils();
function binaryToDecimal(data) {
let ret = "";
while (data !== "0") {
let end = 0;
let fullName = "";
for (let i = 0; i < data.length; i++) {
end = 2 * end + parseInt(data[i], 10);
if (end >= 10) {
fullName += "1";
end -= 10;
} else {
fullName += "0";
}
}
ret = end.toString() + ret;
data = fullName.slice(fullName.indexOf("1"));
}
return ret;
}
function generateOfflineThreadingID2() {
const ret = Date.now();
const value = Math.floor(Math.random() * 4294967295);
const str = ("0000000000000000000000" + value.toString(2)).slice(-22);
const msgs = ret.toString(2) + str;
return binaryToDecimal(msgs);
}
function generateThreadingID2(clientID) {
const k = Date.now();
const l = Math.floor(Math.random() * 4294967295);
return `<${k}:${l}-${clientID}@mail.projektitan.com>`;
}
function getGUID() {
let sectionLength = Date.now();
const id = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
const r = Math.floor((sectionLength + Math.random() * 16) % 16);
sectionLength = Math.floor(sectionLength / 16);
const guid = (c === "x" ? r : r & 7 | 8).toString(16);
return guid;
});
return id;
}
function generateTimestampRelative2() {
const d = /* @__PURE__ */ new Date();
return `${d.getHours()}:${padZeros(d.getMinutes())}`;
}
module.exports = {
binaryToDecimal,
generateOfflineThreadingID: generateOfflineThreadingID2,
generateThreadingID: generateThreadingID2,
getGUID,
generateTimestampRelative: generateTimestampRelative2
};
}
});
// src/utils/format/message.ts
var require_message = __commonJS({
"src/utils/format/message.ts"(exports, module) {
"use strict";
var import_attachment = __toESM(require_attachment());
var import_delta = __toESM(require_delta());
init_utils();
var { formatAttachment } = import_attachment.default;
var { getAdminTextMessageType: getAdminTextMessageType2 } = import_delta.default;
function formatMessage2(m) {
var originalMessage = m.message ? m.message : m;
var body = originalMessage.body || "";
var args = body == "" ? [] : body.trim().split(/\s+/);
const obj = {
type: "message",
senderName: originalMessage.sender_name,
senderID: formatID(originalMessage.sender_fbid.toString()),
participantNames: originalMessage.group_thread_info ? originalMessage.group_thread_info.participant_names : [originalMessage.sender_name.split(" ")[0]],
participantIDs: originalMessage.group_thread_info ? originalMessage.group_thread_info.participant_ids.map(function(v) {
return formatID(v.toString());
}) : [formatID(originalMessage.sender_fbid)],
body,
args,
threadID: formatID(
(originalMessage.thread_fbid || originalMessage.other_user_fbid).toString()
),
threadName: originalMessage.group_thread_info ? originalMessage.group_thread_info.name : originalMessage.sender_name,
location: originalMessage.coordinates ? originalMessage.coordinates : null,
messageID: originalMessage.mid ? originalMessage.mid.toString() : originalMessage.message_id,
attachments: formatAttachment(
originalMessage.attachments,
originalMessage.attachmentIds,
originalMessage.attachment_map,
originalMessage.share_map
),
timestamp: originalMessage.timestamp,
timestampAbsolute: originalMessage.timestamp_absolute,
timestampRelative: originalMessage.timestamp_relative,
timestampDatetime: originalMessage.timestamp_datetime,
tags: originalMessage.tags,
reactions: originalMessage.reactions ? originalMessage.reactions : [],
isUnread: originalMessage.is_unread
};
if (m.type === "pages_messaging")
obj.pageID = m.realtime_viewer_fbid.toString();
obj.isGroup = obj.participantIDs.length > 2;
return obj;
}
function formatEvent(m) {
var originalMessage = m.message ? m.message : m;
var logMessageType = originalMessage.log_message_type;
var logMessageData;
if (logMessageType === "log:generic-admin-text") {
logMessageData = originalMessage.log_message_data.untypedData;
logMessageType = getAdminTextMessageType2(
originalMessage.log_message_data.message_type
);
} else logMessageData = originalMessage.log_message_data;
return Object.assign(formatMessage2(originalMessage), {
type: "event",
logMessageType,
logMessageData,
logMessageBody: originalMessage.log_message_body
});
}
function formatHistoryMessage(m) {
switch (m.action_type) {
case "ma-type:log-message":
return formatEvent(m);
default:
return formatMessage2(m);
}
}
module.exports = {
formatMessage: formatMessage2,
formatEvent,
formatHistoryMessage
};
}
});
// src/utils/format/presence.ts
var require_presence = __commonJS({
"src/utils/format/presence.ts"(exports, module) {
"use strict";
var PRESENCE_MAP = {
_: "%",
A: "%2",
B: "000",
C: "%7d",
D: "%7b%22",
E: "%2c%22",
F: "%22%3a",
G: "%2c%22ut%22%3a1",
H: "%2c%22bls%22%3a",
I: "%2c%22n%22%3a%22%",
J: "%22%3a%7b%22i%22%3a0%7d",
K: "%2c%22pt%22%3a0%2c%22vis%22%3a",
L: "%2c%22ch%22%3a%7b%22h%22%3a%22",
M: "%7b%22v%22%3a2%2c%22time%22%3a1",
N: ".channel%22%2c%22sub%22%3a%5b",
O: "%2c%22sb%22%3a1%2c%22t%22%3a%5b",
P: "%2c%22ud%22%3a100%2c%22lc%22%3a0",
Q: "%5d%2c%22f%22%3anull%2c%22uct%22%3a",
R: ".channel%22%2c%22sub%22%3a%5b1%5d",
S: "%22%2c%22m%22%3a0%7d%2c%7b%22i%22%3a",
T: "%2c%22blc%22%3a1%2c%22snd%22%3a1%2c%22ct%22%3a",
U: "%2c%22blc%22%3a0%2c%22snd%22%3a1%2c%22ct%22%3a",
V: "%2c%22blc%22%3a0%2c%22snd%22%3a0%2c%22ct%22%3a",
W: "%2c%22s%22%3a0%2c%22blo%22%3a0%7d%2c%22bl%22%3a%7b%22ac%22%3a",
X: "%2c%22ri%22%3a0%7d%2c%22state%22%3a%7b%22p%22%3a0%2c%22ut%22%3a1",
Y: "%2c%22pt%22%3a0%2c%22vis%22%3a1%2c%22bls%22%3a0%2c%22blc%22%3a0%2c%22snd%22%3a1%2c%22ct%22%3a",
Z: "%2c%22sb%22%3a1%2c%22t%22%3a%5b%5d%2c%22f%22%3anull%2c%22uct%22%3a0%2c%22s%22%3a0%2c%22blo%22%3a0%7d%2c%22bl%22%3a%7b%22ac%22%3a"
};
var PRESENCE_REVERSE = {};
var PRESENCE_REGEX;
(function() {
const l = [];
for (const m of Object.keys(PRESENCE_MAP)) {
const v = PRESENCE_MAP[m];
if (v !== void 0) {
PRESENCE_REVERSE[v] = m;
l.push(v);
}
}
l.reverse();
PRESENCE_REGEX = new RegExp(l.join("|"), "g");
})();
function presenceEncode(str) {
return encodeURIComponent(str).replace(/([_A-Z])|%../g, function(m, n) {
return n ? "%" + n.charCodeAt(0).toString(16) : m;
}).toLowerCase().replace(PRESENCE_REGEX, function(m) {
return PRESENCE_REVERSE[m] ?? m;
});
}
function presenceDecode(str) {
return decodeURIComponent(
str.replace(/[_A-Z]/g, function(m) {
return PRESENCE_MAP[m] ?? m;
})
);
}
function generatePresence(userID) {
const time = Date.now();
return "E" + presenceEncode(
JSON.stringify({
v: 3,
time: Math.floor(time / 1e3),
user: userID,
state: {
ut: 0,
t2: [],
lm2: null,
uct2: time,
tr: null,
tw: Math.floor(Math.random() * 4294967295) + 1,
at: time
},
ch: {
["p_" + userID]: 0
}
})
);
}
function generateAccessiblityCookie() {
const time = Date.now();
return encodeURIComponent(
JSON.stringify({
sr: 0,
"sr-ts": time,
jk: 0,
"jk-ts": time,
kb: 0,
"kb-ts": time,
hcm: 0,
"hcm-ts": time
})
);
}
function formatProxyPresence(presence, userID) {
const p = presence;
if (p.lat === void 0 || p.p === void 0) return null;
return {
type: "presence",
timestamp: p.lat * 1e3,
userID: userID || "",
statuses: p.p
};
}
function formatPresence(presence, userID) {
const pr = presence;
return {
type: "presence",
timestamp: (pr.la ?? 0) * 1e3,
userID: userID || "",
statuses: pr.a
};
}
module.exports = {
presenceEncode,
presenceDecode,
generatePresence,
generateAccessiblityCookie,
formatProxyPresence,
formatPresence
};
}
});
// src/utils/format/readTyp.ts
var require_readTyp = __commonJS({
"src/utils/format/readTyp.ts"(exports, module) {
"use strict";
init_utils();
function formatReadReceipt(event) {
return {
reader: event.reader.toString(),
time: event.time,
threadID: formatID((event.thread_fbid || event.reader).toString()),
type: "read_receipt"
};
}
function formatRead(event) {
return {
threadID: formatID((event.chat_ids && event.chat_ids[0] || event.thread_fbids && event.thread_fbids[0]).toString()),
time: event.timestamp,
type: "read"
};
}
function formatTyp(event) {
return {
isTyping: Boolean(event.st),
from: event.from.toString(),
threadID: formatID((event.to || event.thread_fbid || event.from).toString()),
fromMobile: Object.prototype.hasOwnProperty.call(event, "from_mobile") ? event.from_mobile : true,
userID: (event.realtime_viewer_fbid || event.from).toString(),
type: "typ"
};
}
module.exports = {
formatReadReceipt,
formatRead,
formatTyp
};
}
});
// src/utils/format/thread.ts
var require_thread = __commonJS({
"src/utils/format/thread.ts"(exports, module) {
"use strict";
init_utils();
function formatThread2(data) {
return {
threadID: formatID(data.thread_fbid.toString()),
participants: data.participants.map(formatID),
participantIDs: data.participants.map(formatID),
name: data.name,
nicknames: data.custom_nickname,
snippet: data.snippet,
snippetAttachments: data.snippet_attachments,
snippetSender: formatID((data.snippet_sender || "").toString()),
unreadCount: data.unread_count,
messageCount: data.message_count,
imageSrc: data.image_src,
timestamp: data.timestamp,
muteUntil: data.mute_until,
isCanonicalUser: data.is_canonical_user,
isCanonical: data.is_canonical,
isSubscribed: data.is_subscribed,
folder: data.folder,
isArchived: data.is_archived,
recipientsLoadable: data.recipients_loadable,
hasEmailParticipant: data.has_email_participant,
readOnly: data.read_only,
canReply: data.can_reply,
cannotReplyReason: data.cannot_reply_reason,
lastMessageTimestamp: data.last_message_timestamp,
lastReadTimestamp: data.last_read_timestamp,
lastMessageType: data.last_message_type,
emoji: data.custom_like_icon,
color: data.custom_color,
adminIDs: data.admin_ids,
threadType: data.thread_type
};
}
module.exports = {
formatThread: formatThread2
};
}
});
// src/utils/format/index.ts
var require_format = __commonJS({
"src/utils/format/index.ts"(exports, module) {
"use strict";
var import_attachment = __toESM(require_attachment());
var import_cookie = __toESM(require_cookie());
var import_date = __toESM(require_date());
var import_decode = __toESM(require_decode());
var import_delta = __toESM(require_delta());
var import_ids = __toESM(require_ids());
var import_message = __toESM(require_message());
var import_presence = __toESM(require_presence());
var import_readTyp = __toESM(require_readTyp());
var import_thread2 = __toESM(require_thread());
init_utils();
module.exports = {
getType,
formatID,
padZeros,
arrayToObject,
arrToForm,
getData_Path,
setData_Path,
getPaths,
cleanHTML,
getCurrentTimestamp,
getSignatureID,
generateOfflineThreadingID: import_ids.default.generateOfflineThreadingID,
generateThreadingID: import_ids.default.generateThreadingID,
getGUID: import_ids.default.getGUID,
generateTimestampRelative: import_ids.default.generateTimestampRelative,
formatDate: import_date.default.formatDate,
presenceEncode: import_presence.default.presenceEncode,
presenceDecode: import_presence.default.presenceDecode,
generatePresence: import_presence.default.generatePresence,
generateAccessiblityCookie: import_presence.default.generateAccessiblityCookie,
formatProxyPresence: import_presence.default.formatProxyPresence,
formatPresence: import_presence.default.formatPresence,
_formatAttachment: import_attachment.default._formatAttachment,
formatAttachment: import_attachment.default.formatAttachment,
getAdminTextMessageType: import_delta.default.getAdminTextMessageType,
formatDeltaEvent: import_delta.default.formatDeltaEvent,
formatDeltaMessage: import_delta.default.formatDeltaMessage,
getMentionsFromDeltaMessage: import_delta.default.getMentionsFromDeltaMessage,
formatDeltaReadReceipt: import_delta.default.formatDeltaReadReceipt,
formatMessage: import_message.default.formatMessage,
formatEvent: import_message.default.formatEvent,
formatHistoryMessage: import_message.default.formatHistoryMessage,
formatReadReceipt: import_readTyp.default.formatReadReceipt,
formatRead: import_readTyp.default.formatRead,
formatTyp: import_readTyp.default.formatTyp,
formatThread: import_thread2.default.formatThread,
decodeClientPayload: import_decode.default.decodeClientPayload,
formatCookie: import_cookie.default.formatCookie
};
}
});
// src/core/state.ts
function createStateStore(initialState) {
const state = Object.assign({}, initialState);
Object.defineProperty(state, "__set", {
enumerable: false,
configurable: false,
writable: false,
value: function setStateField(key, value) {
state[key] = value;
return value;
}
});
Object.defineProperty(state, "__merge", {
enumerable: false,
configurable: false,
writable: false,
value: function mergeState(partial) {
if (partial && typeof partial === "object") {
Object.assign(state, partial);
}
return state;
}
});
Object.defineProperty(state, "__snapshot", {
enumerable: false,
configurable: false,
writable: false,
value: function snapshotState() {
return { ...state };
}
});
return state;
}
function createFcaState(input) {
const base = createDefaultContext();
const state = createStateStore({
...base,
userID: input.userID,
fbid: input.userID || base.fbid,
jar: input.jar,
globalOptions: input.globalOptions,
options: input.globalOptions || base.options,
loggedIn: true,
access_token: input.access_token || "NONE",