@lazyneoaz/metachat 6.0.5 → 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
@@ -89023,7 +89023,7 @@ var sendMessage_default = (defaultFuncs, api, ctx) => {
89023
89023
  }, null);
89024
89024
  return messageInfo;
89025
89025
  }
89026
- return async function sendMessage(msg, threadID, callback, replyToMessage, isGroup) {
89026
+ const sendMessageCore = async function(msg, threadID, callback, replyToMessage, isGroup) {
89027
89027
  if (typeof isGroup === "undefined") isGroup = null;
89028
89028
  if (!callback && (getType(threadID) === "Function" || getType(threadID) === "AsyncFunction")) {
89029
89029
  throw new Error("Pass a threadID as a second argument.");
@@ -89047,11 +89047,13 @@ var sendMessage_default = (defaultFuncs, api, ctx) => {
89047
89047
  if (msgType !== "String" && msgType !== "Object") {
89048
89048
  const err = new Error("Message should be of type string or object and not " + msgType + ".");
89049
89049
  settle2(err);
89050
+ if (legacyCallback) return null;
89050
89051
  throw err;
89051
89052
  }
89052
89053
  if (threadIDType !== "Array" && threadIDType !== "Number" && threadIDType !== "String") {
89053
89054
  const err = new Error("ThreadID should be of type number, string, or array and not " + threadIDType + ".");
89054
89055
  settle2(err);
89056
+ if (legacyCallback) return null;
89055
89057
  throw err;
89056
89058
  }
89057
89059
  if (messageIDType === "Function" || messageIDType === "Undefined" || messageIDType === "Null") {
@@ -89059,6 +89061,7 @@ var sendMessage_default = (defaultFuncs, api, ctx) => {
89059
89061
  } else if (replyToMessage && messageIDType !== "String") {
89060
89062
  const err = new Error("MessageID should be of type string and not " + messageIDType + ".");
89061
89063
  settle2(err);
89064
+ if (legacyCallback) return null;
89062
89065
  throw err;
89063
89066
  }
89064
89067
  let isSingleUser = null;
@@ -89316,6 +89319,12 @@ var sendMessage_default = (defaultFuncs, api, ctx) => {
89316
89319
  }
89317
89320
  }
89318
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
+ };
89319
89328
  };
89320
89329
 
89321
89330
  // src/deltas/apis/messaging/sendTypingIndicator.ts
@@ -90959,6 +90968,8 @@ var sendMessageMqtt_default = (defaultFuncs, api, ctx) => {
90959
90968
  resolveFunc = resolve;
90960
90969
  rejectFunc = reject;
90961
90970
  });
90971
+ returnPromise.catch(() => {
90972
+ });
90962
90973
  const userCallback = typeof callback === "function" ? callback : null;
90963
90974
  let finished2 = false;
90964
90975
  const finish = (err, data2) => {
@@ -90975,51 +90986,14 @@ var sendMessageMqtt_default = (defaultFuncs, api, ctx) => {
90975
90986
  if (!callback) {
90976
90987
  callback = finish;
90977
90988
  }
90989
+ const done = () => userCallback ? returnPromise.then(() => null, () => null) : returnPromise;
90978
90990
  if (!ctx.mqttClient || !ctx.mqttClient.connected) {
90979
90991
  const error2 = new Error("MQTT client is not connected. Cannot send message.");
90980
90992
  finish(error2);
90981
- return returnPromise;
90993
+ return done();
90982
90994
  }
90983
90995
  const timestamp = Date.now();
90984
- const otid = generateOfflineThreadingID();
90985
- const epoch_id = (BigInt(Date.now()) << 22n).toString();
90986
- const request_id = ctx.wsReqNumber = (ctx.wsReqNumber || 0) + 1;
90987
- const payload = getSendPayload(threadID, msg, otid);
90988
- const tasks = [{
90989
- label: "46",
90990
- payload,
90991
- queue_name: threadID.toString(),
90992
- task_id: 400,
90993
- failure_count: null
90994
- }, {
90995
- label: "21",
90996
- payload: {
90997
- thread_id: threadID.toString(),
90998
- last_read_watermark_ts: timestamp,
90999
- sync_group: 1
91000
- },
91001
- queue_name: threadID.toString(),
91002
- task_id: 401,
91003
- failure_count: null
91004
- }];
91005
- if (replyToMessage) {
91006
- tasks[0].payload.reply_metadata = {
91007
- reply_source_id: replyToMessage,
91008
- reply_source_type: 1,
91009
- reply_type: 0
91010
- };
91011
- }
91012
- const form = {
91013
- app_id: "2220391788200892",
91014
- payload: {
91015
- tasks,
91016
- epoch_id,
91017
- version_id: "24804310205905615",
91018
- data_trace_id: `#${Buffer.from(String(Math.random())).toString("base64").replace(/=+$/g, "")}`
91019
- },
91020
- request_id,
91021
- type: 3
91022
- };
90996
+ let attachmentIds = null;
91023
90997
  if (msg.attachment) {
91024
90998
  try {
91025
90999
  const inputs = Array.isArray(msg.attachment) ? msg.attachment : [msg.attachment];
@@ -91036,20 +91010,62 @@ var sendMessageMqtt_default = (defaultFuncs, api, ctx) => {
91036
91010
  ids.push(file && typeof file === "object" ? String(Object.values(file)[0]) : String(file));
91037
91011
  }
91038
91012
  }
91039
- form.payload.tasks[0].payload.attachment_fbids = ids;
91013
+ attachmentIds = ids;
91040
91014
  } catch (err) {
91041
91015
  error("Attachment upload failed:", err);
91042
91016
  callback(err);
91043
- return returnPromise;
91017
+ return done();
91044
91018
  }
91045
91019
  }
91046
- form.payload.tasks.forEach((task) => {
91047
- task.payload = JSON.stringify(task.payload);
91048
- });
91049
- form.payload = JSON.stringify(form.payload);
91050
- const fallbackMessageID = `mid.${otid}`;
91051
91020
  const mqttClient = ctx.mqttClient;
91052
- 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) => {
91053
91069
  let settled = false;
91054
91070
  let timer = null;
91055
91071
  const cleanup = () => {
@@ -91089,10 +91105,12 @@ var sendMessageMqtt_default = (defaultFuncs, api, ctx) => {
91089
91105
  threadIDFromAck = String(node[2][1]);
91090
91106
  }
91091
91107
  if (node[1] === "markOptimisticMessageFailed") {
91092
- 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." };
91093
91110
  }
91094
91111
  if (node[1] === "updateSubscriptErrorMessage" || node[1] === "fatalError") {
91095
- 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;
91096
91114
  }
91097
91115
  }
91098
91116
  for (const child of node) visit(child);
@@ -91113,24 +91131,33 @@ var sendMessageMqtt_default = (defaultFuncs, api, ctx) => {
91113
91131
  });
91114
91132
  timer = setTimeout(() => settle2({ timeout: true }), 15e3);
91115
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
+ }
91116
91143
  if (result.failure || result.serverError) {
91117
91144
  const err = result.failure || { error: result.serverError };
91118
91145
  if (err.error && err.error === 1545012) {
91119
91146
  warn("sendMessageMqtt [MQTT]", `Got error 1545012. Bot is not part of the conversation ${threadID}`);
91120
91147
  finish(null, null);
91121
- return returnPromise;
91148
+ return done();
91122
91149
  }
91123
91150
  error("sendMessageMqtt", "Send failed:", err.error || err);
91124
91151
  finish(err);
91125
- return returnPromise;
91152
+ return done();
91126
91153
  }
91127
91154
  finish(null, {
91128
91155
  threadID: result.threadID || threadID.toString(),
91129
- messageID: result.messageID || fallbackMessageID,
91156
+ messageID: result.messageID || `mid.${lastOtid}`,
91130
91157
  timestamp,
91131
91158
  type: replyToMessage ? "message_reply" : "message"
91132
91159
  });
91133
- return returnPromise;
91160
+ return done();
91134
91161
  };
91135
91162
  };
91136
91163
 
package/dist/index.mjs CHANGED
@@ -88991,7 +88991,7 @@ var sendMessage_default = (defaultFuncs, api, ctx) => {
88991
88991
  }, null);
88992
88992
  return messageInfo;
88993
88993
  }
88994
- return async function sendMessage(msg, threadID, callback, replyToMessage, isGroup) {
88994
+ const sendMessageCore = async function(msg, threadID, callback, replyToMessage, isGroup) {
88995
88995
  if (typeof isGroup === "undefined") isGroup = null;
88996
88996
  if (!callback && (getType(threadID) === "Function" || getType(threadID) === "AsyncFunction")) {
88997
88997
  throw new Error("Pass a threadID as a second argument.");
@@ -89015,11 +89015,13 @@ var sendMessage_default = (defaultFuncs, api, ctx) => {
89015
89015
  if (msgType !== "String" && msgType !== "Object") {
89016
89016
  const err = new Error("Message should be of type string or object and not " + msgType + ".");
89017
89017
  settle2(err);
89018
+ if (legacyCallback) return null;
89018
89019
  throw err;
89019
89020
  }
89020
89021
  if (threadIDType !== "Array" && threadIDType !== "Number" && threadIDType !== "String") {
89021
89022
  const err = new Error("ThreadID should be of type number, string, or array and not " + threadIDType + ".");
89022
89023
  settle2(err);
89024
+ if (legacyCallback) return null;
89023
89025
  throw err;
89024
89026
  }
89025
89027
  if (messageIDType === "Function" || messageIDType === "Undefined" || messageIDType === "Null") {
@@ -89027,6 +89029,7 @@ var sendMessage_default = (defaultFuncs, api, ctx) => {
89027
89029
  } else if (replyToMessage && messageIDType !== "String") {
89028
89030
  const err = new Error("MessageID should be of type string and not " + messageIDType + ".");
89029
89031
  settle2(err);
89032
+ if (legacyCallback) return null;
89030
89033
  throw err;
89031
89034
  }
89032
89035
  let isSingleUser = null;
@@ -89284,6 +89287,12 @@ var sendMessage_default = (defaultFuncs, api, ctx) => {
89284
89287
  }
89285
89288
  }
89286
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
+ };
89287
89296
  };
89288
89297
 
89289
89298
  // src/deltas/apis/messaging/sendTypingIndicator.ts
@@ -90927,6 +90936,8 @@ var sendMessageMqtt_default = (defaultFuncs, api, ctx) => {
90927
90936
  resolveFunc = resolve;
90928
90937
  rejectFunc = reject;
90929
90938
  });
90939
+ returnPromise.catch(() => {
90940
+ });
90930
90941
  const userCallback = typeof callback === "function" ? callback : null;
90931
90942
  let finished2 = false;
90932
90943
  const finish = (err, data2) => {
@@ -90943,51 +90954,14 @@ var sendMessageMqtt_default = (defaultFuncs, api, ctx) => {
90943
90954
  if (!callback) {
90944
90955
  callback = finish;
90945
90956
  }
90957
+ const done = () => userCallback ? returnPromise.then(() => null, () => null) : returnPromise;
90946
90958
  if (!ctx.mqttClient || !ctx.mqttClient.connected) {
90947
90959
  const error2 = new Error("MQTT client is not connected. Cannot send message.");
90948
90960
  finish(error2);
90949
- return returnPromise;
90961
+ return done();
90950
90962
  }
90951
90963
  const timestamp = Date.now();
90952
- const otid = generateOfflineThreadingID();
90953
- const epoch_id = (BigInt(Date.now()) << 22n).toString();
90954
- const request_id = ctx.wsReqNumber = (ctx.wsReqNumber || 0) + 1;
90955
- const payload = getSendPayload(threadID, msg, otid);
90956
- const tasks = [{
90957
- label: "46",
90958
- payload,
90959
- queue_name: threadID.toString(),
90960
- task_id: 400,
90961
- failure_count: null
90962
- }, {
90963
- label: "21",
90964
- payload: {
90965
- thread_id: threadID.toString(),
90966
- last_read_watermark_ts: timestamp,
90967
- sync_group: 1
90968
- },
90969
- queue_name: threadID.toString(),
90970
- task_id: 401,
90971
- failure_count: null
90972
- }];
90973
- if (replyToMessage) {
90974
- tasks[0].payload.reply_metadata = {
90975
- reply_source_id: replyToMessage,
90976
- reply_source_type: 1,
90977
- reply_type: 0
90978
- };
90979
- }
90980
- const form = {
90981
- app_id: "2220391788200892",
90982
- payload: {
90983
- tasks,
90984
- epoch_id,
90985
- version_id: "24804310205905615",
90986
- data_trace_id: `#${Buffer.from(String(Math.random())).toString("base64").replace(/=+$/g, "")}`
90987
- },
90988
- request_id,
90989
- type: 3
90990
- };
90964
+ let attachmentIds = null;
90991
90965
  if (msg.attachment) {
90992
90966
  try {
90993
90967
  const inputs = Array.isArray(msg.attachment) ? msg.attachment : [msg.attachment];
@@ -91004,20 +90978,62 @@ var sendMessageMqtt_default = (defaultFuncs, api, ctx) => {
91004
90978
  ids.push(file && typeof file === "object" ? String(Object.values(file)[0]) : String(file));
91005
90979
  }
91006
90980
  }
91007
- form.payload.tasks[0].payload.attachment_fbids = ids;
90981
+ attachmentIds = ids;
91008
90982
  } catch (err) {
91009
90983
  error("Attachment upload failed:", err);
91010
90984
  callback(err);
91011
- return returnPromise;
90985
+ return done();
91012
90986
  }
91013
90987
  }
91014
- form.payload.tasks.forEach((task) => {
91015
- task.payload = JSON.stringify(task.payload);
91016
- });
91017
- form.payload = JSON.stringify(form.payload);
91018
- const fallbackMessageID = `mid.${otid}`;
91019
90988
  const mqttClient = ctx.mqttClient;
91020
- 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) => {
91021
91037
  let settled = false;
91022
91038
  let timer = null;
91023
91039
  const cleanup = () => {
@@ -91057,10 +91073,12 @@ var sendMessageMqtt_default = (defaultFuncs, api, ctx) => {
91057
91073
  threadIDFromAck = String(node[2][1]);
91058
91074
  }
91059
91075
  if (node[1] === "markOptimisticMessageFailed") {
91060
- 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." };
91061
91078
  }
91062
91079
  if (node[1] === "updateSubscriptErrorMessage" || node[1] === "fatalError") {
91063
- 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;
91064
91082
  }
91065
91083
  }
91066
91084
  for (const child of node) visit(child);
@@ -91081,24 +91099,33 @@ var sendMessageMqtt_default = (defaultFuncs, api, ctx) => {
91081
91099
  });
91082
91100
  timer = setTimeout(() => settle2({ timeout: true }), 15e3);
91083
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
+ }
91084
91111
  if (result.failure || result.serverError) {
91085
91112
  const err = result.failure || { error: result.serverError };
91086
91113
  if (err.error && err.error === 1545012) {
91087
91114
  warn("sendMessageMqtt [MQTT]", `Got error 1545012. Bot is not part of the conversation ${threadID}`);
91088
91115
  finish(null, null);
91089
- return returnPromise;
91116
+ return done();
91090
91117
  }
91091
91118
  error("sendMessageMqtt", "Send failed:", err.error || err);
91092
91119
  finish(err);
91093
- return returnPromise;
91120
+ return done();
91094
91121
  }
91095
91122
  finish(null, {
91096
91123
  threadID: result.threadID || threadID.toString(),
91097
- messageID: result.messageID || fallbackMessageID,
91124
+ messageID: result.messageID || `mid.${lastOtid}`,
91098
91125
  timestamp,
91099
91126
  type: replyToMessage ? "message_reply" : "message"
91100
91127
  });
91101
- return returnPromise;
91128
+ return done();
91102
91129
  };
91103
91130
  };
91104
91131
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lazyneoaz/metachat",
3
- "version": "6.0.5",
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
  },