alicezetion 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- package/.cache/replit/__replit_disk_meta.json +1 -0
- package/.cache/replit/modules.stamp +0 -0
- package/.cache/replit/nix/env.json +1 -0
- package/.travis.yml +6 -0
- package/README.md +40 -0
- package/alice/add.js +99 -0
- package/alice/admin.js +65 -0
- package/alice/archive.js +41 -0
- package/alice/block.js +72 -0
- package/alice/chat.js +415 -0
- package/alice/color.js +53 -0
- package/alice/deletegc.js +43 -0
- package/alice/deletemsg.js +43 -0
- package/alice/delivered.js +41 -0
- package/alice/emoji.js +41 -0
- package/alice/emojiurl.js +29 -0
- package/alice/forward.js +47 -0
- package/alice/friend.js +70 -0
- package/alice/gchistorydeprecated.js +76 -0
- package/alice/gcimage.js +115 -0
- package/alice/gcimg.js +66 -0
- package/alice/gcinfo.js +170 -0
- package/alice/gcinfodeprecated.js +65 -0
- package/alice/gclist.js +220 -0
- package/alice/gclistdeprecated.js +75 -0
- package/alice/gcolor.js +22 -0
- package/alice/gcsearch.js +39 -0
- package/alice/history.js +632 -0
- package/alice/id.js +7 -0
- package/alice/kick.js +65 -0
- package/alice/listen.js +553 -0
- package/alice/listenMqtt.js +560 -0
- package/alice/logout.js +59 -0
- package/alice/msgrequest.js +51 -0
- package/alice/mute.js +38 -0
- package/alice/nickname.js +44 -0
- package/alice/poll.js +55 -0
- package/alice/react.js +82 -0
- package/alice/read.js +52 -0
- package/alice/resolveimgurl.js +31 -0
- package/alice/seen.js +36 -0
- package/alice/title.js +73 -0
- package/alice/typeindicator.js +77 -0
- package/alice/unsend.js +35 -0
- package/alice/userid.js +52 -0
- package/alice/userinfo.js +57 -0
- package/index.js +423 -0
- package/package.json +70 -0
- package/utils.js +1283 -0
package/alice/forward.js
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
var utils = require("../utils");
|
4
|
+
var log = require("npmlog");
|
5
|
+
|
6
|
+
module.exports = function(defaultFuncs, bot, ctx) {
|
7
|
+
return function forwardAttachment(attachmentID, userOrUsers, callback) {
|
8
|
+
if (!callback) {
|
9
|
+
callback = function() {};
|
10
|
+
}
|
11
|
+
|
12
|
+
var form = {
|
13
|
+
attachment_id: attachmentID
|
14
|
+
};
|
15
|
+
|
16
|
+
if (utils.getType(userOrUsers) !== "Array") {
|
17
|
+
userOrUsers = [userOrUsers];
|
18
|
+
}
|
19
|
+
|
20
|
+
var timestamp = Math.floor(Date.now() / 1000);
|
21
|
+
|
22
|
+
for (var i = 0; i < userOrUsers.length; i++) {
|
23
|
+
//That's good, the key of the array is really timestmap in seconds + index
|
24
|
+
//Probably time when the attachment will be sent?
|
25
|
+
form["recipient_map[" + (timestamp + i) + "]"] = userOrUsers[i];
|
26
|
+
}
|
27
|
+
|
28
|
+
defaultFuncs
|
29
|
+
.post(
|
30
|
+
"https://www.facebook.com/mercury/attachments/forward/",
|
31
|
+
ctx.jar,
|
32
|
+
form
|
33
|
+
)
|
34
|
+
.then(utils.parseAndCheckLogin(ctx.jar, defaultFuncs))
|
35
|
+
.then(function(resData) {
|
36
|
+
if (resData.error) {
|
37
|
+
throw resData;
|
38
|
+
}
|
39
|
+
|
40
|
+
return callback(null);
|
41
|
+
})
|
42
|
+
.catch(function(err) {
|
43
|
+
log.error("forwardAttachment", err);
|
44
|
+
return callback(err);
|
45
|
+
});
|
46
|
+
};
|
47
|
+
};
|
package/alice/friend.js
ADDED
@@ -0,0 +1,70 @@
|
|
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, bot, ctx) {
|
43
|
+
return function getFriendsList(callback) {
|
44
|
+
if (!callback) {
|
45
|
+
throw { error: "getFriendsList: need callback" };
|
46
|
+
}
|
47
|
+
|
48
|
+
defaultFuncs
|
49
|
+
.postFormData(
|
50
|
+
"https://www.facebook.com/chat/user_info_all",
|
51
|
+
ctx.jar,
|
52
|
+
{},
|
53
|
+
{ viewer: ctx.userID }
|
54
|
+
)
|
55
|
+
.then(utils.parseAndCheckLogin(ctx, defaultFuncs))
|
56
|
+
.then(function(resData) {
|
57
|
+
if (!resData) {
|
58
|
+
throw { error: "getFriendsList returned empty object." };
|
59
|
+
}
|
60
|
+
if (resData.error) {
|
61
|
+
throw resData;
|
62
|
+
}
|
63
|
+
callback(null, formatData(resData.payload));
|
64
|
+
})
|
65
|
+
.catch(function(err) {
|
66
|
+
log.error("getFriendsList", err);
|
67
|
+
return callback(err);
|
68
|
+
});
|
69
|
+
};
|
70
|
+
};
|
@@ -0,0 +1,76 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
var utils = require("../utils");
|
4
|
+
var log = require("npmlog");
|
5
|
+
|
6
|
+
module.exports = function(defaultFuncs, bot, ctx) {
|
7
|
+
return function getThreadHistory(threadID, amount, timestamp, callback) {
|
8
|
+
if (!callback) {
|
9
|
+
throw { error: "getThreadHistory: need callback" };
|
10
|
+
}
|
11
|
+
|
12
|
+
var form = {
|
13
|
+
client: "mercury"
|
14
|
+
};
|
15
|
+
|
16
|
+
api.getUserInfo(threadID, function(err, res) {
|
17
|
+
if (err) {
|
18
|
+
return callback(err);
|
19
|
+
}
|
20
|
+
var key = Object.keys(res).length > 0 ? "user_ids" : "thread_fbids";
|
21
|
+
form["messages[" + key + "][" + threadID + "][offset]"] = 0;
|
22
|
+
form["messages[" + key + "][" + threadID + "][timestamp]"] = timestamp;
|
23
|
+
form["messages[" + key + "][" + threadID + "][limit]"] = amount;
|
24
|
+
|
25
|
+
if (ctx.globalOptions.pageID)
|
26
|
+
form.request_user_id = ctx.globalOptions.pageID;
|
27
|
+
|
28
|
+
defaultFuncs
|
29
|
+
.post(
|
30
|
+
"https://www.facebook.com/ajax/mercury/thread_info.php",
|
31
|
+
ctx.jar,
|
32
|
+
form
|
33
|
+
)
|
34
|
+
.then(utils.parseAndCheckLogin(ctx, defaultFuncs))
|
35
|
+
.then(function(resData) {
|
36
|
+
if (resData.error) {
|
37
|
+
throw resData;
|
38
|
+
} else if (!resData.payload) {
|
39
|
+
throw { error: "Could not retrieve thread history." };
|
40
|
+
}
|
41
|
+
|
42
|
+
// Asking for message history from a thread with no message history
|
43
|
+
// will return undefined for actions here
|
44
|
+
if (!resData.payload.actions) {
|
45
|
+
resData.payload.actions = [];
|
46
|
+
}
|
47
|
+
|
48
|
+
var userIDs = {};
|
49
|
+
resData.payload.actions.forEach(function(v) {
|
50
|
+
userIDs[v.author.split(":").pop()] = "";
|
51
|
+
});
|
52
|
+
|
53
|
+
api.getUserInfo(Object.keys(userIDs), function(err, data) {
|
54
|
+
if (err) return callback(err); //callback({error: "Could not retrieve user information in getThreadHistory."});
|
55
|
+
|
56
|
+
resData.payload.actions.forEach(function(v) {
|
57
|
+
var sender = data[v.author.split(":").pop()];
|
58
|
+
if (sender) v.sender_name = sender.name;
|
59
|
+
else v.sender_name = "Facebook User";
|
60
|
+
v.sender_fbid = v.author;
|
61
|
+
delete v.author;
|
62
|
+
});
|
63
|
+
|
64
|
+
callback(
|
65
|
+
null,
|
66
|
+
resData.payload.actions.map(utils.formatHistoryMessage)
|
67
|
+
);
|
68
|
+
});
|
69
|
+
})
|
70
|
+
.catch(function(err) {
|
71
|
+
log.error("getThreadHistory", err);
|
72
|
+
return callback(err);
|
73
|
+
});
|
74
|
+
});
|
75
|
+
};
|
76
|
+
};
|
package/alice/gcimage.js
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
var utils = require("../utils");
|
4
|
+
var log = require("npmlog");
|
5
|
+
var bluebird = require("bluebird");
|
6
|
+
|
7
|
+
module.exports = function(defaultFuncs, bot, ctx) {
|
8
|
+
function handleUpload(image, callback) {
|
9
|
+
var uploads = [];
|
10
|
+
|
11
|
+
var form = {
|
12
|
+
images_only: "true",
|
13
|
+
"attachment[]": image
|
14
|
+
};
|
15
|
+
|
16
|
+
uploads.push(
|
17
|
+
defaultFuncs
|
18
|
+
.postFormData(
|
19
|
+
"https://upload.facebook.com/ajax/mercury/upload.php",
|
20
|
+
ctx.jar,
|
21
|
+
form,
|
22
|
+
{}
|
23
|
+
)
|
24
|
+
.then(utils.parseAndCheckLogin(ctx, defaultFuncs))
|
25
|
+
.then(function(resData) {
|
26
|
+
if (resData.error) {
|
27
|
+
throw resData;
|
28
|
+
}
|
29
|
+
|
30
|
+
return resData.payload.metadata[0];
|
31
|
+
})
|
32
|
+
);
|
33
|
+
|
34
|
+
// resolve all promises
|
35
|
+
bluebird
|
36
|
+
.all(uploads)
|
37
|
+
.then(function(resData) {
|
38
|
+
callback(null, resData);
|
39
|
+
})
|
40
|
+
.catch(function(err) {
|
41
|
+
log.error("handleUpload", err);
|
42
|
+
return callback(err);
|
43
|
+
});
|
44
|
+
}
|
45
|
+
|
46
|
+
return function changeGroupImage(image, threadID, callback) {
|
47
|
+
if (
|
48
|
+
!callback &&
|
49
|
+
(utils.getType(threadID) === "Function" ||
|
50
|
+
utils.getType(threadID) === "AsyncFunction")
|
51
|
+
) {
|
52
|
+
throw { error: "please pass a threadID as a second argument." };
|
53
|
+
}
|
54
|
+
|
55
|
+
if (!callback) {
|
56
|
+
callback = function() {};
|
57
|
+
}
|
58
|
+
|
59
|
+
var messageAndOTID = utils.generateOfflineThreadingID();
|
60
|
+
var form = {
|
61
|
+
client: "mercury",
|
62
|
+
action_type: "ma-type:log-message",
|
63
|
+
author: "fbid:" + ctx.userID,
|
64
|
+
author_email: "",
|
65
|
+
ephemeral_ttl_mode: "0",
|
66
|
+
is_filtered_content: false,
|
67
|
+
is_filtered_content_account: false,
|
68
|
+
is_filtered_content_bh: false,
|
69
|
+
is_filtered_content_invalid_app: false,
|
70
|
+
is_filtered_content_quasar: false,
|
71
|
+
is_forward: false,
|
72
|
+
is_spoof_warning: false,
|
73
|
+
is_unread: false,
|
74
|
+
log_message_type: "log:thread-image",
|
75
|
+
manual_retry_cnt: "0",
|
76
|
+
message_id: messageAndOTID,
|
77
|
+
offline_threading_id: messageAndOTID,
|
78
|
+
source: "source:chat:web",
|
79
|
+
"source_tags[0]": "source:chat",
|
80
|
+
status: "0",
|
81
|
+
thread_fbid: threadID,
|
82
|
+
thread_id: "",
|
83
|
+
timestamp: Date.now(),
|
84
|
+
timestamp_absolute: "Today",
|
85
|
+
timestamp_relative: utils.generateTimestampRelative(),
|
86
|
+
timestamp_time_passed: "0"
|
87
|
+
};
|
88
|
+
|
89
|
+
handleUpload(image, function(err, payload) {
|
90
|
+
if (err) {
|
91
|
+
return callback(err);
|
92
|
+
}
|
93
|
+
|
94
|
+
form["thread_image_id"] = payload[0]["image_id"];
|
95
|
+
form["thread_id"] = threadID;
|
96
|
+
|
97
|
+
defaultFuncs
|
98
|
+
.post("https://www.facebook.com/messaging/set_thread_image/", ctx.jar, form)
|
99
|
+
.then(utils.parseAndCheckLogin(ctx, defaultFuncs))
|
100
|
+
.then(function(resData) {
|
101
|
+
// check for errors here
|
102
|
+
|
103
|
+
if (resData.error) {
|
104
|
+
throw resData;
|
105
|
+
}
|
106
|
+
|
107
|
+
return callback();
|
108
|
+
})
|
109
|
+
.catch(function(err) {
|
110
|
+
log.error("changeGroupImage", err);
|
111
|
+
return callback(err);
|
112
|
+
});
|
113
|
+
});
|
114
|
+
};
|
115
|
+
};
|
package/alice/gcimg.js
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
var utils = require("../utils");
|
4
|
+
var log = require("npmlog");
|
5
|
+
|
6
|
+
module.exports = function(defaultFuncs, bot, ctx) {
|
7
|
+
return function getThreadPictures(threadID, offset, limit, callback) {
|
8
|
+
if (!callback) {
|
9
|
+
throw { error: "getThreadPictures: need callback" };
|
10
|
+
}
|
11
|
+
|
12
|
+
var form = {
|
13
|
+
thread_id: threadID,
|
14
|
+
offset: offset,
|
15
|
+
limit: limit
|
16
|
+
};
|
17
|
+
|
18
|
+
defaultFuncs
|
19
|
+
.post(
|
20
|
+
"https://www.facebook.com/ajax/messaging/attachments/sharedphotos.php",
|
21
|
+
ctx.jar,
|
22
|
+
form
|
23
|
+
)
|
24
|
+
.then(utils.parseAndCheckLogin(ctx, defaultFuncs))
|
25
|
+
.then(function(resData) {
|
26
|
+
if (resData.error) {
|
27
|
+
throw resData;
|
28
|
+
}
|
29
|
+
return Promise.all(
|
30
|
+
resData.payload.imagesData.map(function(image) {
|
31
|
+
form = {
|
32
|
+
thread_id: threadID,
|
33
|
+
image_id: image.fbid
|
34
|
+
};
|
35
|
+
return defaultFuncs
|
36
|
+
.post(
|
37
|
+
"https://www.facebook.com/ajax/messaging/attachments/sharedphotos.php",
|
38
|
+
ctx.jar,
|
39
|
+
form
|
40
|
+
)
|
41
|
+
.then(utils.parseAndCheckLogin(ctx, defaultFuncs))
|
42
|
+
.then(function(resData) {
|
43
|
+
if (resData.error) {
|
44
|
+
throw resData;
|
45
|
+
}
|
46
|
+
// the response is pretty messy
|
47
|
+
var queryThreadID =
|
48
|
+
resData.jsmods.require[0][3][1].query_metadata.query_path[0]
|
49
|
+
.message_thread;
|
50
|
+
var imageData =
|
51
|
+
resData.jsmods.require[0][3][1].query_results[queryThreadID]
|
52
|
+
.message_images.edges[0].node.image2;
|
53
|
+
return imageData;
|
54
|
+
});
|
55
|
+
})
|
56
|
+
);
|
57
|
+
})
|
58
|
+
.then(function(resData) {
|
59
|
+
callback(null, resData);
|
60
|
+
})
|
61
|
+
.catch(function(err) {
|
62
|
+
log.error("Error in getThreadPictures", err);
|
63
|
+
callback(err);
|
64
|
+
});
|
65
|
+
};
|
66
|
+
};
|
package/alice/gcinfo.js
ADDED
@@ -0,0 +1,170 @@
|
|
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
|
36
|
+
? messageThread.thread_key.thread_fbid
|
37
|
+
: messageThread.thread_key.other_user_id;
|
38
|
+
|
39
|
+
// Remove me
|
40
|
+
var lastM = messageThread.last_message;
|
41
|
+
var snippetID =
|
42
|
+
lastM &&
|
43
|
+
lastM.nodes &&
|
44
|
+
lastM.nodes[0] &&
|
45
|
+
lastM.nodes[0].message_sender &&
|
46
|
+
lastM.nodes[0].message_sender.messaging_actor
|
47
|
+
? lastM.nodes[0].message_sender.messaging_actor.id
|
48
|
+
: null;
|
49
|
+
var snippetText =
|
50
|
+
lastM && lastM.nodes && lastM.nodes[0] ? lastM.nodes[0].snippet : null;
|
51
|
+
var lastR = messageThread.last_read_receipt;
|
52
|
+
var lastReadTimestamp =
|
53
|
+
lastR && lastR.nodes && lastR.nodes[0] && lastR.nodes[0].timestamp_precise
|
54
|
+
? lastR.nodes[0].timestamp_precise
|
55
|
+
: null;
|
56
|
+
|
57
|
+
return {
|
58
|
+
threadID: threadID,
|
59
|
+
threadName: messageThread.name,
|
60
|
+
participantIDs: messageThread.all_participants.nodes.map(function(d) {
|
61
|
+
return d.messaging_actor.id;
|
62
|
+
}),
|
63
|
+
unreadCount: messageThread.unread_count,
|
64
|
+
messageCount: messageThread.messages_count,
|
65
|
+
timestamp: messageThread.updated_time_precise,
|
66
|
+
muteUntil: messageThread.mute_until,
|
67
|
+
isGroup: messageThread.thread_type == "GROUP",
|
68
|
+
isSubscribed: messageThread.is_viewer_subscribed,
|
69
|
+
isArchived: messageThread.has_viewer_archived,
|
70
|
+
folder: messageThread.folder,
|
71
|
+
cannotReplyReason: messageThread.cannot_reply_reason,
|
72
|
+
eventReminders: messageThread.event_reminders
|
73
|
+
? messageThread.event_reminders.nodes.map(formatEventReminders)
|
74
|
+
: null,
|
75
|
+
emoji: messageThread.customization_info
|
76
|
+
? messageThread.customization_info.emoji
|
77
|
+
: null,
|
78
|
+
color:
|
79
|
+
messageThread.customization_info &&
|
80
|
+
messageThread.customization_info.outgoing_bubble_color
|
81
|
+
? messageThread.customization_info.outgoing_bubble_color.slice(2)
|
82
|
+
: null,
|
83
|
+
nicknames:
|
84
|
+
messageThread.customization_info &&
|
85
|
+
messageThread.customization_info.participant_customizations
|
86
|
+
? messageThread.customization_info.participant_customizations.reduce(
|
87
|
+
function(res, val) {
|
88
|
+
if (val.nickname) res[val.participant_id] = val.nickname;
|
89
|
+
return res;
|
90
|
+
},
|
91
|
+
{}
|
92
|
+
)
|
93
|
+
: {},
|
94
|
+
adminIDs: messageThread.thread_admins,
|
95
|
+
|
96
|
+
// @Undocumented
|
97
|
+
topEmojis: messageThread.top_emojis,
|
98
|
+
reactionsMuteMode: messageThread.reactions_mute_mode.toLowerCase(),
|
99
|
+
mentionsMuteMode: messageThread.mentions_mute_mode.toLowerCase(),
|
100
|
+
isPinProtected: messageThread.is_pin_protected,
|
101
|
+
relatedPageThread: messageThread.related_page_thread,
|
102
|
+
|
103
|
+
// @Legacy
|
104
|
+
name: messageThread.name,
|
105
|
+
snippet: snippetText,
|
106
|
+
snippetSender: snippetID,
|
107
|
+
snippetAttachments: [],
|
108
|
+
serverTimestamp: messageThread.updated_time_precise,
|
109
|
+
imageSrc: messageThread.image ? messageThread.image.uri : null,
|
110
|
+
isCanonicalUser: messageThread.is_canonical_neo_user,
|
111
|
+
isCanonical: messageThread.thread_type != "GROUP",
|
112
|
+
recipientsLoadable: true,
|
113
|
+
hasEmailParticipant: false,
|
114
|
+
readOnly: false,
|
115
|
+
canReply: messageThread.cannot_reply_reason == null,
|
116
|
+
lastMessageTimestamp: messageThread.last_message
|
117
|
+
? messageThread.last_message.timestamp_precise
|
118
|
+
: null,
|
119
|
+
lastMessageType: "message",
|
120
|
+
lastReadTimestamp: lastReadTimestamp,
|
121
|
+
threadType: messageThread.thread_type == "GROUP" ? 2 : 1
|
122
|
+
};
|
123
|
+
}
|
124
|
+
|
125
|
+
module.exports = function(defaultFuncs, bot, ctx) {
|
126
|
+
return function getThreadInfoGraphQL(threadID, callback) {
|
127
|
+
if (!callback) {
|
128
|
+
throw { error: "getThreadInfoGraphQL: need callback" };
|
129
|
+
}
|
130
|
+
|
131
|
+
// `queries` has to be a string. I couldn't tell from the dev console. This
|
132
|
+
// took me a really long time to figure out. I deserve a cookie for this.
|
133
|
+
var form = {
|
134
|
+
queries: JSON.stringify({
|
135
|
+
o0: {
|
136
|
+
// This doc_id is valid as of February 1st, 2018.
|
137
|
+
doc_id: "1498317363570230",
|
138
|
+
query_params: {
|
139
|
+
id: threadID,
|
140
|
+
message_limit: 0,
|
141
|
+
load_messages: 0,
|
142
|
+
load_read_receipts: false,
|
143
|
+
before: null
|
144
|
+
}
|
145
|
+
}
|
146
|
+
})
|
147
|
+
};
|
148
|
+
|
149
|
+
defaultFuncs
|
150
|
+
.post("https://www.facebook.com/api/graphqlbatch/", ctx.jar, form)
|
151
|
+
.then(utils.parseAndCheckLogin(ctx, defaultFuncs))
|
152
|
+
.then(function(resData) {
|
153
|
+
if (resData.error) {
|
154
|
+
throw resData;
|
155
|
+
}
|
156
|
+
// This returns us an array of things. The last one is the success /
|
157
|
+
// failure one.
|
158
|
+
// @TODO What do we do in this case?
|
159
|
+
if (resData[resData.length - 1].error_results !== 0) {
|
160
|
+
throw new Error("well darn there was an error_result");
|
161
|
+
}
|
162
|
+
|
163
|
+
callback(null, formatThreadGraphQLResponse(resData[0]));
|
164
|
+
})
|
165
|
+
.catch(function(err) {
|
166
|
+
log.error("getThreadInfoGraphQL", err);
|
167
|
+
return callback(err);
|
168
|
+
});
|
169
|
+
};
|
170
|
+
};
|
@@ -0,0 +1,65 @@
|
|
1
|
+
"use strict";
|
2
|
+
|
3
|
+
var utils = require("../utils");
|
4
|
+
var log = require("npmlog");
|
5
|
+
|
6
|
+
module.exports = function(defaultFuncs, bot, ctx) {
|
7
|
+
return function getThreadInfo(threadID, callback) {
|
8
|
+
if (!callback) callback = function() {};
|
9
|
+
|
10
|
+
var form = {
|
11
|
+
client: "mercury"
|
12
|
+
};
|
13
|
+
|
14
|
+
api.getUserInfo(threadID, function(err, userRes) {
|
15
|
+
if (err) {
|
16
|
+
return callback(err);
|
17
|
+
}
|
18
|
+
var key = Object.keys(userRes).length > 0 ? "user_ids" : "thread_fbids";
|
19
|
+
form["threads[" + key + "][0]"] = threadID;
|
20
|
+
|
21
|
+
if (ctx.globalOptions.pageId)
|
22
|
+
form.request_user_id = ctx.globalOptions.pageId;
|
23
|
+
|
24
|
+
defaultFuncs
|
25
|
+
.post(
|
26
|
+
"https://www.facebook.com/ajax/mercury/thread_info.php",
|
27
|
+
ctx.jar,
|
28
|
+
form
|
29
|
+
)
|
30
|
+
.then(utils.parseAndCheckLogin(ctx, defaultFuncs))
|
31
|
+
.then(function(resData) {
|
32
|
+
if (resData.error) {
|
33
|
+
throw resData;
|
34
|
+
} else if (!resData.payload) {
|
35
|
+
throw {
|
36
|
+
error: "Could not retrieve thread Info."
|
37
|
+
};
|
38
|
+
}
|
39
|
+
var threadData = resData.payload.threads[0];
|
40
|
+
var userData = userRes[threadID];
|
41
|
+
|
42
|
+
if (threadData == null) {
|
43
|
+
throw {
|
44
|
+
error: "ThreadData is null"
|
45
|
+
};
|
46
|
+
}
|
47
|
+
|
48
|
+
threadData.name =
|
49
|
+
userData != null && userData.name != null
|
50
|
+
? userData.name
|
51
|
+
: threadData.name;
|
52
|
+
threadData.image_src =
|
53
|
+
userData != null && userData.thumbSrc != null
|
54
|
+
? userData.thumbSrc
|
55
|
+
: threadData.image_src;
|
56
|
+
|
57
|
+
callback(null, utils.formatThread(threadData));
|
58
|
+
})
|
59
|
+
.catch(function(err) {
|
60
|
+
log.error("getThreadInfo", err);
|
61
|
+
return callback(err);
|
62
|
+
});
|
63
|
+
});
|
64
|
+
};
|
65
|
+
};
|