alicezetion 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (49) hide show
  1. package/.cache/replit/__replit_disk_meta.json +1 -0
  2. package/.cache/replit/modules.stamp +0 -0
  3. package/.cache/replit/nix/env.json +1 -0
  4. package/.travis.yml +6 -0
  5. package/README.md +40 -0
  6. package/alice/add.js +99 -0
  7. package/alice/admin.js +65 -0
  8. package/alice/archive.js +41 -0
  9. package/alice/block.js +72 -0
  10. package/alice/chat.js +415 -0
  11. package/alice/color.js +53 -0
  12. package/alice/deletegc.js +43 -0
  13. package/alice/deletemsg.js +43 -0
  14. package/alice/delivered.js +41 -0
  15. package/alice/emoji.js +41 -0
  16. package/alice/emojiurl.js +29 -0
  17. package/alice/forward.js +47 -0
  18. package/alice/friend.js +70 -0
  19. package/alice/gchistorydeprecated.js +76 -0
  20. package/alice/gcimage.js +115 -0
  21. package/alice/gcimg.js +66 -0
  22. package/alice/gcinfo.js +170 -0
  23. package/alice/gcinfodeprecated.js +65 -0
  24. package/alice/gclist.js +220 -0
  25. package/alice/gclistdeprecated.js +75 -0
  26. package/alice/gcolor.js +22 -0
  27. package/alice/gcsearch.js +39 -0
  28. package/alice/history.js +632 -0
  29. package/alice/id.js +7 -0
  30. package/alice/kick.js +65 -0
  31. package/alice/listen.js +553 -0
  32. package/alice/listenMqtt.js +560 -0
  33. package/alice/logout.js +59 -0
  34. package/alice/msgrequest.js +51 -0
  35. package/alice/mute.js +38 -0
  36. package/alice/nickname.js +44 -0
  37. package/alice/poll.js +55 -0
  38. package/alice/react.js +82 -0
  39. package/alice/read.js +52 -0
  40. package/alice/resolveimgurl.js +31 -0
  41. package/alice/seen.js +36 -0
  42. package/alice/title.js +73 -0
  43. package/alice/typeindicator.js +77 -0
  44. package/alice/unsend.js +35 -0
  45. package/alice/userid.js +52 -0
  46. package/alice/userinfo.js +57 -0
  47. package/index.js +423 -0
  48. package/package.json +70 -0
  49. package/utils.js +1283 -0
@@ -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
+ };
@@ -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
+ };
@@ -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
+ };
@@ -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
+ };