@dongdev/fca-unofficial 3.0.23 → 3.0.27

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.
@@ -1,47 +1,13 @@
1
1
  "use strict";
2
2
 
3
- const { getType } = require("../../utils/format");
4
- const { parseAndCheckLogin } = require("../../utils/client");
5
- const log = require("npmlog");
3
+ const { getType, generateOfflineThreadingID } = require("../../utils/format");
6
4
 
7
5
  module.exports = function (defaultFuncs, api, ctx) {
8
- function removeUserFromGroupNoMqtt(userID, threadID, callback) {
9
- if (!callback && (getType(threadID) === "Function" || getType(threadID) === "AsyncFunction")) throw { error: "please pass a threadID as a second argument." };
10
- if (getType(threadID) !== "Number" && getType(threadID) !== "String") throw { error: "threadID should be of type Number or String and not " + getType(threadID) + "." };
11
- if (getType(userID) !== "Number" && getType(userID) !== "String") throw { error: "userID should be of type Number or String and not " + getType(userID) + "." };
12
- var resolveFunc = function () { };
13
- var rejectFunc = function () { };
14
- var returnPromise = new Promise(function (resolve, reject) {
15
- resolveFunc = resolve;
16
- rejectFunc = reject;
17
- });
18
- if (!callback) {
19
- callback = function (err, data) {
20
- if (err) return rejectFunc(err);
21
- resolveFunc(data);
22
- };
23
- }
24
- var form = {
25
- uid: userID,
26
- tid: threadID
27
- };
28
- defaultFuncs
29
- .post("https://www.facebook.com/chat/remove_participants", ctx.jar, form)
30
- .then(parseAndCheckLogin(ctx, defaultFuncs))
31
- .then(function (resData) {
32
- if (!resData) throw { error: "Remove from group failed." };
33
- if (resData.error) throw resData;
34
- return callback();
35
- })
36
- .catch(function (err) {
37
- log.error("removeUserFromGroup", err);
38
- return callback(err);
39
- });
40
- return returnPromise;
41
- };
42
- function removeUserFromGroupMqtt(userID, threadID, callback) {
6
+ return function removeUserFromGroup(userID, threadID, callback) {
43
7
  if (!ctx.mqttClient) {
44
- throw new Error("Not connected to MQTT");
8
+ const err = new Error("Not connected to MQTT");
9
+ if (callback) return callback(err);
10
+ return Promise.reject(err);
45
11
  }
46
12
  if (!callback && (getType(threadID) === "Function" || getType(threadID) === "AsyncFunction")) throw { error: "please pass a threadID as a second argument." };
47
13
  if (getType(threadID) !== "Number" && getType(threadID) !== "String") throw { error: "threadID should be of type Number or String and not " + getType(threadID) + "." };
@@ -58,7 +24,8 @@ module.exports = function (defaultFuncs, api, ctx) {
58
24
  resolveFunc(data);
59
25
  };
60
26
  }
61
- let count_req = 0;
27
+ if (typeof ctx.wsReqNumber !== "number") ctx.wsReqNumber = 0;
28
+ const reqID = ++ctx.wsReqNumber;
62
29
  var form = JSON.stringify({
63
30
  "app_id": "2220391788200892",
64
31
  "payload": JSON.stringify({
@@ -76,15 +43,15 @@ module.exports = function (defaultFuncs, api, ctx) {
76
43
  task_id: Math.random() * 1001 << 0
77
44
  }
78
45
  ],
79
- version_id: '8798795233522156'
46
+ version_id: '25002366262773827'
80
47
  }),
81
- "request_id": ++count_req,
48
+ "request_id": reqID,
82
49
  "type": 3
83
50
  });
84
- mqttClient.publish('/ls_req', form, (err, data) => {
51
+ ctx.mqttClient.publish('/ls_req', form, (err, data) => {
85
52
  if (err) {
86
53
  callback(err, null);
87
- rejectFunc(false);
54
+ rejectFunc(err);
88
55
  } else {
89
56
  callback(null, true);
90
57
  resolveFunc(true);
@@ -92,15 +59,4 @@ module.exports = function (defaultFuncs, api, ctx) {
92
59
  });
93
60
  return returnPromise;
94
61
  };
95
- return function removeUserFromGroup(userID, threadID, callback) {
96
- if (ctx.mqttClient) {
97
- try {
98
- removeUserFromGroupMqtt(userID, threadID, callback);
99
- } catch (e) {
100
- removeUserFromGroupNoMqtt(userID, threadID, callback);
101
- }
102
- } else {
103
- removeUserFromGroupNoMqtt(userID, threadID, callback);
104
- }
105
- };
106
62
  };
@@ -12,30 +12,15 @@
12
12
 
13
13
  "use strict";
14
14
  const log = require("npmlog");
15
- const { parseAndCheckLogin } = require("../../utils/client");
16
15
  const { getType } = require("../../utils/format");
17
16
  const { isReadableStream } = require("../../utils/constants");
18
17
  const { generateOfflineThreadingID } = require("../../utils/format");
19
18
 
20
19
  module.exports = function (defaultFuncs, api, ctx) {
20
+ const uploadAttachment = require("./uploadAttachment")(defaultFuncs, api, ctx);
21
21
  const hasLinks = s => typeof s === "string" && /(https?:\/\/|www\.|t\.me\/|fb\.me\/|youtu\.be\/|facebook\.com\/|youtube\.com\/)/i.test(s);
22
22
  const emojiSizes = { small: 1, medium: 2, large: 3 };
23
23
 
24
- async function uploadAttachment(streams) {
25
- const uploads = streams.map(stream => {
26
- if (!isReadableStream(stream)) throw { error: "Attachment should be a readable stream and not " + getType(stream) + "." };
27
- const form = { farr: stream };
28
- return defaultFuncs
29
- .postFormData("https://www.facebook.com/ajax/mercury/upload.php", ctx.jar, form, {})
30
- .then(parseAndCheckLogin(ctx, defaultFuncs))
31
- .then(resData => {
32
- if (resData.error) throw resData;
33
- return resData.payload.metadata[0];
34
- });
35
- });
36
- return Promise.all(uploads);
37
- }
38
-
39
24
  function extractIdsFromPayload(payload) {
40
25
  let messageID = null;
41
26
  let threadID = null;
@@ -57,6 +42,19 @@ module.exports = function (defaultFuncs, api, ctx) {
57
42
 
58
43
  function publishWithAck(content, text, reqID, callback) {
59
44
  return new Promise((resolve, reject) => {
45
+ // Ensure MQTT client is available before using it
46
+ if (!ctx.mqttClient || typeof ctx.mqttClient.on !== "function" || typeof ctx.mqttClient.publish !== "function") {
47
+ const err = new Error("MQTT client is not initialized");
48
+ log.error("sendMessageMqtt", err);
49
+ callback && callback(err);
50
+ return reject(err);
51
+ }
52
+
53
+ // Remove default max listeners limit to avoid MaxListenersExceededWarning
54
+ if (typeof ctx.mqttClient.setMaxListeners === "function") {
55
+ ctx.mqttClient.setMaxListeners(0);
56
+ }
57
+
60
58
  let done = false;
61
59
  const cleanup = () => {
62
60
  if (done) return;
@@ -269,4 +267,4 @@ module.exports = function (defaultFuncs, api, ctx) {
269
267
  content.payload = JSON.stringify(content.payload);
270
268
  return publishWithAck(content, baseBody, reqID, callback);
271
269
  };
272
- };
270
+ };
@@ -1,13 +1,13 @@
1
1
  "use strict";
2
2
  const { getType } = require("../../utils/format.js");
3
3
  module.exports = function (defaultFuncs, api, ctx) {
4
- return function sendTyping(threadID, isTyping, options, callback) {
5
- var resolveFunc = function () { };
6
- var rejectFunc = function () { };
7
- var returnPromise = new Promise(function (resolve, reject) {
8
- resolveFunc = resolve;
9
- rejectFunc = reject;
10
- });
4
+ return function sendTyping(threadID, isTyping, options, callback) {
5
+ var resolveFunc = function () { };
6
+ var rejectFunc = function () { };
7
+ var returnPromise = new Promise(function (resolve, reject) {
8
+ resolveFunc = resolve;
9
+ rejectFunc = reject;
10
+ });
11
11
  if (getType(options) == "Function" || getType(options) == "AsyncFunction") {
12
12
  callback = options;
13
13
  options = {};
@@ -19,11 +19,18 @@ module.exports = function (defaultFuncs, api, ctx) {
19
19
  resolveFunc(data);
20
20
  };
21
21
  }
22
- if (!threadID) {
23
- return callback(new Error("threadID is required"));
24
- }
25
- const threadIDs = Array.isArray(threadID) ? threadID : [threadID];
26
- threadIDs.forEach(tid => {
22
+ if (!threadID) {
23
+ return callback(new Error("threadID is required"));
24
+ }
25
+ if (!ctx.mqttClient) {
26
+ const err = new Error("Not connected to MQTT");
27
+ callback(err);
28
+ rejectFunc(err);
29
+ return returnPromise;
30
+ }
31
+ if (typeof ctx.wsReqNumber !== "number") ctx.wsReqNumber = 0;
32
+ const threadIDs = Array.isArray(threadID) ? threadID : [threadID];
33
+ threadIDs.forEach(tid => {
27
34
  var isGroupThread = getType(tid) === "Array" ? 0 : 1;
28
35
  var threadType = isGroupThread ? 2 : 1;
29
36
  var duration = options.duration || 10000;
@@ -45,10 +52,10 @@ module.exports = function (defaultFuncs, api, ctx) {
45
52
  }),
46
53
  version: "8965252033599983"
47
54
  }),
48
- request_id: ++ctx.req_ID,
49
- type: 4
50
- }),
51
- {
55
+ request_id: ++ctx.wsReqNumber,
56
+ type: 4
57
+ }),
58
+ {
52
59
  qos: 1,
53
60
  retain: false,
54
61
  }
@@ -1,76 +1,91 @@
1
- "use strict";
2
-
3
- const logger = require("../../../func/logger");
4
- const { generateOfflineThreadingID, getCurrentTimestamp } = require("../../utils/format");
5
-
6
- module.exports = function (defaultFuncs, api, ctx) {
7
- return function setMessageReaction(reaction, messageID, threadID, callback) {
8
- return new Promise((resolve, reject) => {
9
- if (!ctx.mqttClient) {
10
- const err = new Error("MQTT client not connected");
11
- if (typeof callback === 'function') callback(err);
12
- return reject(err);
13
- }
14
- if (!reaction || !messageID || !threadID) {
15
- const err = new Error("Missing required parameters");
16
- if (typeof callback === 'function') callback(err);
17
- return reject(err);
18
- }
19
- const reqID = ++ctx.wsReqNumber;
20
- const taskID = ++ctx.wsTaskNumber;
21
- const taskPayload = {
22
- thread_key: threadID,
23
- timestamp_ms: getCurrentTimestamp(),
24
- message_id: messageID,
25
- reaction: reaction,
26
- actor_id: ctx.userID,
27
- reaction_style: null,
28
- sync_group: 1,
29
- send_attribution: 65537,
30
- dataclass_params: null,
31
- attachment_fbid: null
32
- };
33
- const task = {
34
- failure_count: null,
35
- label: "29",
36
- payload: JSON.stringify(taskPayload),
37
- queue_name: JSON.stringify(["reaction", messageID]),
38
- task_id: taskID,
39
- };
40
- const mqttForm = {
41
- app_id: "772021112871879",
42
- payload: JSON.stringify({
43
- data_trace_id: null,
44
- epoch_id: parseInt(generateOfflineThreadingID()),
45
- tasks: [task],
46
- version_id: "25376272951962053"
47
- }),
48
- request_id: reqID,
49
- type: 3
50
- };
51
- const handleResponse = (topic, message) => {
52
- if (topic !== "/ls_resp") return;
53
- let json;
54
- try {
55
- json = JSON.parse(message.toString());
56
- json.payload = JSON.parse(json.payload);
57
- } catch {
58
- return;
59
- }
60
- if (json.request_id !== reqID) return;
61
- ctx.mqttClient.removeListener("message", handleResponse);
62
- if (typeof callback === 'function') callback(null, { success: true });
63
- return resolve({ success: true });
64
- };
65
- ctx.mqttClient.on("message", handleResponse);
66
- ctx.mqttClient.publish("/ls_req", JSON.stringify(mqttForm), { qos: 1, retain: false }, (err) => {
67
- if (err) {
68
- ctx.mqttClient.removeListener("message", handleResponse);
69
- logger("setMessageReaction" + err, "error");
70
- if (typeof callback === 'function') callback(err);
71
- return reject(err);
72
- }
73
- });
74
- });
75
- };
76
- };
1
+ "use strict";
2
+
3
+ const logger = require("../../../func/logger");
4
+ const { generateOfflineThreadingID, getCurrentTimestamp } = require("../../utils/format");
5
+
6
+ module.exports = function (defaultFuncs, api, ctx) {
7
+ return function setMessageReaction(reaction, messageID, threadID, callback, forceCustomReaction) {
8
+ if (typeof threadID === "function") {
9
+ forceCustomReaction = callback;
10
+ callback = threadID;
11
+ threadID = undefined;
12
+ } else if (typeof threadID === "boolean") {
13
+ forceCustomReaction = threadID;
14
+ threadID = undefined;
15
+ } else if (typeof callback === "boolean") {
16
+ forceCustomReaction = callback;
17
+ callback = undefined;
18
+ }
19
+ const cb = typeof callback === "function" ? callback : undefined;
20
+
21
+ return new Promise((resolve, reject) => {
22
+ if (!ctx.mqttClient) {
23
+ const err = new Error("MQTT client not connected");
24
+ if (cb) cb(err);
25
+ return reject(err);
26
+ }
27
+ if (reaction === undefined || reaction === null || !messageID || !threadID) {
28
+ const err = new Error("Missing required parameters (reaction, messageID, threadID)");
29
+ if (cb) cb(err);
30
+ return reject(err);
31
+ }
32
+ if (typeof ctx.wsReqNumber !== "number") ctx.wsReqNumber = 0;
33
+ if (typeof ctx.wsTaskNumber !== "number") ctx.wsTaskNumber = 0;
34
+ const reqID = ++ctx.wsReqNumber;
35
+ const taskID = ++ctx.wsTaskNumber;
36
+ const taskPayload = {
37
+ thread_key: threadID,
38
+ timestamp_ms: getCurrentTimestamp(),
39
+ message_id: messageID,
40
+ reaction: reaction,
41
+ actor_id: ctx.userID,
42
+ reaction_style: forceCustomReaction ? 1 : null,
43
+ sync_group: 1,
44
+ send_attribution: 65537,
45
+ dataclass_params: null,
46
+ attachment_fbid: null
47
+ };
48
+ const task = {
49
+ failure_count: null,
50
+ label: "29",
51
+ payload: JSON.stringify(taskPayload),
52
+ queue_name: JSON.stringify(["reaction", messageID]),
53
+ task_id: taskID,
54
+ };
55
+ const mqttForm = {
56
+ app_id: "772021112871879",
57
+ payload: JSON.stringify({
58
+ data_trace_id: null,
59
+ epoch_id: parseInt(generateOfflineThreadingID()),
60
+ tasks: [task],
61
+ version_id: "25376272951962053"
62
+ }),
63
+ request_id: reqID,
64
+ type: 3
65
+ };
66
+ const handleResponse = (topic, message) => {
67
+ if (topic !== "/ls_resp") return;
68
+ let json;
69
+ try {
70
+ json = JSON.parse(message.toString());
71
+ json.payload = JSON.parse(json.payload);
72
+ } catch {
73
+ return;
74
+ }
75
+ if (json.request_id !== reqID) return;
76
+ ctx.mqttClient.removeListener("message", handleResponse);
77
+ if (cb) cb(null, { success: true });
78
+ return resolve({ success: true });
79
+ };
80
+ ctx.mqttClient.on("message", handleResponse);
81
+ ctx.mqttClient.publish("/ls_req", JSON.stringify(mqttForm), { qos: 1, retain: false }, (err) => {
82
+ if (err) {
83
+ ctx.mqttClient.removeListener("message", handleResponse);
84
+ logger("setMessageReaction" + err, "error");
85
+ if (cb) cb(err);
86
+ return reject(err);
87
+ }
88
+ });
89
+ });
90
+ };
91
+ };
@@ -62,28 +62,30 @@ module.exports = function (defaultFuncs, api, ctx) {
62
62
  });
63
63
  return returnPromise;
64
64
  };
65
- function setTitleMqtt(newTitle, threadID, callback) {
66
- if (!ctx.mqttClient) {
67
- throw new Error("Not connected to MQTT");
68
- }
69
- var resolveFunc = function () { };
70
- var rejectFunc = function () { };
71
- var returnPromise = new Promise(function (resolve, reject) {
72
- resolveFunc = resolve;
73
- rejectFunc = reject;
74
- });
75
- if (!callback) {
76
- callback = function (err, data) {
77
- if (err) return rejectFunc(err);
78
- resolveFunc(data);
79
- data
80
- };
81
- }
82
- let count_req = 0
83
- var form = JSON.stringify({
84
- "app_id": "2220391788200892",
85
- "payload": JSON.stringify({
86
- epoch_id: generateOfflineThreadingID(),
65
+ function setTitleMqtt(newTitle, threadID, callback) {
66
+ if (!ctx.mqttClient) {
67
+ throw new Error("Not connected to MQTT");
68
+ }
69
+ if (typeof ctx.wsReqNumber !== "number") ctx.wsReqNumber = 0;
70
+ const reqID = ++ctx.wsReqNumber;
71
+ var resolveFunc = function () { };
72
+ var rejectFunc = function () { };
73
+ var returnPromise = new Promise(function (resolve, reject) {
74
+ resolveFunc = resolve;
75
+ rejectFunc = reject;
76
+ });
77
+ const done = (err, data) => {
78
+ if (err) {
79
+ if (callback) callback(err);
80
+ return rejectFunc(err);
81
+ }
82
+ if (callback) callback(null, data);
83
+ resolveFunc(data);
84
+ };
85
+ var form = JSON.stringify({
86
+ "app_id": "2220391788200892",
87
+ "payload": JSON.stringify({
88
+ epoch_id: generateOfflineThreadingID(),
87
89
  tasks: [
88
90
  {
89
91
  failure_count: null,
@@ -97,23 +99,26 @@ module.exports = function (defaultFuncs, api, ctx) {
97
99
  task_id: Math.random() * 1001 << 0
98
100
  }
99
101
  ],
100
- version_id: '8798795233522156'
101
- }),
102
- "request_id": ++count_req,
103
- "type": 3
104
- });
105
- mqttClient.publish('/ls_req', form);
106
- return returnPromise;
107
- };
108
- return function setTitle(newTitle, threadID, callback) {
109
- if (ctx.mqttClient) {
110
- try {
111
- setTitleMqtt(newTitle, threadID, callback);
112
- } catch (e) {
113
- setTitleNoMqtt(newTitle, threadID, callback);
114
- }
115
- } else {
116
- setTitleNoMqtt(newTitle, threadID, callback);
117
- }
118
- };
119
- };
102
+ version_id: '8798795233522156'
103
+ }),
104
+ "request_id": reqID,
105
+ "type": 3
106
+ });
107
+ ctx.mqttClient.publish("/ls_req", form, { qos: 1, retain: false }, (err) => {
108
+ if (err) return done(err);
109
+ done(null, { success: true });
110
+ });
111
+ return returnPromise;
112
+ };
113
+ return function setTitle(newTitle, threadID, callback) {
114
+ if (ctx.mqttClient) {
115
+ try {
116
+ return setTitleMqtt(newTitle, threadID, callback);
117
+ } catch (e) {
118
+ return setTitleNoMqtt(newTitle, threadID, callback);
119
+ }
120
+ } else {
121
+ return setTitleNoMqtt(newTitle, threadID, callback);
122
+ }
123
+ };
124
+ };
@@ -43,7 +43,7 @@ module.exports = function(defaultFuncs, api, ctx) {
43
43
  request_id: ++count_req,
44
44
  type: 3
45
45
  });
46
- mqttClient.publish("/ls_req", form);
46
+ ctx.mqttClient.publish("/ls_req", form);
47
47
  return returnPromise;
48
48
  };
49
49
  };