bb-fca 2.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 (253) hide show
  1. package/LICENSE-MIT +21 -0
  2. package/README.md +0 -0
  3. package/dist/core/client.js +50 -0
  4. package/dist/core/client.js.map +1 -0
  5. package/dist/core/models/buildAPI.js +103 -0
  6. package/dist/core/models/buildAPI.js.map +1 -0
  7. package/dist/core/models/loginHelper.js +209 -0
  8. package/dist/core/models/loginHelper.js.map +1 -0
  9. package/dist/core/models/setOptions.js +47 -0
  10. package/dist/core/models/setOptions.js.map +1 -0
  11. package/dist/deltas/apis/create.js +30 -0
  12. package/dist/deltas/apis/create.js.map +1 -0
  13. package/dist/deltas/apis/extra/addExternalModule.js +23 -0
  14. package/dist/deltas/apis/extra/addExternalModule.js.map +1 -0
  15. package/dist/deltas/apis/extra/getAccess.js +110 -0
  16. package/dist/deltas/apis/extra/getAccess.js.map +1 -0
  17. package/dist/deltas/apis/http/httpGet.js +57 -0
  18. package/dist/deltas/apis/http/httpGet.js.map +1 -0
  19. package/dist/deltas/apis/http/httpPost.js +57 -0
  20. package/dist/deltas/apis/http/httpPost.js.map +1 -0
  21. package/dist/deltas/apis/http/httpPostFormData.js +61 -0
  22. package/dist/deltas/apis/http/httpPostFormData.js.map +1 -0
  23. package/dist/deltas/apis/login/GetBotInfo.js +83 -0
  24. package/dist/deltas/apis/login/GetBotInfo.js.map +1 -0
  25. package/dist/deltas/apis/login/getBotInitialData.js +46 -0
  26. package/dist/deltas/apis/login/getBotInitialData.js.map +1 -0
  27. package/dist/deltas/apis/login/logout.js +54 -0
  28. package/dist/deltas/apis/login/logout.js.map +1 -0
  29. package/dist/deltas/apis/messaging/editMessage.js +64 -0
  30. package/dist/deltas/apis/messaging/editMessage.js.map +1 -0
  31. package/dist/deltas/apis/messaging/emoji.js +120 -0
  32. package/dist/deltas/apis/messaging/emoji.js.map +1 -0
  33. package/dist/deltas/apis/messaging/gcmember.js +164 -0
  34. package/dist/deltas/apis/messaging/gcmember.js.map +1 -0
  35. package/dist/deltas/apis/messaging/gcname.js +119 -0
  36. package/dist/deltas/apis/messaging/gcname.js.map +1 -0
  37. package/dist/deltas/apis/messaging/gcrule.js +144 -0
  38. package/dist/deltas/apis/messaging/gcrule.js.map +1 -0
  39. package/dist/deltas/apis/messaging/markAsDelivered.js +44 -0
  40. package/dist/deltas/apis/messaging/markAsDelivered.js.map +1 -0
  41. package/dist/deltas/apis/messaging/markAsRead.js +84 -0
  42. package/dist/deltas/apis/messaging/markAsRead.js.map +1 -0
  43. package/dist/deltas/apis/messaging/markAsReadAll.js +34 -0
  44. package/dist/deltas/apis/messaging/markAsReadAll.js.map +1 -0
  45. package/dist/deltas/apis/messaging/markAsSeen.js +64 -0
  46. package/dist/deltas/apis/messaging/markAsSeen.js.map +1 -0
  47. package/dist/deltas/apis/messaging/nickname.js +129 -0
  48. package/dist/deltas/apis/messaging/nickname.js.map +1 -0
  49. package/dist/deltas/apis/messaging/notes.js +156 -0
  50. package/dist/deltas/apis/messaging/notes.js.map +1 -0
  51. package/dist/deltas/apis/messaging/resolvePhotoUrl.js +55 -0
  52. package/dist/deltas/apis/messaging/resolvePhotoUrl.js.map +1 -0
  53. package/dist/deltas/apis/messaging/sendMessage.js +239 -0
  54. package/dist/deltas/apis/messaging/sendMessage.js.map +1 -0
  55. package/dist/deltas/apis/messaging/sendTypingIndicator.js +41 -0
  56. package/dist/deltas/apis/messaging/sendTypingIndicator.js.map +1 -0
  57. package/dist/deltas/apis/messaging/setMessageReaction.js +30 -0
  58. package/dist/deltas/apis/messaging/setMessageReaction.js.map +1 -0
  59. package/dist/deltas/apis/messaging/shareContact.js +59 -0
  60. package/dist/deltas/apis/messaging/shareContact.js.map +1 -0
  61. package/dist/deltas/apis/messaging/stickers.js +246 -0
  62. package/dist/deltas/apis/messaging/stickers.js.map +1 -0
  63. package/dist/deltas/apis/messaging/theme.js +227 -0
  64. package/dist/deltas/apis/messaging/theme.js.map +1 -0
  65. package/dist/deltas/apis/messaging/unsendMessage.js +19 -0
  66. package/dist/deltas/apis/messaging/unsendMessage.js.map +1 -0
  67. package/dist/deltas/apis/mqtt/deltas/value.js +193 -0
  68. package/dist/deltas/apis/mqtt/deltas/value.js.map +1 -0
  69. package/dist/deltas/apis/mqtt/listenMqtt.js +306 -0
  70. package/dist/deltas/apis/mqtt/listenMqtt.js.map +1 -0
  71. package/dist/deltas/apis/mqtt/listenSpeed.js +166 -0
  72. package/dist/deltas/apis/mqtt/listenSpeed.js.map +1 -0
  73. package/dist/deltas/apis/mqtt/pinMessage.js +166 -0
  74. package/dist/deltas/apis/mqtt/pinMessage.js.map +1 -0
  75. package/dist/deltas/apis/mqtt/realtime.js +160 -0
  76. package/dist/deltas/apis/mqtt/realtime.js.map +1 -0
  77. package/dist/deltas/apis/mqtt/sendMessageMqtt.js +184 -0
  78. package/dist/deltas/apis/mqtt/sendMessageMqtt.js.map +1 -0
  79. package/dist/deltas/apis/mqtt/setMessageReactionMqtt.js +57 -0
  80. package/dist/deltas/apis/mqtt/setMessageReactionMqtt.js.map +1 -0
  81. package/dist/deltas/apis/posting/comment.js +195 -0
  82. package/dist/deltas/apis/posting/comment.js.map +1 -0
  83. package/dist/deltas/apis/posting/follow.js +82 -0
  84. package/dist/deltas/apis/posting/follow.js.map +1 -0
  85. package/dist/deltas/apis/posting/friend.js +253 -0
  86. package/dist/deltas/apis/posting/friend.js.map +1 -0
  87. package/dist/deltas/apis/posting/post.js +551 -0
  88. package/dist/deltas/apis/posting/post.js.map +1 -0
  89. package/dist/deltas/apis/posting/share.js +59 -0
  90. package/dist/deltas/apis/posting/share.js.map +1 -0
  91. package/dist/deltas/apis/posting/story.js +176 -0
  92. package/dist/deltas/apis/posting/story.js.map +1 -0
  93. package/dist/deltas/apis/threads/getThreadHistory.js +233 -0
  94. package/dist/deltas/apis/threads/getThreadHistory.js.map +1 -0
  95. package/dist/deltas/apis/threads/getThreadInfo.js +197 -0
  96. package/dist/deltas/apis/threads/getThreadInfo.js.map +1 -0
  97. package/dist/deltas/apis/threads/getThreadList.js +201 -0
  98. package/dist/deltas/apis/threads/getThreadList.js.map +1 -0
  99. package/dist/deltas/apis/users/getUserInfo.js +254 -0
  100. package/dist/deltas/apis/users/getUserInfo.js.map +1 -0
  101. package/dist/index.d.ts +696 -0
  102. package/dist/types/core/client.d.ts +2 -0
  103. package/dist/types/core/models/buildAPI.d.ts +13 -0
  104. package/dist/types/core/models/loginHelper.d.ts +15 -0
  105. package/dist/types/core/models/setOptions.d.ts +2 -0
  106. package/dist/types/deltas/apis/create.d.ts +23 -0
  107. package/dist/types/deltas/apis/extra/addExternalModule.d.ts +1 -0
  108. package/dist/types/deltas/apis/extra/getAccess.d.ts +1 -0
  109. package/dist/types/deltas/apis/http/httpGet.d.ts +1 -0
  110. package/dist/types/deltas/apis/http/httpPost.d.ts +1 -0
  111. package/dist/types/deltas/apis/http/httpPostFormData.d.ts +1 -0
  112. package/dist/types/deltas/apis/login/GetBotInfo.d.ts +32 -0
  113. package/dist/types/deltas/apis/login/getBotInitialData.d.ts +1 -0
  114. package/dist/types/deltas/apis/login/logout.d.ts +7 -0
  115. package/dist/types/deltas/apis/messaging/editMessage.d.ts +7 -0
  116. package/dist/types/deltas/apis/messaging/emoji.d.ts +1 -0
  117. package/dist/types/deltas/apis/messaging/gcmember.d.ts +1 -0
  118. package/dist/types/deltas/apis/messaging/gcname.d.ts +1 -0
  119. package/dist/types/deltas/apis/messaging/gcrule.d.ts +1 -0
  120. package/dist/types/deltas/apis/messaging/markAsDelivered.d.ts +7 -0
  121. package/dist/types/deltas/apis/messaging/markAsRead.d.ts +6 -0
  122. package/dist/types/deltas/apis/messaging/markAsReadAll.d.ts +7 -0
  123. package/dist/types/deltas/apis/messaging/markAsSeen.d.ts +6 -0
  124. package/dist/types/deltas/apis/messaging/nickname.d.ts +1 -0
  125. package/dist/types/deltas/apis/messaging/notes.d.ts +14 -0
  126. package/dist/types/deltas/apis/messaging/resolvePhotoUrl.d.ts +9 -0
  127. package/dist/types/deltas/apis/messaging/sendMessage.d.ts +1 -0
  128. package/dist/types/deltas/apis/messaging/sendTypingIndicator.d.ts +6 -0
  129. package/dist/types/deltas/apis/messaging/setMessageReaction.d.ts +1 -0
  130. package/dist/types/deltas/apis/messaging/shareContact.d.ts +8 -0
  131. package/dist/types/deltas/apis/messaging/stickers.d.ts +48 -0
  132. package/dist/types/deltas/apis/messaging/theme.d.ts +1 -0
  133. package/dist/types/deltas/apis/messaging/unsendMessage.d.ts +1 -0
  134. package/dist/types/deltas/apis/mqtt/deltas/value.d.ts +2 -0
  135. package/dist/types/deltas/apis/mqtt/listenMqtt.d.ts +20 -0
  136. package/dist/types/deltas/apis/mqtt/listenSpeed.d.ts +21 -0
  137. package/dist/types/deltas/apis/mqtt/pinMessage.d.ts +1 -0
  138. package/dist/types/deltas/apis/mqtt/realtime.d.ts +1 -0
  139. package/dist/types/deltas/apis/mqtt/sendMessageMqtt.d.ts +1 -0
  140. package/dist/types/deltas/apis/mqtt/setMessageReactionMqtt.d.ts +1 -0
  141. package/dist/types/deltas/apis/posting/comment.d.ts +9 -0
  142. package/dist/types/deltas/apis/posting/follow.d.ts +14 -0
  143. package/dist/types/deltas/apis/posting/friend.d.ts +61 -0
  144. package/dist/types/deltas/apis/posting/post.d.ts +20 -0
  145. package/dist/types/deltas/apis/posting/share.d.ts +1 -0
  146. package/dist/types/deltas/apis/posting/story.d.ts +39 -0
  147. package/dist/types/deltas/apis/threads/getThreadHistory.d.ts +7 -0
  148. package/dist/types/deltas/apis/threads/getThreadInfo.d.ts +7 -0
  149. package/dist/types/deltas/apis/threads/getThreadList.d.ts +7 -0
  150. package/dist/types/deltas/apis/users/getUserInfo.d.ts +1 -0
  151. package/dist/types/utils/axios.d.ts +7 -0
  152. package/dist/types/utils/clients.d.ts +4 -0
  153. package/dist/types/utils/constants.d.ts +24 -0
  154. package/dist/types/utils/formatters/data/formatAttachment.d.ts +2 -0
  155. package/dist/types/utils/formatters/data/formatDelta.d.ts +4 -0
  156. package/dist/types/utils/formatters/index.d.ts +17 -0
  157. package/dist/types/utils/formatters/value/formatCookie.d.ts +8 -0
  158. package/dist/types/utils/formatters/value/formatDate.d.ts +6 -0
  159. package/dist/types/utils/formatters/value/formatID.d.ts +7 -0
  160. package/dist/types/utils/headers.d.ts +2 -0
  161. package/dist/types/utils/index.d.ts +75 -0
  162. package/dist/types/utils/user-agents.d.ts +9 -0
  163. package/dist/utils/axios.js +148 -0
  164. package/dist/utils/axios.js.map +1 -0
  165. package/dist/utils/clients.js +120 -0
  166. package/dist/utils/clients.js.map +1 -0
  167. package/dist/utils/constants.js +249 -0
  168. package/dist/utils/constants.js.map +1 -0
  169. package/dist/utils/formatters/data/formatAttachment.js +61 -0
  170. package/dist/utils/formatters/data/formatAttachment.js.map +1 -0
  171. package/dist/utils/formatters/data/formatDelta.js +67 -0
  172. package/dist/utils/formatters/data/formatDelta.js.map +1 -0
  173. package/dist/utils/formatters/index.js +132 -0
  174. package/dist/utils/formatters/index.js.map +1 -0
  175. package/dist/utils/formatters/value/formatCookie.js +13 -0
  176. package/dist/utils/formatters/value/formatCookie.js.map +1 -0
  177. package/dist/utils/formatters/value/formatDate.js +33 -0
  178. package/dist/utils/formatters/value/formatDate.js.map +1 -0
  179. package/dist/utils/formatters/value/formatID.js +17 -0
  180. package/dist/utils/formatters/value/formatID.js.map +1 -0
  181. package/dist/utils/headers.js +61 -0
  182. package/dist/utils/headers.js.map +1 -0
  183. package/dist/utils/index.js +105 -0
  184. package/dist/utils/index.js.map +1 -0
  185. package/dist/utils/user-agents.js +41 -0
  186. package/dist/utils/user-agents.js.map +1 -0
  187. package/examples/post.example.js +149 -0
  188. package/module/index.js +5 -0
  189. package/package.json +56 -0
  190. package/src/core/client.ts +66 -0
  191. package/src/core/models/buildAPI.ts +131 -0
  192. package/src/core/models/loginHelper.ts +226 -0
  193. package/src/core/models/setOptions.ts +48 -0
  194. package/src/deltas/apis/create.ts +28 -0
  195. package/src/deltas/apis/extra/addExternalModule.ts +23 -0
  196. package/src/deltas/apis/extra/getAccess.ts +141 -0
  197. package/src/deltas/apis/http/httpGet.ts +61 -0
  198. package/src/deltas/apis/http/httpPost.ts +61 -0
  199. package/src/deltas/apis/http/httpPostFormData.ts +67 -0
  200. package/src/deltas/apis/login/GetBotInfo.ts +88 -0
  201. package/src/deltas/apis/login/getBotInitialData.ts +42 -0
  202. package/src/deltas/apis/login/logout.ts +62 -0
  203. package/src/deltas/apis/messaging/editMessage.ts +69 -0
  204. package/src/deltas/apis/messaging/emoji.ts +135 -0
  205. package/src/deltas/apis/messaging/gcmember.ts +175 -0
  206. package/src/deltas/apis/messaging/gcname.ts +136 -0
  207. package/src/deltas/apis/messaging/gcrule.ts +152 -0
  208. package/src/deltas/apis/messaging/markAsDelivered.ts +47 -0
  209. package/src/deltas/apis/messaging/markAsRead.ts +94 -0
  210. package/src/deltas/apis/messaging/markAsReadAll.ts +38 -0
  211. package/src/deltas/apis/messaging/markAsSeen.ts +69 -0
  212. package/src/deltas/apis/messaging/nickname.ts +153 -0
  213. package/src/deltas/apis/messaging/notes.ts +165 -0
  214. package/src/deltas/apis/messaging/resolvePhotoUrl.ts +56 -0
  215. package/src/deltas/apis/messaging/sendMessage.ts +286 -0
  216. package/src/deltas/apis/messaging/sendTypingIndicator.ts +48 -0
  217. package/src/deltas/apis/messaging/setMessageReaction.ts +25 -0
  218. package/src/deltas/apis/messaging/shareContact.ts +63 -0
  219. package/src/deltas/apis/messaging/stickers.ts +255 -0
  220. package/src/deltas/apis/messaging/theme.ts +280 -0
  221. package/src/deltas/apis/messaging/unsendMessage.ts +15 -0
  222. package/src/deltas/apis/mqtt/deltas/value.ts +224 -0
  223. package/src/deltas/apis/mqtt/listenMqtt.ts +332 -0
  224. package/src/deltas/apis/mqtt/listenSpeed.ts +179 -0
  225. package/src/deltas/apis/mqtt/pinMessage.ts +135 -0
  226. package/src/deltas/apis/mqtt/realtime.ts +169 -0
  227. package/src/deltas/apis/mqtt/sendMessageMqtt.ts +206 -0
  228. package/src/deltas/apis/mqtt/setMessageReactionMqtt.ts +61 -0
  229. package/src/deltas/apis/posting/comment.ts +205 -0
  230. package/src/deltas/apis/posting/follow.ts +79 -0
  231. package/src/deltas/apis/posting/friend.ts +241 -0
  232. package/src/deltas/apis/posting/post.ts +599 -0
  233. package/src/deltas/apis/posting/share.ts +60 -0
  234. package/src/deltas/apis/posting/story.ts +207 -0
  235. package/src/deltas/apis/threads/getThreadHistory.ts +237 -0
  236. package/src/deltas/apis/threads/getThreadInfo.ts +210 -0
  237. package/src/deltas/apis/threads/getThreadList.ts +224 -0
  238. package/src/deltas/apis/users/getUserInfo.ts +244 -0
  239. package/src/types/index.d.ts +696 -0
  240. package/src/utils/axios.ts +178 -0
  241. package/src/utils/clients.ts +125 -0
  242. package/src/utils/constants.ts +281 -0
  243. package/src/utils/formatters/data/formatAttachment.ts +58 -0
  244. package/src/utils/formatters/data/formatDelta.ts +45 -0
  245. package/src/utils/formatters/index.ts +82 -0
  246. package/src/utils/formatters/value/formatCookie.ts +13 -0
  247. package/src/utils/formatters/value/formatDate.ts +34 -0
  248. package/src/utils/formatters/value/formatID.ts +14 -0
  249. package/src/utils/formatters.old.ts +1049 -0
  250. package/src/utils/headers.ts +65 -0
  251. package/src/utils/index.ts +65 -0
  252. package/src/utils/user-agents.ts +49 -0
  253. package/tsconfig.json +37 -0
@@ -0,0 +1,1049 @@
1
+ const url = require("url");
2
+
3
+ const querystring = require("querystring");
4
+
5
+ const stream = require("stream");
6
+
7
+ const { getType, padZeros, NUM_TO_MONTH, NUM_TO_DAY } = require("./constants");
8
+ function isReadableStream(obj) {
9
+ return obj instanceof stream.Stream && typeof obj._read == "function" && getType(obj._readableState) == "Object";
10
+ }
11
+
12
+ function getExtension(original_extension, fullFileName = "") {
13
+ if (original_extension) {
14
+ return original_extension;
15
+ } else {
16
+ const extension = fullFileName.split(".").pop();
17
+ if (extension === fullFileName) {
18
+ return "";
19
+ } else {
20
+ return extension;
21
+ }
22
+ }
23
+ }
24
+
25
+ /**
26
+ * A function for formatting incoming attachments.
27
+ * @param {Object} attachment1 - The main attachment object.
28
+ * @param {Object} attachment2 - A secondary attachment object that sometimes contains additional data.
29
+ * @returns {Object} A formatted attachment object.
30
+ */
31
+ function _formatAttachment(attachment1, attachment2) {
32
+ const blob_attachment = attachment1.mercury || attachment1.blob_attachment || attachment1.sticker_attachment;
33
+ const type_attachment = blob_attachment && blob_attachment.__typename ? blob_attachment.__typename : attachment1.attach_type;
34
+ if (type_attachment == null && attachment1.id != null && attachment1.extensible_attachment == null) {
35
+ return {
36
+ type: "share",
37
+ ID: attachment1.id,
38
+ url: attachment1.href,
39
+ title: "Shared Content",
40
+ description: "Unsupported shared content.",
41
+ source: null,
42
+ isUnrecognized: true
43
+ };
44
+ }
45
+
46
+ if (!attachment1.attach_type && attachment1.imageMetadata) {
47
+ return {
48
+ type: 'photo',
49
+ ID: attachment1.fbid,
50
+ filename: attachment1.filename,
51
+ fileSize: Number(attachment1.fileSize || 0),
52
+ mimeType: attachment1.mimeType,
53
+ width: attachment1.imageMetadata.width,
54
+ height: attachment1.imageMetadata.height,
55
+ url: null, // URLs are not provided in this delta format
56
+ thumbnailUrl: null,
57
+ previewUrl: null,
58
+ largePreviewUrl: null,
59
+ name: attachment1.filename
60
+ };
61
+ }
62
+ // END of new code
63
+
64
+ attachment2 = attachment2 || {
65
+ id: "",
66
+ image_data: {}
67
+ };
68
+ attachment1 = attachment1.mercury || attachment1;
69
+ let blob = attachment1.blob_attachment || attachment1.sticker_attachment;
70
+ let type =
71
+ blob && blob.__typename ? blob.__typename : attachment1.attach_type;
72
+ if (!type && attachment1.sticker_attachment) {
73
+ type = "StickerAttachment";
74
+ blob = attachment1.sticker_attachment;
75
+ } else if (!type && attachment1.extensible_attachment) {
76
+ if (
77
+ attachment1.extensible_attachment.story_attachment &&
78
+ attachment1.extensible_attachment.story_attachment.target &&
79
+ attachment1.extensible_attachment.story_attachment.target.__typename &&
80
+ attachment1.extensible_attachment.story_attachment.target.__typename === "MessageLocation"
81
+ ) {
82
+ type = "MessageLocation";
83
+ } else {
84
+ type = "ExtensibleAttachment";
85
+ }
86
+
87
+ blob = attachment1.extensible_attachment;
88
+ }
89
+
90
+ const fullFileName = attachment1.filename;
91
+ const fileSize = Number(attachment1.fileSize || 0);
92
+ const durationVideo = attachment1.genericMetadata ? Number(attachment1.genericMetadata.videoLength) : undefined;
93
+ const durationAudio = attachment1.genericMetadata ? Number(attachment1.genericMetadata.duration) : undefined;
94
+ const mimeType = attachment1.mimeType;
95
+
96
+ switch (type) {
97
+ case "sticker":
98
+ return {
99
+ type: "sticker",
100
+ ID: attachment1.metadata.stickerID.toString(),
101
+ url: attachment1.url,
102
+ packID: attachment1.metadata.packID.toString(),
103
+ spriteUrl: attachment1.metadata.spriteURI,
104
+ spriteUrl2x: attachment1.metadata.spriteURI2x,
105
+ width: attachment1.metadata.width,
106
+ height: attachment1.metadata.height,
107
+ caption: attachment2.caption,
108
+ description: attachment2.description,
109
+ frameCount: attachment1.metadata.frameCount,
110
+ frameRate: attachment1.metadata.frameRate,
111
+ framesPerRow: attachment1.metadata.framesPerRow,
112
+ framesPerCol: attachment1.metadata.framesPerCol,
113
+ stickerID: attachment1.metadata.stickerID.toString(),
114
+ spriteURI: attachment1.metadata.spriteURI,
115
+ spriteURI2x: attachment1.metadata.spriteURI2x
116
+ };
117
+ case "file":
118
+ return {
119
+ type: "file",
120
+ ID: attachment2.id.toString(),
121
+ fullFileName: fullFileName,
122
+ filename: attachment1.name,
123
+ fileSize: fileSize,
124
+ original_extension: getExtension(attachment1.original_extension, fullFileName),
125
+ mimeType: mimeType,
126
+ url: attachment1.url,
127
+ isMalicious: attachment2.is_malicious,
128
+ contentType: attachment2.mime_type,
129
+ name: attachment1.name
130
+ };
131
+ case "photo":
132
+ return {
133
+ type: "photo",
134
+ ID: attachment1.metadata.fbid.toString(),
135
+ filename: attachment1.fileName,
136
+ fullFileName: fullFileName,
137
+ fileSize: fileSize,
138
+ original_extension: getExtension(attachment1.original_extension, fullFileName),
139
+ mimeType: mimeType,
140
+ thumbnailUrl: attachment1.thumbnail_url,
141
+ previewUrl: attachment1.preview_url,
142
+ previewWidth: attachment1.preview_width,
143
+ previewHeight: attachment1.preview_height,
144
+ largePreviewUrl: attachment1.large_preview_url,
145
+ largePreviewWidth: attachment1.large_preview_width,
146
+ largePreviewHeight: attachment1.large_preview_height,
147
+ url: attachment1.metadata.url,
148
+ width: attachment1.metadata.dimensions.split(",")[0],
149
+ height: attachment1.metadata.dimensions.split(",")[1],
150
+ name: fullFileName
151
+ };
152
+ case "animated_image":
153
+ return {
154
+ type: "animated_image",
155
+ ID: attachment2.id.toString(),
156
+ filename: attachment2.filename,
157
+ fullFileName: fullFileName,
158
+ original_extension: getExtension(attachment2.original_extension, fullFileName),
159
+ mimeType: mimeType,
160
+ previewUrl: attachment1.preview_url,
161
+ previewWidth: attachment1.preview_width,
162
+ previewHeight: attachment1.preview_height,
163
+ url: attachment2.image_data.url,
164
+ width: attachment2.image_data.width,
165
+ height: attachment2.image_data.height,
166
+ name: attachment1.name,
167
+ facebookUrl: attachment1.url,
168
+ thumbnailUrl: attachment1.thumbnail_url,
169
+ rawGifImage: attachment2.image_data.raw_gif_image,
170
+ rawWebpImage: attachment2.image_data.raw_webp_image,
171
+ animatedGifUrl: attachment2.image_data.animated_gif_url,
172
+ animatedGifPreviewUrl: attachment2.image_data.animated_gif_preview_url,
173
+ animatedWebpUrl: attachment2.image_data.animated_webp_url,
174
+ animatedWebpPreviewUrl: attachment2.image_data.animated_webp_preview_url
175
+ };
176
+ case "share":
177
+ return {
178
+ type: "share",
179
+ ID: attachment1.share.share_id.toString(),
180
+ url: attachment2.href,
181
+ title: attachment1.share.title,
182
+ description: attachment1.share.description,
183
+ source: attachment1.share.source,
184
+ image: attachment1.share.media.image,
185
+ width: attachment1.share.media.image_slicewidth,
186
+ height: attachment1.share.media.image_size.height,
187
+ playable: attachment1.share.media.playable,
188
+ duration: attachment1.share.media.duration,
189
+ subattachments: attachment1.share.subattachments,
190
+ properties: {},
191
+ animatedImageSize: attachment1.share.media.animated_image_size,
192
+ facebookUrl: attachment1.share.uri,
193
+ target: attachment1.share.target,
194
+ styleList: attachment1.share.style_list
195
+ };
196
+ case "video":
197
+ return {
198
+ type: "video",
199
+ ID: attachment1.metadata.fbid.toString(),
200
+ filename: attachment1.name,
201
+ fullFileName: fullFileName,
202
+ original_extension: getExtension(attachment1.original_extension, fullFileName),
203
+ mimeType: mimeType,
204
+ duration: durationVideo,
205
+ previewUrl: attachment1.preview_url,
206
+ previewWidth: attachment1.preview_width,
207
+ previewHeight: attachment1.preview_height,
208
+ url: attachment1.url,
209
+ width: attachment1.metadata.dimensions.width,
210
+ height: attachment1.metadata.dimensions.height,
211
+ videoType: "unknown",
212
+ thumbnailUrl: attachment1.thumbnail_url
213
+ };
214
+ case "error":
215
+ return {
216
+ type: "error",
217
+ attachment1: attachment1,
218
+ attachment2: attachment2
219
+ };
220
+ case "MessageImage":
221
+ return {
222
+ type: "photo",
223
+ ID: blob.legacy_attachment_id,
224
+ filename: blob.filename,
225
+ fullFileName: fullFileName,
226
+ fileSize: fileSize,
227
+ original_extension: getExtension(blob.original_extension, fullFileName),
228
+ mimeType: mimeType,
229
+ thumbnailUrl: blob.thumbnail.uri,
230
+ previewUrl: blob.preview.uri,
231
+ previewWidth: blob.preview.width,
232
+ previewHeight: blob.preview.height,
233
+ largePreviewUrl: blob.large_preview.uri,
234
+ largePreviewWidth: blob.large_preview.width,
235
+ largePreviewHeight: blob.large_preview.height,
236
+ url: blob.large_preview.uri,
237
+ width: blob.original_dimensions.x,
238
+ height: blob.original_dimensions.y,
239
+ name: blob.filename
240
+ };
241
+ case "MessageAnimatedImage":
242
+ return {
243
+ type: "animated_image",
244
+ ID: blob.legacy_attachment_id,
245
+ filename: blob.filename,
246
+ fullFileName: fullFileName,
247
+ original_extension: getExtension(blob.original_extension, fullFileName),
248
+ mimeType: mimeType,
249
+ previewUrl: blob.preview_image.uri,
250
+ previewWidth: blob.preview_image.width,
251
+ previewHeight: blob.preview_image.height,
252
+ url: blob.animated_image.uri,
253
+ width: blob.animated_image.width,
254
+ height: blob.animated_image.height,
255
+ thumbnailUrl: blob.preview_image.uri,
256
+ name: blob.filename,
257
+ facebookUrl: blob.animated_image.uri,
258
+ rawGifImage: blob.animated_image.uri,
259
+ animatedGifUrl: blob.animated_image.uri,
260
+ animatedGifPreviewUrl: blob.preview_image.uri,
261
+ animatedWebpUrl: blob.animated_image.uri,
262
+ animatedWebpPreviewUrl: blob.preview_image.uri
263
+ };
264
+ case "MessageVideo":
265
+ return {
266
+ type: "video",
267
+ ID: blob.legacy_attachment_id,
268
+ filename: blob.filename,
269
+ fullFileName: fullFileName,
270
+ original_extension: getExtension(blob.original_extension, fullFileName),
271
+ fileSize: fileSize,
272
+ duration: durationVideo,
273
+ mimeType: mimeType,
274
+ previewUrl: blob.large_image.uri,
275
+ previewWidth: blob.large_image.width,
276
+ previewHeight: blob.large_image.height,
277
+ url: blob.playable_url,
278
+ width: blob.original_dimensions.x,
279
+ height: blob.original_dimensions.y,
280
+ videoType: blob.video_type.toLowerCase(),
281
+ thumbnailUrl: blob.large_image.uri
282
+ };
283
+ case "MessageAudio":
284
+ return {
285
+ type: "audio",
286
+ ID: blob.url_shimhash,
287
+ filename: blob.filename,
288
+ fullFileName: fullFileName,
289
+ fileSize: fileSize,
290
+ duration: durationAudio,
291
+ original_extension: getExtension(blob.original_extension, fullFileName),
292
+ mimeType: mimeType,
293
+ audioType: blob.audio_type,
294
+ url: blob.playable_url,
295
+ isVoiceMail: blob.is_voicemail
296
+ };
297
+ case "StickerAttachment":
298
+ case "Sticker":
299
+ return {
300
+ type: "sticker",
301
+ ID: blob.id,
302
+ url: blob.url,
303
+ packID: blob.pack ? blob.pack.id : null,
304
+ spriteUrl: blob.sprite_image,
305
+ spriteUrl2x: blob.sprite_image_2x,
306
+ width: blob.width,
307
+ height: blob.height,
308
+ caption: blob.label,
309
+ description: blob.label,
310
+ frameCount: blob.frame_count,
311
+ frameRate: blob.frame_rate,
312
+ framesPerRow: blob.frames_per_row,
313
+ framesPerCol: blob.frames_per_column,
314
+ stickerID: blob.id,
315
+ spriteURI: blob.sprite_image,
316
+ spriteURI2x: blob.sprite_image_2x
317
+ };
318
+ case "MessageLocation":
319
+ var urlAttach = blob.story_attachment.url;
320
+ var mediaAttach = blob.story_attachment.media;
321
+
322
+ var u = querystring.parse(url.parse(urlAttach).query).u;
323
+ var where1 = querystring.parse(url.parse(u).query).where1;
324
+ var address = where1.split(", ");
325
+
326
+ var latitude;
327
+ var longitude;
328
+
329
+ try {
330
+ latitude = Number.parseFloat(address[0]);
331
+ longitude = Number.parseFloat(address[1]);
332
+ } catch (err) {
333
+ /* empty */
334
+ }
335
+ var imageUrl;
336
+ var width;
337
+ var height;
338
+ if (mediaAttach && mediaAttach.image) {
339
+ imageUrl = mediaAttach.image.uri;
340
+ width = mediaAttach.image.width;
341
+ height = mediaAttach.image.height;
342
+ }
343
+
344
+ return {
345
+ type: "location",
346
+ ID: blob.legacy_attachment_id,
347
+ latitude: latitude,
348
+ longitude: longitude,
349
+ image: imageUrl,
350
+ width: width,
351
+ height: height,
352
+ url: u || urlAttach,
353
+ address: where1,
354
+ facebookUrl: blob.story_attachment.url,
355
+ target: blob.story_attachment.target,
356
+ styleList: blob.story_attachment.style_list
357
+ };
358
+ case "ExtensibleAttachment":
359
+ return {
360
+ type: "share",
361
+ ID: blob.legacy_attachment_id,
362
+ url: blob.story_attachment.url,
363
+ title: blob.story_attachment.title_with_entities.text,
364
+ description:
365
+ blob.story_attachment.description &&
366
+ blob.story_attachment.description.text,
367
+ source: blob.story_attachment.source ? blob.story_attachment.source.text : null,
368
+ image:
369
+ blob.story_attachment.media &&
370
+ blob.story_attachment.media.image &&
371
+ blob.story_attachment.media.image.uri,
372
+ width:
373
+ blob.story_attachment.media &&
374
+ blob.story_attachment.media.image &&
375
+ blob.story_attachment.media.image.width,
376
+ height:
377
+ blob.story_attachment.media &&
378
+ blob.story_attachment.media.image &&
379
+ blob.story_attachment.media.image.height,
380
+ playable:
381
+ blob.story_attachment.media &&
382
+ blob.story_attachment.media.is_playable,
383
+ duration:
384
+ blob.story_attachment.media &&
385
+ blob.story_attachment.media.playable_duration_in_ms,
386
+ playableUrl:
387
+ blob.story_attachment.media == null ? null :
388
+ blob.story_attachment.media.playable_url,
389
+ subattachments: blob.story_attachment.subattachments,
390
+ properties: blob.story_attachment.properties.reduce(function (obj, cur) {
391
+ obj[cur.key] = cur.value.text;
392
+ return obj;
393
+ }, {}),
394
+ facebookUrl: blob.story_attachment.url,
395
+ target: blob.story_attachment.target,
396
+ styleList: blob.story_attachment.style_list
397
+ };
398
+ case "MessageFile":
399
+ return {
400
+ type: "file",
401
+ ID: blob.message_file_fbid,
402
+ fullFileName: fullFileName,
403
+ filename: blob.filename,
404
+ fileSize: fileSize,
405
+ mimeType: blob.mimetype,
406
+ original_extension: blob.original_extension || fullFileName.split(".").pop(),
407
+ url: blob.url,
408
+ isMalicious: blob.is_malicious,
409
+ contentType: blob.content_type,
410
+ name: blob.filename
411
+ };
412
+ default:
413
+ throw new Error(
414
+ "unrecognized attach_file of type " +
415
+ type +
416
+ "`" +
417
+ JSON.stringify(attachment1, null, 4) +
418
+ " attachment2: " +
419
+ JSON.stringify(attachment2, null, 4) +
420
+ "`"
421
+ );
422
+ }
423
+ } function formatAttachment(attachments, attachmentIds, attachmentMap, shareMap) {
424
+ attachmentMap = shareMap || attachmentMap;
425
+ return attachments ?
426
+ attachments.map(function (val, i) {
427
+ if (
428
+ !attachmentMap ||
429
+ !attachmentIds ||
430
+ !attachmentMap[attachmentIds[i]]
431
+ ) {
432
+ return _formatAttachment(val);
433
+ }
434
+ return _formatAttachment(val, attachmentMap[attachmentIds[i]]);
435
+ }) : [];
436
+ }
437
+
438
+ /**
439
+ * file: bb-fca/datas/formatters.js
440
+ * Hanapin ang function na ito at palitan ng version na ito.
441
+ */
442
+ function formatDeltaMessage(m) {
443
+ const md = m.delta.messageMetadata;
444
+ const mdata =
445
+ m.delta.data === undefined ?
446
+ [] :
447
+ m.delta.data.prng === undefined ?
448
+ [] :
449
+ JSON.parse(m.delta.data.prng);
450
+ const m_id = mdata.map(u => u.i);
451
+ const m_offset = mdata.map(u => u.o);
452
+ const m_length = mdata.map(u => u.l);
453
+ const mentions = {};
454
+ for (let i = 0; i < m_id.length; i++) {
455
+ mentions[m_id[i]] = m.delta.body.substring(
456
+ m_offset[i],
457
+ m_offset[i] + m_length[i]
458
+ );
459
+ }
460
+
461
+ return {
462
+ type: "message",
463
+ senderID: formatID(md.actorFbId.toString()),
464
+ body: m.delta.body || "",
465
+ threadID: formatID(
466
+ (md.threadKey.threadFbId || md.threadKey.otherUserFbId).toString()
467
+ ),
468
+ messageID: md.messageId,
469
+ offlineThreadingId: md.offlineThreadingId,
470
+ attachments: (m.delta.attachments || []).map(v => _formatAttachment(v)),
471
+ mentions: mentions,
472
+ timestamp: md.timestamp,
473
+ isGroup: !!md.threadKey.threadFbId,
474
+ participantIDs: m.delta.participants
475
+ };
476
+ } function formatID(id) {
477
+ if (id != undefined && id != null) {
478
+ return id.replace(/(fb)?id[:.]/, "");
479
+ } else {
480
+ return id;
481
+ }
482
+ }
483
+
484
+ function formatMessage(m) {
485
+ const originalMessage = m.message ? m.message : m;
486
+ const obj = {
487
+ type: "message",
488
+ senderName: originalMessage.sender_name,
489
+ senderID: formatID(originalMessage.sender_fbid.toString()),
490
+ participantNames: originalMessage.group_thread_info ?
491
+ originalMessage.group_thread_info.participant_names : [originalMessage.sender_name.split(" ")[0]],
492
+ participantIDs: originalMessage.group_thread_info ?
493
+ originalMessage.group_thread_info.participant_ids.map(function (v) {
494
+ return formatID(v.toString());
495
+ }) : [formatID(originalMessage.sender_fbid)],
496
+ body: originalMessage.body || "",
497
+ threadID: formatID(
498
+ (
499
+ originalMessage.thread_fbid || originalMessage.other_user_fbid
500
+ ).toString()
501
+ ),
502
+ threadName: originalMessage.group_thread_info ?
503
+ originalMessage.group_thread_info.name : originalMessage.sender_name,
504
+ location: originalMessage.coordinates ? originalMessage.coordinates : null,
505
+ messageID: originalMessage.mid ?
506
+ originalMessage.mid.toString() : originalMessage.message_id,
507
+ attachments: formatAttachment(
508
+ originalMessage.attachments,
509
+ originalMessage.attachmentIds,
510
+ originalMessage.attachment_map,
511
+ originalMessage.share_map
512
+ ),
513
+ timestamp: originalMessage.timestamp,
514
+ timestampAbsolute: originalMessage.timestamp_absolute,
515
+ timestampRelative: originalMessage.timestamp_relative,
516
+ timestampDatetime: originalMessage.timestamp_datetime,
517
+ tags: originalMessage.tags,
518
+ reactions: originalMessage.reactions ? originalMessage.reactions : [],
519
+ isUnread: originalMessage.is_unread
520
+ };
521
+
522
+ if (m.type === "pages_messaging")
523
+ obj.pageID = m.realtime_viewer_fbid.toString();
524
+ obj.isGroup = obj.participantIDs.length > 2;
525
+
526
+ return obj;
527
+ }
528
+
529
+ function formatEvent(m) {
530
+ const originalMessage = m.message ? m.message : m;
531
+ let logMessageType = originalMessage.log_message_type;
532
+ let logMessageData;
533
+ if (logMessageType === "log:generic-admin-text") {
534
+ logMessageData = originalMessage.log_message_data.untypedData;
535
+ logMessageType = getAdminTextMessageType(
536
+ originalMessage.log_message_data.message_type
537
+ );
538
+ } else {
539
+ logMessageData = originalMessage.log_message_data;
540
+ }
541
+
542
+ return Object.assign(formatMessage(originalMessage), {
543
+ type: "event",
544
+ logMessageType: logMessageType,
545
+ logMessageData: logMessageData,
546
+ logMessageBody: originalMessage.log_message_body
547
+ });
548
+ }
549
+
550
+ function formatHistoryMessage(m) {
551
+ switch (m.action_type) {
552
+ case "ma-type:log-message":
553
+ return formatEvent(m);
554
+ default:
555
+ return formatMessage(m);
556
+ }
557
+ }
558
+
559
+ // Get a more readable message type for AdminTextMessages
560
+ function getAdminTextMessageType(type) {
561
+ switch (type) {
562
+ case 'unpin_messages_v2':
563
+ return 'log:unpin-message';
564
+ case 'pin_messages_v2':
565
+ return 'log:pin-message';
566
+ case "change_thread_theme":
567
+ return "log:thread-color";
568
+ case "change_thread_icon":
569
+ case 'change_thread_quick_reaction':
570
+ return "log:thread-icon";
571
+ case "change_thread_nickname":
572
+ return "log:user-nickname";
573
+ case "change_thread_admins":
574
+ return "log:thread-admins";
575
+ case "group_poll":
576
+ return "log:thread-poll";
577
+ case "change_thread_approval_mode":
578
+ return "log:thread-approval-mode";
579
+ case "messenger_call_log":
580
+ case "participant_joined_group_call":
581
+ return "log:thread-call";
582
+ default:
583
+ return type;
584
+ }
585
+ }
586
+
587
+ function formatDeltaEvent(m) {
588
+ let logMessageType;
589
+ let logMessageData;
590
+
591
+ // log:thread-color => {theme_color}
592
+ // log:user-nickname => {participant_id, nickname}
593
+ // log:thread-icon => {thread_icon}
594
+ // log:thread-name => {name}
595
+ // log:subscribe => {addedParticipants - [Array]}
596
+ // log:unsubscribe => {leftParticipantFbId}
597
+
598
+ switch (m.class) {
599
+ case "AdminTextMessage":
600
+ logMessageData = m.untypedData;
601
+ logMessageType = getAdminTextMessageType(m.type);
602
+ break;
603
+ case "ThreadName":
604
+ logMessageType = "log:thread-name";
605
+ logMessageData = {
606
+ name: m.name
607
+ };
608
+ break;
609
+ case "ParticipantsAddedToGroupThread":
610
+ logMessageType = "log:subscribe";
611
+ logMessageData = {
612
+ addedParticipants: m.addedParticipants
613
+ };
614
+ break;
615
+ case "ParticipantLeftGroupThread":
616
+ logMessageType = "log:unsubscribe";
617
+ logMessageData = {
618
+ leftParticipantFbId: m.leftParticipantFbId
619
+ };
620
+ break;
621
+ case "ApprovalQueue":
622
+ logMessageType = "log:approval-queue";
623
+ logMessageData = {
624
+ approvalQueue: {
625
+ action: m.action,
626
+ recipientFbId: m.recipientFbId,
627
+ requestSource: m.requestSource,
628
+ ...m.messageMetadata
629
+ }
630
+ };
631
+ }
632
+ return {
633
+ type: "event",
634
+ threadID: formatID(
635
+ (
636
+ m.messageMetadata.threadKey.threadFbId ||
637
+ m.messageMetadata.threadKey.otherUserFbId
638
+ ).toString()
639
+ ),
640
+ messageID: m.messageMetadata.messageId.toString(),
641
+ logMessageType,
642
+ logMessageData,
643
+ logMessageBody: m.messageMetadata.adminText,
644
+ timestamp: m.messageMetadata.timestamp,
645
+ author: m.messageMetadata.actorFbId,
646
+ participantIDs: m.participants
647
+ };
648
+ }
649
+
650
+ function formatTyp(event) {
651
+ return {
652
+ isTyping: !!event.st,
653
+ from: event.from.toString(),
654
+ threadID: formatID(
655
+ (event.to || event.thread_fbid || event.from).toString()
656
+ ),
657
+ // When receiving typ indication from mobile, `from_mobile` isn't set.
658
+ // If it is, we just use that value.
659
+ fromMobile: event.hasOwnProperty("from_mobile") ? event.from_mobile : true,
660
+ userID: (event.realtime_viewer_fbid || event.from).toString(),
661
+ type: "typ"
662
+ };
663
+ }
664
+
665
+ function formatDeltaReadReceipt(delta) {
666
+ // otherUserFbId seems to be used as both the readerID and the threadID in a 1-1 chat.
667
+ // In a group chat actorFbId is used for the reader and threadFbId for the thread.
668
+ return {
669
+ reader: (delta.threadKey.otherUserFbId || delta.actorFbId).toString(),
670
+ time: delta.actionTimestampMs,
671
+ threadID: formatID(
672
+ (delta.threadKey.otherUserFbId || delta.threadKey.threadFbId).toString()
673
+ ),
674
+ type: "read_receipt"
675
+ };
676
+ }
677
+
678
+ function formatReadReceipt(event) {
679
+ return {
680
+ reader: event.reader.toString(),
681
+ time: event.time,
682
+ threadID: formatID((event.thread_fbid || event.reader).toString()),
683
+ type: "read_receipt"
684
+ };
685
+ }
686
+
687
+ function formatRead(event) {
688
+ return {
689
+ threadID: formatID(
690
+ (
691
+ (event.chat_ids && event.chat_ids[0]) ||
692
+ (event.thread_fbids && event.thread_fbids[0])
693
+ ).toString()
694
+ ),
695
+ time: event.timestamp,
696
+ type: "read"
697
+ };
698
+ }
699
+
700
+ function getFrom(str, startToken, endToken) {
701
+ const start = str.indexOf(startToken) + startToken.length;
702
+ if (start < startToken.length) return "";
703
+
704
+ const lastHalf = str.substring(start);
705
+ const end = lastHalf.indexOf(endToken);
706
+ if (end === -1) {
707
+ throw Error(
708
+ "Could not find endTime `" + endToken + "` in the given string."
709
+ );
710
+ }
711
+ return lastHalf.substring(0, end);
712
+ }
713
+
714
+ function makeParsable(html) {
715
+ const withoutForLoop = html.replace(/for\s*\(\s*;\s*;\s*\)\s*;\s*/, "");
716
+
717
+ // (What the fuck FB, why windows style newlines?)
718
+ // So sometimes FB will send us base multiple objects in the same response.
719
+ // They're all valid JSON, one after the other, at the top level. We detect
720
+ // that and make it parse-able by JSON.parse.
721
+ // Ben - July 15th 2017
722
+ //
723
+ // It turns out that Facebook may insert random number of spaces before
724
+ // next object begins (issue #616)
725
+ // rav_kr - 2018-03-19
726
+ const maybeMultipleObjects = withoutForLoop.split(/\}\r\n *\{/);
727
+ if (maybeMultipleObjects.length === 1) return maybeMultipleObjects;
728
+
729
+ return "[" + maybeMultipleObjects.join("},{") + "]";
730
+ }
731
+
732
+ function arrToForm(form) {
733
+ return arrayToObject(
734
+ form,
735
+ function (v) {
736
+ return v.name;
737
+ },
738
+ function (v) {
739
+ return v.val;
740
+ }
741
+ );
742
+ }
743
+
744
+ function arrayToObject(arr, getKey, getValue) {
745
+ return arr.reduce(function (acc, val) {
746
+ acc[getKey(val)] = getValue(val);
747
+ return acc;
748
+ }, {});
749
+ }
750
+
751
+ function getSignatureID() {
752
+ return Math.floor(Math.random() * 2147483648).toString(16);
753
+ }
754
+
755
+ function generateTimestampRelative() {
756
+ const d = new Date();
757
+ return d.getHours() + ":" + padZeros(d.getMinutes());
758
+ }
759
+
760
+ function makeDefaults(html, userID, ctx) {
761
+ let reqCounter = 1;
762
+ const revision = getFrom(html, 'revision":', ",");
763
+ function mergeWithDefaults(obj) {
764
+ const newObj = {
765
+ av: userID,
766
+ __user: userID,
767
+ __req: (reqCounter++).toString(36),
768
+ __rev: revision,
769
+ __a: 1,
770
+ ...(ctx && {
771
+ fb_dtsg: ctx.fb_dtsg,
772
+ jazoest: ctx.jazoest
773
+ })
774
+ }
775
+
776
+ if (!obj) return newObj;
777
+
778
+ for (var prop in obj) {
779
+ if (obj.hasOwnProperty(prop)) {
780
+ if (!newObj[prop])
781
+ newObj[prop] = obj[prop];
782
+ }
783
+ }
784
+
785
+ return newObj;
786
+ }
787
+
788
+ return {
789
+ get: (url, jar, qs, ctxx, customHeader = {}) => get(url, jar, mergeWithDefaults(qs), ctx.globalOptions, ctxx || ctx, customHeader),
790
+ post: (url, jar, form, ctxx, customHeader = {}) => post(url, jar, mergeWithDefaults(form), ctx.globalOptions, ctxx || ctx, customHeader),
791
+ postFormData: (url, jar, form, qs, ctxx) => postFormData(url, jar, mergeWithDefaults(form), mergeWithDefaults(qs), ctx.globalOptions, ctxx || ctx)
792
+ };
793
+ }
794
+
795
+ function parseAndCheckLogin(ctx, http, retryCount) {
796
+ var delay = (ms) => new Promise(resolve => setTimeout(resolve, ms));
797
+ var _try = (tryData) => new Promise<any>(function (resolve, reject) {
798
+ try {
799
+ resolve(tryData());
800
+ } catch (error) {
801
+ reject(error);
802
+ }
803
+ });
804
+ if (retryCount == undefined) retryCount = 0;
805
+
806
+ return function (data) {
807
+ function any() {
808
+ if (data.statusCode >= 500 && data.statusCode < 600) {
809
+ if (retryCount >= 5) {
810
+ const err = new Error("Request retry failed. Check the `res` and `statusCode` property on this error.");
811
+ err.statusCode = data.statusCode;
812
+ err.res = data.body;
813
+ err.error = "Request retry failed. Check the `res` and `statusCode` property on this error.";
814
+ throw err;
815
+ }
816
+ retryCount++;
817
+ const retryTime = Math.floor(Math.random() * 5000);
818
+ console.warn("parseAndCheckLogin", "Got status code " + data.statusCode + " - " + retryCount + ". attempt to retry in " + retryTime + " milliseconds...");
819
+ const url = data.request.uri.protocol + "//" + data.request.uri.hostname + data.request.uri.pathname;
820
+ if (data.request.headers["content-type"].split(";")[0] === "multipart/form-data") {
821
+ return delay(retryTime)
822
+ .then(function () {
823
+ return http
824
+ .postFormData(url, ctx.jar, data.request.formData);
825
+ })
826
+ .then(parseAndCheckLogin(ctx, http, retryCount));
827
+ } else {
828
+ return delay(retryTime)
829
+ .then(function () {
830
+ return http
831
+ .post(url, ctx.jar, data.request.formData);
832
+ })
833
+ .then(parseAndCheckLogin(ctx, http, retryCount));
834
+ }
835
+ }
836
+
837
+ if (data.statusCode === 404) return;
838
+
839
+ if (data.statusCode !== 200)
840
+ throw new Error("parseAndCheckLogin got status code: " + data.statusCode + ". Bailing out of trying to parse response.");
841
+
842
+ let res = null;
843
+ try {
844
+ res = JSON.parse(makeParsable(data.body));
845
+ } catch (e) {
846
+ const err = new Error("JSON.parse error. Check the `detail` property on this error.");
847
+ err.error = "JSON.parse error. Check the `detail` property on this error.";
848
+ err.detail = e;
849
+ err.res = data.body;
850
+ throw err;
851
+ }
852
+
853
+ // In some cases the response contains only a redirect URL which should be followed
854
+ if (res.redirect && data.request.method === "GET") {
855
+ return http
856
+ .get(res.redirect, ctx.jar)
857
+ .then(parseAndCheckLogin(ctx, http));
858
+ }
859
+
860
+ // TODO: handle multiple cookies?
861
+ if (res.jsmods && res.jsmods.require && Array.isArray(res.jsmods.require[0]) && res.jsmods.require[0][0] === "Cookie") {
862
+ res.jsmods.require[0][3][0] = res.jsmods.require[0][3][0].replace("_js_", "");
863
+ const requireCookie = res.jsmods.require[0][3];
864
+ ctx.jar.setCookie(formatCookie(requireCookie, "facebook"), "https://www.facebook.com");
865
+ ctx.jar.setCookie(formatCookie(requireCookie, "messenger"), "https://www.messenger.com");
866
+ }
867
+
868
+ // On every request we check if we got a DTSG and we mutate the context so that we use the latest
869
+ // one for the next requests.
870
+ if (res.jsmods && Array.isArray(res.jsmods.require)) {
871
+ const arr = res.jsmods.require;
872
+ for (const i in arr) {
873
+ if (arr[i][0] === "DTSG" && arr[i][1] === "setToken") {
874
+ ctx.fb_dtsg = arr[i][3][0];
875
+
876
+ // Update ttstamp since that depends on fb_dtsg
877
+ ctx.ttstamp = "2";
878
+ for (let j = 0; j < ctx.fb_dtsg.length; j++) {
879
+ ctx.ttstamp += ctx.fb_dtsg.charCodeAt(j);
880
+ }
881
+ }
882
+ }
883
+ }
884
+
885
+ if (res.error === 1357001) {
886
+ const err = new Error('Facebook blocked the login');
887
+ err.error = "Not logged in.";
888
+ throw err;
889
+ }
890
+ return res;
891
+ }
892
+ return _try(any);
893
+ };
894
+ }
895
+
896
+ function saveCookies(jar) {
897
+ return function (res) {
898
+ const cookies = res.headers["set-cookie"] || [];
899
+ cookies.forEach(function (c) {
900
+ if (c.indexOf(".facebook.com") > -1) {
901
+ jar.setCookie(c, "https://www.facebook.com");
902
+ }
903
+ const c2 = c.replace(/domain=\.facebook\.com/, "domain=.messenger.com");
904
+ jar.setCookie(c2, "https://www.messenger.com");
905
+ });
906
+ return res;
907
+ };
908
+ }
909
+
910
+ function formatThread(data) {
911
+ return {
912
+ threadID: formatID(data.thread_fbid.toString()),
913
+ participants: data.participants.map(formatID),
914
+ participantIDs: data.participants.map(formatID),
915
+ name: data.name,
916
+ nicknames: data.custom_nickname,
917
+ snippet: data.snippet,
918
+ snippetAttachments: data.snippet_attachments,
919
+ snippetSender: formatID((data.snippet_sender || "").toString()),
920
+ unreadCount: data.unread_count,
921
+ messageCount: data.message_count,
922
+ imageSrc: data.image_src,
923
+ timestamp: data.timestamp,
924
+ serverTimestamp: data.server_timestamp, // what is this?
925
+ muteUntil: data.mute_until,
926
+ isCanonicalUser: data.is_canonical_user,
927
+ isCanonical: data.is_canonical,
928
+ isSubscribed: data.is_subscribed,
929
+ folder: data.folder,
930
+ isArchived: data.is_archived,
931
+ recipientsLoadable: data.recipients_loadable,
932
+ hasEmailParticipant: data.has_email_participant,
933
+ readOnly: data.read_only,
934
+ canReply: data.can_reply,
935
+ cannotReplyReason: data.cannot_reply_reason,
936
+ lastMessageTimestamp: data.last_message_timestamp,
937
+ lastReadTimestamp: data.last_read_timestamp,
938
+ lastMessageType: data.last_message_type,
939
+ emoji: data.custom_like_icon,
940
+ color: data.custom_color,
941
+ adminIDs: data.admin_ids,
942
+ threadType: data.thread_type
943
+ };
944
+ }
945
+
946
+ function formatDate(date) {
947
+ let d = date.getUTCDate();
948
+ d = d >= 10 ? d : "0" + d;
949
+ let h = date.getUTCHours();
950
+ h = h >= 10 ? h : "0" + h;
951
+ let m = date.getUTCMinutes();
952
+ m = m >= 10 ? m : "0" + m;
953
+ let s = date.getUTCSeconds();
954
+ s = s >= 10 ? s : "0" + s;
955
+ return (
956
+ NUM_TO_DAY[date.getUTCDay()] +
957
+ ", " +
958
+ d +
959
+ " " +
960
+ NUM_TO_MONTH[date.getUTCMonth()] +
961
+ " " +
962
+ date.getUTCFullYear() +
963
+ " " +
964
+ h +
965
+ ":" +
966
+ m +
967
+ ":" +
968
+ s +
969
+ " GMT"
970
+ );
971
+ }
972
+
973
+ function formatCookie(arr, url) {
974
+ return (
975
+ arr[0] + "=" + arr[1] + "; Path=" + arr[3] + "; Domain=" + url + ".com"
976
+ );
977
+ }
978
+
979
+ function formatProxyPresence(presence, userID) {
980
+ if (presence.lat === undefined || presence.p === undefined) return null;
981
+ return {
982
+ type: "presence",
983
+ timestamp: presence.lat * 1000,
984
+ userID: userID,
985
+ statuses: presence.p
986
+ };
987
+ }
988
+
989
+ function formatPresence(presence, userID) {
990
+ return {
991
+ type: "presence",
992
+ timestamp: presence.la * 1000,
993
+ userID: userID,
994
+ statuses: presence.a
995
+ };
996
+ }
997
+
998
+ function decodeClientPayload(payload) {
999
+ /*
1000
+ Special function which Client using to "encode" clients JSON payload
1001
+ */
1002
+ return JSON.parse(String.fromCharCode.apply(null, payload));
1003
+ }
1004
+
1005
+
1006
+ module.exports = {
1007
+
1008
+ isReadableStream,
1009
+
1010
+ getExtension,
1011
+
1012
+ _formatAttachment,
1013
+
1014
+ formatAttachment,
1015
+
1016
+ formatDeltaMessage,
1017
+
1018
+ formatID,
1019
+
1020
+ formatMessage,
1021
+
1022
+ formatEvent,
1023
+
1024
+ formatHistoryMessage,
1025
+
1026
+ getAdminTextMessageType,
1027
+
1028
+ formatDeltaEvent,
1029
+
1030
+ formatTyp,
1031
+
1032
+ formatDeltaReadReceipt,
1033
+
1034
+ formatReadReceipt,
1035
+
1036
+ formatRead,
1037
+
1038
+ formatDate,
1039
+
1040
+ formatCookie,
1041
+
1042
+ formatThread,
1043
+
1044
+ formatProxyPresence,
1045
+
1046
+ formatPresence,
1047
+
1048
+ decodeClientPayload,
1049
+ };