@dongdev/fca-unofficial 0.0.1 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/index.js +113 -84
  2. package/package.json +47 -83
  3. package/src/listenMqtt.js +59 -50
package/index.js CHANGED
@@ -10,70 +10,73 @@ var defaultLogRecordSize = 100;
10
10
  log.maxRecordSize = defaultLogRecordSize;
11
11
 
12
12
  function setOptions(globalOptions, options) {
13
- Object.keys(options).map(function (key) {
14
- switch (key) {
15
- case 'pauseLog':
16
- if (options.pauseLog) log.pause();
17
- break;
18
- case 'online':
19
- globalOptions.online = Boolean(options.online);
20
- break;
21
- case 'logLevel':
22
- log.level = options.logLevel;
23
- globalOptions.logLevel = options.logLevel;
24
- break;
25
- case 'logRecordSize':
26
- log.maxRecordSize = options.logRecordSize;
27
- globalOptions.logRecordSize = options.logRecordSize;
28
- break;
29
- case 'selfListen':
30
- globalOptions.selfListen = Boolean(options.selfListen);
31
- break;
32
- case 'listenEvents':
33
- globalOptions.listenEvents = Boolean(options.listenEvents);
34
- break;
35
- case 'pageID':
36
- globalOptions.pageID = options.pageID.toString();
37
- break;
38
- case 'updatePresence':
39
- globalOptions.updatePresence = Boolean(options.updatePresence);
40
- break;
41
- case 'forceLogin':
42
- globalOptions.forceLogin = Boolean(options.forceLogin);
43
- break;
44
- case 'userAgent':
45
- globalOptions.userAgent = options.userAgent;
46
- break;
47
- case 'autoMarkDelivery':
48
- globalOptions.autoMarkDelivery = Boolean(options.autoMarkDelivery);
49
- break;
50
- case 'autoMarkRead':
51
- globalOptions.autoMarkRead = Boolean(options.autoMarkRead);
52
- break;
53
- case 'listenTyping':
54
- globalOptions.listenTyping = Boolean(options.listenTyping);
55
- break;
56
- case 'proxy':
57
- if (typeof options.proxy != "string") {
58
- delete globalOptions.proxy;
59
- utils.setProxy();
60
- }
61
- else {
62
- globalOptions.proxy = options.proxy;
63
- utils.setProxy(globalOptions.proxy);
64
- }
65
- break;
66
- case 'autoReconnect':
67
- globalOptions.autoReconnect = Boolean(options.autoReconnect);
68
- break;
69
- case 'emitReady':
70
- globalOptions.emitReady = Boolean(options.emitReady);
71
- break;
72
- default:
73
- log.warn("setOptions", "Unrecognized option given to setOptions: " + key);
74
- break;
75
- }
76
- });
13
+ if (options && typeof options === 'object') {
14
+ Object.keys(options).map(function (key) {
15
+ switch (key) {
16
+ case 'pauseLog':
17
+ if (options.pauseLog) log.pause();
18
+ break;
19
+ case 'online':
20
+ globalOptions.online = Boolean(options.online);
21
+ break;
22
+ case 'logLevel':
23
+ log.level = options.logLevel;
24
+ globalOptions.logLevel = options.logLevel;
25
+ break;
26
+ case 'logRecordSize':
27
+ log.maxRecordSize = options.logRecordSize;
28
+ globalOptions.logRecordSize = options.logRecordSize;
29
+ break;
30
+ case 'selfListen':
31
+ globalOptions.selfListen = Boolean(options.selfListen);
32
+ break;
33
+ case 'listenEvents':
34
+ globalOptions.listenEvents = Boolean(options.listenEvents);
35
+ break;
36
+ case 'pageID':
37
+ globalOptions.pageID = options.pageID.toString();
38
+ break;
39
+ case 'updatePresence':
40
+ globalOptions.updatePresence = Boolean(options.updatePresence);
41
+ break;
42
+ case 'forceLogin':
43
+ globalOptions.forceLogin = Boolean(options.forceLogin);
44
+ break;
45
+ case 'userAgent':
46
+ globalOptions.userAgent = options.userAgent;
47
+ break;
48
+ case 'autoMarkDelivery':
49
+ globalOptions.autoMarkDelivery = Boolean(options.autoMarkDelivery);
50
+ break;
51
+ case 'autoMarkRead':
52
+ globalOptions.autoMarkRead = Boolean(options.autoMarkRead);
53
+ break;
54
+ case 'listenTyping':
55
+ globalOptions.listenTyping = Boolean(options.listenTyping);
56
+ break;
57
+ case 'proxy':
58
+ if (typeof options.proxy != "string") {
59
+ delete globalOptions.proxy;
60
+ utils.setProxy();
61
+ } else {
62
+ globalOptions.proxy = options.proxy;
63
+ utils.setProxy(globalOptions.proxy);
64
+ }
65
+ break;
66
+ case 'autoReconnect':
67
+ globalOptions.autoReconnect = Boolean(options.autoReconnect);
68
+ break;
69
+ case 'emitReady':
70
+ globalOptions.emitReady = Boolean(options.emitReady);
71
+ break;
72
+ default:
73
+ log.warn("setOptions", "Unrecognized option given to setOptions: " + key);
74
+ break;
75
+ }
76
+ });
77
+ } else {
78
+ log.warn("setOptions", "Invalid or undefined options provided.");
79
+ }
77
80
  }
78
81
 
79
82
  function buildAPI(globalOptions, html, jar) {
@@ -451,26 +454,52 @@ function loginHelper(appState, email, password, globalOptions, callback, prCallb
451
454
  });
452
455
  }
453
456
 
454
- var ctx = null;
455
- var _defaultFuncs = null;
456
- var api = null;
457
-
458
- mainPromise = mainPromise
459
- .then(function (res) {
460
- // Hacky check for the redirection that happens on some ISPs, which doesn't return statusCode 3xx
461
- var reg = /<meta http-equiv="refresh" content="0;url=([^"]+)[^>]+>/;
462
- var redirect = reg.exec(res.body);
463
- if (redirect && redirect[1]) return utils.get(redirect[1], jar, null, globalOptions).then(utils.saveCookies(jar));
464
- return res;
465
- })
466
- .then(function (res) {
467
- var html = res.body;
468
- var stuff = buildAPI(globalOptions, html, jar);
469
- ctx = stuff[0];
470
- _defaultFuncs = stuff[1];
471
- api = stuff[2];
472
- return res;
473
- });
457
+ var redirect = [1, "https://m.facebook.com/"], bypass_region_err = false, ctx, _defaultFuncs, api;
458
+ function CheckAndFixErr(res) {
459
+ let reg_antierr = /This browser is not supported/gs;
460
+ if (reg_antierr.test(res.body)) {
461
+ const Data = JSON.stringify(res.body);
462
+ const Dt_Check = Data.split('2Fhome.php&amp;gfid=')[1];
463
+ if (Dt_Check == undefined) return res
464
+ const fid = Dt_Check.split("\\\\")[0];
465
+ if (Dt_Check == undefined || Dt_Check == "") return res
466
+ const final_fid = fid.split(`\\`)[0];
467
+ if (final_fid == undefined || final_fid == '') return res;
468
+ const redirectlink = redirect[1] + "a/preferences.php?basic_site_devices=m_basic&uri=" + encodeURIComponent("https://m.facebook.com/home.php") + "&gfid=" + final_fid;
469
+ bypass_region_err = true;
470
+ log.info('login', 'Bypass vùng tài khoản thành công');
471
+ return utils.get(redirectlink, jar, null, globalOptions).then(utils.saveCookies(jar));
472
+ }
473
+ else return res
474
+ }
475
+ function Redirect(res) {
476
+ var reg = /<meta http-equiv="refresh" content="0;url=([^"]+)[^>]+>/;
477
+ redirect = reg.exec(res.body);
478
+ if (redirect && redirect[1]) return utils.get(redirect[1], jar, null, globalOptions).then(utils.saveCookies(jar));
479
+ return res;
480
+ }
481
+
482
+ mainPromise = mainPromise
483
+ .then(res => Redirect(res))
484
+ .then(res => CheckAndFixErr(res))
485
+ .then(function(res) {
486
+ let Regex_Via = /MPageLoadClientMetrics/gs;
487
+ if (!Regex_Via.test(res.body)) {
488
+ globalOptions.userAgent = "Mozilla/5.0 (iPhone; CPU iPhone OS 16_6 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/16.6 Mobile/15E148 Safari/604.1";
489
+ return utils.get('https://www.facebook.com/', jar, null, globalOptions, { noRef: true }).then(utils.saveCookies(jar));
490
+ }
491
+ else return res
492
+ })
493
+ .then(res => Redirect(res))
494
+ .then(res => CheckAndFixErr(res))
495
+ .then(function (res) {
496
+ var html = res.body;
497
+ var stuff = buildAPI(globalOptions, html, jar, bypass_region_err);
498
+ ctx = stuff[0];
499
+ _defaultFuncs = stuff[1];
500
+ api = stuff[2];
501
+ return res;
502
+ });
474
503
 
475
504
  // given a pageID we log in as a page
476
505
  if (globalOptions.pageID) {
package/package.json CHANGED
@@ -1,84 +1,48 @@
1
- {
2
- "name": "@dongdev/fca-unofficial",
3
- "version": "0.0.1",
4
- "description": "A Facebook chat API that doesn't rely on XMPP. Will NOT be deprecated after April 30th 2015.",
5
- "scripts": {
6
- "test": "mocha",
7
- "lint": "eslint **.js",
8
- "prettier": "prettier utils.js src/* --write"
9
- },
10
- "publishConfig": {
11
- "access": "public"
12
- },
13
- "repository": {
14
- "type": "git",
15
- "url": "git://github.com/DongDevVN/fca-unofficial.git"
16
- },
17
- "keywords": [
18
- "facebook",
19
- "chat",
20
- "api",
21
- "fca"
22
- ],
23
- "bugs": {
24
- "url": "https://github.com/DongDevVN/fca-unofficial/issues"
25
- },
26
- "author": "Avery, David, Maude, Benjamin, UIRI, MiraiTeam",
27
- "license": "MIT",
28
- "dependencies": {
29
- "bluebird": "^2.11.0",
30
- "cheerio": "^1.0.0-rc.10",
31
- "https-proxy-agent": "^4.0.0",
32
- "mqtt": "^4.2.8",
33
- "npmlog": "^1.2.0",
34
- "request": "^2.53.0",
35
- "websocket-stream": "^5.5.0"
36
- },
37
- "engines": {
38
- "node": ">=10.x"
39
- },
40
- "devDependencies": {
41
- "eslint": "^7.5.0",
42
- "mocha": "^7.0.1",
43
- "prettier": "^1.11.1"
44
- },
45
- "eslintConfig": {
46
- "env": {
47
- "es6": true,
48
- "es2017": true,
49
- "node": true
50
- },
51
- "extends": "eslint:recommended",
52
- "parserOptions": {
53
- "sourceType": "module"
54
- },
55
- "rules": {
56
- "linebreak-style": [
57
- "error",
58
- "unix"
59
- ],
60
- "semi": [
61
- "error",
62
- "always"
63
- ],
64
- "no-unused-vars": [
65
- 1,
66
- {
67
- "argsIgnorePattern": "^_",
68
- "varsIgnorePattern": "^_"
69
- }
70
- ],
71
- "no-empty": [
72
- "error",
73
- {
74
- "allowEmptyCatch": true
75
- }
76
- ]
77
- }
78
- },
79
- "homepage": "https://github.com/DongDevVN/fca-unofficial#readme",
80
- "main": "index.js",
81
- "directories": {
82
- "test": "test"
83
- }
1
+ {
2
+ "name": "@dongdev/fca-unofficial",
3
+ "version": "0.0.3",
4
+ "description": "A Facebook chat API without XMPP, will not be deprecated after April 30th, 2015.",
5
+ "main": "index.js",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/DongDev-VN/fca-unofficial.git"
9
+ },
10
+ "author": "Avery, David, Maude, Benjamin, UIRI, MiraiTeam",
11
+ "license": "MIT",
12
+ "dependencies": {
13
+ "bluebird": "^2.11.0",
14
+ "cheerio": "^1.0.0-rc.10",
15
+ "https-proxy-agent": "^4.0.0",
16
+ "mqtt": "^4.2.8",
17
+ "npmlog": "^1.2.0",
18
+ "request": "^2.53.0",
19
+ "websocket-stream": "^5.5.0"
20
+ },
21
+ "devDependencies": {
22
+ "eslint": "^7.5.0",
23
+ "mocha": "^7.0.1",
24
+ "prettier": "^1.11.1"
25
+ },
26
+ "scripts": {
27
+ "test": "mocha",
28
+ "lint": "eslint **/*.js",
29
+ "prettier": "prettier utils.js src/* --write"
30
+ },
31
+ "keywords": [
32
+ "facebook",
33
+ "chat",
34
+ "api",
35
+ "fca",
36
+ "facebook-chat-api"
37
+ ],
38
+ "engines": {
39
+ "node": ">=10.x"
40
+ },
41
+ "homepage": "https://github.com/DongDev-VN/fca-unofficial#readme",
42
+ "bugs": {
43
+ "url": "https://github.com/DongDev-VN/fca-unofficial/issues"
44
+ },
45
+ "directories": {
46
+ "test": "test"
47
+ }
84
48
  }
package/src/listenMqtt.js CHANGED
@@ -42,52 +42,57 @@ function listenMqtt(defaultFuncs, api, ctx, globalCallback) {
42
42
  var foreground = false;
43
43
 
44
44
  var sessionID = Math.floor(Math.random() * 9007199254740991) + 1;
45
- var username = {
46
- u: ctx.userID,
47
- s: sessionID,
48
- chat_on: chatOn,
49
- fg: foreground,
50
- d: utils.getGUID(),
51
- ct: "websocket",
52
- //App id from facebook
53
- aid: "219994525426954",
54
- mqtt_sid: "",
55
- cp: 3,
56
- ecp: 10,
57
- st: [],
58
- pm: [],
59
- dc: "",
60
- no_auto_fg: true,
61
- gas: null,
62
- pack: []
63
- };
45
+ var GUID = utils.getGUID();
46
+ const username = {
47
+ u: ctx.userID,
48
+ s: sessionID,
49
+ chat_on: chatOn,
50
+ fg: foreground,
51
+ d: GUID,
52
+ ct: 'websocket',
53
+ aid: '219994525426954',
54
+ aids: null,
55
+ mqtt_sid: '',
56
+ cp: 3,
57
+ ecp: 10,
58
+ st: [],
59
+ pm: [],
60
+ dc: '',
61
+ no_auto_fg: true,
62
+ gas: null,
63
+ pack: [],
64
+ p: null,
65
+ php_override: ""
66
+ };
64
67
  var cookies = ctx.jar.getCookies("https://www.facebook.com").join("; ");
65
68
 
66
69
  var host;
67
- if (ctx.mqttEndpoint) host = `${ctx.mqttEndpoint}&sid=${sessionID}`;
68
- else if (ctx.region) host = `wss://edge-chat.facebook.com/chat?region=${ctx.region.toLocaleLowerCase()}&sid=${sessionID}`;
69
- else host = `wss://edge-chat.facebook.com/chat?sid=${sessionID}`;
70
+ if (ctx.mqttEndpoint) host = `${ctx.mqttEndpoint}&sid=${sessionID}&cid=${GUID}`;
71
+ else if (ctx.region) host = `wss://edge-chat.facebook.com/chat?region=${ctx.region.toLocaleLowerCase()}&sid=${sessionID}&cid=${GUID}`;
72
+ else host = `wss://edge-chat.facebook.com/chat?sid=${sessionID}&cid=${GUID}`;
70
73
 
71
- var options = {
72
- clientId: "mqttwsclient",
74
+ const options = {
75
+ clientId: 'mqttwsclient',
73
76
  protocolId: 'MQIsdp',
74
77
  protocolVersion: 3,
75
78
  username: JSON.stringify(username),
76
79
  clean: true,
77
80
  wsOptions: {
78
- headers: {
79
- 'Cookie': cookies,
80
- 'Origin': 'https://www.facebook.com',
81
- 'User-Agent': ctx.globalOptions.userAgent,
82
- 'Referer': 'https://www.facebook.com/',
83
- 'Host': new URL(host).hostname //'edge-chat.facebook.com'
84
- },
85
- origin: 'https://www.facebook.com',
86
- protocolVersion: 13
81
+ headers: {
82
+ Cookie: cookies,
83
+ Origin: 'https://www.facebook.com',
84
+ 'User-Agent': ctx.globalOptions.userAgent || 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/101.0.4951.64 Safari/537.36',
85
+ Referer: 'https://www.facebook.com/',
86
+ Host: new URL(host).hostname,
87
+ },
88
+ origin: 'https://www.facebook.com',
89
+ protocolVersion: 13,
90
+ binaryType: 'arraybuffer',
87
91
  },
88
- keepalive: 10,
89
- reschedulePings: false
90
- };
92
+ keepalive: 60,
93
+ reschedulePings: true,
94
+ reconnectPeriod: 3,
95
+ };
91
96
 
92
97
  if (typeof ctx.globalOptions.proxy != "undefined") {
93
98
  var agent = new HttpsProxyAgent(ctx.globalOptions.proxy);
@@ -96,7 +101,7 @@ function listenMqtt(defaultFuncs, api, ctx, globalCallback) {
96
101
 
97
102
  ctx.mqttClient = new mqtt.Client(_ => websocket(host, options.wsOptions), options);
98
103
 
99
- global. mqttClient = ctx.mqttClient;
104
+ global.mqttClient = ctx.mqttClient;
100
105
 
101
106
  mqttClient.on('error', function (err) {
102
107
  log.error("listenMqtt", err);
@@ -197,10 +202,7 @@ function listenMqtt(defaultFuncs, api, ctx, globalCallback) {
197
202
 
198
203
  });
199
204
 
200
- mqttClient.on('close', function () {
201
- //(function () { globalCallback("Connection closed."); })();
202
- // client.end();
203
- });
205
+ mqttClient.on('close', function () {});
204
206
  }
205
207
 
206
208
  function parseDelta(defaultFuncs, api, ctx, globalCallback, v) {
@@ -445,15 +447,22 @@ function parseDelta(defaultFuncs, api, ctx, globalCallback, v) {
445
447
  return (function () { globalCallback(null, fmtMsg); })();
446
448
  case "AdminTextMessage":
447
449
  switch (v.delta.type) {
448
- case "change_thread_theme":
449
- case "change_thread_icon":
450
- case "change_thread_quick_reaction":
451
- case "change_thread_nickname":
452
- case "change_thread_admins":
453
- case "change_thread_approval_mode":
454
- case "group_poll":
455
- case "messenger_call_log":
456
- case "participant_joined_group_call":
450
+ case 'confirm_friend_request':
451
+ case 'shared_album_delete':
452
+ case 'shared_album_addition':
453
+ case 'pin_messages_v2':
454
+ case 'unpin_messages_v2':
455
+ case "change_thread_theme":
456
+ case "change_thread_nickname":
457
+ case "change_thread_icon":
458
+ case "change_thread_quick_reaction":
459
+ case "change_thread_admins":
460
+ case "group_poll":
461
+ case "joinable_group_link_mode_change":
462
+ case "magic_words":
463
+ case "change_thread_approval_mode":
464
+ case "messenger_call_log":
465
+ case "participant_joined_group_call":
457
466
  var fmtMsg;
458
467
  try {
459
468
  fmtMsg = utils.formatDeltaEvent(v.delta);