alicezetion 1.1.0 → 1.1.1

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.
Files changed (75) hide show
  1. package/.cache/replit/__replit_disk_meta.json +1 -1
  2. package/.cache/replit/nix/env.json +1 -1
  3. package/index.js +558 -490
  4. package/leiamnash/addExternalModule.js +19 -0
  5. package/{src → leiamnash}/addUserToGroup.js +52 -16
  6. package/leiamnash/changeAdminStatus.js +79 -0
  7. package/leiamnash/changeArchivedStatus.js +55 -0
  8. package/{src → leiamnash}/changeBio.js +19 -6
  9. package/{src → leiamnash}/changeBlockedStatus.js +14 -3
  10. package/{src → leiamnash}/changeGroupImage.js +40 -16
  11. package/leiamnash/changeNickname.js +59 -0
  12. package/{src → leiamnash}/changeThreadColor.js +20 -10
  13. package/leiamnash/changeThreadEmoji.js +55 -0
  14. package/leiamnash/chat.js +459 -0
  15. package/{src → leiamnash}/createNewGroup.js +28 -12
  16. package/{src → leiamnash}/createPoll.js +25 -13
  17. package/leiamnash/deleteMessage.js +56 -0
  18. package/leiamnash/deleteThread.js +56 -0
  19. package/leiamnash/forwardAttachment.js +60 -0
  20. package/{src → leiamnash}/getCurrentUserID.js +1 -1
  21. package/{src → leiamnash}/getEmojiUrl.js +4 -2
  22. package/{src → leiamnash}/getFriendsList.js +21 -10
  23. package/{src → leiamnash}/getThreadHistory.js +166 -58
  24. package/{src → leiamnash}/getThreadHistoryDeprecated.js +42 -20
  25. package/{src → leiamnash}/getThreadInfo.js +60 -25
  26. package/leiamnash/getThreadInfoDeprecated.js +80 -0
  27. package/{src → leiamnash}/getThreadList.js +66 -41
  28. package/leiamnash/getThreadListDeprecated.js +75 -0
  29. package/leiamnash/getThreadPictures.js +79 -0
  30. package/{src → leiamnash}/getUserID.js +14 -9
  31. package/{src → leiamnash}/getUserInfo.js +1 -1
  32. package/leiamnash/handleFriendRequest.js +61 -0
  33. package/leiamnash/handleMessageRequest.js +65 -0
  34. package/{src → leiamnash}/httpGet.js +17 -12
  35. package/{src → leiamnash}/httpPost.js +17 -12
  36. package/leiamnash/listenMqtt.js +687 -0
  37. package/{src → leiamnash}/logout.js +20 -13
  38. package/{src → leiamnash}/markAsDelivered.js +22 -11
  39. package/{src → leiamnash}/markAsRead.js +21 -11
  40. package/{src → leiamnash}/markAsReadAll.js +20 -10
  41. package/{src → leiamnash}/markAsSeen.js +18 -7
  42. package/{src → leiamnash}/muteThread.js +18 -11
  43. package/leiamnash/removeUserFromGroup.js +79 -0
  44. package/{src → leiamnash}/resolvePhotoUrl.js +17 -8
  45. package/{src → leiamnash}/searchForThread.js +21 -10
  46. package/{src → leiamnash}/sendTypingIndicator.js +47 -14
  47. package/{src → leiamnash}/setMessageReaction.js +26 -12
  48. package/{src → leiamnash}/setPostReaction.js +26 -13
  49. package/{src → leiamnash}/setTitle.js +29 -13
  50. package/leiamnash/threadColors.js +57 -0
  51. package/{src → leiamnash}/unfriend.js +19 -9
  52. package/{src → leiamnash}/unsendMessage.js +19 -9
  53. package/package.json +9 -14
  54. package/replit.nix +0 -1
  55. package/utils.js +1193 -1023
  56. package/src/addExternalModule.js +0 -15
  57. package/src/changeAdminStatus.js +0 -47
  58. package/src/changeArchivedStatus.js +0 -41
  59. package/src/changeNickname.js +0 -43
  60. package/src/changeThreadEmoji.js +0 -41
  61. package/src/chat.js +0 -315
  62. package/src/deleteMessage.js +0 -44
  63. package/src/deleteThread.js +0 -42
  64. package/src/forwardAttachment.js +0 -47
  65. package/src/forwardMessage.js +0 -0
  66. package/src/getThreadInfoDeprecated.js +0 -56
  67. package/src/getThreadListDeprecated.js +0 -46
  68. package/src/getThreadPictures.js +0 -59
  69. package/src/handleFriendRequest.js +0 -46
  70. package/src/handleMessageRequest.js +0 -47
  71. package/src/listen.js +0 -553
  72. package/src/listenMqtt-Test.js +0 -687
  73. package/src/listenMqtt.js +0 -677
  74. package/src/removeUserFromGroup.js +0 -45
  75. package/src/threadColors.js +0 -41
@@ -3,54 +3,73 @@
3
3
  var utils = require("../utils");
4
4
  var log = require("npmlog");
5
5
 
6
- module.exports = function (defaultFuncs, api, ctx) {
6
+ module.exports = function(defaultFuncs, api, ctx) {
7
7
  return function getThreadHistory(threadID, amount, timestamp, callback) {
8
- var resolveFunc = function () { };
9
- var rejectFunc = function () { };
8
+ var resolveFunc = function(){};
9
+ var rejectFunc = function(){};
10
10
  var returnPromise = new Promise(function (resolve, reject) {
11
11
  resolveFunc = resolve;
12
12
  rejectFunc = reject;
13
13
  });
14
14
 
15
15
  if (!callback) {
16
- callback = function (err, threadInfo) {
17
- if (err) return rejectFunc(err);
18
- resolveFunc(threadInfo);
16
+ callback = function (err, friendList) {
17
+ if (err) {
18
+ return rejectFunc(err);
19
+ }
20
+ resolveFunc(friendList);
19
21
  };
20
22
  }
21
23
 
22
- if (!callback) throw { error: "getThreadHistory: need callback" };
24
+ if (!callback) {
25
+ throw { error: "getThreadHistory: need callback" };
26
+ }
27
+
23
28
  var form = {
24
29
  client: "mercury"
25
30
  };
26
31
 
27
- api.getUserInfo(threadID, function (err, res) {
28
- if (err) return callback(err);
32
+ api.getUserInfo(threadID, function(err, res) {
33
+ if (err) {
34
+ return callback(err);
35
+ }
29
36
  var key = Object.keys(res).length > 0 ? "user_ids" : "thread_fbids";
30
37
  form["messages[" + key + "][" + threadID + "][offset]"] = 0;
31
38
  form["messages[" + key + "][" + threadID + "][timestamp]"] = timestamp;
32
39
  form["messages[" + key + "][" + threadID + "][limit]"] = amount;
33
40
 
34
- if (ctx.globalOptions.pageID) form.request_user_id = ctx.globalOptions.pageID;
41
+ if (ctx.globalOptions.pageID)
42
+ form.request_user_id = ctx.globalOptions.pageID;
35
43
 
36
44
  defaultFuncs
37
- .post("https://www.facebook.com/ajax/mercury/thread_info.php", ctx.jar, form)
45
+ .post(
46
+ "https://www.facebook.com/ajax/mercury/thread_info.php",
47
+ ctx.jar,
48
+ form
49
+ )
38
50
  .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
39
- .then(function (resData) {
40
- if (resData.error) throw resData;
41
- else if (!resData.payload) throw { error: "Could not retrieve thread history." };
51
+ .then(function(resData) {
52
+ if (resData.error) {
53
+ throw resData;
54
+ } else if (!resData.payload) {
55
+ throw { error: "Could not retrieve thread history." };
56
+ }
42
57
 
43
58
  // Asking for message history from a thread with no message history
44
59
  // will return undefined for actions here
45
- if (!resData.payload.actions) resData.payload.actions = [];
60
+ if (!resData.payload.actions) {
61
+ resData.payload.actions = [];
62
+ }
46
63
 
47
64
  var userIDs = {};
48
- resData.payload.actions.forEach(v => userIDs[v.author.split(":").pop()] = "");
65
+ resData.payload.actions.forEach(function(v) {
66
+ userIDs[v.author.split(":").pop()] = "";
67
+ });
49
68
 
50
- api.getUserInfo(Object.keys(userIDs), function (err, data) {
69
+ api.getUserInfo(Object.keys(userIDs), function(err, data) {
51
70
  if (err) return callback(err); //callback({error: "Could not retrieve user information in getThreadHistory."});
52
71
 
53
- resData.payload.actions.forEach(function (v) {
72
+ resData.payload.actions.forEach(function(v) {
54
73
  var sender = data[v.author.split(":").pop()];
55
74
  if (sender) v.sender_name = sender.name;
56
75
  else v.sender_name = "Facebook User";
@@ -58,10 +77,13 @@ module.exports = function (defaultFuncs, api, ctx) {
58
77
  delete v.author;
59
78
  });
60
79
 
61
- callback(null, resData.payload.actions.map(utils.formatHistoryMessage));
80
+ callback(
81
+ null,
82
+ resData.payload.actions.map(utils.formatHistoryMessage)
83
+ );
62
84
  });
63
85
  })
64
- .catch(function (err) {
86
+ .catch(function(err) {
65
87
  log.error("getThreadHistory", err);
66
88
  return callback(err);
67
89
  });
@@ -21,7 +21,7 @@ function formatEventReminders(reminder) {
21
21
  secondsToNotifyBefore: reminder.seconds_to_notify_before,
22
22
  allowsRsvp: reminder.allows_rsvp,
23
23
  relatedEvent: reminder.related_event,
24
- members: reminder.event_reminder_members.edges.map(function (member) {
24
+ members: reminder.event_reminder_members.edges.map(function(member) {
25
25
  return {
26
26
  memberID: member.node.id,
27
27
  state: member.guest_list_state.toLowerCase()
@@ -31,15 +31,33 @@ function formatEventReminders(reminder) {
31
31
  }
32
32
 
33
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;
34
+ try{
35
+ var messageThread = data.o0.data.message_thread;
36
+ } catch (err){
37
+ console.error("GetThreadInfoGraphQL", "Can't get this thread info!");
38
+ return {err: err};
39
+ }
40
+ var threadID = messageThread.thread_key.thread_fbid
41
+ ? messageThread.thread_key.thread_fbid
42
+ : messageThread.thread_key.other_user_id;
36
43
 
37
44
  // Remove me
38
45
  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;
46
+ var snippetID =
47
+ lastM &&
48
+ lastM.nodes &&
49
+ lastM.nodes[0] &&
50
+ lastM.nodes[0].message_sender &&
51
+ lastM.nodes[0].message_sender.messaging_actor
52
+ ? lastM.nodes[0].message_sender.messaging_actor.id
53
+ : null;
54
+ var snippetText =
55
+ lastM && lastM.nodes && lastM.nodes[0] ? lastM.nodes[0].snippet : null;
41
56
  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;
57
+ var lastReadTimestamp =
58
+ lastR && lastR.nodes && lastR.nodes[0] && lastR.nodes[0].timestamp_precise
59
+ ? lastR.nodes[0].timestamp_precise
60
+ : null;
43
61
 
44
62
  return {
45
63
  threadID: threadID,
@@ -66,16 +84,27 @@ function formatThreadGraphQLResponse(data) {
66
84
  isArchived: messageThread.has_viewer_archived,
67
85
  folder: messageThread.folder,
68
86
  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,
87
+ eventReminders: messageThread.event_reminders
88
+ ? messageThread.event_reminders.nodes.map(formatEventReminders)
89
+ : null,
90
+ emoji: messageThread.customization_info
91
+ ? messageThread.customization_info.emoji
92
+ : null,
93
+ color:
94
+ messageThread.customization_info &&
95
+ messageThread.customization_info.outgoing_bubble_color
96
+ ? messageThread.customization_info.outgoing_bubble_color.slice(2)
97
+ : null,
72
98
  nicknames:
73
99
  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
- }, {})
100
+ messageThread.customization_info.participant_customizations
101
+ ? messageThread.customization_info.participant_customizations.reduce(
102
+ function(res, val) {
103
+ if (val.nickname) res[val.participant_id] = val.nickname;
104
+ return res;
105
+ },
106
+ {}
107
+ )
79
108
  : {},
80
109
  adminIDs: messageThread.thread_admins,
81
110
  approvalMode: Boolean(messageThread.approval_mode),
@@ -105,17 +134,19 @@ function formatThreadGraphQLResponse(data) {
105
134
  hasEmailParticipant: false,
106
135
  readOnly: false,
107
136
  canReply: messageThread.cannot_reply_reason == null,
108
- lastMessageTimestamp: messageThread.last_message ? messageThread.last_message.timestamp_precise : null,
137
+ lastMessageTimestamp: messageThread.last_message
138
+ ? messageThread.last_message.timestamp_precise
139
+ : null,
109
140
  lastMessageType: "message",
110
141
  lastReadTimestamp: lastReadTimestamp,
111
142
  threadType: messageThread.thread_type == "GROUP" ? 2 : 1
112
143
  };
113
144
  }
114
145
 
115
- module.exports = function (defaultFuncs, api, ctx) {
146
+ module.exports = function(defaultFuncs, api, ctx) {
116
147
  return function getThreadInfoGraphQL(threadID, callback) {
117
- var resolveFunc = function () { };
118
- var rejectFunc = function () { };
148
+ var resolveFunc = function(){};
149
+ var rejectFunc = function(){};
119
150
  var returnPromise = new Promise(function (resolve, reject) {
120
151
  resolveFunc = resolve;
121
152
  rejectFunc = reject;
@@ -123,7 +154,9 @@ module.exports = function (defaultFuncs, api, ctx) {
123
154
 
124
155
  if (utils.getType(callback) != "Function" && utils.getType(callback) != "AsyncFunction") {
125
156
  callback = function (err, data) {
126
- if (err) return rejectFunc(err);
157
+ if (err) {
158
+ return rejectFunc(err);
159
+ }
127
160
  resolveFunc(data);
128
161
  };
129
162
  }
@@ -150,19 +183,21 @@ module.exports = function (defaultFuncs, api, ctx) {
150
183
  defaultFuncs
151
184
  .post("https://www.facebook.com/api/graphqlbatch/", ctx.jar, form)
152
185
  .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
153
- .then(function (resData) {
154
- if (resData.error) throw resData;
186
+ .then(function(resData) {
187
+ if (resData.error) {
188
+ throw resData;
189
+ }
155
190
  // This returns us an array of things. The last one is the success /
156
191
  // failure one.
157
192
  // @TODO What do we do in this case?
158
193
  if (resData[resData.length - 1].error_results !== 0) {
159
- console.log(resData); //Log more info
160
- throw new Error("well darn there was an error_result");
194
+ console.error("GetThreadInfo", "Well darn there was an error_result");
161
195
  }
196
+
162
197
  callback(null, formatThreadGraphQLResponse(resData[0]));
163
198
  })
164
- .catch(function (err) {
165
- log.error("getThreadInfoGraphQL", "Can't get thread info");
199
+ .catch(function(err) {
200
+ log.error("getThreadInfoGraphQL", err);
166
201
  return callback(err);
167
202
  });
168
203
 
@@ -0,0 +1,80 @@
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 getThreadInfo(threadID, 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
+ callback = function (err, friendList) {
17
+ if (err) {
18
+ return rejectFunc(err);
19
+ }
20
+ resolveFunc(friendList);
21
+ };
22
+ }
23
+
24
+ var form = {
25
+ client: "mercury"
26
+ };
27
+
28
+ api.getUserInfo(threadID, function(err, userRes) {
29
+ if (err) {
30
+ return callback(err);
31
+ }
32
+ var key = Object.keys(userRes).length > 0 ? "user_ids" : "thread_fbids";
33
+ form["threads[" + key + "][0]"] = threadID;
34
+
35
+ if (ctx.globalOptions.pageId)
36
+ form.request_user_id = ctx.globalOptions.pageId;
37
+
38
+ defaultFuncs
39
+ .post(
40
+ "https://www.facebook.com/ajax/mercury/thread_info.php",
41
+ ctx.jar,
42
+ form
43
+ )
44
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
45
+ .then(function(resData) {
46
+ if (resData.error) {
47
+ throw resData;
48
+ } else if (!resData.payload) {
49
+ throw {
50
+ error: "Could not retrieve thread Info."
51
+ };
52
+ }
53
+ var threadData = resData.payload.threads[0];
54
+ var userData = userRes[threadID];
55
+
56
+ if (threadData == null) {
57
+ throw {
58
+ error: "ThreadData is null"
59
+ };
60
+ }
61
+
62
+ threadData.name =
63
+ userData != null && userData.name != null
64
+ ? userData.name
65
+ : threadData.name;
66
+ threadData.image_src =
67
+ userData != null && userData.thumbSrc != null
68
+ ? userData.thumbSrc
69
+ : threadData.image_src;
70
+
71
+ callback(null, utils.formatThread(threadData));
72
+ })
73
+ .catch(function(err) {
74
+ log.error("getThreadInfo", err);
75
+ return callback(err);
76
+ });
77
+ });
78
+ return returnPromise;
79
+ };
80
+ };
@@ -9,7 +9,7 @@ function createProfileUrl(url, username, id) {
9
9
  }
10
10
 
11
11
  function formatParticipants(participants) {
12
- return participants.edges.map((p) => {
12
+ return participants.edges.map((p)=>{
13
13
  p = p.node.messaging_actor;
14
14
  switch (p["__typename"]) {
15
15
  case "User":
@@ -21,7 +21,7 @@ function formatParticipants(participants) {
21
21
  gender: p.gender,
22
22
  url: p.url, // how about making it profileURL
23
23
  profilePicture: p.big_image_src.uri,
24
- username: (p.username || null),
24
+ username: (p.username||null),
25
25
  // TODO: maybe better names for these?
26
26
  isViewerFriend: p.is_viewer_friend, // true/false
27
27
  isMessengerUser: p.is_messenger_user, // true/false
@@ -37,7 +37,7 @@ function formatParticipants(participants) {
37
37
  name: p.name,
38
38
  url: p.url,
39
39
  profilePicture: p.big_image_src.uri,
40
- username: (p.username || null),
40
+ username: (p.username||null),
41
41
  // uhm... better names maybe?
42
42
  acceptsMessengerUserFeedback: p.accepts_messenger_user_feedback, // true/false
43
43
  isMessengerUser: p.is_messenger_user, // true/false
@@ -46,18 +46,27 @@ function formatParticipants(participants) {
46
46
  isMessageBlockedByViewer: p.is_message_blocked_by_viewer, // true/false
47
47
  };
48
48
  case "ReducedMessagingActor":
49
- case "UnavailableMessagingActor":
50
49
  return {
51
50
  accountType: p["__typename"],
52
51
  userID: utils.formatID(p.id.toString()),
53
52
  name: p.name,
54
53
  url: createProfileUrl(p.url, p.username, p.id), // in this case p.url is null all the time
55
54
  profilePicture: p.big_image_src.uri, // in this case it is default facebook photo, we could determine gender using it
56
- username: (p.username || null), // maybe we could use it to generate profile URL?
55
+ username: (p.username||null), // maybe we could use it to generate profile URL?
56
+ isMessageBlockedByViewer: p.is_message_blocked_by_viewer, // true/false
57
+ };
58
+ case "UnavailableMessagingActor":
59
+ return {
60
+ accountType: p["__typename"],
61
+ userID: utils.formatID(p.id.toString()),
62
+ name: p.name, // "Facebook User" in user's language
63
+ url: createProfileUrl(p.url, p.username, p.id), // in this case p.url is null all the time
64
+ profilePicture: p.big_image_src.uri, // default male facebook photo
65
+ username: (p.username||null), // maybe we could use it to generate profile URL?
57
66
  isMessageBlockedByViewer: p.is_message_blocked_by_viewer, // true/false
58
67
  };
59
68
  default:
60
- log.warn("getThreadList", "Found participant with unsupported typename. Please open an issue at https://github.com/Schmavery/facebook-chat-api/issues\n" + JSON.stringify(p, null, 2));
69
+ log.warn("getThreadList", "Found participant with unsupported typename. Please open an issue at https://github.com/Schmavery/fca-unofficial/issues\n" + JSON.stringify(p, null, 2));
61
70
  return {
62
71
  accountType: p["__typename"],
63
72
  userID: utils.formatID(p.id.toString()),
@@ -69,7 +78,9 @@ function formatParticipants(participants) {
69
78
 
70
79
  // "FF8C0077" -> "8C0077"
71
80
  function formatColor(color) {
72
- if (color && color.match(/^(?:[0-9a-fA-F]{8})$/g)) return color.slice(2);
81
+ if (color && color.match(/^(?:[0-9a-fA-F]{8})$/g)) {
82
+ return color.slice(2);
83
+ }
73
84
  return color;
74
85
  }
75
86
 
@@ -84,24 +95,24 @@ function getThreadName(t) {
84
95
 
85
96
  function mapNicknames(customizationInfo) {
86
97
  return (customizationInfo && customizationInfo.participant_customizations) ? customizationInfo.participant_customizations.map(u => {
87
- return {
88
- "userID": u.participant_id,
89
- "nickname": u.nickname
90
- };
91
- }) : [];
98
+ return {
99
+ "userID": u.participant_id,
100
+ "nickname": u.nickname
101
+ };
102
+ }):[];
92
103
  }
93
104
 
94
105
  function formatThreadList(data) {
95
106
  return data.map(t => {
96
- let lastMessageNode = (t.last_message && t.last_message.nodes && t.last_message.nodes.length > 0) ? t.last_message.nodes[0] : null;
107
+ let lastMessageNode = (t.last_message&&t.last_message.nodes&&t.last_message.nodes.length>0)?t.last_message.nodes[0]:null;
97
108
  return {
98
- threadID: t.thread_key ? utils.formatID(t.thread_key.thread_fbid || t.thread_key.other_user_id) : null, // shall never be null
109
+ threadID: t.thread_key?utils.formatID(t.thread_key.thread_fbid || t.thread_key.other_user_id):null, // shall never be null
99
110
  name: getThreadName(t),
100
111
  unreadCount: t.unread_count,
101
112
  messageCount: t.messages_count,
102
- imageSrc: t.image ? t.image.uri : null,
103
- emoji: t.customization_info ? t.customization_info.emoji : null,
104
- color: formatColor(t.customization_info ? t.customization_info.outgoing_bubble_color : null),
113
+ imageSrc: t.image?t.image.uri:null,
114
+ emoji: t.customization_info?t.customization_info.emoji:null,
115
+ color: formatColor(t.customization_info?t.customization_info.outgoing_bubble_color:null),
105
116
  nicknames: mapNicknames(t.customization_info),
106
117
  muteUntil: t.mute_until,
107
118
  participants: formatParticipants(t.all_participants),
@@ -112,7 +123,7 @@ function formatThreadList(data) {
112
123
  // isPinProtected: t.is_pin_protected, // feature from future? always false (2018-04-04)
113
124
  customizationEnabled: t.customization_enabled, // false for ONE_TO_ONE with Page or ReducedMessagingActor
114
125
  participantAddMode: t.participant_add_mode_as_string, // "ADD" if "GROUP" and null if "ONE_TO_ONE"
115
- montageThread: t.montage_thread ? Buffer.from(t.montage_thread.id, "base64").toString() : null, // base64 encoded string "message_thread:0000000000000000"
126
+ montageThread: t.montage_thread?Buffer.from(t.montage_thread.id,"base64").toString():null, // base64 encoded string "message_thread:0000000000000000"
116
127
  // it is not userID nor any other ID known to me...
117
128
  // can somebody inspect it? where is it used?
118
129
  // probably Messenger Day uses it
@@ -123,13 +134,13 @@ function formatThreadList(data) {
123
134
  timestamp: t.updated_time_precise, // in miliseconds
124
135
  // isCanonicalUser: t.is_canonical_neo_user, // is it always false?
125
136
  // TODO: how about putting snippet in another object? current implementation does not handle every possibile message type etc.
126
- snippet: lastMessageNode ? lastMessageNode.snippet : null,
127
- snippetAttachments: lastMessageNode ? lastMessageNode.extensible_attachment : null, // TODO: not sure if it works
128
- snippetSender: lastMessageNode ? utils.formatID((lastMessageNode.message_sender.messaging_actor.id || "").toString()) : null,
129
- lastMessageTimestamp: lastMessageNode ? lastMessageNode.timestamp_precise : null, // timestamp in miliseconds
130
- lastReadTimestamp: (t.last_read_receipt && t.last_read_receipt.nodes.length > 0)
131
- ? (t.last_read_receipt.nodes[0] ? t.last_read_receipt.nodes[0].timestamp_precise : null)
132
- : null, // timestamp in miliseconds
137
+ snippet: lastMessageNode?lastMessageNode.snippet:null,
138
+ snippetAttachments: lastMessageNode?lastMessageNode.extensible_attachment:null, // TODO: not sure if it works
139
+ snippetSender: lastMessageNode?utils.formatID((lastMessageNode.message_sender.messaging_actor.id || "").toString()):null,
140
+ lastMessageTimestamp: lastMessageNode?lastMessageNode.timestamp_precise:null, // timestamp in miliseconds
141
+ lastReadTimestamp: (t.last_read_receipt&&t.last_read_receipt.nodes.length>0)
142
+ ? (t.last_read_receipt.nodes[0]?t.last_read_receipt.nodes[0].timestamp_precise:null)
143
+ : null, // timestamp in miliseconds
133
144
  cannotReplyReason: t.cannot_reply_reason, // TODO: inspect possible values
134
145
  approvalMode: Boolean(t.approval_mode),
135
146
 
@@ -140,21 +151,28 @@ function formatThreadList(data) {
140
151
  });
141
152
  }
142
153
 
143
- module.exports = function (defaultFuncs, api, ctx) {
154
+ module.exports = function(defaultFuncs, api, ctx) {
144
155
  return function getThreadList(limit, timestamp, tags, callback) {
145
156
  if (!callback && (utils.getType(tags) === "Function" || utils.getType(tags) === "AsyncFunction")) {
146
157
  callback = tags;
147
158
  tags = [""];
148
159
  }
149
- if (utils.getType(limit) !== "Number" || !Number.isInteger(limit) || limit <= 0) throw { error: "getThreadList: limit must be a positive integer" };
150
-
151
- if (utils.getType(timestamp) !== "Null" && (utils.getType(timestamp) !== "Number" || !Number.isInteger(timestamp))) throw { error: "getThreadList: timestamp must be an integer or null" };
152
-
153
- if (utils.getType(tags) === "String") tags = [tags];
154
- if (utils.getType(tags) !== "Array") throw { error: "getThreadList: tags must be an array" };
160
+ if (utils.getType(limit) !== "Number" || !Number.isInteger(limit) || limit <= 0) {
161
+ throw {error: "getThreadList: limit must be a positive integer"};
162
+ }
163
+ if (utils.getType(timestamp) !== "Null" &&
164
+ (utils.getType(timestamp) !== "Number" || !Number.isInteger(timestamp))) {
165
+ throw {error: "getThreadList: timestamp must be an integer or null"};
166
+ }
167
+ if (utils.getType(tags) === "String") {
168
+ tags = [tags];
169
+ }
170
+ if (utils.getType(tags) !== "Array") {
171
+ throw {error: "getThreadList: tags must be an array"};
172
+ }
155
173
 
156
- var resolveFunc = function () { };
157
- var rejectFunc = function () { };
174
+ var resolveFunc = function(){};
175
+ var rejectFunc = function(){};
158
176
  var returnPromise = new Promise(function (resolve, reject) {
159
177
  resolveFunc = resolve;
160
178
  rejectFunc = reject;
@@ -162,7 +180,9 @@ module.exports = function (defaultFuncs, api, ctx) {
162
180
 
163
181
  if (utils.getType(callback) !== "Function" && utils.getType(callback) !== "AsyncFunction") {
164
182
  callback = function (err, data) {
165
- if (err) return rejectFunc(err);
183
+ if (err) {
184
+ return rejectFunc(err);
185
+ }
166
186
  resolveFunc(data);
167
187
  };
168
188
  }
@@ -174,7 +194,7 @@ module.exports = function (defaultFuncs, api, ctx) {
174
194
  // This doc_id was valid on 2020-07-20
175
195
  "doc_id": "3336396659757871",
176
196
  "query_params": {
177
- "limit": limit + (timestamp ? 1 : 0),
197
+ "limit": limit+(timestamp?1:0),
178
198
  "before": timestamp,
179
199
  "tags": tags,
180
200
  "includeDeliveryReceipts": true,
@@ -189,9 +209,13 @@ module.exports = function (defaultFuncs, api, ctx) {
189
209
  .post("https://www.facebook.com/api/graphqlbatch/", ctx.jar, form)
190
210
  .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
191
211
  .then((resData) => {
192
- if (resData[resData.length - 1].error_results > 0) throw resData[0].o0.errors;
212
+ if (resData[resData.length - 1].error_results > 0) {
213
+ throw resData[0].o0.errors;
214
+ }
193
215
 
194
- if (resData[resData.length - 1].successful_results === 0) throw { error: "getThreadList: there was no successful_results", res: resData };
216
+ if (resData[resData.length - 1].successful_results === 0) {
217
+ throw {error: "getThreadList: there was no successful_results", res: resData};
218
+ }
195
219
 
196
220
  // When we ask for threads using timestamp from the previous request,
197
221
  // we are getting the last thread repeated as the first thread in this response.
@@ -199,12 +223,13 @@ module.exports = function (defaultFuncs, api, ctx) {
199
223
  // It is also the reason for increasing limit by 1 when timestamp is set
200
224
  // this way user asks for 10 threads, we are asking for 11,
201
225
  // but after removing the duplicated one, it is again 10
202
- if (timestamp) resData[0].o0.data.viewer.message_threads.nodes.shift();
203
-
226
+ if (timestamp) {
227
+ resData[0].o0.data.viewer.message_threads.nodes.shift();
228
+ }
204
229
  callback(null, formatThreadList(resData[0].o0.data.viewer.message_threads.nodes));
205
230
  })
206
231
  .catch((err) => {
207
- log.error("getThreadList", "ParseAndCheckLogin got status code: 404. Bailing out of trying to parse response.");
232
+ log.error("getThreadList", err);
208
233
  return callback(err);
209
234
  });
210
235
 
@@ -0,0 +1,75 @@
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 getThreadList(start, end, type, callback) {
8
+ if (utils.getType(callback) === "Undefined") {
9
+ if (utils.getType(end) !== "Number") {
10
+ throw {
11
+ error: "Please pass a number as a second argument."
12
+ };
13
+ } else if (
14
+ utils.getType(type) === "Function" ||
15
+ utils.getType(type) === "AsyncFunction"
16
+ ) {
17
+ callback = type;
18
+ type = "inbox"; //default to inbox
19
+ } else if (utils.getType(type) !== "String") {
20
+ throw {
21
+ error:
22
+ "Please pass a String as a third argument. Your options are: inbox, pending, and archived"
23
+ };
24
+ } else {
25
+ throw {
26
+ error: "getThreadList: need callback"
27
+ };
28
+ }
29
+ }
30
+
31
+ if (type === "archived") {
32
+ type = "action:archived";
33
+ } else if (type !== "inbox" && type !== "pending" && type !== "other") {
34
+ throw {
35
+ error:
36
+ "type can only be one of the following: inbox, pending, archived, other"
37
+ };
38
+ }
39
+
40
+ if (end <= start) end = start + 20;
41
+
42
+ var form = {
43
+ client: "mercury"
44
+ };
45
+
46
+ form[type + "[offset]"] = start;
47
+ form[type + "[limit]"] = end - start;
48
+
49
+ if (ctx.globalOptions.pageID) {
50
+ form.request_user_id = ctx.globalOptions.pageID;
51
+ }
52
+
53
+ defaultFuncs
54
+ .post(
55
+ "https://www.facebook.com/ajax/mercury/threadlist_info.php",
56
+ ctx.jar,
57
+ form
58
+ )
59
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
60
+ .then(function(resData) {
61
+ if (resData.error) {
62
+ throw resData;
63
+ }
64
+ log.verbose("getThreadList", JSON.stringify(resData.payload.threads));
65
+ return callback(
66
+ null,
67
+ (resData.payload.threads || []).map(utils.formatThread)
68
+ );
69
+ })
70
+ .catch(function(err) {
71
+ log.error("getThreadList", err);
72
+ return callback(err);
73
+ });
74
+ };
75
+ };