@dongdev/fca-unofficial 3.0.22 → 3.0.25
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/CHANGELOG.md +6 -0
- package/DOCS.md +3 -3
- package/README.md +1 -1
- package/index.d.ts +1 -1
- package/package.json +1 -1
- package/src/api/messaging/changeAdminStatus.js +56 -52
- package/src/api/messaging/changeThreadEmoji.js +47 -42
- package/src/api/messaging/createPoll.js +19 -16
- package/src/api/messaging/forwardAttachment.js +28 -22
- package/src/api/messaging/removeUserFromGroup.js +40 -39
- package/src/api/messaging/sendTypingIndicator.js +23 -16
- package/src/api/messaging/setMessageReaction.js +60 -42
- package/src/api/messaging/setTitle.js +47 -42
- package/src/api/messaging/shareContact.js +1 -1
- package/src/api/socket/core/connectMqtt.js +0 -5
- package/src/api/socket/core/emitAuth.js +1 -8
- package/src/api/socket/core/parseDelta.js +3 -17
- package/src/api/socket/listenMqtt.js +0 -4
- package/src/utils/format.js +48 -16
package/CHANGELOG.md
CHANGED
package/DOCS.md
CHANGED
|
@@ -1568,7 +1568,7 @@ Add reaction (like, love, haha, wow, sad, angry) to message.
|
|
|
1568
1568
|
|
|
1569
1569
|
#### Syntax:
|
|
1570
1570
|
```javascript
|
|
1571
|
-
api.setMessageReaction(reaction, messageID, callback);
|
|
1571
|
+
api.setMessageReaction(reaction, messageID, threadID, callback, forceCustomReaction);
|
|
1572
1572
|
```
|
|
1573
1573
|
|
|
1574
1574
|
#### Example:
|
|
@@ -1587,7 +1587,7 @@ api.listenMqtt((err, event) => {
|
|
|
1587
1587
|
if (err) return console.error(err);
|
|
1588
1588
|
|
|
1589
1589
|
if (event.type === "message" && event.body === "React me") {
|
|
1590
|
-
api.setMessageReaction("❤️", event.messageID, (err) => {
|
|
1590
|
+
api.setMessageReaction("❤️", event.messageID, event.threadID, (err) => {
|
|
1591
1591
|
if (err) {
|
|
1592
1592
|
console.error("React error:", err);
|
|
1593
1593
|
return;
|
|
@@ -1598,7 +1598,7 @@ api.listenMqtt((err, event) => {
|
|
|
1598
1598
|
});
|
|
1599
1599
|
|
|
1600
1600
|
// Remove reaction
|
|
1601
|
-
api.setMessageReaction("", "mid.xxx", (err) => {
|
|
1601
|
+
api.setMessageReaction("", "mid.xxx", "1234567890", (err) => {
|
|
1602
1602
|
if (err) return console.error(err);
|
|
1603
1603
|
console.log("Reaction removed!");
|
|
1604
1604
|
});
|
package/README.md
CHANGED
|
@@ -343,7 +343,7 @@ api.deleteMessage(messageID, callback);
|
|
|
343
343
|
api.unsendMessage(messageID, callback);
|
|
344
344
|
|
|
345
345
|
// Set message reaction
|
|
346
|
-
api.setMessageReaction(reaction, messageID, callback);
|
|
346
|
+
api.setMessageReaction(reaction, messageID, threadID, callback, forceCustomReaction);
|
|
347
347
|
|
|
348
348
|
// Forward attachment
|
|
349
349
|
api.forwardAttachment(attachmentID, threadID, callback);
|
package/index.d.ts
CHANGED
|
@@ -143,7 +143,7 @@
|
|
|
143
143
|
pinMessage: (pinMode: boolean, messageID: string, threadID: string, callback?: (err?: Error) => void) => Promise<void>;
|
|
144
144
|
|
|
145
145
|
// Reactions & Interactions
|
|
146
|
-
setMessageReaction: (reaction: string, messageID: string, callback?: (err?: Error) => void, forceCustomReaction?: boolean) => Promise<void>;
|
|
146
|
+
setMessageReaction: (reaction: string, messageID: string, threadID: string, callback?: (err?: Error) => void, forceCustomReaction?: boolean) => Promise<void>;
|
|
147
147
|
setMessageReactionMqtt: (reaction: string, messageID: string, threadID: string, callback?: (err?: Error) => void) => Promise<void>;
|
|
148
148
|
sendTypingIndicator: (threadID: string, callback?: (err?: Error) => void) => Promise<void>;
|
|
149
149
|
sendTypingIndicatorMqtt: (isTyping: boolean, threadID: string, callback?: (err?: Error) => void) => Promise<void>;
|
package/package.json
CHANGED
|
@@ -3,15 +3,17 @@
|
|
|
3
3
|
const { generateOfflineThreadingID, getType } = require("../../utils/format");
|
|
4
4
|
|
|
5
5
|
module.exports = function (defaultFuncs, api, ctx) {
|
|
6
|
-
function changeAdminStatusNoMqtt(threadID, adminID, adminStatus) {
|
|
7
|
-
if (getType(threadID) !== "String") throw { error: "changeAdminStatus: threadID must be a string" };
|
|
8
|
-
if (getType(adminID) !== "String" && getType(adminID) !== "Array") throw { error: "changeAdminStatus: adminID must be a string or an array" };
|
|
9
|
-
if (getType(adminStatus) !== "Boolean") throw { error: "changeAdminStatus: adminStatus must be true or false" };
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
6
|
+
function changeAdminStatusNoMqtt(threadID, adminID, adminStatus) {
|
|
7
|
+
if (getType(threadID) !== "String") throw { error: "changeAdminStatus: threadID must be a string" };
|
|
8
|
+
if (getType(adminID) !== "String" && getType(adminID) !== "Array") throw { error: "changeAdminStatus: adminID must be a string or an array" };
|
|
9
|
+
if (getType(adminStatus) !== "Boolean") throw { error: "changeAdminStatus: adminStatus must be true or false" };
|
|
10
|
+
if (typeof ctx.wsReqNumber !== "number") ctx.wsReqNumber = 0;
|
|
11
|
+
const reqID = ++ctx.wsReqNumber;
|
|
12
|
+
let wsContent = {
|
|
13
|
+
request_id: reqID,
|
|
14
|
+
type: 3,
|
|
15
|
+
payload: {
|
|
16
|
+
version_id: '3816854585040595',
|
|
15
17
|
tasks: [],
|
|
16
18
|
epoch_id: generateOfflineThreadingID(),
|
|
17
19
|
data_trace_id: null
|
|
@@ -37,12 +39,20 @@ module.exports = function (defaultFuncs, api, ctx) {
|
|
|
37
39
|
failure_count: null
|
|
38
40
|
});
|
|
39
41
|
}
|
|
40
|
-
wsContent.payload = JSON.stringify(wsContent.payload);
|
|
41
|
-
return new Promise((resolve, reject) =>
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
42
|
+
wsContent.payload = JSON.stringify(wsContent.payload);
|
|
43
|
+
return new Promise((resolve, reject) => {
|
|
44
|
+
if (!ctx.mqttClient) {
|
|
45
|
+
return reject(new Error("Not connected to MQTT"));
|
|
46
|
+
}
|
|
47
|
+
ctx.mqttClient.publish("/ls_req", JSON.stringify(wsContent), {}, (err) => {
|
|
48
|
+
if (err) return reject(err);
|
|
49
|
+
resolve();
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
};
|
|
53
|
+
function changeAdminStatusMqtt(threadID, adminID, adminStatus) {
|
|
54
|
+
if (!ctx.mqttClient) {
|
|
55
|
+
throw new Error("Not connected to MQTT");
|
|
46
56
|
}
|
|
47
57
|
if (getType(threadID) !== "String") {
|
|
48
58
|
throw { error: "changeAdminStatus: threadID must be a string" };
|
|
@@ -83,40 +93,34 @@ module.exports = function (defaultFuncs, api, ctx) {
|
|
|
83
93
|
task_id: 1
|
|
84
94
|
});
|
|
85
95
|
}
|
|
86
|
-
|
|
87
|
-
const
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
}
|
|
118
|
-
} else {
|
|
119
|
-
changeAdminStatusNoMqtt(threadID, adminID, adminStatus);
|
|
120
|
-
}
|
|
121
|
-
};
|
|
122
|
-
};
|
|
96
|
+
if (typeof ctx.wsReqNumber !== "number") ctx.wsReqNumber = 0;
|
|
97
|
+
const reqID = ++ctx.wsReqNumber;
|
|
98
|
+
const form = JSON.stringify({
|
|
99
|
+
app_id: "2220391788200892",
|
|
100
|
+
payload: JSON.stringify({
|
|
101
|
+
epoch_id: epochID,
|
|
102
|
+
tasks: tasks,
|
|
103
|
+
version_id: "8798795233522156"
|
|
104
|
+
}),
|
|
105
|
+
request_id: reqID,
|
|
106
|
+
type: 3
|
|
107
|
+
});
|
|
108
|
+
return new Promise((resolve, reject) => {
|
|
109
|
+
ctx.mqttClient.publish("/ls_req", form, {}, (err) => {
|
|
110
|
+
if (err) return reject(err);
|
|
111
|
+
resolve();
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
};
|
|
115
|
+
return function changeAdminStatus(threadID, adminID, adminStatus) {
|
|
116
|
+
if (ctx.mqttClient) {
|
|
117
|
+
try {
|
|
118
|
+
return changeAdminStatusMqtt(threadID, adminID, adminStatus);
|
|
119
|
+
} catch (e) {
|
|
120
|
+
return changeAdminStatusNoMqtt(threadID, adminID, adminStatus);
|
|
121
|
+
}
|
|
122
|
+
} else {
|
|
123
|
+
return changeAdminStatusNoMqtt(threadID, adminID, adminStatus);
|
|
124
|
+
}
|
|
125
|
+
};
|
|
126
|
+
};
|
|
@@ -48,28 +48,30 @@ module.exports = function (defaultFuncs, api, ctx) {
|
|
|
48
48
|
});
|
|
49
49
|
return returnPromise;
|
|
50
50
|
};
|
|
51
|
-
function changeThreadEmojiMqtt(emoji, threadID, callback) {
|
|
52
|
-
if (!ctx.mqttClient) {
|
|
53
|
-
throw new Error("Not connected to MQTT");
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
var
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
51
|
+
function changeThreadEmojiMqtt(emoji, threadID, callback) {
|
|
52
|
+
if (!ctx.mqttClient) {
|
|
53
|
+
throw new Error("Not connected to MQTT");
|
|
54
|
+
}
|
|
55
|
+
if (typeof ctx.wsReqNumber !== "number") ctx.wsReqNumber = 0;
|
|
56
|
+
const reqID = ++ctx.wsReqNumber;
|
|
57
|
+
var resolveFunc = function () { };
|
|
58
|
+
var rejectFunc = function () { };
|
|
59
|
+
var returnPromise = new Promise(function (resolve, reject) {
|
|
60
|
+
resolveFunc = resolve;
|
|
61
|
+
rejectFunc = reject;
|
|
62
|
+
});
|
|
63
|
+
const done = (err, data) => {
|
|
64
|
+
if (err) {
|
|
65
|
+
if (callback) callback(err);
|
|
66
|
+
return rejectFunc(err);
|
|
67
|
+
}
|
|
68
|
+
if (callback) callback(null, data);
|
|
69
|
+
resolveFunc(data);
|
|
70
|
+
};
|
|
71
|
+
var form = JSON.stringify({
|
|
72
|
+
"app_id": "2220391788200892",
|
|
73
|
+
"payload": JSON.stringify({
|
|
74
|
+
epoch_id: generateOfflineThreadingID(),
|
|
73
75
|
tasks: [
|
|
74
76
|
{
|
|
75
77
|
failure_count: null,
|
|
@@ -84,23 +86,26 @@ module.exports = function (defaultFuncs, api, ctx) {
|
|
|
84
86
|
task_id: Math.random() * 1001 << 0
|
|
85
87
|
}
|
|
86
88
|
],
|
|
87
|
-
version_id: '8798795233522156'
|
|
88
|
-
}),
|
|
89
|
-
"request_id":
|
|
90
|
-
"type": 3
|
|
91
|
-
});
|
|
92
|
-
mqttClient.publish(
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
89
|
+
version_id: '8798795233522156'
|
|
90
|
+
}),
|
|
91
|
+
"request_id": reqID,
|
|
92
|
+
"type": 3
|
|
93
|
+
});
|
|
94
|
+
ctx.mqttClient.publish("/ls_req", form, { qos: 1, retain: false }, (err) => {
|
|
95
|
+
if (err) return done(err);
|
|
96
|
+
done(null, { success: true });
|
|
97
|
+
});
|
|
98
|
+
return returnPromise;
|
|
99
|
+
};
|
|
100
|
+
return function changeThreadEmoji(emoji, threadID, callback) {
|
|
101
|
+
if (ctx.mqttClient) {
|
|
102
|
+
try {
|
|
103
|
+
return changeThreadEmojiMqtt(emoji, threadID, callback);
|
|
104
|
+
} catch (e) {
|
|
105
|
+
return changeThreadEmojiNoMqtt(emoji, threadID, callback);
|
|
106
|
+
}
|
|
107
|
+
} else {
|
|
108
|
+
return changeThreadEmojiNoMqtt(emoji, threadID, callback);
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
};
|
|
@@ -2,13 +2,16 @@
|
|
|
2
2
|
|
|
3
3
|
const { generateOfflineThreadingID } = require("../../utils/format");
|
|
4
4
|
|
|
5
|
-
module.exports = function (defaultFuncs, api, ctx) {
|
|
6
|
-
return async function createPoll(threadID, questionText, options) {
|
|
7
|
-
let count_req = 0
|
|
8
|
-
return new Promise((resolve, reject) => {
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
5
|
+
module.exports = function (defaultFuncs, api, ctx) {
|
|
6
|
+
return async function createPoll(threadID, questionText, options) {
|
|
7
|
+
let count_req = 0
|
|
8
|
+
return new Promise((resolve, reject) => {
|
|
9
|
+
if (!ctx.mqttClient) {
|
|
10
|
+
return reject(new Error("Not connected to MQTT"));
|
|
11
|
+
}
|
|
12
|
+
const payload = {
|
|
13
|
+
epoch_id: generateOfflineThreadingID(),
|
|
14
|
+
tasks: [
|
|
12
15
|
{
|
|
13
16
|
failure_count: null,
|
|
14
17
|
label: "163",
|
|
@@ -30,14 +33,14 @@ module.exports = function (defaultFuncs, api, ctx) {
|
|
|
30
33
|
payload: JSON.stringify(payload),
|
|
31
34
|
request_id: ++count_req,
|
|
32
35
|
type: 3
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
try {
|
|
36
|
-
mqttClient.publish("/ls_req", form);
|
|
37
|
-
resolve();
|
|
38
|
-
} catch (err) {
|
|
39
|
-
reject(err);
|
|
40
|
-
}
|
|
41
|
-
});
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
try {
|
|
39
|
+
ctx.mqttClient.publish("/ls_req", form);
|
|
40
|
+
resolve();
|
|
41
|
+
} catch (err) {
|
|
42
|
+
reject(err);
|
|
43
|
+
}
|
|
44
|
+
});
|
|
42
45
|
};
|
|
43
46
|
};
|
|
@@ -2,23 +2,29 @@
|
|
|
2
2
|
|
|
3
3
|
const { generateOfflineThreadingID } = require("../../utils/format");
|
|
4
4
|
|
|
5
|
-
module.exports = function (defaultFuncs, api, ctx) {
|
|
6
|
-
return async function forwardMessage(threadID, forwardedMsgID, callback) {
|
|
7
|
-
let resolveFunc, rejectFunc;
|
|
8
|
-
const returnPromise = new Promise((resolve, reject) => {
|
|
5
|
+
module.exports = function (defaultFuncs, api, ctx) {
|
|
6
|
+
return async function forwardMessage(threadID, forwardedMsgID, callback) {
|
|
7
|
+
let resolveFunc, rejectFunc;
|
|
8
|
+
const returnPromise = new Promise((resolve, reject) => {
|
|
9
9
|
resolveFunc = resolve;
|
|
10
10
|
rejectFunc = reject;
|
|
11
11
|
});
|
|
12
|
-
if (!callback) {
|
|
13
|
-
callback = (err, data) => {
|
|
14
|
-
if (err) return rejectFunc(err);
|
|
15
|
-
resolveFunc(data);
|
|
16
|
-
};
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
12
|
+
if (!callback) {
|
|
13
|
+
callback = (err, data) => {
|
|
14
|
+
if (err) return rejectFunc(err);
|
|
15
|
+
resolveFunc(data);
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
if (!ctx.mqttClient) {
|
|
19
|
+
const err = new Error("Not connected to MQTT");
|
|
20
|
+
callback?.(err);
|
|
21
|
+
rejectFunc(err);
|
|
22
|
+
return returnPromise;
|
|
23
|
+
}
|
|
24
|
+
let count_req = 0
|
|
25
|
+
const payload = {
|
|
26
|
+
epoch_id: generateOfflineThreadingID(),
|
|
27
|
+
tasks: [
|
|
22
28
|
{
|
|
23
29
|
failure_count: null,
|
|
24
30
|
label: "46",
|
|
@@ -41,11 +47,11 @@ module.exports = function (defaultFuncs, api, ctx) {
|
|
|
41
47
|
};
|
|
42
48
|
const form = JSON.stringify({
|
|
43
49
|
app_id: "772021112871879",
|
|
44
|
-
payload: JSON.stringify(payload),
|
|
45
|
-
"request_id": ++count_req,
|
|
46
|
-
"type": 3
|
|
47
|
-
});
|
|
48
|
-
mqttClient.publish("/ls_req", form);
|
|
49
|
-
return returnPromise;
|
|
50
|
-
};
|
|
51
|
-
};
|
|
50
|
+
payload: JSON.stringify(payload),
|
|
51
|
+
"request_id": ++count_req,
|
|
52
|
+
"type": 3
|
|
53
|
+
});
|
|
54
|
+
ctx.mqttClient.publish("/ls_req", form);
|
|
55
|
+
return returnPromise;
|
|
56
|
+
};
|
|
57
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
const { getType } = require("../../utils/format");
|
|
3
|
+
const { getType, generateOfflineThreadingID } = require("../../utils/format");
|
|
4
4
|
const { parseAndCheckLogin } = require("../../utils/client");
|
|
5
5
|
const log = require("npmlog");
|
|
6
6
|
|
|
@@ -39,13 +39,15 @@ module.exports = function (defaultFuncs, api, ctx) {
|
|
|
39
39
|
});
|
|
40
40
|
return returnPromise;
|
|
41
41
|
};
|
|
42
|
-
function removeUserFromGroupMqtt(userID, threadID, callback) {
|
|
43
|
-
if (!ctx.mqttClient) {
|
|
44
|
-
throw new Error("Not connected to MQTT");
|
|
45
|
-
}
|
|
46
|
-
if (
|
|
47
|
-
|
|
48
|
-
if (getType(
|
|
42
|
+
function removeUserFromGroupMqtt(userID, threadID, callback) {
|
|
43
|
+
if (!ctx.mqttClient) {
|
|
44
|
+
throw new Error("Not connected to MQTT");
|
|
45
|
+
}
|
|
46
|
+
if (typeof ctx.wsReqNumber !== "number") ctx.wsReqNumber = 0;
|
|
47
|
+
const reqID = ++ctx.wsReqNumber;
|
|
48
|
+
if (!callback && (getType(threadID) === "Function" || getType(threadID) === "AsyncFunction")) throw { error: "please pass a threadID as a second argument." };
|
|
49
|
+
if (getType(threadID) !== "Number" && getType(threadID) !== "String") throw { error: "threadID should be of type Number or String and not " + getType(threadID) + "." };
|
|
50
|
+
if (getType(userID) !== "Number" && getType(userID) !== "String") throw { error: "userID should be of type Number or String and not " + getType(userID) + "." };
|
|
49
51
|
var resolveFunc = function () { };
|
|
50
52
|
var rejectFunc = function () { };
|
|
51
53
|
var returnPromise = new Promise(function (resolve, reject) {
|
|
@@ -58,11 +60,10 @@ module.exports = function (defaultFuncs, api, ctx) {
|
|
|
58
60
|
resolveFunc(data);
|
|
59
61
|
};
|
|
60
62
|
}
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
"
|
|
64
|
-
|
|
65
|
-
epoch_id: generateOfflineThreadingID(),
|
|
63
|
+
var form = JSON.stringify({
|
|
64
|
+
"app_id": "2220391788200892",
|
|
65
|
+
"payload": JSON.stringify({
|
|
66
|
+
epoch_id: generateOfflineThreadingID(),
|
|
66
67
|
tasks: [
|
|
67
68
|
{
|
|
68
69
|
failure_count: null,
|
|
@@ -76,31 +77,31 @@ module.exports = function (defaultFuncs, api, ctx) {
|
|
|
76
77
|
task_id: Math.random() * 1001 << 0
|
|
77
78
|
}
|
|
78
79
|
],
|
|
79
|
-
version_id: '8798795233522156'
|
|
80
|
-
}),
|
|
81
|
-
"request_id":
|
|
82
|
-
"type": 3
|
|
83
|
-
});
|
|
84
|
-
mqttClient.publish('/ls_req', form, (err, data) => {
|
|
85
|
-
if (err) {
|
|
86
|
-
callback(err, null);
|
|
87
|
-
rejectFunc(
|
|
88
|
-
} else {
|
|
89
|
-
callback(null, true);
|
|
90
|
-
resolveFunc(true);
|
|
91
|
-
}
|
|
92
|
-
});
|
|
80
|
+
version_id: '8798795233522156'
|
|
81
|
+
}),
|
|
82
|
+
"request_id": reqID,
|
|
83
|
+
"type": 3
|
|
84
|
+
});
|
|
85
|
+
ctx.mqttClient.publish('/ls_req', form, (err, data) => {
|
|
86
|
+
if (err) {
|
|
87
|
+
callback(err, null);
|
|
88
|
+
rejectFunc(err);
|
|
89
|
+
} else {
|
|
90
|
+
callback(null, true);
|
|
91
|
+
resolveFunc(true);
|
|
92
|
+
}
|
|
93
|
+
});
|
|
93
94
|
return returnPromise;
|
|
94
95
|
};
|
|
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
|
-
};
|
|
96
|
+
return function removeUserFromGroup(userID, threadID, callback) {
|
|
97
|
+
if (ctx.mqttClient) {
|
|
98
|
+
try {
|
|
99
|
+
return removeUserFromGroupMqtt(userID, threadID, callback);
|
|
100
|
+
} catch (e) {
|
|
101
|
+
return removeUserFromGroupNoMqtt(userID, threadID, callback);
|
|
102
|
+
}
|
|
103
|
+
} else {
|
|
104
|
+
return removeUserFromGroupNoMqtt(userID, threadID, callback);
|
|
105
|
+
}
|
|
106
|
+
};
|
|
107
|
+
};
|
|
@@ -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
|
-
|
|
26
|
-
|
|
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.
|
|
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
|
}
|
|
@@ -3,33 +3,51 @@
|
|
|
3
3
|
const logger = require("../../../func/logger");
|
|
4
4
|
const { generateOfflineThreadingID, getCurrentTimestamp } = require("../../utils/format");
|
|
5
5
|
|
|
6
|
-
module.exports = function (defaultFuncs, api, ctx) {
|
|
7
|
-
return function setMessageReaction(reaction, messageID, threadID, callback) {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
6
|
+
module.exports = function (defaultFuncs, api, ctx) {
|
|
7
|
+
return function setMessageReaction(reaction, messageID, threadID, callback, forceCustomReaction) {
|
|
8
|
+
// Signature support:
|
|
9
|
+
// 1) (reaction, messageID, threadID, callback?, forceCustomReaction?)
|
|
10
|
+
// 2) (reaction, messageID, callback?, forceCustomReaction?) -> will error because threadID is required for MQTT
|
|
11
|
+
if (typeof threadID === "function") {
|
|
12
|
+
forceCustomReaction = callback;
|
|
13
|
+
callback = threadID;
|
|
14
|
+
threadID = undefined;
|
|
15
|
+
} else if (typeof threadID === "boolean") {
|
|
16
|
+
forceCustomReaction = threadID;
|
|
17
|
+
threadID = undefined;
|
|
18
|
+
} else if (typeof callback === "boolean") {
|
|
19
|
+
forceCustomReaction = callback;
|
|
20
|
+
callback = undefined;
|
|
21
|
+
}
|
|
22
|
+
const cb = typeof callback === "function" ? callback : undefined;
|
|
23
|
+
|
|
24
|
+
return new Promise((resolve, reject) => {
|
|
25
|
+
if (!ctx.mqttClient) {
|
|
26
|
+
const err = new Error("MQTT client not connected");
|
|
27
|
+
if (cb) cb(err);
|
|
28
|
+
return reject(err);
|
|
29
|
+
}
|
|
30
|
+
if (reaction === undefined || reaction === null || !messageID || !threadID) {
|
|
31
|
+
const err = new Error("Missing required parameters (reaction, messageID, threadID)");
|
|
32
|
+
if (cb) cb(err);
|
|
33
|
+
return reject(err);
|
|
34
|
+
}
|
|
35
|
+
if (typeof ctx.wsReqNumber !== "number") ctx.wsReqNumber = 0;
|
|
36
|
+
if (typeof ctx.wsTaskNumber !== "number") ctx.wsTaskNumber = 0;
|
|
37
|
+
const reqID = ++ctx.wsReqNumber;
|
|
38
|
+
const taskID = ++ctx.wsTaskNumber;
|
|
39
|
+
const taskPayload = {
|
|
40
|
+
thread_key: threadID,
|
|
41
|
+
timestamp_ms: getCurrentTimestamp(),
|
|
42
|
+
message_id: messageID,
|
|
43
|
+
reaction: reaction,
|
|
44
|
+
actor_id: ctx.userID,
|
|
45
|
+
reaction_style: forceCustomReaction ? 1 : null,
|
|
46
|
+
sync_group: 1,
|
|
47
|
+
send_attribution: 65537,
|
|
48
|
+
dataclass_params: null,
|
|
49
|
+
attachment_fbid: null
|
|
50
|
+
};
|
|
33
51
|
const task = {
|
|
34
52
|
failure_count: null,
|
|
35
53
|
label: "29",
|
|
@@ -59,18 +77,18 @@ module.exports = function (defaultFuncs, api, ctx) {
|
|
|
59
77
|
}
|
|
60
78
|
if (json.request_id !== reqID) return;
|
|
61
79
|
ctx.mqttClient.removeListener("message", handleResponse);
|
|
62
|
-
if (
|
|
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 (
|
|
71
|
-
return reject(err);
|
|
72
|
-
}
|
|
73
|
-
});
|
|
74
|
-
});
|
|
75
|
-
};
|
|
76
|
-
};
|
|
80
|
+
if (cb) cb(null, { success: true });
|
|
81
|
+
return resolve({ success: true });
|
|
82
|
+
};
|
|
83
|
+
ctx.mqttClient.on("message", handleResponse);
|
|
84
|
+
ctx.mqttClient.publish("/ls_req", JSON.stringify(mqttForm), { qos: 1, retain: false }, (err) => {
|
|
85
|
+
if (err) {
|
|
86
|
+
ctx.mqttClient.removeListener("message", handleResponse);
|
|
87
|
+
logger("setMessageReaction" + err, "error");
|
|
88
|
+
if (cb) cb(err);
|
|
89
|
+
return reject(err);
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
});
|
|
93
|
+
};
|
|
94
|
+
};
|
|
@@ -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
|
-
|
|
70
|
-
|
|
71
|
-
var
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
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":
|
|
103
|
-
"type": 3
|
|
104
|
-
});
|
|
105
|
-
mqttClient.publish(
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
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
|
+
};
|
|
@@ -85,11 +85,6 @@ module.exports = function createListenMqtt(deps) {
|
|
|
85
85
|
options
|
|
86
86
|
);
|
|
87
87
|
const mqttClient = ctx.mqttClient;
|
|
88
|
-
// Remove global reference to prevent memory leak
|
|
89
|
-
// Only set if needed for debugging, but clear on cleanup
|
|
90
|
-
if (process.env.DEBUG_MQTT) {
|
|
91
|
-
global.mqttClient = mqttClient;
|
|
92
|
-
}
|
|
93
88
|
|
|
94
89
|
mqttClient.on("error", function (err) {
|
|
95
90
|
const msg = String(err && err.message ? err.message : err || "");
|
|
@@ -80,14 +80,7 @@ module.exports = function createEmitAuth({ logger }) {
|
|
|
80
80
|
}
|
|
81
81
|
} catch (_) { }
|
|
82
82
|
|
|
83
|
-
|
|
84
|
-
try {
|
|
85
|
-
if (global.mqttClient) {
|
|
86
|
-
delete global.mqttClient;
|
|
87
|
-
}
|
|
88
|
-
} catch (_) { }
|
|
89
|
-
|
|
90
|
-
const msg = detail || reason;
|
|
83
|
+
const msg = detail || reason;
|
|
91
84
|
logger(`auth change -> ${reason}: ${msg}`, "error");
|
|
92
85
|
|
|
93
86
|
if (typeof globalCallback === "function") {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
const { formatDeltaEvent, formatMessage, _formatAttachment, formatDeltaMessage, formatDeltaReadReceipt, formatID, getType, decodeClientPayload } = require("../../../utils/format");
|
|
2
|
+
const { formatDeltaEvent, formatMessage, _formatAttachment, formatDeltaMessage, formatDeltaReadReceipt, formatID, getType, decodeClientPayload, getMentionsFromDeltaMessage } = require("../../../utils/format");
|
|
3
3
|
const logger = require("../../../../func/logger");
|
|
4
4
|
module.exports = function createParseDelta(deps) {
|
|
5
5
|
const { markDelivery, parseAndCheckLogin } = deps;
|
|
@@ -67,14 +67,7 @@ module.exports = function createParseDelta(deps) {
|
|
|
67
67
|
logger("parseDelta: deltaMessageReply.message or messageMetadata is missing", "warn");
|
|
68
68
|
return;
|
|
69
69
|
}
|
|
70
|
-
const
|
|
71
|
-
const m_id = mdata.map(u => u.i);
|
|
72
|
-
const m_offset = mdata.map(u => u.o);
|
|
73
|
-
const m_length = mdata.map(u => u.l);
|
|
74
|
-
const mentions = {};
|
|
75
|
-
for (let i = 0; i < m_id.length; i++) {
|
|
76
|
-
mentions[m_id[i]] = (msg.body || "").substring(m_offset[i], m_offset[i] + m_length[i]);
|
|
77
|
-
}
|
|
70
|
+
const mentions = getMentionsFromDeltaMessage(msg);
|
|
78
71
|
const msgMetadata = msg.messageMetadata;
|
|
79
72
|
const threadKey = msgMetadata.threadKey || {};
|
|
80
73
|
callbackToReturn = {
|
|
@@ -111,14 +104,7 @@ module.exports = function createParseDelta(deps) {
|
|
|
111
104
|
if (d.deltaMessageReply.repliedToMessage) {
|
|
112
105
|
try {
|
|
113
106
|
const repliedTo = d.deltaMessageReply.repliedToMessage;
|
|
114
|
-
const
|
|
115
|
-
const m_id2 = mdata2.map(u => u.i);
|
|
116
|
-
const m_offset2 = mdata2.map(u => u.o);
|
|
117
|
-
const m_length2 = mdata2.map(u => u.l);
|
|
118
|
-
const rmentions = {};
|
|
119
|
-
for (let i = 0; i < m_id2.length; i++) {
|
|
120
|
-
rmentions[m_id2[i]] = (repliedTo.body || "").substring(m_offset2[i], m_offset2[i] + m_length2[i]);
|
|
121
|
-
}
|
|
107
|
+
const rmentions = getMentionsFromDeltaMessage(repliedTo);
|
|
122
108
|
const msgMetadata = repliedTo.messageMetadata;
|
|
123
109
|
if (msgMetadata && msgMetadata.threadKey) {
|
|
124
110
|
callbackToReturn.messageReply = {
|
|
@@ -199,10 +199,6 @@ module.exports = function (defaultFuncs, api, ctx, opts) {
|
|
|
199
199
|
} catch (_) { }
|
|
200
200
|
ctx._scheduler = undefined;
|
|
201
201
|
}
|
|
202
|
-
// Clear global mqttClient reference if set
|
|
203
|
-
if (global.mqttClient) {
|
|
204
|
-
delete global.mqttClient;
|
|
205
|
-
}
|
|
206
202
|
next && next();
|
|
207
203
|
};
|
|
208
204
|
try {
|
package/src/utils/format.js
CHANGED
|
@@ -540,25 +540,56 @@ function formatAttachment(attachments, attachmentIds, attachmentMap, shareMap) {
|
|
|
540
540
|
: [];
|
|
541
541
|
}
|
|
542
542
|
|
|
543
|
+
/**
|
|
544
|
+
* Extract mentions from message - supports legacy (data.prng) and new format (messageMetadata.data.data.Gb.asMap.data).
|
|
545
|
+
* @param {Object} m - Raw message object (NewMessage delta)
|
|
546
|
+
* @returns {Object} mentions - Map of userID -> mention text
|
|
547
|
+
*/
|
|
548
|
+
function getMentionsFromDeltaMessage(m) {
|
|
549
|
+
var body = m.body || "";
|
|
550
|
+
var mentions = {};
|
|
551
|
+
var mdata = [];
|
|
552
|
+
if (m.data && m.data.prng) {
|
|
553
|
+
try {
|
|
554
|
+
mdata = JSON.parse(m.data.prng);
|
|
555
|
+
} catch (e) {
|
|
556
|
+
mdata = [];
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
if (mdata.length > 0) {
|
|
560
|
+
for (var i = 0; i < mdata.length; i++) {
|
|
561
|
+
var id = mdata[i].i;
|
|
562
|
+
var o = parseInt(mdata[i].o, 10) || 0;
|
|
563
|
+
var l = parseInt(mdata[i].l, 10) || 0;
|
|
564
|
+
mentions[String(id)] = body.substring(o, o + l);
|
|
565
|
+
}
|
|
566
|
+
return mentions;
|
|
567
|
+
}
|
|
568
|
+
var md = m.messageMetadata;
|
|
569
|
+
if (md && md.data && md.data.data && md.data.data.Gb && md.data.data.Gb.asMap && md.data.data.Gb.asMap.data) {
|
|
570
|
+
var gbData = md.data.data.Gb.asMap.data;
|
|
571
|
+
for (var key in gbData) {
|
|
572
|
+
if (!Object.prototype.hasOwnProperty.call(gbData, key)) continue;
|
|
573
|
+
var entry = gbData[key];
|
|
574
|
+
if (entry && entry.asMap && entry.asMap.data) {
|
|
575
|
+
var d = entry.asMap.data;
|
|
576
|
+
var id = d.id && d.id.asLong ? String(d.id.asLong) : null;
|
|
577
|
+
var offset = parseInt((d.offset && d.offset.asLong) ? d.offset.asLong : 0, 10);
|
|
578
|
+
var len = parseInt((d.length && d.length.asLong) ? d.length.asLong : 0, 10);
|
|
579
|
+
if (id != null) {
|
|
580
|
+
mentions[id] = body.substring(offset, offset + len);
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
}
|
|
585
|
+
return mentions;
|
|
586
|
+
}
|
|
587
|
+
|
|
543
588
|
function formatDeltaMessage(m) {
|
|
544
589
|
var md = m.messageMetadata;
|
|
545
|
-
var mdata =
|
|
546
|
-
m.data === undefined
|
|
547
|
-
? []
|
|
548
|
-
: m.data.prng === undefined
|
|
549
|
-
? []
|
|
550
|
-
: JSON.parse(m.data.prng);
|
|
551
|
-
var m_id = mdata.map((/** @type {{ i: any; }} */ u) => u.i);
|
|
552
|
-
var m_offset = mdata.map((/** @type {{ o: any; }} */ u) => u.o);
|
|
553
|
-
var m_length = mdata.map((/** @type {{ l: any; }} */ u) => u.l);
|
|
554
|
-
var mentions = {};
|
|
555
590
|
var body = m.body || "";
|
|
556
|
-
var
|
|
557
|
-
|
|
558
|
-
mentions[m_id[i]] = m.body.substring(
|
|
559
|
-
m_offset[i],
|
|
560
|
-
m_offset[i] + m_length[i]
|
|
561
|
-
);
|
|
591
|
+
var mentions = getMentionsFromDeltaMessage(m);
|
|
592
|
+
var args = body === "" ? [] : body.trim().split(/\s+/);
|
|
562
593
|
return {
|
|
563
594
|
type: "message",
|
|
564
595
|
senderID: formatID(md.actorFbId.toString()),
|
|
@@ -1091,6 +1122,7 @@ module.exports = {
|
|
|
1091
1122
|
_formatAttachment,
|
|
1092
1123
|
formatDeltaEvent,
|
|
1093
1124
|
formatDeltaMessage,
|
|
1125
|
+
getMentionsFromDeltaMessage,
|
|
1094
1126
|
formatDeltaReadReceipt,
|
|
1095
1127
|
getType,
|
|
1096
1128
|
formatID,
|