@lazyneoaz/metachat 6.0.9 → 6.0.10

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/dist/index.cjs CHANGED
@@ -25552,6 +25552,7 @@ async function post(url2, reqJar, form, options, ctx, customHeader) {
25552
25552
  for (const key in form) {
25553
25553
  if (Object.prototype.hasOwnProperty.call(form, key)) {
25554
25554
  let value = form[key];
25555
+ if (value == null) continue;
25555
25556
  if (getType(value) === "Object") {
25556
25557
  value = JSON.stringify(value);
25557
25558
  }
@@ -25589,6 +25590,7 @@ async function postFormData(url2, reqJar, form, qs2, options, ctx, customHeader)
25589
25590
  const formData = new import_form_data2.default();
25590
25591
  for (const key in form) {
25591
25592
  if (Object.prototype.hasOwnProperty.call(form, key)) {
25593
+ if (form[key] == null) continue;
25592
25594
  formData.append(key, form[key]);
25593
25595
  }
25594
25596
  }
@@ -84842,6 +84844,165 @@ function _formatAttachment(attachment1, attachment2) {
84842
84844
  properties
84843
84845
  };
84844
84846
  }
84847
+ // Legacy / Mercury attach_type cases. Every realtime NewMessage attachment
84848
+ // is routed through this function, and Mercury (non-GraphQL) payloads carry
84849
+ // attach_type values like "photo"/"video"/"file" — without these branches
84850
+ // they all fell through to { type: "unknown" } and bots that switch on
84851
+ // att.type saw nothing.
84852
+ case "photo":
84853
+ return {
84854
+ type: "photo",
84855
+ ID: attachment1.metadata?.fbid != null ? String(attachment1.metadata.fbid) : void 0,
84856
+ filename: attachment1.fileName,
84857
+ thumbnailUrl: attachment1.thumbnail_url,
84858
+ previewUrl: attachment1.preview_url,
84859
+ previewWidth: attachment1.preview_width,
84860
+ previewHeight: attachment1.preview_height,
84861
+ largePreviewUrl: attachment1.large_preview_url,
84862
+ largePreviewWidth: attachment1.large_preview_width,
84863
+ largePreviewHeight: attachment1.large_preview_height,
84864
+ url: attachment1.metadata?.url,
84865
+ width: attachment1.metadata?.dimensions != null ? String(attachment1.metadata.dimensions).split(",")[0] : void 0,
84866
+ height: attachment1.metadata?.dimensions != null ? String(attachment1.metadata.dimensions).split(",")[1] : void 0,
84867
+ name: attachment1.fileName
84868
+ };
84869
+ case "video":
84870
+ return {
84871
+ type: "video",
84872
+ ID: attachment1.metadata?.fbid != null ? String(attachment1.metadata.fbid) : void 0,
84873
+ filename: attachment1.name,
84874
+ previewUrl: attachment1.preview_url,
84875
+ previewWidth: attachment1.preview_width,
84876
+ previewHeight: attachment1.preview_height,
84877
+ url: attachment1.url,
84878
+ width: attachment1.metadata?.dimensions?.width,
84879
+ height: attachment1.metadata?.dimensions?.height,
84880
+ duration: attachment1.metadata?.duration,
84881
+ videoType: "unknown",
84882
+ thumbnailUrl: attachment1.thumbnail_url
84883
+ };
84884
+ case "file":
84885
+ return {
84886
+ type: "file",
84887
+ filename: attachment1.name,
84888
+ ID: attachment2.id != null ? String(attachment2.id) : void 0,
84889
+ url: attachment1.url,
84890
+ isMalicious: attachment2.is_malicious,
84891
+ contentType: attachment2.mime_type,
84892
+ name: attachment1.name,
84893
+ mimeType: attachment2.mime_type,
84894
+ fileSize: attachment2.file_size
84895
+ };
84896
+ case "animated_image":
84897
+ return {
84898
+ type: "animated_image",
84899
+ ID: attachment2.id != null ? String(attachment2.id) : void 0,
84900
+ filename: attachment2.filename,
84901
+ previewUrl: attachment1.preview_url,
84902
+ previewWidth: attachment1.preview_width,
84903
+ previewHeight: attachment1.preview_height,
84904
+ url: attachment2.image_data?.url,
84905
+ width: attachment2.image_data?.width,
84906
+ height: attachment2.image_data?.height,
84907
+ name: attachment1.name,
84908
+ facebookUrl: attachment1.url,
84909
+ thumbnailUrl: attachment1.thumbnail_url,
84910
+ mimeType: attachment2.mime_type,
84911
+ rawGifImage: attachment2.image_data?.raw_gif_image,
84912
+ rawWebpImage: attachment2.image_data?.raw_webp_image,
84913
+ animatedGifUrl: attachment2.image_data?.animated_gif_url,
84914
+ animatedGifPreviewUrl: attachment2.image_data?.animated_gif_preview_url,
84915
+ animatedWebpUrl: attachment2.image_data?.animated_webp_url,
84916
+ animatedWebpPreviewUrl: attachment2.image_data?.animated_webp_preview_url
84917
+ };
84918
+ case "share": {
84919
+ const share = attachment1.share || {};
84920
+ const media = share.media || {};
84921
+ const imageSize = media.image_size || {};
84922
+ return {
84923
+ type: "share",
84924
+ ID: share.share_id != null ? String(share.share_id) : void 0,
84925
+ url: attachment2.href,
84926
+ title: share.title,
84927
+ description: share.description,
84928
+ source: share.source,
84929
+ image: media.image,
84930
+ width: imageSize.width,
84931
+ height: imageSize.height,
84932
+ playable: media.playable,
84933
+ duration: media.duration,
84934
+ subattachments: share.subattachments,
84935
+ properties: {},
84936
+ animatedImageSize: media.animated_image_size,
84937
+ facebookUrl: share.uri,
84938
+ target: share.target,
84939
+ styleList: share.style_list
84940
+ };
84941
+ }
84942
+ case "sticker": {
84943
+ const meta2 = attachment1.metadata || {};
84944
+ return {
84945
+ type: "sticker",
84946
+ ID: meta2.stickerID != null ? String(meta2.stickerID) : void 0,
84947
+ url: attachment1.url,
84948
+ packID: meta2.packID != null ? String(meta2.packID) : null,
84949
+ spriteUrl: meta2.spriteURI,
84950
+ spriteUrl2x: meta2.spriteURI2x,
84951
+ width: meta2.width,
84952
+ height: meta2.height,
84953
+ caption: attachment2.caption,
84954
+ description: attachment2.description,
84955
+ frameCount: meta2.frameCount,
84956
+ frameRate: meta2.frameRate,
84957
+ framesPerRow: meta2.framesPerRow,
84958
+ framesPerCol: meta2.framesPerCol,
84959
+ stickerID: meta2.stickerID != null ? String(meta2.stickerID) : void 0,
84960
+ spriteURI: meta2.spriteURI,
84961
+ spriteURI2x: meta2.spriteURI2x
84962
+ };
84963
+ }
84964
+ case "error":
84965
+ return { type: "error", attachment1, attachment2 };
84966
+ case "MessageLocation":
84967
+ case "location": {
84968
+ const story = blob && blob.story_attachment || attachment1.story_attachment || {};
84969
+ const walkWhere = (raw) => {
84970
+ try {
84971
+ const outer = new URL(String(raw));
84972
+ const u = outer.searchParams.get("u");
84973
+ if (u) {
84974
+ try {
84975
+ const where1 = new URL(u).searchParams.get("where1");
84976
+ if (where1) return where1;
84977
+ } catch (_) {
84978
+ }
84979
+ const m = String(u).match(/where1=([^&]+)/);
84980
+ if (m) return decodeURIComponent(m[1]);
84981
+ }
84982
+ } catch (_) {
84983
+ }
84984
+ return "";
84985
+ };
84986
+ const whereStr = walkWhere(story.url);
84987
+ const address = whereStr.split(", ");
84988
+ const latitude = Number.parseFloat(address[0]);
84989
+ const longitude = Number.parseFloat(address[1]);
84990
+ const image = story.media?.image;
84991
+ return {
84992
+ type: "location",
84993
+ ID: blob?.legacy_attachment_id,
84994
+ latitude: Number.isFinite(latitude) ? latitude : void 0,
84995
+ longitude: Number.isFinite(longitude) ? longitude : void 0,
84996
+ image: image?.uri,
84997
+ width: image?.width,
84998
+ height: image?.height,
84999
+ url: whereStr || story.url,
85000
+ address: whereStr,
85001
+ facebookUrl: story.url,
85002
+ target: story.target,
85003
+ styleList: story.style_list
85004
+ };
85005
+ }
84845
85006
  default:
84846
85007
  return { type: "unknown", error: `Unrecognized attachment type: ${type}` };
84847
85008
  }
@@ -84914,7 +85075,11 @@ function getAdminTextMessageType(type) {
84914
85075
  case "unpin_messages_v2":
84915
85076
  return "log:unpin-message";
84916
85077
  case "pin_messages_v2":
84917
- return "log:pin-message";
85078
+ return "log:thread-pinned";
85079
+ case "joinable_group_link_mode_change":
85080
+ return "log:link-status";
85081
+ case "magic_words":
85082
+ return "log:magic-words";
84918
85083
  case "change_thread_theme":
84919
85084
  return "log:thread-color";
84920
85085
  case "change_thread_icon":
@@ -84961,6 +85126,7 @@ function formatDeltaMessage(m) {
84961
85126
  author: senderID,
84962
85127
  userID: senderID,
84963
85128
  body,
85129
+ args: body.trim().split(/\s+/),
84964
85130
  threadID: formatID((threadKey.threadFbId || threadKey.otherUserFbId || "").toString()),
84965
85131
  messageID: md.messageId,
84966
85132
  offlineThreadingId: md.offlineThreadingId,
@@ -85008,6 +85174,7 @@ function formatDeltaNewMessage(m) {
85008
85174
  author: senderID,
85009
85175
  userID: senderID,
85010
85176
  body,
85177
+ args: body.trim().split(/\s+/),
85011
85178
  threadID,
85012
85179
  messageID: md.messageId,
85013
85180
  offlineThreadingId: md.offlineThreadingId,
@@ -85039,6 +85206,28 @@ function formatDeltaEvent(m) {
85039
85206
  logMessageType = "log:unsubscribe";
85040
85207
  logMessageData = { leftParticipantFbId: m.leftParticipantFbId };
85041
85208
  break;
85209
+ case "UserLocation": {
85210
+ const story = m.attachments?.[0]?.mercury?.extensible_attachment?.story_attachment || {};
85211
+ logMessageType = "log:user-location";
85212
+ logMessageData = {
85213
+ Image: story.media?.image,
85214
+ Location: story.target?.location_title,
85215
+ coordinates: story.target?.coordinate,
85216
+ url: story.url
85217
+ };
85218
+ break;
85219
+ }
85220
+ case "ApprovalQueue":
85221
+ logMessageType = "log:approval-queue";
85222
+ logMessageData = {
85223
+ approvalQueue: {
85224
+ action: m.action,
85225
+ recipientFbId: m.recipientFbId,
85226
+ requestSource: m.requestSource,
85227
+ ...m.messageMetadata || {}
85228
+ }
85229
+ };
85230
+ break;
85042
85231
  default:
85043
85232
  logMessageType = m.class;
85044
85233
  logMessageData = m;
@@ -85931,7 +86120,11 @@ async function scrapeTokens(ctx, defaultFuncs, state, force = false) {
85931
86120
  }
85932
86121
  function hasCometTokens(ctx) {
85933
86122
  const state = ctx.__cometTokens || {};
85934
- return Boolean(state.lsd && state.fb_dtsg);
86123
+ if (tokenPairFresh(state)) return true;
86124
+ if (!state.fetchedAt) {
86125
+ return Boolean(state.lsd && state.fb_dtsg || ctx.lsd && ctx.fb_dtsg);
86126
+ }
86127
+ return false;
85935
86128
  }
85936
86129
  function invalidateCometTokens(ctx) {
85937
86130
  const state = tokenState(ctx);
@@ -87009,10 +87202,10 @@ function makeDefaults(html3, userID, ctx) {
87009
87202
  __req: reqId,
87010
87203
  __rev: ctx.revision || revision,
87011
87204
  __a: 1,
87012
- ...ctx && {
87013
- fb_dtsg: ctx.fb_dtsg,
87014
- jazoest: ctx.jazoest
87015
- },
87205
+ // Only emit the document-token fields when they actually hold a value;
87206
+ // spreading them unconditionally created `fb_dtsg=undefined` form entries.
87207
+ ...ctx && ctx.fb_dtsg ? { fb_dtsg: ctx.fb_dtsg } : {},
87208
+ ...ctx && ctx.jazoest ? { jazoest: ctx.jazoest } : {},
87016
87209
  // The Comet document token and its spin siblings gate GraphQL; include
87017
87210
  // them whenever they are known so no module has to remember.
87018
87211
  ...ctx && ctx.lsd ? { lsd: ctx.lsd } : {},
@@ -87116,6 +87309,11 @@ async function setOptions(globalOptions, options = {}) {
87116
87309
 
87117
87310
  // src/core/models/buildAPI.ts
87118
87311
  async function buildAPI(html3, jar2, netData, globalOptions, fbLinkFunc, errorRetrievingMsg) {
87312
+ if (isLoggedOutDocument(html3)) {
87313
+ throw new Error(
87314
+ "Facebook returned the logged-out page for these cookies: the session is expired or invalid. Export a fresh appState from a logged-in browser and try again."
87315
+ );
87316
+ }
87119
87317
  const userID = (() => {
87120
87318
  const origins = [
87121
87319
  "https://www.facebook.com",
@@ -87985,6 +88183,115 @@ function editMessage_default(_defaultFuncs, _api, ctx) {
87985
88183
  };
87986
88184
  }
87987
88185
 
88186
+ // src/deltas/apis/mqtt/threadTasks.ts
88187
+ var THREAD_TASK_VERSIONS = {
88188
+ // Thread settings mutations share one family: title, emoji, color, nickname,
88189
+ // admin status, group image.
88190
+ threadSettings: "8798795233522156",
88191
+ addParticipant: "24502707779384158",
88192
+ removeParticipant: "25002366262773827",
88193
+ sendMessage: "24804310205905615",
88194
+ forwardAttachment: "8768858626531631",
88195
+ shareContact: "7214102258676893",
88196
+ editMessage: "6903494529735864",
88197
+ unsendMessage: "25393437286970779",
88198
+ deleteMessage: "25909428212080747",
88199
+ setReaction: "24585299697835063",
88200
+ typingIndicator: "8965252033599983",
88201
+ createPoll: "34195258046739157"
88202
+ };
88203
+ var APP_ID_LS = "2220391788200892";
88204
+ function mqttReady(ctx) {
88205
+ return !!(ctx && ctx.mqttClient && ctx.mqttClient.connected);
88206
+ }
88207
+ async function publishThreadTask(ctx, label, queueName, payload, versionId, appId = APP_ID_LS) {
88208
+ const task = {
88209
+ failure_count: null,
88210
+ label,
88211
+ payload: JSON.stringify(payload),
88212
+ queue_name: queueName
88213
+ };
88214
+ const content = buildWsTaskContent(ctx, [task], versionId, appId);
88215
+ return publishLsRequestWithAck({
88216
+ client: ctx.mqttClient,
88217
+ content,
88218
+ requestId: content.request_id,
88219
+ extract: (parsed) => {
88220
+ const body = parsed && parsed.payload;
88221
+ if (!body || typeof body !== "object") return { success: true };
88222
+ return body;
88223
+ }
88224
+ });
88225
+ }
88226
+
88227
+ // src/deltas/apis/messaging/deleteMessage.ts
88228
+ function deleteMessage_default(defaultFuncs, _api, ctx) {
88229
+ return function deleteMessage(messageOrMessages, callback) {
88230
+ const cb = typeof callback === "function" ? callback : void 0;
88231
+ let _resolve = () => {
88232
+ };
88233
+ let _reject = () => {
88234
+ };
88235
+ const returnPromise = new Promise((resolve, reject) => {
88236
+ _resolve = resolve;
88237
+ _reject = reject;
88238
+ });
88239
+ returnPromise.catch(() => {
88240
+ });
88241
+ const done = (err, data2) => {
88242
+ if (cb) {
88243
+ cb(err, data2);
88244
+ return;
88245
+ }
88246
+ if (err) _reject(err);
88247
+ else _resolve(data2);
88248
+ };
88249
+ const messages = Array.isArray(messageOrMessages) ? messageOrMessages : [messageOrMessages];
88250
+ if (messages.length === 0 || messages.some((value) => value === null || typeof value === "undefined" || value === "")) {
88251
+ done({ error: "deleteMessage: messageID is required." });
88252
+ return returnPromise;
88253
+ }
88254
+ if (!mqttReady(ctx)) {
88255
+ done({ error: "deleteMessage: not connected to MQTT." });
88256
+ return returnPromise;
88257
+ }
88258
+ const tasks = messages.map((messageID) => {
88259
+ const queueName = String(messageID);
88260
+ return {
88261
+ failure_count: null,
88262
+ label: "146",
88263
+ payload: JSON.stringify({
88264
+ thread_key: queueName,
88265
+ remove_type: 0,
88266
+ sync_group: 1
88267
+ }),
88268
+ queue_name: queueName
88269
+ };
88270
+ });
88271
+ let content;
88272
+ try {
88273
+ content = buildWsTaskContent(ctx, tasks, THREAD_TASK_VERSIONS.deleteMessage, APP_ID_LS);
88274
+ } catch (error2) {
88275
+ done(error2);
88276
+ return returnPromise;
88277
+ }
88278
+ publishLsRequestWithAck({
88279
+ client: ctx.mqttClient,
88280
+ content,
88281
+ requestId: content.request_id,
88282
+ extract: (parsed) => {
88283
+ const body = parsed && parsed.payload;
88284
+ if (!body || typeof body !== "object") return { success: true };
88285
+ return body;
88286
+ }
88287
+ }).then((result) => done(null, result)).catch((error2) => {
88288
+ error("deleteMessage", error2?.error || error2?.message || error2);
88289
+ done(error2);
88290
+ });
88291
+ return returnPromise;
88292
+ };
88293
+ }
88294
+
87988
88295
  // src/deltas/apis/messaging/getMessage.ts
87989
88296
  function formatExtensibleAttachment(ext) {
87990
88297
  if (!ext || Object.keys(ext).length === 0) return [];
@@ -89431,7 +89738,11 @@ function sendTypingIndicator_default(defaultFuncs, api, ctx) {
89431
89738
  options = options || {};
89432
89739
  let actualThreadID;
89433
89740
  let actualSendTyping;
89434
- if (typeof sendTyping === "string" || typeof sendTyping === "number") {
89741
+ const firstLooksLikeThread = typeof sendTyping === "string" || typeof sendTyping === "number";
89742
+ if (firstLooksLikeThread && typeof threadID === "boolean") {
89743
+ actualThreadID = sendTyping;
89744
+ actualSendTyping = threadID;
89745
+ } else if (firstLooksLikeThread) {
89435
89746
  actualThreadID = sendTyping;
89436
89747
  actualSendTyping = true;
89437
89748
  } else {
@@ -90150,47 +90461,6 @@ function makeAiTheme_default(defaultFuncs, _api, ctx) {
90150
90461
  };
90151
90462
  }
90152
90463
 
90153
- // src/deltas/apis/mqtt/threadTasks.ts
90154
- var THREAD_TASK_VERSIONS = {
90155
- // Thread settings mutations share one family: title, emoji, color, nickname,
90156
- // admin status, group image.
90157
- threadSettings: "8798795233522156",
90158
- addParticipant: "24502707779384158",
90159
- removeParticipant: "25002366262773827",
90160
- sendMessage: "24804310205905615",
90161
- forwardAttachment: "8768858626531631",
90162
- shareContact: "7214102258676893",
90163
- editMessage: "6903494529735864",
90164
- unsendMessage: "25393437286970779",
90165
- deleteMessage: "25909428212080747",
90166
- setReaction: "24585299697835063",
90167
- typingIndicator: "8965252033599983",
90168
- createPoll: "34195258046739157"
90169
- };
90170
- var APP_ID_LS = "2220391788200892";
90171
- function mqttReady(ctx) {
90172
- return !!(ctx && ctx.mqttClient && ctx.mqttClient.connected);
90173
- }
90174
- async function publishThreadTask(ctx, label, queueName, payload, versionId, appId = APP_ID_LS) {
90175
- const task = {
90176
- failure_count: null,
90177
- label,
90178
- payload: JSON.stringify(payload),
90179
- queue_name: queueName
90180
- };
90181
- const content = buildWsTaskContent(ctx, [task], versionId, appId);
90182
- return publishLsRequestWithAck({
90183
- client: ctx.mqttClient,
90184
- content,
90185
- requestId: content.request_id,
90186
- extract: (parsed) => {
90187
- const body = parsed && parsed.payload;
90188
- if (!body || typeof body !== "object") return { success: true };
90189
- return body;
90190
- }
90191
- });
90192
- }
90193
-
90194
90464
  // src/deltas/apis/messaging/unsendMessage.ts
90195
90465
  function extractUnsend(message) {
90196
90466
  try {
@@ -90462,9 +90732,15 @@ function searchMusic_default(defaultFuncs, _api, ctx) {
90462
90732
  cacheResult(ctx, cacheKey, result);
90463
90733
  return result;
90464
90734
  }
90465
- for (let retry = 0; retry < 6; retry++) {
90466
- await sleep(1e3 + retry * 600 + Math.floor(Math.random() * 350));
90467
- const retried = await attempt(retry >= 3 || !hasCometTokens(ctx));
90735
+ let forcedScrape = false;
90736
+ for (let retry = 0; retry < 2; retry++) {
90737
+ await sleep(900 + retry * 1100 + Math.floor(Math.random() * 350));
90738
+ let force = false;
90739
+ if (!forcedScrape && !hasCometTokens(ctx)) {
90740
+ force = true;
90741
+ forcedScrape = true;
90742
+ }
90743
+ const retried = await attempt(force);
90468
90744
  if (isStaleTokenError(retried) || retried?.error || (retried?.errors || []).length) continue;
90469
90745
  const retryPage = collectTracks(retried);
90470
90746
  const retryTracks = retryPage.tracks.slice(0, count);
@@ -92210,6 +92486,22 @@ function formatMessagesGraphQLResponse(data2) {
92210
92486
  return "other";
92211
92487
  }
92212
92488
  })();
92489
+ const logMessageData = (() => {
92490
+ switch (d.__typename) {
92491
+ case "ThreadNameMessage":
92492
+ return { name: d.thread_name };
92493
+ case "ParticipantLeftMessage":
92494
+ return {
92495
+ leftParticipantFbId: (d.participants_removed || []).map((p) => String(p.id))
92496
+ };
92497
+ case "ParticipantsAddedMessage":
92498
+ return {
92499
+ addedParticipants: (d.participants_added || []).map((p) => String(p.id))
92500
+ };
92501
+ default:
92502
+ return d.extensible_message_admin_text || d.extensible_message_admin_text_type || d;
92503
+ }
92504
+ })();
92213
92505
  return {
92214
92506
  type: "event",
92215
92507
  messageID: d.message_id,
@@ -92220,7 +92512,8 @@ function formatMessagesGraphQLResponse(data2) {
92220
92512
  timestamp: d.timestamp_precise,
92221
92513
  snippet: d.snippet,
92222
92514
  logMessageType,
92223
- logMessageData: d.extensible_message_admin_text || d.extensible_message_admin_text_type || d
92515
+ logMessageData,
92516
+ eventData: d
92224
92517
  };
92225
92518
  }
92226
92519
  default:
@@ -92523,7 +92816,10 @@ function formatThreadGraphQLResponse2(messageThread) {
92523
92816
  },
92524
92817
  {}
92525
92818
  ) : {},
92526
- adminIDs: messageThread.thread_admins || [],
92819
+ // thread_admins is [{id:"…"}]; callers test `adminIDs.includes(userID)`
92820
+ // (the bot's getRole does exactly that), so hand back id strings like the
92821
+ // reference. Returning the raw objects made every admin check false.
92822
+ adminIDs: (messageThread.thread_admins || []).map((a) => String(a.id)),
92527
92823
  approvalMode: Boolean(messageThread.approval_mode),
92528
92824
  approvalQueue: (messageThread.group_approval_queue && messageThread.group_approval_queue.nodes || []).map((a) => ({
92529
92825
  inviterID: a.inviter.id,
@@ -92630,24 +92926,25 @@ function getThreadList_default(defaultFuncs, api, ctx) {
92630
92926
  }
92631
92927
 
92632
92928
  // src/deltas/apis/threads/getThreadPictures.ts
92633
- function getThreadPictures_default(defaultFuncs, api, ctx) {
92929
+ var SHARED_PHOTOS_URL = "https://www.facebook.com/ajax/messaging/attachments/sharedphotos.php";
92930
+ function getThreadPictures_default(defaultFuncs, _api, ctx) {
92931
+ const postSharedPhotos = (form) => defaultFuncs.post(SHARED_PHOTOS_URL, ctx.jar, form).then(parseAndCheckLogin(ctx, defaultFuncs));
92634
92932
  return async function getThreadPictures(threadID, offset = 0, limit = 5) {
92635
- const fetchAmount = Math.max(limit + offset, 20);
92636
- const history = await api.getThreadHistory(threadID, fetchAmount);
92637
- const urls = [];
92638
- for (const message of history || []) {
92639
- const attachments = message && message.attachments;
92640
- if (!Array.isArray(attachments)) continue;
92641
- for (const attachment of attachments) {
92642
- if (!attachment) continue;
92643
- if (attachment.type === "photo" || attachment.type === "image") {
92644
- const url2 = attachment.previewUrl || attachment.thumbnailUrl || attachment.url;
92645
- if (url2) urls.push(url2);
92646
- }
92647
- }
92648
- }
92649
- urls.reverse();
92650
- return urls.slice(offset, offset + limit);
92933
+ const resData = await postSharedPhotos({ thread_id: threadID, offset, limit });
92934
+ if (resData && resData.error) throw resData;
92935
+ const images = resData && resData.payload && resData.payload.imagesData || [];
92936
+ const urls = await Promise.all(
92937
+ images.map(
92938
+ (image) => postSharedPhotos({ thread_id: threadID, image_id: image.fbid }).then((detail) => {
92939
+ if (detail && detail.error) throw detail;
92940
+ const require2 = detail && detail.jsmods && detail.jsmods.require;
92941
+ const block = require2 && require2[0] && require2[0][3] && require2[0][3][1];
92942
+ const queryThreadID = block && block.query_metadata && block.query_metadata.query_path ? block.query_metadata.query_path[0]?.message_thread : void 0;
92943
+ return block && block.query_results && block.query_results[queryThreadID] ? block.query_results[queryThreadID]?.message_images?.edges?.[0]?.node?.image2 : void 0;
92944
+ })
92945
+ )
92946
+ );
92947
+ return urls.filter(Boolean);
92651
92948
  };
92652
92949
  }
92653
92950
 
@@ -93927,6 +94224,18 @@ function parseDelta(defaultFuncs, api, ctx, globalCallback, v) {
93927
94224
  if (!v || !v.delta || typeof v.delta !== "object") return;
93928
94225
  if (v.delta.class == "NewMessage") {
93929
94226
  if (ctx.globalOptions.pageID && ctx.globalOptions.pageID != v.queue) return;
94227
+ const liveAttachment = v.delta.attachments && v.delta.attachments.length === 1 ? v.delta.attachments[0]?.mercury?.extensible_attachment : void 0;
94228
+ const liveStyles = liveAttachment?.story_attachment?.style_list;
94229
+ if (Array.isArray(liveStyles) && liveStyles.includes("message_live_location")) {
94230
+ v.delta.class = "UserLocation";
94231
+ let fmtLive;
94232
+ try {
94233
+ fmtLive = formatDeltaEvent(v.delta);
94234
+ } catch (err) {
94235
+ return;
94236
+ }
94237
+ return globalCallback(null, fmtLive);
94238
+ }
93930
94239
  (function resolveAttachmentUrl(i2) {
93931
94240
  if (!v.delta.attachments || !Array.isArray(v.delta.attachments) || i2 >= v.delta.attachments.length) {
93932
94241
  let fmtMsg;
@@ -94101,6 +94410,8 @@ function parseDelta(defaultFuncs, api, ctx, globalCallback, v) {
94101
94410
  case "ThreadName":
94102
94411
  case "ParticipantsAddedToGroupThread":
94103
94412
  case "ParticipantLeftGroupThread":
94413
+ case "UserLocation":
94414
+ case "ApprovalQueue":
94104
94415
  let fmtEvent;
94105
94416
  try {
94106
94417
  fmtEvent = formatDeltaEvent(v.delta);
@@ -94108,6 +94419,89 @@ function parseDelta(defaultFuncs, api, ctx, globalCallback, v) {
94108
94419
  return globalCallback({ error: "Problem parsing event", detail: err, res: v.delta, type: "parse_error" });
94109
94420
  }
94110
94421
  return globalCallback(null, fmtEvent);
94422
+ case "ForcedFetch": {
94423
+ const delta = v.delta;
94424
+ if (!delta.threadKey) return;
94425
+ const mid = delta.messageId;
94426
+ const tid = delta.threadKey.threadFbId;
94427
+ if (!mid || !tid) return;
94428
+ const form = {
94429
+ av: ctx.globalOptions.pageID || ctx.userID,
94430
+ queries: JSON.stringify({
94431
+ o0: {
94432
+ doc_id: "2848441488556444",
94433
+ query_params: {
94434
+ thread_and_message_id: { thread_id: tid.toString(), message_id: mid }
94435
+ }
94436
+ }
94437
+ })
94438
+ };
94439
+ defaultFuncs.post("https://www.facebook.com/api/graphqlbatch/", ctx.jar, form).then(parseAndCheckLogin(ctx, defaultFuncs)).then((resData) => {
94440
+ if (!Array.isArray(resData) || !resData.length) return;
94441
+ const last2 = resData[resData.length - 1] || {};
94442
+ if (last2.error_results > 0) throw resData[0]?.o0?.errors;
94443
+ if (last2.successful_results === 0) throw { error: "forcedFetch: there was no successful_results", res: resData };
94444
+ const fetchData = resData[0]?.o0?.data?.message;
94445
+ if (!fetchData || typeof fetchData !== "object") return;
94446
+ if (ctx.loggedIn === false) return;
94447
+ if (!ctx.globalOptions.selfListen && String(fetchData.message_sender?.id) === String(ctx.userID)) return;
94448
+ if (fetchData.__typename === "ThreadImageMessage") {
94449
+ const meta2 = fetchData.image_with_metadata || {};
94450
+ return globalCallback(null, {
94451
+ type: "event",
94452
+ threadID: formatID(tid.toString()),
94453
+ logMessageType: "log:thread-image",
94454
+ logMessageData: {
94455
+ image: {
94456
+ attachmentID: meta2.legacy_attachment_id,
94457
+ width: meta2.original_dimensions?.x,
94458
+ height: meta2.original_dimensions?.y,
94459
+ url: meta2.preview?.uri
94460
+ }
94461
+ },
94462
+ logMessageBody: fetchData.snippet,
94463
+ timestamp: fetchData.timestamp_precise,
94464
+ author: fetchData.message_sender?.id
94465
+ });
94466
+ }
94467
+ if (fetchData.__typename === "UserMessage") {
94468
+ const ext = fetchData.extensible_attachment || {};
94469
+ const story = ext.story_attachment || {};
94470
+ const media = story.media || {};
94471
+ const image = media.image || {};
94472
+ return globalCallback(null, {
94473
+ type: "message",
94474
+ senderID: formatID(String(fetchData.message_sender?.id)),
94475
+ body: fetchData.message?.text || "",
94476
+ threadID: formatID(tid.toString()),
94477
+ messageID: fetchData.message_id,
94478
+ attachments: [
94479
+ {
94480
+ type: "share",
94481
+ ID: ext.legacy_attachment_id,
94482
+ url: story.url,
94483
+ title: story.title_with_entities?.text,
94484
+ description: story.description?.text,
94485
+ source: story.source,
94486
+ image: image.uri,
94487
+ width: image.width,
94488
+ height: image.height,
94489
+ playable: media.is_playable || false,
94490
+ duration: media.playable_duration_in_ms || 0,
94491
+ subattachments: ext.subattachments,
94492
+ properties: story.properties
94493
+ }
94494
+ ],
94495
+ mentions: {},
94496
+ timestamp: parseInt(String(fetchData.timestamp_precise)),
94497
+ isGroup: String(fetchData.message_sender?.id) !== tid.toString()
94498
+ });
94499
+ }
94500
+ }).catch((err) => {
94501
+ warn("parseDelta", `ForcedFetch error: ${err?.message || err}`);
94502
+ });
94503
+ return;
94504
+ }
94111
94505
  }
94112
94506
  }
94113
94507
 
@@ -94308,13 +94702,19 @@ var listenMqtt_default = (defaultFuncs, api, ctx) => {
94308
94702
  clearReconnectTimer();
94309
94703
  let delay3;
94310
94704
  if (throttled) {
94311
- delay3 = Math.min(lifecycle.throttleDelay + getJitter(8e3), MQTT_CONFIG.MAX_THROTTLE_DELAY);
94705
+ delay3 = Math.min(
94706
+ Math.max(MQTT_CONFIG.THROTTLE_DELAY, lifecycle.throttleDelay) + Math.abs(getJitter(8e3)),
94707
+ MQTT_CONFIG.MAX_THROTTLE_DELAY
94708
+ );
94312
94709
  lifecycle.throttleDelay = Math.min(
94313
94710
  lifecycle.throttleDelay * MQTT_CONFIG.RETRY_MULTIPLIER,
94314
94711
  MQTT_CONFIG.MAX_THROTTLE_DELAY
94315
94712
  );
94316
94713
  } else {
94317
- delay3 = Math.min(lifecycle.delay + getJitter(1500), MQTT_CONFIG.MAX_RETRY_DELAY);
94714
+ delay3 = Math.min(
94715
+ Math.max(MQTT_CONFIG.INITIAL_RETRY_DELAY, lifecycle.delay) + Math.abs(getJitter(1500)),
94716
+ MQTT_CONFIG.MAX_RETRY_DELAY
94717
+ );
94318
94718
  lifecycle.delay = Math.min(lifecycle.delay * MQTT_CONFIG.RETRY_MULTIPLIER, MQTT_CONFIG.MAX_RETRY_DELAY);
94319
94719
  }
94320
94720
  lifecycle.attempts++;
@@ -94698,6 +95098,7 @@ var apiModules = {
94698
95098
  refreshFbDtsg: refreshFbDtsg_default,
94699
95099
  enableAutoSaveAppState: enableAutoSaveAppState_default,
94700
95100
  editMessage: editMessage_default,
95101
+ deleteMessage: deleteMessage_default,
94701
95102
  getMessage: getMessage_default,
94702
95103
  emoji: emoji_default,
94703
95104
  gcmember: gcmember_default,