fca-riyad 37.0.0

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 (242) hide show
  1. package/CHANGELOG.md +325 -0
  2. package/DOCS.md +2712 -0
  3. package/README.md +410 -0
  4. package/func/checkUpdate.js +7 -0
  5. package/func/logAdapter.js +33 -0
  6. package/func/logger.js +48 -0
  7. package/index.d.ts +751 -0
  8. package/index.js +22 -0
  9. package/module/config.js +40 -0
  10. package/module/login.js +133 -0
  11. package/module/loginHelper.js +1359 -0
  12. package/module/options.js +44 -0
  13. package/package.json +95 -0
  14. package/src/api/action/addExternalModule.js +25 -0
  15. package/src/api/action/changeAvatar.js +137 -0
  16. package/src/api/action/changeBio.js +75 -0
  17. package/src/api/action/enableAutoSaveAppState.js +73 -0
  18. package/src/api/action/getCurrentUserID.js +7 -0
  19. package/src/api/action/handleFriendRequest.js +57 -0
  20. package/src/api/action/logout.js +76 -0
  21. package/src/api/action/refreshFb_dtsg.js +48 -0
  22. package/src/api/action/setPostReaction.js +106 -0
  23. package/src/api/action/unfriend.js +54 -0
  24. package/src/api/http/httpGet.js +46 -0
  25. package/src/api/http/httpPost.js +52 -0
  26. package/src/api/http/postFormData.js +47 -0
  27. package/src/api/messaging/addUserToGroup.js +68 -0
  28. package/src/api/messaging/changeAdminStatus.js +126 -0
  29. package/src/api/messaging/changeArchivedStatus.js +55 -0
  30. package/src/api/messaging/changeBlockedStatus.js +48 -0
  31. package/src/api/messaging/changeGroupImage.js +91 -0
  32. package/src/api/messaging/changeNickname.js +70 -0
  33. package/src/api/messaging/changeThreadColor.js +79 -0
  34. package/src/api/messaging/changeThreadEmoji.js +111 -0
  35. package/src/api/messaging/createNewGroup.js +88 -0
  36. package/src/api/messaging/createPoll.js +46 -0
  37. package/src/api/messaging/createThemeAI.js +98 -0
  38. package/src/api/messaging/deleteMessage.js +136 -0
  39. package/src/api/messaging/deleteThread.js +56 -0
  40. package/src/api/messaging/editMessage.js +90 -0
  41. package/src/api/messaging/forwardAttachment.js +57 -0
  42. package/src/api/messaging/forwardMessage.js +134 -0
  43. package/src/api/messaging/getEmojiUrl.js +29 -0
  44. package/src/api/messaging/getFriendsList.js +82 -0
  45. package/src/api/messaging/getMessage.js +829 -0
  46. package/src/api/messaging/getThemePictures.js +62 -0
  47. package/src/api/messaging/handleMessageRequest.js +65 -0
  48. package/src/api/messaging/markAsDelivered.js +57 -0
  49. package/src/api/messaging/markAsRead.js +88 -0
  50. package/src/api/messaging/markAsReadAll.js +49 -0
  51. package/src/api/messaging/markAsSeen.js +61 -0
  52. package/src/api/messaging/muteThread.js +50 -0
  53. package/src/api/messaging/pinMessage.js +115 -0
  54. package/src/api/messaging/removeUserFromGroup.js +62 -0
  55. package/src/api/messaging/resolvePhotoUrl.js +43 -0
  56. package/src/api/messaging/scheduler.js +264 -0
  57. package/src/api/messaging/searchForThread.js +53 -0
  58. package/src/api/messaging/sendBroadcast.js +93 -0
  59. package/src/api/messaging/sendMessage.js +269 -0
  60. package/src/api/messaging/sendTypingIndicator.js +74 -0
  61. package/src/api/messaging/sessionGuard.js +130 -0
  62. package/src/api/messaging/setMessageReaction.js +95 -0
  63. package/src/api/messaging/setTitle.js +124 -0
  64. package/src/api/messaging/shareContact.js +49 -0
  65. package/src/api/messaging/threadColors.js +128 -0
  66. package/src/api/messaging/unsendMessage.js +81 -0
  67. package/src/api/messaging/uploadAttachment.js +492 -0
  68. package/src/api/socket/OldMessage.js +186 -0
  69. package/src/api/socket/core/connectMqtt.js +269 -0
  70. package/src/api/socket/core/emitAuth.js +103 -0
  71. package/src/api/socket/core/getSeqID.js +321 -0
  72. package/src/api/socket/core/getTaskResponseData.js +25 -0
  73. package/src/api/socket/core/parseDelta.js +387 -0
  74. package/src/api/socket/detail/buildStream.js +215 -0
  75. package/src/api/socket/detail/constants.js +28 -0
  76. package/src/api/socket/e2ee/crypto.js +173 -0
  77. package/src/api/socket/e2ee/e2ee/crypto.js +173 -0
  78. package/src/api/socket/e2ee/e2ee/index.js +421 -0
  79. package/src/api/socket/e2ee/e2ee/proto/ArmadilloApplication.proto +281 -0
  80. package/src/api/socket/e2ee/e2ee/proto/ArmadilloICDC.proto +14 -0
  81. package/src/api/socket/e2ee/e2ee/proto/ConsumerApplication.proto +232 -0
  82. package/src/api/socket/e2ee/e2ee/proto/MessageApplication.proto +82 -0
  83. package/src/api/socket/e2ee/e2ee/proto/MessageTransport.proto +77 -0
  84. package/src/api/socket/e2ee/e2ee/proto/WACommon.proto +66 -0
  85. package/src/api/socket/e2ee/e2ee/proto/WAMediaTransport.proto +176 -0
  86. package/src/api/socket/e2ee/e2ee/proto/proto-writer.ts +76 -0
  87. package/src/api/socket/e2ee/e2ee/protocol.js +196 -0
  88. package/src/api/socket/e2ee/e2ee/ratchet.js +219 -0
  89. package/src/api/socket/e2ee/e2ee/store.js +182 -0
  90. package/src/api/socket/e2ee/e2ee/vendor/fb-e2ee.cjs +9162 -0
  91. package/src/api/socket/e2ee/e2ee/vendor/proto/ArmadilloApplication.proto +281 -0
  92. package/src/api/socket/e2ee/e2ee/vendor/proto/ArmadilloICDC.proto +14 -0
  93. package/src/api/socket/e2ee/e2ee/vendor/proto/ConsumerApplication.proto +232 -0
  94. package/src/api/socket/e2ee/e2ee/vendor/proto/MessageApplication.proto +82 -0
  95. package/src/api/socket/e2ee/e2ee/vendor/proto/MessageTransport.proto +77 -0
  96. package/src/api/socket/e2ee/e2ee/vendor/proto/WACommon.proto +66 -0
  97. package/src/api/socket/e2ee/e2ee/vendor/proto/WAMediaTransport.proto +176 -0
  98. package/src/api/socket/e2ee/e2ee/vendor/proto/proto-writer.ts +76 -0
  99. package/src/api/socket/e2ee/index.js +437 -0
  100. package/src/api/socket/e2ee/proto/ArmadilloApplication.proto +281 -0
  101. package/src/api/socket/e2ee/proto/ArmadilloICDC.proto +14 -0
  102. package/src/api/socket/e2ee/proto/ConsumerApplication.proto +232 -0
  103. package/src/api/socket/e2ee/proto/MessageApplication.proto +82 -0
  104. package/src/api/socket/e2ee/proto/MessageTransport.proto +77 -0
  105. package/src/api/socket/e2ee/proto/WACommon.proto +66 -0
  106. package/src/api/socket/e2ee/proto/WAMediaTransport.proto +176 -0
  107. package/src/api/socket/e2ee/proto/proto-writer.ts +76 -0
  108. package/src/api/socket/e2ee/protocol.js +196 -0
  109. package/src/api/socket/e2ee/ratchet.js +219 -0
  110. package/src/api/socket/e2ee/store.js +182 -0
  111. package/src/api/socket/e2ee/vendor/fb-e2ee.cjs +9162 -0
  112. package/src/api/socket/e2ee/vendor/proto/ArmadilloApplication.proto +281 -0
  113. package/src/api/socket/e2ee/vendor/proto/ArmadilloICDC.proto +14 -0
  114. package/src/api/socket/e2ee/vendor/proto/ConsumerApplication.proto +232 -0
  115. package/src/api/socket/e2ee/vendor/proto/MessageApplication.proto +82 -0
  116. package/src/api/socket/e2ee/vendor/proto/MessageTransport.proto +77 -0
  117. package/src/api/socket/e2ee/vendor/proto/WACommon.proto +66 -0
  118. package/src/api/socket/e2ee/vendor/proto/WAMediaTransport.proto +176 -0
  119. package/src/api/socket/e2ee/vendor/proto/proto-writer.ts +76 -0
  120. package/src/api/socket/listenE2EE.js +75 -0
  121. package/src/api/socket/listenMqtt.js +388 -0
  122. package/src/api/socket/middleware/index.js +216 -0
  123. package/src/api/socket/sendMessage.js +309 -0
  124. package/src/api/socket/sendMessageMqtt.js +69 -0
  125. package/src/api/threads/getThreadHistory.js +664 -0
  126. package/src/api/threads/getThreadInfo.js +296 -0
  127. package/src/api/threads/getThreadList.js +293 -0
  128. package/src/api/threads/getThreadPictures.js +78 -0
  129. package/src/api/users/getUserID.js +65 -0
  130. package/src/api/users/getUserInfo.js +402 -0
  131. package/src/api/users/getUserInfoV2.js +134 -0
  132. package/src/app/MessengerBot.js +209 -0
  133. package/src/app/MessengerContext.js +32 -0
  134. package/src/app/createFcaClient.js +136 -0
  135. package/src/app/threadInfoRealtimeSync.js +284 -0
  136. package/src/core/sendReqMqtt.js +96 -0
  137. package/src/database/helpers.js +53 -0
  138. package/src/database/models/index.js +88 -0
  139. package/src/database/models/thread.js +50 -0
  140. package/src/database/models/user.js +46 -0
  141. package/src/database/threadData.js +94 -0
  142. package/src/database/userData.js +98 -0
  143. package/src/remote/remoteClient.js +123 -0
  144. package/src/utils/broadcast.js +51 -0
  145. package/src/utils/client.js +10 -0
  146. package/src/utils/constants.js +23 -0
  147. package/src/utils/cookies.js +68 -0
  148. package/src/utils/format/attachment.js +357 -0
  149. package/src/utils/format/cookie.js +9 -0
  150. package/src/utils/format/date.js +50 -0
  151. package/src/utils/format/decode.js +44 -0
  152. package/src/utils/format/delta.js +194 -0
  153. package/src/utils/format/ids.js +64 -0
  154. package/src/utils/format/index.js +64 -0
  155. package/src/utils/format/message.js +88 -0
  156. package/src/utils/format/presence.js +132 -0
  157. package/src/utils/format/readTyp.js +44 -0
  158. package/src/utils/format/thread.js +42 -0
  159. package/src/utils/format/utils.js +141 -0
  160. package/src/utils/headers.js +115 -0
  161. package/src/utils/loginParser/autoLogin.js +125 -0
  162. package/src/utils/loginParser/helpers.js +43 -0
  163. package/src/utils/loginParser/index.js +10 -0
  164. package/src/utils/loginParser/parseAndCheckLogin.js +220 -0
  165. package/src/utils/loginParser/textUtils.js +28 -0
  166. package/src/utils/nexca-logger.js +144 -0
  167. package/src/utils/nexca-utils.js +686 -0
  168. package/src/utils/request/client.js +26 -0
  169. package/src/utils/request/config.js +23 -0
  170. package/src/utils/request/defaults.js +46 -0
  171. package/src/utils/request/helpers.js +46 -0
  172. package/src/utils/request/index.js +17 -0
  173. package/src/utils/request/methods.js +163 -0
  174. package/src/utils/request/proxy.js +21 -0
  175. package/src/utils/request/retry.js +77 -0
  176. package/src/utils/request/sanitize.js +49 -0
  177. package/src/utils/versionCheck.js +47 -0
  178. package/src/vendor/fca-unofficial/.github/workflows/nodejs.yml +26 -0
  179. package/src/vendor/fca-unofficial/.github/workflows/npmpublish.yml +30 -0
  180. package/src/vendor/fca-unofficial/.travis.yml +6 -0
  181. package/src/vendor/fca-unofficial/DOCS.md +1731 -0
  182. package/src/vendor/fca-unofficial/LICENSE-MIT +21 -0
  183. package/src/vendor/fca-unofficial/README.md +225 -0
  184. package/src/vendor/fca-unofficial/index.js +619 -0
  185. package/src/vendor/fca-unofficial/package.json +76 -0
  186. package/src/vendor/fca-unofficial/src/addExternalModule.js +19 -0
  187. package/src/vendor/fca-unofficial/src/addUserToGroup.js +113 -0
  188. package/src/vendor/fca-unofficial/src/changeAdminStatus.js +79 -0
  189. package/src/vendor/fca-unofficial/src/changeArchivedStatus.js +55 -0
  190. package/src/vendor/fca-unofficial/src/changeBio.js +77 -0
  191. package/src/vendor/fca-unofficial/src/changeBlockedStatus.js +47 -0
  192. package/src/vendor/fca-unofficial/src/changeGroupImage.js +129 -0
  193. package/src/vendor/fca-unofficial/src/changeNickname.js +59 -0
  194. package/src/vendor/fca-unofficial/src/changeThreadColor.js +71 -0
  195. package/src/vendor/fca-unofficial/src/changeThreadEmoji.js +55 -0
  196. package/src/vendor/fca-unofficial/src/createNewGroup.js +86 -0
  197. package/src/vendor/fca-unofficial/src/createPoll.js +71 -0
  198. package/src/vendor/fca-unofficial/src/deleteMessage.js +56 -0
  199. package/src/vendor/fca-unofficial/src/deleteThread.js +56 -0
  200. package/src/vendor/fca-unofficial/src/forwardAttachment.js +60 -0
  201. package/src/vendor/fca-unofficial/src/getCurrentUserID.js +7 -0
  202. package/src/vendor/fca-unofficial/src/getEmojiUrl.js +29 -0
  203. package/src/vendor/fca-unofficial/src/getFriendsList.js +84 -0
  204. package/src/vendor/fca-unofficial/src/getThreadHistory.js +645 -0
  205. package/src/vendor/fca-unofficial/src/getThreadHistoryDeprecated.js +93 -0
  206. package/src/vendor/fca-unofficial/src/getThreadInfo.js +201 -0
  207. package/src/vendor/fca-unofficial/src/getThreadInfoDeprecated.js +80 -0
  208. package/src/vendor/fca-unofficial/src/getThreadList.js +238 -0
  209. package/src/vendor/fca-unofficial/src/getThreadListDeprecated.js +75 -0
  210. package/src/vendor/fca-unofficial/src/getThreadPictures.js +79 -0
  211. package/src/vendor/fca-unofficial/src/getUserID.js +66 -0
  212. package/src/vendor/fca-unofficial/src/getUserInfo.js +72 -0
  213. package/src/vendor/fca-unofficial/src/handleFriendRequest.js +61 -0
  214. package/src/vendor/fca-unofficial/src/handleMessageRequest.js +65 -0
  215. package/src/vendor/fca-unofficial/src/httpGet.js +52 -0
  216. package/src/vendor/fca-unofficial/src/httpPost.js +52 -0
  217. package/src/vendor/fca-unofficial/src/listenMqtt.js +788 -0
  218. package/src/vendor/fca-unofficial/src/logout.js +75 -0
  219. package/src/vendor/fca-unofficial/src/markAsDelivered.js +58 -0
  220. package/src/vendor/fca-unofficial/src/markAsRead.js +80 -0
  221. package/src/vendor/fca-unofficial/src/markAsReadAll.js +50 -0
  222. package/src/vendor/fca-unofficial/src/markAsSeen.js +59 -0
  223. package/src/vendor/fca-unofficial/src/muteThread.js +52 -0
  224. package/src/vendor/fca-unofficial/src/removeUserFromGroup.js +79 -0
  225. package/src/vendor/fca-unofficial/src/resolvePhotoUrl.js +45 -0
  226. package/src/vendor/fca-unofficial/src/searchForThread.js +53 -0
  227. package/src/vendor/fca-unofficial/src/sendMessage.js +459 -0
  228. package/src/vendor/fca-unofficial/src/sendTypingIndicator.js +103 -0
  229. package/src/vendor/fca-unofficial/src/setMessageReaction.js +117 -0
  230. package/src/vendor/fca-unofficial/src/setPostReaction.js +76 -0
  231. package/src/vendor/fca-unofficial/src/setTitle.js +86 -0
  232. package/src/vendor/fca-unofficial/src/threadColors.js +57 -0
  233. package/src/vendor/fca-unofficial/src/unfriend.js +52 -0
  234. package/src/vendor/fca-unofficial/src/unsendMessage.js +49 -0
  235. package/src/vendor/fca-unofficial/test/data/shareAttach.js +146 -0
  236. package/src/vendor/fca-unofficial/test/data/something.mov +0 -0
  237. package/src/vendor/fca-unofficial/test/data/test.png +0 -0
  238. package/src/vendor/fca-unofficial/test/data/test.txt +7 -0
  239. package/src/vendor/fca-unofficial/test/example-config.json +18 -0
  240. package/src/vendor/fca-unofficial/test/test-page.js +140 -0
  241. package/src/vendor/fca-unofficial/test/test.js +385 -0
  242. package/src/vendor/fca-unofficial/utils.js +1358 -0
@@ -0,0 +1,686 @@
1
+ "use strict";
2
+
3
+ var url = require("url");
4
+ var stream = require("stream");
5
+ var bluebird = require("bluebird");
6
+ var querystring = require("querystring");
7
+ var request = bluebird.promisify(require("request").defaults({ jar: true }));
8
+
9
+ function setProxy(proxyUrl) {
10
+ if (typeof proxyUrl === "undefined") {
11
+ request = bluebird.promisify(require("request").defaults({ jar: true }));
12
+ } else {
13
+ request = bluebird.promisify(require("request").defaults({ jar: true, proxy: proxyUrl }));
14
+ }
15
+ }
16
+
17
+ function sanitizeHeaderValue(value) {
18
+ if (value === null || value === undefined) return "";
19
+ var str = String(value);
20
+ if (str.trim().startsWith("[") && str.trim().endsWith("]")) {
21
+ try {
22
+ var parsed = JSON.parse(str);
23
+ if (Array.isArray(parsed)) return "";
24
+ } catch (_) { }
25
+ }
26
+ str = str.replace(/[\x00-\x08\x0B-\x0C\x0E-\x1F\x7F\r\n\[\]]/g, "").trim();
27
+ return str;
28
+ }
29
+
30
+ function sanitizeHeaderName(name) {
31
+ if (!name || typeof name !== "string") return "";
32
+ return name.replace(/[^\x21-\x7E]/g, "").trim();
33
+ }
34
+
35
+ function getHeaders(reqUrl, options, ctx, customHeader) {
36
+ options = options || {};
37
+ var host;
38
+ try { host = new URL(reqUrl).host; } catch (_) { host = reqUrl.replace("https://", "").split("/")[0]; }
39
+ var ua = options.userAgent ||
40
+ "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/18.4 Safari/605.1.15";
41
+ var referer = options.referer || "https://www.facebook.com/";
42
+ var origin = referer.replace(/\/+$/, "");
43
+ var contentType = options.contentType || "application/x-www-form-urlencoded";
44
+ var acceptLang = options.acceptLanguage || "en-US,en;q=0.9";
45
+
46
+ var headers = {
47
+ Host: sanitizeHeaderValue(host),
48
+ Origin: sanitizeHeaderValue(origin),
49
+ Referer: sanitizeHeaderValue(referer),
50
+ "User-Agent": sanitizeHeaderValue(ua),
51
+ Accept: "text/html,application/xhtml+xml,application/xml;q=0.9,application/json;q=0.8,*/*;q=0.7",
52
+ "Accept-Language": sanitizeHeaderValue(acceptLang),
53
+ "Accept-Encoding": "gzip, deflate",
54
+ "Content-Type": sanitizeHeaderValue(contentType),
55
+ Connection: "keep-alive",
56
+ DNT: "1",
57
+ "Upgrade-Insecure-Requests": "1",
58
+ "Sec-Fetch-Site": "same-origin",
59
+ "Sec-Fetch-Mode": "cors",
60
+ "Sec-Fetch-Dest": "empty",
61
+ "X-Requested-With": "XMLHttpRequest",
62
+ Pragma: "no-cache",
63
+ "Cache-Control": "no-cache"
64
+ };
65
+
66
+ if (ctx && ctx.region) {
67
+ var regionVal = sanitizeHeaderValue(ctx.region);
68
+ if (regionVal) headers["X-MSGR-Region"] = regionVal;
69
+ }
70
+
71
+ if (customHeader && typeof customHeader === "object") {
72
+ for (var key in customHeader) {
73
+ if (!Object.prototype.hasOwnProperty.call(customHeader, key)) continue;
74
+ var val = customHeader[key];
75
+ if (val === null || val === undefined || typeof val === "function" || typeof val === "object") continue;
76
+ var sk = sanitizeHeaderName(key);
77
+ var sv = sanitizeHeaderValue(val);
78
+ if (sk && sv !== "") headers[sk] = sv;
79
+ }
80
+ }
81
+
82
+ var sanitized = {};
83
+ for (var k in headers) {
84
+ if (!Object.prototype.hasOwnProperty.call(headers, k)) continue;
85
+ var sk2 = sanitizeHeaderName(k);
86
+ var sv2 = sanitizeHeaderValue(headers[k]);
87
+ if (sk2 && sv2 !== "") sanitized[sk2] = sv2;
88
+ }
89
+ return sanitized;
90
+ }
91
+
92
+ function isReadableStream(obj) {
93
+ return (
94
+ obj instanceof stream.Stream &&
95
+ (getType(obj._read) === "Function" || getType(obj._read) === "AsyncFunction") &&
96
+ getType(obj._readableState) === "Object"
97
+ );
98
+ }
99
+
100
+ function get(reqUrl, jar, qs, options, ctx) {
101
+ if (getType(qs) === "Object") {
102
+ for (var prop in qs) {
103
+ if (qs.hasOwnProperty(prop) && getType(qs[prop]) === "Object") qs[prop] = JSON.stringify(qs[prop]);
104
+ }
105
+ }
106
+ var op = {
107
+ headers: getHeaders(reqUrl, options, ctx),
108
+ timeout: 60000,
109
+ qs: qs,
110
+ url: reqUrl,
111
+ method: "GET",
112
+ jar: jar,
113
+ gzip: true
114
+ };
115
+ return request(op);
116
+ }
117
+
118
+ function post(reqUrl, jar, form, options, ctx, customHeader) {
119
+ var op = {
120
+ headers: getHeaders(reqUrl, options, ctx, customHeader),
121
+ timeout: 60000,
122
+ url: reqUrl,
123
+ method: "POST",
124
+ form: form,
125
+ jar: jar,
126
+ gzip: true
127
+ };
128
+ return request(op);
129
+ }
130
+
131
+ function postFormData(reqUrl, jar, form, qs, options, ctx) {
132
+ var headers = getHeaders(reqUrl, options, ctx);
133
+ headers["Content-Type"] = "multipart/form-data";
134
+ var op = {
135
+ headers: headers,
136
+ timeout: 60000,
137
+ url: reqUrl,
138
+ method: "POST",
139
+ formData: form,
140
+ qs: qs,
141
+ jar: jar,
142
+ gzip: true
143
+ };
144
+ return request(op);
145
+ }
146
+
147
+ function getJar() {
148
+ return require("request").jar();
149
+ }
150
+
151
+ function getAppState(jar) {
152
+ return jar.getCookies("https://www.facebook.com").map(c => ({
153
+ key: c.key,
154
+ value: c.value,
155
+ domain: c.domain,
156
+ path: c.path,
157
+ hostOnly: c.hostOnly,
158
+ creation: c.creation,
159
+ lastAccessed: c.lastAccessed
160
+ }));
161
+ }
162
+
163
+ function saveCookies(jar) {
164
+ return function (res) {
165
+ var cookies = res.headers["set-cookie"];
166
+ if (cookies) {
167
+ if (!Array.isArray(cookies)) cookies = [cookies];
168
+ cookies.forEach(c => {
169
+ try { jar.setCookie(c, "https://www.facebook.com"); } catch (_) { }
170
+ });
171
+ }
172
+ return res;
173
+ };
174
+ }
175
+
176
+ function getType(obj) {
177
+ return Object.prototype.toString.call(obj).slice(8, -1);
178
+ }
179
+
180
+ function getFrom(str, startToken, endToken) {
181
+ var start = str.indexOf(startToken) + startToken.length;
182
+ if (start < startToken.length) return "";
183
+ var end = str.indexOf(endToken, start);
184
+ if (end < 0) return "";
185
+ return str.slice(start, end);
186
+ }
187
+
188
+ function generateOfflineThreadingID() {
189
+ var ret = Date.now();
190
+ var value = Math.floor(Math.random() * 4294967295);
191
+ var str = ("0000000000000000000000" + value.toString(2)).slice(-22);
192
+ var msgs = ret.toString(2) + str;
193
+ return binaryToDecimal(msgs);
194
+ }
195
+
196
+ function binaryToDecimal(data) {
197
+ var ret = "";
198
+ while (data !== "0") {
199
+ var end = 0;
200
+ var fullName = "";
201
+ for (var i = 0; i < data.length; i++) {
202
+ end = 2 * end + parseInt(data[i], 10);
203
+ if (end >= 10) { fullName += "1"; end -= 10; }
204
+ else fullName += "0";
205
+ }
206
+ ret = end.toString() + ret;
207
+ data = fullName.slice(fullName.indexOf("1"));
208
+ }
209
+ return ret;
210
+ }
211
+
212
+ function generateThreadingID(clientID) {
213
+ var k = Date.now();
214
+ var l = Math.floor(Math.random() * 4294967295);
215
+ return "<" + k + ":" + l + "-" + clientID + "@mail.projektitan.com>";
216
+ }
217
+
218
+ function getGUID() {
219
+ var s4 = () => Math.floor((1 + Math.random()) * 0x10000).toString(16).substring(1);
220
+ return s4() + s4() + "-" + s4() + "-" + s4() + "-" + s4() + "-" + s4() + s4() + s4();
221
+ }
222
+
223
+ function arrToForm(arr) {
224
+ return arr.reduce((obj, item) => {
225
+ obj[item.name] = item.val;
226
+ return obj;
227
+ }, {});
228
+ }
229
+
230
+ function formatCookie(arr, domain) {
231
+ return arr[0] + "=" + arr[1] + ";domain=." + domain + ".com";
232
+ }
233
+
234
+ function formatID(id) {
235
+ return id && id.replace ? id.replace(/\D/g, "") : String(id);
236
+ }
237
+
238
+ function decodeClientPayload(payload) {
239
+ try {
240
+ return JSON.parse(String.fromCharCode.apply(null, payload));
241
+ } catch (_) {
242
+ return null;
243
+ }
244
+ }
245
+
246
+ function parseAndCheckLogin(ctx, defaultFuncs) {
247
+ return function (res) {
248
+ if (res.statusCode >= 500 && res.statusCode < 600) {
249
+ throw { error: "Facebook internal server error: " + res.statusCode, res };
250
+ }
251
+ if (res.statusCode === 404 || res.statusCode === 410) {
252
+ throw { error: "Endpoint not found: " + res.statusCode, res };
253
+ }
254
+ if (!res.body) throw { error: "Empty response body", res };
255
+
256
+ var body = res.body;
257
+ if (typeof body !== "string") body = JSON.stringify(body);
258
+
259
+ var stripped = body;
260
+ for (var prefix of ["for (;;);", "throw 1; /* "])
261
+ if (stripped.startsWith(prefix)) { stripped = stripped.slice(prefix.length); break; }
262
+
263
+ var data;
264
+ try {
265
+ var lines = stripped.split("\n").map(l => l.trim()).filter(l => l.length > 0);
266
+ if (lines.length > 1) {
267
+ data = lines.map(l => JSON.parse(l));
268
+ } else {
269
+ data = JSON.parse(stripped);
270
+ }
271
+ } catch (e) {
272
+ throw { error: "Could not parse JSON: " + e.message, body: body.slice(0, 200) };
273
+ }
274
+
275
+ if (!Array.isArray(data)) {
276
+ if (data.error === 1357001) throw { error: "Not logged in" };
277
+ if (data.error === 1357004) throw { error: "Request failed" };
278
+ }
279
+ return data;
280
+ };
281
+ }
282
+
283
+ function makeDefaults(html, userID, ctx) {
284
+ function postWithDefaults(reqUrl, jar, form, options, customHeader) {
285
+ var merged = Object.assign({
286
+ __user: userID,
287
+ __req: (++ctx.req_ID).toString(36),
288
+ __a: 1,
289
+ fb_dtsg: ctx.fb_dtsg || ""
290
+ }, form);
291
+ return post(reqUrl, jar, merged, options, ctx, customHeader);
292
+ }
293
+
294
+ function getWithDefaults(reqUrl, jar, qs, options) {
295
+ return get(reqUrl, jar, qs, options, ctx);
296
+ }
297
+
298
+ function postFormDataWithDefaults(reqUrl, jar, form, qs) {
299
+ var mergedQs = Object.assign({
300
+ __user: userID,
301
+ __req: (++ctx.req_ID).toString(36),
302
+ __a: 1,
303
+ fb_dtsg: ctx.fb_dtsg || ""
304
+ }, qs);
305
+ return postFormData(reqUrl, jar, form, mergedQs, {}, ctx);
306
+ }
307
+
308
+ return {
309
+ post: postWithDefaults,
310
+ get: getWithDefaults,
311
+ postFormData: postFormDataWithDefaults
312
+ };
313
+ }
314
+
315
+ function _formatAttachment(attachment, atch) {
316
+ atch = atch || attachment.mercury || {};
317
+ // Also pull in mercuryJSON if mercury was empty
318
+ if (attachment.mercuryJSON && !atch.attach_type && !atch.blob_attachment && !atch.sticker_attachment) {
319
+ try { Object.assign(atch, JSON.parse(attachment.mercuryJSON)); } catch (_) {}
320
+ }
321
+
322
+ var attach_type = atch.attach_type;
323
+ var preview = atch.metadata || {};
324
+ var attach = {
325
+ type: "unknown",
326
+ ID: attachment.attach_fbid ? attachment.attach_fbid.toString() : null,
327
+ };
328
+
329
+ switch (attach_type) {
330
+ case "photo":
331
+ attach.type = "photo";
332
+ attach.name = atch.name;
333
+ attach.filename = atch.filename || atch.fileName;
334
+ attach.url = preview.url || atch.metadata && atch.metadata.url;
335
+ attach.previewUrl = atch.preview_url || null;
336
+ attach.largePreviewUrl = atch.large_preview_url || null;
337
+ attach.width = preview.dimensions ? (preview.dimensions.width || preview.dimensions.split && parseInt(preview.dimensions.split(",")[0]) || 0) : 0;
338
+ attach.height = preview.dimensions ? (preview.dimensions.height || preview.dimensions.split && parseInt(preview.dimensions.split(",")[1]) || 0) : 0;
339
+ break;
340
+ case "video":
341
+ attach.type = "video";
342
+ attach.name = atch.name;
343
+ attach.filename = atch.filename;
344
+ attach.url = preview.url;
345
+ attach.width = preview.dimensions ? preview.dimensions.width : 0;
346
+ attach.height = preview.dimensions ? preview.dimensions.height : 0;
347
+ attach.duration = preview.duration;
348
+ break;
349
+ case "audio":
350
+ attach.type = "audio";
351
+ attach.name = atch.name;
352
+ attach.filename = atch.filename;
353
+ attach.url = preview.url;
354
+ attach.duration = preview.duration;
355
+ break;
356
+ case "file":
357
+ attach.type = "file";
358
+ attach.name = atch.name;
359
+ attach.filename = atch.filename;
360
+ attach.url = preview.url;
361
+ attach.size = preview.size;
362
+ attach.mimeType = atch.mimeType;
363
+ break;
364
+ case "animated_image":
365
+ attach.type = "animated_image";
366
+ attach.name = atch.name;
367
+ attach.filename = atch.filename;
368
+ attach.previewUrl = atch.preview_url || null;
369
+ attach.url = (preview && preview.image_data && preview.image_data.url)
370
+ || atch.url || atch.thumbnail_url || null;
371
+ break;
372
+ case "sticker":
373
+ attach.type = "sticker";
374
+ attach.url = atch.url;
375
+ attach.stickerID = (preview.stickerID && preview.stickerID.toString())
376
+ || (attachment.attach_fbid && attachment.attach_fbid.toString()) || null;
377
+ attach.ID = attach.stickerID;
378
+ attach.packID = (preview.packID && preview.packID.toString()) || (atch.pack ? atch.pack.id : null);
379
+ attach.spriteUrl = preview.spriteURI || atch.sprite_image;
380
+ attach.spriteUrl2x = preview.spriteURI2x || atch.sprite_image_2x;
381
+ attach.width = preview.width || atch.width;
382
+ attach.height = preview.height || atch.height;
383
+ attach.caption = atch.caption;
384
+ attach.description = atch.description;
385
+ attach.frameCount = preview.frameCount || atch.frame_count;
386
+ attach.frameRate = preview.frameRate || atch.frame_rate;
387
+ attach.framesPerRow = preview.framesPerRow || atch.frames_per_row;
388
+ attach.framesPerCol = preview.framesPerCol || atch.frames_per_column;
389
+ break;
390
+ default: {
391
+ // blob_attachment lives inside atch (mercury) for MQTT delta messages.
392
+ // Fall back to attachment.blob_attachment for ForcedFetch / getThreadHistory paths.
393
+ var blob = atch.blob_attachment || attachment.blob_attachment;
394
+ if (blob) {
395
+ var typename = blob.__typename || "";
396
+ switch (typename) {
397
+ case "MessageImage":
398
+ attach.type = "photo";
399
+ attach.url = (blob.large_preview || blob.preview || {}).uri || null;
400
+ attach.previewUrl = (blob.preview || {}).uri || null;
401
+ attach.largePreviewUrl = (blob.large_preview || {}).uri || null;
402
+ attach.width = (blob.large_preview || {}).width || 0;
403
+ attach.height = (blob.large_preview || {}).height || 0;
404
+ break;
405
+ case "MessageVideo":
406
+ attach.type = "video";
407
+ attach.url = blob.playable_url_quality_hd || blob.playable_url || null;
408
+ attach.duration = blob.playable_duration_in_ms;
409
+ break;
410
+ case "MessageAudio":
411
+ attach.type = "audio";
412
+ attach.url = blob.playable_url || null;
413
+ attach.duration = blob.playable_duration_in_ms;
414
+ attach.audioType = blob.audio_type;
415
+ attach.isVoiceMail = blob.is_voicemail;
416
+ break;
417
+ case "MessageFile":
418
+ attach.type = "file";
419
+ attach.url = blob.url || null;
420
+ attach.mimeType = blob.content_type;
421
+ break;
422
+ case "MessageAnimatedImage":
423
+ attach.type = "animated_image";
424
+ attach.url = (blob.animated_image || blob.preview || {}).uri || null;
425
+ attach.previewUrl = (blob.preview || {}).uri || null;
426
+ break;
427
+ default:
428
+ attach.type = typename.toLowerCase() || "unknown";
429
+ }
430
+ attach.filename = blob.filename;
431
+ attach.name = blob.filename;
432
+ attach.ID = blob.legacy_attachment_id || blob.message_file_fbid || attach.ID;
433
+ }
434
+
435
+ // sticker_attachment lives inside atch (mercury) in MQTT delta messages
436
+ if (!blob && atch.sticker_attachment) {
437
+ var sticker = atch.sticker_attachment;
438
+ attach.type = "sticker";
439
+ attach.stickerID = sticker.id ? sticker.id.toString() : attach.ID;
440
+ attach.ID = attach.stickerID;
441
+ attach.url = sticker.url || null;
442
+ attach.packID = sticker.pack ? sticker.pack.id : null;
443
+ attach.width = sticker.width;
444
+ attach.height = sticker.height;
445
+ attach.frameCount = sticker.frame_count;
446
+ attach.frameRate = sticker.frame_rate;
447
+ attach.framesPerRow = sticker.frames_per_row;
448
+ attach.framesPerCol = sticker.frames_per_column;
449
+ attach.spriteUrl = sticker.sprite_image;
450
+ attach.spriteUrl2x = sticker.sprite_image_2x;
451
+ }
452
+ }
453
+ }
454
+ return attach;
455
+ }
456
+
457
+ function _splitCsv(str) {
458
+ if (!str) return [];
459
+ return String(str).split(",").map(s => s.trim()).filter(Boolean);
460
+ }
461
+
462
+ function _extractMentions(delta, body) {
463
+ var mentions = {};
464
+ var d = delta.data || {};
465
+
466
+ // Strategy 1: prng JSON array [{i, o, l}] — legacy delta format
467
+ try {
468
+ if (d.prng) {
469
+ JSON.parse(d.prng).forEach(function(u) {
470
+ if (u && u.i != null)
471
+ mentions[u.i] = body.substring(u.o || 0, (u.o || 0) + (u.l || 0));
472
+ });
473
+ }
474
+ } catch (_) {}
475
+
476
+ // Strategy 2: flat CSV fields in data (data.mention_ids / mentions_ids / mentionIds)
477
+ if (!Object.keys(mentions).length) {
478
+ var mids = _splitCsv(d.mention_ids || d.mentions_ids || d.mentionIds);
479
+ var mos = _splitCsv(d.mention_offsets || d.mentions_offsets || d.mentionOffsets);
480
+ var mls = _splitCsv(d.mention_lengths || d.mentions_lengths || d.mentionLengths);
481
+ for (var i = 0; i < mids.length; i++) {
482
+ var o = parseInt(mos[i]) || 0, l = parseInt(mls[i]) || 0;
483
+ if (mids[i]) mentions[mids[i]] = body.substring(o, o + l);
484
+ }
485
+ }
486
+
487
+ // Strategy 3: ranges / profileRanges array (newer delta format)
488
+ if (!Object.keys(mentions).length) {
489
+ var ranges = [];
490
+ if (Array.isArray(delta.ranges)) ranges = delta.ranges;
491
+ else if (Array.isArray(d.ranges)) ranges = d.ranges;
492
+ else if (Array.isArray(delta.profileRanges)) ranges = delta.profileRanges;
493
+ else if (Array.isArray(d.profileRanges)) ranges = d.profileRanges;
494
+ else if (typeof d.ranges === "string") { try { ranges = JSON.parse(d.ranges); } catch (_) {} }
495
+ ranges.forEach(function(r) {
496
+ var id = (r && r.entity && r.entity.id) || (r && r.id) || (r && r.i);
497
+ var ro = r && (r.offset != null ? r.offset : r.o);
498
+ var rl = r && (r.length != null ? r.length : r.l);
499
+ if (id && rl) mentions[id] = body.substring(ro || 0, (ro || 0) + rl);
500
+ });
501
+ }
502
+
503
+ // Strategy 4: Gb protobuf nested format — Facebook encodes mentions inside
504
+ // messageMetadata.data.data.Gb.asMap.data when sending via the newer Gb path.
505
+ // Reference: stfca formatDeltaMessage (confirmed working in v1.3.2+)
506
+ if (!Object.keys(mentions).length) {
507
+ try {
508
+ var md2 = delta.messageMetadata || {};
509
+ var gbData = md2.data && md2.data.data && md2.data.data.Gb &&
510
+ md2.data.data.Gb.asMap && md2.data.data.Gb.asMap.data;
511
+ if (gbData) {
512
+ for (var key in gbData) {
513
+ if (!Object.prototype.hasOwnProperty.call(gbData, key)) continue;
514
+ var entry = gbData[key];
515
+ if (entry && entry.asMap && entry.asMap.data) {
516
+ var ed = entry.asMap.data;
517
+ var gid = ed.id && ed.id.asLong ? String(ed.id.asLong) : null;
518
+ var go = parseInt(ed.offset && ed.offset.asLong ? ed.offset.asLong : 0, 10);
519
+ var gl = parseInt(ed.length && ed.length.asLong ? ed.length.asLong : 0, 10);
520
+ if (gid != null) mentions[gid] = body.substring(go, go + gl);
521
+ }
522
+ }
523
+ }
524
+ } catch (_) {}
525
+ }
526
+
527
+ return mentions;
528
+ }
529
+
530
+ function formatDeltaMessage(v) {
531
+ var delta = v.delta;
532
+ var md = delta.messageMetadata || {};
533
+ var body = delta.body || "";
534
+ var mentions = _extractMentions(delta, body);
535
+ var threadKey = md.threadKey || {};
536
+ var threadID = (threadKey.threadFbId || threadKey.otherUserFbId || "").toString();
537
+ return {
538
+ type: "message",
539
+ senderID: (md.actorFbId || "").toString(),
540
+ body: body,
541
+ threadID: formatID(threadID),
542
+ messageID: md.messageId,
543
+ attachments: (delta.attachments || []).map(att => {
544
+ var mercury = att.mercury || {};
545
+ if (att.mercuryJSON) {
546
+ try { Object.assign(mercury, JSON.parse(att.mercuryJSON)); } catch (_) { }
547
+ }
548
+ var x;
549
+ try { x = _formatAttachment(att, mercury); }
550
+ catch (ex) { x = { type: "unknown", error: ex }; }
551
+ return x;
552
+ }),
553
+ args: body.trim().split(/\s+/),
554
+ mentions: mentions,
555
+ timestamp: parseInt(md.timestamp),
556
+ isGroup: !!threadKey.threadFbId,
557
+ participantIDs: (md.cid && md.cid.canonicalParticipantFbids) ? md.cid.canonicalParticipantFbids.map(e => e.toString()) : []
558
+ };
559
+ }
560
+
561
+ function _getAdminTextMessageType(delta) {
562
+ switch (delta.type) {
563
+ case "joinable_group_link_mode_change": return "log:link-status";
564
+ case "magic_words": return "log:magic-words";
565
+ case "change_thread_theme": return "log:thread-color";
566
+ case "change_thread_icon": return "log:thread-icon";
567
+ case "change_thread_nickname": return "log:user-nickname";
568
+ case "change_thread_admins": return "log:thread-admins";
569
+ case "group_poll": return "log:thread-poll";
570
+ case "change_thread_approval_mode": return "log:thread-approval-mode";
571
+ case "messenger_call_log":
572
+ case "participant_joined_group_call": return "log:thread-call";
573
+ case "pin_messages_v2":
574
+ case "unpin_messages_v2": return "log:thread-pinned";
575
+ case "confirm_friend_request": return "log:confirmed-friend-request";
576
+ case "shared_album_delete":
577
+ case "shared_album_addition": return "log:shared-album";
578
+ default: return delta.type || "log:unknown";
579
+ }
580
+ }
581
+
582
+ function formatDeltaEvent(delta) {
583
+ var md = delta.messageMetadata || {};
584
+ var threadKey = md.threadKey || {};
585
+ var threadID = (threadKey.threadFbId || threadKey.otherUserFbId || "").toString();
586
+ var participantIDs = (delta.participants || []).map(function(p) { return p.toString(); });
587
+
588
+ switch (delta.class) {
589
+ case "AdminTextMessage":
590
+ return {
591
+ type: "event",
592
+ threadID: formatID(threadID),
593
+ messageID: md.messageId,
594
+ author: (md.actorFbId || "").toString(),
595
+ logMessageType: _getAdminTextMessageType(delta),
596
+ logMessageData: delta.untypedData || {},
597
+ logMessageBody: md.adminText || "",
598
+ participantIDs: participantIDs,
599
+ timestamp: parseInt(md.timestamp)
600
+ };
601
+ case "ThreadName":
602
+ return {
603
+ type: "event",
604
+ threadID: formatID(threadID),
605
+ messageID: md.messageId,
606
+ author: (md.actorFbId || "").toString(),
607
+ logMessageType: "log:thread-name",
608
+ logMessageData: { name: delta.name },
609
+ logMessageBody: md.adminText || "",
610
+ participantIDs: participantIDs,
611
+ timestamp: parseInt(md.timestamp)
612
+ };
613
+ case "ParticipantsAddedToGroupThread":
614
+ return {
615
+ type: "event",
616
+ threadID: formatID(threadID),
617
+ messageID: md.messageId,
618
+ author: (md.actorFbId || "").toString(),
619
+ logMessageType: "log:subscribe",
620
+ logMessageData: { addedParticipants: delta.addedParticipants || [] },
621
+ logMessageBody: md.adminText || "",
622
+ participantIDs: participantIDs,
623
+ timestamp: parseInt(md.timestamp)
624
+ };
625
+ case "ParticipantLeftGroupThread":
626
+ return {
627
+ type: "event",
628
+ threadID: formatID(threadID),
629
+ messageID: md.messageId,
630
+ author: (md.actorFbId || "").toString(),
631
+ logMessageType: "log:unsubscribe",
632
+ logMessageData: { leftParticipantFbId: (delta.leftParticipantFbId || "").toString() },
633
+ logMessageBody: md.adminText || "",
634
+ participantIDs: participantIDs,
635
+ timestamp: parseInt(md.timestamp)
636
+ };
637
+ default:
638
+ return {
639
+ type: "event",
640
+ threadID: formatID(threadID),
641
+ messageID: md.messageId,
642
+ author: (md.actorFbId || "").toString(),
643
+ logMessageType: delta.class || "unknown",
644
+ logMessageData: delta.untypedData || {},
645
+ logMessageBody: md.adminText || "",
646
+ participantIDs: participantIDs,
647
+ timestamp: parseInt(md.timestamp)
648
+ };
649
+ }
650
+ }
651
+
652
+ function wrapCallback(callback) {
653
+ var resolve, reject;
654
+ var promise = new Promise((res, rej) => { resolve = res; reject = rej; });
655
+ if (!callback) {
656
+ callback = (err, data) => err ? reject(err) : resolve(data);
657
+ }
658
+ return { callback, promise };
659
+ }
660
+
661
+ module.exports = {
662
+ setProxy,
663
+ get,
664
+ post,
665
+ postFormData,
666
+ getJar,
667
+ getAppState,
668
+ saveCookies,
669
+ getType,
670
+ getFrom,
671
+ getHeaders,
672
+ isReadableStream,
673
+ generateOfflineThreadingID,
674
+ generateThreadingID,
675
+ getGUID,
676
+ arrToForm,
677
+ formatCookie,
678
+ formatID,
679
+ decodeClientPayload,
680
+ parseAndCheckLogin,
681
+ makeDefaults,
682
+ _formatAttachment,
683
+ formatDeltaMessage,
684
+ formatDeltaEvent,
685
+ wrapCallback,
686
+ };