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
package/alice/chat.js ADDED
@@ -0,0 +1,415 @@
1
+ "use strict";
2
+
3
+ var utils = require("../utils");
4
+ var log = require("npmlog");
5
+ var bluebird = require("bluebird");
6
+
7
+ var allowedProperties = {
8
+ attachment: true,
9
+ url: true,
10
+ sticker: true,
11
+ emoji: true,
12
+ emojiSize: true,
13
+ body: true,
14
+ mentions: true
15
+ };
16
+
17
+ module.exports = function(defaultFuncs, bot, ctx) {
18
+ function uploadAttachment(attachments, callback) {
19
+ var uploads = [];
20
+
21
+ // create an array of promises
22
+ for (var i = 0; i < attachments.length; i++) {
23
+ if (!utils.isReadableStream(attachments[i])) {
24
+ throw {
25
+ error:
26
+ "Attachment should be a readable stream and not " +
27
+ utils.getType(attachments[i]) +
28
+ "."
29
+ };
30
+ }
31
+
32
+ var form = {
33
+ upload_1024: attachments[i],
34
+ voice_clip: "true"
35
+ };
36
+
37
+ uploads.push(
38
+ defaultFuncs
39
+ .postFormData(
40
+ "https://upload.facebook.com/ajax/mercury/upload.php",
41
+ ctx.jar,
42
+ form,
43
+ {}
44
+ )
45
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
46
+ .then(function(resData) {
47
+ if (resData.error) {
48
+ throw resData;
49
+ }
50
+
51
+ // We have to return the data unformatted unless we want to change it
52
+ // back in sendMessage.
53
+ return resData.payload.metadata[0];
54
+ })
55
+ );
56
+ }
57
+
58
+ // resolve all promises
59
+ bluebird
60
+ .all(uploads)
61
+ .then(function(resData) {
62
+ callback(null, resData);
63
+ })
64
+ .catch(function(err) {
65
+ log.error("uploadAttachment", err);
66
+ return callback(err);
67
+ });
68
+ }
69
+
70
+ function getUrl(url, callback) {
71
+ var form = {
72
+ image_height: 960,
73
+ image_width: 960,
74
+ uri: url
75
+ };
76
+
77
+ defaultFuncs
78
+ .post(
79
+ "https://www.facebook.com/message_share_attachment/fromURI/",
80
+ ctx.jar,
81
+ form
82
+ )
83
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
84
+ .then(function(resData) {
85
+ if (resData.error) {
86
+ return callback(resData);
87
+ }
88
+
89
+ if (!resData.payload) {
90
+ return callback({ error: "Invalid url" });
91
+ }
92
+
93
+ callback(null, resData.payload.share_data.share_params);
94
+ })
95
+ .catch(function(err) {
96
+ log.error("getUrl", err);
97
+ return callback(err);
98
+ });
99
+ }
100
+
101
+ function sendContent(form, threadID, isSingleUser, messageAndOTID, callback) {
102
+ // There are three cases here:
103
+ // 1. threadID is of type array, where we're starting a new group chat with users
104
+ // specified in the array.
105
+ // 2. User is sending a message to a specific user.
106
+ // 3. No additional form params and the message goes to an existing group chat.
107
+ if (utils.getType(threadID) === "Array") {
108
+ for (var i = 0; i < threadID.length; i++) {
109
+ form["specific_to_list[" + i + "]"] = "fbid:" + threadID[i];
110
+ }
111
+ form["specific_to_list[" + threadID.length + "]"] = "fbid:" + ctx.userID;
112
+ form["client_thread_id"] = "root:" + messageAndOTID;
113
+ log.info("sendMessage", "Sending message to multiple users: " + threadID);
114
+ } else {
115
+ // This means that threadID is the id of a user, and the chat
116
+ // is a single person chat
117
+ if (isSingleUser) {
118
+ form["specific_to_list[0]"] = "fbid:" + threadID;
119
+ form["specific_to_list[1]"] = "fbid:" + ctx.userID;
120
+ form["other_user_fbid"] = threadID;
121
+ } else {
122
+ form["thread_fbid"] = threadID;
123
+ }
124
+ }
125
+
126
+ if (ctx.globalOptions.pageID) {
127
+ form["author"] = "fbid:" + ctx.globalOptions.pageID;
128
+ form["specific_to_list[1]"] = "fbid:" + ctx.globalOptions.pageID;
129
+ form["creator_info[creatorID]"] = ctx.userID;
130
+ form["creator_info[creatorType]"] = "direct_admin";
131
+ form["creator_info[labelType]"] = "sent_message";
132
+ form["creator_info[pageID]"] = ctx.globalOptions.pageID;
133
+ form["request_user_id"] = ctx.globalOptions.pageID;
134
+ form["creator_info[profileURI]"] =
135
+ "https://www.facebook.com/profile.php?id=" + ctx.userID;
136
+ }
137
+
138
+ defaultFuncs
139
+ .post("https://www.facebook.com/messaging/send/", ctx.jar, form)
140
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
141
+ .then(function(resData) {
142
+ if (!resData) {
143
+ return callback({ error: "Send message failed." });
144
+ }
145
+
146
+ if (resData.error) {
147
+ if (resData.error === 1545012) {
148
+ log.warn(
149
+ "sendMessage",
150
+ "Got error 1545012. This might mean that you're not part of the conversation " +
151
+ threadID
152
+ );
153
+ }
154
+ return callback(resData);
155
+ }
156
+
157
+ var messageInfo = resData.payload.actions.reduce(function(p, v) {
158
+ return (
159
+ {
160
+ threadID: v.thread_fbid,
161
+ messageID: v.message_id,
162
+ timestamp: v.timestamp
163
+ } || p
164
+ );
165
+ }, null);
166
+
167
+ return callback(null, messageInfo);
168
+ })
169
+ .catch(function(err) {
170
+ log.error("sendMessage", err);
171
+ return callback(err);
172
+ });
173
+ }
174
+
175
+ function send(form, threadID, messageAndOTID, callback) {
176
+ // We're doing a query to this to check if the given id is the id of
177
+ // a user or of a group chat. The form will be different depending
178
+ // on that.
179
+ if (utils.getType(threadID) === "Array") {
180
+ sendContent(form, threadID, false, messageAndOTID, callback);
181
+ } else {
182
+ sendContent(
183
+ form,
184
+ threadID,
185
+ threadID.length === 15,
186
+ messageAndOTID,
187
+ callback
188
+ );
189
+ }
190
+ }
191
+
192
+ function handleUrl(msg, form, callback, cb) {
193
+ if (msg.url) {
194
+ form["shareable_attachment[share_type]"] = "100";
195
+ getUrl(msg.url, function(err, params) {
196
+ if (err) {
197
+ return callback(err);
198
+ }
199
+
200
+ form["shareable_attachment[share_params]"] = params;
201
+ cb();
202
+ });
203
+ } else {
204
+ cb();
205
+ }
206
+ }
207
+
208
+ function handleSticker(msg, form, callback, cb) {
209
+ if (msg.sticker) {
210
+ form["sticker_id"] = msg.sticker;
211
+ }
212
+ cb();
213
+ }
214
+
215
+ function handleEmoji(msg, form, callback, cb) {
216
+ if (msg.emojiSize != null && msg.emoji == null) {
217
+ return callback({ error: "emoji property is empty" });
218
+ }
219
+ if (msg.emoji) {
220
+ if (msg.emojiSize == null) {
221
+ msg.emojiSize = "medium";
222
+ }
223
+ if (
224
+ msg.emojiSize != "small" &&
225
+ msg.emojiSize != "medium" &&
226
+ msg.emojiSize != "large"
227
+ ) {
228
+ return callback({ error: "emojiSize property is invalid" });
229
+ }
230
+ if (form["body"] != null && form["body"] != "") {
231
+ return callback({ error: "body is not empty" });
232
+ }
233
+ form["body"] = msg.emoji;
234
+ form["tags[0]"] = "hot_emoji_size:" + msg.emojiSize;
235
+ }
236
+ cb();
237
+ }
238
+
239
+ function handleAttachment(msg, form, callback, cb) {
240
+ if (msg.attachment) {
241
+ form["image_ids"] = [];
242
+ form["gif_ids"] = [];
243
+ form["file_ids"] = [];
244
+ form["video_ids"] = [];
245
+ form["audio_ids"] = [];
246
+
247
+ if (utils.getType(msg.attachment) !== "Array") {
248
+ msg.attachment = [msg.attachment];
249
+ }
250
+
251
+ uploadAttachment(msg.attachment, function(err, files) {
252
+ if (err) {
253
+ return callback(err);
254
+ }
255
+
256
+ files.forEach(function(file) {
257
+ var key = Object.keys(file);
258
+ var type = key[0]; // image_id, file_id, etc
259
+ form["" + type + "s"].push(file[type]); // push the id
260
+ });
261
+ cb();
262
+ });
263
+ } else {
264
+ cb();
265
+ }
266
+ }
267
+
268
+ function handleMention(msg, form, callback, cb) {
269
+ if (msg.mentions) {
270
+ for (let i = 0; i < msg.mentions.length; i++) {
271
+ const mention = msg.mentions[i];
272
+
273
+ const tag = mention.tag;
274
+ if (typeof tag !== "string") {
275
+ return callback({ error: "Mention tags must be strings." });
276
+ }
277
+
278
+ const offset = msg.body.indexOf(tag, mention.fromIndex || 0);
279
+
280
+ if (offset < 0) {
281
+ log.warn(
282
+ "handleMention",
283
+ 'Mention for "' + tag + '" not found in message string.'
284
+ );
285
+ }
286
+
287
+ if (mention.id == null) {
288
+ log.warn("handleMention", "Mention id should be non-null.");
289
+ }
290
+
291
+ const id = mention.id || 0;
292
+ form["profile_xmd[" + i + "][offset]"] = offset;
293
+ form["profile_xmd[" + i + "][length]"] = tag.length;
294
+ form["profile_xmd[" + i + "][id]"] = id;
295
+ form["profile_xmd[" + i + "][type]"] = "p";
296
+ }
297
+ }
298
+ cb();
299
+ }
300
+
301
+ return function sendMessage(msg, threadID, callback, replyToMessage) {
302
+ if (
303
+ !callback &&
304
+ (utils.getType(threadID) === "Function" ||
305
+ utils.getType(threadID) === "AsyncFunction")
306
+ ) {
307
+ return callback({ error: "Pass a threadID as a second argument." });
308
+ }
309
+ if (
310
+ !replyToMessage &&
311
+ utils.getType(callback) === "String"
312
+ ) {
313
+ replyToMessage = callback;
314
+ callback = function() {};
315
+ }
316
+
317
+ if (!callback) {
318
+ callback = function() {};
319
+ }
320
+
321
+ var msgType = utils.getType(msg);
322
+ var threadIDType = utils.getType(threadID);
323
+ var messageIDType = utils.getType(replyToMessage);
324
+
325
+ if (msgType !== "String" && msgType !== "Object") {
326
+ return callback({
327
+ error:
328
+ "Message should be of type string or object and not " + msgType + "."
329
+ });
330
+ }
331
+
332
+ // Changing this to accomodate an array of users
333
+ if (
334
+ threadIDType !== "Array" &&
335
+ threadIDType !== "Number" &&
336
+ threadIDType !== "String"
337
+ ) {
338
+ return callback({
339
+ error:
340
+ "ThreadID should be of type number, string, or array and not " +
341
+ threadIDType +
342
+ "."
343
+ });
344
+ }
345
+
346
+ if (replyToMessage && messageIDType !== 'String') {
347
+ return callback({
348
+ error:
349
+ "MessageID should be of type string and not " +
350
+ threadIDType +
351
+ "."
352
+ });
353
+ }
354
+
355
+ if (msgType === "String") {
356
+ msg = { body: msg };
357
+ }
358
+
359
+ var disallowedProperties = Object.keys(msg).filter(
360
+ prop => !allowedProperties[prop]
361
+ );
362
+ if (disallowedProperties.length > 0) {
363
+ return callback({
364
+ error: "Dissallowed props: `" + disallowedProperties.join(", ") + "`"
365
+ });
366
+ }
367
+
368
+ var messageAndOTID = utils.generateOfflineThreadingID();
369
+
370
+ var form = {
371
+ client: "mercury",
372
+ action_type: "ma-type:user-generated-message",
373
+ author: "fbid:" + ctx.userID,
374
+ timestamp: Date.now(),
375
+ timestamp_absolute: "Today",
376
+ timestamp_relative: utils.generateTimestampRelative(),
377
+ timestamp_time_passed: "0",
378
+ is_unread: false,
379
+ is_cleared: false,
380
+ is_forward: false,
381
+ is_filtered_content: false,
382
+ is_filtered_content_bh: false,
383
+ is_filtered_content_account: false,
384
+ is_filtered_content_quasar: false,
385
+ is_filtered_content_invalid_app: false,
386
+ is_spoof_warning: false,
387
+ source: "source:chat:web",
388
+ "source_tags[0]": "source:chat",
389
+ body: msg.body ? msg.body.toString() : "",
390
+ html_body: false,
391
+ ui_push_phase: "V3",
392
+ status: "0",
393
+ offline_threading_id: messageAndOTID,
394
+ message_id: messageAndOTID,
395
+ threading_id: utils.generateThreadingID(ctx.clientID),
396
+ "ephemeral_ttl_mode:": "0",
397
+ manual_retry_cnt: "0",
398
+ has_attachment: !!(msg.attachment || msg.url || msg.sticker),
399
+ signatureID: utils.getSignatureID(),
400
+ replied_to_message_id: replyToMessage
401
+ };
402
+
403
+ handleSticker(msg, form, callback, () =>
404
+ handleAttachment(msg, form, callback, () =>
405
+ handleUrl(msg, form, callback, () =>
406
+ handleEmoji(msg, form, callback, () =>
407
+ handleMention(msg, form, callback, () =>
408
+ send(form, threadID, messageAndOTID, callback)
409
+ )
410
+ )
411
+ )
412
+ )
413
+ );
414
+ };
415
+ };
package/alice/color.js ADDED
@@ -0,0 +1,53 @@
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 changeThreadColor(color, threadID, callback) {
8
+ if (!callback) {
9
+ callback = function() {};
10
+ }
11
+
12
+ var validatedColor = color !== null ? color.toLowerCase() : color; // API only accepts lowercase letters in hex string
13
+ var colorList = Object.keys(api.threadColors).map(function(name) {
14
+ return api.threadColors[name];
15
+ });
16
+ if (!colorList.includes(validatedColor)) {
17
+ throw {
18
+ error:
19
+ "The color you are trying to use is not a valid thread color. Use api.threadColors to find acceptable values."
20
+ };
21
+ }
22
+
23
+ var form = {
24
+ color_choice: validatedColor,
25
+ thread_or_other_fbid: threadID
26
+ };
27
+
28
+ defaultFuncs
29
+ .post(
30
+ "https://www.facebook.com/messaging/save_thread_color/?source=thread_settings&dpr=1",
31
+ ctx.jar,
32
+ form
33
+ )
34
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
35
+ .then(function(resData) {
36
+ if (resData.error === 1357031) {
37
+ throw {
38
+ error:
39
+ "Trying to change colors of a chat that doesn't exist. Have at least one message in the thread before trying to change the colors."
40
+ };
41
+ }
42
+ if (resData.error) {
43
+ throw resData;
44
+ }
45
+
46
+ return callback();
47
+ })
48
+ .catch(function(err) {
49
+ log.error("changeThreadColor", err);
50
+ return callback(err);
51
+ });
52
+ };
53
+ };
@@ -0,0 +1,43 @@
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 deleteThread(threadOrThreads, callback) {
8
+ if (!callback) {
9
+ callback = function() {};
10
+ }
11
+
12
+ var form = {
13
+ client: "mercury"
14
+ };
15
+
16
+ if (utils.getType(threadOrThreads) !== "Array") {
17
+ threadOrThreads = [threadOrThreads];
18
+ }
19
+
20
+ for (var i = 0; i < threadOrThreads.length; i++) {
21
+ form["ids[" + i + "]"] = threadOrThreads[i];
22
+ }
23
+
24
+ defaultFuncs
25
+ .post(
26
+ "https://www.facebook.com/ajax/mercury/delete_thread.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
+ }
35
+
36
+ return callback();
37
+ })
38
+ .catch(function(err) {
39
+ log.error("deleteThread", err);
40
+ return callback(err);
41
+ });
42
+ };
43
+ };
@@ -0,0 +1,43 @@
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 deleteMessage(messageOrMessages, callback) {
8
+ if (!callback) {
9
+ callback = function() {};
10
+ }
11
+
12
+ var form = {
13
+ client: "mercury"
14
+ };
15
+
16
+ if (utils.getType(messageOrMessages) !== "Array") {
17
+ messageOrMessages = [messageOrMessages];
18
+ }
19
+
20
+ for (var i = 0; i < messageOrMessages.length; i++) {
21
+ form["message_ids[" + i + "]"] = messageOrMessages[i];
22
+ }
23
+
24
+ defaultFuncs
25
+ .post(
26
+ "https://www.facebook.com/ajax/mercury/delete_messages.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
+ }
35
+
36
+ return callback();
37
+ })
38
+ .catch(function(err) {
39
+ log.error("deleteMessage", err);
40
+ return callback(err);
41
+ });
42
+ };
43
+ };
@@ -0,0 +1,41 @@
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 markAsDelivered(threadID, messageID, callback) {
8
+ if (!callback) {
9
+ callback = function () { };
10
+ }
11
+
12
+ if (!threadID || !messageID) {
13
+ return callback("Error: messageID or threadID is not defined");
14
+ }
15
+
16
+ var form = {};
17
+
18
+ form["message_ids[0]"] = messageID;
19
+ form["thread_ids[" + threadID + "][0]"] = messageID;
20
+
21
+ defaultFuncs
22
+ .post(
23
+ "https://www.facebook.com/ajax/mercury/delivery_receipts.php",
24
+ ctx.jar,
25
+ form
26
+ )
27
+ .then(utils.saveCookies(ctx.jar))
28
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
29
+ .then(function (resData) {
30
+ if (resData.error) {
31
+ throw resData;
32
+ }
33
+
34
+ return callback();
35
+ })
36
+ .catch(function (err) {
37
+ log.error("markAsDelivered", err);
38
+ return callback(err);
39
+ });
40
+ };
41
+ };
package/alice/emoji.js ADDED
@@ -0,0 +1,41 @@
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 changeThreadEmoji(emoji, threadID, callback) {
8
+ if (!callback) {
9
+ callback = function() {};
10
+ }
11
+ var form = {
12
+ emoji_choice: emoji,
13
+ thread_or_other_fbid: threadID
14
+ };
15
+
16
+ defaultFuncs
17
+ .post(
18
+ "https://www.facebook.com/messaging/save_thread_emoji/?source=thread_settings&__pc=EXP1%3Amessengerdotcom_pkg",
19
+ ctx.jar,
20
+ form
21
+ )
22
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
23
+ .then(function(resData) {
24
+ if (resData.error === 1357031) {
25
+ throw {
26
+ error:
27
+ "Trying to change emoji of a chat that doesn't exist. Have at least one message in the thread before trying to change the emoji."
28
+ };
29
+ }
30
+ if (resData.error) {
31
+ throw resData;
32
+ }
33
+
34
+ return callback();
35
+ })
36
+ .catch(function(err) {
37
+ log.error("changeThreadEmoji", err);
38
+ return callback(err);
39
+ });
40
+ };
41
+ };
@@ -0,0 +1,29 @@
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++) {
23
+ base = (base << 5) - base + ending.charCodeAt(i);
24
+ }
25
+
26
+ let hashed = (base & 255).toString(16);
27
+ return util.format(baseUrl, hashed, ending);
28
+ };
29
+ };