shadowx-fca 2.3.0 → 2.5.0
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/checkUpdate.js +1 -1
- package/index.js +345 -122
- package/package.json +1 -1
- package/src/GetBotInfo.js +57 -0
- package/src/OldMessage.js +38 -10
- package/src/comment.js +213 -0
- package/src/createThemeAI.js +129 -0
- package/src/emoji.js +124 -0
- package/src/friend.js +243 -0
- package/src/gcmember.js +122 -0
- package/src/getUserInfo.js +222 -43
- package/src/listenMqtt.js +9 -116
- package/src/nickname.js +132 -0
- package/src/postFormData.js +46 -0
- package/src/sendMessage.js +224 -235
- package/src/sendTypingIndicator.js +45 -101
- package/src/share.js +62 -0
- package/src/shareContact.js +17 -61
- package/src/stickers.js +117 -0
- package/src/story.js +181 -0
- package/src/theme.js +233 -0
- package/utils.js +24 -1311
package/src/sendMessage.js
CHANGED
|
@@ -1,243 +1,232 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
+
|
|
3
4
|
const utils = require('../utils');
|
|
4
|
-
// @NethWs3Dev
|
|
5
5
|
|
|
6
6
|
const allowedProperties = {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
7
|
+
attachment : true,
|
|
8
|
+
url : true,
|
|
9
|
+
sticker : true,
|
|
10
|
+
emoji : true,
|
|
11
|
+
emojiSize : true,
|
|
12
|
+
body : true,
|
|
13
|
+
mentions : true,
|
|
14
|
+
location : true,
|
|
15
15
|
};
|
|
16
16
|
|
|
17
|
+
|
|
18
|
+
|
|
17
19
|
module.exports = (defaultFuncs, api, ctx) => {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
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
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
form["profile_xmd[" + i + "][offset]"] = offset + 1;
|
|
232
|
-
form["profile_xmd[" + i + "][length]"] = tag.length;
|
|
233
|
-
form["profile_xmd[" + i + "][id]"] = id;
|
|
234
|
-
form["profile_xmd[" + i + "][type]"] = "p";
|
|
235
|
-
}
|
|
236
|
-
}
|
|
237
|
-
const result = await sendContent(form, threadID, isSingleUser, messageAndOTID);
|
|
238
|
-
if (callback && typeof callback === "function") {
|
|
239
|
-
callback(null, result);
|
|
240
|
-
}
|
|
241
|
-
return result;
|
|
242
|
-
};
|
|
243
|
-
};
|
|
20
|
+
|
|
21
|
+
async function uploadAttachment(attachments) {
|
|
22
|
+
const uploads = [];
|
|
23
|
+
for (const att of attachments) {
|
|
24
|
+
if (!utils.isReadableStream(att)) {
|
|
25
|
+
throw new Error("Attachment must be a readable stream, got: " + utils.getType(att));
|
|
26
|
+
}
|
|
27
|
+
const res = await defaultFuncs.postFormData(
|
|
28
|
+
"https://upload.facebook.com/ajax/mercury/upload.php",
|
|
29
|
+
ctx.jar,
|
|
30
|
+
{ upload_1024: att, voice_clip: "true" },
|
|
31
|
+
{}
|
|
32
|
+
).then(utils.parseAndCheckLogin(ctx, defaultFuncs));
|
|
33
|
+
if (res.error) throw new Error("Upload failed: " + JSON.stringify(res));
|
|
34
|
+
uploads.push(res.payload.metadata[0]);
|
|
35
|
+
}
|
|
36
|
+
return uploads;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async function getUrl(url) {
|
|
40
|
+
const res = await defaultFuncs.post(
|
|
41
|
+
"https://www.facebook.com/message_share_attachment/fromURI/",
|
|
42
|
+
ctx.jar,
|
|
43
|
+
{ image_height: 960, image_width: 960, uri: url }
|
|
44
|
+
).then(utils.parseAndCheckLogin(ctx, defaultFuncs));
|
|
45
|
+
if (!res || res.error || !res.payload) throw new Error("URL attachment failed: " + JSON.stringify(res));
|
|
46
|
+
return res.payload;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
async function sendContent(form, threadID, messageAndOTID) {
|
|
50
|
+
const tid = String(threadID);
|
|
51
|
+
|
|
52
|
+
if (Array.isArray(threadID)) {
|
|
53
|
+
threadID.forEach((id, idx) => { form[`specific_to_list[${idx}]`] = "fbid:" + id; });
|
|
54
|
+
form[`specific_to_list[${threadID.length}]`] = "fbid:" + ctx.userID;
|
|
55
|
+
form["client_thread_id"] = "root:" + messageAndOTID;
|
|
56
|
+
utils.log("sendMessage", "Creating new group with users: " + threadID.join(', '));
|
|
57
|
+
} else {
|
|
58
|
+
// Group thread — works for any digit length (15, 16, 17, 18, 19...)
|
|
59
|
+
form["thread_fbid"] = tid;
|
|
60
|
+
utils.log("sendMessage", "Sending to group thread: " + tid);
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (ctx.globalOptions.pageID) {
|
|
64
|
+
form["author"] = "fbid:" + ctx.globalOptions.pageID;
|
|
65
|
+
form["specific_to_list[1]"] = "fbid:" + ctx.globalOptions.pageID;
|
|
66
|
+
form["creator_info[creatorID]"] = ctx.userID;
|
|
67
|
+
form["creator_info[creatorType]"] = "direct_admin";
|
|
68
|
+
form["creator_info[labelType]"] = "sent_message";
|
|
69
|
+
form["creator_info[pageID]"] = ctx.globalOptions.pageID;
|
|
70
|
+
form["request_user_id"] = ctx.globalOptions.pageID;
|
|
71
|
+
form["creator_info[profileURI]"] = "https://www.facebook.com/profile.php?id=" + ctx.userID;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
const resData = await defaultFuncs
|
|
75
|
+
.post("https://www.facebook.com/messaging/send/", ctx.jar, form)
|
|
76
|
+
.then(utils.parseAndCheckLogin(ctx, defaultFuncs));
|
|
77
|
+
|
|
78
|
+
if (!resData) throw new Error("Send message failed — no response.");
|
|
79
|
+
if (resData.error) {
|
|
80
|
+
if (resData.error === 1545012) {
|
|
81
|
+
utils.warn("sendMessage", "Error 1545012: You may not be a member of thread " + tid);
|
|
82
|
+
}
|
|
83
|
+
throw new Error("Send message error: " + JSON.stringify(resData));
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return resData.payload.actions.reduce((p, v) => ({
|
|
87
|
+
threadID : v.thread_fbid,
|
|
88
|
+
messageID : v.message_id,
|
|
89
|
+
timestamp : v.timestamp,
|
|
90
|
+
}), null);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Send a message to a Facebook group thread.
|
|
95
|
+
*
|
|
96
|
+
* Supports both callback and Promise/await style:
|
|
97
|
+
*
|
|
98
|
+
* api.sendMessage("Hello!", threadID, callback) // callback style
|
|
99
|
+
* await api.sendMessage("Hello!", threadID) // promise style
|
|
100
|
+
* api.sendMessage("Reply!", threadID, msgID, callback) // reply + callback
|
|
101
|
+
* await api.sendMessage("Reply!", threadID, msgID) // reply + promise
|
|
102
|
+
*
|
|
103
|
+
* @param {string|object} msg — text string or {body, sticker, attachment, url, emoji, mentions, location}
|
|
104
|
+
* @param {string|Array} threadID — group thread ID (any length) or array of userIDs to create new group
|
|
105
|
+
* @param {string|Function} [replyOrCallback]— optional: message ID to reply to, OR callback function(err, info)
|
|
106
|
+
* @param {Function} [callback] — optional: callback(err, info) when replyToMessage is provided
|
|
107
|
+
*/
|
|
108
|
+
return (msg, threadID, replyOrCallback, callbackArg) => {
|
|
109
|
+
|
|
110
|
+
// ── Resolve replyToMessage vs callback ───────────────────────
|
|
111
|
+
let replyToMessage = null;
|
|
112
|
+
let callback = null;
|
|
113
|
+
|
|
114
|
+
if (typeof replyOrCallback === 'function') {
|
|
115
|
+
// sendMessage(msg, threadID, callback)
|
|
116
|
+
callback = replyOrCallback;
|
|
117
|
+
} else if (typeof replyOrCallback === 'string') {
|
|
118
|
+
// sendMessage(msg, threadID, replyMsgID) or sendMessage(msg, threadID, replyMsgID, callback)
|
|
119
|
+
replyToMessage = replyOrCallback;
|
|
120
|
+
if (typeof callbackArg === 'function') callback = callbackArg;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
// ── Core send logic (async) ──────────────────────────────────
|
|
124
|
+
const doSend = async () => {
|
|
125
|
+
const msgType = utils.getType(msg);
|
|
126
|
+
if (msgType !== "String" && msgType !== "Object") {
|
|
127
|
+
throw new Error("Message must be a string or object, got: " + msgType);
|
|
128
|
+
}
|
|
129
|
+
if (msgType === "String") msg = { body: msg };
|
|
130
|
+
|
|
131
|
+
const disallowed = Object.keys(msg).filter(p => !allowedProperties[p]);
|
|
132
|
+
if (disallowed.length > 0) {
|
|
133
|
+
throw new Error("Disallowed message properties: " + disallowed.join(", "));
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const messageAndOTID = utils.generateOfflineThreadingID();
|
|
137
|
+
const form = {
|
|
138
|
+
client : "mercury",
|
|
139
|
+
action_type : "ma-type:user-generated-message",
|
|
140
|
+
author : "fbid:" + ctx.userID,
|
|
141
|
+
timestamp : Date.now(),
|
|
142
|
+
timestamp_absolute : "Today",
|
|
143
|
+
timestamp_relative : utils.generateTimestampRelative(),
|
|
144
|
+
timestamp_time_passed : "0",
|
|
145
|
+
is_unread : false,
|
|
146
|
+
is_cleared : false,
|
|
147
|
+
is_forward : false,
|
|
148
|
+
is_filtered_content : false,
|
|
149
|
+
is_filtered_content_bh : false,
|
|
150
|
+
is_filtered_content_account : false,
|
|
151
|
+
is_filtered_content_quasar : false,
|
|
152
|
+
is_filtered_content_invalid_app : false,
|
|
153
|
+
is_spoof_warning : false,
|
|
154
|
+
source : "source:chat:web",
|
|
155
|
+
"source_tags[0]" : "source:chat",
|
|
156
|
+
...(msg.body && { body: msg.body }),
|
|
157
|
+
html_body : false,
|
|
158
|
+
ui_push_phase : "V3",
|
|
159
|
+
status : "0",
|
|
160
|
+
offline_threading_id : messageAndOTID,
|
|
161
|
+
message_id : messageAndOTID,
|
|
162
|
+
threading_id : utils.generateThreadingID(ctx.clientID),
|
|
163
|
+
"ephemeral_ttl_mode:" : "0",
|
|
164
|
+
manual_retry_cnt : "0",
|
|
165
|
+
has_attachment : !!(msg.attachment || msg.url || msg.sticker),
|
|
166
|
+
signatureID : utils.getSignatureID(),
|
|
167
|
+
...(replyToMessage && { replied_to_message_id: replyToMessage }),
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
if (msg.location) {
|
|
171
|
+
if (!msg.location.latitude || !msg.location.longitude) {
|
|
172
|
+
throw new Error("location needs both latitude and longitude.");
|
|
173
|
+
}
|
|
174
|
+
form["location_attachment[coordinates][latitude]"] = msg.location.latitude;
|
|
175
|
+
form["location_attachment[coordinates][longitude]"] = msg.location.longitude;
|
|
176
|
+
form["location_attachment[is_current_location]"] = !!msg.location.current;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
if (msg.sticker) form["sticker_id"] = msg.sticker;
|
|
180
|
+
|
|
181
|
+
if (msg.attachment) {
|
|
182
|
+
form.image_ids = []; form.gif_ids = []; form.file_ids = [];
|
|
183
|
+
form.video_ids = []; form.audio_ids = [];
|
|
184
|
+
if (utils.getType(msg.attachment) !== "Array") msg.attachment = [msg.attachment];
|
|
185
|
+
const files = await uploadAttachment(msg.attachment);
|
|
186
|
+
files.forEach(file => {
|
|
187
|
+
const type = Object.keys(file)[0];
|
|
188
|
+
form[type + "s"].push(file[type]);
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
if (msg.url) {
|
|
193
|
+
form["shareable_attachment[share_type]"] = "100";
|
|
194
|
+
form["shareable_attachment[share_params]"] = await getUrl(msg.url);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
if (msg.emoji) {
|
|
198
|
+
if (!msg.emojiSize) msg.emojiSize = "medium";
|
|
199
|
+
if (!["small","medium","large"].includes(msg.emojiSize)) {
|
|
200
|
+
throw new Error("emojiSize must be small, medium, or large.");
|
|
201
|
+
}
|
|
202
|
+
if (!form.body) throw new Error("body must not be empty when using emoji.");
|
|
203
|
+
form.body = msg.emoji;
|
|
204
|
+
form["tags[0]"] = "hot_emoji_size:" + msg.emojiSize;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
if (msg.mentions) {
|
|
208
|
+
for (let i = 0; i < msg.mentions.length; i++) {
|
|
209
|
+
const { tag, id, fromIndex } = msg.mentions[i];
|
|
210
|
+
if (typeof tag !== "string") throw new Error("Mention tags must be strings.");
|
|
211
|
+
const offset = msg.body.indexOf(tag, fromIndex || 0);
|
|
212
|
+
if (offset < 0) utils.warn("sendMessage", `Mention "${tag}" not found in body.`);
|
|
213
|
+
const emptyChar = '\u200E';
|
|
214
|
+
form["body"] = emptyChar + msg.body;
|
|
215
|
+
form[`profile_xmd[${i}][offset]`] = offset + 1;
|
|
216
|
+
form[`profile_xmd[${i}][length]`] = tag.length;
|
|
217
|
+
form[`profile_xmd[${i}][id]`] = id || 0;
|
|
218
|
+
form[`profile_xmd[${i}][type]`] = "p";
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
return sendContent(form, threadID, messageAndOTID);
|
|
223
|
+
};
|
|
224
|
+
|
|
225
|
+
// ── Return Promise OR call callback ──────────────────────────
|
|
226
|
+
if (callback) {
|
|
227
|
+
doSend().then(info => callback(null, info)).catch(err => callback(err));
|
|
228
|
+
} else {
|
|
229
|
+
return doSend();
|
|
230
|
+
}
|
|
231
|
+
};
|
|
232
|
+
};
|
|
@@ -1,101 +1,45 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
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
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
defaultFuncs
|
|
47
|
-
.post(
|
|
48
|
-
"https://www.facebook.com/ajax/messaging/typ.php",
|
|
49
|
-
ctx.jar,
|
|
50
|
-
form,
|
|
51
|
-
)
|
|
52
|
-
.then(utils.parseAndCheckLogin(ctx, defaultFuncs))
|
|
53
|
-
.then(function (resData) {
|
|
54
|
-
if (resData.error) {
|
|
55
|
-
throw resData;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
return callback();
|
|
59
|
-
})
|
|
60
|
-
.catch(function (err) {
|
|
61
|
-
console.error("sendTypingIndicator", err);
|
|
62
|
-
return callback(err);
|
|
63
|
-
});
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
return function sendTypingIndicator(threadID, callback, isGroup) {
|
|
69
|
-
if (
|
|
70
|
-
utils.getType(callback) !== "Function" &&
|
|
71
|
-
utils.getType(callback) !== "AsyncFunction"
|
|
72
|
-
) {
|
|
73
|
-
if (callback) {
|
|
74
|
-
console.warn(
|
|
75
|
-
"sendTypingIndicator",
|
|
76
|
-
"callback is not a function - ignoring.",
|
|
77
|
-
);
|
|
78
|
-
}
|
|
79
|
-
callback = () => {};
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
makeTypingIndicator(true, threadID, callback, isGroup);
|
|
83
|
-
|
|
84
|
-
return function end(cb) {
|
|
85
|
-
if (
|
|
86
|
-
utils.getType(cb) !== "Function" &&
|
|
87
|
-
utils.getType(cb) !== "AsyncFunction"
|
|
88
|
-
) {
|
|
89
|
-
if (cb) {
|
|
90
|
-
console.warn(
|
|
91
|
-
"sendTypingIndicator",
|
|
92
|
-
"callback is not a function - ignoring.",
|
|
93
|
-
);
|
|
94
|
-
}
|
|
95
|
-
cb = () => {};
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
makeTypingIndicator(false, threadID, cb, isGroup);
|
|
99
|
-
};
|
|
100
|
-
};
|
|
101
|
-
};
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
var utils = require("../utils");
|
|
6
|
+
// @NethWs3Dev
|
|
7
|
+
|
|
8
|
+
module.exports = function (defaultFuncs, api, ctx) {
|
|
9
|
+
return async function sendTypingIndicatorV2(sendTyping, threadID, callback) {
|
|
10
|
+
const mqttClient = ctx.mqttClient || global.mqttClient;
|
|
11
|
+
if (!mqttClient) {
|
|
12
|
+
if (typeof callback === 'function') callback(new Error('No MQTT client available for typing indicator'));
|
|
13
|
+
return;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
let count_req = 0;
|
|
17
|
+
var wsContent = {
|
|
18
|
+
app_id: 2220391788200892,
|
|
19
|
+
payload: JSON.stringify({
|
|
20
|
+
label: 3,
|
|
21
|
+
payload: JSON.stringify({
|
|
22
|
+
thread_key: threadID.toString(),
|
|
23
|
+
is_group_thread: +(threadID.toString().length >= 16),
|
|
24
|
+
is_typing: +sendTyping,
|
|
25
|
+
attribution: 0
|
|
26
|
+
}),
|
|
27
|
+
version: 5849951561777440
|
|
28
|
+
}),
|
|
29
|
+
request_id: ++count_req,
|
|
30
|
+
type: 4
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
return new Promise((resolve, reject) => {
|
|
34
|
+
mqttClient.publish('/ls_req', JSON.stringify(wsContent), {}, (err, _packet) => {
|
|
35
|
+
if (err) {
|
|
36
|
+
if (typeof callback === 'function') callback(err);
|
|
37
|
+
reject(err);
|
|
38
|
+
} else {
|
|
39
|
+
if (typeof callback === 'function') callback(null, _packet);
|
|
40
|
+
resolve(_packet);
|
|
41
|
+
}
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
};
|
|
45
|
+
};
|