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.
- package/LICENSE-MIT +21 -0
- package/README.md +0 -0
- package/dist/core/client.js +50 -0
- package/dist/core/client.js.map +1 -0
- package/dist/core/models/buildAPI.js +103 -0
- package/dist/core/models/buildAPI.js.map +1 -0
- package/dist/core/models/loginHelper.js +209 -0
- package/dist/core/models/loginHelper.js.map +1 -0
- package/dist/core/models/setOptions.js +47 -0
- package/dist/core/models/setOptions.js.map +1 -0
- package/dist/deltas/apis/create.js +30 -0
- package/dist/deltas/apis/create.js.map +1 -0
- package/dist/deltas/apis/extra/addExternalModule.js +23 -0
- package/dist/deltas/apis/extra/addExternalModule.js.map +1 -0
- package/dist/deltas/apis/extra/getAccess.js +110 -0
- package/dist/deltas/apis/extra/getAccess.js.map +1 -0
- package/dist/deltas/apis/http/httpGet.js +57 -0
- package/dist/deltas/apis/http/httpGet.js.map +1 -0
- package/dist/deltas/apis/http/httpPost.js +57 -0
- package/dist/deltas/apis/http/httpPost.js.map +1 -0
- package/dist/deltas/apis/http/httpPostFormData.js +61 -0
- package/dist/deltas/apis/http/httpPostFormData.js.map +1 -0
- package/dist/deltas/apis/login/GetBotInfo.js +83 -0
- package/dist/deltas/apis/login/GetBotInfo.js.map +1 -0
- package/dist/deltas/apis/login/getBotInitialData.js +46 -0
- package/dist/deltas/apis/login/getBotInitialData.js.map +1 -0
- package/dist/deltas/apis/login/logout.js +54 -0
- package/dist/deltas/apis/login/logout.js.map +1 -0
- package/dist/deltas/apis/messaging/editMessage.js +64 -0
- package/dist/deltas/apis/messaging/editMessage.js.map +1 -0
- package/dist/deltas/apis/messaging/emoji.js +120 -0
- package/dist/deltas/apis/messaging/emoji.js.map +1 -0
- package/dist/deltas/apis/messaging/gcmember.js +164 -0
- package/dist/deltas/apis/messaging/gcmember.js.map +1 -0
- package/dist/deltas/apis/messaging/gcname.js +119 -0
- package/dist/deltas/apis/messaging/gcname.js.map +1 -0
- package/dist/deltas/apis/messaging/gcrule.js +144 -0
- package/dist/deltas/apis/messaging/gcrule.js.map +1 -0
- package/dist/deltas/apis/messaging/markAsDelivered.js +44 -0
- package/dist/deltas/apis/messaging/markAsDelivered.js.map +1 -0
- package/dist/deltas/apis/messaging/markAsRead.js +84 -0
- package/dist/deltas/apis/messaging/markAsRead.js.map +1 -0
- package/dist/deltas/apis/messaging/markAsReadAll.js +34 -0
- package/dist/deltas/apis/messaging/markAsReadAll.js.map +1 -0
- package/dist/deltas/apis/messaging/markAsSeen.js +64 -0
- package/dist/deltas/apis/messaging/markAsSeen.js.map +1 -0
- package/dist/deltas/apis/messaging/nickname.js +129 -0
- package/dist/deltas/apis/messaging/nickname.js.map +1 -0
- package/dist/deltas/apis/messaging/notes.js +156 -0
- package/dist/deltas/apis/messaging/notes.js.map +1 -0
- package/dist/deltas/apis/messaging/resolvePhotoUrl.js +55 -0
- package/dist/deltas/apis/messaging/resolvePhotoUrl.js.map +1 -0
- package/dist/deltas/apis/messaging/sendMessage.js +239 -0
- package/dist/deltas/apis/messaging/sendMessage.js.map +1 -0
- package/dist/deltas/apis/messaging/sendTypingIndicator.js +41 -0
- package/dist/deltas/apis/messaging/sendTypingIndicator.js.map +1 -0
- package/dist/deltas/apis/messaging/setMessageReaction.js +30 -0
- package/dist/deltas/apis/messaging/setMessageReaction.js.map +1 -0
- package/dist/deltas/apis/messaging/shareContact.js +59 -0
- package/dist/deltas/apis/messaging/shareContact.js.map +1 -0
- package/dist/deltas/apis/messaging/stickers.js +246 -0
- package/dist/deltas/apis/messaging/stickers.js.map +1 -0
- package/dist/deltas/apis/messaging/theme.js +227 -0
- package/dist/deltas/apis/messaging/theme.js.map +1 -0
- package/dist/deltas/apis/messaging/unsendMessage.js +19 -0
- package/dist/deltas/apis/messaging/unsendMessage.js.map +1 -0
- package/dist/deltas/apis/mqtt/deltas/value.js +193 -0
- package/dist/deltas/apis/mqtt/deltas/value.js.map +1 -0
- package/dist/deltas/apis/mqtt/listenMqtt.js +306 -0
- package/dist/deltas/apis/mqtt/listenMqtt.js.map +1 -0
- package/dist/deltas/apis/mqtt/listenSpeed.js +166 -0
- package/dist/deltas/apis/mqtt/listenSpeed.js.map +1 -0
- package/dist/deltas/apis/mqtt/pinMessage.js +166 -0
- package/dist/deltas/apis/mqtt/pinMessage.js.map +1 -0
- package/dist/deltas/apis/mqtt/realtime.js +160 -0
- package/dist/deltas/apis/mqtt/realtime.js.map +1 -0
- package/dist/deltas/apis/mqtt/sendMessageMqtt.js +184 -0
- package/dist/deltas/apis/mqtt/sendMessageMqtt.js.map +1 -0
- package/dist/deltas/apis/mqtt/setMessageReactionMqtt.js +57 -0
- package/dist/deltas/apis/mqtt/setMessageReactionMqtt.js.map +1 -0
- package/dist/deltas/apis/posting/comment.js +195 -0
- package/dist/deltas/apis/posting/comment.js.map +1 -0
- package/dist/deltas/apis/posting/follow.js +82 -0
- package/dist/deltas/apis/posting/follow.js.map +1 -0
- package/dist/deltas/apis/posting/friend.js +253 -0
- package/dist/deltas/apis/posting/friend.js.map +1 -0
- package/dist/deltas/apis/posting/post.js +551 -0
- package/dist/deltas/apis/posting/post.js.map +1 -0
- package/dist/deltas/apis/posting/share.js +59 -0
- package/dist/deltas/apis/posting/share.js.map +1 -0
- package/dist/deltas/apis/posting/story.js +176 -0
- package/dist/deltas/apis/posting/story.js.map +1 -0
- package/dist/deltas/apis/threads/getThreadHistory.js +233 -0
- package/dist/deltas/apis/threads/getThreadHistory.js.map +1 -0
- package/dist/deltas/apis/threads/getThreadInfo.js +197 -0
- package/dist/deltas/apis/threads/getThreadInfo.js.map +1 -0
- package/dist/deltas/apis/threads/getThreadList.js +201 -0
- package/dist/deltas/apis/threads/getThreadList.js.map +1 -0
- package/dist/deltas/apis/users/getUserInfo.js +254 -0
- package/dist/deltas/apis/users/getUserInfo.js.map +1 -0
- package/dist/index.d.ts +696 -0
- package/dist/types/core/client.d.ts +2 -0
- package/dist/types/core/models/buildAPI.d.ts +13 -0
- package/dist/types/core/models/loginHelper.d.ts +15 -0
- package/dist/types/core/models/setOptions.d.ts +2 -0
- package/dist/types/deltas/apis/create.d.ts +23 -0
- package/dist/types/deltas/apis/extra/addExternalModule.d.ts +1 -0
- package/dist/types/deltas/apis/extra/getAccess.d.ts +1 -0
- package/dist/types/deltas/apis/http/httpGet.d.ts +1 -0
- package/dist/types/deltas/apis/http/httpPost.d.ts +1 -0
- package/dist/types/deltas/apis/http/httpPostFormData.d.ts +1 -0
- package/dist/types/deltas/apis/login/GetBotInfo.d.ts +32 -0
- package/dist/types/deltas/apis/login/getBotInitialData.d.ts +1 -0
- package/dist/types/deltas/apis/login/logout.d.ts +7 -0
- package/dist/types/deltas/apis/messaging/editMessage.d.ts +7 -0
- package/dist/types/deltas/apis/messaging/emoji.d.ts +1 -0
- package/dist/types/deltas/apis/messaging/gcmember.d.ts +1 -0
- package/dist/types/deltas/apis/messaging/gcname.d.ts +1 -0
- package/dist/types/deltas/apis/messaging/gcrule.d.ts +1 -0
- package/dist/types/deltas/apis/messaging/markAsDelivered.d.ts +7 -0
- package/dist/types/deltas/apis/messaging/markAsRead.d.ts +6 -0
- package/dist/types/deltas/apis/messaging/markAsReadAll.d.ts +7 -0
- package/dist/types/deltas/apis/messaging/markAsSeen.d.ts +6 -0
- package/dist/types/deltas/apis/messaging/nickname.d.ts +1 -0
- package/dist/types/deltas/apis/messaging/notes.d.ts +14 -0
- package/dist/types/deltas/apis/messaging/resolvePhotoUrl.d.ts +9 -0
- package/dist/types/deltas/apis/messaging/sendMessage.d.ts +1 -0
- package/dist/types/deltas/apis/messaging/sendTypingIndicator.d.ts +6 -0
- package/dist/types/deltas/apis/messaging/setMessageReaction.d.ts +1 -0
- package/dist/types/deltas/apis/messaging/shareContact.d.ts +8 -0
- package/dist/types/deltas/apis/messaging/stickers.d.ts +48 -0
- package/dist/types/deltas/apis/messaging/theme.d.ts +1 -0
- package/dist/types/deltas/apis/messaging/unsendMessage.d.ts +1 -0
- package/dist/types/deltas/apis/mqtt/deltas/value.d.ts +2 -0
- package/dist/types/deltas/apis/mqtt/listenMqtt.d.ts +20 -0
- package/dist/types/deltas/apis/mqtt/listenSpeed.d.ts +21 -0
- package/dist/types/deltas/apis/mqtt/pinMessage.d.ts +1 -0
- package/dist/types/deltas/apis/mqtt/realtime.d.ts +1 -0
- package/dist/types/deltas/apis/mqtt/sendMessageMqtt.d.ts +1 -0
- package/dist/types/deltas/apis/mqtt/setMessageReactionMqtt.d.ts +1 -0
- package/dist/types/deltas/apis/posting/comment.d.ts +9 -0
- package/dist/types/deltas/apis/posting/follow.d.ts +14 -0
- package/dist/types/deltas/apis/posting/friend.d.ts +61 -0
- package/dist/types/deltas/apis/posting/post.d.ts +20 -0
- package/dist/types/deltas/apis/posting/share.d.ts +1 -0
- package/dist/types/deltas/apis/posting/story.d.ts +39 -0
- package/dist/types/deltas/apis/threads/getThreadHistory.d.ts +7 -0
- package/dist/types/deltas/apis/threads/getThreadInfo.d.ts +7 -0
- package/dist/types/deltas/apis/threads/getThreadList.d.ts +7 -0
- package/dist/types/deltas/apis/users/getUserInfo.d.ts +1 -0
- package/dist/types/utils/axios.d.ts +7 -0
- package/dist/types/utils/clients.d.ts +4 -0
- package/dist/types/utils/constants.d.ts +24 -0
- package/dist/types/utils/formatters/data/formatAttachment.d.ts +2 -0
- package/dist/types/utils/formatters/data/formatDelta.d.ts +4 -0
- package/dist/types/utils/formatters/index.d.ts +17 -0
- package/dist/types/utils/formatters/value/formatCookie.d.ts +8 -0
- package/dist/types/utils/formatters/value/formatDate.d.ts +6 -0
- package/dist/types/utils/formatters/value/formatID.d.ts +7 -0
- package/dist/types/utils/headers.d.ts +2 -0
- package/dist/types/utils/index.d.ts +75 -0
- package/dist/types/utils/user-agents.d.ts +9 -0
- package/dist/utils/axios.js +148 -0
- package/dist/utils/axios.js.map +1 -0
- package/dist/utils/clients.js +120 -0
- package/dist/utils/clients.js.map +1 -0
- package/dist/utils/constants.js +249 -0
- package/dist/utils/constants.js.map +1 -0
- package/dist/utils/formatters/data/formatAttachment.js +61 -0
- package/dist/utils/formatters/data/formatAttachment.js.map +1 -0
- package/dist/utils/formatters/data/formatDelta.js +67 -0
- package/dist/utils/formatters/data/formatDelta.js.map +1 -0
- package/dist/utils/formatters/index.js +132 -0
- package/dist/utils/formatters/index.js.map +1 -0
- package/dist/utils/formatters/value/formatCookie.js +13 -0
- package/dist/utils/formatters/value/formatCookie.js.map +1 -0
- package/dist/utils/formatters/value/formatDate.js +33 -0
- package/dist/utils/formatters/value/formatDate.js.map +1 -0
- package/dist/utils/formatters/value/formatID.js +17 -0
- package/dist/utils/formatters/value/formatID.js.map +1 -0
- package/dist/utils/headers.js +61 -0
- package/dist/utils/headers.js.map +1 -0
- package/dist/utils/index.js +105 -0
- package/dist/utils/index.js.map +1 -0
- package/dist/utils/user-agents.js +41 -0
- package/dist/utils/user-agents.js.map +1 -0
- package/examples/post.example.js +149 -0
- package/module/index.js +5 -0
- package/package.json +56 -0
- package/src/core/client.ts +66 -0
- package/src/core/models/buildAPI.ts +131 -0
- package/src/core/models/loginHelper.ts +226 -0
- package/src/core/models/setOptions.ts +48 -0
- package/src/deltas/apis/create.ts +28 -0
- package/src/deltas/apis/extra/addExternalModule.ts +23 -0
- package/src/deltas/apis/extra/getAccess.ts +141 -0
- package/src/deltas/apis/http/httpGet.ts +61 -0
- package/src/deltas/apis/http/httpPost.ts +61 -0
- package/src/deltas/apis/http/httpPostFormData.ts +67 -0
- package/src/deltas/apis/login/GetBotInfo.ts +88 -0
- package/src/deltas/apis/login/getBotInitialData.ts +42 -0
- package/src/deltas/apis/login/logout.ts +62 -0
- package/src/deltas/apis/messaging/editMessage.ts +69 -0
- package/src/deltas/apis/messaging/emoji.ts +135 -0
- package/src/deltas/apis/messaging/gcmember.ts +175 -0
- package/src/deltas/apis/messaging/gcname.ts +136 -0
- package/src/deltas/apis/messaging/gcrule.ts +152 -0
- package/src/deltas/apis/messaging/markAsDelivered.ts +47 -0
- package/src/deltas/apis/messaging/markAsRead.ts +94 -0
- package/src/deltas/apis/messaging/markAsReadAll.ts +38 -0
- package/src/deltas/apis/messaging/markAsSeen.ts +69 -0
- package/src/deltas/apis/messaging/nickname.ts +153 -0
- package/src/deltas/apis/messaging/notes.ts +165 -0
- package/src/deltas/apis/messaging/resolvePhotoUrl.ts +56 -0
- package/src/deltas/apis/messaging/sendMessage.ts +286 -0
- package/src/deltas/apis/messaging/sendTypingIndicator.ts +48 -0
- package/src/deltas/apis/messaging/setMessageReaction.ts +25 -0
- package/src/deltas/apis/messaging/shareContact.ts +63 -0
- package/src/deltas/apis/messaging/stickers.ts +255 -0
- package/src/deltas/apis/messaging/theme.ts +280 -0
- package/src/deltas/apis/messaging/unsendMessage.ts +15 -0
- package/src/deltas/apis/mqtt/deltas/value.ts +224 -0
- package/src/deltas/apis/mqtt/listenMqtt.ts +332 -0
- package/src/deltas/apis/mqtt/listenSpeed.ts +179 -0
- package/src/deltas/apis/mqtt/pinMessage.ts +135 -0
- package/src/deltas/apis/mqtt/realtime.ts +169 -0
- package/src/deltas/apis/mqtt/sendMessageMqtt.ts +206 -0
- package/src/deltas/apis/mqtt/setMessageReactionMqtt.ts +61 -0
- package/src/deltas/apis/posting/comment.ts +205 -0
- package/src/deltas/apis/posting/follow.ts +79 -0
- package/src/deltas/apis/posting/friend.ts +241 -0
- package/src/deltas/apis/posting/post.ts +599 -0
- package/src/deltas/apis/posting/share.ts +60 -0
- package/src/deltas/apis/posting/story.ts +207 -0
- package/src/deltas/apis/threads/getThreadHistory.ts +237 -0
- package/src/deltas/apis/threads/getThreadInfo.ts +210 -0
- package/src/deltas/apis/threads/getThreadList.ts +224 -0
- package/src/deltas/apis/users/getUserInfo.ts +244 -0
- package/src/types/index.d.ts +696 -0
- package/src/utils/axios.ts +178 -0
- package/src/utils/clients.ts +125 -0
- package/src/utils/constants.ts +281 -0
- package/src/utils/formatters/data/formatAttachment.ts +58 -0
- package/src/utils/formatters/data/formatDelta.ts +45 -0
- package/src/utils/formatters/index.ts +82 -0
- package/src/utils/formatters/value/formatCookie.ts +13 -0
- package/src/utils/formatters/value/formatDate.ts +34 -0
- package/src/utils/formatters/value/formatID.ts +14 -0
- package/src/utils/formatters.old.ts +1049 -0
- package/src/utils/headers.ts +65 -0
- package/src/utils/index.ts +65 -0
- package/src/utils/user-agents.ts +49 -0
- 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
|
+
};
|