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,178 @@
|
|
|
1
|
+
import axios from 'axios';
|
|
2
|
+
import { wrapper } from 'axios-cookiejar-support';
|
|
3
|
+
import FormData from 'form-data';
|
|
4
|
+
import { CookieJar } from 'tough-cookie';
|
|
5
|
+
import { getType } from './constants';
|
|
6
|
+
import { getHeaders } from './headers';
|
|
7
|
+
|
|
8
|
+
const jar = new CookieJar();
|
|
9
|
+
const client = wrapper(axios.create({ jar } as any));
|
|
10
|
+
|
|
11
|
+
let proxyConfig: any = {};
|
|
12
|
+
|
|
13
|
+
const delay = (ms: number): Promise<void> =>
|
|
14
|
+
new Promise((resolve) => setTimeout(resolve, ms));
|
|
15
|
+
|
|
16
|
+
function adaptResponse(res: any): any {
|
|
17
|
+
const response = res.response || res;
|
|
18
|
+
return {
|
|
19
|
+
...response,
|
|
20
|
+
body: response.data,
|
|
21
|
+
statusCode: response.status,
|
|
22
|
+
request: {
|
|
23
|
+
uri: new URL(response.config.url),
|
|
24
|
+
headers: response.config.headers,
|
|
25
|
+
method: response.config.method.toUpperCase(),
|
|
26
|
+
form: response.config.data,
|
|
27
|
+
formData: response.config.data,
|
|
28
|
+
},
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
async function requestWithRetry(
|
|
33
|
+
requestFunction: () => Promise<any>,
|
|
34
|
+
retries: number = 3,
|
|
35
|
+
): Promise<any> {
|
|
36
|
+
for (let i = 0; i < retries; i++) {
|
|
37
|
+
try {
|
|
38
|
+
const res = await requestFunction();
|
|
39
|
+
return adaptResponse(res);
|
|
40
|
+
} catch (error) {
|
|
41
|
+
if (i === retries - 1) {
|
|
42
|
+
console.error(
|
|
43
|
+
`Request failed after ${retries} attempts:`,
|
|
44
|
+
error.message,
|
|
45
|
+
);
|
|
46
|
+
if (error.response) {
|
|
47
|
+
return adaptResponse(error.response);
|
|
48
|
+
}
|
|
49
|
+
throw error;
|
|
50
|
+
}
|
|
51
|
+
const backoffTime = Math.pow(2, i) * 1000;
|
|
52
|
+
console.warn(
|
|
53
|
+
`Request attempt ${i + 1} failed. Retrying in ${backoffTime}ms...`,
|
|
54
|
+
);
|
|
55
|
+
await delay(backoffTime);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
export function setProxy(proxyUrl?: string): void {
|
|
61
|
+
if (proxyUrl) {
|
|
62
|
+
try {
|
|
63
|
+
const parsedProxy = new URL(proxyUrl);
|
|
64
|
+
proxyConfig = {
|
|
65
|
+
proxy: {
|
|
66
|
+
host: parsedProxy.hostname,
|
|
67
|
+
port: parsedProxy.port,
|
|
68
|
+
protocol: parsedProxy.protocol.replace(':', ''),
|
|
69
|
+
auth:
|
|
70
|
+
parsedProxy.username && parsedProxy.password
|
|
71
|
+
? {
|
|
72
|
+
username: parsedProxy.username,
|
|
73
|
+
password: parsedProxy.password,
|
|
74
|
+
}
|
|
75
|
+
: undefined,
|
|
76
|
+
},
|
|
77
|
+
};
|
|
78
|
+
} catch (e) {
|
|
79
|
+
console.error('Invalid proxy URL.');
|
|
80
|
+
proxyConfig = {};
|
|
81
|
+
}
|
|
82
|
+
} else {
|
|
83
|
+
proxyConfig = {};
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
export function cleanGet(url: string): Promise<any> {
|
|
88
|
+
const fn = () => client.get(url, { timeout: 60000, ...proxyConfig });
|
|
89
|
+
return requestWithRetry(fn as any);
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export async function get(
|
|
93
|
+
url: string,
|
|
94
|
+
reqJar: any,
|
|
95
|
+
qs?: any,
|
|
96
|
+
options?: any,
|
|
97
|
+
ctx?: any,
|
|
98
|
+
customHeader?: any,
|
|
99
|
+
): Promise<any> {
|
|
100
|
+
const config: any = {
|
|
101
|
+
headers: getHeaders(url, options, ctx, customHeader),
|
|
102
|
+
timeout: 60000,
|
|
103
|
+
params: qs,
|
|
104
|
+
...proxyConfig,
|
|
105
|
+
validateStatus: (status: number) => status >= 200 && status < 600,
|
|
106
|
+
};
|
|
107
|
+
return requestWithRetry(async () => await client.get(url, config));
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
export async function post(
|
|
111
|
+
url: string,
|
|
112
|
+
reqJar: any,
|
|
113
|
+
form?: any,
|
|
114
|
+
options?: any,
|
|
115
|
+
ctx?: any,
|
|
116
|
+
customHeader?: any,
|
|
117
|
+
): Promise<any> {
|
|
118
|
+
const headers = getHeaders(url, options, ctx, customHeader);
|
|
119
|
+
let data: any = form;
|
|
120
|
+
let contentType =
|
|
121
|
+
headers['Content-Type'] || 'application/x-www-form-urlencoded';
|
|
122
|
+
|
|
123
|
+
if (contentType.includes('json')) {
|
|
124
|
+
data = JSON.stringify(form);
|
|
125
|
+
} else {
|
|
126
|
+
const transformedForm = new URLSearchParams();
|
|
127
|
+
for (const key in form) {
|
|
128
|
+
if (form.hasOwnProperty(key)) {
|
|
129
|
+
let value = form[key];
|
|
130
|
+
if (getType(value) === 'Object') {
|
|
131
|
+
value = JSON.stringify(value);
|
|
132
|
+
}
|
|
133
|
+
transformedForm.append(key, value);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
data = transformedForm.toString();
|
|
137
|
+
}
|
|
138
|
+
headers['Content-Type'] = contentType;
|
|
139
|
+
|
|
140
|
+
const config: any = {
|
|
141
|
+
headers,
|
|
142
|
+
timeout: 60000,
|
|
143
|
+
...proxyConfig,
|
|
144
|
+
validateStatus: (status: number) => status >= 200 && status < 600,
|
|
145
|
+
};
|
|
146
|
+
return requestWithRetry(async () => await client.post(url, data, config));
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export async function postFormData(
|
|
150
|
+
url: string,
|
|
151
|
+
reqJar: any,
|
|
152
|
+
form: any,
|
|
153
|
+
qs?: any,
|
|
154
|
+
options?: any,
|
|
155
|
+
ctx?: any,
|
|
156
|
+
): Promise<any> {
|
|
157
|
+
const formData = new FormData();
|
|
158
|
+
for (const key in form) {
|
|
159
|
+
if (form.hasOwnProperty(key)) {
|
|
160
|
+
formData.append(key, form[key]);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const customHeader = {
|
|
165
|
+
'Content-Type': `multipart/form-data; boundary=${formData.getBoundary()}`,
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
const config: any = {
|
|
169
|
+
headers: getHeaders(url, options, ctx, customHeader),
|
|
170
|
+
timeout: 60000,
|
|
171
|
+
params: qs,
|
|
172
|
+
...proxyConfig,
|
|
173
|
+
validateStatus: (status: number) => status >= 200 && status < 600,
|
|
174
|
+
};
|
|
175
|
+
return requestWithRetry(async () => await client.post(url, formData, config));
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
export const getJar = (): CookieJar => jar;
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { makeParsable, log, warn } from "./constants";
|
|
2
|
+
|
|
3
|
+
function formatCookie(arr: any[], url: string): string {
|
|
4
|
+
return arr[0] + "=" + arr[1] + "; Path=" + arr[3] + "; Domain=" + url + ".com";
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
export function parseAndCheckLogin(ctx: any, http: any, retryCount: number = 0): (data: any) => Promise<any> {
|
|
8
|
+
const delay = (ms: number): Promise<void> => new Promise<any>((resolve) => setTimeout(resolve, ms));
|
|
9
|
+
|
|
10
|
+
return async (data: any): Promise<any> => {
|
|
11
|
+
if (data.statusCode >= 500 && data.statusCode < 600) {
|
|
12
|
+
if (retryCount >= 5) {
|
|
13
|
+
const err: any = new Error("Request retry failed.");
|
|
14
|
+
err.statusCode = data.statusCode;
|
|
15
|
+
err.res = data.body;
|
|
16
|
+
throw err;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
retryCount++;
|
|
20
|
+
const retryTime = Math.floor(Math.random() * 5000);
|
|
21
|
+
const url = data.request.uri.protocol + "//" + data.request.uri.hostname + data.request.uri.pathname;
|
|
22
|
+
|
|
23
|
+
await delay(retryTime);
|
|
24
|
+
|
|
25
|
+
if (data.request.headers["content-type"].split(";")[0] === "multipart/form-data") {
|
|
26
|
+
const newData = await http.postFormData(url, ctx.jar, data.request.formData, data.request.qs, ctx.globalOptions, ctx);
|
|
27
|
+
return await parseAndCheckLogin(ctx, http, retryCount)(newData);
|
|
28
|
+
} else {
|
|
29
|
+
const newData = await http.post(url, ctx.jar, data.request.form, ctx.globalOptions, ctx);
|
|
30
|
+
return await parseAndCheckLogin(ctx, http, retryCount)(newData);
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (data.statusCode === 404) return;
|
|
35
|
+
|
|
36
|
+
if (data.statusCode !== 200) {
|
|
37
|
+
throw new Error("parseAndCheckLogin got status code: " + data.statusCode);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
let res: any = null;
|
|
41
|
+
|
|
42
|
+
if (typeof data.body === "object" && data.body !== null) {
|
|
43
|
+
res = data.body;
|
|
44
|
+
} else if (typeof data.body === "string") {
|
|
45
|
+
try {
|
|
46
|
+
res = JSON.parse(makeParsable(data.body) as string);
|
|
47
|
+
} catch (e) {
|
|
48
|
+
const err: any = new Error("JSON.parse error.");
|
|
49
|
+
err.detail = e;
|
|
50
|
+
err.res = data.body;
|
|
51
|
+
throw err;
|
|
52
|
+
}
|
|
53
|
+
} else {
|
|
54
|
+
throw new Error("Unknown response body type: " + typeof data.body);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (res.redirect && data.request.method === "GET") {
|
|
58
|
+
const redirectRes = await http.get(res.redirect, ctx.jar);
|
|
59
|
+
return await parseAndCheckLogin(ctx, http)(redirectRes);
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
if (res.jsmods && res.jsmods.require && Array.isArray(res.jsmods.require[0]) && res.jsmods.require[0][0] === "Cookie") {
|
|
63
|
+
res.jsmods.require[0][3][0] = res.jsmods.require[0][3][0].replace("_js_", "");
|
|
64
|
+
const requireCookie = res.jsmods.require[0][3];
|
|
65
|
+
ctx.jar.setCookie(formatCookie(requireCookie, "facebook"), "https://www.facebook.com");
|
|
66
|
+
ctx.jar.setCookie(formatCookie(requireCookie, "messenger"), "https://www.messenger.com");
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (res.jsmods && Array.isArray(res.jsmods.require)) {
|
|
70
|
+
const arr = res.jsmods.require;
|
|
71
|
+
for (const i in arr) {
|
|
72
|
+
if (arr[i][0] === "DTSG" && arr[i][1] === "setToken") {
|
|
73
|
+
ctx.fb_dtsg = arr[i][3][0];
|
|
74
|
+
ctx.ttstamp = "2";
|
|
75
|
+
for (let j = 0; j < ctx.fb_dtsg.length; j++) {
|
|
76
|
+
ctx.ttstamp += ctx.fb_dtsg.charCodeAt(j);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
if (res.error === 1357001) {
|
|
83
|
+
const err: any = new Error("Facebook blocked the login");
|
|
84
|
+
err.error = "Not logged in.";
|
|
85
|
+
throw err;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return res;
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
export function saveCookies(jar: any): (res: any) => any {
|
|
93
|
+
return function (res: any): any {
|
|
94
|
+
const cookies = res.headers["set-cookie"] || [];
|
|
95
|
+
cookies.forEach(function (c: string) {
|
|
96
|
+
if (c.indexOf(".facebook.com") > -1) {
|
|
97
|
+
jar.setCookie(c, "https://www.facebook.com");
|
|
98
|
+
}
|
|
99
|
+
const c2 = c.replace(/domain=\.facebook\.com/, "domain=.messenger.com");
|
|
100
|
+
jar.setCookie(c2, "https://www.messenger.com");
|
|
101
|
+
});
|
|
102
|
+
return res;
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export function getAccessFromBusiness(jar: any, Options: any): (res: any) => Promise<[string | null, string | null]> {
|
|
107
|
+
return async function (res: any): Promise<[string | null, string | null]> {
|
|
108
|
+
const html = res ? res.body : null;
|
|
109
|
+
const { get } = require("./axios");
|
|
110
|
+
try {
|
|
111
|
+
const businessRes = await get("https://business.facebook.com/content_management", jar, null, Options, null, { noRef: true });
|
|
112
|
+
const match = /"accessToken":"([^.]+)","clientID":/g.exec(businessRes.body);
|
|
113
|
+
const token = match ? match[1] : null;
|
|
114
|
+
return [html, token];
|
|
115
|
+
} catch (e) {
|
|
116
|
+
return [html, null];
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export function getAppState(jar: any): any[] {
|
|
122
|
+
return jar
|
|
123
|
+
.getCookiesSync("https://www.facebook.com")
|
|
124
|
+
.concat(jar.getCookiesSync("https://www.messenger.com"));
|
|
125
|
+
}
|
|
@@ -0,0 +1,281 @@
|
|
|
1
|
+
const chalk = require('chalk');
|
|
2
|
+
const gradient = require('gradient-string');
|
|
3
|
+
const echaceb = gradient(['#0061ff', '#681297']);
|
|
4
|
+
const ws = echaceb('bb-fca');
|
|
5
|
+
|
|
6
|
+
let h;
|
|
7
|
+
const i = {};
|
|
8
|
+
const j = {
|
|
9
|
+
_: '%',
|
|
10
|
+
A: '%2',
|
|
11
|
+
B: '000',
|
|
12
|
+
C: '%7d',
|
|
13
|
+
D: '%7b%22',
|
|
14
|
+
E: '%2c%22',
|
|
15
|
+
F: '%22%3a',
|
|
16
|
+
G: '%2c%22ut%22%3a1',
|
|
17
|
+
H: '%2c%22bls%22%3a',
|
|
18
|
+
I: '%2c%22n%22%3a%22%',
|
|
19
|
+
J: '%22%3a%7b%22i%22%3a0%7d',
|
|
20
|
+
K: '%2c%22pt%22%3a0%2c%22vis%22%3a',
|
|
21
|
+
L: '%2c%22ch%22%3a%7b%22h%22%3a%22',
|
|
22
|
+
M: '%7b%22v%22%3a2%2c%22time%22%3a1',
|
|
23
|
+
N: '.channel%22%2c%22sub%22%3a%5b',
|
|
24
|
+
O: '%2c%22sb%22%3a1%2c%22t%22%3a%5b',
|
|
25
|
+
P: '%2c%22ud%22%3a100%2c%22lc%22%3a0',
|
|
26
|
+
Q: '%5d%2c%22f%22%3anull%2c%22uct%22%3a',
|
|
27
|
+
R: '.channel%22%2c%22sub%22%3a%5b1%5d',
|
|
28
|
+
S: '%22%2c%22m%22%3a0%7d%2c%7b%22i%22%3a',
|
|
29
|
+
T: '%2c%22blc%22%3a1%2c%22snd%22%3a1%2c%22ct%22%3a',
|
|
30
|
+
U: '%2c%22blc%22%3a0%2c%22snd%22%3a1%2c%22ct%22%3a',
|
|
31
|
+
V: '%2c%22blc%22%3a0%2c%22snd%22%3a0%2c%22ct%22%3a',
|
|
32
|
+
W: '%2c%22s%22%3a0%2c%22blo%22%3a0%7d%2c%22bl%22%3a%7b%22ac%22%3a',
|
|
33
|
+
X: '%2c%22ri%22%3a0%7d%2c%22state%22%3a%7b%22p%22%3a0%2c%22ut%22%3a1',
|
|
34
|
+
Y:
|
|
35
|
+
'%2c%22pt%22%3a0%2c%22vis%22%3a1%2c%22bls%22%3a0%2c%22blc%22%3a0%2c%22snd%22%3a1%2c%22ct%22%3a',
|
|
36
|
+
Z:
|
|
37
|
+
'%2c%22sb%22%3a1%2c%22t%22%3a%5b%5d%2c%22f%22%3anull%2c%22uct%22%3a0%2c%22s%22%3a0%2c%22blo%22%3a0%7d%2c%22bl%22%3a%7b%22ac%22%3a',
|
|
38
|
+
};
|
|
39
|
+
(function() {
|
|
40
|
+
const l = [];
|
|
41
|
+
for (const m in j) {
|
|
42
|
+
i[j[m]] = m;
|
|
43
|
+
l.push(j[m]);
|
|
44
|
+
}
|
|
45
|
+
l.reverse();
|
|
46
|
+
h = new RegExp(l.join('|'), 'g');
|
|
47
|
+
})();
|
|
48
|
+
|
|
49
|
+
const NUM_TO_MONTH = [
|
|
50
|
+
'Jan',
|
|
51
|
+
'Feb',
|
|
52
|
+
'Mar',
|
|
53
|
+
'Apr',
|
|
54
|
+
'May',
|
|
55
|
+
'Jun',
|
|
56
|
+
'Jul',
|
|
57
|
+
'Aug',
|
|
58
|
+
'Sep',
|
|
59
|
+
'Oct',
|
|
60
|
+
'Nov',
|
|
61
|
+
'Dec',
|
|
62
|
+
];
|
|
63
|
+
const NUM_TO_DAY = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
|
|
64
|
+
|
|
65
|
+
function getRandom(arr) {
|
|
66
|
+
return arr[Math.floor(Math.random() * arr.length)];
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function padZeros(val, len = 2) {
|
|
70
|
+
val = String(val);
|
|
71
|
+
while (val.length < len) val = '0' + val;
|
|
72
|
+
return val;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
function generateThreadingID(clientID) {
|
|
76
|
+
const k = Date.now();
|
|
77
|
+
const l = Math.floor(Math.random() * 4294967295);
|
|
78
|
+
const m = clientID;
|
|
79
|
+
return '<' + k + ':' + l + '-' + m + '@mail.projektitan.com>';
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function binaryToDecimal(data) {
|
|
83
|
+
let ret = '';
|
|
84
|
+
while (data !== '0') {
|
|
85
|
+
let end = 0;
|
|
86
|
+
let fullName = '';
|
|
87
|
+
let i = 0;
|
|
88
|
+
for (; i < data.length; i++) {
|
|
89
|
+
end = 2 * end + parseInt(data[i], 10);
|
|
90
|
+
if (end >= 10) {
|
|
91
|
+
fullName += '1';
|
|
92
|
+
end -= 10;
|
|
93
|
+
} else {
|
|
94
|
+
fullName += '0';
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
ret = end.toString() + ret;
|
|
98
|
+
data = fullName.slice(fullName.indexOf('1'));
|
|
99
|
+
}
|
|
100
|
+
return ret;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
function generateOfflineThreadingID() {
|
|
104
|
+
const ret = Date.now();
|
|
105
|
+
const value = Math.floor(Math.random() * 4294967295);
|
|
106
|
+
const str = ('0000000000000000000000' + value.toString(2)).slice(-22);
|
|
107
|
+
const msgs = ret.toString(2) + str;
|
|
108
|
+
return binaryToDecimal(msgs);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
function presenceEncode(str) {
|
|
112
|
+
return encodeURIComponent(str)
|
|
113
|
+
.replace(/([_A-Z])|%../g, function(m, n) {
|
|
114
|
+
return n ? '%' + n.charCodeAt(0).toString(16) : m;
|
|
115
|
+
})
|
|
116
|
+
.toLowerCase()
|
|
117
|
+
.replace(h, function(m) {
|
|
118
|
+
return i[m];
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
function presenceDecode(str) {
|
|
123
|
+
return decodeURIComponent(
|
|
124
|
+
str.replace(/[_A-Z]/g, function(m) {
|
|
125
|
+
return j[m];
|
|
126
|
+
}),
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function generatePresence(userID) {
|
|
131
|
+
const time = Date.now();
|
|
132
|
+
return (
|
|
133
|
+
'E' +
|
|
134
|
+
presenceEncode(
|
|
135
|
+
JSON.stringify({
|
|
136
|
+
v: 3,
|
|
137
|
+
time: parseInt(String(time / 1000), 10),
|
|
138
|
+
user: userID,
|
|
139
|
+
state: {
|
|
140
|
+
ut: 0,
|
|
141
|
+
t2: [],
|
|
142
|
+
lm2: null,
|
|
143
|
+
uct2: time,
|
|
144
|
+
tr: null,
|
|
145
|
+
tw: Math.floor(Math.random() * 4294967295) + 1,
|
|
146
|
+
at: time,
|
|
147
|
+
},
|
|
148
|
+
ch: {
|
|
149
|
+
['p_' + userID]: 0,
|
|
150
|
+
},
|
|
151
|
+
}),
|
|
152
|
+
)
|
|
153
|
+
);
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function generateAccessiblityCookie() {
|
|
157
|
+
const time = Date.now();
|
|
158
|
+
return encodeURIComponent(
|
|
159
|
+
JSON.stringify({
|
|
160
|
+
sr: 0,
|
|
161
|
+
'sr-ts': time,
|
|
162
|
+
jk: 0,
|
|
163
|
+
'jk-ts': time,
|
|
164
|
+
kb: 0,
|
|
165
|
+
'kb-ts': time,
|
|
166
|
+
hcm: 0,
|
|
167
|
+
'hcm-ts': time,
|
|
168
|
+
}),
|
|
169
|
+
);
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
function getGUID() {
|
|
173
|
+
let sectionLength = Date.now();
|
|
174
|
+
const id = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function(
|
|
175
|
+
c,
|
|
176
|
+
) {
|
|
177
|
+
const r = Math.floor((sectionLength + Math.random() * 16) % 16);
|
|
178
|
+
sectionLength = Math.floor(sectionLength / 16);
|
|
179
|
+
const _guid = (c == 'x' ? r : (r & 7) | 8).toString(16);
|
|
180
|
+
return _guid;
|
|
181
|
+
});
|
|
182
|
+
return id;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
function getFrom(str, startToken, endToken) {
|
|
186
|
+
const start = str.indexOf(startToken) + startToken.length;
|
|
187
|
+
if (start < startToken.length) return '';
|
|
188
|
+
|
|
189
|
+
const lastHalf = str.substring(start);
|
|
190
|
+
const end = lastHalf.indexOf(endToken);
|
|
191
|
+
if (end === -1) {
|
|
192
|
+
throw Error(
|
|
193
|
+
'Could not find endTime `' + endToken + '` in the given string.',
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
return lastHalf.substring(0, end);
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function makeParsable(html) {
|
|
200
|
+
const withoutForLoop = html.replace(/for\s*\(\s*;\s*;\s*\)\s*;\s*/, '');
|
|
201
|
+
const maybeMultipleObjects = withoutForLoop.split(/\}\r\n *\{/);
|
|
202
|
+
if (maybeMultipleObjects.length === 1) return maybeMultipleObjects;
|
|
203
|
+
|
|
204
|
+
return '[' + maybeMultipleObjects.join('},{') + ']';
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
function arrToForm(form) {
|
|
208
|
+
return arrayToObject(
|
|
209
|
+
form,
|
|
210
|
+
function(v) {
|
|
211
|
+
return v.name;
|
|
212
|
+
},
|
|
213
|
+
function(v) {
|
|
214
|
+
return v.val;
|
|
215
|
+
},
|
|
216
|
+
);
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
function arrayToObject(arr, getKey, getValue) {
|
|
220
|
+
return arr.reduce(function(acc, val) {
|
|
221
|
+
acc[getKey(val)] = getValue(val);
|
|
222
|
+
return acc;
|
|
223
|
+
}, {});
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
function getSignatureID() {
|
|
227
|
+
return Math.floor(Math.random() * 2147483648).toString(16);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
function generateTimestampRelative() {
|
|
231
|
+
const d = new Date();
|
|
232
|
+
return d.getHours() + ':' + padZeros(d.getMinutes());
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
function getType(obj) {
|
|
236
|
+
return Object.prototype.toString.call(obj).slice(8, -1);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
// Logs
|
|
240
|
+
let logging = true;
|
|
241
|
+
function logOptions(bool) {
|
|
242
|
+
logging = bool;
|
|
243
|
+
}
|
|
244
|
+
function log(...args) {
|
|
245
|
+
if (logging === false) return;
|
|
246
|
+
console.log(ws, chalk.green.bold('[LOG]'), ...args);
|
|
247
|
+
}
|
|
248
|
+
function error(...args) {
|
|
249
|
+
if (logging === false) return;
|
|
250
|
+
console.error(ws, chalk.red.bold('[ERROR]'), ...args);
|
|
251
|
+
}
|
|
252
|
+
function warn(...args) {
|
|
253
|
+
if (logging === false) return;
|
|
254
|
+
console.warn(ws, chalk.yellow.bold('[WARNING]'), ...args);
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
export {
|
|
258
|
+
NUM_TO_DAY,
|
|
259
|
+
NUM_TO_MONTH,
|
|
260
|
+
arrToForm,
|
|
261
|
+
arrayToObject,
|
|
262
|
+
binaryToDecimal,
|
|
263
|
+
error,
|
|
264
|
+
generateAccessiblityCookie,
|
|
265
|
+
generateOfflineThreadingID,
|
|
266
|
+
generatePresence,
|
|
267
|
+
generateThreadingID,
|
|
268
|
+
generateTimestampRelative,
|
|
269
|
+
getFrom,
|
|
270
|
+
getGUID,
|
|
271
|
+
getRandom,
|
|
272
|
+
getSignatureID,
|
|
273
|
+
getType,
|
|
274
|
+
log,
|
|
275
|
+
logOptions,
|
|
276
|
+
makeParsable,
|
|
277
|
+
padZeros,
|
|
278
|
+
presenceDecode,
|
|
279
|
+
presenceEncode,
|
|
280
|
+
warn,
|
|
281
|
+
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import * as url from "url";
|
|
2
|
+
import * as querystring from "querystring";
|
|
3
|
+
import { getType } from "../../constants";
|
|
4
|
+
|
|
5
|
+
function getExtension(original_extension: string | null, fullFileName: string = ""): string {
|
|
6
|
+
if (original_extension) {
|
|
7
|
+
return original_extension;
|
|
8
|
+
} else {
|
|
9
|
+
const extension = fullFileName.split(".").pop();
|
|
10
|
+
return extension === fullFileName ? "" : extension || "";
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export function _formatAttachment(attachment1: any, attachment2?: any): any {
|
|
15
|
+
const blob_attachment = attachment1.mercury || attachment1.blob_attachment || attachment1.sticker_attachment;
|
|
16
|
+
let type_attachment = blob_attachment && blob_attachment.__typename ? blob_attachment.__typename : attachment1.attach_type;
|
|
17
|
+
|
|
18
|
+
if (type_attachment == null && attachment1.id != null && attachment1.extensible_attachment == null) {
|
|
19
|
+
return { type: "share", ID: attachment1.id, url: attachment1.href, title: "Shared Content", description: "Unsupported shared content.", source: null, isUnrecognized: true };
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
if (!attachment1.attach_type && attachment1.imageMetadata) {
|
|
23
|
+
return { type: "photo", ID: attachment1.fbid, filename: attachment1.filename, fileSize: Number(attachment1.fileSize || 0), mimeType: attachment1.mimeType, width: attachment1.imageMetadata.width, height: attachment1.imageMetadata.height, url: null, thumbnailUrl: null, previewUrl: null, largePreviewUrl: null, name: attachment1.filename };
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
attachment2 = attachment2 || { id: "", image_data: {} };
|
|
27
|
+
attachment1 = attachment1.mercury || attachment1;
|
|
28
|
+
let blob = attachment1.blob_attachment || attachment1.sticker_attachment;
|
|
29
|
+
let type = blob && blob.__typename ? blob.__typename : attachment1.attach_type;
|
|
30
|
+
|
|
31
|
+
if (!type && attachment1.sticker_attachment) {
|
|
32
|
+
type = "StickerAttachment";
|
|
33
|
+
blob = attachment1.sticker_attachment;
|
|
34
|
+
} else if (!type && attachment1.extensible_attachment) {
|
|
35
|
+
if (attachment1.extensible_attachment.story_attachment?.target?.__typename === "MessageLocation") {
|
|
36
|
+
type = "MessageLocation";
|
|
37
|
+
} else {
|
|
38
|
+
type = "ExtensibleAttachment";
|
|
39
|
+
}
|
|
40
|
+
blob = attachment1.extensible_attachment;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
switch (type) {
|
|
44
|
+
case "MessageImage": return { type: "photo", ID: blob.legacy_attachment_id, filename: blob.filename, thumbnailUrl: blob.thumbnail.uri, previewUrl: blob.preview.uri, previewWidth: blob.preview.width, previewHeight: blob.preview.height, largePreviewUrl: blob.large_preview.uri, largePreviewWidth: blob.large_preview.width, largePreviewHeight: blob.large_preview.height, url: blob.large_preview.uri, width: blob.original_dimensions.x, height: blob.original_dimensions.y, name: blob.filename };
|
|
45
|
+
case "MessageAnimatedImage": return { type: "animated_image", ID: blob.legacy_attachment_id, name: blob.filename, previewUrl: blob.preview_image.uri, previewWidth: blob.preview_image.width, previewHeight: blob.preview_image.height, url: blob.animated_image.uri, width: blob.animated_image.width, height: blob.animated_image.height, facebookUrl: blob.animated_image.uri };
|
|
46
|
+
case "MessageVideo": return { type: "video", ID: blob.legacy_attachment_id, filename: blob.filename, duration: blob.playable_duration_in_ms, thumbnailUrl: blob.large_image.uri, previewUrl: blob.large_image.uri, previewWidth: blob.large_image.width, previewHeight: blob.large_image.height, url: blob.playable_url, width: blob.original_dimensions.x, height: blob.original_dimensions.y, videoType: blob.video_type.toLowerCase() };
|
|
47
|
+
case "MessageFile": return { type: "file", ID: blob.message_file_fbid, filename: blob.filename, url: blob.url, isMalicious: blob.is_malicious, contentType: blob.content_type, name: blob.filename };
|
|
48
|
+
case "MessageAudio": return { type: "audio", ID: blob.url_shimhash, filename: blob.filename, duration: blob.playable_duration_in_ms, audioType: blob.audio_type, url: blob.playable_url, isVoiceMail: blob.is_voicemail };
|
|
49
|
+
case "Sticker": case "StickerAttachment": return { type: "sticker", ID: blob.id, url: blob.url, packID: blob.pack?.id, spriteUrl: blob.sprite_image, spriteUrl2x: blob.sprite_image_2x, width: blob.width, height: blob.height, caption: blob.label, description: blob.label, frameCount: blob.frame_count, frameRate: blob.frame_rate, framesPerRow: blob.frames_per_row, framesPerCol: blob.frames_per_column, stickerID: blob.id };
|
|
50
|
+
case "ExtensibleAttachment": { const story = blob.story_attachment; return { type: "share", ID: blob.legacy_attachment_id, url: story.url, title: story.title_with_entities.text, description: story.description?.text, source: story.source?.text, image: story.media?.image?.uri, width: story.media?.image?.width, height: story.media?.image?.height, playable: story.media?.is_playable, duration: story.media?.playable_duration_in_ms, playableUrl: story.media?.playable_url, subattachments: story.subattachments, properties: story.properties.reduce((obj: any, cur: any) => ({ ...obj, [cur.key]: cur.value.text }), {}) }; }
|
|
51
|
+
default: return { type: "unknown", error: `Unrecognized attachment type: ${type}` };
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
export function formatAttachment(attachments: any[], attachmentIds?: any[], attachmentMap?: any, shareMap?: any): any[] {
|
|
56
|
+
attachmentMap = shareMap || attachmentMap;
|
|
57
|
+
return attachments ? attachments.map((val, i) => { if (!attachmentMap || !attachmentIds || !attachmentMap[attachmentIds[i]]) { return _formatAttachment(val); } return _formatAttachment(val, attachmentMap[attachmentIds[i]]); }) : [];
|
|
58
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import formatID from "../value/formatID";
|
|
2
|
+
import { _formatAttachment } from "./formatAttachment";
|
|
3
|
+
|
|
4
|
+
export function getAdminTextMessageType(type: string): string {
|
|
5
|
+
switch (type) {
|
|
6
|
+
case "unpin_messages_v2": return "log:unpin-message";
|
|
7
|
+
case "pin_messages_v2": return "log:pin-message";
|
|
8
|
+
case "change_thread_theme": return "log:thread-color";
|
|
9
|
+
case "change_thread_icon": case "change_thread_quick_reaction": return "log:thread-icon";
|
|
10
|
+
case "change_thread_nickname": return "log:user-nickname";
|
|
11
|
+
case "change_thread_admins": return "log:thread-admins";
|
|
12
|
+
case "group_poll": return "log:thread-poll";
|
|
13
|
+
case "change_thread_approval_mode": return "log:thread-approval-mode";
|
|
14
|
+
case "messenger_call_log": case "participant_joined_group_call": return "log:thread-call";
|
|
15
|
+
default: return type;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export function formatDeltaMessage(m: any): any {
|
|
20
|
+
const md = m.delta.messageMetadata;
|
|
21
|
+
const mdata = m.delta.data?.prng ? JSON.parse(m.delta.data.prng) : [];
|
|
22
|
+
const mentions: Record<string, string> = {};
|
|
23
|
+
for (const mention of mdata) {
|
|
24
|
+
mentions[mention.i] = m.delta.body.substring(mention.o, mention.o + mention.l);
|
|
25
|
+
}
|
|
26
|
+
const messageReply = m.delta.messageReply ? { messageID: m.delta.messageReply.messageID, senderID: formatID(m.delta.messageReply.senderID), body: m.delta.messageReply.body, attachments: m.delta.messageReply.attachments, timestamp: m.delta.messageReply.timestamp, isReply: true } : null;
|
|
27
|
+
return { type: "message", senderID: formatID(md.actorFbId.toString()), body: m.delta.body || "", threadID: formatID((md.threadKey.threadFbId || md.threadKey.otherUserFbId).toString()), messageID: md.messageId, offlineThreadingId: md.offlineThreadingId, attachments: (m.delta.attachments || []).map((v: any) => _formatAttachment(v)), mentions, timestamp: md.timestamp, isGroup: !!md.threadKey.threadFbId, participantIDs: m.delta.participants, messageReply };
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export function formatDeltaEvent(m: any): any {
|
|
31
|
+
let logMessageType: string;
|
|
32
|
+
let logMessageData: any;
|
|
33
|
+
switch (m.class) {
|
|
34
|
+
case "AdminTextMessage": logMessageData = m.untypedData; logMessageType = getAdminTextMessageType(m.type); break;
|
|
35
|
+
case "ThreadName": logMessageType = "log:thread-name"; logMessageData = { name: m.name }; break;
|
|
36
|
+
case "ParticipantsAddedToGroupThread": logMessageType = "log:subscribe"; logMessageData = { addedParticipants: m.addedParticipants }; break;
|
|
37
|
+
case "ParticipantLeftGroupThread": logMessageType = "log:unsubscribe"; logMessageData = { leftParticipantFbId: m.leftParticipantFbId }; break;
|
|
38
|
+
default: logMessageType = m.class; logMessageData = m;
|
|
39
|
+
}
|
|
40
|
+
return { type: "event", threadID: formatID((m.messageMetadata.threadKey.threadFbId || m.messageMetadata.threadKey.otherUserFbId).toString()), messageID: m.messageMetadata.messageId.toString(), logMessageType, logMessageData, logMessageBody: m.messageMetadata.adminText, timestamp: m.messageMetadata.timestamp, author: m.messageMetadata.actorFbId, participantIDs: m.participants };
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export function formatDeltaReadReceipt(delta: any): any {
|
|
44
|
+
return { reader: (delta.threadKey.otherUserFbId || delta.actorFbId).toString(), time: delta.actionTimestampMs, threadID: formatID((delta.threadKey.otherUserFbId || delta.threadKey.threadFbId).toString()), type: "read_receipt" };
|
|
45
|
+
}
|