@lazyneoaz/metachat 6.0.8 → 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 [];
@@ -88499,6 +88806,8 @@ function gcrule_default(defaultFuncs, api, ctx) {
88499
88806
  resolvePromise = resolve;
88500
88807
  rejectPromise = reject;
88501
88808
  });
88809
+ returnPromise.catch(() => {
88810
+ });
88502
88811
  if (typeof _callback != "function") {
88503
88812
  _callback = (err, data2) => {
88504
88813
  if (err) return rejectPromise(err);
@@ -89429,7 +89738,11 @@ function sendTypingIndicator_default(defaultFuncs, api, ctx) {
89429
89738
  options = options || {};
89430
89739
  let actualThreadID;
89431
89740
  let actualSendTyping;
89432
- 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) {
89433
89746
  actualThreadID = sendTyping;
89434
89747
  actualSendTyping = true;
89435
89748
  } else {
@@ -89815,11 +90128,22 @@ function theme_default(defaultFuncs, api, ctx) {
89815
90128
  _callback = void 0;
89816
90129
  _initiatorID = void 0;
89817
90130
  }
90131
+ finalReturnPromise.catch(() => {
90132
+ });
89818
90133
  if (!_callback) {
89819
90134
  _callback = function(_err, _data) {
89820
90135
  if (_err) _rejectFunc(_err);
89821
90136
  else _resolveFunc(_data);
89822
90137
  };
90138
+ } else {
90139
+ const originalCallback = _callback;
90140
+ _callback = function(_err, _data) {
90141
+ try {
90142
+ originalCallback(_err, _data);
90143
+ } finally {
90144
+ _resolveFunc(_data);
90145
+ }
90146
+ };
89823
90147
  }
89824
90148
  _initiatorID = _initiatorID || ctx.userID;
89825
90149
  threadID = threadID || ctx.threadID;
@@ -90137,47 +90461,6 @@ function makeAiTheme_default(defaultFuncs, _api, ctx) {
90137
90461
  };
90138
90462
  }
90139
90463
 
90140
- // src/deltas/apis/mqtt/threadTasks.ts
90141
- var THREAD_TASK_VERSIONS = {
90142
- // Thread settings mutations share one family: title, emoji, color, nickname,
90143
- // admin status, group image.
90144
- threadSettings: "8798795233522156",
90145
- addParticipant: "24502707779384158",
90146
- removeParticipant: "25002366262773827",
90147
- sendMessage: "24804310205905615",
90148
- forwardAttachment: "8768858626531631",
90149
- shareContact: "7214102258676893",
90150
- editMessage: "6903494529735864",
90151
- unsendMessage: "25393437286970779",
90152
- deleteMessage: "25909428212080747",
90153
- setReaction: "24585299697835063",
90154
- typingIndicator: "8965252033599983",
90155
- createPoll: "34195258046739157"
90156
- };
90157
- var APP_ID_LS = "2220391788200892";
90158
- function mqttReady(ctx) {
90159
- return !!(ctx && ctx.mqttClient && ctx.mqttClient.connected);
90160
- }
90161
- async function publishThreadTask(ctx, label, queueName, payload, versionId, appId = APP_ID_LS) {
90162
- const task = {
90163
- failure_count: null,
90164
- label,
90165
- payload: JSON.stringify(payload),
90166
- queue_name: queueName
90167
- };
90168
- const content = buildWsTaskContent(ctx, [task], versionId, appId);
90169
- return publishLsRequestWithAck({
90170
- client: ctx.mqttClient,
90171
- content,
90172
- requestId: content.request_id,
90173
- extract: (parsed) => {
90174
- const body = parsed && parsed.payload;
90175
- if (!body || typeof body !== "object") return { success: true };
90176
- return body;
90177
- }
90178
- });
90179
- }
90180
-
90181
90464
  // src/deltas/apis/messaging/unsendMessage.ts
90182
90465
  function extractUnsend(message) {
90183
90466
  try {
@@ -90449,9 +90732,15 @@ function searchMusic_default(defaultFuncs, _api, ctx) {
90449
90732
  cacheResult(ctx, cacheKey, result);
90450
90733
  return result;
90451
90734
  }
90452
- for (let retry = 0; retry < 6; retry++) {
90453
- await sleep(1e3 + retry * 600 + Math.floor(Math.random() * 350));
90454
- 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);
90455
90744
  if (isStaleTokenError(retried) || retried?.error || (retried?.errors || []).length) continue;
90456
90745
  const retryPage = collectTracks(retried);
90457
90746
  const retryTracks = retryPage.tracks.slice(0, count);
@@ -92197,6 +92486,22 @@ function formatMessagesGraphQLResponse(data2) {
92197
92486
  return "other";
92198
92487
  }
92199
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
+ })();
92200
92505
  return {
92201
92506
  type: "event",
92202
92507
  messageID: d.message_id,
@@ -92207,7 +92512,8 @@ function formatMessagesGraphQLResponse(data2) {
92207
92512
  timestamp: d.timestamp_precise,
92208
92513
  snippet: d.snippet,
92209
92514
  logMessageType,
92210
- logMessageData: d.extensible_message_admin_text || d.extensible_message_admin_text_type || d
92515
+ logMessageData,
92516
+ eventData: d
92211
92517
  };
92212
92518
  }
92213
92519
  default:
@@ -92510,7 +92816,10 @@ function formatThreadGraphQLResponse2(messageThread) {
92510
92816
  },
92511
92817
  {}
92512
92818
  ) : {},
92513
- 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)),
92514
92823
  approvalMode: Boolean(messageThread.approval_mode),
92515
92824
  approvalQueue: (messageThread.group_approval_queue && messageThread.group_approval_queue.nodes || []).map((a) => ({
92516
92825
  inviterID: a.inviter.id,
@@ -92617,24 +92926,25 @@ function getThreadList_default(defaultFuncs, api, ctx) {
92617
92926
  }
92618
92927
 
92619
92928
  // src/deltas/apis/threads/getThreadPictures.ts
92620
- 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));
92621
92932
  return async function getThreadPictures(threadID, offset = 0, limit = 5) {
92622
- const fetchAmount = Math.max(limit + offset, 20);
92623
- const history = await api.getThreadHistory(threadID, fetchAmount);
92624
- const urls = [];
92625
- for (const message of history || []) {
92626
- const attachments = message && message.attachments;
92627
- if (!Array.isArray(attachments)) continue;
92628
- for (const attachment of attachments) {
92629
- if (!attachment) continue;
92630
- if (attachment.type === "photo" || attachment.type === "image") {
92631
- const url2 = attachment.previewUrl || attachment.thumbnailUrl || attachment.url;
92632
- if (url2) urls.push(url2);
92633
- }
92634
- }
92635
- }
92636
- urls.reverse();
92637
- 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);
92638
92948
  };
92639
92949
  }
92640
92950
 
@@ -92857,15 +93167,8 @@ function changeAdminStatus_default(defaultFuncs, _api, ctx) {
92857
93167
  requestId: content.request_id,
92858
93168
  extract: (parsed) => {
92859
93169
  const body = parsed && parsed.payload;
92860
- const error2 = body && (body.error || body.errorDescription);
92861
- if (error2) {
92862
- const err = new Error(
92863
- typeof error2 === "string" ? error2 : error2.message || "admin_status task rejected"
92864
- );
92865
- err.error = error2;
92866
- throw err;
92867
- }
92868
- return body || { success: true };
93170
+ if (!body || typeof body !== "object") return { success: true };
93171
+ return body;
92869
93172
  }
92870
93173
  });
92871
93174
  if (cb) cb(null);
@@ -93921,6 +94224,18 @@ function parseDelta(defaultFuncs, api, ctx, globalCallback, v) {
93921
94224
  if (!v || !v.delta || typeof v.delta !== "object") return;
93922
94225
  if (v.delta.class == "NewMessage") {
93923
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
+ }
93924
94239
  (function resolveAttachmentUrl(i2) {
93925
94240
  if (!v.delta.attachments || !Array.isArray(v.delta.attachments) || i2 >= v.delta.attachments.length) {
93926
94241
  let fmtMsg;
@@ -94095,6 +94410,8 @@ function parseDelta(defaultFuncs, api, ctx, globalCallback, v) {
94095
94410
  case "ThreadName":
94096
94411
  case "ParticipantsAddedToGroupThread":
94097
94412
  case "ParticipantLeftGroupThread":
94413
+ case "UserLocation":
94414
+ case "ApprovalQueue":
94098
94415
  let fmtEvent;
94099
94416
  try {
94100
94417
  fmtEvent = formatDeltaEvent(v.delta);
@@ -94102,6 +94419,89 @@ function parseDelta(defaultFuncs, api, ctx, globalCallback, v) {
94102
94419
  return globalCallback({ error: "Problem parsing event", detail: err, res: v.delta, type: "parse_error" });
94103
94420
  }
94104
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
+ }
94105
94505
  }
94106
94506
  }
94107
94507
 
@@ -94302,13 +94702,19 @@ var listenMqtt_default = (defaultFuncs, api, ctx) => {
94302
94702
  clearReconnectTimer();
94303
94703
  let delay3;
94304
94704
  if (throttled) {
94305
- 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
+ );
94306
94709
  lifecycle.throttleDelay = Math.min(
94307
94710
  lifecycle.throttleDelay * MQTT_CONFIG.RETRY_MULTIPLIER,
94308
94711
  MQTT_CONFIG.MAX_THROTTLE_DELAY
94309
94712
  );
94310
94713
  } else {
94311
- 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
+ );
94312
94718
  lifecycle.delay = Math.min(lifecycle.delay * MQTT_CONFIG.RETRY_MULTIPLIER, MQTT_CONFIG.MAX_RETRY_DELAY);
94313
94719
  }
94314
94720
  lifecycle.attempts++;
@@ -94692,6 +95098,7 @@ var apiModules = {
94692
95098
  refreshFbDtsg: refreshFbDtsg_default,
94693
95099
  enableAutoSaveAppState: enableAutoSaveAppState_default,
94694
95100
  editMessage: editMessage_default,
95101
+ deleteMessage: deleteMessage_default,
94695
95102
  getMessage: getMessage_default,
94696
95103
  emoji: emoji_default,
94697
95104
  gcmember: gcmember_default,