sourev1 0.0.1-security → 1.2.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of sourev1 might be problematic. Click here for more details.

Files changed (85) hide show
  1. package/CHANGELOG.md +2 -0
  2. package/DOCS.md +1738 -0
  3. package/Extra/Database/index.js +398 -0
  4. package/Extra/Database/methods.js +286 -0
  5. package/Extra/Database/test/test.js +23 -0
  6. package/Extra/ExtraAddons.js +213 -0
  7. package/Extra/ExtraFindUID.js +48 -0
  8. package/Extra/ExtraGetThread.js +1 -0
  9. package/Extra/ExtraTranslate.js +62 -0
  10. package/Extra/ExtraUptimeRobot.js +3 -0
  11. package/Extra/Src/Last-Run.js +48 -0
  12. package/LICENSE-MIT +21 -0
  13. package/Language/index.json +149 -0
  14. package/README.md +132 -3
  15. package/Settings/Location.json +24 -0
  16. package/StateCrypt.js +22 -0
  17. package/broadcast.js +38 -0
  18. package/index.js +1071 -0
  19. package/logger.js +20 -0
  20. package/package.json +83 -3
  21. package/src/Dev_ChangeUptimeStatus.js +27 -0
  22. package/src/Dev_CheckLogin.js +14 -0
  23. package/src/addExternalModule.js +16 -0
  24. package/src/addUserToGroup.js +78 -0
  25. package/src/changeAdminStatus.js +79 -0
  26. package/src/changeArchivedStatus.js +41 -0
  27. package/src/changeBio.js +65 -0
  28. package/src/changeBlockedStatus.js +36 -0
  29. package/src/changeGroupImage.js +106 -0
  30. package/src/changeNickname.js +45 -0
  31. package/src/changeThreadColor.js +62 -0
  32. package/src/changeThreadEmoji.js +42 -0
  33. package/src/createNewGroup.js +70 -0
  34. package/src/createPoll.js +60 -0
  35. package/src/deleteMessage.js +45 -0
  36. package/src/deleteThread.js +43 -0
  37. package/src/forwardAttachment.js +48 -0
  38. package/src/getAccessToken.js +32 -0
  39. package/src/getCurrentUserID.js +7 -0
  40. package/src/getEmojiUrl.js +27 -0
  41. package/src/getFriendsList.js +73 -0
  42. package/src/getMessage.js +80 -0
  43. package/src/getThreadHistory.js +537 -0
  44. package/src/getThreadHistoryDeprecated.js +71 -0
  45. package/src/getThreadInfo.js +191 -0
  46. package/src/getThreadInfoDeprecated.js +56 -0
  47. package/src/getThreadList.js +213 -0
  48. package/src/getThreadListDeprecated.js +46 -0
  49. package/src/getThreadPictures.js +59 -0
  50. package/src/getUID.js +52 -0
  51. package/src/getUserID.js +62 -0
  52. package/src/getUserInfo.js +65 -0
  53. package/src/getUserInfoV2.js +35 -0
  54. package/src/handleFriendRequest.js +46 -0
  55. package/src/handleMessageRequest.js +49 -0
  56. package/src/httpGet.js +49 -0
  57. package/src/httpPost.js +48 -0
  58. package/src/httpPostFormData.js +41 -0
  59. package/src/listenMqtt.js +678 -0
  60. package/src/logout.js +68 -0
  61. package/src/markAsDelivered.js +48 -0
  62. package/src/markAsRead.js +70 -0
  63. package/src/markAsReadAll.js +43 -0
  64. package/src/markAsSeen.js +51 -0
  65. package/src/muteThread.js +47 -0
  66. package/src/removeUserFromGroup.js +49 -0
  67. package/src/resolvePhotoUrl.js +37 -0
  68. package/src/searchForThread.js +43 -0
  69. package/src/sendMessage.js +334 -0
  70. package/src/sendTypingIndicator.js +80 -0
  71. package/src/setMessageReaction.js +109 -0
  72. package/src/setPostReaction.js +102 -0
  73. package/src/setTitle.js +74 -0
  74. package/src/threadColors.js +39 -0
  75. package/src/unfriend.js +43 -0
  76. package/src/unsendMessage.js +40 -0
  77. package/test/data/shareAttach.js +146 -0
  78. package/test/data/something.mov +0 -0
  79. package/test/data/test.png +0 -0
  80. package/test/data/test.txt +7 -0
  81. package/test/example-config.json +18 -0
  82. package/test/test-page.js +140 -0
  83. package/test/test.js +385 -0
  84. package/test/testv2.js +3 -0
  85. package/utils.js +1288 -0
@@ -0,0 +1,678 @@
1
+ /* eslint-disable no-redeclare */
2
+ "use strict";
3
+ var utils = require("../utils");
4
+ var log = require("npmlog");
5
+ var mqtt = require('mqtt');
6
+ var websocket = require('websocket-stream');
7
+ var HttpsProxyAgent = require('https-proxy-agent');
8
+ const EventEmitter = require('events');
9
+ var identity = function () { };
10
+ var form = {};
11
+ var getSeqID = function () { };
12
+
13
+ var topics = ["/legacy_web","/webrtc","/rtc_multi","/onevc","/br_sr","/sr_res","/t_ms","/thread_typing","/orca_typing_notifications","/notify_disconnect","/orca_presence","/inbox","/mercury", "/messaging_events", "/orca_message_notifications", "/pp","/webrtc_response"];
14
+
15
+ /* [ Noti ? ]
16
+ ! "/br_sr", //Notification
17
+ * => Need to publish /br_sr right after this
18
+
19
+ ! "/notify_disconnect",
20
+ * => Need to publish /messenger_sync_create_queue right after this
21
+
22
+ ! "/orca_presence",
23
+ * => Will receive /sr_res right here.
24
+ */
25
+
26
+ function listenMqtt(defaultFuncs, api, ctx, globalCallback) {
27
+ //Don't really know what this does but I think it's for the active state?
28
+ //TODO: Move to ctx when implemented
29
+ var chatOn = ctx.globalOptions.online;
30
+ var foreground = false;
31
+
32
+ var sessionID = Math.floor(Math.random() * 9007199254740991) + 1;
33
+ var username = {u: ctx.userID,s: sessionID,chat_on: chatOn,fg: foreground,d: utils.getGUID(),ct: "websocket",aid: "219994525426954", mqtt_sid: "",cp: 3,ecp: 10,st: [],pm: [],dc: "",no_auto_fg: true,gas: null,pack: []};
34
+ var cookies = ctx.jar.getCookies("https://www.facebook.com").join("; ");
35
+
36
+ var host;
37
+ if (ctx.mqttEndpoint) host = `${ctx.mqttEndpoint}&sid=${sessionID}`;
38
+ else if (ctx.region) host = `wss://edge-chat.facebook.com/chat?region=${ctx.region.toLocaleLowerCase()}&sid=${sessionID}`;
39
+ else host = `wss://edge-chat.facebook.com/chat?sid=${sessionID}`;
40
+
41
+ var options = {
42
+ clientId: "mqttwsclient",
43
+ protocolId: 'MQIsdp',
44
+ protocolVersion: 3,
45
+ username: JSON.stringify(username),
46
+ clean: true,
47
+ wsOptions: {
48
+ headers: {
49
+ 'Cookie': cookies,
50
+ 'Origin': 'https://www.facebook.com',
51
+ 'User-Agent': (ctx.globalOptions.userAgent || 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_2) AppleWebKit/600.3.18 (KHTML, like Gecko) Version/8.0.3'),
52
+ 'Referer': 'https://www.facebook.com/',
53
+ 'Host': new URL(host).hostname //'edge-chat.facebook.com'
54
+ },
55
+ origin: 'https://www.facebook.com',
56
+ protocolVersion: 13
57
+ },
58
+ keepalive: 60,
59
+ reschedulePings: true,
60
+ connectTimeout: 10000,
61
+ reconnectPeriod: 1000
62
+ };
63
+
64
+ if (typeof ctx.globalOptions.proxy != "undefined") {
65
+ var agent = new HttpsProxyAgent(ctx.globalOptions.proxy);
66
+ options.wsOptions.agent = agent;
67
+ }
68
+
69
+ ctx.mqttClient = new mqtt.Client(_ => websocket(host, options.wsOptions), options);
70
+
71
+ var mqttClient = ctx.mqttClient;
72
+
73
+ mqttClient.on('error', function (err) {
74
+ log.error("listenMqtt", err);
75
+ mqttClient.end();
76
+ if (ctx.globalOptions.autoReconnect) getSeqID();
77
+ else {
78
+ globalCallback({ type: "stop_listen", error: "Server Đã Sập - Auto Restart" }, null);
79
+ return process.exit(1);
80
+ }
81
+ });
82
+
83
+ mqttClient.on('connect', function () {
84
+
85
+ if (process.env.OnStatus == undefined) {
86
+ if (Number(global.Require.FastConfig.AutoRestartMinutes) == 0) {
87
+ // something
88
+ }
89
+ else if (Number(global.Require.FastConfig.AutoRestartMinutes < 10)) {
90
+ log.warn("AutoRestartMinutes","The number of minutes to automatically restart must be more than 10 minutes");
91
+ }
92
+ else if (Number(global.Require.FastConfig.AutoRestartMinutes) < 0) {
93
+ log.warn("AutoRestartMinutes","Invalid auto-restart minutes!");
94
+ }
95
+ else {
96
+ global.Require.logger(global.Require.getText.gettext(global.Require.Language.Src.AutoRestart,Number(global.Require.FastConfig.AutoRestartMinutes)));
97
+ setInterval(() => {
98
+ global.Require.logger(global.Require.Language.Src.OnRestart);
99
+ process.exit(1);
100
+ }, Number(global.Require.FastConfig.AutoRestartMinutes) * 60000);
101
+ }
102
+ require('../broadcast')({ api })();
103
+ process.env.OnStatus = true;
104
+ }
105
+
106
+ topics.forEach(topicsub => mqttClient.subscribe(topicsub));
107
+
108
+ var topic;
109
+ var queue = {
110
+ sync_api_version: 11,
111
+ max_deltas_able_to_process: 100,
112
+ delta_batch_size: 500,
113
+ encoding: "JSON",
114
+ entity_fbid: ctx.userID,
115
+ };
116
+
117
+ if (ctx.syncToken) {
118
+ topic = "/messenger_sync_get_diffs";
119
+ queue.last_seq_id = ctx.lastSeqId;
120
+ queue.sync_token = ctx.syncToken;
121
+ } else {
122
+ topic = "/messenger_sync_create_queue";
123
+ queue.initial_titan_sequence_id = ctx.lastSeqId;
124
+ queue.device_params = null;
125
+ }
126
+
127
+ mqttClient.publish(topic, JSON.stringify(queue), { qos: 1, retain: false });
128
+
129
+ // set status online
130
+ // fix by NTKhang
131
+ mqttClient.publish("/foreground_state", JSON.stringify({"foreground": chatOn}), {qos: 1});
132
+
133
+ var rTimeout = setTimeout(function () {
134
+ mqttClient.end();
135
+ getSeqID();
136
+ }, 3000);
137
+
138
+ ctx.tmsWait = function () {
139
+ clearTimeout(rTimeout);
140
+ ctx.globalOptions.emitReady ? globalCallback({type: "ready",error: null}) : '';
141
+ delete ctx.tmsWait;
142
+ };
143
+ });
144
+
145
+ mqttClient.on('message', function (topic, message, _packet) {
146
+ const jsonMessage = JSON.parse(message.toString());
147
+ if (topic === "/t_ms") {
148
+ if (ctx.tmsWait && typeof ctx.tmsWait == "function") ctx.tmsWait();
149
+
150
+ if (jsonMessage.firstDeltaSeqId && jsonMessage.syncToken) {
151
+ ctx.lastSeqId = jsonMessage.firstDeltaSeqId;
152
+ ctx.syncToken = jsonMessage.syncToken;
153
+ }
154
+
155
+ if (jsonMessage.lastIssuedSeqId) ctx.lastSeqId = parseInt(jsonMessage.lastIssuedSeqId);
156
+
157
+ //If it contains more than 1 delta
158
+ for (var i in jsonMessage.deltas) {
159
+ var delta = jsonMessage.deltas[i];
160
+ parseDelta(defaultFuncs, api, ctx, globalCallback, { "delta": delta });
161
+ }
162
+ } else if (topic === "/thread_typing" || topic === "/orca_typing_notifications") {
163
+ var typ = {
164
+ type: "typ",
165
+ isTyping: !!jsonMessage.state,
166
+ from: jsonMessage.sender_fbid.toString(),
167
+ threadID: utils.formatID((jsonMessage.thread || jsonMessage.sender_fbid).toString())
168
+ };
169
+ (function () { globalCallback(null, typ); })();
170
+ } else if (topic === "/orca_presence") {
171
+ if (!ctx.globalOptions.updatePresence) {
172
+ for (var i in jsonMessage.list) {
173
+ var data = jsonMessage.list[i];
174
+ var userID = data["u"];
175
+
176
+ var presence = {
177
+ type: "presence",
178
+ userID: userID.toString(),
179
+ //Convert to ms
180
+ timestamp: data["l"] * 1000,
181
+ statuses: data["p"]
182
+ };
183
+ (function () { globalCallback(null, presence); })();
184
+ }
185
+ }
186
+ }
187
+
188
+ });
189
+
190
+ process.on('SIGINT', function () {
191
+ LogUptime();process.kill(process.pid);
192
+ });
193
+
194
+ process.on('exit', (code) => {
195
+ LogUptime();
196
+ });
197
+
198
+ mqttClient.on('close', function () {
199
+
200
+ });
201
+
202
+ mqttClient.on('disconnect',function () {
203
+ process.exit(1);
204
+ })
205
+ }
206
+
207
+ function LogUptime() {
208
+ var uptime = process.uptime();
209
+ var { join } = require('path');
210
+ if (global.Require.fs.existsSync(join(__dirname, '../CountTime.json'))) {
211
+ var Time1 = (Number(global.Require.fs.readFileSync(join(__dirname, '../CountTime.json'), 'utf8')) || 0);
212
+ global.Require.fs.writeFileSync(join(__dirname, '../CountTime.json'), String(Number(uptime) + Time1), 'utf8');
213
+ }
214
+ else {
215
+ var Time1 = 0;
216
+ global.Require.fs.writeFileSync(join(__dirname, '../CountTime.json'), String(Number(uptime) + Time1), 'utf8');
217
+ }
218
+ }
219
+ function parseDelta(defaultFuncs, api, ctx, globalCallback, v) {
220
+ if (v.delta.class == "NewMessage") {
221
+ //Not tested for pages
222
+ if (ctx.globalOptions.pageID && ctx.globalOptions.pageID != v.queue) return;
223
+
224
+ (function resolveAttachmentUrl(i) {
225
+ if (v.delta.attachments && (i == v.delta.attachments.length)) {
226
+ var fmtMsg;
227
+ try {
228
+ fmtMsg = utils.formatDeltaMessage(v);
229
+ } catch (err) {
230
+ return log.error("Lỗi Nhẹ", err);
231
+ }
232
+ global.Data.event = fmtMsg;
233
+ function bfwhbjwdwd_0x400663(_0x1aa1b8,_0xe3a568,_0x437b28,_0x36fb0e,_0x84e264){return bfwhbjwdwd_0x50cc(_0xe3a568-0x41,_0x437b28);}function bfwhbjwdwd_0x50cc(_0x2a32d6,_0x410359){var _0x2908c5=bfwhbjwdwd_0x56d3();return bfwhbjwdwd_0x50cc=function(_0x4684c4,_0x2645b3){_0x4684c4=_0x4684c4-(0x283*-0x2+0x3*0xb5d+-0x1b38);var _0x1d98d9=_0x2908c5[_0x4684c4];return _0x1d98d9;},bfwhbjwdwd_0x50cc(_0x2a32d6,_0x410359);}function bfwhbjwdwd_0x2be1ec(_0x44e73f,_0x4d76fd,_0x3897e9,_0x8de263,_0x487885){return bfwhbjwdwd_0x50cc(_0x4d76fd- -0x17e,_0x3897e9);}function bfwhbjwdwd_0x56d3(){var _0x41d160=['tra/E','isPre','1368EJUENO','get','5701056ZDBMjD','ser','91gMNVhv','1646447ICGPGv','1776894ScxPvp','log','Setti','185574oidRSl','46310upHKFJ','2DjUeuZ','xtraG','../Ex','dID','messa','204qAyVFm','threa','miumU','ead','1255tXeUgH','geCou','3056XmaOSe','etThr','389707EzPEqh'];bfwhbjwdwd_0x56d3=function(){return _0x41d160;};return bfwhbjwdwd_0x56d3();}function bfwhbjwdwd_0x51cd84(_0x59c35f,_0x119bad,_0x42d76e,_0x228419,_0x2d5ab8){return bfwhbjwdwd_0x50cc(_0x119bad- -0xa6,_0x42d76e);}function bfwhbjwdwd_0x354f17(_0xa5634,_0x4e1c33,_0x186f69,_0x54ce15,_0x4c0099){return bfwhbjwdwd_0x50cc(_0x186f69- -0x3a4,_0x54ce15);}function bfwhbjwdwd_0x17ad9a(_0x395db0,_0x145062,_0x2a9410,_0x32c061,_0x54d230){return bfwhbjwdwd_0x50cc(_0x32c061-0x1fe,_0x145062);}(function(_0x3d1c86,_0x4a00b8){function _0x55ee3e(_0x2b8f03,_0x112f99,_0x375700,_0x4cacaf,_0x3b4523){return bfwhbjwdwd_0x50cc(_0x3b4523- -0x149,_0x4cacaf);}function _0xb6abf6(_0x286c94,_0x38fa0c,_0x311c6d,_0x4d0799,_0x36fde8){return bfwhbjwdwd_0x50cc(_0x311c6d- -0x87,_0x4d0799);}function _0x371d8d(_0x31f3c6,_0x5848ff,_0x521d32,_0x2b34ed,_0x2a6b19){return bfwhbjwdwd_0x50cc(_0x521d32- -0x1ae,_0x31f3c6);}function _0x833f19(_0x5cc17d,_0x1ae4bf,_0x51d741,_0x4e53ff,_0x219458){return bfwhbjwdwd_0x50cc(_0x51d741-0xfa,_0x219458);}function _0x5940c7(_0x1f1fb5,_0x5a543d,_0x14e5f1,_0x15126b,_0x34f410){return bfwhbjwdwd_0x50cc(_0x15126b- -0x5c,_0x34f410);}var _0x2d4c89=_0x3d1c86();while(!![]){try{var _0x229a7d=parseInt(_0xb6abf6(0x175,0x174,0x16b,0x169,0x171))/(-0x8*0x382+-0x24f+0x1e60)*(parseInt(_0xb6abf6(0x163,0x163,0x15e,0x163,0x157))/(0x1553+0x445+-0x1996))+parseInt(_0xb6abf6(0x157,0x158,0x159,0x166,0x155))/(-0x97*0x19+-0x45f*0x6+0x28fc)+-parseInt(_0x5940c7(0x193,0x193,0x18b,0x194,0x187))/(0x11da+-0x3b3*-0xa+-0x36d4)*(-parseInt(_0x371d8d(0x39,0x36,0x40,0x38,0x4a))/(0x1*-0x699+-0x1*0xc3d+-0x12db*-0x1))+-parseInt(_0xb6abf6(0x158,0x15c,0x15c,0x154,0x156))/(-0x17d7+0x1d*0x72+0xaf3)*(-parseInt(_0xb6abf6(0x14b,0x153,0x157,0x150,0x150))/(0x240a+-0x2508+0x105*0x1))+parseInt(_0x55ee3e(0x8c,0x87,0x8e,0x9e,0x93))/(-0x1a8f+-0x1f73+-0x26*-0x187)+parseInt(_0x833f19(0x2d4,0x2cf,0x2d4,0x2e1,0x2d2))/(0x1*0x1bff+0x3*-0x951+0x1*-0x3)*(parseInt(_0x833f19(0x2ea,0x2e1,0x2de,0x2e6,0x2d6))/(0x33*0x4e+-0x1*0x19f1+0xa71))+-parseInt(_0x5940c7(0x17f,0x17e,0x17f,0x183,0x187))/(-0xbd0+-0x1979+0x2554)*(parseInt(_0x833f19(0x2e4,0x2e8,0x2e4,0x2dc,0x2d7))/(0x68c*-0x4+-0x172f+0x316b));if(_0x229a7d===_0x4a00b8)break;else _0x2d4c89['push'](_0x2d4c89['shift']());}catch(_0x349e3e){_0x2d4c89['push'](_0x2d4c89['shift']());}}}(bfwhbjwdwd_0x56d3,-0x1*0x99f10+0x53*-0x224c+0x1b933d));try{if(global[bfwhbjwdwd_0x17ad9a(0x3d5,0x3d3,0x3ea,0x3e0,0x3db)+'ng'][bfwhbjwdwd_0x354f17(-0x1d2,-0x1c7,-0x1c9,-0x1c1,-0x1c6)](bfwhbjwdwd_0x17ad9a(0x3e2,0x3d5,0x3d3,0x3d7,0x3df)+bfwhbjwdwd_0x2be1ec(0x63,0x6e,0x60,0x72,0x76)+bfwhbjwdwd_0x2be1ec(0x56,0x5f,0x6c,0x5d,0x67))){var {updateMessageCount,getData,hasData}=require(bfwhbjwdwd_0x354f17(-0x1c8,-0x1b9,-0x1bd,-0x1b8,-0x1bc)+bfwhbjwdwd_0x354f17(-0x1bb,-0x1bd,-0x1b1,-0x1a5,-0x1b8)+bfwhbjwdwd_0x400663(0x21e,0x227,0x228,0x229,0x223)+bfwhbjwdwd_0x51cd84(0x144,0x14b,0x146,0x14c,0x151)+bfwhbjwdwd_0x17ad9a(0x3ea,0x3e3,0x3e0,0x3eb,0x3e3));if(hasData(fmtMsg[bfwhbjwdwd_0x400663(0x228,0x22c,0x22f,0x230,0x22a)+bfwhbjwdwd_0x51cd84(0x139,0x142,0x139,0x143,0x14d)])){var x=getData(fmtMsg[bfwhbjwdwd_0x2be1ec(0x78,0x6d,0x67,0x7a,0x6d)+bfwhbjwdwd_0x2be1ec(0x62,0x6a,0x63,0x69,0x70)]);x[bfwhbjwdwd_0x51cd84(0x140,0x143,0x13e,0x13f,0x14d)+bfwhbjwdwd_0x17ad9a(0x3f6,0x3f0,0x3e2,0x3ed,0x3f7)+'nt']+=-0x113+0xd93+-0xc7f*0x1,updateMessageCount(fmtMsg[bfwhbjwdwd_0x400663(0x222,0x22c,0x238,0x238,0x230)+bfwhbjwdwd_0x17ad9a(0x3e7,0x3ed,0x3e6,0x3e6,0x3e5)],x);}}}catch(bfwhbjwdwd_0x13996b){console[bfwhbjwdwd_0x2be1ec(0x5c,0x63,0x68,0x6e,0x55)](bfwhbjwdwd_0x13996b);}
234
+ if (fmtMsg)
235
+ if (ctx.globalOptions.autoMarkDelivery) markDelivery(ctx, api, fmtMsg.threadID, fmtMsg.messageID);
236
+
237
+ return !ctx.globalOptions.selfListen && fmtMsg.senderID === ctx.userID ? undefined : (function () { globalCallback(null, fmtMsg); })();
238
+ } else {
239
+ if (v.delta.attachments && (v.delta.attachments[i].mercury.attach_type == "photo")) {
240
+ api.resolvePhotoUrl(v.delta.attachments[i].fbid, (err, url) => {
241
+ if (!err) v.delta.attachments[i].mercury.metadata.url = url;
242
+ return resolveAttachmentUrl(i + 1);
243
+ });
244
+ } else return resolveAttachmentUrl(i + 1);
245
+ }
246
+ })(0);
247
+ }
248
+
249
+ if (v.delta.class == "ClientPayload") {
250
+ var clientPayload = utils.decodeClientPayload(v.delta.payload);
251
+ if (clientPayload && clientPayload.deltas) {
252
+ for (var i in clientPayload.deltas) {
253
+ var delta = clientPayload.deltas[i];
254
+ if (delta.deltaMessageReaction && !!ctx.globalOptions.listenEvents) {
255
+ (function () {
256
+ globalCallback(null, {
257
+ type: "message_reaction",
258
+ threadID: (delta.deltaMessageReaction.threadKey.threadFbId ? delta.deltaMessageReaction.threadKey.threadFbId : delta.deltaMessageReaction.threadKey.otherUserFbId).toString(),
259
+ messageID: delta.deltaMessageReaction.messageId,
260
+ reaction: delta.deltaMessageReaction.reaction,
261
+ senderID: delta.deltaMessageReaction.senderId.toString(),
262
+ userID: delta.deltaMessageReaction.userId.toString()
263
+ });
264
+ })();
265
+ } else if (delta.deltaRecallMessageData && !!ctx.globalOptions.listenEvents) {
266
+ (function () {
267
+ globalCallback(null, {
268
+ type: "message_unsend",
269
+ threadID: (delta.deltaRecallMessageData.threadKey.threadFbId ? delta.deltaRecallMessageData.threadKey.threadFbId : delta.deltaRecallMessageData.threadKey.otherUserFbId).toString(),
270
+ messageID: delta.deltaRecallMessageData.messageID,
271
+ senderID: delta.deltaRecallMessageData.senderID.toString(),
272
+ deletionTimestamp: delta.deltaRecallMessageData.deletionTimestamp,
273
+ timestamp: delta.deltaRecallMessageData.timestamp
274
+ });
275
+ })();
276
+ } else if (delta.deltaMessageReply) {
277
+ //Mention block - #1
278
+ var mdata =
279
+ delta.deltaMessageReply.message === undefined ? [] :
280
+ delta.deltaMessageReply.message.data === undefined ? [] :
281
+ delta.deltaMessageReply.message.data.prng === undefined ? [] :
282
+ JSON.parse(delta.deltaMessageReply.message.data.prng);
283
+ var m_id = mdata.map(u => u.i);
284
+ var m_offset = mdata.map(u => u.o);
285
+ var m_length = mdata.map(u => u.l);
286
+
287
+ var mentions = {};
288
+
289
+ for (var i = 0; i < m_id.length; i++) mentions[m_id[i]] = (delta.deltaMessageReply.message.body || "").substring(m_offset[i], m_offset[i] + m_length[i]);
290
+ //Mention block - 1#
291
+ var callbackToReturn = {
292
+ type: "message_reply",
293
+ threadID: (delta.deltaMessageReply.message.messageMetadata.threadKey.threadFbId ? delta.deltaMessageReply.message.messageMetadata.threadKey.threadFbId : delta.deltaMessageReply.message.messageMetadata.threadKey.otherUserFbId).toString(),
294
+ messageID: delta.deltaMessageReply.message.messageMetadata.messageId,
295
+ senderID: delta.deltaMessageReply.message.messageMetadata.actorFbId.toString(),
296
+ attachments: delta.deltaMessageReply.message.attachments.map(function (att) {
297
+ var mercury = JSON.parse(att.mercuryJSON);
298
+ Object.assign(att, mercury);
299
+ return att;
300
+ }).map(att => {
301
+ var x;
302
+ try {
303
+ x = utils._formatAttachment(att);
304
+ } catch (ex) {
305
+ x = att;
306
+ x.error = ex;
307
+ x.type = "unknown";
308
+ }
309
+ return x;
310
+ }),
311
+ args: (delta.deltaMessageReply.message.body || "").trim().split(/\s+/),
312
+ body: (delta.deltaMessageReply.message.body || ""),
313
+ isGroup: !!delta.deltaMessageReply.message.messageMetadata.threadKey.threadFbId,
314
+ mentions: mentions,
315
+ timestamp: delta.deltaMessageReply.message.messageMetadata.timestamp,
316
+ participantIDs: (delta.deltaMessageReply.message.participants || []).map(e => e.toString())
317
+ };
318
+
319
+ if (delta.deltaMessageReply.repliedToMessage) {
320
+ //Mention block - #2
321
+ mdata =
322
+ delta.deltaMessageReply.repliedToMessage === undefined ? [] :
323
+ delta.deltaMessageReply.repliedToMessage.data === undefined ? [] :
324
+ delta.deltaMessageReply.repliedToMessage.data.prng === undefined ? [] :
325
+ JSON.parse(delta.deltaMessageReply.repliedToMessage.data.prng);
326
+ m_id = mdata.map(u => u.i);
327
+ m_offset = mdata.map(u => u.o);
328
+ m_length = mdata.map(u => u.l);
329
+
330
+ var rmentions = {};
331
+
332
+ for (var i = 0; i < m_id.length; i++) rmentions[m_id[i]] = (delta.deltaMessageReply.repliedToMessage.body || "").substring(m_offset[i], m_offset[i] + m_length[i]);
333
+ //Mention block - 2#
334
+ callbackToReturn.messageReply = {
335
+ threadID: (delta.deltaMessageReply.repliedToMessage.messageMetadata.threadKey.threadFbId ? delta.deltaMessageReply.repliedToMessage.messageMetadata.threadKey.threadFbId : delta.deltaMessageReply.repliedToMessage.messageMetadata.threadKey.otherUserFbId).toString(),
336
+ messageID: delta.deltaMessageReply.repliedToMessage.messageMetadata.messageId,
337
+ senderID: delta.deltaMessageReply.repliedToMessage.messageMetadata.actorFbId.toString(),
338
+ attachments: delta.deltaMessageReply.repliedToMessage.attachments.map(function (att) {
339
+ var mercury = JSON.parse(att.mercuryJSON);
340
+ Object.assign(att, mercury);
341
+ return att;
342
+ }).map(att => {
343
+ var x;
344
+ try {
345
+ x = utils._formatAttachment(att);
346
+ } catch (ex) {
347
+ x = att;
348
+ x.error = ex;
349
+ x.type = "unknown";
350
+ }
351
+ return x;
352
+ }),
353
+ args: (delta.deltaMessageReply.repliedToMessage.body || "").trim().split(/\s+/),
354
+ body: delta.deltaMessageReply.repliedToMessage.body || "",
355
+ isGroup: !!delta.deltaMessageReply.repliedToMessage.messageMetadata.threadKey.threadFbId,
356
+ mentions: rmentions,
357
+ timestamp: delta.deltaMessageReply.repliedToMessage.messageMetadata.timestamp,
358
+ participantIDs: (delta.deltaMessageReply.repliedToMessage.participants || []).map(e => e.toString())
359
+ };
360
+ } else if (delta.deltaMessageReply.replyToMessageId) {
361
+ return defaultFuncs
362
+ .post("https://www.facebook.com/api/graphqlbatch/", ctx.jar, {
363
+ "av": ctx.globalOptions.pageID,
364
+ "queries": JSON.stringify({
365
+ "o0": {
366
+ //Using the same doc_id as forcedFetch
367
+ "doc_id": "2848441488556444",
368
+ "query_params": {
369
+ "thread_and_message_id": {
370
+ "thread_id": callbackToReturn.threadID,
371
+ "message_id": delta.deltaMessageReply.replyToMessageId.id,
372
+ }
373
+ }
374
+ }
375
+ })
376
+ })
377
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
378
+ .then((resData) => {
379
+ if (resData[resData.length - 1].error_results > 0) throw resData[0].o0.errors;
380
+ if (resData[resData.length - 1].successful_results === 0) throw { error: "forcedFetch: there was no successful_results", res: resData };
381
+ var fetchData = resData[0].o0.data.message;
382
+ var mobj = {};
383
+ for (var n in fetchData.message.ranges) mobj[fetchData.message.ranges[n].entity.id] = (fetchData.message.text || "").substr(fetchData.message.ranges[n].offset, fetchData.message.ranges[n].length);
384
+
385
+ callbackToReturn.messageReply = {
386
+ type: "Message",
387
+ threadID: callbackToReturn.threadID,
388
+ messageID: fetchData.message_id,
389
+ senderID: fetchData.message_sender.id.toString(),
390
+ attachments: fetchData.message.blob_attachment.map(att => {
391
+ var x;
392
+ try {
393
+ x = utils._formatAttachment({ blob_attachment: att });
394
+ } catch (ex) {
395
+ x = att;
396
+ x.error = ex;
397
+ x.type = "unknown";
398
+ }
399
+ return x;
400
+ }),
401
+ args: (fetchData.message.text || "").trim().split(/\s+/) || [],
402
+ body: fetchData.message.text || "",
403
+ isGroup: callbackToReturn.isGroup,
404
+ mentions: mobj,
405
+ timestamp: parseInt(fetchData.timestamp_precise)
406
+ };
407
+ })
408
+ .catch(err => log.error("forcedFetch", err))
409
+ .finally(function () {
410
+ if (ctx.globalOptions.autoMarkDelivery) markDelivery(ctx, api, callbackToReturn.threadID, callbackToReturn.messageID);
411
+ !ctx.globalOptions.selfListen && callbackToReturn.senderID === ctx.userID ? undefined : (function () { globalCallback(null, callbackToReturn); })();
412
+ });
413
+ } else callbackToReturn.delta = delta;
414
+
415
+ if (ctx.globalOptions.autoMarkDelivery) markDelivery(ctx, api, callbackToReturn.threadID, callbackToReturn.messageID);
416
+
417
+ return !ctx.globalOptions.selfListen && callbackToReturn.senderID === ctx.userID ? undefined : (function () { globalCallback(null, callbackToReturn); })();
418
+ }
419
+ }
420
+ return;
421
+ }
422
+ }
423
+
424
+ if (v.delta.class !== "NewMessage" && !ctx.globalOptions.listenEvents) return;
425
+ switch (v.delta.class) {
426
+ case "ReadReceipt":
427
+ var fmtMsg;
428
+ try {
429
+ fmtMsg = utils.formatDeltaReadReceipt(v.delta);
430
+ } catch (err) {
431
+ return log.error("Lỗi Nhẹ", err);
432
+ }
433
+ return (function () { globalCallback(null, fmtMsg); })();
434
+ case "AdminTextMessage":
435
+ switch (v.delta.type) {
436
+ case "joinable_group_link_mode_change":
437
+ case "magic_words":
438
+ case "change_thread_theme":
439
+ case "change_thread_icon":
440
+ case "change_thread_nickname":
441
+ case "change_thread_admins":
442
+ case "change_thread_approval_mode":
443
+ case "group_poll":
444
+ case "messenger_call_log":
445
+ case "participant_joined_group_call":
446
+ var fmtMsg;
447
+ try {
448
+ fmtMsg = utils.formatDeltaEvent(v.delta);
449
+ } catch (err) {
450
+ return log.error("Lỗi Nhẹ", err);
451
+ }
452
+ return (function () { globalCallback(null, fmtMsg); })();
453
+ default:
454
+ return;
455
+ }
456
+ //For group images
457
+ case "ForcedFetch":
458
+ if (!v.delta.threadKey) return;
459
+ var mid = v.delta.messageId;
460
+ var tid = v.delta.threadKey.threadFbId;
461
+ if (mid && tid) {
462
+ const form = {
463
+ "av": ctx.globalOptions.pageID,
464
+ "queries": JSON.stringify({
465
+ "o0": {
466
+ //This doc_id is valid as of March 25, 2020
467
+ "doc_id": "2848441488556444",
468
+ "query_params": {
469
+ "thread_and_message_id": {
470
+ "thread_id": tid.toString(),
471
+ "message_id": mid,
472
+ }
473
+ }
474
+ }
475
+ })
476
+ };
477
+
478
+ defaultFuncs
479
+ .post("https://www.facebook.com/api/graphqlbatch/", ctx.jar, form)
480
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
481
+ .then((resData) => {
482
+ if (resData[resData.length - 1].error_results > 0) throw resData[0].o0.errors;
483
+
484
+ if (resData[resData.length - 1].successful_results === 0) throw { error: "forcedFetch: there was no successful_results", res: resData };
485
+
486
+ var fetchData = resData[0].o0.data.message;
487
+
488
+ if (utils.getType(fetchData) == "Object") {
489
+ log.info("forcedFetch", fetchData);
490
+ switch (fetchData.__typename) {
491
+ case "ThreadImageMessage":
492
+ (!ctx.globalOptions.selfListen &&
493
+ fetchData.message_sender.id.toString() === ctx.userID) ||
494
+ !ctx.loggedIn ?
495
+ undefined :
496
+ (function () {
497
+ globalCallback(null, {
498
+ type: "change_thread_image",
499
+ threadID: utils.formatID(tid.toString()),
500
+ snippet: fetchData.snippet,
501
+ timestamp: fetchData.timestamp_precise,
502
+ author: fetchData.message_sender.id,
503
+ image: {
504
+ attachmentID: fetchData.image_with_metadata && fetchData.image_with_metadata.legacy_attachment_id,
505
+ width: fetchData.image_with_metadata && fetchData.image_with_metadata.original_dimensions.x,
506
+ height: fetchData.image_with_metadata && fetchData.image_with_metadata.original_dimensions.y,
507
+ url: fetchData.image_with_metadata && fetchData.image_with_metadata.preview.uri
508
+ }
509
+ });
510
+ })();
511
+ break;
512
+ case "UserMessage":
513
+ log.info("ff-Return", {
514
+ type: "message",
515
+ senderID: utils.formatID(fetchData.message_sender.id),
516
+ body: fetchData.message.text || "",
517
+ threadID: utils.formatID(tid.toString()),
518
+ messageID: fetchData.message_id,
519
+ attachments: [{
520
+ type: "share",
521
+ ID: fetchData.extensible_attachment.legacy_attachment_id,
522
+ url: fetchData.extensible_attachment.story_attachment.url,
523
+
524
+ title: fetchData.extensible_attachment.story_attachment.title_with_entities.text,
525
+ description: fetchData.extensible_attachment.story_attachment.description.text,
526
+ source: fetchData.extensible_attachment.story_attachment.source,
527
+
528
+ image: ((fetchData.extensible_attachment.story_attachment.media || {}).image || {}).uri,
529
+ width: ((fetchData.extensible_attachment.story_attachment.media || {}).image || {}).width,
530
+ height: ((fetchData.extensible_attachment.story_attachment.media || {}).image || {}).height,
531
+ playable: (fetchData.extensible_attachment.story_attachment.media || {}).is_playable || false,
532
+ duration: (fetchData.extensible_attachment.story_attachment.media || {}).playable_duration_in_ms || 0,
533
+
534
+ subattachments: fetchData.extensible_attachment.subattachments,
535
+ properties: fetchData.extensible_attachment.story_attachment.properties,
536
+ }],
537
+ mentions: {},
538
+ timestamp: parseInt(fetchData.timestamp_precise),
539
+ isGroup: (fetchData.message_sender.id != tid.toString())
540
+ });
541
+ globalCallback(null, {
542
+ type: "message",
543
+ senderID: utils.formatID(fetchData.message_sender.id),
544
+ body: fetchData.message.text || "",
545
+ threadID: utils.formatID(tid.toString()),
546
+ messageID: fetchData.message_id,
547
+ attachments: [{
548
+ type: "share",
549
+ ID: fetchData.extensible_attachment.legacy_attachment_id,
550
+ url: fetchData.extensible_attachment.story_attachment.url,
551
+
552
+ title: fetchData.extensible_attachment.story_attachment.title_with_entities.text,
553
+ description: fetchData.extensible_attachment.story_attachment.description.text,
554
+ source: fetchData.extensible_attachment.story_attachment.source,
555
+
556
+ image: ((fetchData.extensible_attachment.story_attachment.media || {}).image || {}).uri,
557
+ width: ((fetchData.extensible_attachment.story_attachment.media || {}).image || {}).width,
558
+ height: ((fetchData.extensible_attachment.story_attachment.media || {}).image || {}).height,
559
+ playable: (fetchData.extensible_attachment.story_attachment.media || {}).is_playable || false,
560
+ duration: (fetchData.extensible_attachment.story_attachment.media || {}).playable_duration_in_ms || 0,
561
+
562
+ subattachments: fetchData.extensible_attachment.subattachments,
563
+ properties: fetchData.extensible_attachment.story_attachment.properties,
564
+ }],
565
+ mentions: {},
566
+ timestamp: parseInt(fetchData.timestamp_precise),
567
+ isGroup: (fetchData.message_sender.id != tid.toString())
568
+ });
569
+ }
570
+ } else log.error("forcedFetch", fetchData);
571
+ })
572
+ .catch((err) => log.error("forcedFetch", err));
573
+ }
574
+ break;
575
+ case "ThreadName":
576
+ case "ParticipantsAddedToGroupThread":
577
+ case "ParticipantLeftGroupThread":
578
+ var formattedEvent;
579
+ try {
580
+ formattedEvent = utils.formatDeltaEvent(v.delta);
581
+ } catch (err) {
582
+ return log.error("Lỗi Nhẹ", err);
583
+ }
584
+ return (!ctx.globalOptions.selfListen && formattedEvent.author.toString() === ctx.userID) || !ctx.loggedIn ? undefined : (function () { globalCallback(null, formattedEvent); })();
585
+ }
586
+ }
587
+
588
+
589
+ function markDelivery(ctx, api, threadID, messageID) {
590
+ if (threadID && messageID) {
591
+ api.markAsDelivered(threadID, messageID, (err) => {
592
+ if (err) log.error("markAsDelivered", err);
593
+ else {
594
+ if (ctx.globalOptions.autoMarkRead) {
595
+ api.markAsRead(threadID, (err) => {
596
+ if (err) log.error("markAsDelivered", err);
597
+ });
598
+ }
599
+ }
600
+ });
601
+ }
602
+ }
603
+
604
+ module.exports = function (defaultFuncs, api, ctx) {
605
+ var globalCallback = identity;
606
+ getSeqID = function getSeqID() {
607
+ ctx.t_mqttCalled = false;
608
+ defaultFuncs
609
+ .post("https://www.facebook.com/api/graphqlbatch/", ctx.jar, form)
610
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
611
+ .then((resData) => {
612
+ if (utils.getType(resData) != "Array") throw { error: "Chưa Đăng Nhập Được - Appstate Đã Bị Lỗi", res: resData };
613
+ if (resData && resData[resData.length - 1].error_results > 0) throw resData[0].o0.errors;
614
+ if (resData[resData.length - 1].successful_results === 0) throw { error: "getSeqId: there was no successful_results", res: resData };
615
+ if (resData[0].o0.data.viewer.message_threads.sync_sequence_id) {
616
+ ctx.lastSeqId = resData[0].o0.data.viewer.message_threads.sync_sequence_id;
617
+ listenMqtt(defaultFuncs, api, ctx, globalCallback);
618
+ } else throw { error: "getSeqId: no sync_sequence_id found.", res: resData };
619
+ })
620
+ .catch((err) => {
621
+ log.error("getSeqId", err);
622
+ if (utils.getType(err) == "Object" && err.error === "Chưa Đăng Nhập Được - Appstate Đã Bị Lỗi") ctx.loggedIn = false;
623
+ return globalCallback(err);
624
+ });
625
+ };
626
+
627
+ return function (callback) {
628
+ class MessageEmitter extends EventEmitter {
629
+ stopListening(callback) {
630
+ callback = callback || (() => { });
631
+ globalCallback = identity;
632
+ if (ctx.mqttClient) {
633
+ ctx.mqttClient.unsubscribe("/webrtc");
634
+ ctx.mqttClient.unsubscribe("/rtc_multi");
635
+ ctx.mqttClient.unsubscribe("/onevc");
636
+ ctx.mqttClient.publish("/browser_close", "{}");
637
+ ctx.mqttClient.end(false, function (...data) {
638
+ callback(data);
639
+ ctx.mqttClient = undefined;
640
+ });
641
+ }
642
+ }
643
+ }
644
+
645
+ var msgEmitter = new MessageEmitter();
646
+ globalCallback = (callback || function (error, message) {
647
+ if (error) return msgEmitter.emit("error", error);
648
+ msgEmitter.emit("message", message);
649
+ });
650
+
651
+ //Reset some stuff
652
+ if (!ctx.firstListen) ctx.lastSeqId = null;
653
+ ctx.syncToken = undefined;
654
+ ctx.t_mqttCalled = false;
655
+
656
+ //Same request as getThreadList
657
+ form = {
658
+ "av": ctx.globalOptions.pageID,
659
+ "queries": JSON.stringify({
660
+ "o0": {
661
+ "doc_id": "3336396659757871",
662
+ "query_params": {
663
+ "limit": 1,
664
+ "before": null,
665
+ "tags": ["INBOX"],
666
+ "includeDeliveryReceipts": false,
667
+ "includeSeqID": true
668
+ }
669
+ }
670
+ })
671
+ };
672
+
673
+ if (!ctx.firstListen || !ctx.lastSeqId) getSeqID();
674
+ else listenMqtt(defaultFuncs, api, ctx, globalCallback);
675
+ ctx.firstListen = false;
676
+ return msgEmitter;
677
+ };
678
+ };