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,169 @@
1
+ import { EventEmitter } from 'events';
2
+ import HttpsProxyAgent from 'https-proxy-agent';
3
+ import { WebSocket } from 'undici';
4
+ import utils = require('../../../utils');
5
+
6
+ function formatNotification(data) {
7
+ if (!data.data || !data.data.viewer) return null;
8
+ const notifEdge =
9
+ data.data.viewer.notifications_page?.edges?.[1]?.node?.notif;
10
+ if (!notifEdge) return null;
11
+
12
+ return {
13
+ type: 'notification',
14
+ notifID: notifEdge.notif_id,
15
+ body: notifEdge.body?.text,
16
+ senderID: Object.keys(notifEdge.tracking.from_uids || {})[0],
17
+ url: notifEdge.url,
18
+ timestamp: notifEdge.creation_time.timestamp,
19
+ seenState: notifEdge.seen_state,
20
+ };
21
+ }
22
+
23
+ export default function(defaultFuncs: any, api: any, ctx: any) {
24
+ return function listenRealtime() {
25
+ const emitter: any = new EventEmitter();
26
+ let ws;
27
+ let reconnectTimeout;
28
+ let keepAliveInterval;
29
+
30
+ const subscriptions = [
31
+ '{"x-dgw-app-XRSS-method":"Falco","x-dgw-app-xrs-body":"true","x-dgw-app-XRS-Accept-Ack":"RSAck","x-dgw-app-XRSS-http_referer":"https://www.facebook.com/friends"}',
32
+ '{"x-dgw-app-XRSS-method":"FBGQLS:USER_ACTIVITY_UPDATE_SUBSCRIBE","x-dgw-app-XRSS-doc_id":"9525970914181809","x-dgw-app-XRSS-routing_hint":"UserActivitySubscription","x-dgw-app-xrs-body":"true","x-dgw-app-XRS-Accept-Ack":"RSAck","x-dgw-app-XRSS-http_referer":"https://www.facebook.com/friends"}',
33
+ '{"x-dgw-app-XRSS-method":"FBGQLS:ACTOR_GATEWAY_EXPERIENCE_SUBSCRIBE","x-dgw-app-XRSS-doc_id":"24191710730466150","x-dgw-app-XRSS-routing_hint":"CometActorGatewayExperienceSubscription","x-dgw-app-xrs-body":"true","x-dgw-app-XRS-Accept-Ack":"RSAck","x-dgw-app-XRSS-http_referer":"https://www.facebook.com/friends"}',
34
+ `{"x-dgw-app-XRSS-method":"FBLQ:comet_notifications_live_query_experimental","x-dgw-app-XRSS-doc_id":"9784489068321501","x-dgw-app-XRSS-actor_id":"${ctx.userID}","x-dgw-app-XRSS-page_id":"${ctx.userID}","x-dgw-app-XRSS-request_stream_retry":"false","x-dgw-app-xrs-body":"true","x-dgw-app-XRS-Accept-Ack":"RSAck","x-dgw-app-XRSS-http_referer":"https://www.facebook.com/friends"}`,
35
+ '{"x-dgw-app-XRSS-method":"FBGQLS:FRIEND_REQUEST_CONFIRM_SUBSCRIBE","x-dgw-app-XRSS-doc_id":"9687616244672204","x-dgw-app-XRSS-routing_hint":"FriendingCometFriendRequestConfirmSubscription","x-dgw-app-xrs-body":"true","x-dgw-app-XRS-Accept-Ack":"RSAck","x-dgw-app-XRSS-http_referer":"https://www.facebook.com/friends"}',
36
+ '{"x-dgw-app-XRSS-method":"FBGQLS:FRIEND_REQUEST_RECEIVE_SUBSCRIBE","x-dgw-app-XRSS-doc_id":"24047008371656912","x-dgw-app-XRSS-routing_hint":"FriendingCometFriendRequestReceiveSubscription","x-dgw-app-xrs-body":"true","x-dgw-app-XRS-Accept-Ack":"RSAck","x-dgw-app-XRSS-http_referer":"https://www.facebook.com/friends"}',
37
+ '{"x-dgw-app-XRSS-method":"FBGQLS:RTWEB_CALL_BLOCKED_SETTING_SUBSCRIBE","x-dgw-app-XRSS-doc_id":"24429620016626810","x-dgw-app-XRSS-routing_hint":"RTWebCallBlockedSettingSubscription_CallBlockSettingSubscription","x-dgw-app-xrs-body":"true","x-dgw-app-XRS-Accept-Ack":"RSAck","x-dgw-app-XRSS-http_referer":"https://www.facebook.com/friends"}',
38
+ '{"x-dgw-app-XRSS-method":"PresenceUnifiedJSON","x-dgw-app-xrs-body":"true","x-dgw-app-XRS-Accept-Ack":"RSAck","x-dgw-app-XRSS-http_referer":"https://www.facebook.com/friends"}',
39
+ '{"x-dgw-app-XRSS-method":"FBGQLS:MESSENGER_CHAT_TABS_NOTIFICATION_SUBSCRIBE","x-dgw-app-XRSS-doc_id":"23885219097739619","x-dgw-app-XRSS-routing_hint":"MWChatTabsNotificationSubscription_MessengerChatTabsNotificationSubscription","x-dgw-app-xrs-body":"true","x-dgw-app-XRS-Accept-Ack":"RSAck","x-dgw-app-XRSS-http_referer":"https://www.facebook.com/friends"}',
40
+ '{"x-dgw-app-XRSS-method":"FBGQLS:BATCH_NOTIFICATION_STATE_CHANGE_SUBSCRIBE","x-dgw-app-XRSS-doc_id":"30300156509571373","x-dgw-app-XRSS-routing_hint":"CometBatchNotificationsStateChangeSubscription","x-dgw-app-xrs-body":"true","x-dgw-app-XRS-Accept-Ack":"RSAck","x-dgw-app-XRSS-http_referer":"https://www.facebook.com/friends"}',
41
+ '{"x-dgw-app-XRSS-method":"FBGQLS:NOTIFICATION_STATE_CHANGE_SUBSCRIBE","x-dgw-app-XRSS-doc_id":"23864641996495578","x-dgw-app-XRSS-routing_hint":"CometNotificationsStateChangeSubscription","x-dgw-app-xrs-body":"true","x-dgw-app-XRS-Accept-Ack":"RSAck","x-dgw-app-XRSS-http_referer":"https://www.facebook.com/friends"}',
42
+ '{"x-dgw-app-XRSS-method":"FBGQLS:NOTIFICATION_STATE_CHANGE_SUBSCRIBE","x-dgw-app-XRSS-doc_id":"9754477301332178","x-dgw-app-XRSS-routing_hint":"CometFriendNotificationsStateChangeSubscription","x-dgw-app-xrs-body":"true","x-dgw-app-XRS-Accept-Ack":"RSAck","x-dgw-app-XRSS-http_referer":"https://www.facebook.com/friends"}',
43
+ ];
44
+
45
+ async function handleMessage(data) {
46
+ try {
47
+ const text = await data.text();
48
+ const jsonStart = text.indexOf('{');
49
+ if (jsonStart !== -1) {
50
+ const jsonData = JSON.parse(text.substring(jsonStart));
51
+ if (jsonData.code === 200) {
52
+ utils.log('✅ Subscription success received.');
53
+ emitter.emit('success', jsonData);
54
+ return;
55
+ }
56
+
57
+ const formattedNotif = formatNotification(jsonData);
58
+ if (formattedNotif) {
59
+ emitter.emit('notification', formattedNotif);
60
+ } else {
61
+ emitter.emit('payload', jsonData);
62
+ }
63
+ }
64
+ } catch (err) {
65
+ utils.error('❌ Error parsing WebSocket message:', err);
66
+ emitter.emit('error', err);
67
+ }
68
+ }
69
+
70
+ async function connect() {
71
+ try {
72
+ const queryParams = new URLSearchParams({
73
+ 'x-dgw-appid': '2220391788200892',
74
+ 'x-dgw-appversion': '0',
75
+ 'x-dgw-authtype': '1:0',
76
+ 'x-dgw-version': '5',
77
+ 'x-dgw-uuid': ctx.userID,
78
+ 'x-dgw-tier': 'prod',
79
+ 'x-dgw-deviceid': ctx.clientID,
80
+ 'x-dgw-app-stream-group': 'group1',
81
+ });
82
+
83
+ const url = `wss://gateway.facebook.com/ws/realtime?${queryParams.toString()}`;
84
+ const cookies = ctx.jar
85
+ .getCookiesSync('https://www.facebook.com')
86
+ .join('; ');
87
+
88
+ const baseHeaders = {
89
+ Cookie: cookies,
90
+ Origin: 'https://www.facebook.com',
91
+ 'User-Agent': ctx.globalOptions.userAgent,
92
+ Referer: 'https://www.facebook.com',
93
+ Host: new URL(url).hostname,
94
+ 'Accept-Encoding': 'gzip, deflate, br',
95
+ 'Accept-Language': 'en-US,en;q=0.9',
96
+ };
97
+
98
+ utils.log(
99
+ `📤 Headers for WebSocket handshake:\n${Object.entries(baseHeaders)
100
+ .map(([k, v]) => `${k}: ${v}`)
101
+ .join('\n')}`,
102
+ );
103
+
104
+ const wsOptions: any = { headers: baseHeaders };
105
+ if (ctx.globalOptions.proxy) {
106
+ wsOptions.agent = new HttpsProxyAgent(ctx.globalOptions.proxy);
107
+ }
108
+
109
+ ws = new WebSocket(url, wsOptions);
110
+
111
+ ws.onopen = () => {
112
+ utils.log('✅ Connected via undici.WebSocket');
113
+ subscriptions.forEach((payload, index) => {
114
+ const prefix = Buffer.from([14, index, 0, payload.length]);
115
+ const suffix = Buffer.from([0, 0]);
116
+ const fullMessage = Buffer.concat([
117
+ prefix,
118
+ Buffer.from(payload),
119
+ suffix,
120
+ ]);
121
+ ws.send(fullMessage);
122
+ });
123
+
124
+ keepAliveInterval = setInterval(() => {
125
+ if (ws.readyState === ws.OPEN) {
126
+ ws.send('ping');
127
+ utils.log('🔁 Sent keep-alive ping.');
128
+ }
129
+ }, 10000);
130
+ };
131
+
132
+ ws.onmessage = (event) => {
133
+ if (event.data instanceof Blob) {
134
+ handleMessage(event.data);
135
+ } else {
136
+ utils.warn('Unknown message type:', typeof event.data);
137
+ }
138
+ };
139
+
140
+ ws.onerror = (err) => {
141
+ utils.error('WebSocket error:', err.message || err);
142
+ emitter.emit('error', err);
143
+ };
144
+
145
+ ws.onclose = () => {
146
+ utils.warn('🔌 WebSocket closed. Reconnecting...');
147
+ clearInterval(keepAliveInterval);
148
+ reconnectTimeout = setTimeout(connect, 1000);
149
+ };
150
+ } catch (err) {
151
+ utils.error('💥 Connection error:', err.message);
152
+ emitter.emit('error', err);
153
+ clearInterval(keepAliveInterval);
154
+ clearTimeout(reconnectTimeout);
155
+ reconnectTimeout = setTimeout(connect, 1000);
156
+ }
157
+ }
158
+
159
+ connect();
160
+
161
+ emitter.stop = () => {
162
+ clearInterval(keepAliveInterval);
163
+ clearTimeout(reconnectTimeout);
164
+ if (ws) ws.close();
165
+ };
166
+
167
+ return emitter;
168
+ };
169
+ }
@@ -0,0 +1,206 @@
1
+ import utils = require('../../../utils');
2
+ const delay = async (ms) => await new Promise((res) => setTimeout(res, ms));
3
+
4
+ export default function(defaultFuncs: any, api: any, ctx: any) {
5
+ /**
6
+ * Uploads an attachment to Facebook's servers.
7
+ * @param {Array<Stream>} attachments An array of readable streams.
8
+ * @param {Function} callback The callback function.
9
+ */
10
+ function uploadAttachment(attachments, callback) {
11
+ callback = callback || function() {};
12
+ var uploads = [];
13
+ for (var i = 0; i < attachments.length; i++) {
14
+ if (!utils.isReadableStream(attachments[i])) {
15
+ throw {
16
+ error:
17
+ 'Attachment should be a readable stream and not ' +
18
+ utils.getType(attachments[i]) +
19
+ '.',
20
+ };
21
+ }
22
+ var form = {
23
+ upload_1024: attachments[i],
24
+ voice_clip: 'true',
25
+ };
26
+ uploads.push(
27
+ defaultFuncs
28
+ .postFormData(
29
+ 'https://upload.facebook.com/ajax/mercury/upload.php',
30
+ ctx.jar,
31
+ form,
32
+ {},
33
+ )
34
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
35
+ .then((resData) => {
36
+ if (resData.error) throw resData;
37
+ return resData.payload.metadata[0];
38
+ }),
39
+ );
40
+ }
41
+ Promise.all(uploads)
42
+ .then((resData) => callback(null, resData))
43
+ .catch((err) => {
44
+ utils.error('uploadAttachment', err);
45
+ return callback(err);
46
+ });
47
+ }
48
+
49
+ function getSendPayload(threadID, msg, otid) {
50
+ const isString = typeof msg === 'string';
51
+ const body = isString ? msg : msg.body || '';
52
+ otid = otid.toString() || utils.generateOfflineThreadingID().toString();
53
+ let payload: any = {
54
+ thread_id: threadID.toString(),
55
+ otid,
56
+ source: 0,
57
+ send_type: 1,
58
+ sync_group: 1,
59
+ text: body,
60
+ initiating_source: 1,
61
+ skip_url_preview_gen: 0,
62
+ };
63
+ if (typeof msg === 'object') {
64
+ if (msg.sticker) {
65
+ payload.send_type = 2;
66
+ payload.sticker_id = msg.sticker;
67
+ payload.text = null;
68
+ }
69
+ if (msg.attachment) {
70
+ payload.send_type = 3;
71
+ payload.attachment_fbids = Array.isArray(msg.attachment)
72
+ ? msg.attachment
73
+ : [msg.attachment];
74
+ }
75
+ }
76
+ return payload;
77
+ }
78
+
79
+ /**
80
+ * Sends a message to a thread via MQTT with optional sequential editing.
81
+ * @param {object|string} msg The message to send. Can be a string or an object.
82
+ * @param {string} msg.body The main text of the message.
83
+ * @param {*} [msg.attachment] An attachment to send.
84
+ * @param {*} [msg.sticker] A sticker to send.
85
+ * @param {*} [msg.emoji] An emoji to send.
86
+ * @param {string} threadID The ID of the thread.
87
+ * @param {string} [replyToMessage] The ID of the message to reply to.
88
+ */
89
+
90
+ return async (msg, threadID, replyToMessage, callback) => {
91
+ if (typeof msg !== 'string' && typeof msg !== 'object') {
92
+ throw new Error(
93
+ 'Message should be of type string or object, not ' +
94
+ utils.getType(msg) +
95
+ '.',
96
+ );
97
+ }
98
+
99
+ if (typeof threadID !== 'string' && typeof threadID !== 'number') {
100
+ throw new Error('threadID must be a string or number.');
101
+ }
102
+
103
+ if (!callback && typeof threadID === 'function') {
104
+ throw new Error('Pass a threadID as a second argument.');
105
+ }
106
+
107
+ if (!callback && typeof replyToMessage === 'function') {
108
+ callback = replyToMessage;
109
+ replyToMessage = null;
110
+ }
111
+
112
+ let resolveFunc: Function = () => {};
113
+ let rejectFunc: Function = () => {};
114
+ let returnPromise = new Promise<any>((resolve, reject) => {
115
+ resolveFunc = resolve;
116
+ rejectFunc = reject;
117
+ });
118
+
119
+ if (!callback) {
120
+ callback = (err, data) => {
121
+ if (err) return rejectFunc(err);
122
+ resolveFunc(data);
123
+ };
124
+ }
125
+
126
+ const timestamp = Date.now();
127
+ const otid = utils.generateOfflineThreadingID();
128
+ const epoch_id = utils.generateOfflineThreadingID();
129
+ const payload = getSendPayload(threadID, msg, otid);
130
+
131
+ const tasks = [
132
+ {
133
+ label: '46',
134
+ payload,
135
+ queue_name: threadID.toString(),
136
+ task_id: 0,
137
+ failure_count: null,
138
+ },
139
+ {
140
+ label: '21',
141
+ payload: {
142
+ thread_id: threadID.toString(),
143
+ last_read_watermark_ts: timestamp,
144
+ sync_group: 1,
145
+ },
146
+ queue_name: threadID.toString(),
147
+ task_id: 1,
148
+ failure_count: null,
149
+ },
150
+ ];
151
+
152
+ if (replyToMessage) {
153
+ tasks[0].payload.reply_metadata = {
154
+ reply_source_id: replyToMessage,
155
+ reply_source_type: 1,
156
+ reply_type: 0,
157
+ };
158
+ }
159
+
160
+ const form: any = {
161
+ app_id: '2220391788200892',
162
+ payload: {
163
+ tasks,
164
+ epoch_id,
165
+ version_id: '6120284488008082',
166
+ data_trace_id: null,
167
+ },
168
+ request_id: 1,
169
+ type: 3,
170
+ };
171
+
172
+ if (msg.attachment) {
173
+ try {
174
+ const files = await new Promise<any>((resolve, reject) => {
175
+ uploadAttachment(
176
+ Array.isArray(msg.attachment) ? msg.attachment : [msg.attachment],
177
+ (err, files) => {
178
+ if (err) return reject(err);
179
+ return resolve(files);
180
+ },
181
+ );
182
+ });
183
+ form.payload.tasks[0].payload.attachment_fbids = files.map(
184
+ (file) => Object.values(file)[0],
185
+ );
186
+ } catch (err) {
187
+ utils.error('Attachment upload failed:', err);
188
+ throw new Error(err);
189
+ }
190
+ }
191
+
192
+ form.payload.tasks.forEach((task) => {
193
+ task.payload = JSON.stringify(task.payload);
194
+ });
195
+ form.payload = JSON.stringify(form.payload);
196
+ await ctx.mqttClient.publish('/ls_req', JSON.stringify(form), {
197
+ qos: 1,
198
+ retain: false,
199
+ });
200
+ callback(null, {
201
+ threadID,
202
+ type: replyToMessage ? 'message_reply' : 'message',
203
+ });
204
+ return returnPromise;
205
+ };
206
+ }
@@ -0,0 +1,61 @@
1
+ // @ChoruOfficial
2
+ 'use strict';
3
+
4
+ import utils = require("../../../utils");
5
+
6
+ function isCallable(func) {
7
+   try {
8
+     Reflect.apply(func, null, []);
9
+     return true;
10
+   } catch (error) {
11
+     return false;
12
+   }
13
+ }
14
+
15
+ export default function(defaultFuncs: any, api: any, ctx: any) {
16
+   return function setMessageReactionMqtt(reaction, messageID, threadID) {
17
+     if (!ctx.mqttClient) {
18
+       throw new Error('Not connected to MQTT');
19
+     }
20
+
21
+     ctx.wsReqNumber += 1;
22
+     ctx.wsTaskNumber += 1;
23
+
24
+     const taskPayload = {
25
+       thread_key: threadID,
26
+       timestamp_ms: Date.now(),
27
+       message_id: messageID,
28
+       reaction,
29
+       actor_id: ctx.userID,
30
+       reaction_style: null,
31
+       sync_group: 1,
32
+       send_attribution: Math.random() < 0.5 ? 65537 : 524289
33
+     };
34
+
35
+     const task = {
36
+       failure_count: null,
37
+       label: '29',
38
+       payload: JSON.stringify(taskPayload),
39
+       queue_name: JSON.stringify(['reaction', messageID]),
40
+       task_id: ctx.wsTaskNumber
41
+     };
42
+
43
+     const content = {
44
+       app_id: '2220391788200892',
45
+       payload: JSON.stringify({
46
+         data_trace_id: null,
47
+         epoch_id: parseInt(utils.generateOfflineThreadingID()), // ✅ fixed here
48
+         tasks: [task],
49
+         version_id: '7158486590867448',
50
+       }),
51
+       request_id: ctx.wsReqNumber,
52
+       type: 3,
53
+     };
54
+
55
+     /*if (isCallable(callback)) {
56
+       ctx.reqCallbacks[ctx.wsReqNumber] = callback;
57
+     }*/
58
+
59
+     ctx.mqttClient.publish('/ls_req', JSON.stringify(content), { qos: 1, retain: false });
60
+   };
61
+ };
@@ -0,0 +1,205 @@
1
+ import utils = require("../../../utils");
2
+
3
+ /**
4
+ * Handles the upload of attachments (images/videos) for a comment.
5
+ * @param {object} defaultFuncs - The default functions for making API requests.
6
+ * @param {object} ctx - The context object.
7
+ * @param {object} msg - The message object, containing attachments.
8
+ * @param {object} form - The main form object to be populated.
9
+ * @returns {Promise<void>}
10
+ */
11
+ async function handleUpload(defaultFuncs, ctx, msg, form) {
12
+ if (!msg.attachments || msg.attachments.length === 0) {
13
+ return;
14
+ }
15
+
16
+ const uploads = msg.attachments.map(item => {
17
+ if (!utils.isReadableStream(item)) {
18
+ throw new Error('Attachments must be a readable stream.');
19
+ }
20
+ return defaultFuncs
21
+ .postFormData('https://www.facebook.com/ajax/ufi/upload/', ctx.jar, {
22
+ profile_id: ctx.userID,
23
+ source: 19,
24
+ target_id: ctx.userID,
25
+ file: item
26
+ })
27
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs))
28
+ .then(res => {
29
+ if (res.error || !res.payload?.fbid) {
30
+ throw res;
31
+ }
32
+ return { media: { id: res.payload.fbid } };
33
+ });
34
+ });
35
+
36
+ const results = await Promise.all(uploads);
37
+ form.input.attachments.push(...results);
38
+ }
39
+
40
+ /**
41
+ * Handles a URL attachment for a comment.
42
+ * @param {object} msg - The message object.
43
+ * @param {object} form - The main form object.
44
+ */
45
+ function handleURL(msg, form) {
46
+ if (typeof msg.url === 'string') {
47
+ form.input.attachments.push({
48
+ link: {
49
+ external: {
50
+ url: msg.url
51
+ }
52
+ }
53
+ });
54
+ }
55
+ }
56
+
57
+ /**
58
+ * Handles mentions in the comment body.
59
+ * @param {object} msg - The message object.
60
+ * @param {object} form - The main form object.
61
+ */
62
+ function handleMentions(msg, form) {
63
+ if (!msg.mentions) return;
64
+
65
+ for (const item of msg.mentions) {
66
+ const { tag, id, fromIndex } = item;
67
+ if (typeof tag !== 'string' || !id) {
68
+ utils.warn('createCommentPost', 'Mentions must have a string "tag" and an "id".');
69
+ continue;
70
+ }
71
+ const offset = msg.body.indexOf(tag, fromIndex || 0);
72
+ if (offset < 0) {
73
+ utils.warn('createCommentPost', `Mention for "${tag}" not found in message string.`);
74
+ continue;
75
+ }
76
+ form.input.message.ranges.push({
77
+ entity: { id },
78
+ length: tag.length,
79
+ offset
80
+ });
81
+ }
82
+ }
83
+
84
+ /**
85
+ * Handles a sticker attachment for a comment.
86
+ * @param {object} msg - The message object.
87
+ * @param {object} form - The main form object.
88
+ */
89
+ function handleSticker(msg, form) {
90
+ if (msg.sticker) {
91
+ form.input.attachments.push({
92
+ media: {
93
+ id: String(msg.sticker)
94
+ }
95
+ });
96
+ }
97
+ }
98
+
99
+ /**
100
+ * Submits the final comment form to the GraphQL endpoint.
101
+ * @param {object} defaultFuncs - The default functions.
102
+ * @param {object} ctx - The context object.
103
+ * @param {object} form - The fully constructed form object.
104
+ * @returns {Promise<object>} A promise that resolves with the comment info.
105
+ */
106
+ async function createContent(defaultFuncs, ctx, form) {
107
+ const res = await defaultFuncs
108
+ .post('https://www.facebook.com/api/graphql/', ctx.jar, {
109
+ fb_api_caller_class: 'RelayModern',
110
+ fb_api_req_friendly_name: 'useCometUFICreateCommentMutation',
111
+ variables: JSON.stringify(form),
112
+ server_timestamps: true,
113
+ doc_id: 6993516810709754
114
+ })
115
+ .then(utils.parseAndCheckLogin(ctx, defaultFuncs));
116
+
117
+ if (res.errors) {
118
+ throw res;
119
+ }
120
+
121
+ const commentEdge = res.data.comment_create.feedback_comment_edge;
122
+ return {
123
+ id: commentEdge.node.id,
124
+ url: commentEdge.node.feedback.url,
125
+ count: res.data.comment_create.feedback.total_comment_count
126
+ };
127
+ }
128
+
129
+ /**
130
+ * Creates a comment on a Facebook post. Can also reply to an existing comment.
131
+ * @param {string|object} msg - The message to post. Can be a string or an object with `body`, `attachments`, `mentions`, etc.
132
+ * @param {string} postID - The ID of the post to comment on.
133
+ * @param {string} [replyCommentID] - (Optional) The ID of the comment to reply to.
134
+ * @param {function} [callback] - (Optional) A callback function.
135
+ * @returns {Promise<object>} A promise that resolves with the new comment's information.
136
+ */
137
+ export default function(defaultFuncs: any, api: any, ctx: any) {
138
+ return async function createCommentPost(msg, postID, replyCommentID, callback) {
139
+ let cb;
140
+ const returnPromise = new Promise<any>((resolve, reject) => {
141
+ cb = (error, info) => info ? resolve(info) : reject(error);
142
+ });
143
+
144
+ if (typeof replyCommentID === 'function') {
145
+ callback = replyCommentID;
146
+ replyCommentID = null;
147
+ }
148
+ if (typeof callback === 'function') {
149
+ cb = callback;
150
+ }
151
+
152
+ if (typeof msg !== 'string' && typeof msg !== 'object') {
153
+ const error = 'Message must be a string or an object.';
154
+ utils.error('createCommentPost', error);
155
+ return cb(error);
156
+ }
157
+ if (typeof postID !== 'string') {
158
+ const error = 'postID must be a string.';
159
+ utils.error('createCommentPost', error);
160
+ return cb(error);
161
+ }
162
+
163
+ let messageObject = typeof msg === 'string' ? { body: msg } : { ...msg };
164
+ messageObject.mentions = messageObject.mentions || [];
165
+ messageObject.attachments = messageObject.attachments || [];
166
+
167
+ const form = {
168
+ feedLocation: 'NEWSFEED',
169
+ feedbackSource: 1,
170
+ groupID: null,
171
+ input: {
172
+ client_mutation_id: Math.round(Math.random() * 19).toString(),
173
+ actor_id: ctx.userID,
174
+ attachments: [],
175
+ feedback_id: Buffer.from('feedback:' + postID).toString('base64'),
176
+ message: {
177
+ ranges: [],
178
+ text: messageObject.body || ''
179
+ },
180
+ reply_comment_parent_fbid: replyCommentID || null,
181
+ is_tracking_encrypted: true,
182
+ tracking: [],
183
+ feedback_source: 'NEWS_FEED',
184
+ idempotence_token: 'client:' + utils.getGUID(),
185
+ session_id: utils.getGUID()
186
+ },
187
+ scale: 1,
188
+ useDefaultActor: false
189
+ };
190
+
191
+ try {
192
+ await handleUpload(defaultFuncs, ctx, messageObject, form);
193
+ handleURL(messageObject, form);
194
+ handleMentions(messageObject, form);
195
+ handleSticker(messageObject, form);
196
+ const info = await createContent(defaultFuncs, ctx, form);
197
+ cb(null, info);
198
+ } catch (err) {
199
+ utils.error('createCommentPost', err);
200
+ cb(err);
201
+ }
202
+
203
+ return returnPromise;
204
+ };
205
+ };