zai-fca 1.0.9

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 zai-fca might be problematic. Click here for more details.

Files changed (290) hide show
  1. package/.cache/replit/env/latest +56 -0
  2. package/.cache/replit/env/latest.json +1 -0
  3. package/.cache/replit/modules/nodejs-20.res +1 -0
  4. package/.cache/replit/modules/replit.res +1 -0
  5. package/.cache/replit/modules.stamp +0 -0
  6. package/.cache/typescript/5.6/node_modules/.package-lock.json +178 -0
  7. package/.cache/typescript/5.6/node_modules/@types/bluebird/LICENSE +21 -0
  8. package/.cache/typescript/5.6/node_modules/@types/bluebird/README.md +15 -0
  9. package/.cache/typescript/5.6/node_modules/@types/bluebird/index.d.ts +1365 -0
  10. package/.cache/typescript/5.6/node_modules/@types/bluebird/package.json +25 -0
  11. package/.cache/typescript/5.6/node_modules/@types/caseless/LICENSE +21 -0
  12. package/.cache/typescript/5.6/node_modules/@types/caseless/README.md +48 -0
  13. package/.cache/typescript/5.6/node_modules/@types/caseless/index.d.ts +29 -0
  14. package/.cache/typescript/5.6/node_modules/@types/caseless/package.json +35 -0
  15. package/.cache/typescript/5.6/node_modules/@types/mocha/LICENSE +21 -0
  16. package/.cache/typescript/5.6/node_modules/@types/mocha/README.md +15 -0
  17. package/.cache/typescript/5.6/node_modules/@types/mocha/index.d.ts +2929 -0
  18. package/.cache/typescript/5.6/node_modules/@types/mocha/package.json +56 -0
  19. package/.cache/typescript/5.6/node_modules/@types/node/LICENSE +21 -0
  20. package/.cache/typescript/5.6/node_modules/@types/node/README.md +15 -0
  21. package/.cache/typescript/5.6/node_modules/@types/node/assert/strict.d.ts +8 -0
  22. package/.cache/typescript/5.6/node_modules/@types/node/assert.d.ts +1040 -0
  23. package/.cache/typescript/5.6/node_modules/@types/node/async_hooks.d.ts +541 -0
  24. package/.cache/typescript/5.6/node_modules/@types/node/buffer.buffer.d.ts +385 -0
  25. package/.cache/typescript/5.6/node_modules/@types/node/buffer.d.ts +1933 -0
  26. package/.cache/typescript/5.6/node_modules/@types/node/child_process.d.ts +1549 -0
  27. package/.cache/typescript/5.6/node_modules/@types/node/cluster.d.ts +579 -0
  28. package/.cache/typescript/5.6/node_modules/@types/node/compatibility/disposable.d.ts +16 -0
  29. package/.cache/typescript/5.6/node_modules/@types/node/compatibility/index.d.ts +9 -0
  30. package/.cache/typescript/5.6/node_modules/@types/node/compatibility/indexable.d.ts +23 -0
  31. package/.cache/typescript/5.6/node_modules/@types/node/compatibility/iterators.d.ts +21 -0
  32. package/.cache/typescript/5.6/node_modules/@types/node/console.d.ts +452 -0
  33. package/.cache/typescript/5.6/node_modules/@types/node/constants.d.ts +19 -0
  34. package/.cache/typescript/5.6/node_modules/@types/node/crypto.d.ts +4475 -0
  35. package/.cache/typescript/5.6/node_modules/@types/node/dgram.d.ts +596 -0
  36. package/.cache/typescript/5.6/node_modules/@types/node/diagnostics_channel.d.ts +554 -0
  37. package/.cache/typescript/5.6/node_modules/@types/node/dns/promises.d.ts +476 -0
  38. package/.cache/typescript/5.6/node_modules/@types/node/dns.d.ts +865 -0
  39. package/.cache/typescript/5.6/node_modules/@types/node/dom-events.d.ts +124 -0
  40. package/.cache/typescript/5.6/node_modules/@types/node/domain.d.ts +170 -0
  41. package/.cache/typescript/5.6/node_modules/@types/node/events.d.ts +931 -0
  42. package/.cache/typescript/5.6/node_modules/@types/node/fs/promises.d.ts +1275 -0
  43. package/.cache/typescript/5.6/node_modules/@types/node/fs.d.ts +4396 -0
  44. package/.cache/typescript/5.6/node_modules/@types/node/globals.d.ts +566 -0
  45. package/.cache/typescript/5.6/node_modules/@types/node/globals.typedarray.d.ts +21 -0
  46. package/.cache/typescript/5.6/node_modules/@types/node/http.d.ts +1958 -0
  47. package/.cache/typescript/5.6/node_modules/@types/node/http2.d.ts +2558 -0
  48. package/.cache/typescript/5.6/node_modules/@types/node/https.d.ts +543 -0
  49. package/.cache/typescript/5.6/node_modules/@types/node/index.d.ts +92 -0
  50. package/.cache/typescript/5.6/node_modules/@types/node/inspector.d.ts +3966 -0
  51. package/.cache/typescript/5.6/node_modules/@types/node/module.d.ts +402 -0
  52. package/.cache/typescript/5.6/node_modules/@types/node/net.d.ts +1001 -0
  53. package/.cache/typescript/5.6/node_modules/@types/node/os.d.ts +495 -0
  54. package/.cache/typescript/5.6/node_modules/@types/node/package.json +220 -0
  55. package/.cache/typescript/5.6/node_modules/@types/node/path.d.ts +200 -0
  56. package/.cache/typescript/5.6/node_modules/@types/node/perf_hooks.d.ts +965 -0
  57. package/.cache/typescript/5.6/node_modules/@types/node/process.d.ts +1963 -0
  58. package/.cache/typescript/5.6/node_modules/@types/node/punycode.d.ts +117 -0
  59. package/.cache/typescript/5.6/node_modules/@types/node/querystring.d.ts +153 -0
  60. package/.cache/typescript/5.6/node_modules/@types/node/readline/promises.d.ts +162 -0
  61. package/.cache/typescript/5.6/node_modules/@types/node/readline.d.ts +589 -0
  62. package/.cache/typescript/5.6/node_modules/@types/node/repl.d.ts +430 -0
  63. package/.cache/typescript/5.6/node_modules/@types/node/sea.d.ts +153 -0
  64. package/.cache/typescript/5.6/node_modules/@types/node/sqlite.d.ts +213 -0
  65. package/.cache/typescript/5.6/node_modules/@types/node/stream/consumers.d.ts +12 -0
  66. package/.cache/typescript/5.6/node_modules/@types/node/stream/promises.d.ts +90 -0
  67. package/.cache/typescript/5.6/node_modules/@types/node/stream/web.d.ts +609 -0
  68. package/.cache/typescript/5.6/node_modules/@types/node/stream.d.ts +1726 -0
  69. package/.cache/typescript/5.6/node_modules/@types/node/string_decoder.d.ts +67 -0
  70. package/.cache/typescript/5.6/node_modules/@types/node/test.d.ts +2248 -0
  71. package/.cache/typescript/5.6/node_modules/@types/node/timers/promises.d.ts +97 -0
  72. package/.cache/typescript/5.6/node_modules/@types/node/timers.d.ts +240 -0
  73. package/.cache/typescript/5.6/node_modules/@types/node/tls.d.ts +1226 -0
  74. package/.cache/typescript/5.6/node_modules/@types/node/trace_events.d.ts +197 -0
  75. package/.cache/typescript/5.6/node_modules/@types/node/ts5.6/buffer.buffer.d.ts +385 -0
  76. package/.cache/typescript/5.6/node_modules/@types/node/ts5.6/globals.typedarray.d.ts +19 -0
  77. package/.cache/typescript/5.6/node_modules/@types/node/ts5.6/index.d.ts +92 -0
  78. package/.cache/typescript/5.6/node_modules/@types/node/tty.d.ts +208 -0
  79. package/.cache/typescript/5.6/node_modules/@types/node/url.d.ts +972 -0
  80. package/.cache/typescript/5.6/node_modules/@types/node/util.d.ts +2371 -0
  81. package/.cache/typescript/5.6/node_modules/@types/node/v8.d.ts +808 -0
  82. package/.cache/typescript/5.6/node_modules/@types/node/vm.d.ts +976 -0
  83. package/.cache/typescript/5.6/node_modules/@types/node/wasi.d.ts +181 -0
  84. package/.cache/typescript/5.6/node_modules/@types/node/worker_threads.d.ts +745 -0
  85. package/.cache/typescript/5.6/node_modules/@types/node/zlib.d.ts +539 -0
  86. package/.cache/typescript/5.6/node_modules/@types/node-cron/LICENSE +21 -0
  87. package/.cache/typescript/5.6/node_modules/@types/node-cron/README.md +76 -0
  88. package/.cache/typescript/5.6/node_modules/@types/node-cron/index.d.ts +57 -0
  89. package/.cache/typescript/5.6/node_modules/@types/node-cron/package.json +50 -0
  90. package/.cache/typescript/5.6/node_modules/@types/npmlog/LICENSE +21 -0
  91. package/.cache/typescript/5.6/node_modules/@types/npmlog/README.md +15 -0
  92. package/.cache/typescript/5.6/node_modules/@types/npmlog/index.d.ts +84 -0
  93. package/.cache/typescript/5.6/node_modules/@types/npmlog/package.json +32 -0
  94. package/.cache/typescript/5.6/node_modules/@types/request/LICENSE +21 -0
  95. package/.cache/typescript/5.6/node_modules/@types/request/README.md +15 -0
  96. package/.cache/typescript/5.6/node_modules/@types/request/index.d.ts +395 -0
  97. package/.cache/typescript/5.6/node_modules/@types/request/package.json +70 -0
  98. package/.cache/typescript/5.6/node_modules/@types/tough-cookie/LICENSE +21 -0
  99. package/.cache/typescript/5.6/node_modules/@types/tough-cookie/README.md +15 -0
  100. package/.cache/typescript/5.6/node_modules/@types/tough-cookie/index.d.ts +321 -0
  101. package/.cache/typescript/5.6/node_modules/@types/tough-cookie/package.json +35 -0
  102. package/.cache/typescript/5.6/node_modules/asynckit/LICENSE +21 -0
  103. package/.cache/typescript/5.6/node_modules/asynckit/README.md +233 -0
  104. package/.cache/typescript/5.6/node_modules/asynckit/bench.js +76 -0
  105. package/.cache/typescript/5.6/node_modules/asynckit/index.js +6 -0
  106. package/.cache/typescript/5.6/node_modules/asynckit/lib/abort.js +29 -0
  107. package/.cache/typescript/5.6/node_modules/asynckit/lib/async.js +34 -0
  108. package/.cache/typescript/5.6/node_modules/asynckit/lib/defer.js +26 -0
  109. package/.cache/typescript/5.6/node_modules/asynckit/lib/iterate.js +75 -0
  110. package/.cache/typescript/5.6/node_modules/asynckit/lib/readable_asynckit.js +91 -0
  111. package/.cache/typescript/5.6/node_modules/asynckit/lib/readable_parallel.js +25 -0
  112. package/.cache/typescript/5.6/node_modules/asynckit/lib/readable_serial.js +25 -0
  113. package/.cache/typescript/5.6/node_modules/asynckit/lib/readable_serial_ordered.js +29 -0
  114. package/.cache/typescript/5.6/node_modules/asynckit/lib/state.js +37 -0
  115. package/.cache/typescript/5.6/node_modules/asynckit/lib/streamify.js +141 -0
  116. package/.cache/typescript/5.6/node_modules/asynckit/lib/terminator.js +29 -0
  117. package/.cache/typescript/5.6/node_modules/asynckit/package.json +63 -0
  118. package/.cache/typescript/5.6/node_modules/asynckit/parallel.js +43 -0
  119. package/.cache/typescript/5.6/node_modules/asynckit/serial.js +17 -0
  120. package/.cache/typescript/5.6/node_modules/asynckit/serialOrdered.js +75 -0
  121. package/.cache/typescript/5.6/node_modules/asynckit/stream.js +21 -0
  122. package/.cache/typescript/5.6/node_modules/combined-stream/License +19 -0
  123. package/.cache/typescript/5.6/node_modules/combined-stream/Readme.md +138 -0
  124. package/.cache/typescript/5.6/node_modules/combined-stream/lib/combined_stream.js +208 -0
  125. package/.cache/typescript/5.6/node_modules/combined-stream/package.json +25 -0
  126. package/.cache/typescript/5.6/node_modules/combined-stream/yarn.lock +17 -0
  127. package/.cache/typescript/5.6/node_modules/delayed-stream/License +19 -0
  128. package/.cache/typescript/5.6/node_modules/delayed-stream/Makefile +7 -0
  129. package/.cache/typescript/5.6/node_modules/delayed-stream/Readme.md +141 -0
  130. package/.cache/typescript/5.6/node_modules/delayed-stream/lib/delayed_stream.js +107 -0
  131. package/.cache/typescript/5.6/node_modules/delayed-stream/package.json +27 -0
  132. package/.cache/typescript/5.6/node_modules/form-data/License +19 -0
  133. package/.cache/typescript/5.6/node_modules/form-data/Readme.md +350 -0
  134. package/.cache/typescript/5.6/node_modules/form-data/index.d.ts +51 -0
  135. package/.cache/typescript/5.6/node_modules/form-data/lib/browser.js +2 -0
  136. package/.cache/typescript/5.6/node_modules/form-data/lib/form_data.js +484 -0
  137. package/.cache/typescript/5.6/node_modules/form-data/lib/populate.js +10 -0
  138. package/.cache/typescript/5.6/node_modules/form-data/package.json +72 -0
  139. package/.cache/typescript/5.6/node_modules/mime-db/HISTORY.md +507 -0
  140. package/.cache/typescript/5.6/node_modules/mime-db/LICENSE +23 -0
  141. package/.cache/typescript/5.6/node_modules/mime-db/README.md +100 -0
  142. package/.cache/typescript/5.6/node_modules/mime-db/db.json +8519 -0
  143. package/.cache/typescript/5.6/node_modules/mime-db/index.js +12 -0
  144. package/.cache/typescript/5.6/node_modules/mime-db/package.json +60 -0
  145. package/.cache/typescript/5.6/node_modules/mime-types/HISTORY.md +397 -0
  146. package/.cache/typescript/5.6/node_modules/mime-types/LICENSE +23 -0
  147. package/.cache/typescript/5.6/node_modules/mime-types/README.md +113 -0
  148. package/.cache/typescript/5.6/node_modules/mime-types/index.js +188 -0
  149. package/.cache/typescript/5.6/node_modules/mime-types/package.json +44 -0
  150. package/.cache/typescript/5.6/node_modules/safe-buffer/LICENSE +21 -0
  151. package/.cache/typescript/5.6/node_modules/safe-buffer/README.md +584 -0
  152. package/.cache/typescript/5.6/node_modules/safe-buffer/index.d.ts +187 -0
  153. package/.cache/typescript/5.6/node_modules/safe-buffer/index.js +65 -0
  154. package/.cache/typescript/5.6/node_modules/safe-buffer/package.json +51 -0
  155. package/.cache/typescript/5.6/node_modules/types-registry/README.md +2 -0
  156. package/.cache/typescript/5.6/node_modules/types-registry/index.json +1 -0
  157. package/.cache/typescript/5.6/node_modules/types-registry/package.json +20 -0
  158. package/.cache/typescript/5.6/node_modules/undici-types/LICENSE +21 -0
  159. package/.cache/typescript/5.6/node_modules/undici-types/README.md +6 -0
  160. package/.cache/typescript/5.6/node_modules/undici-types/agent.d.ts +31 -0
  161. package/.cache/typescript/5.6/node_modules/undici-types/api.d.ts +43 -0
  162. package/.cache/typescript/5.6/node_modules/undici-types/balanced-pool.d.ts +29 -0
  163. package/.cache/typescript/5.6/node_modules/undici-types/cache.d.ts +36 -0
  164. package/.cache/typescript/5.6/node_modules/undici-types/client.d.ts +108 -0
  165. package/.cache/typescript/5.6/node_modules/undici-types/connector.d.ts +34 -0
  166. package/.cache/typescript/5.6/node_modules/undici-types/content-type.d.ts +21 -0
  167. package/.cache/typescript/5.6/node_modules/undici-types/cookies.d.ts +28 -0
  168. package/.cache/typescript/5.6/node_modules/undici-types/diagnostics-channel.d.ts +66 -0
  169. package/.cache/typescript/5.6/node_modules/undici-types/dispatcher.d.ts +255 -0
  170. package/.cache/typescript/5.6/node_modules/undici-types/env-http-proxy-agent.d.ts +21 -0
  171. package/.cache/typescript/5.6/node_modules/undici-types/errors.d.ts +149 -0
  172. package/.cache/typescript/5.6/node_modules/undici-types/eventsource.d.ts +61 -0
  173. package/.cache/typescript/5.6/node_modules/undici-types/fetch.d.ts +209 -0
  174. package/.cache/typescript/5.6/node_modules/undici-types/file.d.ts +39 -0
  175. package/.cache/typescript/5.6/node_modules/undici-types/filereader.d.ts +54 -0
  176. package/.cache/typescript/5.6/node_modules/undici-types/formdata.d.ts +108 -0
  177. package/.cache/typescript/5.6/node_modules/undici-types/global-dispatcher.d.ts +9 -0
  178. package/.cache/typescript/5.6/node_modules/undici-types/global-origin.d.ts +7 -0
  179. package/.cache/typescript/5.6/node_modules/undici-types/handlers.d.ts +15 -0
  180. package/.cache/typescript/5.6/node_modules/undici-types/header.d.ts +4 -0
  181. package/.cache/typescript/5.6/node_modules/undici-types/index.d.ts +71 -0
  182. package/.cache/typescript/5.6/node_modules/undici-types/interceptors.d.ts +17 -0
  183. package/.cache/typescript/5.6/node_modules/undici-types/mock-agent.d.ts +50 -0
  184. package/.cache/typescript/5.6/node_modules/undici-types/mock-client.d.ts +25 -0
  185. package/.cache/typescript/5.6/node_modules/undici-types/mock-errors.d.ts +12 -0
  186. package/.cache/typescript/5.6/node_modules/undici-types/mock-interceptor.d.ts +93 -0
  187. package/.cache/typescript/5.6/node_modules/undici-types/mock-pool.d.ts +25 -0
  188. package/.cache/typescript/5.6/node_modules/undici-types/package.json +55 -0
  189. package/.cache/typescript/5.6/node_modules/undici-types/patch.d.ts +33 -0
  190. package/.cache/typescript/5.6/node_modules/undici-types/pool-stats.d.ts +19 -0
  191. package/.cache/typescript/5.6/node_modules/undici-types/pool.d.ts +39 -0
  192. package/.cache/typescript/5.6/node_modules/undici-types/proxy-agent.d.ts +28 -0
  193. package/.cache/typescript/5.6/node_modules/undici-types/readable.d.ts +60 -0
  194. package/.cache/typescript/5.6/node_modules/undici-types/retry-agent.d.ts +8 -0
  195. package/.cache/typescript/5.6/node_modules/undici-types/retry-handler.d.ts +116 -0
  196. package/.cache/typescript/5.6/node_modules/undici-types/util.d.ts +18 -0
  197. package/.cache/typescript/5.6/node_modules/undici-types/webidl.d.ts +222 -0
  198. package/.cache/typescript/5.6/node_modules/undici-types/websocket.d.ts +150 -0
  199. package/.cache/typescript/5.6/package-lock.json +190 -0
  200. package/.cache/typescript/5.6/package.json +1 -0
  201. package/.replit +4 -0
  202. package/.upm/store.json +1 -0
  203. package/LICENSE +21 -0
  204. package/README.md +289 -0
  205. package/index.js +523 -0
  206. package/package.json +45 -0
  207. package/src/Screenshot.js +83 -0
  208. package/src/addExternalModule.js +25 -0
  209. package/src/addUserToGroup.js +115 -0
  210. package/src/changeAdminStatus.js +103 -0
  211. package/src/changeArchivedStatus.js +55 -0
  212. package/src/changeAvatar.js +136 -0
  213. package/src/changeAvatarV2.js +86 -0
  214. package/src/changeAvt.js +85 -0
  215. package/src/changeBio.js +76 -0
  216. package/src/changeBlockedStatus.js +49 -0
  217. package/src/changeBlockedStatusMqtt.js +80 -0
  218. package/src/changeCover.js +72 -0
  219. package/src/changeGroupImage.js +135 -0
  220. package/src/changeName.js +79 -0
  221. package/src/changeNickname.js +59 -0
  222. package/src/changeThreadColor.js +65 -0
  223. package/src/changeThreadEmoji.js +55 -0
  224. package/src/changeUsername.js +59 -0
  225. package/src/createCommentPost.js +230 -0
  226. package/src/createNewGroup.js +88 -0
  227. package/src/createPoll.js +71 -0
  228. package/src/createPost.js +276 -0
  229. package/src/deleteMessage.js +56 -0
  230. package/src/deleteThread.js +56 -0
  231. package/src/editMessage.js +59 -0
  232. package/src/editMessageOld.js +67 -0
  233. package/src/follow.js +74 -0
  234. package/src/forwardAttachment.js +60 -0
  235. package/src/getAccess.js +112 -0
  236. package/src/getAvatarUser.js +78 -0
  237. package/src/getCurrentUserID.js +7 -0
  238. package/src/getEmojiUrl.js +29 -0
  239. package/src/getFriendsList.js +83 -0
  240. package/src/getMessage.js +835 -0
  241. package/src/getRegion.js +7 -0
  242. package/src/getThreadHistory.js +680 -0
  243. package/src/getThreadHistoryDeprecated.js +71 -0
  244. package/src/getThreadInfo.js +232 -0
  245. package/src/getThreadInfoDeprecated.js +56 -0
  246. package/src/getThreadList.js +213 -0
  247. package/src/getThreadListDeprecated.js +46 -0
  248. package/src/getThreadPictures.js +59 -0
  249. package/src/getUID.js +119 -0
  250. package/src/getUserID.js +61 -0
  251. package/src/getUserInfo.js +66 -0
  252. package/src/handleFriendRequest.js +46 -0
  253. package/src/handleMessageRequest.js +47 -0
  254. package/src/httpGet.js +49 -0
  255. package/src/httpPost.js +48 -0
  256. package/src/listenMqtt.js +827 -0
  257. package/src/listenMqtt.txt +827 -0
  258. package/src/logout.js +75 -0
  259. package/src/markAsDelivered.js +47 -0
  260. package/src/markAsRead.js +70 -0
  261. package/src/markAsReadAll.js +40 -0
  262. package/src/markAsSeen.js +48 -0
  263. package/src/muteThread.js +45 -0
  264. package/src/postFormData.txt +46 -0
  265. package/src/refreshFb_dtsg.js +89 -0
  266. package/src/removeUserFromGroup.js +79 -0
  267. package/src/resolvePhotoUrl.js +45 -0
  268. package/src/searchForThread.js +53 -0
  269. package/src/searchStickers.js +53 -0
  270. package/src/sendMessage.js +329 -0
  271. package/src/sendMessageMqtt.js +322 -0
  272. package/src/sendTypingIndicator.js +101 -0
  273. package/src/sendTypingIndicatorV2.js +28 -0
  274. package/src/setMessageReaction.js +122 -0
  275. package/src/setMessageReactionMqtt.js +62 -0
  276. package/src/setPostReaction.js +112 -0
  277. package/src/setProfileGuard.js +45 -0
  278. package/src/setStoryReaction.js +64 -0
  279. package/src/setTitle.js +90 -0
  280. package/src/shareContact.js +110 -0
  281. package/src/shareLink.js +59 -0
  282. package/src/stopListenMqtt.js +23 -0
  283. package/src/threadColors.js +131 -0
  284. package/src/unfriend.js +52 -0
  285. package/src/unsendMessage.js +45 -0
  286. package/src/uploadAttachment.js +94 -0
  287. package/test/example-config.json +18 -0
  288. package/test/test-page.js +140 -0
  289. package/test/test.js +385 -0
  290. package/utils.js +1379 -0
package/utils.js ADDED
@@ -0,0 +1,1379 @@
1
+
2
+ /* eslint-disable no-prototype-builtins */
3
+ "use strict";
4
+
5
+ let request = require("request").defaults({ jar: true });
6
+ const stream = require("stream");
7
+ const querystring = require("querystring");
8
+ const url = require("url");
9
+
10
+ function setProxy(proxy) {
11
+ if (typeof proxy == 'string')
12
+ request = require("request").defaults({ jar: !0, proxy });
13
+ else
14
+ request = require('request').defaults({ jar: !0 });
15
+ return;
16
+ }
17
+
18
+ function getHeaders(url, options, ctx, customHeader) {
19
+ var headers = {
20
+ "Content-Type": "application/x-www-form-urlencoded",
21
+ Referer: "https://www.facebook.com/",
22
+ Host: new URL(url).hostname,
23
+ Origin: "https://www.facebook.com",
24
+ "User-Agent": options.userAgent,
25
+ Connection: "keep-alive",
26
+ "Sec-Fetch-Site": "same-origin",
27
+ 'Sec-Fetch-User': '?1'
28
+ };
29
+ if (customHeader) {
30
+ Object.assign(headers, customHeader);
31
+ if (customHeader.noRef)
32
+ delete headers.Referer;
33
+ }
34
+ if (ctx && ctx.region)
35
+ headers["X-MSGR-Region"] = ctx.region;
36
+
37
+ return headers;
38
+ }
39
+
40
+ function isReadableStream(obj) {
41
+ return obj instanceof stream.Stream && typeof obj._read == "function" && getType(obj._readableState) == "Object";
42
+ }
43
+
44
+ function get(url, jar, qs, options, ctx, customHeader) {
45
+ let callback;
46
+ var returnPromise = new Promise(function (resolve, reject) {
47
+ callback = (error, res) => error ? reject(error) : resolve(res);
48
+ });
49
+ if (getType(qs) == "Object")
50
+ for (let prop in qs) {
51
+ if (getType(qs[prop]) == 'Object')
52
+ qs[prop] = JSON.stringify(qs[prop]);
53
+ }
54
+ var op = {
55
+ headers: getHeaders(url, options, ctx, customHeader),
56
+ timeout: 60000,
57
+ qs,
58
+ jar,
59
+ gzip: !0
60
+ }
61
+
62
+ request.get(url, op, callback);
63
+
64
+ return returnPromise;
65
+ }
66
+
67
+ function post(url, jar, form, options, ctx, customHeader) {
68
+ let callback;
69
+ var returnPromise = new Promise(function (resolve, reject) {
70
+ callback = (error, res) => error ? reject(error) : resolve(res);
71
+ });
72
+
73
+ var op = {
74
+ headers: getHeaders(url, options, ctx, customHeader),
75
+ timeout: 60000,
76
+ form,
77
+ jar,
78
+ gzip: !0
79
+ }
80
+
81
+ request.post(url, op, callback);
82
+
83
+ return returnPromise;
84
+ }
85
+
86
+ function postFormData(url, jar, form, qs, options, ctx) {
87
+ let callback;
88
+ var returnPromise = new Promise(function (resolve, reject) {
89
+ callback = (error, res) => error ? reject(error) : resolve(res);
90
+ });
91
+ if (getType(qs) == "Object")
92
+ for (let prop in qs) {
93
+ if (getType(qs[prop]) == 'Object')
94
+ qs[prop] = JSON.stringify(qs[prop]);
95
+ }
96
+ var op = {
97
+ headers: getHeaders(url, options, ctx, {
98
+ 'Content-Type': 'multipart/form-data'
99
+ }),
100
+ timeout: 60000,
101
+ formData: form,
102
+ qs,
103
+ jar,
104
+ gzip: !0
105
+ }
106
+
107
+ request.post(url, op, callback);
108
+
109
+ return returnPromise;
110
+ }
111
+
112
+ function padZeros(val, len) {
113
+ val = String(val);
114
+ len = len || 2;
115
+ while (val.length < len) val = "0" + val;
116
+ return val;
117
+ }
118
+
119
+ function generateThreadingID(clientID) {
120
+ const k = Date.now();
121
+ const l = Math.floor(Math.random() * 4294967295);
122
+ const m = clientID;
123
+ return "<" + k + ":" + l + "-" + m + "@mail.projektitan.com>";
124
+ }
125
+
126
+ function binaryToDecimal(data) {
127
+ let ret = "";
128
+ while (data !== "0") {
129
+ let end = 0;
130
+ let fullName = "";
131
+ let i = 0;
132
+ for (; i < data.length; i++) {
133
+ end = 2 * end + parseInt(data[i], 10);
134
+ if (end >= 10) {
135
+ fullName += "1";
136
+ end -= 10;
137
+ }
138
+ else {
139
+ fullName += "0";
140
+ }
141
+ }
142
+ ret = end.toString() + ret;
143
+ data = fullName.slice(fullName.indexOf("1"));
144
+ }
145
+ return ret;
146
+ }
147
+
148
+ function generateOfflineThreadingID() {
149
+ const ret = Date.now();
150
+ const value = Math.floor(Math.random() * 4294967295);
151
+ const str = ("0000000000000000000000" + value.toString(2)).slice(-22);
152
+ const msgs = ret.toString(2) + str;
153
+ return binaryToDecimal(msgs);
154
+ }
155
+
156
+ let h;
157
+ const i = {};
158
+ const j = {
159
+ _: "%",
160
+ A: "%2",
161
+ B: "000",
162
+ C: "%7d",
163
+ D: "%7b%22",
164
+ E: "%2c%22",
165
+ F: "%22%3a",
166
+ G: "%2c%22ut%22%3a1",
167
+ H: "%2c%22bls%22%3a",
168
+ I: "%2c%22n%22%3a%22%",
169
+ J: "%22%3a%7b%22i%22%3a0%7d",
170
+ K: "%2c%22pt%22%3a0%2c%22vis%22%3a",
171
+ L: "%2c%22ch%22%3a%7b%22h%22%3a%22",
172
+ M: "%7b%22v%22%3a2%2c%22time%22%3a1",
173
+ N: ".channel%22%2c%22sub%22%3a%5b",
174
+ O: "%2c%22sb%22%3a1%2c%22t%22%3a%5b",
175
+ P: "%2c%22ud%22%3a100%2c%22lc%22%3a0",
176
+ Q: "%5d%2c%22f%22%3anull%2c%22uct%22%3a",
177
+ R: ".channel%22%2c%22sub%22%3a%5b1%5d",
178
+ S: "%22%2c%22m%22%3a0%7d%2c%7b%22i%22%3a",
179
+ T: "%2c%22blc%22%3a1%2c%22snd%22%3a1%2c%22ct%22%3a",
180
+ U: "%2c%22blc%22%3a0%2c%22snd%22%3a1%2c%22ct%22%3a",
181
+ V: "%2c%22blc%22%3a0%2c%22snd%22%3a0%2c%22ct%22%3a",
182
+ W: "%2c%22s%22%3a0%2c%22blo%22%3a0%7d%2c%22bl%22%3a%7b%22ac%22%3a",
183
+ X: "%2c%22ri%22%3a0%7d%2c%22state%22%3a%7b%22p%22%3a0%2c%22ut%22%3a1",
184
+ Y:
185
+ "%2c%22pt%22%3a0%2c%22vis%22%3a1%2c%22bls%22%3a0%2c%22blc%22%3a0%2c%22snd%22%3a1%2c%22ct%22%3a",
186
+ Z:
187
+ "%2c%22sb%22%3a1%2c%22t%22%3a%5b%5d%2c%22f%22%3anull%2c%22uct%22%3a0%2c%22s%22%3a0%2c%22blo%22%3a0%7d%2c%22bl%22%3a%7b%22ac%22%3a"
188
+ };
189
+ (function () {
190
+ const l = [];
191
+ for (const m in j) {
192
+ i[j[m]] = m;
193
+ l.push(j[m]);
194
+ }
195
+ l.reverse();
196
+ h = new RegExp(l.join("|"), "g");
197
+ })();
198
+
199
+ function presenceEncode(str) {
200
+ return encodeURIComponent(str)
201
+ .replace(/([_A-Z])|%../g, function (m, n) {
202
+ return n ? "%" + n.charCodeAt(0).toString(16) : m;
203
+ })
204
+ .toLowerCase()
205
+ .replace(h, function (m) {
206
+ return i[m];
207
+ });
208
+ }
209
+
210
+ // eslint-disable-next-line no-unused-vars
211
+ function presenceDecode(str) {
212
+ return decodeURIComponent(
213
+ str.replace(/[_A-Z]/g, function (m) {
214
+ return j[m];
215
+ })
216
+ );
217
+ }
218
+
219
+ function generatePresence(userID) {
220
+ const time = Date.now();
221
+ return (
222
+ "E" +
223
+ presenceEncode(
224
+ JSON.stringify({
225
+ v: 3,
226
+ time: parseInt(time / 1000, 10),
227
+ user: userID,
228
+ state: {
229
+ ut: 0,
230
+ t2: [],
231
+ lm2: null,
232
+ uct2: time,
233
+ tr: null,
234
+ tw: Math.floor(Math.random() * 4294967295) + 1,
235
+ at: time
236
+ },
237
+ ch: {
238
+ ["p_" + userID]: 0
239
+ }
240
+ })
241
+ )
242
+ );
243
+ }
244
+
245
+ function generateAccessiblityCookie() {
246
+ const time = Date.now();
247
+ return encodeURIComponent(
248
+ JSON.stringify({
249
+ sr: 0,
250
+ "sr-ts": time,
251
+ jk: 0,
252
+ "jk-ts": time,
253
+ kb: 0,
254
+ "kb-ts": time,
255
+ hcm: 0,
256
+ "hcm-ts": time
257
+ })
258
+ );
259
+ }
260
+
261
+ function getGUID() {
262
+ /** @type {number} */
263
+ let sectionLength = Date.now();
264
+ /** @type {string} */
265
+ const id = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
266
+ /** @type {number} */
267
+ const r = Math.floor((sectionLength + Math.random() * 16) % 16);
268
+ /** @type {number} */
269
+ sectionLength = Math.floor(sectionLength / 16);
270
+ /** @type {string} */
271
+ const _guid = (c == "x" ? r : (r & 7) | 8).toString(16);
272
+ return _guid;
273
+ });
274
+ return id;
275
+ }
276
+
277
+ function getExtension(original_extension, fullFileName = "") {
278
+ if (original_extension) {
279
+ return original_extension;
280
+ }
281
+ else {
282
+ const extension = fullFileName.split(".").pop();
283
+ if (extension === fullFileName) {
284
+ return "";
285
+ }
286
+ else {
287
+ return extension;
288
+ }
289
+ }
290
+ }
291
+
292
+ function _formatAttachment(attachment1, attachment2) {
293
+ // TODO: THIS IS REALLY BAD
294
+ // This is an attempt at fixing Facebook's inconsistencies. Sometimes they give us
295
+ // two attachment objects, but sometimes only one. They each contain part of the
296
+ // data that you'd want so we merge them for convenience.
297
+ // Instead of having a bunch of if statements guarding every access to image_data,
298
+ // we set it to empty object and use the fact that it'll return undefined.
299
+ const fullFileName = attachment1.filename;
300
+ const fileSize = Number(attachment1.fileSize || 0);
301
+ const durationVideo = attachment1.genericMetadata ? Number(attachment1.genericMetadata.videoLength) : undefined;
302
+ const durationAudio = attachment1.genericMetadata ? Number(attachment1.genericMetadata.duration) : undefined;
303
+ const mimeType = attachment1.mimeType;
304
+
305
+ attachment2 = attachment2 || { id: "", image_data: {} };
306
+ attachment1 = attachment1.mercury || attachment1;
307
+ let blob = attachment1.blob_attachment || attachment1.sticker_attachment;
308
+ let type =
309
+ blob && blob.__typename ? blob.__typename : attachment1.attach_type;
310
+ if (!type && attachment1.sticker_attachment) {
311
+ type = "StickerAttachment";
312
+ blob = attachment1.sticker_attachment;
313
+ }
314
+ else if (!type && attachment1.extensible_attachment) {
315
+ if (
316
+ attachment1.extensible_attachment.story_attachment &&
317
+ attachment1.extensible_attachment.story_attachment.target &&
318
+ attachment1.extensible_attachment.story_attachment.target.__typename &&
319
+ attachment1.extensible_attachment.story_attachment.target.__typename === "MessageLocation"
320
+ ) {
321
+ type = "MessageLocation";
322
+ }
323
+ else {
324
+ type = "ExtensibleAttachment";
325
+ }
326
+
327
+ blob = attachment1.extensible_attachment;
328
+ }
329
+ // TODO: Determine whether "sticker", "photo", "file" etc are still used
330
+ // KEEP IN SYNC WITH getThreadHistory
331
+ switch (type) {
332
+ case "sticker":
333
+ return {
334
+ type: "sticker",
335
+ ID: attachment1.metadata.stickerID.toString(),
336
+ url: attachment1.url,
337
+
338
+ packID: attachment1.metadata.packID.toString(),
339
+ spriteUrl: attachment1.metadata.spriteURI,
340
+ spriteUrl2x: attachment1.metadata.spriteURI2x,
341
+ width: attachment1.metadata.width,
342
+ height: attachment1.metadata.height,
343
+
344
+ caption: attachment2.caption,
345
+ description: attachment2.description,
346
+
347
+ frameCount: attachment1.metadata.frameCount,
348
+ frameRate: attachment1.metadata.frameRate,
349
+ framesPerRow: attachment1.metadata.framesPerRow,
350
+ framesPerCol: attachment1.metadata.framesPerCol,
351
+
352
+ stickerID: attachment1.metadata.stickerID.toString(), // @Legacy
353
+ spriteURI: attachment1.metadata.spriteURI, // @Legacy
354
+ spriteURI2x: attachment1.metadata.spriteURI2x // @Legacy
355
+ };
356
+ case "file":
357
+ return {
358
+ type: "file",
359
+ ID: attachment2.id.toString(),
360
+ fullFileName: fullFileName,
361
+ filename: attachment1.name,
362
+ fileSize: fileSize,
363
+ original_extension: getExtension(attachment1.original_extension, fullFileName),
364
+ mimeType: mimeType,
365
+ url: attachment1.url,
366
+
367
+ isMalicious: attachment2.is_malicious,
368
+ contentType: attachment2.mime_type,
369
+
370
+ name: attachment1.name // @Legacy
371
+ };
372
+ case "photo":
373
+ return {
374
+ type: "photo",
375
+ ID: attachment1.metadata.fbid.toString(),
376
+ filename: attachment1.fileName,
377
+ fullFileName: fullFileName,
378
+ fileSize: fileSize,
379
+ original_extension: getExtension(attachment1.original_extension, fullFileName),
380
+ mimeType: mimeType,
381
+ thumbnailUrl: attachment1.thumbnail_url,
382
+
383
+ previewUrl: attachment1.preview_url,
384
+ previewWidth: attachment1.preview_width,
385
+ previewHeight: attachment1.preview_height,
386
+
387
+ largePreviewUrl: attachment1.large_preview_url,
388
+ largePreviewWidth: attachment1.large_preview_width,
389
+ largePreviewHeight: attachment1.large_preview_height,
390
+
391
+ url: attachment1.metadata.url, // @Legacy
392
+ width: attachment1.metadata.dimensions.split(",")[0], // @Legacy
393
+ height: attachment1.metadata.dimensions.split(",")[1], // @Legacy
394
+ name: fullFileName // @Legacy
395
+ };
396
+ case "animated_image":
397
+ return {
398
+ type: "animated_image",
399
+ ID: attachment2.id.toString(),
400
+ filename: attachment2.filename,
401
+ fullFileName: fullFileName,
402
+ original_extension: getExtension(attachment2.original_extension, fullFileName),
403
+ mimeType: mimeType,
404
+
405
+ previewUrl: attachment1.preview_url,
406
+ previewWidth: attachment1.preview_width,
407
+ previewHeight: attachment1.preview_height,
408
+
409
+ url: attachment2.image_data.url,
410
+ width: attachment2.image_data.width,
411
+ height: attachment2.image_data.height,
412
+
413
+ name: attachment1.name, // @Legacy
414
+ facebookUrl: attachment1.url, // @Legacy
415
+ thumbnailUrl: attachment1.thumbnail_url, // @Legacy
416
+ rawGifImage: attachment2.image_data.raw_gif_image, // @Legacy
417
+ rawWebpImage: attachment2.image_data.raw_webp_image, // @Legacy
418
+ animatedGifUrl: attachment2.image_data.animated_gif_url, // @Legacy
419
+ animatedGifPreviewUrl: attachment2.image_data.animated_gif_preview_url, // @Legacy
420
+ animatedWebpUrl: attachment2.image_data.animated_webp_url, // @Legacy
421
+ animatedWebpPreviewUrl: attachment2.image_data.animated_webp_preview_url // @Legacy
422
+ };
423
+ case "share":
424
+ return {
425
+ type: "share",
426
+ ID: attachment1.share.share_id.toString(),
427
+ url: attachment2.href,
428
+
429
+ title: attachment1.share.title,
430
+ description: attachment1.share.description,
431
+ source: attachment1.share.source,
432
+
433
+ image: attachment1.share.media.image,
434
+ width: attachment1.share.media.image_size.width,
435
+ height: attachment1.share.media.image_size.height,
436
+ playable: attachment1.share.media.playable,
437
+ duration: attachment1.share.media.duration,
438
+
439
+ subattachments: attachment1.share.subattachments,
440
+ properties: {},
441
+
442
+ animatedImageSize: attachment1.share.media.animated_image_size, // @Legacy
443
+ facebookUrl: attachment1.share.uri, // @Legacy
444
+ target: attachment1.share.target, // @Legacy
445
+ styleList: attachment1.share.style_list // @Legacy
446
+ };
447
+ case "video":
448
+ return {
449
+ type: "video",
450
+ ID: attachment1.metadata.fbid.toString(),
451
+ filename: attachment1.name,
452
+ fullFileName: fullFileName,
453
+ original_extension: getExtension(attachment1.original_extension, fullFileName),
454
+ mimeType: mimeType,
455
+ duration: durationVideo,
456
+
457
+ previewUrl: attachment1.preview_url,
458
+ previewWidth: attachment1.preview_width,
459
+ previewHeight: attachment1.preview_height,
460
+
461
+ url: attachment1.url,
462
+ width: attachment1.metadata.dimensions.width,
463
+ height: attachment1.metadata.dimensions.height,
464
+
465
+ videoType: "unknown",
466
+
467
+ thumbnailUrl: attachment1.thumbnail_url // @Legacy
468
+ };
469
+ case "error":
470
+ return {
471
+ type: "error",
472
+
473
+ // Save error attachments because we're unsure of their format,
474
+ // and whether there are cases they contain something useful for debugging.
475
+ attachment1: attachment1,
476
+ attachment2: attachment2
477
+ };
478
+ case "MessageImage":
479
+ return {
480
+ type: "photo",
481
+ ID: blob.legacy_attachment_id,
482
+ filename: blob.filename,
483
+ fullFileName: fullFileName,
484
+ fileSize: fileSize,
485
+ original_extension: getExtension(blob.original_extension, fullFileName),
486
+ mimeType: mimeType,
487
+ thumbnailUrl: blob.thumbnail.uri,
488
+
489
+ previewUrl: blob.preview.uri,
490
+ previewWidth: blob.preview.width,
491
+ previewHeight: blob.preview.height,
492
+
493
+ largePreviewUrl: blob.large_preview.uri,
494
+ largePreviewWidth: blob.large_preview.width,
495
+ largePreviewHeight: blob.large_preview.height,
496
+
497
+ url: blob.large_preview.uri, // @Legacy
498
+ width: blob.original_dimensions.x, // @Legacy
499
+ height: blob.original_dimensions.y, // @Legacy
500
+ name: blob.filename // @Legacy
501
+ };
502
+ case "MessageAnimatedImage":
503
+ return {
504
+ type: "animated_image",
505
+ ID: blob.legacy_attachment_id,
506
+ filename: blob.filename,
507
+ fullFileName: fullFileName,
508
+ original_extension: getExtension(blob.original_extension, fullFileName),
509
+ mimeType: mimeType,
510
+
511
+ previewUrl: blob.preview_image.uri,
512
+ previewWidth: blob.preview_image.width,
513
+ previewHeight: blob.preview_image.height,
514
+
515
+ url: blob.animated_image.uri,
516
+ width: blob.animated_image.width,
517
+ height: blob.animated_image.height,
518
+
519
+ thumbnailUrl: blob.preview_image.uri, // @Legacy
520
+ name: blob.filename, // @Legacy
521
+ facebookUrl: blob.animated_image.uri, // @Legacy
522
+ rawGifImage: blob.animated_image.uri, // @Legacy
523
+ animatedGifUrl: blob.animated_image.uri, // @Legacy
524
+ animatedGifPreviewUrl: blob.preview_image.uri, // @Legacy
525
+ animatedWebpUrl: blob.animated_image.uri, // @Legacy
526
+ animatedWebpPreviewUrl: blob.preview_image.uri // @Legacy
527
+ };
528
+ case "MessageVideo":
529
+ return {
530
+ type: "video",
531
+ ID: blob.legacy_attachment_id,
532
+ filename: blob.filename,
533
+ fullFileName: fullFileName,
534
+ original_extension: getExtension(blob.original_extension, fullFileName),
535
+ fileSize: fileSize,
536
+ duration: durationVideo,
537
+ mimeType: mimeType,
538
+
539
+ previewUrl: blob.large_image.uri,
540
+ previewWidth: blob.large_image.width,
541
+ previewHeight: blob.large_image.height,
542
+
543
+ url: blob.playable_url,
544
+ width: blob.original_dimensions.x,
545
+ height: blob.original_dimensions.y,
546
+
547
+ videoType: blob.video_type.toLowerCase(),
548
+
549
+ thumbnailUrl: blob.large_image.uri // @Legacy
550
+ };
551
+ case "MessageAudio":
552
+ return {
553
+ type: "audio",
554
+ ID: blob.url_shimhash,
555
+ filename: blob.filename,
556
+ fullFileName: fullFileName,
557
+ fileSize: fileSize,
558
+ duration: durationAudio,
559
+ original_extension: getExtension(blob.original_extension, fullFileName),
560
+ mimeType: mimeType,
561
+
562
+ audioType: blob.audio_type,
563
+ url: blob.playable_url,
564
+
565
+ isVoiceMail: blob.is_voicemail
566
+ };
567
+ case "StickerAttachment":
568
+ case "Sticker":
569
+ return {
570
+ type: "sticker",
571
+ ID: blob.id,
572
+ url: blob.url,
573
+
574
+ packID: blob.pack ? blob.pack.id : null,
575
+ spriteUrl: blob.sprite_image,
576
+ spriteUrl2x: blob.sprite_image_2x,
577
+ width: blob.width,
578
+ height: blob.height,
579
+
580
+ caption: blob.label,
581
+ description: blob.label,
582
+
583
+ frameCount: blob.frame_count,
584
+ frameRate: blob.frame_rate,
585
+ framesPerRow: blob.frames_per_row,
586
+ framesPerCol: blob.frames_per_column,
587
+
588
+ stickerID: blob.id, // @Legacy
589
+ spriteURI: blob.sprite_image, // @Legacy
590
+ spriteURI2x: blob.sprite_image_2x // @Legacy
591
+ };
592
+ case "MessageLocation":
593
+ var urlAttach = blob.story_attachment.url;
594
+ var mediaAttach = blob.story_attachment.media;
595
+
596
+ var u = querystring.parse(url.parse(urlAttach).query).u;
597
+ var where1 = querystring.parse(url.parse(u).query).where1;
598
+ var address = where1.split(", ");
599
+
600
+ var latitude;
601
+ var longitude;
602
+
603
+ try {
604
+ latitude = Number.parseFloat(address[0]);
605
+ longitude = Number.parseFloat(address[1]);
606
+ } catch (err) {
607
+ /* empty */
608
+ }
609
+
610
+ var imageUrl;
611
+ var width;
612
+ var height;
613
+
614
+ if (mediaAttach && mediaAttach.image) {
615
+ imageUrl = mediaAttach.image.uri;
616
+ width = mediaAttach.image.width;
617
+ height = mediaAttach.image.height;
618
+ }
619
+
620
+ return {
621
+ type: "location",
622
+ ID: blob.legacy_attachment_id,
623
+ latitude: latitude,
624
+ longitude: longitude,
625
+ image: imageUrl,
626
+ width: width,
627
+ height: height,
628
+ url: u || urlAttach,
629
+ address: where1,
630
+
631
+ facebookUrl: blob.story_attachment.url, // @Legacy
632
+ target: blob.story_attachment.target, // @Legacy
633
+ styleList: blob.story_attachment.style_list // @Legacy
634
+ };
635
+ case "ExtensibleAttachment":
636
+ return {
637
+ type: "share",
638
+ ID: blob.legacy_attachment_id,
639
+ url: blob.story_attachment.url,
640
+
641
+ title: blob.story_attachment.title_with_entities.text,
642
+ description:
643
+ blob.story_attachment.description &&
644
+ blob.story_attachment.description.text,
645
+ source: blob.story_attachment.source
646
+ ? blob.story_attachment.source.text
647
+ : null,
648
+
649
+ image:
650
+ blob.story_attachment.media &&
651
+ blob.story_attachment.media.image &&
652
+ blob.story_attachment.media.image.uri,
653
+ width:
654
+ blob.story_attachment.media &&
655
+ blob.story_attachment.media.image &&
656
+ blob.story_attachment.media.image.width,
657
+ height:
658
+ blob.story_attachment.media &&
659
+ blob.story_attachment.media.image &&
660
+ blob.story_attachment.media.image.height,
661
+ playable:
662
+ blob.story_attachment.media &&
663
+ blob.story_attachment.media.is_playable,
664
+ duration:
665
+ blob.story_attachment.media &&
666
+ blob.story_attachment.media.playable_duration_in_ms,
667
+ playableUrl:
668
+ blob.story_attachment.media == null
669
+ ? null
670
+ : blob.story_attachment.media.playable_url,
671
+
672
+ subattachments: blob.story_attachment.subattachments,
673
+ properties: blob.story_attachment.properties.reduce(function (obj, cur) {
674
+ obj[cur.key] = cur.value.text;
675
+ return obj;
676
+ }, {}),
677
+
678
+ facebookUrl: blob.story_attachment.url, // @Legacy
679
+ target: blob.story_attachment.target, // @Legacy
680
+ styleList: blob.story_attachment.style_list // @Legacy
681
+ };
682
+ case "MessageFile":
683
+ return {
684
+ type: "file",
685
+ ID: blob.message_file_fbid,
686
+ fullFileName: fullFileName,
687
+ filename: blob.filename,
688
+ fileSize: fileSize,
689
+ mimeType: blob.mimetype,
690
+ original_extension: blob.original_extension || fullFileName.split(".").pop(),
691
+
692
+ url: blob.url,
693
+ isMalicious: blob.is_malicious,
694
+ contentType: blob.content_type,
695
+
696
+ name: blob.filename
697
+ };
698
+ default:
699
+ throw new Error(
700
+ "unrecognized attach_file of type " +
701
+ type +
702
+ "`" +
703
+ JSON.stringify(attachment1, null, 4) +
704
+ " attachment2: " +
705
+ JSON.stringify(attachment2, null, 4) +
706
+ "`"
707
+ );
708
+ }
709
+ }
710
+
711
+ function formatAttachment(attachments, attachmentIds, attachmentMap, shareMap) {
712
+ attachmentMap = shareMap || attachmentMap;
713
+ return attachments
714
+ ? attachments.map(function (val, i) {
715
+ if (
716
+ !attachmentMap ||
717
+ !attachmentIds ||
718
+ !attachmentMap[attachmentIds[i]]
719
+ ) {
720
+ return _formatAttachment(val);
721
+ }
722
+ return _formatAttachment(val, attachmentMap[attachmentIds[i]]);
723
+ })
724
+ : [];
725
+ }
726
+
727
+ function formatDeltaMessage(m) {
728
+ const md = m.delta.messageMetadata;
729
+
730
+ const mdata =
731
+ m.delta.data === undefined
732
+ ? []
733
+ : m.delta.data.prng === undefined
734
+ ? []
735
+ : JSON.parse(m.delta.data.prng);
736
+ const m_id = mdata.map(u => u.i);
737
+ const m_offset = mdata.map(u => u.o);
738
+ const m_length = mdata.map(u => u.l);
739
+ const mentions = {};
740
+ for (let i = 0; i < m_id.length; i++) {
741
+ mentions[m_id[i]] = m.delta.body.substring(
742
+ m_offset[i],
743
+ m_offset[i] + m_length[i]
744
+ );
745
+ }
746
+
747
+ return {
748
+ type: "message",
749
+ senderID: formatID(md.actorFbId.toString()),
750
+ body: m.delta.body || "",
751
+ threadID: formatID(
752
+ (md.threadKey.threadFbId || md.threadKey.otherUserFbId).toString()
753
+ ),
754
+ messageID: md.messageId,
755
+ attachments: (m.delta.attachments || []).map(v => _formatAttachment(v)),
756
+ mentions: mentions,
757
+ timestamp: md.timestamp,
758
+ isGroup: !!md.threadKey.threadFbId,
759
+ participantIDs: m.delta.participants
760
+ };
761
+ }
762
+
763
+ function formatID(id) {
764
+ if (id != undefined && id != null) {
765
+ return id.replace(/(fb)?id[:.]/, "");
766
+ }
767
+ else {
768
+ return id;
769
+ }
770
+ }
771
+
772
+ function formatMessage(m) {
773
+ const originalMessage = m.message ? m.message : m;
774
+ const obj = {
775
+ type: "message",
776
+ senderName: originalMessage.sender_name,
777
+ senderID: formatID(originalMessage.sender_fbid.toString()),
778
+ participantNames: originalMessage.group_thread_info
779
+ ? originalMessage.group_thread_info.participant_names
780
+ : [originalMessage.sender_name.split(" ")[0]],
781
+ participantIDs: originalMessage.group_thread_info
782
+ ? originalMessage.group_thread_info.participant_ids.map(function (v) {
783
+ return formatID(v.toString());
784
+ })
785
+ : [formatID(originalMessage.sender_fbid)],
786
+ body: originalMessage.body || "",
787
+ threadID: formatID(
788
+ (
789
+ originalMessage.thread_fbid || originalMessage.other_user_fbid
790
+ ).toString()
791
+ ),
792
+ threadName: originalMessage.group_thread_info
793
+ ? originalMessage.group_thread_info.name
794
+ : originalMessage.sender_name,
795
+ location: originalMessage.coordinates ? originalMessage.coordinates : null,
796
+ messageID: originalMessage.mid
797
+ ? originalMessage.mid.toString()
798
+ : originalMessage.message_id,
799
+ attachments: formatAttachment(
800
+ originalMessage.attachments,
801
+ originalMessage.attachmentIds,
802
+ originalMessage.attachment_map,
803
+ originalMessage.share_map
804
+ ),
805
+ timestamp: originalMessage.timestamp,
806
+ timestampAbsolute: originalMessage.timestamp_absolute,
807
+ timestampRelative: originalMessage.timestamp_relative,
808
+ timestampDatetime: originalMessage.timestamp_datetime,
809
+ tags: originalMessage.tags,
810
+ reactions: originalMessage.reactions ? originalMessage.reactions : [],
811
+ isUnread: originalMessage.is_unread
812
+ };
813
+
814
+ if (m.type === "pages_messaging")
815
+ obj.pageID = m.realtime_viewer_fbid.toString();
816
+ obj.isGroup = obj.participantIDs.length > 2;
817
+
818
+ return obj;
819
+ }
820
+
821
+ function formatEvent(m) {
822
+ const originalMessage = m.message ? m.message : m;
823
+ let logMessageType = originalMessage.log_message_type;
824
+ let logMessageData;
825
+ if (logMessageType === "log:generic-admin-text") {
826
+ logMessageData = originalMessage.log_message_data.untypedData;
827
+ logMessageType = getAdminTextMessageType(
828
+ originalMessage.log_message_data.message_type
829
+ );
830
+ }
831
+ else {
832
+ logMessageData = originalMessage.log_message_data;
833
+ }
834
+
835
+ return Object.assign(formatMessage(originalMessage), {
836
+ type: "event",
837
+ logMessageType: logMessageType,
838
+ logMessageData: logMessageData,
839
+ logMessageBody: originalMessage.log_message_body
840
+ });
841
+ }
842
+
843
+ function formatHistoryMessage(m) {
844
+ switch (m.action_type) {
845
+ case "ma-type:log-message":
846
+ return formatEvent(m);
847
+ default:
848
+ return formatMessage(m);
849
+ }
850
+ }
851
+
852
+ // Get a more readable message type for AdminTextMessages
853
+ function getAdminTextMessageType(type) {
854
+ switch (type) {
855
+ case 'unpin_messages_v2':
856
+ return 'log:unpin-message';
857
+ case 'pin_messages_v2':
858
+ return 'log:pin-message';
859
+ case "change_thread_theme":
860
+ return "log:thread-color";
861
+ case "change_thread_icon":
862
+ case 'change_thread_quick_reaction':
863
+ return "log:thread-icon";
864
+ case "change_thread_nickname":
865
+ return "log:user-nickname";
866
+ case "change_thread_admins":
867
+ return "log:thread-admins";
868
+ case "group_poll":
869
+ return "log:thread-poll";
870
+ case "change_thread_approval_mode":
871
+ return "log:thread-approval-mode";
872
+ case "messenger_call_log":
873
+ case "participant_joined_group_call":
874
+ return "log:thread-call";
875
+ default:
876
+ return type;
877
+ }
878
+ }
879
+
880
+ function formatDeltaEvent(m) {
881
+ let logMessageType;
882
+ let logMessageData;
883
+
884
+ // log:thread-color => {theme_color}
885
+ // log:user-nickname => {participant_id, nickname}
886
+ // log:thread-icon => {thread_icon}
887
+ // log:thread-name => {name}
888
+ // log:subscribe => {addedParticipants - [Array]}
889
+ // log:unsubscribe => {leftParticipantFbId}
890
+
891
+ switch (m.class) {
892
+ case "AdminTextMessage":
893
+ logMessageData = m.untypedData;
894
+ logMessageType = getAdminTextMessageType(m.type);
895
+ break;
896
+ case "ThreadName":
897
+ logMessageType = "log:thread-name";
898
+ logMessageData = { name: m.name };
899
+ break;
900
+ case "ParticipantsAddedToGroupThread":
901
+ logMessageType = "log:subscribe";
902
+ logMessageData = { addedParticipants: m.addedParticipants };
903
+ break;
904
+ case "ParticipantLeftGroupThread":
905
+ logMessageType = "log:unsubscribe";
906
+ logMessageData = { leftParticipantFbId: m.leftParticipantFbId };
907
+ break;
908
+ case "ApprovalQueue":
909
+ logMessageType = "log:approval-queue";
910
+ logMessageData = {
911
+ approvalQueue: {
912
+ action: m.action,
913
+ recipientFbId: m.recipientFbId,
914
+ requestSource: m.requestSource,
915
+ ...m.messageMetadata
916
+ }
917
+ };
918
+ }
919
+ return {
920
+ type: "event",
921
+ threadID: formatID(
922
+ (
923
+ m.messageMetadata.threadKey.threadFbId ||
924
+ m.messageMetadata.threadKey.otherUserFbId
925
+ ).toString()
926
+ ),
927
+ messageID: m.messageMetadata.messageId.toString(),
928
+ logMessageType,
929
+ logMessageData,
930
+ logMessageBody: m.messageMetadata.adminText,
931
+ timestamp: m.messageMetadata.timestamp,
932
+ author: m.messageMetadata.actorFbId,
933
+ participantIDs: m.participants
934
+ };
935
+ }
936
+
937
+ function formatTyp(event) {
938
+ return {
939
+ isTyping: !!event.st,
940
+ from: event.from.toString(),
941
+ threadID: formatID(
942
+ (event.to || event.thread_fbid || event.from).toString()
943
+ ),
944
+ // When receiving typ indication from mobile, `from_mobile` isn't set.
945
+ // If it is, we just use that value.
946
+ fromMobile: event.hasOwnProperty("from_mobile") ? event.from_mobile : true,
947
+ userID: (event.realtime_viewer_fbid || event.from).toString(),
948
+ type: "typ"
949
+ };
950
+ }
951
+
952
+ function formatDeltaReadReceipt(delta) {
953
+ // otherUserFbId seems to be used as both the readerID and the threadID in a 1-1 chat.
954
+ // In a group chat actorFbId is used for the reader and threadFbId for the thread.
955
+ return {
956
+ reader: (delta.threadKey.otherUserFbId || delta.actorFbId).toString(),
957
+ time: delta.actionTimestampMs,
958
+ threadID: formatID(
959
+ (delta.threadKey.otherUserFbId || delta.threadKey.threadFbId).toString()
960
+ ),
961
+ type: "read_receipt"
962
+ };
963
+ }
964
+
965
+ function formatReadReceipt(event) {
966
+ return {
967
+ reader: event.reader.toString(),
968
+ time: event.time,
969
+ threadID: formatID((event.thread_fbid || event.reader).toString()),
970
+ type: "read_receipt"
971
+ };
972
+ }
973
+
974
+ function formatRead(event) {
975
+ return {
976
+ threadID: formatID(
977
+ (
978
+ (event.chat_ids && event.chat_ids[0]) ||
979
+ (event.thread_fbids && event.thread_fbids[0])
980
+ ).toString()
981
+ ),
982
+ time: event.timestamp,
983
+ type: "read"
984
+ };
985
+ }
986
+
987
+ function getFrom(str, startToken, endToken) {
988
+ const start = str.indexOf(startToken) + startToken.length;
989
+ if (start < startToken.length) return "";
990
+
991
+ const lastHalf = str.substring(start);
992
+ const end = lastHalf.indexOf(endToken);
993
+ if (end === -1) {
994
+ throw Error(
995
+ "Could not find endTime `" + endToken + "` in the given string."
996
+ );
997
+ }
998
+ return lastHalf.substring(0, end);
999
+ }
1000
+
1001
+ function makeParsable(html) {
1002
+ const withoutForLoop = html.replace(/for\s*\(\s*;\s*;\s*\)\s*;\s*/, "");
1003
+
1004
+ // (What the fuck FB, why windows style newlines?)
1005
+ // So sometimes FB will send us base multiple objects in the same response.
1006
+ // They're all valid JSON, one after the other, at the top level. We detect
1007
+ // that and make it parse-able by JSON.parse.
1008
+ // Ben - July 15th 2017
1009
+ //
1010
+ // It turns out that Facebook may insert random number of spaces before
1011
+ // next object begins (issue #616)
1012
+ // rav_kr - 2018-03-19
1013
+ const maybeMultipleObjects = withoutForLoop.split(/\}\r\n *\{/);
1014
+ if (maybeMultipleObjects.length === 1) return maybeMultipleObjects;
1015
+
1016
+ return "[" + maybeMultipleObjects.join("},{") + "]";
1017
+ }
1018
+
1019
+ function arrToForm(form) {
1020
+ return arrayToObject(
1021
+ form,
1022
+ function (v) {
1023
+ return v.name;
1024
+ },
1025
+ function (v) {
1026
+ return v.val;
1027
+ }
1028
+ );
1029
+ }
1030
+
1031
+ function arrayToObject(arr, getKey, getValue) {
1032
+ return arr.reduce(function (acc, val) {
1033
+ acc[getKey(val)] = getValue(val);
1034
+ return acc;
1035
+ }, {});
1036
+ }
1037
+
1038
+ function getSignatureID() {
1039
+ return Math.floor(Math.random() * 2147483648).toString(16);
1040
+ }
1041
+
1042
+ function generateTimestampRelative() {
1043
+ const d = new Date();
1044
+ return d.getHours() + ":" + padZeros(d.getMinutes());
1045
+ }
1046
+
1047
+ function makeDefaults(html, userID, ctx) {
1048
+ let reqCounter = 1;
1049
+ const fb_dtsg = getFrom(html, 'name="fb_dtsg" value="', '"');
1050
+
1051
+ let ttstamp = "2";
1052
+ for (let i = 0; i < fb_dtsg.length; i++) {
1053
+ ttstamp += fb_dtsg.charCodeAt(i);
1054
+ }
1055
+ const revision = getFrom(html, 'revision":', ",");
1056
+
1057
+ function mergeWithDefaults(obj) {
1058
+ const newObj = {
1059
+ av: userID,
1060
+ __user: userID,
1061
+ __req: (reqCounter++).toString(36),
1062
+ __rev: revision,
1063
+ __a: 1,
1064
+ fb_dtsg: ctx.fb_dtsg || fb_dtsg,
1065
+ jazoest: ctx.ttstamp || ttstamp
1066
+ }
1067
+
1068
+ if (!obj) return newObj;
1069
+
1070
+ for (var prop in obj) {
1071
+ if (obj.hasOwnProperty(prop)) {
1072
+ if (!newObj[prop])
1073
+ newObj[prop] = obj[prop];
1074
+ }
1075
+ }
1076
+
1077
+ return newObj;
1078
+ }
1079
+
1080
+ return {
1081
+ get: (url, jar, qs, ctxx, customHeader = {}) => get(url, jar, mergeWithDefaults(qs), ctx.globalOptions, ctxx || ctx, customHeader),
1082
+ post: (url, jar, form, ctxx, customHeader = {}) => post(url, jar, mergeWithDefaults(form), ctx.globalOptions, ctxx || ctx, customHeader),
1083
+ postFormData: (url, jar, form, qs, ctxx) => postFormData(url, jar, mergeWithDefaults(form), mergeWithDefaults(qs), ctx.globalOptions, ctxx || ctx)
1084
+ };
1085
+ }
1086
+
1087
+ function parseAndCheckLogin(ctx, http, retryCount) {
1088
+ var delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
1089
+ var _try = (tryData) => new Promise(function (resolve, reject) {
1090
+ try {
1091
+ resolve(tryData());
1092
+ } catch (error) {
1093
+ reject(error);
1094
+ }
1095
+ });
1096
+ if (retryCount == undefined) retryCount = 0;
1097
+
1098
+ return function (data) {
1099
+ function any() {
1100
+ if (data.statusCode >= 500 && data.statusCode < 600) {
1101
+ if (retryCount >= 5) {
1102
+ const err = new Error("Request retry failed. Check the `res` and `statusCode` property on this error.");
1103
+ err.statusCode = data.statusCode;
1104
+ err.res = data.body;
1105
+ err.error = "Request retry failed. Check the `res` and `statusCode` property on this error.";
1106
+ throw err;
1107
+ }
1108
+ retryCount++;
1109
+ const retryTime = Math.floor(Math.random() * 5000);
1110
+ console.warn("parseAndCheckLogin", "Got status code " + data.statusCode + " - " + retryCount + ". attempt to retry in " + retryTime + " milliseconds...");
1111
+ const url = data.request.uri.protocol + "//" + data.request.uri.hostname + data.request.uri.pathname;
1112
+ if (data.request.headers["Content-Type"].split(";")[0] === "multipart/form-data") {
1113
+ return delay(retryTime)
1114
+ .then(function () {
1115
+ return http
1116
+ .postFormData(url, ctx.jar, data.request.formData);
1117
+ })
1118
+ .then(parseAndCheckLogin(ctx, http, retryCount));
1119
+ }
1120
+ else {
1121
+ return delay(retryTime)
1122
+ .then(function () {
1123
+ return http
1124
+ .post(url, ctx.jar, data.request.formData);
1125
+ })
1126
+ .then(parseAndCheckLogin(ctx, http, retryCount));
1127
+ }
1128
+ }
1129
+
1130
+ if (data.statusCode === 404) return;
1131
+
1132
+ if (data.statusCode !== 200)
1133
+ throw new Error("parseAndCheckLogin got status code: " + data.statusCode + ". Bailing out of trying to parse response.");
1134
+
1135
+ let res = null;
1136
+ try {
1137
+ res = JSON.parse(makeParsable(data.body));
1138
+ } catch (e) {
1139
+ const err = new Error("JSON.parse error. Check the `detail` property on this error.");
1140
+ err.error = "JSON.parse error. Check the `detail` property on this error.";
1141
+ err.detail = e;
1142
+ err.res = data.body;
1143
+ throw err;
1144
+ }
1145
+
1146
+ // In some cases the response contains only a redirect URL which should be followed
1147
+ if (res.redirect && data.request.method === "GET") {
1148
+ return http
1149
+ .get(res.redirect, ctx.jar)
1150
+ .then(parseAndCheckLogin(ctx, http));
1151
+ }
1152
+
1153
+ // TODO: handle multiple cookies?
1154
+ if (res.jsmods && res.jsmods.require && Array.isArray(res.jsmods.require[0]) && res.jsmods.require[0][0] === "Cookie") {
1155
+ res.jsmods.require[0][3][0] = res.jsmods.require[0][3][0].replace("_js_", "");
1156
+ const requireCookie = res.jsmods.require[0][3];
1157
+ ctx.jar.setCookie(formatCookie(requireCookie, "facebook"), "https://www.facebook.com");
1158
+ ctx.jar.setCookie(formatCookie(requireCookie, "messenger"), "https://www.messenger.com");
1159
+ }
1160
+
1161
+ // On every request we check if we got a DTSG and we mutate the context so that we use the latest
1162
+ // one for the next requests.
1163
+ if (res.jsmods && Array.isArray(res.jsmods.require)) {
1164
+ const arr = res.jsmods.require;
1165
+ for (const i in arr) {
1166
+ if (arr[i][0] === "DTSG" && arr[i][1] === "setToken") {
1167
+ ctx.fb_dtsg = arr[i][3][0];
1168
+
1169
+ // Update ttstamp since that depends on fb_dtsg
1170
+ ctx.ttstamp = "2";
1171
+ for (let j = 0; j < ctx.fb_dtsg.length; j++) {
1172
+ ctx.ttstamp += ctx.fb_dtsg.charCodeAt(j);
1173
+ }
1174
+ }
1175
+ }
1176
+ }
1177
+
1178
+ if (res.error === 1357001) {
1179
+ const err = new Error('Facebook blocked the login');
1180
+ err.error = "Not logged in.";
1181
+ throw err;
1182
+ }
1183
+ return res;
1184
+ }
1185
+ return _try(any);
1186
+ };
1187
+ }
1188
+
1189
+ function saveCookies(jar) {
1190
+ return function (res) {
1191
+ const cookies = res.headers["set-cookie"] || [];
1192
+ cookies.forEach(function (c) {
1193
+ if (c.indexOf(".facebook.com") > -1) {
1194
+ jar.setCookie(c, "https://www.facebook.com");
1195
+ }
1196
+ const c2 = c.replace(/domain=\.facebook\.com/, "domain=.messenger.com");
1197
+ jar.setCookie(c2, "https://www.messenger.com");
1198
+ });
1199
+ return res;
1200
+ };
1201
+ }
1202
+
1203
+ const NUM_TO_MONTH = [
1204
+ "Jan",
1205
+ "Feb",
1206
+ "Mar",
1207
+ "Apr",
1208
+ "May",
1209
+ "Jun",
1210
+ "Jul",
1211
+ "Aug",
1212
+ "Sep",
1213
+ "Oct",
1214
+ "Nov",
1215
+ "Dec"
1216
+ ];
1217
+ const NUM_TO_DAY = ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"];
1218
+ function formatDate(date) {
1219
+ let d = date.getUTCDate();
1220
+ d = d >= 10 ? d : "0" + d;
1221
+ let h = date.getUTCHours();
1222
+ h = h >= 10 ? h : "0" + h;
1223
+ let m = date.getUTCMinutes();
1224
+ m = m >= 10 ? m : "0" + m;
1225
+ let s = date.getUTCSeconds();
1226
+ s = s >= 10 ? s : "0" + s;
1227
+ return (
1228
+ NUM_TO_DAY[date.getUTCDay()] +
1229
+ ", " +
1230
+ d +
1231
+ " " +
1232
+ NUM_TO_MONTH[date.getUTCMonth()] +
1233
+ " " +
1234
+ date.getUTCFullYear() +
1235
+ " " +
1236
+ h +
1237
+ ":" +
1238
+ m +
1239
+ ":" +
1240
+ s +
1241
+ " GMT"
1242
+ );
1243
+ }
1244
+
1245
+ function formatCookie(arr, url) {
1246
+ return (
1247
+ arr[0] + "=" + arr[1] + "; Path=" + arr[3] + "; Domain=" + url + ".com"
1248
+ );
1249
+ }
1250
+
1251
+ function formatThread(data) {
1252
+ return {
1253
+ threadID: formatID(data.thread_fbid.toString()),
1254
+ participants: data.participants.map(formatID),
1255
+ participantIDs: data.participants.map(formatID),
1256
+ name: data.name,
1257
+ nicknames: data.custom_nickname,
1258
+ snippet: data.snippet,
1259
+ snippetAttachments: data.snippet_attachments,
1260
+ snippetSender: formatID((data.snippet_sender || "").toString()),
1261
+ unreadCount: data.unread_count,
1262
+ messageCount: data.message_count,
1263
+ imageSrc: data.image_src,
1264
+ timestamp: data.timestamp,
1265
+ serverTimestamp: data.server_timestamp, // what is this?
1266
+ muteUntil: data.mute_until,
1267
+ isCanonicalUser: data.is_canonical_user,
1268
+ isCanonical: data.is_canonical,
1269
+ isSubscribed: data.is_subscribed,
1270
+ folder: data.folder,
1271
+ isArchived: data.is_archived,
1272
+ recipientsLoadable: data.recipients_loadable,
1273
+ hasEmailParticipant: data.has_email_participant,
1274
+ readOnly: data.read_only,
1275
+ canReply: data.can_reply,
1276
+ cannotReplyReason: data.cannot_reply_reason,
1277
+ lastMessageTimestamp: data.last_message_timestamp,
1278
+ lastReadTimestamp: data.last_read_timestamp,
1279
+ lastMessageType: data.last_message_type,
1280
+ emoji: data.custom_like_icon,
1281
+ color: data.custom_color,
1282
+ adminIDs: data.admin_ids,
1283
+ threadType: data.thread_type
1284
+ };
1285
+ }
1286
+
1287
+ function getType(obj) {
1288
+ return Object.prototype.toString.call(obj).slice(8, -1);
1289
+ }
1290
+
1291
+ function formatProxyPresence(presence, userID) {
1292
+ if (presence.lat === undefined || presence.p === undefined) return null;
1293
+ return {
1294
+ type: "presence",
1295
+ timestamp: presence.lat * 1000,
1296
+ userID: userID,
1297
+ statuses: presence.p
1298
+ };
1299
+ }
1300
+
1301
+ function formatPresence(presence, userID) {
1302
+ return {
1303
+ type: "presence",
1304
+ timestamp: presence.la * 1000,
1305
+ userID: userID,
1306
+ statuses: presence.a
1307
+ };
1308
+ }
1309
+
1310
+ function decodeClientPayload(payload) {
1311
+ /*
1312
+ Special function which Client using to "encode" clients JSON payload
1313
+ */
1314
+ return JSON.parse(String.fromCharCode.apply(null, payload));
1315
+ }
1316
+
1317
+ function getAppState(jar) {
1318
+ return jar
1319
+ .getCookies("https://www.facebook.com")
1320
+ .concat(jar.getCookies("https://www.messenger.com"));
1321
+ }
1322
+
1323
+ function getAccessFromBusiness(jar, Options) {
1324
+ return function (res) {
1325
+ var html = res ? res.body : null;
1326
+ return get('https://business.facebook.com/content_management', jar, null, Options, null, { noRef: true })
1327
+ .then(function (res) {
1328
+ var token = /"accessToken":"([^.]+)","clientID":/g.exec(res.body)[1];
1329
+ return [html, token];
1330
+ })
1331
+ .catch(function () {
1332
+ return [html, null];
1333
+ });
1334
+ }
1335
+ }
1336
+
1337
+ module.exports = {
1338
+ isReadableStream,
1339
+ get,
1340
+ post,
1341
+ postFormData,
1342
+ generateThreadingID,
1343
+ generateOfflineThreadingID,
1344
+ getGUID,
1345
+ getFrom,
1346
+ makeParsable,
1347
+ arrToForm,
1348
+ getSignatureID,
1349
+ getJar: request.jar,
1350
+ generateTimestampRelative,
1351
+ makeDefaults,
1352
+ parseAndCheckLogin,
1353
+ saveCookies,
1354
+ getType,
1355
+ _formatAttachment,
1356
+ formatHistoryMessage,
1357
+ formatID,
1358
+ formatMessage,
1359
+ formatDeltaEvent,
1360
+ formatDeltaMessage,
1361
+ formatProxyPresence,
1362
+ formatPresence,
1363
+ formatTyp,
1364
+ formatDeltaReadReceipt,
1365
+ formatCookie,
1366
+ formatThread,
1367
+ formatReadReceipt,
1368
+ formatRead,
1369
+ generatePresence,
1370
+ generateAccessiblityCookie,
1371
+ formatDate,
1372
+ decodeClientPayload,
1373
+ getAppState,
1374
+ getAdminTextMessageType,
1375
+ setProxy,
1376
+ getAccessFromBusiness,
1377
+ presenceDecode,
1378
+ presenceEncode
1379
+ }