@dongdev/fca-unofficial 2.0.7 → 2.0.10
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/DOCS.md +1699 -1434
- package/README.md +250 -168
- package/package.json +54 -28
- package/src/api/action/addExternalModule.js +5 -5
- package/src/api/action/changeAvatar.js +11 -10
- package/src/api/action/changeBio.js +7 -8
- package/src/api/action/getCurrentUserID.js +1 -1
- package/src/api/action/handleFriendRequest.js +5 -5
- package/src/api/action/logout.js +9 -8
- package/src/api/action/refreshFb_dtsg.js +17 -12
- package/src/api/action/setPostReaction.js +10 -11
- package/src/api/action/unfriend.js +3 -4
- package/src/api/http/httpGet.js +7 -8
- package/src/api/http/httpPost.js +7 -8
- package/src/api/http/postFormData.js +6 -5
- package/src/api/messaging/addUserToGroup.js +0 -1
- package/src/api/messaging/changeAdminStatus.js +108 -89
- package/src/api/messaging/changeArchivedStatus.js +6 -6
- package/src/api/messaging/changeBlockedStatus.js +3 -4
- package/src/api/messaging/changeGroupImage.js +72 -117
- package/src/api/messaging/changeNickname.js +59 -48
- package/src/api/messaging/changeThreadColor.js +61 -47
- package/src/api/messaging/changeThreadEmoji.js +106 -0
- package/src/api/messaging/createNewGroup.js +5 -5
- package/src/api/messaging/createPoll.js +36 -63
- package/src/api/messaging/deleteMessage.js +4 -4
- package/src/api/messaging/deleteThread.js +4 -4
- package/src/api/messaging/forwardAttachment.js +38 -47
- package/src/api/messaging/getFriendsList.js +5 -6
- package/src/api/messaging/getMessage.js +4 -9
- package/src/api/messaging/handleMessageRequest.js +5 -5
- package/src/api/messaging/markAsDelivered.js +5 -5
- package/src/api/messaging/markAsRead.js +7 -7
- package/src/api/messaging/markAsReadAll.js +3 -4
- package/src/api/messaging/markAsSeen.js +7 -7
- package/src/api/messaging/muteThread.js +3 -4
- package/src/api/messaging/removeUserFromGroup.js +82 -56
- package/src/api/messaging/resolvePhotoUrl.js +2 -3
- package/src/api/messaging/searchForThread.js +2 -3
- package/src/api/messaging/sendMessage.js +171 -101
- package/src/api/messaging/sendMessageMqtt.js +14 -12
- package/src/api/messaging/sendTypingIndicator.js +11 -11
- package/src/api/messaging/setMessageReaction.js +68 -82
- package/src/api/messaging/setTitle.js +77 -48
- package/src/api/messaging/shareContact.js +2 -4
- package/src/api/messaging/threadColors.js +0 -3
- package/src/api/messaging/unsendMessage.js +74 -37
- package/src/api/messaging/uploadAttachment.js +11 -9
- package/src/api/socket/core/connectMqtt.js +180 -0
- package/src/api/socket/core/getSeqID.js +25 -0
- package/src/api/socket/core/getTaskResponseData.js +22 -0
- package/src/api/socket/core/markDelivery.js +12 -0
- package/src/api/socket/core/parseDelta.js +351 -0
- package/src/api/socket/detail/buildStream.js +176 -68
- package/src/api/socket/detail/constants.js +24 -0
- package/src/api/socket/listenMqtt.js +80 -1005
- package/src/api/{messaging → threads}/getThreadHistory.js +5 -22
- package/src/api/threads/getThreadInfo.js +35 -248
- package/src/api/threads/getThreadList.js +20 -20
- package/src/api/threads/getThreadPictures.js +3 -4
- package/src/api/users/getUserID.js +5 -6
- package/src/api/users/getUserInfo.js +305 -73
- package/src/api/users/getUserInfoV2.js +134 -0
- package/src/database/models/user.js +32 -0
- package/src/database/userData.js +89 -0
- package/src/utils/constants.js +12 -2
- package/src/utils/format.js +1051 -0
- package/src/utils/request.js +75 -7
- package/CHANGELOG.md +0 -52
- package/LICENSE-MIT +0 -21
- package/func/checkUpdate.js +0 -58
- package/func/logger.js +0 -112
- package/func/login.js +0 -0
- package/index.d.ts +0 -618
- package/module/config.js +0 -34
- package/module/login.js +0 -47
- package/module/loginHelper.js +0 -635
- package/module/options.js +0 -49
- package/src/api/threads/changeThreadEmoji.js +0 -55
- package/src/utils/index.js +0 -1497
@@ -1,9 +1,6 @@
|
|
1
|
-
"use strict";
|
2
|
-
|
3
1
|
const fs = require("fs");
|
4
2
|
const path = require("path");
|
5
3
|
const { Readable } = require("stream");
|
6
|
-
const utils = require("../../utils");
|
7
4
|
const log = require("npmlog");
|
8
5
|
const allowedProperties = {
|
9
6
|
attachment: true,
|
@@ -16,38 +13,27 @@ const allowedProperties = {
|
|
16
13
|
location: true,
|
17
14
|
asPage: true
|
18
15
|
};
|
16
|
+
const { isReadableStream } = require("../../utils/constants");
|
17
|
+
const { parseAndCheckLogin } = require("../../utils/client");
|
18
|
+
const { getType, generateThreadingID, generateTimestampRelative, generateOfflineThreadingID, getSignatureID } = require("../../utils/format");
|
19
|
+
|
19
20
|
module.exports = function (defaultFuncs, api, ctx) {
|
20
21
|
function toReadable(input) {
|
21
|
-
if (
|
22
|
+
if (isReadableStream(input)) return input;
|
22
23
|
if (Buffer.isBuffer(input)) return Readable.from(input);
|
23
24
|
if (typeof input === "string" && fs.existsSync(input) && fs.statSync(input).isFile()) return fs.createReadStream(path.resolve(input));
|
24
25
|
throw { error: "Unsupported attachment input. Use stream/buffer/filepath." };
|
25
26
|
}
|
26
|
-
|
27
|
-
if (!Array.isArray(list)) list = [list];
|
28
|
-
return list.map(a => {
|
29
|
-
if (Array.isArray(a) && /_id$/.test(a[0])) return a;
|
30
|
-
if (a && typeof a === "object") {
|
31
|
-
if (a.id && a.type && /_id$/.test(a.type)) return [a.type, a.id];
|
32
|
-
if (a.image_id || a.file_id || a.video_id || a.audio_id || a.gif_id) {
|
33
|
-
const k = Object.keys(a).find(x => /_id$/.test(x));
|
34
|
-
return [k, a[k]];
|
35
|
-
}
|
36
|
-
}
|
37
|
-
return toReadable(a);
|
38
|
-
});
|
39
|
-
}
|
27
|
+
|
40
28
|
function uploadAttachment(attachments, callback) {
|
41
29
|
const uploads = [];
|
42
30
|
for (let i = 0; i < attachments.length; i++) {
|
43
|
-
if (!
|
44
|
-
throw { error: "Attachment should be a readable stream and not " + utils.getType(attachments[i]) + "." };
|
45
|
-
}
|
31
|
+
if (!isReadableStream(attachments[i])) throw { error: "Attachment should be a readable stream and not " + getType(attachments[i]) + "." };
|
46
32
|
const form = { upload_1024: attachments[i], voice_clip: "true" };
|
47
33
|
uploads.push(
|
48
34
|
defaultFuncs
|
49
35
|
.postFormData("https://upload.facebook.com/ajax/mercury/upload.php", ctx.jar, form, {}, {})
|
50
|
-
.then(
|
36
|
+
.then(parseAndCheckLogin(ctx, defaultFuncs))
|
51
37
|
.then(resData => {
|
52
38
|
if (resData.error) throw resData;
|
53
39
|
return resData.payload.metadata[0];
|
@@ -61,11 +47,12 @@ module.exports = function (defaultFuncs, api, ctx) {
|
|
61
47
|
callback(err);
|
62
48
|
});
|
63
49
|
}
|
50
|
+
|
64
51
|
function getUrl(url, callback) {
|
65
52
|
const form = { image_height: 960, image_width: 960, uri: url };
|
66
53
|
defaultFuncs
|
67
54
|
.post("https://www.facebook.com/message_share_attachment/fromURI/", ctx.jar, form)
|
68
|
-
.then(
|
55
|
+
.then(parseAndCheckLogin(ctx, defaultFuncs))
|
69
56
|
.then(resData => {
|
70
57
|
if (resData.error) return callback(resData);
|
71
58
|
if (!resData.payload) return callback({ error: "Invalid url" });
|
@@ -76,12 +63,16 @@ module.exports = function (defaultFuncs, api, ctx) {
|
|
76
63
|
callback(err);
|
77
64
|
});
|
78
65
|
}
|
79
|
-
|
66
|
+
|
67
|
+
function sleep(ms) {
|
68
|
+
return new Promise(r => setTimeout(r, ms));
|
69
|
+
}
|
70
|
+
|
80
71
|
async function postWithRetry(url, jar, form, tries = 3) {
|
81
72
|
let lastErr;
|
82
73
|
for (let i = 0; i < tries; i++) {
|
83
74
|
try {
|
84
|
-
const res = await defaultFuncs.post(url, jar, form).then(
|
75
|
+
const res = await defaultFuncs.post(url, jar, form).then(parseAndCheckLogin(ctx, defaultFuncs));
|
85
76
|
if (res && !res.error) return res;
|
86
77
|
lastErr = res;
|
87
78
|
if (res && (res.error === 1545003 || res.error === 368)) await sleep(500 * (i + 1));
|
@@ -93,6 +84,7 @@ module.exports = function (defaultFuncs, api, ctx) {
|
|
93
84
|
}
|
94
85
|
throw lastErr || { error: "Send failed" };
|
95
86
|
}
|
87
|
+
|
96
88
|
function applyPageAuthor(form, msg) {
|
97
89
|
const pageID = msg && msg.asPage ? msg.asPage : ctx.globalOptions.pageID;
|
98
90
|
if (!pageID) return;
|
@@ -105,9 +97,16 @@ module.exports = function (defaultFuncs, api, ctx) {
|
|
105
97
|
form["request_user_id"] = pageID;
|
106
98
|
form["creator_info[profileURI]"] = "https://www.facebook.com/profile.php?id=" + ctx.userID;
|
107
99
|
}
|
100
|
+
|
108
101
|
function applyMentions(msg, form) {
|
109
102
|
if (!msg.mentions || !msg.mentions.length) return;
|
110
|
-
|
103
|
+
let body = typeof msg.body === "string" ? msg.body : "";
|
104
|
+
const need = [];
|
105
|
+
for (const m of msg.mentions) {
|
106
|
+
const tag = String(m.tag || "");
|
107
|
+
if (tag && !body.includes(tag)) need.push(tag);
|
108
|
+
}
|
109
|
+
if (need.length) body = (body ? body + " " : "") + need.join(" ");
|
111
110
|
const emptyChar = "\u200E";
|
112
111
|
form["body"] = emptyChar + body;
|
113
112
|
let searchFrom = 0;
|
@@ -122,16 +121,35 @@ module.exports = function (defaultFuncs, api, ctx) {
|
|
122
121
|
searchFrom = off + tag.length;
|
123
122
|
});
|
124
123
|
}
|
124
|
+
|
125
125
|
function finalizeHasAttachment(form) {
|
126
126
|
const keys = ["image_ids", "gif_ids", "file_ids", "video_ids", "audio_ids", "sticker_id", "shareable_attachment[share_params]"];
|
127
127
|
form.has_attachment = keys.some(k => k in form && (Array.isArray(form[k]) ? form[k].length > 0 : !!form[k]));
|
128
128
|
}
|
129
|
+
|
130
|
+
function extractMessageInfo(resData, fallbackThreadID) {
|
131
|
+
let messageID = null;
|
132
|
+
let threadFBID = null;
|
133
|
+
let timestamp = null;
|
134
|
+
const actions = resData && resData.payload && Array.isArray(resData.payload.actions) ? resData.payload.actions : null;
|
135
|
+
if (actions && actions.length) {
|
136
|
+
const v = actions.find(x => x && x.message_id) || actions[0];
|
137
|
+
messageID = v && v.message_id ? v.message_id : null;
|
138
|
+
threadFBID = (v && (v.thread_fbid || v.thread_id)) || fallbackThreadID || null;
|
139
|
+
timestamp = v && v.timestamp ? v.timestamp : null;
|
140
|
+
}
|
141
|
+
if (!messageID) messageID = (resData && resData.payload && resData.payload.message_id) || resData.message_id || null;
|
142
|
+
if (!threadFBID) threadFBID = (resData && resData.payload && resData.payload.thread_id) || fallbackThreadID || null;
|
143
|
+
if (!timestamp) timestamp = (resData && resData.timestamp) || Date.now();
|
144
|
+
if (!messageID) return null;
|
145
|
+
return { threadID: threadFBID, messageID, timestamp };
|
146
|
+
}
|
147
|
+
|
129
148
|
function sendContent(form, threadID, isSingleUser, messageAndOTID, callback) {
|
130
|
-
if (
|
149
|
+
if (getType(threadID) === "Array") {
|
131
150
|
for (let i = 0; i < threadID.length; i++) form["specific_to_list[" + i + "]"] = "fbid:" + threadID[i];
|
132
151
|
form["specific_to_list[" + threadID.length + "]"] = "fbid:" + ctx.userID;
|
133
152
|
form["client_thread_id"] = "root:" + messageAndOTID;
|
134
|
-
log.verbose("sendMessage", "Sending message to multiple users: " + threadID);
|
135
153
|
} else {
|
136
154
|
if (isSingleUser) {
|
137
155
|
form["specific_to_list[0]"] = "fbid:" + threadID;
|
@@ -149,25 +167,23 @@ module.exports = function (defaultFuncs, api, ctx) {
|
|
149
167
|
else log.error("sendMessage", resData);
|
150
168
|
return callback(resData);
|
151
169
|
}
|
152
|
-
|
153
|
-
if (
|
154
|
-
|
155
|
-
if (v && v.message_id) messageInfo = { threadID: v.thread_fbid, messageID: v.message_id, timestamp: v.timestamp };
|
156
|
-
}
|
157
|
-
}
|
158
|
-
callback(null, messageInfo);
|
170
|
+
const info = extractMessageInfo(resData, getType(threadID) === "Array" ? null : String(threadID));
|
171
|
+
if (!info) return callback({ error: "Cannot parse message info." });
|
172
|
+
callback(null, info);
|
159
173
|
})
|
160
174
|
.catch(err => {
|
161
175
|
log.error("sendMessage", err);
|
162
|
-
if (
|
176
|
+
if (getType(err) === "Object" && err.error === "Not logged in.") ctx.loggedIn = false;
|
163
177
|
callback(err);
|
164
178
|
});
|
165
179
|
}
|
180
|
+
|
166
181
|
function send(form, threadID, messageAndOTID, callback, isGroup) {
|
167
|
-
if (
|
168
|
-
if (
|
182
|
+
if (getType(threadID) === "Array") return sendContent(form, threadID, false, messageAndOTID, callback);
|
183
|
+
if (getType(isGroup) !== "Boolean") return sendContent(form, threadID, String(threadID).length === 15, messageAndOTID, callback);
|
169
184
|
return sendContent(form, threadID, !isGroup, messageAndOTID, callback);
|
170
185
|
}
|
186
|
+
|
171
187
|
function handleUrl(msg, form, callback, cb) {
|
172
188
|
if (msg.url) {
|
173
189
|
form["shareable_attachment[share_type]"] = "100";
|
@@ -178,6 +194,7 @@ module.exports = function (defaultFuncs, api, ctx) {
|
|
178
194
|
});
|
179
195
|
} else cb();
|
180
196
|
}
|
197
|
+
|
181
198
|
function handleLocation(msg, form, callback, cb) {
|
182
199
|
if (msg.location) {
|
183
200
|
if (msg.location.latitude == null || msg.location.longitude == null) return callback({ error: "location property needs both latitude and longitude" });
|
@@ -187,10 +204,12 @@ module.exports = function (defaultFuncs, api, ctx) {
|
|
187
204
|
}
|
188
205
|
cb();
|
189
206
|
}
|
207
|
+
|
190
208
|
function handleSticker(msg, form, callback, cb) {
|
191
209
|
if (msg.sticker) form["sticker_id"] = msg.sticker;
|
192
210
|
cb();
|
193
211
|
}
|
212
|
+
|
194
213
|
function handleEmoji(msg, form, callback, cb) {
|
195
214
|
if (msg.emojiSize != null && msg.emoji == null) return callback({ error: "emoji property is empty" });
|
196
215
|
if (msg.emoji) {
|
@@ -202,6 +221,32 @@ module.exports = function (defaultFuncs, api, ctx) {
|
|
202
221
|
}
|
203
222
|
cb();
|
204
223
|
}
|
224
|
+
|
225
|
+
function splitAttachments(list) {
|
226
|
+
if (!Array.isArray(list)) list = [list];
|
227
|
+
const ids = [];
|
228
|
+
const streams = [];
|
229
|
+
for (const a of list) {
|
230
|
+
if (Array.isArray(a) && /_id$/.test(a[0])) {
|
231
|
+
ids.push([a[0], String(a[1])]);
|
232
|
+
continue;
|
233
|
+
}
|
234
|
+
if (a && typeof a === "object") {
|
235
|
+
if (a.id && a.type && /_id$/.test(a.type)) {
|
236
|
+
ids.push([a.type, String(a.id)]);
|
237
|
+
continue;
|
238
|
+
}
|
239
|
+
const k = Object.keys(a || {}).find(x => /_id$/.test(x));
|
240
|
+
if (k) {
|
241
|
+
ids.push([k, String(a[k])]);
|
242
|
+
continue;
|
243
|
+
}
|
244
|
+
}
|
245
|
+
streams.push(toReadable(a));
|
246
|
+
}
|
247
|
+
return { ids, streams };
|
248
|
+
}
|
249
|
+
|
205
250
|
function handleAttachment(msg, form, callback, cb) {
|
206
251
|
if (!msg.attachment) return cb();
|
207
252
|
form["image_ids"] = [];
|
@@ -209,12 +254,10 @@ module.exports = function (defaultFuncs, api, ctx) {
|
|
209
254
|
form["file_ids"] = [];
|
210
255
|
form["video_ids"] = [];
|
211
256
|
form["audio_ids"] = [];
|
212
|
-
const
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
}
|
217
|
-
uploadAttachment(items, function (err, files) {
|
257
|
+
const { ids, streams } = splitAttachments(msg.attachment);
|
258
|
+
for (const [type, id] of ids) form[`${type}s`].push(id);
|
259
|
+
if (!streams.length) return cb();
|
260
|
+
uploadAttachment(streams, function (err, files) {
|
218
261
|
if (err) return callback(err);
|
219
262
|
files.forEach(function (file) {
|
220
263
|
const type = Object.keys(file)[0];
|
@@ -223,16 +266,32 @@ module.exports = function (defaultFuncs, api, ctx) {
|
|
223
266
|
cb();
|
224
267
|
});
|
225
268
|
}
|
269
|
+
|
226
270
|
function handleMention(msg, form, callback, cb) {
|
227
|
-
try {
|
271
|
+
try {
|
272
|
+
applyMentions(msg, form);
|
273
|
+
cb();
|
274
|
+
} catch (e) {
|
275
|
+
callback(e);
|
276
|
+
}
|
228
277
|
}
|
278
|
+
|
229
279
|
return function sendMessage(msg, threadID, callback, replyToMessage, isGroup) {
|
280
|
+
const isFn = v => typeof v === "function";
|
281
|
+
const isStr = v => typeof v === "string";
|
282
|
+
|
230
283
|
if (typeof isGroup === "undefined") isGroup = null;
|
231
|
-
if (!callback && (
|
232
|
-
|
284
|
+
if (!callback && (getType(threadID) === "Function" || getType(threadID) === "AsyncFunction")) return threadID({ error: "Pass a threadID as a second argument." });
|
285
|
+
|
286
|
+
if (isStr(callback) && isFn(replyToMessage)) {
|
287
|
+
const t = callback;
|
288
|
+
callback = replyToMessage;
|
289
|
+
replyToMessage = t;
|
290
|
+
} else if (!replyToMessage && isStr(callback)) {
|
233
291
|
replyToMessage = callback;
|
234
|
-
callback =
|
292
|
+
callback = null;
|
235
293
|
}
|
294
|
+
|
236
295
|
let resolveFunc = function () { };
|
237
296
|
let rejectFunc = function () { };
|
238
297
|
const returnPromise = new Promise(function (resolve, reject) {
|
@@ -245,62 +304,73 @@ module.exports = function (defaultFuncs, api, ctx) {
|
|
245
304
|
resolveFunc(data);
|
246
305
|
};
|
247
306
|
}
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
|
264
|
-
|
265
|
-
|
266
|
-
|
267
|
-
|
268
|
-
|
269
|
-
|
270
|
-
|
271
|
-
|
272
|
-
|
273
|
-
|
274
|
-
|
275
|
-
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
283
|
-
|
284
|
-
|
285
|
-
|
286
|
-
|
287
|
-
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
293
|
-
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
307
|
+
|
308
|
+
try {
|
309
|
+
const msgType = getType(msg);
|
310
|
+
const threadIDType = getType(threadID);
|
311
|
+
const messageIDType = getType(replyToMessage);
|
312
|
+
if (msgType !== "String" && msgType !== "Object") return callback({ error: "Message should be of type string or object and not " + msgType + "." });
|
313
|
+
if (threadIDType !== "Array" && threadIDType !== "Number" && threadIDType !== "String") return callback({ error: "ThreadID should be of type number, string, or array and not " + threadIDType + "." });
|
314
|
+
if (replyToMessage && messageIDType !== "String") return callback({ error: "MessageID should be of type string and not " + threadIDType + "." });
|
315
|
+
if (msgType === "String") msg = { body: msg };
|
316
|
+
|
317
|
+
const disallowedProperties = Object.keys(msg).filter(prop => !allowedProperties[prop]);
|
318
|
+
if (disallowedProperties.length > 0) return callback({ error: "Disallowed props: `" + disallowedProperties.join(", ") + "`" });
|
319
|
+
|
320
|
+
const messageAndOTID = generateOfflineThreadingID();
|
321
|
+
const form = {
|
322
|
+
client: "mercury",
|
323
|
+
action_type: "ma-type:user-generated-message",
|
324
|
+
author: "fbid:" + ctx.userID,
|
325
|
+
timestamp: Date.now(),
|
326
|
+
timestamp_absolute: "Today",
|
327
|
+
timestamp_relative: generateTimestampRelative(),
|
328
|
+
timestamp_time_passed: "0",
|
329
|
+
is_unread: false,
|
330
|
+
is_cleared: false,
|
331
|
+
is_forward: false,
|
332
|
+
is_filtered_content: false,
|
333
|
+
is_filtered_content_bh: false,
|
334
|
+
is_filtered_content_account: false,
|
335
|
+
is_filtered_content_quasar: false,
|
336
|
+
is_filtered_content_invalid_app: false,
|
337
|
+
is_spoof_warning: false,
|
338
|
+
source: "source:chat:web",
|
339
|
+
"source_tags[0]": "source:chat",
|
340
|
+
body: msg.body ? msg.body.toString() : "",
|
341
|
+
html_body: false,
|
342
|
+
ui_push_phase: "V3",
|
343
|
+
status: "0",
|
344
|
+
offline_threading_id: messageAndOTID,
|
345
|
+
message_id: messageAndOTID,
|
346
|
+
threading_id: generateThreadingID(ctx.clientID),
|
347
|
+
ephemeral_ttl_mode: "0",
|
348
|
+
manual_retry_cnt: "0",
|
349
|
+
signatureID: getSignatureID(),
|
350
|
+
replied_to_message_id: replyToMessage ? replyToMessage.toString() : ""
|
351
|
+
};
|
352
|
+
applyPageAuthor(form, msg);
|
353
|
+
handleLocation(msg, form, callback, () =>
|
354
|
+
handleSticker(msg, form, callback, () =>
|
355
|
+
handleAttachment(msg, form, callback, () =>
|
356
|
+
handleUrl(msg, form, callback, () =>
|
357
|
+
handleEmoji(msg, form, callback, () =>
|
358
|
+
handleMention(msg, form, callback, () => {
|
359
|
+
finalizeHasAttachment(form);
|
360
|
+
send(form, threadID, messageAndOTID, callback, isGroup);
|
361
|
+
})
|
362
|
+
)
|
299
363
|
)
|
300
364
|
)
|
301
365
|
)
|
302
|
-
)
|
303
|
-
)
|
366
|
+
);
|
367
|
+
} catch (e) {
|
368
|
+
log.error("sendMessage", e);
|
369
|
+
if (getType(e) === "Object" && e.error === "Not logged in.") ctx.loggedIn = false;
|
370
|
+
return callback(e);
|
371
|
+
}
|
372
|
+
|
304
373
|
return returnPromise;
|
305
374
|
};
|
375
|
+
|
306
376
|
};
|
@@ -1,7 +1,9 @@
|
|
1
|
-
|
1
|
+
|
2
2
|
var log = require("npmlog");
|
3
3
|
var bluebird = require("bluebird");
|
4
|
-
|
4
|
+
const { parseAndCheckLogin } = require("../../utils/client");
|
5
|
+
const { getType } = require("../../utils/format");
|
6
|
+
const { isReadableStream } = require("../../utils/constants");
|
5
7
|
module.exports = function(defaultFuncs, api, ctx) {
|
6
8
|
function uploadAttachment(attachments, callback) {
|
7
9
|
callback = callback || function() {};
|
@@ -9,11 +11,11 @@ module.exports = function(defaultFuncs, api, ctx) {
|
|
9
11
|
|
10
12
|
// create an array of promises
|
11
13
|
for (var i = 0; i < attachments.length; i++) {
|
12
|
-
if (!
|
14
|
+
if (!isReadableStream(attachments[i])) {
|
13
15
|
throw {
|
14
16
|
error:
|
15
17
|
"Attachment should be a readable stream and not " +
|
16
|
-
|
18
|
+
getType(attachments[i]) +
|
17
19
|
"."
|
18
20
|
};
|
19
21
|
}
|
@@ -31,7 +33,7 @@ module.exports = function(defaultFuncs, api, ctx) {
|
|
31
33
|
form,
|
32
34
|
{}
|
33
35
|
)
|
34
|
-
.then(
|
36
|
+
.then(parseAndCheckLogin(ctx, defaultFuncs))
|
35
37
|
.then(function(resData) {
|
36
38
|
if (resData.error) {
|
37
39
|
throw resData;
|
@@ -105,7 +107,7 @@ module.exports = function(defaultFuncs, api, ctx) {
|
|
105
107
|
form.payload.tasks[0].payload.attachment_fbids = [];
|
106
108
|
if (form.payload.tasks[0].payload.text == "")
|
107
109
|
form.payload.tasks[0].payload.text = null;
|
108
|
-
if (
|
110
|
+
if (getType(msg.attachment) !== "Array") {
|
109
111
|
msg.attachment = [msg.attachment];
|
110
112
|
}
|
111
113
|
|
@@ -228,12 +230,12 @@ module.exports = function(defaultFuncs, api, ctx) {
|
|
228
230
|
return function sendMessageMqtt(msg, threadID, callback, replyToMessage) {
|
229
231
|
if (
|
230
232
|
!callback &&
|
231
|
-
(
|
232
|
-
|
233
|
+
(getType(threadID) === "Function" ||
|
234
|
+
getType(threadID) === "AsyncFunction")
|
233
235
|
) {
|
234
236
|
return threadID({ error: "Pass a threadID as a second argument." });
|
235
237
|
}
|
236
|
-
if (!replyToMessage &&
|
238
|
+
if (!replyToMessage && getType(callback) === "String") {
|
237
239
|
replyToMessage = callback;
|
238
240
|
callback = function() {};
|
239
241
|
}
|
@@ -242,9 +244,9 @@ module.exports = function(defaultFuncs, api, ctx) {
|
|
242
244
|
callback = function(err, friendList) {};
|
243
245
|
}
|
244
246
|
|
245
|
-
var msgType =
|
246
|
-
var threadIDType =
|
247
|
-
var messageIDType =
|
247
|
+
var msgType = getType(msg);
|
248
|
+
var threadIDType = getType(threadID);
|
249
|
+
var messageIDType = getType(replyToMessage);
|
248
250
|
|
249
251
|
if (msgType !== "String" && msgType !== "Object") {
|
250
252
|
return callback({
|
@@ -1,8 +1,8 @@
|
|
1
1
|
"use strict";
|
2
2
|
|
3
|
-
const utils = require("../../utils");
|
4
3
|
const log = require("npmlog");
|
5
|
-
|
4
|
+
const { getType } = require("../../utils/format");
|
5
|
+
const { parseAndCheckLogin } = require("../../utils/client");
|
6
6
|
module.exports = function(defaultFuncs, api, ctx) {
|
7
7
|
function makeTypingIndicator(typ, threadID, callback, isGroup) {
|
8
8
|
const form = {
|
@@ -14,13 +14,13 @@ module.exports = function(defaultFuncs, api, ctx) {
|
|
14
14
|
|
15
15
|
// Check if thread is a single person chat or a group chat
|
16
16
|
// More info on this is in api.sendMessage
|
17
|
-
if (
|
17
|
+
if (getType(isGroup) == "Boolean") {
|
18
18
|
if (!isGroup) {
|
19
19
|
form.to = threadID;
|
20
20
|
}
|
21
21
|
defaultFuncs
|
22
22
|
.post("https://www.facebook.com/ajax/messaging/typ.php", ctx.jar, form)
|
23
|
-
.then(
|
23
|
+
.then(parseAndCheckLogin(ctx, defaultFuncs))
|
24
24
|
.then(function(resData) {
|
25
25
|
if (resData.error) {
|
26
26
|
throw resData;
|
@@ -30,7 +30,7 @@ module.exports = function(defaultFuncs, api, ctx) {
|
|
30
30
|
})
|
31
31
|
.catch(function(err) {
|
32
32
|
log.error("sendTypingIndicator", err);
|
33
|
-
if (
|
33
|
+
if (getType(err) == "Object" && err.error === "Not logged in") {
|
34
34
|
ctx.loggedIn = false;
|
35
35
|
}
|
36
36
|
return callback(err);
|
@@ -52,7 +52,7 @@ module.exports = function(defaultFuncs, api, ctx) {
|
|
52
52
|
ctx.jar,
|
53
53
|
form
|
54
54
|
)
|
55
|
-
.then(
|
55
|
+
.then(parseAndCheckLogin(ctx, defaultFuncs))
|
56
56
|
.then(function(resData) {
|
57
57
|
if (resData.error) {
|
58
58
|
throw resData;
|
@@ -63,7 +63,7 @@ module.exports = function(defaultFuncs, api, ctx) {
|
|
63
63
|
.catch(function(err) {
|
64
64
|
log.error("sendTypingIndicator", err);
|
65
65
|
if (
|
66
|
-
|
66
|
+
getType(err) == "Object" &&
|
67
67
|
err.error === "Not logged in."
|
68
68
|
) {
|
69
69
|
ctx.loggedIn = false;
|
@@ -76,8 +76,8 @@ module.exports = function(defaultFuncs, api, ctx) {
|
|
76
76
|
|
77
77
|
return function sendTypingIndicator(threadID, callback, isGroup) {
|
78
78
|
if (
|
79
|
-
|
80
|
-
|
79
|
+
getType(callback) !== "Function" &&
|
80
|
+
getType(callback) !== "AsyncFunction"
|
81
81
|
) {
|
82
82
|
if (callback) {
|
83
83
|
log.warn(
|
@@ -92,8 +92,8 @@ module.exports = function(defaultFuncs, api, ctx) {
|
|
92
92
|
|
93
93
|
return function end(cb) {
|
94
94
|
if (
|
95
|
-
|
96
|
-
|
95
|
+
getType(cb) !== "Function" &&
|
96
|
+
getType(cb) !== "AsyncFunction"
|
97
97
|
) {
|
98
98
|
if (cb) {
|
99
99
|
log.warn(
|