@lazyneoaz/metachat 6.0.4 → 6.0.6

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
@@ -85890,7 +85890,7 @@ async function ensureCometTokens(ctx, defaultFuncs, force = false) {
85890
85890
  }
85891
85891
  }
85892
85892
  if (!state.inflight) {
85893
- state.inflight = scrapeTokens(ctx, defaultFuncs, state).finally(() => {
85893
+ state.inflight = scrapeTokens(ctx, defaultFuncs, state, force).finally(() => {
85894
85894
  state.inflight = null;
85895
85895
  });
85896
85896
  }
@@ -85900,10 +85900,11 @@ async function ensureCometTokens(ctx, defaultFuncs, force = false) {
85900
85900
  }
85901
85901
  applyCached(ctx, state);
85902
85902
  }
85903
- async function scrapeTokens(ctx, defaultFuncs, state) {
85903
+ async function scrapeTokens(ctx, defaultFuncs, state, force = false) {
85904
85904
  state.attemptedAt = Date.now();
85905
85905
  try {
85906
- const res = await defaultFuncs.get("https://www.facebook.com/", ctx.jar);
85906
+ const url2 = force ? `https://www.facebook.com/?_nc_hashed_token=${Date.now().toString(36)}${Math.floor(Math.random() * 1e6).toString(36)}` : "https://www.facebook.com/";
85907
+ const res = await defaultFuncs.get(url2, ctx.jar);
85907
85908
  const html3 = htmlOf(res);
85908
85909
  if (!html3) {
85909
85910
  state.failures++;
@@ -89022,7 +89023,7 @@ var sendMessage_default = (defaultFuncs, api, ctx) => {
89022
89023
  }, null);
89023
89024
  return messageInfo;
89024
89025
  }
89025
- return async function sendMessage(msg, threadID, callback, replyToMessage, isGroup) {
89026
+ const sendMessageCore = async function(msg, threadID, callback, replyToMessage, isGroup) {
89026
89027
  if (typeof isGroup === "undefined") isGroup = null;
89027
89028
  if (!callback && (getType(threadID) === "Function" || getType(threadID) === "AsyncFunction")) {
89028
89029
  throw new Error("Pass a threadID as a second argument.");
@@ -89046,11 +89047,13 @@ var sendMessage_default = (defaultFuncs, api, ctx) => {
89046
89047
  if (msgType !== "String" && msgType !== "Object") {
89047
89048
  const err = new Error("Message should be of type string or object and not " + msgType + ".");
89048
89049
  settle2(err);
89050
+ if (legacyCallback) return null;
89049
89051
  throw err;
89050
89052
  }
89051
89053
  if (threadIDType !== "Array" && threadIDType !== "Number" && threadIDType !== "String") {
89052
89054
  const err = new Error("ThreadID should be of type number, string, or array and not " + threadIDType + ".");
89053
89055
  settle2(err);
89056
+ if (legacyCallback) return null;
89054
89057
  throw err;
89055
89058
  }
89056
89059
  if (messageIDType === "Function" || messageIDType === "Undefined" || messageIDType === "Null") {
@@ -89058,6 +89061,7 @@ var sendMessage_default = (defaultFuncs, api, ctx) => {
89058
89061
  } else if (replyToMessage && messageIDType !== "String") {
89059
89062
  const err = new Error("MessageID should be of type string and not " + messageIDType + ".");
89060
89063
  settle2(err);
89064
+ if (legacyCallback) return null;
89061
89065
  throw err;
89062
89066
  }
89063
89067
  let isSingleUser = null;
@@ -89315,6 +89319,12 @@ var sendMessage_default = (defaultFuncs, api, ctx) => {
89315
89319
  }
89316
89320
  }
89317
89321
  };
89322
+ return function sendMessage(msg, threadID, callback, replyToMessage, isGroup) {
89323
+ const promise = sendMessageCore(msg, threadID, callback, replyToMessage, isGroup);
89324
+ if (typeof callback === "function") promise.catch(() => {
89325
+ });
89326
+ return promise;
89327
+ };
89318
89328
  };
89319
89329
 
89320
89330
  // src/deltas/apis/messaging/sendTypingIndicator.ts
@@ -90326,9 +90336,9 @@ function searchMusic_default(defaultFuncs, _api, ctx) {
90326
90336
  cacheResult(ctx, cacheKey, result);
90327
90337
  return result;
90328
90338
  }
90329
- for (let retry = 0; retry < 3; retry++) {
90330
- await sleep(1200 + retry * 1300 + Math.floor(Math.random() * 400));
90331
- const retried = await attempt(retry === 2 || !hasCometTokens(ctx));
90339
+ for (let retry = 0; retry < 6; retry++) {
90340
+ await sleep(1e3 + retry * 600 + Math.floor(Math.random() * 350));
90341
+ const retried = await attempt(retry >= 3 || !hasCometTokens(ctx));
90332
90342
  if (isStaleTokenError(retried) || retried?.error || (retried?.errors || []).length) continue;
90333
90343
  const retryPage = collectTracks(retried);
90334
90344
  const retryTracks = retryPage.tracks.slice(0, count);
@@ -90958,6 +90968,8 @@ var sendMessageMqtt_default = (defaultFuncs, api, ctx) => {
90958
90968
  resolveFunc = resolve;
90959
90969
  rejectFunc = reject;
90960
90970
  });
90971
+ returnPromise.catch(() => {
90972
+ });
90961
90973
  const userCallback = typeof callback === "function" ? callback : null;
90962
90974
  let finished2 = false;
90963
90975
  const finish = (err, data2) => {
@@ -90974,51 +90986,14 @@ var sendMessageMqtt_default = (defaultFuncs, api, ctx) => {
90974
90986
  if (!callback) {
90975
90987
  callback = finish;
90976
90988
  }
90989
+ const done = () => userCallback ? returnPromise.then(() => null, () => null) : returnPromise;
90977
90990
  if (!ctx.mqttClient || !ctx.mqttClient.connected) {
90978
90991
  const error2 = new Error("MQTT client is not connected. Cannot send message.");
90979
90992
  finish(error2);
90980
- return returnPromise;
90993
+ return done();
90981
90994
  }
90982
90995
  const timestamp = Date.now();
90983
- const otid = generateOfflineThreadingID();
90984
- const epoch_id = (BigInt(Date.now()) << 22n).toString();
90985
- const request_id = ctx.wsReqNumber = (ctx.wsReqNumber || 0) + 1;
90986
- const payload = getSendPayload(threadID, msg, otid);
90987
- const tasks = [{
90988
- label: "46",
90989
- payload,
90990
- queue_name: threadID.toString(),
90991
- task_id: 400,
90992
- failure_count: null
90993
- }, {
90994
- label: "21",
90995
- payload: {
90996
- thread_id: threadID.toString(),
90997
- last_read_watermark_ts: timestamp,
90998
- sync_group: 1
90999
- },
91000
- queue_name: threadID.toString(),
91001
- task_id: 401,
91002
- failure_count: null
91003
- }];
91004
- if (replyToMessage) {
91005
- tasks[0].payload.reply_metadata = {
91006
- reply_source_id: replyToMessage,
91007
- reply_source_type: 1,
91008
- reply_type: 0
91009
- };
91010
- }
91011
- const form = {
91012
- app_id: "2220391788200892",
91013
- payload: {
91014
- tasks,
91015
- epoch_id,
91016
- version_id: "24804310205905615",
91017
- data_trace_id: `#${Buffer.from(String(Math.random())).toString("base64").replace(/=+$/g, "")}`
91018
- },
91019
- request_id,
91020
- type: 3
91021
- };
90996
+ let attachmentIds = null;
91022
90997
  if (msg.attachment) {
91023
90998
  try {
91024
90999
  const inputs = Array.isArray(msg.attachment) ? msg.attachment : [msg.attachment];
@@ -91035,20 +91010,62 @@ var sendMessageMqtt_default = (defaultFuncs, api, ctx) => {
91035
91010
  ids.push(file && typeof file === "object" ? String(Object.values(file)[0]) : String(file));
91036
91011
  }
91037
91012
  }
91038
- form.payload.tasks[0].payload.attachment_fbids = ids;
91013
+ attachmentIds = ids;
91039
91014
  } catch (err) {
91040
91015
  error("Attachment upload failed:", err);
91041
91016
  callback(err);
91042
- return returnPromise;
91017
+ return done();
91043
91018
  }
91044
91019
  }
91045
- form.payload.tasks.forEach((task) => {
91046
- task.payload = JSON.stringify(task.payload);
91047
- });
91048
- form.payload = JSON.stringify(form.payload);
91049
- const fallbackMessageID = `mid.${otid}`;
91050
91020
  const mqttClient = ctx.mqttClient;
91051
- const result = await new Promise((resolve) => {
91021
+ const buildForm = () => {
91022
+ const otid = generateOfflineThreadingID();
91023
+ const epoch_id = (BigInt(Date.now()) << 22n).toString();
91024
+ const request_id = ctx.wsReqNumber = (ctx.wsReqNumber || 0) + 1;
91025
+ const payload = getSendPayload(threadID, msg, otid);
91026
+ if (attachmentIds) payload.attachment_fbids = attachmentIds;
91027
+ const tasks = [{
91028
+ label: "46",
91029
+ payload,
91030
+ queue_name: threadID.toString(),
91031
+ task_id: 400,
91032
+ failure_count: null
91033
+ }, {
91034
+ label: "21",
91035
+ payload: {
91036
+ thread_id: threadID.toString(),
91037
+ last_read_watermark_ts: Date.now(),
91038
+ sync_group: 1
91039
+ },
91040
+ queue_name: threadID.toString(),
91041
+ task_id: 401,
91042
+ failure_count: null
91043
+ }];
91044
+ if (replyToMessage) {
91045
+ tasks[0].payload.reply_metadata = {
91046
+ reply_source_id: replyToMessage,
91047
+ reply_source_type: 1,
91048
+ reply_type: 0
91049
+ };
91050
+ }
91051
+ const form = {
91052
+ app_id: "2220391788200892",
91053
+ payload: {
91054
+ tasks,
91055
+ epoch_id,
91056
+ version_id: "24804310205905615",
91057
+ data_trace_id: `#${Buffer.from(String(Math.random())).toString("base64").replace(/=+$/g, "")}`
91058
+ },
91059
+ request_id,
91060
+ type: 3
91061
+ };
91062
+ form.payload.tasks.forEach((task) => {
91063
+ task.payload = JSON.stringify(task.payload);
91064
+ });
91065
+ form.payload = JSON.stringify(form.payload);
91066
+ return { form, request_id, otid };
91067
+ };
91068
+ const publishAndWait = (form, request_id) => new Promise((resolve) => {
91052
91069
  let settled = false;
91053
91070
  let timer = null;
91054
91071
  const cleanup = () => {
@@ -91088,10 +91105,12 @@ var sendMessageMqtt_default = (defaultFuncs, api, ctx) => {
91088
91105
  threadIDFromAck = String(node[2][1]);
91089
91106
  }
91090
91107
  if (node[1] === "markOptimisticMessageFailed") {
91091
- failure = { error: "Couldn't send.", errorDescription: "Message failed on server." };
91108
+ const detail = typeof node[3] === "string" ? node[3] : "Message failed on server.";
91109
+ failure = { error: detail, errorDescription: "Message failed on server." };
91092
91110
  }
91093
91111
  if (node[1] === "updateSubscriptErrorMessage" || node[1] === "fatalError") {
91094
- serverError = typeof node[3] === "string" ? node[3] : "Couldn't send.";
91112
+ const detail = typeof node[3] === "string" ? node[3] : typeof node[4] === "string" ? node[4] : "Couldn't send.";
91113
+ serverError = detail;
91095
91114
  }
91096
91115
  }
91097
91116
  for (const child of node) visit(child);
@@ -91112,24 +91131,33 @@ var sendMessageMqtt_default = (defaultFuncs, api, ctx) => {
91112
91131
  });
91113
91132
  timer = setTimeout(() => settle2({ timeout: true }), 15e3);
91114
91133
  });
91134
+ let result = null;
91135
+ let lastOtid = "";
91136
+ for (let attempt = 0; attempt < 3; attempt++) {
91137
+ const built = buildForm();
91138
+ lastOtid = built.otid;
91139
+ 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));
91142
+ }
91115
91143
  if (result.failure || result.serverError) {
91116
91144
  const err = result.failure || { error: result.serverError };
91117
91145
  if (err.error && err.error === 1545012) {
91118
91146
  warn("sendMessageMqtt [MQTT]", `Got error 1545012. Bot is not part of the conversation ${threadID}`);
91119
91147
  finish(null, null);
91120
- return returnPromise;
91148
+ return done();
91121
91149
  }
91122
91150
  error("sendMessageMqtt", "Send failed:", err.error || err);
91123
91151
  finish(err);
91124
- return returnPromise;
91152
+ return done();
91125
91153
  }
91126
91154
  finish(null, {
91127
91155
  threadID: result.threadID || threadID.toString(),
91128
- messageID: result.messageID || fallbackMessageID,
91156
+ messageID: result.messageID || `mid.${lastOtid}`,
91129
91157
  timestamp,
91130
91158
  type: replyToMessage ? "message_reply" : "message"
91131
91159
  });
91132
- return returnPromise;
91160
+ return done();
91133
91161
  };
91134
91162
  };
91135
91163
 
package/dist/index.mjs CHANGED
@@ -85858,7 +85858,7 @@ async function ensureCometTokens(ctx, defaultFuncs, force = false) {
85858
85858
  }
85859
85859
  }
85860
85860
  if (!state.inflight) {
85861
- state.inflight = scrapeTokens(ctx, defaultFuncs, state).finally(() => {
85861
+ state.inflight = scrapeTokens(ctx, defaultFuncs, state, force).finally(() => {
85862
85862
  state.inflight = null;
85863
85863
  });
85864
85864
  }
@@ -85868,10 +85868,11 @@ async function ensureCometTokens(ctx, defaultFuncs, force = false) {
85868
85868
  }
85869
85869
  applyCached(ctx, state);
85870
85870
  }
85871
- async function scrapeTokens(ctx, defaultFuncs, state) {
85871
+ async function scrapeTokens(ctx, defaultFuncs, state, force = false) {
85872
85872
  state.attemptedAt = Date.now();
85873
85873
  try {
85874
- const res = await defaultFuncs.get("https://www.facebook.com/", ctx.jar);
85874
+ const url2 = force ? `https://www.facebook.com/?_nc_hashed_token=${Date.now().toString(36)}${Math.floor(Math.random() * 1e6).toString(36)}` : "https://www.facebook.com/";
85875
+ const res = await defaultFuncs.get(url2, ctx.jar);
85875
85876
  const html3 = htmlOf(res);
85876
85877
  if (!html3) {
85877
85878
  state.failures++;
@@ -88990,7 +88991,7 @@ var sendMessage_default = (defaultFuncs, api, ctx) => {
88990
88991
  }, null);
88991
88992
  return messageInfo;
88992
88993
  }
88993
- return async function sendMessage(msg, threadID, callback, replyToMessage, isGroup) {
88994
+ const sendMessageCore = async function(msg, threadID, callback, replyToMessage, isGroup) {
88994
88995
  if (typeof isGroup === "undefined") isGroup = null;
88995
88996
  if (!callback && (getType(threadID) === "Function" || getType(threadID) === "AsyncFunction")) {
88996
88997
  throw new Error("Pass a threadID as a second argument.");
@@ -89014,11 +89015,13 @@ var sendMessage_default = (defaultFuncs, api, ctx) => {
89014
89015
  if (msgType !== "String" && msgType !== "Object") {
89015
89016
  const err = new Error("Message should be of type string or object and not " + msgType + ".");
89016
89017
  settle2(err);
89018
+ if (legacyCallback) return null;
89017
89019
  throw err;
89018
89020
  }
89019
89021
  if (threadIDType !== "Array" && threadIDType !== "Number" && threadIDType !== "String") {
89020
89022
  const err = new Error("ThreadID should be of type number, string, or array and not " + threadIDType + ".");
89021
89023
  settle2(err);
89024
+ if (legacyCallback) return null;
89022
89025
  throw err;
89023
89026
  }
89024
89027
  if (messageIDType === "Function" || messageIDType === "Undefined" || messageIDType === "Null") {
@@ -89026,6 +89029,7 @@ var sendMessage_default = (defaultFuncs, api, ctx) => {
89026
89029
  } else if (replyToMessage && messageIDType !== "String") {
89027
89030
  const err = new Error("MessageID should be of type string and not " + messageIDType + ".");
89028
89031
  settle2(err);
89032
+ if (legacyCallback) return null;
89029
89033
  throw err;
89030
89034
  }
89031
89035
  let isSingleUser = null;
@@ -89283,6 +89287,12 @@ var sendMessage_default = (defaultFuncs, api, ctx) => {
89283
89287
  }
89284
89288
  }
89285
89289
  };
89290
+ return function sendMessage(msg, threadID, callback, replyToMessage, isGroup) {
89291
+ const promise = sendMessageCore(msg, threadID, callback, replyToMessage, isGroup);
89292
+ if (typeof callback === "function") promise.catch(() => {
89293
+ });
89294
+ return promise;
89295
+ };
89286
89296
  };
89287
89297
 
89288
89298
  // src/deltas/apis/messaging/sendTypingIndicator.ts
@@ -90294,9 +90304,9 @@ function searchMusic_default(defaultFuncs, _api, ctx) {
90294
90304
  cacheResult(ctx, cacheKey, result);
90295
90305
  return result;
90296
90306
  }
90297
- for (let retry = 0; retry < 3; retry++) {
90298
- await sleep(1200 + retry * 1300 + Math.floor(Math.random() * 400));
90299
- const retried = await attempt(retry === 2 || !hasCometTokens(ctx));
90307
+ for (let retry = 0; retry < 6; retry++) {
90308
+ await sleep(1e3 + retry * 600 + Math.floor(Math.random() * 350));
90309
+ const retried = await attempt(retry >= 3 || !hasCometTokens(ctx));
90300
90310
  if (isStaleTokenError(retried) || retried?.error || (retried?.errors || []).length) continue;
90301
90311
  const retryPage = collectTracks(retried);
90302
90312
  const retryTracks = retryPage.tracks.slice(0, count);
@@ -90926,6 +90936,8 @@ var sendMessageMqtt_default = (defaultFuncs, api, ctx) => {
90926
90936
  resolveFunc = resolve;
90927
90937
  rejectFunc = reject;
90928
90938
  });
90939
+ returnPromise.catch(() => {
90940
+ });
90929
90941
  const userCallback = typeof callback === "function" ? callback : null;
90930
90942
  let finished2 = false;
90931
90943
  const finish = (err, data2) => {
@@ -90942,51 +90954,14 @@ var sendMessageMqtt_default = (defaultFuncs, api, ctx) => {
90942
90954
  if (!callback) {
90943
90955
  callback = finish;
90944
90956
  }
90957
+ const done = () => userCallback ? returnPromise.then(() => null, () => null) : returnPromise;
90945
90958
  if (!ctx.mqttClient || !ctx.mqttClient.connected) {
90946
90959
  const error2 = new Error("MQTT client is not connected. Cannot send message.");
90947
90960
  finish(error2);
90948
- return returnPromise;
90961
+ return done();
90949
90962
  }
90950
90963
  const timestamp = Date.now();
90951
- const otid = generateOfflineThreadingID();
90952
- const epoch_id = (BigInt(Date.now()) << 22n).toString();
90953
- const request_id = ctx.wsReqNumber = (ctx.wsReqNumber || 0) + 1;
90954
- const payload = getSendPayload(threadID, msg, otid);
90955
- const tasks = [{
90956
- label: "46",
90957
- payload,
90958
- queue_name: threadID.toString(),
90959
- task_id: 400,
90960
- failure_count: null
90961
- }, {
90962
- label: "21",
90963
- payload: {
90964
- thread_id: threadID.toString(),
90965
- last_read_watermark_ts: timestamp,
90966
- sync_group: 1
90967
- },
90968
- queue_name: threadID.toString(),
90969
- task_id: 401,
90970
- failure_count: null
90971
- }];
90972
- if (replyToMessage) {
90973
- tasks[0].payload.reply_metadata = {
90974
- reply_source_id: replyToMessage,
90975
- reply_source_type: 1,
90976
- reply_type: 0
90977
- };
90978
- }
90979
- const form = {
90980
- app_id: "2220391788200892",
90981
- payload: {
90982
- tasks,
90983
- epoch_id,
90984
- version_id: "24804310205905615",
90985
- data_trace_id: `#${Buffer.from(String(Math.random())).toString("base64").replace(/=+$/g, "")}`
90986
- },
90987
- request_id,
90988
- type: 3
90989
- };
90964
+ let attachmentIds = null;
90990
90965
  if (msg.attachment) {
90991
90966
  try {
90992
90967
  const inputs = Array.isArray(msg.attachment) ? msg.attachment : [msg.attachment];
@@ -91003,20 +90978,62 @@ var sendMessageMqtt_default = (defaultFuncs, api, ctx) => {
91003
90978
  ids.push(file && typeof file === "object" ? String(Object.values(file)[0]) : String(file));
91004
90979
  }
91005
90980
  }
91006
- form.payload.tasks[0].payload.attachment_fbids = ids;
90981
+ attachmentIds = ids;
91007
90982
  } catch (err) {
91008
90983
  error("Attachment upload failed:", err);
91009
90984
  callback(err);
91010
- return returnPromise;
90985
+ return done();
91011
90986
  }
91012
90987
  }
91013
- form.payload.tasks.forEach((task) => {
91014
- task.payload = JSON.stringify(task.payload);
91015
- });
91016
- form.payload = JSON.stringify(form.payload);
91017
- const fallbackMessageID = `mid.${otid}`;
91018
90988
  const mqttClient = ctx.mqttClient;
91019
- const result = await new Promise((resolve) => {
90989
+ const buildForm = () => {
90990
+ const otid = generateOfflineThreadingID();
90991
+ const epoch_id = (BigInt(Date.now()) << 22n).toString();
90992
+ const request_id = ctx.wsReqNumber = (ctx.wsReqNumber || 0) + 1;
90993
+ const payload = getSendPayload(threadID, msg, otid);
90994
+ if (attachmentIds) payload.attachment_fbids = attachmentIds;
90995
+ const tasks = [{
90996
+ label: "46",
90997
+ payload,
90998
+ queue_name: threadID.toString(),
90999
+ task_id: 400,
91000
+ failure_count: null
91001
+ }, {
91002
+ label: "21",
91003
+ payload: {
91004
+ thread_id: threadID.toString(),
91005
+ last_read_watermark_ts: Date.now(),
91006
+ sync_group: 1
91007
+ },
91008
+ queue_name: threadID.toString(),
91009
+ task_id: 401,
91010
+ failure_count: null
91011
+ }];
91012
+ if (replyToMessage) {
91013
+ tasks[0].payload.reply_metadata = {
91014
+ reply_source_id: replyToMessage,
91015
+ reply_source_type: 1,
91016
+ reply_type: 0
91017
+ };
91018
+ }
91019
+ const form = {
91020
+ app_id: "2220391788200892",
91021
+ payload: {
91022
+ tasks,
91023
+ epoch_id,
91024
+ version_id: "24804310205905615",
91025
+ data_trace_id: `#${Buffer.from(String(Math.random())).toString("base64").replace(/=+$/g, "")}`
91026
+ },
91027
+ request_id,
91028
+ type: 3
91029
+ };
91030
+ form.payload.tasks.forEach((task) => {
91031
+ task.payload = JSON.stringify(task.payload);
91032
+ });
91033
+ form.payload = JSON.stringify(form.payload);
91034
+ return { form, request_id, otid };
91035
+ };
91036
+ const publishAndWait = (form, request_id) => new Promise((resolve) => {
91020
91037
  let settled = false;
91021
91038
  let timer = null;
91022
91039
  const cleanup = () => {
@@ -91056,10 +91073,12 @@ var sendMessageMqtt_default = (defaultFuncs, api, ctx) => {
91056
91073
  threadIDFromAck = String(node[2][1]);
91057
91074
  }
91058
91075
  if (node[1] === "markOptimisticMessageFailed") {
91059
- failure = { error: "Couldn't send.", errorDescription: "Message failed on server." };
91076
+ const detail = typeof node[3] === "string" ? node[3] : "Message failed on server.";
91077
+ failure = { error: detail, errorDescription: "Message failed on server." };
91060
91078
  }
91061
91079
  if (node[1] === "updateSubscriptErrorMessage" || node[1] === "fatalError") {
91062
- serverError = typeof node[3] === "string" ? node[3] : "Couldn't send.";
91080
+ const detail = typeof node[3] === "string" ? node[3] : typeof node[4] === "string" ? node[4] : "Couldn't send.";
91081
+ serverError = detail;
91063
91082
  }
91064
91083
  }
91065
91084
  for (const child of node) visit(child);
@@ -91080,24 +91099,33 @@ var sendMessageMqtt_default = (defaultFuncs, api, ctx) => {
91080
91099
  });
91081
91100
  timer = setTimeout(() => settle2({ timeout: true }), 15e3);
91082
91101
  });
91102
+ let result = null;
91103
+ let lastOtid = "";
91104
+ for (let attempt = 0; attempt < 3; attempt++) {
91105
+ const built = buildForm();
91106
+ lastOtid = built.otid;
91107
+ 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));
91110
+ }
91083
91111
  if (result.failure || result.serverError) {
91084
91112
  const err = result.failure || { error: result.serverError };
91085
91113
  if (err.error && err.error === 1545012) {
91086
91114
  warn("sendMessageMqtt [MQTT]", `Got error 1545012. Bot is not part of the conversation ${threadID}`);
91087
91115
  finish(null, null);
91088
- return returnPromise;
91116
+ return done();
91089
91117
  }
91090
91118
  error("sendMessageMqtt", "Send failed:", err.error || err);
91091
91119
  finish(err);
91092
- return returnPromise;
91120
+ return done();
91093
91121
  }
91094
91122
  finish(null, {
91095
91123
  threadID: result.threadID || threadID.toString(),
91096
- messageID: result.messageID || fallbackMessageID,
91124
+ messageID: result.messageID || `mid.${lastOtid}`,
91097
91125
  timestamp,
91098
91126
  type: replyToMessage ? "message_reply" : "message"
91099
91127
  });
91100
- return returnPromise;
91128
+ return done();
91101
91129
  };
91102
91130
  };
91103
91131
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lazyneoaz/metachat",
3
- "version": "6.0.4",
3
+ "version": "6.0.6",
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",
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",
61
61
  "audit": "npm audit",
62
62
  "audit:fix": "npm audit fix"
63
63
  },