metacord 0.0.1-security → 1.2.0-Beta
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.
Potentially problematic release.
This version of metacord might be problematic. Click here for more details.
- package/LICENSE +21 -0
- package/MetaCord_Config.json +11 -0
- package/MetaCord_Database/Database.sqlite +0 -0
- package/MetaCord_Database/Do not delete this folder or any of the files in it +0 -0
- package/README.md +207 -5
- package/index.js +678 -0
- package/logger.js +16 -0
- package/package.json +38 -3
- package/src/addExternalModule.js +16 -0
- package/src/addUserToGroup.js +78 -0
- package/src/changeAdminStatus.js +78 -0
- package/src/changeArchivedStatus.js +41 -0
- package/src/changeBio.js +65 -0
- package/src/changeBlockedStatus.js +36 -0
- package/src/changeGroupImage.js +106 -0
- package/src/changeNickname.js +45 -0
- package/src/changeThreadColor.js +62 -0
- package/src/changeThreadEmoji.js +42 -0
- package/src/createNewGroup.js +70 -0
- package/src/createPoll.js +60 -0
- package/src/deleteMessage.js +45 -0
- package/src/deleteThread.js +43 -0
- package/src/forwardAttachment.js +48 -0
- package/src/getCurrentUserID.js +7 -0
- package/src/getEmojiUrl.js +27 -0
- package/src/getFriendsList.js +73 -0
- package/src/getOnlineTime.js +31 -0
- package/src/getThreadHistory.js +193 -0
- package/src/getThreadInfo.js +197 -0
- package/src/getThreadList.js +213 -0
- package/src/getThreadPictures.js +59 -0
- package/src/getUID.js +57 -0
- package/src/getUserID.js +62 -0
- package/src/getUserInfo.js +66 -0
- package/src/handleFriendRequest.js +49 -0
- package/src/handleMessageRequest.js +49 -0
- package/src/httpGet.js +49 -0
- package/src/httpPost.js +48 -0
- package/src/httpPostFormData.js +41 -0
- package/src/listenMqtt.js +634 -0
- package/src/logout.js +68 -0
- package/src/markAsDelivered.js +48 -0
- package/src/markAsRead.js +70 -0
- package/src/markAsReadAll.js +43 -0
- package/src/markAsSeen.js +51 -0
- package/src/muteThread.js +47 -0
- package/src/removeUserFromGroup.js +49 -0
- package/src/resolvePhotoUrl.js +37 -0
- package/src/searchForThread.js +43 -0
- package/src/sendMessage.js +334 -0
- package/src/sendTypingIndicator.js +80 -0
- package/src/setMessageReaction.js +109 -0
- package/src/setPostReaction.js +102 -0
- package/src/setTitle.js +74 -0
- package/src/threadColors.js +39 -0
- package/src/unfriend.js +43 -0
- package/src/unsendMessage.js +40 -0
- package/utils/Database.js +42 -0
- package/utils/Extension.js +143 -0
- package/utils/Html/MetaCord.png +0 -0
- package/utils/Html/index.html +200 -0
- package/utils/StateCrypt.js +53 -0
- package/utils.js +1249 -0
| @@ -0,0 +1,70 @@ | |
| 1 | 
            +
            "use strict";
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            var utils = require("../utils");
         | 
| 4 | 
            +
            var log = require("npmlog");
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            module.exports = function (defaultFuncs, api, ctx) {
         | 
| 7 | 
            +
              return function createNewGroup(participantIDs, groupTitle, callback) {
         | 
| 8 | 
            +
                if (utils.getType(groupTitle) == "Function") {
         | 
| 9 | 
            +
                  callback = groupTitle;
         | 
| 10 | 
            +
                  groupTitle = null;
         | 
| 11 | 
            +
                }
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                if (utils.getType(participantIDs) !== "Array") throw { error: "createNewGroup: participantIDs should be an array." };
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                if (participantIDs.length < 2) throw { error: "createNewGroup: participantIDs should have at least 2 IDs." };
         | 
| 16 | 
            +
             | 
| 17 | 
            +
                var resolveFunc = function () { };
         | 
| 18 | 
            +
                var rejectFunc = function () { };
         | 
| 19 | 
            +
                var returnPromise = new Promise(function (resolve, reject) {
         | 
| 20 | 
            +
                  resolveFunc = resolve;
         | 
| 21 | 
            +
                  rejectFunc = reject;
         | 
| 22 | 
            +
                });
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                if (!callback) {
         | 
| 25 | 
            +
                  callback = function (err, threadID) {
         | 
| 26 | 
            +
                    if (err) return rejectFunc(err);
         | 
| 27 | 
            +
                    resolveFunc(threadID);
         | 
| 28 | 
            +
                  };
         | 
| 29 | 
            +
                }
         | 
| 30 | 
            +
             | 
| 31 | 
            +
                var pids = [];
         | 
| 32 | 
            +
                for (var n in participantIDs) pids.push({ fbid: participantIDs[n] });
         | 
| 33 | 
            +
                pids.push({ fbid: ctx.userID });
         | 
| 34 | 
            +
             | 
| 35 | 
            +
                var form = {
         | 
| 36 | 
            +
                  fb_api_caller_class: "RelayModern",
         | 
| 37 | 
            +
                  fb_api_req_friendly_name: "MessengerGroupCreateMutation",
         | 
| 38 | 
            +
                  av: ctx.userID,
         | 
| 39 | 
            +
                  //This doc_id is valid as of January 11th, 2020
         | 
| 40 | 
            +
                  doc_id: "577041672419534",
         | 
| 41 | 
            +
                  variables: JSON.stringify({
         | 
| 42 | 
            +
                    input: {
         | 
| 43 | 
            +
                      entry_point: "jewel_new_group",
         | 
| 44 | 
            +
                      actor_id: ctx.userID,
         | 
| 45 | 
            +
                      participants: pids,
         | 
| 46 | 
            +
                      client_mutation_id: Math.round(Math.random() * 1024).toString(),
         | 
| 47 | 
            +
                      thread_settings: {
         | 
| 48 | 
            +
                        name: groupTitle,
         | 
| 49 | 
            +
                        joinable_mode: "PRIVATE",
         | 
| 50 | 
            +
                        thread_image_fbid: null
         | 
| 51 | 
            +
                      }
         | 
| 52 | 
            +
                    }
         | 
| 53 | 
            +
                  })
         | 
| 54 | 
            +
                };
         | 
| 55 | 
            +
             | 
| 56 | 
            +
                defaultFuncs
         | 
| 57 | 
            +
                  .post("https://www.facebook.com/api/graphql/", ctx.jar, form)
         | 
| 58 | 
            +
                  .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
         | 
| 59 | 
            +
                  .then(function (resData) {
         | 
| 60 | 
            +
                    if (resData.errors) throw resData;
         | 
| 61 | 
            +
                    return callback(null, resData.data.messenger_group_thread_create.thread.thread_key.thread_fbid);
         | 
| 62 | 
            +
                  })
         | 
| 63 | 
            +
                  .catch(function (err) {
         | 
| 64 | 
            +
                    log.error("createNewGroup", err);
         | 
| 65 | 
            +
                    return callback(err);
         | 
| 66 | 
            +
                  });
         | 
| 67 | 
            +
             | 
| 68 | 
            +
                return returnPromise;
         | 
| 69 | 
            +
              };
         | 
| 70 | 
            +
            };
         | 
| @@ -0,0 +1,60 @@ | |
| 1 | 
            +
            "use strict";
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            var utils = require("../utils");
         | 
| 4 | 
            +
            var log = require("npmlog");
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            module.exports = function (defaultFuncs, api, ctx) {
         | 
| 7 | 
            +
              return function createPoll(title, threadID, options, callback) {
         | 
| 8 | 
            +
                var resolveFunc = function () { };
         | 
| 9 | 
            +
                var rejectFunc = function () { };
         | 
| 10 | 
            +
                var returnPromise = new Promise(function (resolve, reject) {
         | 
| 11 | 
            +
                  resolveFunc = resolve;
         | 
| 12 | 
            +
                  rejectFunc = reject;
         | 
| 13 | 
            +
                });
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                if (!callback) {
         | 
| 16 | 
            +
                  if (utils.getType(options) == "Function") {
         | 
| 17 | 
            +
                    callback = options;
         | 
| 18 | 
            +
                    options = null;
         | 
| 19 | 
            +
                  }
         | 
| 20 | 
            +
                  else {
         | 
| 21 | 
            +
                    callback = function (err) {
         | 
| 22 | 
            +
                      if (err) return rejectFunc(err);
         | 
| 23 | 
            +
                      resolveFunc();
         | 
| 24 | 
            +
                    };
         | 
| 25 | 
            +
                  }
         | 
| 26 | 
            +
                }
         | 
| 27 | 
            +
                if (!options) options = {}; // Initial poll options are optional
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                var form = {
         | 
| 30 | 
            +
                  target_id: threadID,
         | 
| 31 | 
            +
                  question_text: title
         | 
| 32 | 
            +
                };
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                // Set fields for options (and whether they are selected initially by the posting user)
         | 
| 35 | 
            +
                var ind = 0;
         | 
| 36 | 
            +
                for (var opt in options) {
         | 
| 37 | 
            +
                  // eslint-disable-next-line no-prototype-builtins
         | 
| 38 | 
            +
                  if (options.hasOwnProperty(opt)) {
         | 
| 39 | 
            +
                    form["option_text_array[" + ind + "]"] = opt;
         | 
| 40 | 
            +
                    form["option_is_selected_array[" + ind + "]"] = options[opt] ? "1" : "0";
         | 
| 41 | 
            +
                    ind++;
         | 
| 42 | 
            +
                  }
         | 
| 43 | 
            +
                }
         | 
| 44 | 
            +
             | 
| 45 | 
            +
                defaultFuncs
         | 
| 46 | 
            +
                  .post("https://www.facebook.com/messaging/group_polling/create_poll/?dpr=1", ctx.jar, form)
         | 
| 47 | 
            +
                  .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
         | 
| 48 | 
            +
                  .then(function (resData) {
         | 
| 49 | 
            +
                    if (resData.payload.status != "success") throw resData;
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                    return callback();
         | 
| 52 | 
            +
                  })
         | 
| 53 | 
            +
                  .catch(function (err) {
         | 
| 54 | 
            +
                    log.error("createPoll", err);
         | 
| 55 | 
            +
                    return callback(err);
         | 
| 56 | 
            +
                  });
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                return returnPromise;
         | 
| 59 | 
            +
              };
         | 
| 60 | 
            +
            };
         | 
| @@ -0,0 +1,45 @@ | |
| 1 | 
            +
            "use strict";
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            var utils = require("../utils");
         | 
| 4 | 
            +
            var log = require("npmlog");
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            module.exports = function (defaultFuncs, api, ctx) {
         | 
| 7 | 
            +
              return function deleteMessage(messageOrMessages, callback) {
         | 
| 8 | 
            +
                var resolveFunc = function () { };
         | 
| 9 | 
            +
                var rejectFunc = function () { };
         | 
| 10 | 
            +
                var returnPromise = new Promise(function (resolve, reject) {
         | 
| 11 | 
            +
                  resolveFunc = resolve;
         | 
| 12 | 
            +
                  rejectFunc = reject;
         | 
| 13 | 
            +
                });
         | 
| 14 | 
            +
                if (!callback) {
         | 
| 15 | 
            +
                  callback = function (err) {
         | 
| 16 | 
            +
                    if (err) return rejectFunc(err);
         | 
| 17 | 
            +
             | 
| 18 | 
            +
                    resolveFunc();
         | 
| 19 | 
            +
                  };
         | 
| 20 | 
            +
                }
         | 
| 21 | 
            +
             | 
| 22 | 
            +
                var form = {
         | 
| 23 | 
            +
                  client: "mercury"
         | 
| 24 | 
            +
                };
         | 
| 25 | 
            +
             | 
| 26 | 
            +
                if (utils.getType(messageOrMessages) !== "Array") messageOrMessages = [messageOrMessages];
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                for (var i = 0; i < messageOrMessages.length; i++) form["message_ids[" + i + "]"] = messageOrMessages[i];
         | 
| 29 | 
            +
             | 
| 30 | 
            +
                defaultFuncs
         | 
| 31 | 
            +
                  .post("https://www.facebook.com/ajax/mercury/delete_messages.php", ctx.jar, form)
         | 
| 32 | 
            +
                  .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
         | 
| 33 | 
            +
                  .then(function (resData) {
         | 
| 34 | 
            +
                    if (resData.error) throw resData;
         | 
| 35 | 
            +
             | 
| 36 | 
            +
                    return callback();
         | 
| 37 | 
            +
                  })
         | 
| 38 | 
            +
                  .catch(function (err) {
         | 
| 39 | 
            +
                    log.error("deleteMessage", err);
         | 
| 40 | 
            +
                    return callback(err);
         | 
| 41 | 
            +
                  });
         | 
| 42 | 
            +
             | 
| 43 | 
            +
                return returnPromise;
         | 
| 44 | 
            +
              };
         | 
| 45 | 
            +
            };
         | 
| @@ -0,0 +1,43 @@ | |
| 1 | 
            +
            "use strict";
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            var utils = require("../utils");
         | 
| 4 | 
            +
            var log = require("npmlog");
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            module.exports = function (defaultFuncs, api, ctx) {
         | 
| 7 | 
            +
              return function deleteThread(threadOrThreads, callback) {
         | 
| 8 | 
            +
                var resolveFunc = function () { };
         | 
| 9 | 
            +
                var rejectFunc = function () { };
         | 
| 10 | 
            +
                var returnPromise = new Promise(function (resolve, reject) {
         | 
| 11 | 
            +
                  resolveFunc = resolve;
         | 
| 12 | 
            +
                  rejectFunc = reject;
         | 
| 13 | 
            +
                });
         | 
| 14 | 
            +
                if (!callback) {
         | 
| 15 | 
            +
                  callback = function (err) {
         | 
| 16 | 
            +
                    if (err) return rejectFunc(err);
         | 
| 17 | 
            +
                    resolveFunc();
         | 
| 18 | 
            +
                  };
         | 
| 19 | 
            +
                }
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                var form = {
         | 
| 22 | 
            +
                  client: "mercury"
         | 
| 23 | 
            +
                };
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                if (utils.getType(threadOrThreads) !== "Array") threadOrThreads = [threadOrThreads];
         | 
| 26 | 
            +
                for (var i = 0; i < threadOrThreads.length; i++) form["ids[" + i + "]"] = threadOrThreads[i];
         | 
| 27 | 
            +
             | 
| 28 | 
            +
                defaultFuncs
         | 
| 29 | 
            +
                  .post("https://www.facebook.com/ajax/mercury/delete_thread.php", ctx.jar, form)
         | 
| 30 | 
            +
                  .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
         | 
| 31 | 
            +
                  .then(function (resData) {
         | 
| 32 | 
            +
                    if (resData.error) throw resData;
         | 
| 33 | 
            +
             | 
| 34 | 
            +
                    return callback();
         | 
| 35 | 
            +
                  })
         | 
| 36 | 
            +
                  .catch(function (err) {
         | 
| 37 | 
            +
                    log.error("deleteThread", err);
         | 
| 38 | 
            +
                    return callback(err);
         | 
| 39 | 
            +
                  });
         | 
| 40 | 
            +
             | 
| 41 | 
            +
                return returnPromise;
         | 
| 42 | 
            +
              };
         | 
| 43 | 
            +
            };
         | 
| @@ -0,0 +1,48 @@ | |
| 1 | 
            +
            "use strict";
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            var utils = require("../utils");
         | 
| 4 | 
            +
            var log = require("npmlog");
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            module.exports = function (defaultFuncs, api, ctx) {
         | 
| 7 | 
            +
              return function forwardAttachment(attachmentID, userOrUsers, callback) {
         | 
| 8 | 
            +
                var resolveFunc = function () { };
         | 
| 9 | 
            +
                var rejectFunc = function () { };
         | 
| 10 | 
            +
                var returnPromise = new Promise(function (resolve, reject) {
         | 
| 11 | 
            +
                  resolveFunc = resolve;
         | 
| 12 | 
            +
                  rejectFunc = reject;
         | 
| 13 | 
            +
                });
         | 
| 14 | 
            +
                if (!callback) {
         | 
| 15 | 
            +
                  callback = function (err) {
         | 
| 16 | 
            +
                    if (err) return rejectFunc(err);
         | 
| 17 | 
            +
                    resolveFunc();
         | 
| 18 | 
            +
                  };
         | 
| 19 | 
            +
                }
         | 
| 20 | 
            +
             | 
| 21 | 
            +
                var form = {
         | 
| 22 | 
            +
                  attachment_id: attachmentID
         | 
| 23 | 
            +
                };
         | 
| 24 | 
            +
             | 
| 25 | 
            +
                if (utils.getType(userOrUsers) !== "Array") userOrUsers = [userOrUsers];
         | 
| 26 | 
            +
             | 
| 27 | 
            +
                var timestamp = Math.floor(Date.now() / 1000);
         | 
| 28 | 
            +
             | 
| 29 | 
            +
                //That's good, the key of the array is really timestmap in seconds + index
         | 
| 30 | 
            +
                //Probably time when the attachment will be sent?
         | 
| 31 | 
            +
                for (var i = 0; i < userOrUsers.length; i++) form["recipient_map[" + (timestamp + i) + "]"] = userOrUsers[i];
         | 
| 32 | 
            +
             | 
| 33 | 
            +
                defaultFuncs
         | 
| 34 | 
            +
                  .post("https://www.facebook.com/mercury/attachments/forward/", ctx.jar, form)
         | 
| 35 | 
            +
                  .then(utils.parseAndCheckLogin(ctx.jar, defaultFuncs))
         | 
| 36 | 
            +
                  .then(function (resData) {
         | 
| 37 | 
            +
                    if (resData.error) throw resData;
         | 
| 38 | 
            +
             | 
| 39 | 
            +
                    return callback();
         | 
| 40 | 
            +
                  })
         | 
| 41 | 
            +
                  .catch(function (err) {
         | 
| 42 | 
            +
                    log.error("forwardAttachment", err);
         | 
| 43 | 
            +
                    return callback(err);
         | 
| 44 | 
            +
                  });
         | 
| 45 | 
            +
             | 
| 46 | 
            +
                return returnPromise;
         | 
| 47 | 
            +
              };
         | 
| 48 | 
            +
            };
         | 
| @@ -0,0 +1,27 @@ | |
| 1 | 
            +
            "use strict";
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            const util = require("util");
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            module.exports = function () {
         | 
| 6 | 
            +
              return function getEmojiUrl(c, size, pixelRatio) {
         | 
| 7 | 
            +
                /*
         | 
| 8 | 
            +
                 Resolves Facebook Messenger emoji image asset URL for an emoji character.
         | 
| 9 | 
            +
                 Supported sizes are 32, 64, and 128.
         | 
| 10 | 
            +
                 Supported pixel ratios are '1.0' and '1.5' (possibly more; haven't tested)
         | 
| 11 | 
            +
                 */
         | 
| 12 | 
            +
                const baseUrl = "https://static.xx.fbcdn.net/images/emoji.php/v8/z%s/%s";
         | 
| 13 | 
            +
                pixelRatio = pixelRatio || "1.0";
         | 
| 14 | 
            +
             | 
| 15 | 
            +
                let ending = util.format(
         | 
| 16 | 
            +
                  "%s/%s/%s.png",
         | 
| 17 | 
            +
                  pixelRatio,
         | 
| 18 | 
            +
                  size,
         | 
| 19 | 
            +
                  c.codePointAt(0).toString(16)
         | 
| 20 | 
            +
                );
         | 
| 21 | 
            +
                let base = 317426846;
         | 
| 22 | 
            +
                for (let i = 0; i < ending.length; i++) base = (base << 5) - base + ending.charCodeAt(i);
         | 
| 23 | 
            +
             | 
| 24 | 
            +
                let hashed = (base & 255).toString(16);
         | 
| 25 | 
            +
                return util.format(baseUrl, hashed, ending);
         | 
| 26 | 
            +
              };
         | 
| 27 | 
            +
            };
         | 
| @@ -0,0 +1,73 @@ | |
| 1 | 
            +
            "use strict";
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            //var cheerio = require("cheerio");
         | 
| 4 | 
            +
            var utils = require("../utils");
         | 
| 5 | 
            +
            var log = require("npmlog");
         | 
| 6 | 
            +
             | 
| 7 | 
            +
            // [almost] copy pasted from one of FB's minified file (GenderConst)
         | 
| 8 | 
            +
            var GENDERS = {
         | 
| 9 | 
            +
              0: "unknown",
         | 
| 10 | 
            +
              1: "female_singular",
         | 
| 11 | 
            +
              2: "male_singular",
         | 
| 12 | 
            +
              3: "female_singular_guess",
         | 
| 13 | 
            +
              4: "male_singular_guess",
         | 
| 14 | 
            +
              5: "mixed",
         | 
| 15 | 
            +
              6: "neuter_singular",
         | 
| 16 | 
            +
              7: "unknown_singular",
         | 
| 17 | 
            +
              8: "female_plural",
         | 
| 18 | 
            +
              9: "male_plural",
         | 
| 19 | 
            +
              10: "neuter_plural",
         | 
| 20 | 
            +
              11: "unknown_plural"
         | 
| 21 | 
            +
            };
         | 
| 22 | 
            +
             | 
| 23 | 
            +
            function formatData(obj) {
         | 
| 24 | 
            +
              return Object.keys(obj).map(function (key) {
         | 
| 25 | 
            +
                var user = obj[key];
         | 
| 26 | 
            +
                return {
         | 
| 27 | 
            +
                  alternateName: user.alternateName,
         | 
| 28 | 
            +
                  firstName: user.firstName,
         | 
| 29 | 
            +
                  gender: GENDERS[user.gender],
         | 
| 30 | 
            +
                  userID: utils.formatID(user.id.toString()),
         | 
| 31 | 
            +
                  isFriend: user.is_friend != null && user.is_friend ? true : false,
         | 
| 32 | 
            +
                  fullName: user.name,
         | 
| 33 | 
            +
                  profilePicture: user.thumbSrc,
         | 
| 34 | 
            +
                  type: user.type,
         | 
| 35 | 
            +
                  profileUrl: user.uri,
         | 
| 36 | 
            +
                  vanity: user.vanity,
         | 
| 37 | 
            +
                  isBirthday: !!user.is_birthday
         | 
| 38 | 
            +
                };
         | 
| 39 | 
            +
              });
         | 
| 40 | 
            +
            }
         | 
| 41 | 
            +
             | 
| 42 | 
            +
            module.exports = function (defaultFuncs, api, ctx) {
         | 
| 43 | 
            +
              return function getFriendsList(callback) {
         | 
| 44 | 
            +
                var resolveFunc = function () { };
         | 
| 45 | 
            +
                var rejectFunc = function () { };
         | 
| 46 | 
            +
                var returnPromise = new Promise(function (resolve, reject) {
         | 
| 47 | 
            +
                  resolveFunc = resolve;
         | 
| 48 | 
            +
                  rejectFunc = reject;
         | 
| 49 | 
            +
                });
         | 
| 50 | 
            +
             | 
| 51 | 
            +
                if (!callback) {
         | 
| 52 | 
            +
                  callback = function (err, friendList) {
         | 
| 53 | 
            +
                    if (err) return rejectFunc(err);
         | 
| 54 | 
            +
                    resolveFunc(friendList);
         | 
| 55 | 
            +
                  };
         | 
| 56 | 
            +
                }
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                defaultFuncs
         | 
| 59 | 
            +
                  .postFormData("https://www.facebook.com/chat/user_info_all", ctx.jar, {}, { viewer: ctx.userID })
         | 
| 60 | 
            +
                  .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
         | 
| 61 | 
            +
                  .then(function (resData) {
         | 
| 62 | 
            +
                    if (!resData) throw { error: "getFriendsList returned empty object." };
         | 
| 63 | 
            +
                    if (resData.error) throw resData;
         | 
| 64 | 
            +
                    callback(null, formatData(resData.payload));
         | 
| 65 | 
            +
                  })
         | 
| 66 | 
            +
                  .catch(function (err) {
         | 
| 67 | 
            +
                    log.error("getFriendsList", "Lỗi getFriendsList Có Thể Do Bạn Spam Quá Nhiều ! Hãy Hạn Chế !");
         | 
| 68 | 
            +
                    return callback(err);
         | 
| 69 | 
            +
                  });
         | 
| 70 | 
            +
             | 
| 71 | 
            +
                return returnPromise;
         | 
| 72 | 
            +
              };
         | 
| 73 | 
            +
            };
         | 
| @@ -0,0 +1,31 @@ | |
| 1 | 
            +
            /* eslint-disable linebreak-style */
         | 
| 2 | 
            +
            "use strict";
         | 
| 3 | 
            +
             | 
| 4 | 
            +
            module.exports = function (_defaultFuncs, _ctx) {
         | 
| 5 | 
            +
                return function getUID(callback) {
         | 
| 6 | 
            +
                    var resolveFunc = function () { };
         | 
| 7 | 
            +
                    var rejectFunc = function () { };
         | 
| 8 | 
            +
                    var returnPromise = new Promise(function (resolve, reject) {
         | 
| 9 | 
            +
                        resolveFunc = resolve;
         | 
| 10 | 
            +
                        rejectFunc = reject;
         | 
| 11 | 
            +
                    });
         | 
| 12 | 
            +
             | 
| 13 | 
            +
                    if (!callback) {
         | 
| 14 | 
            +
                        callback = function (err, data) {
         | 
| 15 | 
            +
                            if (err) return rejectFunc(err);
         | 
| 16 | 
            +
                            resolveFunc(data);
         | 
| 17 | 
            +
                        };
         | 
| 18 | 
            +
                    }
         | 
| 19 | 
            +
             | 
| 20 | 
            +
                    try {
         | 
| 21 | 
            +
                        if (!require(process.cwd() + "/MetaCord_Config.json").Count_Online_Time) return callback(null, "Not Enable Count Online Time");
         | 
| 22 | 
            +
                        const extension = require('../utils/Extension');
         | 
| 23 | 
            +
                        const time = extension.GetCountOnlineTime();
         | 
| 24 | 
            +
                        callback(time, null);
         | 
| 25 | 
            +
                    }
         | 
| 26 | 
            +
                    catch (e) {
         | 
| 27 | 
            +
                        return callback(null, e);
         | 
| 28 | 
            +
                    }
         | 
| 29 | 
            +
                    return returnPromise;
         | 
| 30 | 
            +
                };
         | 
| 31 | 
            +
            };
         | 
| @@ -0,0 +1,193 @@ | |
| 1 | 
            +
            "use strict";
         | 
| 2 | 
            +
             | 
| 3 | 
            +
            var utils = require("../utils");
         | 
| 4 | 
            +
            var log = require("npmlog");
         | 
| 5 | 
            +
             | 
| 6 | 
            +
            function formatEventReminders(reminder) {
         | 
| 7 | 
            +
              return {
         | 
| 8 | 
            +
                reminderID: reminder.id,
         | 
| 9 | 
            +
                eventCreatorID: reminder.lightweight_event_creator.id,
         | 
| 10 | 
            +
                time: reminder.time,
         | 
| 11 | 
            +
                eventType: reminder.lightweight_event_type.toLowerCase(),
         | 
| 12 | 
            +
                locationName: reminder.location_name,
         | 
| 13 | 
            +
                // @TODO verify this
         | 
| 14 | 
            +
                locationCoordinates: reminder.location_coordinates,
         | 
| 15 | 
            +
                locationPage: reminder.location_page,
         | 
| 16 | 
            +
                eventStatus: reminder.lightweight_event_status.toLowerCase(),
         | 
| 17 | 
            +
                note: reminder.note,
         | 
| 18 | 
            +
                repeatMode: reminder.repeat_mode.toLowerCase(),
         | 
| 19 | 
            +
                eventTitle: reminder.event_title,
         | 
| 20 | 
            +
                triggerMessage: reminder.trigger_message,
         | 
| 21 | 
            +
                secondsToNotifyBefore: reminder.seconds_to_notify_before,
         | 
| 22 | 
            +
                allowsRsvp: reminder.allows_rsvp,
         | 
| 23 | 
            +
                relatedEvent: reminder.related_event,
         | 
| 24 | 
            +
                members: reminder.event_reminder_members.edges.map(function (member) {
         | 
| 25 | 
            +
                  return {
         | 
| 26 | 
            +
                    memberID: member.node.id,
         | 
| 27 | 
            +
                    state: member.guest_list_state.toLowerCase()
         | 
| 28 | 
            +
                  };
         | 
| 29 | 
            +
                })
         | 
| 30 | 
            +
              };
         | 
| 31 | 
            +
            }
         | 
| 32 | 
            +
             | 
| 33 | 
            +
            function formatThreadGraphQLResponse(data) {
         | 
| 34 | 
            +
              var messageThread = data.o0.data.message_thread;
         | 
| 35 | 
            +
              var threadID = messageThread.thread_key.thread_fbid ? messageThread.thread_key.thread_fbid : messageThread.thread_key.other_user_id;
         | 
| 36 | 
            +
             | 
| 37 | 
            +
              // Remove me
         | 
| 38 | 
            +
              var lastM = messageThread.last_message;
         | 
| 39 | 
            +
              var snippetID = lastM && lastM.nodes && lastM.nodes[0] && lastM.nodes[0].message_sender && lastM.nodes[0].message_sender.messaging_actor ? lastM.nodes[0].message_sender.messaging_actor.id : null;
         | 
| 40 | 
            +
              var snippetText = lastM && lastM.nodes && lastM.nodes[0] ? lastM.nodes[0].snippet : null;
         | 
| 41 | 
            +
              var lastR = messageThread.last_read_receipt;
         | 
| 42 | 
            +
              var lastReadTimestamp = lastR && lastR.nodes && lastR.nodes[0] && lastR.nodes[0].timestamp_precise ? lastR.nodes[0].timestamp_precise : null;
         | 
| 43 | 
            +
             | 
| 44 | 
            +
              return {
         | 
| 45 | 
            +
                threadID: threadID,
         | 
| 46 | 
            +
                threadName: messageThread.name,
         | 
| 47 | 
            +
                participantIDs: messageThread.all_participants.edges.map(d => d.node.messaging_actor.id),
         | 
| 48 | 
            +
                userInfo: messageThread.all_participants.edges.map(d => ({
         | 
| 49 | 
            +
                  id: d.node.messaging_actor.id,
         | 
| 50 | 
            +
                  name: d.node.messaging_actor.name,
         | 
| 51 | 
            +
                  firstName: d.node.messaging_actor.short_name,
         | 
| 52 | 
            +
                  vanity: d.node.messaging_actor.username,
         | 
| 53 | 
            +
                  thumbSrc: d.node.messaging_actor.big_image_src.uri,
         | 
| 54 | 
            +
                  profileUrl: d.node.messaging_actor.big_image_src.uri,
         | 
| 55 | 
            +
                  gender: d.node.messaging_actor.gender,
         | 
| 56 | 
            +
                  type: d.node.messaging_actor.__typename,
         | 
| 57 | 
            +
                  isFriend: d.node.messaging_actor.is_viewer_friend,
         | 
| 58 | 
            +
                  isBirthday: !!d.node.messaging_actor.is_birthday //not sure?
         | 
| 59 | 
            +
                })),
         | 
| 60 | 
            +
                unreadCount: messageThread.unread_count,
         | 
| 61 | 
            +
                messageCount: messageThread.messages_count,
         | 
| 62 | 
            +
                timestamp: messageThread.updated_time_precise,
         | 
| 63 | 
            +
                muteUntil: messageThread.mute_until,
         | 
| 64 | 
            +
                isGroup: messageThread.thread_type == "GROUP",
         | 
| 65 | 
            +
                isSubscribed: messageThread.is_viewer_subscribed,
         | 
| 66 | 
            +
                isArchived: messageThread.has_viewer_archived,
         | 
| 67 | 
            +
                folder: messageThread.folder,
         | 
| 68 | 
            +
                cannotReplyReason: messageThread.cannot_reply_reason,
         | 
| 69 | 
            +
                eventReminders: messageThread.event_reminders ? messageThread.event_reminders.nodes.map(formatEventReminders) : null,
         | 
| 70 | 
            +
                emoji: messageThread.customization_info ? messageThread.customization_info.emoji : null,
         | 
| 71 | 
            +
                color: messageThread.customization_info && messageThread.customization_info.outgoing_bubble_color ? messageThread.customization_info.outgoing_bubble_color.slice(2) : null,
         | 
| 72 | 
            +
                nicknames:
         | 
| 73 | 
            +
                  messageThread.customization_info &&
         | 
| 74 | 
            +
                    messageThread.customization_info.participant_customizations
         | 
| 75 | 
            +
                    ? messageThread.customization_info.participant_customizations.reduce(function (res, val) {
         | 
| 76 | 
            +
                      if (val.nickname) res[val.participant_id] = val.nickname;
         | 
| 77 | 
            +
                      return res;
         | 
| 78 | 
            +
                    }, {})
         | 
| 79 | 
            +
                    : {},
         | 
| 80 | 
            +
                adminIDs: messageThread.thread_admins,
         | 
| 81 | 
            +
                approvalMode: Boolean(messageThread.approval_mode),
         | 
| 82 | 
            +
                approvalQueue: messageThread.group_approval_queue.nodes.map(a => ({
         | 
| 83 | 
            +
                  inviterID: a.inviter.id,
         | 
| 84 | 
            +
                  requesterID: a.requester.id,
         | 
| 85 | 
            +
                  timestamp: a.request_timestamp,
         | 
| 86 | 
            +
                  request_source: a.request_source // @Undocumented
         | 
| 87 | 
            +
                })),
         | 
| 88 | 
            +
             | 
| 89 | 
            +
                // @Undocumented
         | 
| 90 | 
            +
                reactionsMuteMode: messageThread.reactions_mute_mode.toLowerCase(),
         | 
| 91 | 
            +
                mentionsMuteMode: messageThread.mentions_mute_mode.toLowerCase(),
         | 
| 92 | 
            +
                isPinProtected: messageThread.is_pin_protected,
         | 
| 93 | 
            +
                relatedPageThread: messageThread.related_page_thread,
         | 
| 94 | 
            +
             | 
| 95 | 
            +
                // @Legacy
         | 
| 96 | 
            +
                name: messageThread.name,
         | 
| 97 | 
            +
                snippet: snippetText,
         | 
| 98 | 
            +
                snippetSender: snippetID,
         | 
| 99 | 
            +
                snippetAttachments: [],
         | 
| 100 | 
            +
                serverTimestamp: messageThread.updated_time_precise,
         | 
| 101 | 
            +
                imageSrc: messageThread.image ? messageThread.image.uri : null,
         | 
| 102 | 
            +
                isCanonicalUser: messageThread.is_canonical_neo_user,
         | 
| 103 | 
            +
                isCanonical: messageThread.thread_type != "GROUP",
         | 
| 104 | 
            +
                recipientsLoadable: true,
         | 
| 105 | 
            +
                hasEmailParticipant: false,
         | 
| 106 | 
            +
                readOnly: false,
         | 
| 107 | 
            +
                canReply: messageThread.cannot_reply_reason == null,
         | 
| 108 | 
            +
                lastMessageTimestamp: messageThread.last_message ? messageThread.last_message.timestamp_precise : null,
         | 
| 109 | 
            +
                lastMessageType: "message",
         | 
| 110 | 
            +
                lastReadTimestamp: lastReadTimestamp,
         | 
| 111 | 
            +
                threadType: messageThread.thread_type == "GROUP" ? 2 : 1
         | 
| 112 | 
            +
              };
         | 
| 113 | 
            +
            }
         | 
| 114 | 
            +
             | 
| 115 | 
            +
            module.exports = function (defaultFuncs, api, ctx) {
         | 
| 116 | 
            +
              return function getThreadInfoGraphQL(threadID, callback) {
         | 
| 117 | 
            +
                var path = require("path");
         | 
| 118 | 
            +
                const { writeFileSync } = require('fs-extra');
         | 
| 119 | 
            +
                var threadData = require('./data/getThreadInfo.json');
         | 
| 120 | 
            +
             | 
| 121 | 
            +
                var threadJson = path.resolve(__dirname, 'data', 'getThreadInfo.json');
         | 
| 122 | 
            +
                if(threadData.some(i => i.data.threadID == threadID)) {
         | 
| 123 | 
            +
                  var thread = threadData.find(i => i.data.threadID == threadID);
         | 
| 124 | 
            +
                  if(((Date.now() - thread.time)/1000).toFixed() >= 60 * 60 * 2) {
         | 
| 125 | 
            +
                    const index = threadData.findIndex(i => i.data.threadID == threadID);
         | 
| 126 | 
            +
                    threadData.splice(index, 1);
         | 
| 127 | 
            +
                    setTimeout(function() {
         | 
| 128 | 
            +
                      writeFileSync(threadJson, JSON.stringify(threadData, null, 4));
         | 
| 129 | 
            +
                    }, 2000);
         | 
| 130 | 
            +
                  }
         | 
| 131 | 
            +
                  return thread.data
         | 
| 132 | 
            +
                }
         | 
| 133 | 
            +
                else {
         | 
| 134 | 
            +
                  var resolveFunc = function () { };
         | 
| 135 | 
            +
                  var rejectFunc = function () { };
         | 
| 136 | 
            +
                  var returnPromise = new Promise(function (resolve, reject) {
         | 
| 137 | 
            +
                    resolveFunc = resolve;
         | 
| 138 | 
            +
                    rejectFunc = reject;
         | 
| 139 | 
            +
                  });
         | 
| 140 | 
            +
             | 
| 141 | 
            +
                  if (utils.getType(callback) != "Function" && utils.getType(callback) != "AsyncFunction") {
         | 
| 142 | 
            +
                    callback = function (err, data) {
         | 
| 143 | 
            +
                      if (err) return rejectFunc(err);
         | 
| 144 | 
            +
                      resolveFunc(data);
         | 
| 145 | 
            +
                    };
         | 
| 146 | 
            +
                  }
         | 
| 147 | 
            +
             | 
| 148 | 
            +
                  // `queries` has to be a string. I couldn't tell from the dev console. This
         | 
| 149 | 
            +
                  // took me a really long time to figure out. I deserve a cookie for this.
         | 
| 150 | 
            +
                  var form = {
         | 
| 151 | 
            +
                    queries: JSON.stringify({
         | 
| 152 | 
            +
                      o0: {
         | 
| 153 | 
            +
                        // This doc_id is valid as of July 20th, 2020
         | 
| 154 | 
            +
                        doc_id: "3449967031715030",
         | 
| 155 | 
            +
                        query_params: {
         | 
| 156 | 
            +
                          id: threadID,
         | 
| 157 | 
            +
                          message_limit: 0,
         | 
| 158 | 
            +
                          load_messages: false,
         | 
| 159 | 
            +
                          load_read_receipts: false,
         | 
| 160 | 
            +
                          before: null
         | 
| 161 | 
            +
                        }
         | 
| 162 | 
            +
                      }
         | 
| 163 | 
            +
                    }),
         | 
| 164 | 
            +
                    batch_name: "MessengerGraphQLThreadFetcher"
         | 
| 165 | 
            +
                  };
         | 
| 166 | 
            +
             | 
| 167 | 
            +
                  defaultFuncs
         | 
| 168 | 
            +
                    .post("https://www.facebook.com/api/graphqlbatch/", ctx.jar, form)
         | 
| 169 | 
            +
                    .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
         | 
| 170 | 
            +
                    .then(function (resData) {
         | 
| 171 | 
            +
                      if (resData.error) throw resData;
         | 
| 172 | 
            +
                      // This returns us an array of things. The last one is the success /
         | 
| 173 | 
            +
                      // failure one.
         | 
| 174 | 
            +
                      // @TODO What do we do in this case?
         | 
| 175 | 
            +
                      if (resData[resData.length - 1].error_results !== 0) {
         | 
| 176 | 
            +
                        console.log(resData); //Log more info
         | 
| 177 | 
            +
                        throw new Error("well darn there was an error_result");
         | 
| 178 | 
            +
                      }
         | 
| 179 | 
            +
                      threadData.push({
         | 
| 180 | 
            +
                        data: formatThreadGraphQLResponse(resData[0]),
         | 
| 181 | 
            +
                        time: Date.now()
         | 
| 182 | 
            +
                      })
         | 
| 183 | 
            +
                      writeFileSync(threadJson, JSON.stringify(threadData, null, 4));
         | 
| 184 | 
            +
                      callback(null, formatThreadGraphQLResponse(resData[0]));
         | 
| 185 | 
            +
                    })
         | 
| 186 | 
            +
                    .catch(function (err) {
         | 
| 187 | 
            +
                      log.error("getThreadInfoGraphQL", err);
         | 
| 188 | 
            +
                      return callback(err);
         | 
| 189 | 
            +
                    });
         | 
| 190 | 
            +
                  return returnPromise;
         | 
| 191 | 
            +
                };
         | 
| 192 | 
            +
              }
         | 
| 193 | 
            +
            };
         |