@lazyneoaz/metachat 6.0.6 → 6.0.8

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.
Files changed (3) hide show
  1. package/dist/index.cjs +239 -93
  2. package/dist/index.mjs +239 -93
  3. package/package.json +2 -2
package/dist/index.cjs CHANGED
@@ -87484,9 +87484,14 @@ function httpGet_default(defaultFuncs, api, ctx) {
87484
87484
  return body;
87485
87485
  }).catch((err) => {
87486
87486
  error("httpGet", err);
87487
- if (typeof callback === "function") callback(err);
87487
+ if (typeof callback === "function") {
87488
+ callback(err);
87489
+ return null;
87490
+ }
87488
87491
  throw err;
87489
87492
  });
87493
+ returnPromise.catch(() => {
87494
+ });
87490
87495
  return returnPromise;
87491
87496
  };
87492
87497
  }
@@ -87510,9 +87515,14 @@ function httpPost_default(defaultFuncs, api, ctx) {
87510
87515
  return body;
87511
87516
  }).catch((err) => {
87512
87517
  error("httpPost", err);
87513
- if (typeof callback === "function") callback(err);
87518
+ if (typeof callback === "function") {
87519
+ callback(err);
87520
+ return null;
87521
+ }
87514
87522
  throw err;
87515
87523
  });
87524
+ returnPromise.catch(() => {
87525
+ });
87516
87526
  return returnPromise;
87517
87527
  };
87518
87528
  }
@@ -87536,9 +87546,14 @@ function httpPostFormData_default(defaultFuncs, api, ctx) {
87536
87546
  return body;
87537
87547
  }).catch((err) => {
87538
87548
  error("httpPostFormData", err);
87539
- if (typeof callback === "function") callback(err);
87549
+ if (typeof callback === "function") {
87550
+ callback(err);
87551
+ return null;
87552
+ }
87540
87553
  throw err;
87541
87554
  });
87555
+ returnPromise.catch(() => {
87556
+ });
87542
87557
  return returnPromise;
87543
87558
  };
87544
87559
  }
@@ -87901,37 +87916,72 @@ function enableAutoSaveAppState_default(_defaultFuncs, api, ctx) {
87901
87916
  }
87902
87917
 
87903
87918
  // src/deltas/apis/messaging/editMessage.ts
87919
+ function extractEditedMessage(message) {
87920
+ try {
87921
+ const candidate = message?.payload?.step?.[1]?.[2]?.[2]?.[1];
87922
+ const messageID = String(candidate?.[2] || "");
87923
+ const body = String(candidate?.[4] || "");
87924
+ return { messageID: messageID || void 0, body: body || void 0 };
87925
+ } catch {
87926
+ return {};
87927
+ }
87928
+ }
87904
87929
  function editMessage_default(_defaultFuncs, _api, ctx) {
87905
- return async function editMessage(text3, messageID, callback) {
87930
+ return function editMessage(text3, messageID, callback) {
87906
87931
  const cb = typeof callback === "function" ? callback : void 0;
87907
- try {
87908
- if (!ctx.mqttClient || !ctx.mqttClient.connected) {
87909
- throw new Error("Not connected to MQTT");
87932
+ const fail = (err) => {
87933
+ error("editMessage", err?.error || err?.message || err);
87934
+ if (cb) {
87935
+ cb(err);
87936
+ return { error: err?.error || err?.message || String(err), success: false };
87910
87937
  }
87911
- const query = {
87912
- failure_count: null,
87913
- label: "742",
87914
- payload: JSON.stringify({
87915
- message_id: messageID,
87916
- text: text3
87917
- }),
87918
- queue_name: "edit_message"
87919
- };
87920
- const content = buildWsTaskContent(ctx, [query], "6903494529735864");
87921
- const result = await publishLsRequestWithAck({
87922
- client: ctx.mqttClient,
87923
- content,
87924
- requestId: content.request_id,
87925
- extract: (parsed) => parsed
87926
- });
87927
- const out = { messageID, text: text3, success: !result?.error };
87938
+ throw err;
87939
+ };
87940
+ if (!ctx.mqttClient || !ctx.mqttClient.connected) {
87941
+ return fail(new Error("Not connected to MQTT"));
87942
+ }
87943
+ if (!text3 || !messageID) {
87944
+ return fail(new Error("text and messageID are required"));
87945
+ }
87946
+ const query = {
87947
+ failure_count: null,
87948
+ label: "742",
87949
+ payload: JSON.stringify({
87950
+ message_id: messageID,
87951
+ text: text3
87952
+ }),
87953
+ queue_name: "edit_message"
87954
+ };
87955
+ const content = buildWsTaskContent(ctx, [query], "6903494529735864");
87956
+ const promise = publishLsRequestWithAck({
87957
+ client: ctx.mqttClient,
87958
+ content,
87959
+ requestId: content.request_id,
87960
+ extract: (parsed) => parsed
87961
+ }).then((parsed) => {
87962
+ const { body } = extractEditedMessage(parsed);
87963
+ if (body && body !== text3) {
87964
+ const error2 = { error: "The message is too old or not from you!", success: false };
87965
+ if (cb) {
87966
+ cb(error2);
87967
+ return error2;
87968
+ }
87969
+ throw error2;
87970
+ }
87971
+ const out = { messageID, text: text3, success: true };
87928
87972
  if (cb) cb(null, out);
87929
87973
  return out;
87930
- } catch (err) {
87974
+ }).catch((err) => {
87931
87975
  error("editMessage", err?.error || err?.message || err);
87932
- if (cb) return cb(err);
87976
+ if (cb) {
87977
+ cb(err);
87978
+ return { error: err?.error || err?.message || String(err), success: false };
87979
+ }
87933
87980
  throw err;
87934
- }
87981
+ });
87982
+ promise.catch(() => {
87983
+ });
87984
+ return promise;
87935
87985
  };
87936
87986
  }
87937
87987
 
@@ -88146,6 +88196,8 @@ function emoji_default(defaultFuncs, api, ctx) {
88146
88196
  _callback = void 0;
88147
88197
  _initiatorID = void 0;
88148
88198
  }
88199
+ returnPromise.catch(() => {
88200
+ });
88149
88201
  if (!_callback) {
88150
88202
  _callback = function(__err, __data) {
88151
88203
  if (__err) _rejectPromise(__err);
@@ -88156,7 +88208,7 @@ function emoji_default(defaultFuncs, api, ctx) {
88156
88208
  _callback = function(__err, __data) {
88157
88209
  if (__err) {
88158
88210
  originalCallback(__err);
88159
- _rejectPromise(__err);
88211
+ _resolvePromise(void 0);
88160
88212
  } else {
88161
88213
  originalCallback(null, __data);
88162
88214
  _resolvePromise(__data);
@@ -88174,6 +88226,8 @@ function emoji_default(defaultFuncs, api, ctx) {
88174
88226
  if (!ctx.mqttClient) {
88175
88227
  return _callback(new Error("Not connected to MQTT"));
88176
88228
  }
88229
+ if (typeof ctx.wsReqNumber !== "number") ctx.wsReqNumber = 0;
88230
+ if (typeof ctx.wsTaskNumber !== "number") ctx.wsTaskNumber = 0;
88177
88231
  ctx.wsReqNumber += 1;
88178
88232
  ctx.wsTaskNumber += 1;
88179
88233
  const queryPayload = {
@@ -88355,6 +88409,8 @@ function gcname_default(defaultFuncs, api, ctx) {
88355
88409
  _callback = void 0;
88356
88410
  _initiatorID = void 0;
88357
88411
  }
88412
+ returnPromise.catch(() => {
88413
+ });
88358
88414
  if (!_callback) {
88359
88415
  _callback = function(__err, __data) {
88360
88416
  if (__err) _rejectPromise(__err);
@@ -88365,7 +88421,7 @@ function gcname_default(defaultFuncs, api, ctx) {
88365
88421
  _callback = function(__err, __data) {
88366
88422
  if (__err) {
88367
88423
  originalCallback(__err);
88368
- _rejectPromise(__err);
88424
+ _resolvePromise(void 0);
88369
88425
  } else {
88370
88426
  originalCallback(null, __data);
88371
88427
  _resolvePromise(__data);
@@ -88383,6 +88439,8 @@ function gcname_default(defaultFuncs, api, ctx) {
88383
88439
  if (!ctx.mqttClient) {
88384
88440
  return _callback(new Error("Not connected to MQTT"));
88385
88441
  }
88442
+ if (typeof ctx.wsReqNumber !== "number") ctx.wsReqNumber = 0;
88443
+ if (typeof ctx.wsTaskNumber !== "number") ctx.wsTaskNumber = 0;
88386
88444
  ctx.wsReqNumber += 1;
88387
88445
  ctx.wsTaskNumber += 1;
88388
88446
  const queryPayload = {
@@ -88523,28 +88581,41 @@ function gcrule_default(defaultFuncs, api, ctx) {
88523
88581
 
88524
88582
  // src/deltas/apis/messaging/markAsDelivered.ts
88525
88583
  function markAsDelivered_default(defaultFuncs, api, ctx) {
88526
- return async function markAsDelivered(threadID, messageID) {
88527
- if (!threadID || !messageID) {
88528
- const err = "Error: messageID or threadID is not defined";
88584
+ return function markAsDelivered(threadID, messageID, callback) {
88585
+ const cb = typeof callback === "function" ? callback : void 0;
88586
+ const fail = (err) => {
88529
88587
  error("markAsDelivered", err);
88530
- throw new Error(err);
88588
+ if (cb) {
88589
+ cb(err);
88590
+ return;
88591
+ }
88592
+ throw err;
88593
+ };
88594
+ if (!threadID || !messageID) {
88595
+ return fail("Error: messageID or threadID is not defined");
88531
88596
  }
88532
88597
  const form = {};
88533
88598
  form["message_ids[0]"] = messageID;
88534
88599
  form["thread_ids[" + threadID + "][0]"] = messageID;
88535
- try {
88536
- const resData = await defaultFuncs.post(
88537
- "https://www.facebook.com/ajax/mercury/delivery_receipts.php",
88538
- ctx.jar,
88539
- form
88540
- ).then(saveCookies(ctx.jar)).then(parseAndCheckLogin(ctx, defaultFuncs));
88541
- if (resData.error) {
88542
- throw resData;
88543
- }
88544
- } catch (err) {
88600
+ const promise = defaultFuncs.post(
88601
+ "https://www.facebook.com/ajax/mercury/delivery_receipts.php",
88602
+ ctx.jar,
88603
+ form
88604
+ ).then(saveCookies(ctx.jar)).then(parseAndCheckLogin(ctx, defaultFuncs)).then((resData) => {
88605
+ if (resData && resData.error) throw resData;
88606
+ if (cb) cb(null, resData);
88607
+ return resData;
88608
+ }).catch((err) => {
88545
88609
  error("markAsDelivered", err);
88610
+ if (cb) {
88611
+ cb(err);
88612
+ return null;
88613
+ }
88546
88614
  throw err;
88547
- }
88615
+ });
88616
+ promise.catch(() => {
88617
+ });
88618
+ return promise;
88548
88619
  };
88549
88620
  }
88550
88621
 
@@ -88632,20 +88703,27 @@ function markAsRead_default(defaultFuncs, api, ctx) {
88632
88703
 
88633
88704
  // src/deltas/apis/messaging/markAsReadAll.ts
88634
88705
  function markAsReadAll_default(defaultFuncs, api, ctx) {
88635
- return async function markAsReadAll() {
88636
- try {
88637
- const resData = await defaultFuncs.post(
88638
- "https://www.facebook.com/ajax/mercury/mark_folder_as_read.php",
88639
- ctx.jar,
88640
- { folder: "inbox" }
88641
- );
88642
- const parsedData = await parseAndCheckLogin(ctx, defaultFuncs)(resData);
88643
- if (parsedData.error) throw parsedData;
88644
- return;
88645
- } catch (err) {
88706
+ return function markAsReadAll(callback) {
88707
+ const cb = typeof callback === "function" ? callback : void 0;
88708
+ const promise = defaultFuncs.post(
88709
+ "https://www.facebook.com/ajax/mercury/mark_folder_as_read.php",
88710
+ ctx.jar,
88711
+ { folder: "inbox" }
88712
+ ).then((resData) => parseAndCheckLogin(ctx, defaultFuncs)(resData)).then((parsedData) => {
88713
+ if (parsedData && parsedData.error) throw parsedData;
88714
+ if (cb) cb(null, parsedData);
88715
+ return parsedData;
88716
+ }).catch((err) => {
88646
88717
  error("markAsReadAll", err);
88718
+ if (cb) {
88719
+ cb(err);
88720
+ return null;
88721
+ }
88647
88722
  throw err;
88648
- }
88723
+ });
88724
+ promise.catch(() => {
88725
+ });
88726
+ return promise;
88649
88727
  };
88650
88728
  }
88651
88729
 
@@ -88673,6 +88751,16 @@ function markAsSeen_default(defaultFuncs, api, ctx) {
88673
88751
  }
88674
88752
  resolveFunc(friendList);
88675
88753
  };
88754
+ } else {
88755
+ const originalCallback = callback;
88756
+ callback = function(err, data2) {
88757
+ try {
88758
+ originalCallback(err, data2);
88759
+ } finally {
88760
+ if (err) resolveFunc(void 0);
88761
+ else resolveFunc(data2);
88762
+ }
88763
+ };
88676
88764
  }
88677
88765
  const form = {
88678
88766
  seen_timestamp
@@ -88724,6 +88812,8 @@ function nickname_default(defaultFuncs, api, ctx) {
88724
88812
  _callback = void 0;
88725
88813
  _initiatorID = void 0;
88726
88814
  }
88815
+ returnPromise.catch(() => {
88816
+ });
88727
88817
  if (!_callback) {
88728
88818
  _callback = function(__err, __data) {
88729
88819
  if (__err) _rejectPromise(__err);
@@ -88734,7 +88824,7 @@ function nickname_default(defaultFuncs, api, ctx) {
88734
88824
  _callback = function(__err, __data) {
88735
88825
  if (__err) {
88736
88826
  originalCallback(__err);
88737
- _rejectPromise(__err);
88827
+ _resolvePromise(void 0);
88738
88828
  } else {
88739
88829
  originalCallback(null, __data);
88740
88830
  _resolvePromise(__data);
@@ -88753,6 +88843,8 @@ function nickname_default(defaultFuncs, api, ctx) {
88753
88843
  if (!ctx.mqttClient) {
88754
88844
  return _callback(new Error("Not connected to MQTT"));
88755
88845
  }
88846
+ if (typeof ctx.wsReqNumber !== "number") ctx.wsReqNumber = 0;
88847
+ if (typeof ctx.wsTaskNumber !== "number") ctx.wsTaskNumber = 0;
88756
88848
  ctx.wsReqNumber += 1;
88757
88849
  ctx.wsTaskNumber += 1;
88758
88850
  const queryPayload = {
@@ -89329,8 +89421,9 @@ var sendMessage_default = (defaultFuncs, api, ctx) => {
89329
89421
 
89330
89422
  // src/deltas/apis/messaging/sendTypingIndicator.ts
89331
89423
  function sendTypingIndicator_default(defaultFuncs, api, ctx) {
89332
- return async function sendTypingIndicatorV2(sendTyping, threadID, options, callback) {
89424
+ return function sendTypingIndicatorV2(sendTyping, threadID, options, callback) {
89333
89425
  if (typeof options === "function") {
89426
+ callback = options;
89334
89427
  options = {};
89335
89428
  }
89336
89429
  options = options || {};
@@ -89343,14 +89436,23 @@ function sendTypingIndicator_default(defaultFuncs, api, ctx) {
89343
89436
  actualSendTyping = sendTyping;
89344
89437
  actualThreadID = threadID;
89345
89438
  }
89439
+ const fail = (message) => {
89440
+ const err = new Error(message);
89441
+ if (typeof callback === "function") {
89442
+ callback(err);
89443
+ return Promise.resolve(null);
89444
+ }
89445
+ return Promise.reject(err);
89446
+ };
89346
89447
  if (!actualThreadID) {
89347
- throw new Error("sendTypingIndicator: threadID is required");
89448
+ return fail("sendTypingIndicator: threadID is required");
89348
89449
  }
89349
89450
  if (!ctx.mqttClient || !ctx.mqttClient.connected) {
89350
- throw new Error("sendTypingIndicator: not connected to MQTT");
89451
+ return fail("sendTypingIndicator: not connected to MQTT");
89351
89452
  }
89352
89453
  const threadIDs = Array.isArray(actualThreadID) ? actualThreadID : [actualThreadID];
89353
89454
  const attribution = options.type || 0;
89455
+ const publishPromises = [];
89354
89456
  const publishTyping = (tid, isTyping) => {
89355
89457
  ctx.wsReqNumber = (ctx.wsReqNumber || 0) + 1;
89356
89458
  const isGroupThread = String(tid).length >= 16 ? 1 : 0;
@@ -89380,18 +89482,26 @@ function sendTypingIndicator_default(defaultFuncs, api, ctx) {
89380
89482
  );
89381
89483
  });
89382
89484
  };
89383
- await Promise.all(threadIDs.map((tid) => publishTyping(tid, actualSendTyping)));
89384
89485
  const duration = options.duration || 1e4;
89385
89486
  const autoStop = options.autoStop !== false;
89386
- if (actualSendTyping && autoStop) {
89387
- threadIDs.forEach((tid) => {
89388
- setTimeout(() => {
89389
- publishTyping(tid, false).catch(() => {
89390
- });
89391
- }, duration);
89487
+ threadIDs.forEach((tid) => {
89488
+ const p = publishTyping(tid, actualSendTyping).then(() => {
89489
+ if (actualSendTyping && autoStop) {
89490
+ setTimeout(() => {
89491
+ publishTyping(tid, false).catch(() => {
89492
+ });
89493
+ }, duration);
89494
+ }
89495
+ return true;
89392
89496
  });
89497
+ publishPromises.push(p);
89498
+ });
89499
+ const result = Promise.all(publishPromises).then(() => true);
89500
+ if (typeof callback === "function") {
89501
+ result.then(() => callback(null, true)).catch((err) => callback(err));
89502
+ return result.catch(() => null);
89393
89503
  }
89394
- return true;
89504
+ return result;
89395
89505
  };
89396
89506
  }
89397
89507
 
@@ -89780,6 +89890,8 @@ function theme_default(defaultFuncs, api, ctx) {
89780
89890
  let currentEpochId = parseInt(generateOfflineThreadingID());
89781
89891
  const createAndPublish = (label, queueName, payload) => {
89782
89892
  currentEpochId = parseInt(generateOfflineThreadingID());
89893
+ if (typeof ctx.wsReqNumber !== "number") ctx.wsReqNumber = 0;
89894
+ if (typeof ctx.wsTaskNumber !== "number") ctx.wsTaskNumber = 0;
89783
89895
  ctx.wsReqNumber += 1;
89784
89896
  ctx.wsTaskNumber += 1;
89785
89897
  const request_id = ctx.wsReqNumber;
@@ -89886,6 +89998,8 @@ function setThreadTheme_default(defaultFuncs, _api, ctx) {
89886
89998
  }
89887
89999
  throw error2;
89888
90000
  }
90001
+ if (typeof ctx.wsReqNumber !== "number") ctx.wsReqNumber = 0;
90002
+ if (typeof ctx.wsTaskNumber !== "number") ctx.wsTaskNumber = 0;
89889
90003
  ctx.wsReqNumber += 1;
89890
90004
  let baseTaskNumber = ++ctx.wsTaskNumber;
89891
90005
  const makeTask = (label, queueName, extraPayload = {}) => ({
@@ -89907,6 +90021,7 @@ function setThreadTheme_default(defaultFuncs, _api, ctx) {
89907
90021
  { label: 43, queue: "thread_theme", extra: { source: null, payload: null } }
89908
90022
  ];
89909
90023
  const messages = definitions.map(({ label, queue, extra }) => {
90024
+ if (typeof ctx.wsReqNumber !== "number") ctx.wsReqNumber = 0;
89910
90025
  ctx.wsReqNumber += 1;
89911
90026
  return {
89912
90027
  app_id: "2220391788200892",
@@ -90057,15 +90172,8 @@ async function publishThreadTask(ctx, label, queueName, payload, versionId, appI
90057
90172
  requestId: content.request_id,
90058
90173
  extract: (parsed) => {
90059
90174
  const body = parsed && parsed.payload;
90060
- const error2 = body && (body.error || body.errorDescription);
90061
- if (error2) {
90062
- const err = new Error(
90063
- typeof error2 === "string" ? error2 : error2.message || "MQTT task was rejected"
90064
- );
90065
- err.error = error2;
90066
- throw err;
90067
- }
90068
- return body || { success: true };
90175
+ if (!body || typeof body !== "object") return { success: true };
90176
+ return body;
90069
90177
  }
90070
90178
  });
90071
90179
  }
@@ -90096,8 +90204,13 @@ function unsendMessage_default(defaultFuncs, _api, ctx) {
90096
90204
  _resolve = resolve;
90097
90205
  _reject = reject;
90098
90206
  });
90207
+ returnPromise.catch(() => {
90208
+ });
90099
90209
  const done = (err, data2) => {
90100
- if (cb) cb(err, data2);
90210
+ if (cb) {
90211
+ cb(err, data2);
90212
+ return;
90213
+ }
90101
90214
  if (err) _reject(err);
90102
90215
  else _resolve(data2);
90103
90216
  };
@@ -90865,6 +90978,7 @@ function pinMessage_default(defaultFuncs, api, ctx) {
90865
90978
  }
90866
90979
 
90867
90980
  // src/deltas/apis/mqtt/sendMessageMqtt.ts
90981
+ var DEFAULT_RETRY_DELAYS_MS = [900, 1600, 2400, 3500, 5e3, 7e3];
90868
90982
  function preUploadedId(item) {
90869
90983
  if (typeof item === "number" && Number.isFinite(item)) return String(item);
90870
90984
  if (typeof item === "string" && /^\d{6,}$/.test(item.trim())) return item.trim();
@@ -91013,7 +91127,7 @@ var sendMessageMqtt_default = (defaultFuncs, api, ctx) => {
91013
91127
  attachmentIds = ids;
91014
91128
  } catch (err) {
91015
91129
  error("Attachment upload failed:", err);
91016
- callback(err);
91130
+ finish(err);
91017
91131
  return done();
91018
91132
  }
91019
91133
  }
@@ -91094,6 +91208,7 @@ var sendMessageMqtt_default = (defaultFuncs, api, ctx) => {
91094
91208
  let threadIDFromAck = null;
91095
91209
  let failure = null;
91096
91210
  let serverError = null;
91211
+ let softFailure = null;
91097
91212
  const steps = parsed.payload?.step;
91098
91213
  const visit = (node) => {
91099
91214
  if (!Array.isArray(node)) return;
@@ -91105,12 +91220,10 @@ var sendMessageMqtt_default = (defaultFuncs, api, ctx) => {
91105
91220
  threadIDFromAck = String(node[2][1]);
91106
91221
  }
91107
91222
  if (node[1] === "markOptimisticMessageFailed") {
91108
- const detail = typeof node[3] === "string" ? node[3] : "Message failed on server.";
91109
- failure = { error: detail, errorDescription: "Message failed on server." };
91223
+ softFailure = typeof node[3] === "string" ? node[3] : "Message failed on server.";
91110
91224
  }
91111
91225
  if (node[1] === "updateSubscriptErrorMessage" || node[1] === "fatalError") {
91112
- const detail = typeof node[3] === "string" ? node[3] : typeof node[4] === "string" ? node[4] : "Couldn't send.";
91113
- serverError = detail;
91226
+ softFailure = typeof node[3] === "string" ? node[3] : typeof node[4] === "string" ? node[4] : "Couldn't send.";
91114
91227
  }
91115
91228
  }
91116
91229
  for (const child of node) visit(child);
@@ -91120,7 +91233,8 @@ var sendMessageMqtt_default = (defaultFuncs, api, ctx) => {
91120
91233
  messageID: resolvedMessageID,
91121
91234
  threadID: threadIDFromAck,
91122
91235
  failure,
91123
- serverError
91236
+ serverError,
91237
+ softFailure
91124
91238
  });
91125
91239
  };
91126
91240
  if (mqttClient && typeof mqttClient.on === "function") {
@@ -91131,14 +91245,21 @@ var sendMessageMqtt_default = (defaultFuncs, api, ctx) => {
91131
91245
  });
91132
91246
  timer = setTimeout(() => settle2({ timeout: true }), 15e3);
91133
91247
  });
91248
+ const retryDelays = (() => {
91249
+ const override = ctx.globalOptions && ctx.globalOptions.mqttSendRetryDelaysMs;
91250
+ return Array.isArray(override) && override.length ? override : DEFAULT_RETRY_DELAYS_MS;
91251
+ })();
91134
91252
  let result = null;
91135
91253
  let lastOtid = "";
91136
- for (let attempt = 0; attempt < 3; attempt++) {
91254
+ for (let attempt = 0; attempt <= retryDelays.length; attempt++) {
91137
91255
  const built = buildForm();
91138
91256
  lastOtid = built.otid;
91139
91257
  result = await publishAndWait(built.form, built.request_id);
91140
- if (!result.failure && !result.serverError) break;
91141
- if (attempt < 2) await sleep(700 + attempt * 900 + Math.floor(Math.random() * 400));
91258
+ if (!result.failure && !result.serverError && !result.softFailure) break;
91259
+ if ((result.failure || result.serverError) && attempt >= 2) break;
91260
+ if (attempt < retryDelays.length) {
91261
+ await sleep(retryDelays[attempt] + Math.floor(Math.random() * 400));
91262
+ }
91142
91263
  }
91143
91264
  if (result.failure || result.serverError) {
91144
91265
  const err = result.failure || { error: result.serverError };
@@ -91151,6 +91272,21 @@ var sendMessageMqtt_default = (defaultFuncs, api, ctx) => {
91151
91272
  finish(err);
91152
91273
  return done();
91153
91274
  }
91275
+ if (result.softFailure) {
91276
+ warn(
91277
+ "sendMessageMqtt [MQTT]",
91278
+ `Facebook rejected the message (${result.softFailure}); thread ${threadID}. Retried ${retryDelays.length} times without success; continuing without failing the bot.`
91279
+ );
91280
+ finish(null, {
91281
+ threadID: result.threadID || threadID.toString(),
91282
+ messageID: result.messageID || null,
91283
+ timestamp,
91284
+ type: replyToMessage ? "message_reply" : "message",
91285
+ error: result.softFailure,
91286
+ success: false
91287
+ });
91288
+ return done();
91289
+ }
91154
91290
  finish(null, {
91155
91291
  threadID: result.threadID || threadID.toString(),
91156
91292
  messageID: result.messageID || `mid.${lastOtid}`,
@@ -92920,8 +93056,13 @@ function createPoll_default(_defaultFuncs, _api, ctx) {
92920
93056
  _resolve = resolve;
92921
93057
  _reject = reject;
92922
93058
  });
93059
+ promise.catch(() => {
93060
+ });
92923
93061
  const done = (err, data2) => {
92924
- if (cb) cb(err, data2);
93062
+ if (cb) {
93063
+ cb(err, data2);
93064
+ return;
93065
+ }
92925
93066
  if (err) _reject(err);
92926
93067
  else _resolve(data2);
92927
93068
  };
@@ -93781,7 +93922,7 @@ function parseDelta(defaultFuncs, api, ctx, globalCallback, v) {
93781
93922
  if (v.delta.class == "NewMessage") {
93782
93923
  if (ctx.globalOptions.pageID && ctx.globalOptions.pageID != v.queue) return;
93783
93924
  (function resolveAttachmentUrl(i2) {
93784
- if (v.delta.attachments && i2 == v.delta.attachments.length) {
93925
+ if (!v.delta.attachments || !Array.isArray(v.delta.attachments) || i2 >= v.delta.attachments.length) {
93785
93926
  let fmtMsg;
93786
93927
  try {
93787
93928
  fmtMsg = formatDeltaMessage(v);
@@ -93972,11 +94113,11 @@ function installTeardownGuard() {
93972
94113
  const isTeardownNoise = (err) => !!err && (err.code === "MQTT_CONNECTION_CLOSED" || /Connection closed|client disconnecting/i.test(String(err && err.message ? err.message : err))) && !/error_gc|1357001|checkpoint/i.test(String(err && err.message ? err.message : err));
93973
94114
  process.on("uncaughtException", (err) => {
93974
94115
  if (isTeardownNoise(err)) return;
93975
- throw err;
94116
+ error("uncaughtException", err);
93976
94117
  });
93977
94118
  process.on("unhandledRejection", (reason) => {
93978
94119
  if (isTeardownNoise(reason)) return;
93979
- throw reason;
94120
+ error("unhandledRejection", reason);
93980
94121
  });
93981
94122
  }
93982
94123
  var MQTT_TOPICS = [
@@ -94962,13 +95103,18 @@ async function login(credentials, options, callback) {
94962
95103
  const finish = (error2, loginApi) => {
94963
95104
  if (settled) return;
94964
95105
  settled = true;
95106
+ const hasCallback = typeof callback === "function";
94965
95107
  try {
94966
95108
  callback?.(error2 || null, loginApi);
94967
95109
  } catch (callbackError) {
94968
95110
  error("login callback", callbackError);
94969
95111
  }
94970
- if (error2) reject(error2);
94971
- else resolve(loginApi);
95112
+ if (error2) {
95113
+ if (hasCallback) resolve(loginApi);
95114
+ else reject(error2);
95115
+ } else {
95116
+ resolve(loginApi);
95117
+ }
94972
95118
  };
94973
95119
  loginHelper(
94974
95120
  credentials,
package/dist/index.mjs CHANGED
@@ -87452,9 +87452,14 @@ function httpGet_default(defaultFuncs, api, ctx) {
87452
87452
  return body;
87453
87453
  }).catch((err) => {
87454
87454
  error("httpGet", err);
87455
- if (typeof callback === "function") callback(err);
87455
+ if (typeof callback === "function") {
87456
+ callback(err);
87457
+ return null;
87458
+ }
87456
87459
  throw err;
87457
87460
  });
87461
+ returnPromise.catch(() => {
87462
+ });
87458
87463
  return returnPromise;
87459
87464
  };
87460
87465
  }
@@ -87478,9 +87483,14 @@ function httpPost_default(defaultFuncs, api, ctx) {
87478
87483
  return body;
87479
87484
  }).catch((err) => {
87480
87485
  error("httpPost", err);
87481
- if (typeof callback === "function") callback(err);
87486
+ if (typeof callback === "function") {
87487
+ callback(err);
87488
+ return null;
87489
+ }
87482
87490
  throw err;
87483
87491
  });
87492
+ returnPromise.catch(() => {
87493
+ });
87484
87494
  return returnPromise;
87485
87495
  };
87486
87496
  }
@@ -87504,9 +87514,14 @@ function httpPostFormData_default(defaultFuncs, api, ctx) {
87504
87514
  return body;
87505
87515
  }).catch((err) => {
87506
87516
  error("httpPostFormData", err);
87507
- if (typeof callback === "function") callback(err);
87517
+ if (typeof callback === "function") {
87518
+ callback(err);
87519
+ return null;
87520
+ }
87508
87521
  throw err;
87509
87522
  });
87523
+ returnPromise.catch(() => {
87524
+ });
87510
87525
  return returnPromise;
87511
87526
  };
87512
87527
  }
@@ -87869,37 +87884,72 @@ function enableAutoSaveAppState_default(_defaultFuncs, api, ctx) {
87869
87884
  }
87870
87885
 
87871
87886
  // src/deltas/apis/messaging/editMessage.ts
87887
+ function extractEditedMessage(message) {
87888
+ try {
87889
+ const candidate = message?.payload?.step?.[1]?.[2]?.[2]?.[1];
87890
+ const messageID = String(candidate?.[2] || "");
87891
+ const body = String(candidate?.[4] || "");
87892
+ return { messageID: messageID || void 0, body: body || void 0 };
87893
+ } catch {
87894
+ return {};
87895
+ }
87896
+ }
87872
87897
  function editMessage_default(_defaultFuncs, _api, ctx) {
87873
- return async function editMessage(text3, messageID, callback) {
87898
+ return function editMessage(text3, messageID, callback) {
87874
87899
  const cb = typeof callback === "function" ? callback : void 0;
87875
- try {
87876
- if (!ctx.mqttClient || !ctx.mqttClient.connected) {
87877
- throw new Error("Not connected to MQTT");
87900
+ const fail = (err) => {
87901
+ error("editMessage", err?.error || err?.message || err);
87902
+ if (cb) {
87903
+ cb(err);
87904
+ return { error: err?.error || err?.message || String(err), success: false };
87878
87905
  }
87879
- const query = {
87880
- failure_count: null,
87881
- label: "742",
87882
- payload: JSON.stringify({
87883
- message_id: messageID,
87884
- text: text3
87885
- }),
87886
- queue_name: "edit_message"
87887
- };
87888
- const content = buildWsTaskContent(ctx, [query], "6903494529735864");
87889
- const result = await publishLsRequestWithAck({
87890
- client: ctx.mqttClient,
87891
- content,
87892
- requestId: content.request_id,
87893
- extract: (parsed) => parsed
87894
- });
87895
- const out = { messageID, text: text3, success: !result?.error };
87906
+ throw err;
87907
+ };
87908
+ if (!ctx.mqttClient || !ctx.mqttClient.connected) {
87909
+ return fail(new Error("Not connected to MQTT"));
87910
+ }
87911
+ if (!text3 || !messageID) {
87912
+ return fail(new Error("text and messageID are required"));
87913
+ }
87914
+ const query = {
87915
+ failure_count: null,
87916
+ label: "742",
87917
+ payload: JSON.stringify({
87918
+ message_id: messageID,
87919
+ text: text3
87920
+ }),
87921
+ queue_name: "edit_message"
87922
+ };
87923
+ const content = buildWsTaskContent(ctx, [query], "6903494529735864");
87924
+ const promise = publishLsRequestWithAck({
87925
+ client: ctx.mqttClient,
87926
+ content,
87927
+ requestId: content.request_id,
87928
+ extract: (parsed) => parsed
87929
+ }).then((parsed) => {
87930
+ const { body } = extractEditedMessage(parsed);
87931
+ if (body && body !== text3) {
87932
+ const error2 = { error: "The message is too old or not from you!", success: false };
87933
+ if (cb) {
87934
+ cb(error2);
87935
+ return error2;
87936
+ }
87937
+ throw error2;
87938
+ }
87939
+ const out = { messageID, text: text3, success: true };
87896
87940
  if (cb) cb(null, out);
87897
87941
  return out;
87898
- } catch (err) {
87942
+ }).catch((err) => {
87899
87943
  error("editMessage", err?.error || err?.message || err);
87900
- if (cb) return cb(err);
87944
+ if (cb) {
87945
+ cb(err);
87946
+ return { error: err?.error || err?.message || String(err), success: false };
87947
+ }
87901
87948
  throw err;
87902
- }
87949
+ });
87950
+ promise.catch(() => {
87951
+ });
87952
+ return promise;
87903
87953
  };
87904
87954
  }
87905
87955
 
@@ -88114,6 +88164,8 @@ function emoji_default(defaultFuncs, api, ctx) {
88114
88164
  _callback = void 0;
88115
88165
  _initiatorID = void 0;
88116
88166
  }
88167
+ returnPromise.catch(() => {
88168
+ });
88117
88169
  if (!_callback) {
88118
88170
  _callback = function(__err, __data) {
88119
88171
  if (__err) _rejectPromise(__err);
@@ -88124,7 +88176,7 @@ function emoji_default(defaultFuncs, api, ctx) {
88124
88176
  _callback = function(__err, __data) {
88125
88177
  if (__err) {
88126
88178
  originalCallback(__err);
88127
- _rejectPromise(__err);
88179
+ _resolvePromise(void 0);
88128
88180
  } else {
88129
88181
  originalCallback(null, __data);
88130
88182
  _resolvePromise(__data);
@@ -88142,6 +88194,8 @@ function emoji_default(defaultFuncs, api, ctx) {
88142
88194
  if (!ctx.mqttClient) {
88143
88195
  return _callback(new Error("Not connected to MQTT"));
88144
88196
  }
88197
+ if (typeof ctx.wsReqNumber !== "number") ctx.wsReqNumber = 0;
88198
+ if (typeof ctx.wsTaskNumber !== "number") ctx.wsTaskNumber = 0;
88145
88199
  ctx.wsReqNumber += 1;
88146
88200
  ctx.wsTaskNumber += 1;
88147
88201
  const queryPayload = {
@@ -88323,6 +88377,8 @@ function gcname_default(defaultFuncs, api, ctx) {
88323
88377
  _callback = void 0;
88324
88378
  _initiatorID = void 0;
88325
88379
  }
88380
+ returnPromise.catch(() => {
88381
+ });
88326
88382
  if (!_callback) {
88327
88383
  _callback = function(__err, __data) {
88328
88384
  if (__err) _rejectPromise(__err);
@@ -88333,7 +88389,7 @@ function gcname_default(defaultFuncs, api, ctx) {
88333
88389
  _callback = function(__err, __data) {
88334
88390
  if (__err) {
88335
88391
  originalCallback(__err);
88336
- _rejectPromise(__err);
88392
+ _resolvePromise(void 0);
88337
88393
  } else {
88338
88394
  originalCallback(null, __data);
88339
88395
  _resolvePromise(__data);
@@ -88351,6 +88407,8 @@ function gcname_default(defaultFuncs, api, ctx) {
88351
88407
  if (!ctx.mqttClient) {
88352
88408
  return _callback(new Error("Not connected to MQTT"));
88353
88409
  }
88410
+ if (typeof ctx.wsReqNumber !== "number") ctx.wsReqNumber = 0;
88411
+ if (typeof ctx.wsTaskNumber !== "number") ctx.wsTaskNumber = 0;
88354
88412
  ctx.wsReqNumber += 1;
88355
88413
  ctx.wsTaskNumber += 1;
88356
88414
  const queryPayload = {
@@ -88491,28 +88549,41 @@ function gcrule_default(defaultFuncs, api, ctx) {
88491
88549
 
88492
88550
  // src/deltas/apis/messaging/markAsDelivered.ts
88493
88551
  function markAsDelivered_default(defaultFuncs, api, ctx) {
88494
- return async function markAsDelivered(threadID, messageID) {
88495
- if (!threadID || !messageID) {
88496
- const err = "Error: messageID or threadID is not defined";
88552
+ return function markAsDelivered(threadID, messageID, callback) {
88553
+ const cb = typeof callback === "function" ? callback : void 0;
88554
+ const fail = (err) => {
88497
88555
  error("markAsDelivered", err);
88498
- throw new Error(err);
88556
+ if (cb) {
88557
+ cb(err);
88558
+ return;
88559
+ }
88560
+ throw err;
88561
+ };
88562
+ if (!threadID || !messageID) {
88563
+ return fail("Error: messageID or threadID is not defined");
88499
88564
  }
88500
88565
  const form = {};
88501
88566
  form["message_ids[0]"] = messageID;
88502
88567
  form["thread_ids[" + threadID + "][0]"] = messageID;
88503
- try {
88504
- const resData = await defaultFuncs.post(
88505
- "https://www.facebook.com/ajax/mercury/delivery_receipts.php",
88506
- ctx.jar,
88507
- form
88508
- ).then(saveCookies(ctx.jar)).then(parseAndCheckLogin(ctx, defaultFuncs));
88509
- if (resData.error) {
88510
- throw resData;
88511
- }
88512
- } catch (err) {
88568
+ const promise = defaultFuncs.post(
88569
+ "https://www.facebook.com/ajax/mercury/delivery_receipts.php",
88570
+ ctx.jar,
88571
+ form
88572
+ ).then(saveCookies(ctx.jar)).then(parseAndCheckLogin(ctx, defaultFuncs)).then((resData) => {
88573
+ if (resData && resData.error) throw resData;
88574
+ if (cb) cb(null, resData);
88575
+ return resData;
88576
+ }).catch((err) => {
88513
88577
  error("markAsDelivered", err);
88578
+ if (cb) {
88579
+ cb(err);
88580
+ return null;
88581
+ }
88514
88582
  throw err;
88515
- }
88583
+ });
88584
+ promise.catch(() => {
88585
+ });
88586
+ return promise;
88516
88587
  };
88517
88588
  }
88518
88589
 
@@ -88600,20 +88671,27 @@ function markAsRead_default(defaultFuncs, api, ctx) {
88600
88671
 
88601
88672
  // src/deltas/apis/messaging/markAsReadAll.ts
88602
88673
  function markAsReadAll_default(defaultFuncs, api, ctx) {
88603
- return async function markAsReadAll() {
88604
- try {
88605
- const resData = await defaultFuncs.post(
88606
- "https://www.facebook.com/ajax/mercury/mark_folder_as_read.php",
88607
- ctx.jar,
88608
- { folder: "inbox" }
88609
- );
88610
- const parsedData = await parseAndCheckLogin(ctx, defaultFuncs)(resData);
88611
- if (parsedData.error) throw parsedData;
88612
- return;
88613
- } catch (err) {
88674
+ return function markAsReadAll(callback) {
88675
+ const cb = typeof callback === "function" ? callback : void 0;
88676
+ const promise = defaultFuncs.post(
88677
+ "https://www.facebook.com/ajax/mercury/mark_folder_as_read.php",
88678
+ ctx.jar,
88679
+ { folder: "inbox" }
88680
+ ).then((resData) => parseAndCheckLogin(ctx, defaultFuncs)(resData)).then((parsedData) => {
88681
+ if (parsedData && parsedData.error) throw parsedData;
88682
+ if (cb) cb(null, parsedData);
88683
+ return parsedData;
88684
+ }).catch((err) => {
88614
88685
  error("markAsReadAll", err);
88686
+ if (cb) {
88687
+ cb(err);
88688
+ return null;
88689
+ }
88615
88690
  throw err;
88616
- }
88691
+ });
88692
+ promise.catch(() => {
88693
+ });
88694
+ return promise;
88617
88695
  };
88618
88696
  }
88619
88697
 
@@ -88641,6 +88719,16 @@ function markAsSeen_default(defaultFuncs, api, ctx) {
88641
88719
  }
88642
88720
  resolveFunc(friendList);
88643
88721
  };
88722
+ } else {
88723
+ const originalCallback = callback;
88724
+ callback = function(err, data2) {
88725
+ try {
88726
+ originalCallback(err, data2);
88727
+ } finally {
88728
+ if (err) resolveFunc(void 0);
88729
+ else resolveFunc(data2);
88730
+ }
88731
+ };
88644
88732
  }
88645
88733
  const form = {
88646
88734
  seen_timestamp
@@ -88692,6 +88780,8 @@ function nickname_default(defaultFuncs, api, ctx) {
88692
88780
  _callback = void 0;
88693
88781
  _initiatorID = void 0;
88694
88782
  }
88783
+ returnPromise.catch(() => {
88784
+ });
88695
88785
  if (!_callback) {
88696
88786
  _callback = function(__err, __data) {
88697
88787
  if (__err) _rejectPromise(__err);
@@ -88702,7 +88792,7 @@ function nickname_default(defaultFuncs, api, ctx) {
88702
88792
  _callback = function(__err, __data) {
88703
88793
  if (__err) {
88704
88794
  originalCallback(__err);
88705
- _rejectPromise(__err);
88795
+ _resolvePromise(void 0);
88706
88796
  } else {
88707
88797
  originalCallback(null, __data);
88708
88798
  _resolvePromise(__data);
@@ -88721,6 +88811,8 @@ function nickname_default(defaultFuncs, api, ctx) {
88721
88811
  if (!ctx.mqttClient) {
88722
88812
  return _callback(new Error("Not connected to MQTT"));
88723
88813
  }
88814
+ if (typeof ctx.wsReqNumber !== "number") ctx.wsReqNumber = 0;
88815
+ if (typeof ctx.wsTaskNumber !== "number") ctx.wsTaskNumber = 0;
88724
88816
  ctx.wsReqNumber += 1;
88725
88817
  ctx.wsTaskNumber += 1;
88726
88818
  const queryPayload = {
@@ -89297,8 +89389,9 @@ var sendMessage_default = (defaultFuncs, api, ctx) => {
89297
89389
 
89298
89390
  // src/deltas/apis/messaging/sendTypingIndicator.ts
89299
89391
  function sendTypingIndicator_default(defaultFuncs, api, ctx) {
89300
- return async function sendTypingIndicatorV2(sendTyping, threadID, options, callback) {
89392
+ return function sendTypingIndicatorV2(sendTyping, threadID, options, callback) {
89301
89393
  if (typeof options === "function") {
89394
+ callback = options;
89302
89395
  options = {};
89303
89396
  }
89304
89397
  options = options || {};
@@ -89311,14 +89404,23 @@ function sendTypingIndicator_default(defaultFuncs, api, ctx) {
89311
89404
  actualSendTyping = sendTyping;
89312
89405
  actualThreadID = threadID;
89313
89406
  }
89407
+ const fail = (message) => {
89408
+ const err = new Error(message);
89409
+ if (typeof callback === "function") {
89410
+ callback(err);
89411
+ return Promise.resolve(null);
89412
+ }
89413
+ return Promise.reject(err);
89414
+ };
89314
89415
  if (!actualThreadID) {
89315
- throw new Error("sendTypingIndicator: threadID is required");
89416
+ return fail("sendTypingIndicator: threadID is required");
89316
89417
  }
89317
89418
  if (!ctx.mqttClient || !ctx.mqttClient.connected) {
89318
- throw new Error("sendTypingIndicator: not connected to MQTT");
89419
+ return fail("sendTypingIndicator: not connected to MQTT");
89319
89420
  }
89320
89421
  const threadIDs = Array.isArray(actualThreadID) ? actualThreadID : [actualThreadID];
89321
89422
  const attribution = options.type || 0;
89423
+ const publishPromises = [];
89322
89424
  const publishTyping = (tid, isTyping) => {
89323
89425
  ctx.wsReqNumber = (ctx.wsReqNumber || 0) + 1;
89324
89426
  const isGroupThread = String(tid).length >= 16 ? 1 : 0;
@@ -89348,18 +89450,26 @@ function sendTypingIndicator_default(defaultFuncs, api, ctx) {
89348
89450
  );
89349
89451
  });
89350
89452
  };
89351
- await Promise.all(threadIDs.map((tid) => publishTyping(tid, actualSendTyping)));
89352
89453
  const duration = options.duration || 1e4;
89353
89454
  const autoStop = options.autoStop !== false;
89354
- if (actualSendTyping && autoStop) {
89355
- threadIDs.forEach((tid) => {
89356
- setTimeout(() => {
89357
- publishTyping(tid, false).catch(() => {
89358
- });
89359
- }, duration);
89455
+ threadIDs.forEach((tid) => {
89456
+ const p = publishTyping(tid, actualSendTyping).then(() => {
89457
+ if (actualSendTyping && autoStop) {
89458
+ setTimeout(() => {
89459
+ publishTyping(tid, false).catch(() => {
89460
+ });
89461
+ }, duration);
89462
+ }
89463
+ return true;
89360
89464
  });
89465
+ publishPromises.push(p);
89466
+ });
89467
+ const result = Promise.all(publishPromises).then(() => true);
89468
+ if (typeof callback === "function") {
89469
+ result.then(() => callback(null, true)).catch((err) => callback(err));
89470
+ return result.catch(() => null);
89361
89471
  }
89362
- return true;
89472
+ return result;
89363
89473
  };
89364
89474
  }
89365
89475
 
@@ -89748,6 +89858,8 @@ function theme_default(defaultFuncs, api, ctx) {
89748
89858
  let currentEpochId = parseInt(generateOfflineThreadingID());
89749
89859
  const createAndPublish = (label, queueName, payload) => {
89750
89860
  currentEpochId = parseInt(generateOfflineThreadingID());
89861
+ if (typeof ctx.wsReqNumber !== "number") ctx.wsReqNumber = 0;
89862
+ if (typeof ctx.wsTaskNumber !== "number") ctx.wsTaskNumber = 0;
89751
89863
  ctx.wsReqNumber += 1;
89752
89864
  ctx.wsTaskNumber += 1;
89753
89865
  const request_id = ctx.wsReqNumber;
@@ -89854,6 +89966,8 @@ function setThreadTheme_default(defaultFuncs, _api, ctx) {
89854
89966
  }
89855
89967
  throw error2;
89856
89968
  }
89969
+ if (typeof ctx.wsReqNumber !== "number") ctx.wsReqNumber = 0;
89970
+ if (typeof ctx.wsTaskNumber !== "number") ctx.wsTaskNumber = 0;
89857
89971
  ctx.wsReqNumber += 1;
89858
89972
  let baseTaskNumber = ++ctx.wsTaskNumber;
89859
89973
  const makeTask = (label, queueName, extraPayload = {}) => ({
@@ -89875,6 +89989,7 @@ function setThreadTheme_default(defaultFuncs, _api, ctx) {
89875
89989
  { label: 43, queue: "thread_theme", extra: { source: null, payload: null } }
89876
89990
  ];
89877
89991
  const messages = definitions.map(({ label, queue, extra }) => {
89992
+ if (typeof ctx.wsReqNumber !== "number") ctx.wsReqNumber = 0;
89878
89993
  ctx.wsReqNumber += 1;
89879
89994
  return {
89880
89995
  app_id: "2220391788200892",
@@ -90025,15 +90140,8 @@ async function publishThreadTask(ctx, label, queueName, payload, versionId, appI
90025
90140
  requestId: content.request_id,
90026
90141
  extract: (parsed) => {
90027
90142
  const body = parsed && parsed.payload;
90028
- const error2 = body && (body.error || body.errorDescription);
90029
- if (error2) {
90030
- const err = new Error(
90031
- typeof error2 === "string" ? error2 : error2.message || "MQTT task was rejected"
90032
- );
90033
- err.error = error2;
90034
- throw err;
90035
- }
90036
- return body || { success: true };
90143
+ if (!body || typeof body !== "object") return { success: true };
90144
+ return body;
90037
90145
  }
90038
90146
  });
90039
90147
  }
@@ -90064,8 +90172,13 @@ function unsendMessage_default(defaultFuncs, _api, ctx) {
90064
90172
  _resolve = resolve;
90065
90173
  _reject = reject;
90066
90174
  });
90175
+ returnPromise.catch(() => {
90176
+ });
90067
90177
  const done = (err, data2) => {
90068
- if (cb) cb(err, data2);
90178
+ if (cb) {
90179
+ cb(err, data2);
90180
+ return;
90181
+ }
90069
90182
  if (err) _reject(err);
90070
90183
  else _resolve(data2);
90071
90184
  };
@@ -90833,6 +90946,7 @@ function pinMessage_default(defaultFuncs, api, ctx) {
90833
90946
  }
90834
90947
 
90835
90948
  // src/deltas/apis/mqtt/sendMessageMqtt.ts
90949
+ var DEFAULT_RETRY_DELAYS_MS = [900, 1600, 2400, 3500, 5e3, 7e3];
90836
90950
  function preUploadedId(item) {
90837
90951
  if (typeof item === "number" && Number.isFinite(item)) return String(item);
90838
90952
  if (typeof item === "string" && /^\d{6,}$/.test(item.trim())) return item.trim();
@@ -90981,7 +91095,7 @@ var sendMessageMqtt_default = (defaultFuncs, api, ctx) => {
90981
91095
  attachmentIds = ids;
90982
91096
  } catch (err) {
90983
91097
  error("Attachment upload failed:", err);
90984
- callback(err);
91098
+ finish(err);
90985
91099
  return done();
90986
91100
  }
90987
91101
  }
@@ -91062,6 +91176,7 @@ var sendMessageMqtt_default = (defaultFuncs, api, ctx) => {
91062
91176
  let threadIDFromAck = null;
91063
91177
  let failure = null;
91064
91178
  let serverError = null;
91179
+ let softFailure = null;
91065
91180
  const steps = parsed.payload?.step;
91066
91181
  const visit = (node) => {
91067
91182
  if (!Array.isArray(node)) return;
@@ -91073,12 +91188,10 @@ var sendMessageMqtt_default = (defaultFuncs, api, ctx) => {
91073
91188
  threadIDFromAck = String(node[2][1]);
91074
91189
  }
91075
91190
  if (node[1] === "markOptimisticMessageFailed") {
91076
- const detail = typeof node[3] === "string" ? node[3] : "Message failed on server.";
91077
- failure = { error: detail, errorDescription: "Message failed on server." };
91191
+ softFailure = typeof node[3] === "string" ? node[3] : "Message failed on server.";
91078
91192
  }
91079
91193
  if (node[1] === "updateSubscriptErrorMessage" || node[1] === "fatalError") {
91080
- const detail = typeof node[3] === "string" ? node[3] : typeof node[4] === "string" ? node[4] : "Couldn't send.";
91081
- serverError = detail;
91194
+ softFailure = typeof node[3] === "string" ? node[3] : typeof node[4] === "string" ? node[4] : "Couldn't send.";
91082
91195
  }
91083
91196
  }
91084
91197
  for (const child of node) visit(child);
@@ -91088,7 +91201,8 @@ var sendMessageMqtt_default = (defaultFuncs, api, ctx) => {
91088
91201
  messageID: resolvedMessageID,
91089
91202
  threadID: threadIDFromAck,
91090
91203
  failure,
91091
- serverError
91204
+ serverError,
91205
+ softFailure
91092
91206
  });
91093
91207
  };
91094
91208
  if (mqttClient && typeof mqttClient.on === "function") {
@@ -91099,14 +91213,21 @@ var sendMessageMqtt_default = (defaultFuncs, api, ctx) => {
91099
91213
  });
91100
91214
  timer = setTimeout(() => settle2({ timeout: true }), 15e3);
91101
91215
  });
91216
+ const retryDelays = (() => {
91217
+ const override = ctx.globalOptions && ctx.globalOptions.mqttSendRetryDelaysMs;
91218
+ return Array.isArray(override) && override.length ? override : DEFAULT_RETRY_DELAYS_MS;
91219
+ })();
91102
91220
  let result = null;
91103
91221
  let lastOtid = "";
91104
- for (let attempt = 0; attempt < 3; attempt++) {
91222
+ for (let attempt = 0; attempt <= retryDelays.length; attempt++) {
91105
91223
  const built = buildForm();
91106
91224
  lastOtid = built.otid;
91107
91225
  result = await publishAndWait(built.form, built.request_id);
91108
- if (!result.failure && !result.serverError) break;
91109
- if (attempt < 2) await sleep(700 + attempt * 900 + Math.floor(Math.random() * 400));
91226
+ if (!result.failure && !result.serverError && !result.softFailure) break;
91227
+ if ((result.failure || result.serverError) && attempt >= 2) break;
91228
+ if (attempt < retryDelays.length) {
91229
+ await sleep(retryDelays[attempt] + Math.floor(Math.random() * 400));
91230
+ }
91110
91231
  }
91111
91232
  if (result.failure || result.serverError) {
91112
91233
  const err = result.failure || { error: result.serverError };
@@ -91119,6 +91240,21 @@ var sendMessageMqtt_default = (defaultFuncs, api, ctx) => {
91119
91240
  finish(err);
91120
91241
  return done();
91121
91242
  }
91243
+ if (result.softFailure) {
91244
+ warn(
91245
+ "sendMessageMqtt [MQTT]",
91246
+ `Facebook rejected the message (${result.softFailure}); thread ${threadID}. Retried ${retryDelays.length} times without success; continuing without failing the bot.`
91247
+ );
91248
+ finish(null, {
91249
+ threadID: result.threadID || threadID.toString(),
91250
+ messageID: result.messageID || null,
91251
+ timestamp,
91252
+ type: replyToMessage ? "message_reply" : "message",
91253
+ error: result.softFailure,
91254
+ success: false
91255
+ });
91256
+ return done();
91257
+ }
91122
91258
  finish(null, {
91123
91259
  threadID: result.threadID || threadID.toString(),
91124
91260
  messageID: result.messageID || `mid.${lastOtid}`,
@@ -92888,8 +93024,13 @@ function createPoll_default(_defaultFuncs, _api, ctx) {
92888
93024
  _resolve = resolve;
92889
93025
  _reject = reject;
92890
93026
  });
93027
+ promise.catch(() => {
93028
+ });
92891
93029
  const done = (err, data2) => {
92892
- if (cb) cb(err, data2);
93030
+ if (cb) {
93031
+ cb(err, data2);
93032
+ return;
93033
+ }
92893
93034
  if (err) _reject(err);
92894
93035
  else _resolve(data2);
92895
93036
  };
@@ -93749,7 +93890,7 @@ function parseDelta(defaultFuncs, api, ctx, globalCallback, v) {
93749
93890
  if (v.delta.class == "NewMessage") {
93750
93891
  if (ctx.globalOptions.pageID && ctx.globalOptions.pageID != v.queue) return;
93751
93892
  (function resolveAttachmentUrl(i2) {
93752
- if (v.delta.attachments && i2 == v.delta.attachments.length) {
93893
+ if (!v.delta.attachments || !Array.isArray(v.delta.attachments) || i2 >= v.delta.attachments.length) {
93753
93894
  let fmtMsg;
93754
93895
  try {
93755
93896
  fmtMsg = formatDeltaMessage(v);
@@ -93940,11 +94081,11 @@ function installTeardownGuard() {
93940
94081
  const isTeardownNoise = (err) => !!err && (err.code === "MQTT_CONNECTION_CLOSED" || /Connection closed|client disconnecting/i.test(String(err && err.message ? err.message : err))) && !/error_gc|1357001|checkpoint/i.test(String(err && err.message ? err.message : err));
93941
94082
  process.on("uncaughtException", (err) => {
93942
94083
  if (isTeardownNoise(err)) return;
93943
- throw err;
94084
+ error("uncaughtException", err);
93944
94085
  });
93945
94086
  process.on("unhandledRejection", (reason) => {
93946
94087
  if (isTeardownNoise(reason)) return;
93947
- throw reason;
94088
+ error("unhandledRejection", reason);
93948
94089
  });
93949
94090
  }
93950
94091
  var MQTT_TOPICS = [
@@ -94930,13 +95071,18 @@ async function login(credentials, options, callback) {
94930
95071
  const finish = (error2, loginApi) => {
94931
95072
  if (settled) return;
94932
95073
  settled = true;
95074
+ const hasCallback = typeof callback === "function";
94933
95075
  try {
94934
95076
  callback?.(error2 || null, loginApi);
94935
95077
  } catch (callbackError) {
94936
95078
  error("login callback", callbackError);
94937
95079
  }
94938
- if (error2) reject(error2);
94939
- else resolve(loginApi);
95080
+ if (error2) {
95081
+ if (hasCallback) resolve(loginApi);
95082
+ else reject(error2);
95083
+ } else {
95084
+ resolve(loginApi);
95085
+ }
94940
95086
  };
94941
95087
  loginHelper(
94942
95088
  credentials,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lazyneoaz/metachat",
3
- "version": "6.0.6",
3
+ "version": "6.0.8",
4
4
  "description": "A modern TypeScript Facebook Chat API client for building reliable Messenger bots, with built-in anti-detection protection, automatic cookie refresh, music search, and AI theme support.",
5
5
  "license": "MIT",
6
6
  "author": {
@@ -57,7 +57,7 @@
57
57
  "prepublishOnly": "npm run build",
58
58
  "lint": "npm run typecheck",
59
59
  "format": "prettier --write \"src/**/*.ts\" \"index.ts\"",
60
- "test": "npm run build && node test/smoke.test.cjs && node test/smoke.test.mjs && node test/music-search.test.cjs && node test/mqtt-lifecycle.test.cjs && node test/session-reliability.test.cjs && node test/anti-detection.test.cjs && node test/account-safety.test.cjs && node test/liveness.test.cjs && node test/recovery.test.cjs && node test/cookie-acquisition.test.cjs && node test/realtime-health.test.cjs && node test/attachment-resilience.test.cjs && node test/reaction-validation.test.cjs && node test/api-surface-fixes.test.cjs && node test/threadinfo-regression.test.cjs && node test/new-modules.test.cjs && node test/mention-parsing.test.cjs && node test/pending-support.test.cjs && node test/music-token-resilience.test.cjs && node test/send-failure.test.cjs",
60
+ "test": "npm run build && node test/smoke.test.cjs && node test/smoke.test.mjs && node test/music-search.test.cjs && node test/mqtt-lifecycle.test.cjs && node test/session-reliability.test.cjs && node test/anti-detection.test.cjs && node test/account-safety.test.cjs && node test/liveness.test.cjs && node test/recovery.test.cjs && node test/cookie-acquisition.test.cjs && node test/realtime-health.test.cjs && node test/attachment-resilience.test.cjs && node test/reaction-validation.test.cjs && node test/api-surface-fixes.test.cjs && node test/threadinfo-regression.test.cjs && node test/new-modules.test.cjs && node test/mention-parsing.test.cjs && node test/pending-support.test.cjs && node test/music-token-resilience.test.cjs && node test/send-failure.test.cjs && node test/crash-safety.test.cjs",
61
61
  "audit": "npm audit",
62
62
  "audit:fix": "npm audit fix"
63
63
  },