@meltwater/conversations-api-services 1.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/.drone.yml +13 -0
- package/.github/workflows/release.yml +42 -0
- package/.nvmrc +1 -0
- package/README.md +91 -0
- package/catalog-info.yaml +12 -0
- package/docs/index.md +28 -0
- package/mkdocs.yml +8 -0
- package/package.json +45 -0
- package/src/data-access/http/InstagramVideoClient.js +37 -0
- package/src/data-access/http/WarpZoneApi.client.js +39 -0
- package/src/data-access/http/amazonS3.js +41 -0
- package/src/data-access/http/asset-manager-tvm.client.js +32 -0
- package/src/data-access/http/companiesApi.client.js +35 -0
- package/src/data-access/http/credentialsApi.client.js +137 -0
- package/src/data-access/http/entitlementsApi.client.js +41 -0
- package/src/data-access/http/facebookApi.client.js +701 -0
- package/src/data-access/http/featureToggleApi.client.js +35 -0
- package/src/data-access/http/identityServices.client.js +117 -0
- package/src/data-access/http/instagramApi.client.js +496 -0
- package/src/data-access/http/ir.client.js +309 -0
- package/src/data-access/http/linkedInApi.client.js +624 -0
- package/src/data-access/http/masf.client.js +93 -0
- package/src/data-access/http/tiktokApi.client.js +477 -0
- package/src/data-access/index.js +33 -0
- package/src/lib/applicationTags.helpers.js +22 -0
- package/src/lib/configuration.js +10 -0
- package/src/lib/document-action-events.js +6 -0
- package/src/lib/externalId.helpers.js +15 -0
- package/src/lib/hiddenComment.helper.js +100 -0
- package/src/lib/logger.js +14 -0
- package/src/lib/metrics.helper.js +107 -0
|
@@ -0,0 +1,701 @@
|
|
|
1
|
+
import superagent from 'superagent'; // @todo remove superagent
|
|
2
|
+
import logger from '../../lib/logger.js';
|
|
3
|
+
import { removePrefix } from '../../lib/externalId.helpers.js';
|
|
4
|
+
import { CredentialsApiClient } from '../http/credentialsApi.client.js';
|
|
5
|
+
|
|
6
|
+
const FACEBOOK_URL = 'https://graph.facebook.com';
|
|
7
|
+
export class FacebookApiClient {
|
|
8
|
+
constructor() {
|
|
9
|
+
this.credentialsAPI = new CredentialsApiClient();
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
// assumes all documents are from same credential
|
|
13
|
+
async shareCount(documents) {
|
|
14
|
+
const {
|
|
15
|
+
documentId,
|
|
16
|
+
metaData: { discussionType = 'og' } = {},
|
|
17
|
+
systemData: {
|
|
18
|
+
connectionsCredential: credentialId,
|
|
19
|
+
policies: { storage: { privateTo: companyId } = {} } = {},
|
|
20
|
+
} = {},
|
|
21
|
+
} = documents;
|
|
22
|
+
if (discussionType !== 'og') {
|
|
23
|
+
return;
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
const token = await this.credentialsAPI.getToken(
|
|
27
|
+
credentialId,
|
|
28
|
+
companyId
|
|
29
|
+
);
|
|
30
|
+
const response = await this.getApi(
|
|
31
|
+
`${FACEBOOK_URL}/${removePrefix(
|
|
32
|
+
documents.metaData.externalId
|
|
33
|
+
)}/?fields=shares`,
|
|
34
|
+
token.token,
|
|
35
|
+
documentId
|
|
36
|
+
);
|
|
37
|
+
return response.body.shares && response.body.shares.count;
|
|
38
|
+
} catch (error) {
|
|
39
|
+
logger.error(
|
|
40
|
+
`${documentId} - error recieved - ${error.code}`,
|
|
41
|
+
error
|
|
42
|
+
);
|
|
43
|
+
return undefined;
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
async reactions(documents) {
|
|
48
|
+
const {
|
|
49
|
+
documentId,
|
|
50
|
+
systemData: {
|
|
51
|
+
connectionsCredential: credentialId,
|
|
52
|
+
policies: { storage: { privateTo: companyId } = {} } = {},
|
|
53
|
+
} = {},
|
|
54
|
+
} = documents[0];
|
|
55
|
+
|
|
56
|
+
try {
|
|
57
|
+
const token = await this.credentialsAPI.getToken(
|
|
58
|
+
credentialId,
|
|
59
|
+
companyId
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
const response = await this.getApi(
|
|
63
|
+
`${FACEBOOK_URL}?ids=${documents
|
|
64
|
+
.map((doc) => removePrefix(doc.metaData.externalId))
|
|
65
|
+
.join(',')}&fields=` +
|
|
66
|
+
`reactions.limit(0).summary(viewer_reaction).as(fb_post_reaction_of_user),` +
|
|
67
|
+
`reactions.type(LOVE).limit(0).summary(total_count).as(fb_post_reactions_love),` +
|
|
68
|
+
`reactions.type(WOW).limit(0).summary(total_count).as(fb_post_reactions_wow),` +
|
|
69
|
+
`reactions.type(SAD).limit(0).summary(total_count).as(fb_post_reactions_sad),` +
|
|
70
|
+
`reactions.type(LIKE).limit(0).summary(total_count).as(fb_post_reactions_like),` +
|
|
71
|
+
`reactions.type(ANGRY).limit(0).summary(total_count).as(fb_post_reactions_angry),` +
|
|
72
|
+
`reactions.type(HAHA).limit(0).summary(total_count).as(fb_post_reactions_haha)`,
|
|
73
|
+
token.token,
|
|
74
|
+
documentId
|
|
75
|
+
);
|
|
76
|
+
return response.body;
|
|
77
|
+
} catch (error) {
|
|
78
|
+
logger.error(
|
|
79
|
+
`${documentId} - error recieved - ${error.code}`,
|
|
80
|
+
error
|
|
81
|
+
);
|
|
82
|
+
return undefined;
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
async comment(accessToken, payload) {
|
|
87
|
+
let response;
|
|
88
|
+
const { inReplyToId, text, documentId, attachment } = payload;
|
|
89
|
+
const isGif = attachment && attachment.mimeType === 'image/gif';
|
|
90
|
+
|
|
91
|
+
logger.debug(
|
|
92
|
+
`Starting to call facebook comment api for documentId ${documentId}`,
|
|
93
|
+
payload
|
|
94
|
+
);
|
|
95
|
+
|
|
96
|
+
response = await this.postApi(
|
|
97
|
+
`${FACEBOOK_URL}/${removePrefix(inReplyToId)}/comments`,
|
|
98
|
+
accessToken.token,
|
|
99
|
+
documentId,
|
|
100
|
+
{
|
|
101
|
+
...(text && text.length && { message: text }),
|
|
102
|
+
...(attachment &&
|
|
103
|
+
!isGif && { attachment_url: attachment.link }),
|
|
104
|
+
...(attachment &&
|
|
105
|
+
isGif && { attachment_share_url: attachment.link }),
|
|
106
|
+
}
|
|
107
|
+
);
|
|
108
|
+
logger.info(
|
|
109
|
+
`Native Facebook API Publish Comment Response for documentId ${documentId}`,
|
|
110
|
+
{ status: response.status, ok: response.ok }
|
|
111
|
+
);
|
|
112
|
+
return response.body;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
async privateMessage(accessToken, payload) {
|
|
116
|
+
let response;
|
|
117
|
+
const { profileId, recipientId, text, documentId, attachment } =
|
|
118
|
+
payload;
|
|
119
|
+
const isGif = attachment && attachment.mimeType === 'image/gif';
|
|
120
|
+
logger.debug(
|
|
121
|
+
`Starting to call facebook messages api for documentId ${documentId}`,
|
|
122
|
+
payload
|
|
123
|
+
);
|
|
124
|
+
|
|
125
|
+
response = await this.postApi(
|
|
126
|
+
`${FACEBOOK_URL}/me/messages`,
|
|
127
|
+
accessToken.token,
|
|
128
|
+
documentId,
|
|
129
|
+
{
|
|
130
|
+
recipient: { id: removePrefix(profileId || recipientId) },
|
|
131
|
+
message: {
|
|
132
|
+
text: text,
|
|
133
|
+
...(attachment && {
|
|
134
|
+
attachment: {
|
|
135
|
+
type: isGif
|
|
136
|
+
? 'video'
|
|
137
|
+
: attachment.mimeType.split('/')[0],
|
|
138
|
+
payload: {
|
|
139
|
+
url: attachment.link,
|
|
140
|
+
is_reusable: true,
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
}),
|
|
144
|
+
},
|
|
145
|
+
tag: 'HUMAN_AGENT',
|
|
146
|
+
}
|
|
147
|
+
);
|
|
148
|
+
logger.info(
|
|
149
|
+
`Native Facebook API Publish Private Message Response for documentId ${documentId}`,
|
|
150
|
+
{ status: response.status, ok: response.ok }
|
|
151
|
+
);
|
|
152
|
+
return response.body;
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
async getApi(apiUrl, accessToken, documentId, payload, queryParams = {}) {
|
|
156
|
+
let response = {};
|
|
157
|
+
try {
|
|
158
|
+
response = await superagent
|
|
159
|
+
.get(apiUrl)
|
|
160
|
+
.set('Accept', 'application/json')
|
|
161
|
+
.set('Content-Type', 'application/json')
|
|
162
|
+
.query({ access_token: accessToken, ...queryParams })
|
|
163
|
+
.send(payload);
|
|
164
|
+
} catch (err) {
|
|
165
|
+
let errorText = '';
|
|
166
|
+
if (
|
|
167
|
+
err &&
|
|
168
|
+
err.response &&
|
|
169
|
+
err.response.body &&
|
|
170
|
+
err.response.body.error
|
|
171
|
+
) {
|
|
172
|
+
errorText = `Failed to call facebook api for documentId ${documentId}: ${err.response.body.error.message}`;
|
|
173
|
+
logger.error(errorText);
|
|
174
|
+
} else {
|
|
175
|
+
errorText = `Failed to call facebook api for documentId ${documentId}`;
|
|
176
|
+
logger.error(errorText, err);
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
throw new Error(errorText);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
if (response.status !== 200) {
|
|
183
|
+
logger.error(
|
|
184
|
+
`Failed to call facebook api for documentId ${documentId}`,
|
|
185
|
+
response.body
|
|
186
|
+
);
|
|
187
|
+
let error = new Error(
|
|
188
|
+
`Failed to call facebook api for documentId ${documentId}`
|
|
189
|
+
);
|
|
190
|
+
error.code = response.status;
|
|
191
|
+
throw error;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
return response;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
async postApi(apiUrl, accessToken, documentId, payload) {
|
|
198
|
+
let response = {};
|
|
199
|
+
try {
|
|
200
|
+
response = await superagent
|
|
201
|
+
.post(apiUrl)
|
|
202
|
+
.set('Accept', 'application/json')
|
|
203
|
+
.set('Content-Type', 'application/json')
|
|
204
|
+
.query({ access_token: accessToken })
|
|
205
|
+
.send(payload);
|
|
206
|
+
} catch (err) {
|
|
207
|
+
let errorText = '';
|
|
208
|
+
if (
|
|
209
|
+
err &&
|
|
210
|
+
err.response &&
|
|
211
|
+
err.response.body &&
|
|
212
|
+
err.response.body.error
|
|
213
|
+
) {
|
|
214
|
+
errorText = `Failed to call facebook api for documentId ${documentId}: ${err.response.body.error.message}`;
|
|
215
|
+
logger.error(errorText);
|
|
216
|
+
} else {
|
|
217
|
+
errorText = `Failed to call facebook api for documentId ${documentId}`;
|
|
218
|
+
logger.error(errorText, err);
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
throw new Error(errorText);
|
|
222
|
+
}
|
|
223
|
+
|
|
224
|
+
if (response.status !== 200) {
|
|
225
|
+
logger.error(
|
|
226
|
+
`Failed to call facebook api for documentId ${documentId}`,
|
|
227
|
+
response.body
|
|
228
|
+
);
|
|
229
|
+
let error = new Error(
|
|
230
|
+
`Failed to call facebook api for documentId ${documentId}`
|
|
231
|
+
);
|
|
232
|
+
error.code = response.status;
|
|
233
|
+
throw error;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
return response;
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
async deleteApi(apiUrl, accessToken, documentId, payload) {
|
|
240
|
+
let response = {};
|
|
241
|
+
try {
|
|
242
|
+
response = await superagent
|
|
243
|
+
.delete(apiUrl)
|
|
244
|
+
.set('Accept', 'application/json')
|
|
245
|
+
.set('Content-Type', 'application/json')
|
|
246
|
+
.query({ access_token: accessToken })
|
|
247
|
+
.send(payload);
|
|
248
|
+
} catch (err) {
|
|
249
|
+
let errorText = '';
|
|
250
|
+
if (
|
|
251
|
+
err &&
|
|
252
|
+
err.response &&
|
|
253
|
+
err.response.body &&
|
|
254
|
+
err.response.body.error
|
|
255
|
+
) {
|
|
256
|
+
errorText = `Failed to call facebook api for documentId ${documentId}: ${err.response.body.error.message}`;
|
|
257
|
+
logger.error(errorText);
|
|
258
|
+
} else {
|
|
259
|
+
errorText = `Failed to call facebook api for documentId ${documentId}`;
|
|
260
|
+
logger.error(errorText, err);
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
throw new Error(errorText);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
if (response.status !== 200) {
|
|
267
|
+
logger.error(
|
|
268
|
+
`Failed to call facebook api for documentId ${documentId}`,
|
|
269
|
+
response.body
|
|
270
|
+
);
|
|
271
|
+
let error = new Error(
|
|
272
|
+
`Failed to call facebook api for documentId ${documentId}`
|
|
273
|
+
);
|
|
274
|
+
error.code = response.status;
|
|
275
|
+
throw error;
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
return response;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
async publish(document) {
|
|
282
|
+
const {
|
|
283
|
+
documentId,
|
|
284
|
+
body: {
|
|
285
|
+
content: { text },
|
|
286
|
+
},
|
|
287
|
+
attachments: [attachment] = [],
|
|
288
|
+
metaData: {
|
|
289
|
+
discussionType,
|
|
290
|
+
inReplyTo: { id: inReplyToId, recipientId, profileId },
|
|
291
|
+
},
|
|
292
|
+
systemData: {
|
|
293
|
+
connectionsCredential: credentialId,
|
|
294
|
+
policies: { storage: { privateTo: companyId } = {} } = {},
|
|
295
|
+
} = {},
|
|
296
|
+
} = document;
|
|
297
|
+
|
|
298
|
+
let updatedDocument;
|
|
299
|
+
let apiResponse;
|
|
300
|
+
try {
|
|
301
|
+
const token = await this.credentialsAPI.getToken(
|
|
302
|
+
credentialId,
|
|
303
|
+
companyId
|
|
304
|
+
);
|
|
305
|
+
logger.debug(
|
|
306
|
+
`finished fetching token for Facebook for ${documentId} on company ${companyId} `
|
|
307
|
+
);
|
|
308
|
+
let payload;
|
|
309
|
+
switch (discussionType) {
|
|
310
|
+
case 'qt':
|
|
311
|
+
case 're':
|
|
312
|
+
payload = {
|
|
313
|
+
documentId,
|
|
314
|
+
companyId,
|
|
315
|
+
credentialId,
|
|
316
|
+
text,
|
|
317
|
+
inReplyToId,
|
|
318
|
+
attachment,
|
|
319
|
+
};
|
|
320
|
+
apiResponse = await this.comment(token, payload);
|
|
321
|
+
break;
|
|
322
|
+
case 'dm':
|
|
323
|
+
payload = {
|
|
324
|
+
documentId,
|
|
325
|
+
companyId,
|
|
326
|
+
credentialId,
|
|
327
|
+
text,
|
|
328
|
+
recipientId,
|
|
329
|
+
profileId,
|
|
330
|
+
attachment,
|
|
331
|
+
};
|
|
332
|
+
apiResponse = await this.privateMessage(token, payload);
|
|
333
|
+
break;
|
|
334
|
+
default:
|
|
335
|
+
throw new Error('Unsupported discussion type');
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
if (apiResponse) {
|
|
339
|
+
let findQuery = { documentId };
|
|
340
|
+
findQuery['systemData.policies.storage.privateTo'] = companyId;
|
|
341
|
+
let updateObj = {};
|
|
342
|
+
updateObj['systemData.status'] = DOCUMENT_STATUS.SUCCESS;
|
|
343
|
+
updateObj['metaData.externalId'] =
|
|
344
|
+
apiResponse.id || apiResponse.message_id;
|
|
345
|
+
updateObj.documentId = Buffer.from(
|
|
346
|
+
`${updateObj['metaData.externalId']}`
|
|
347
|
+
).toString('base64');
|
|
348
|
+
updatedDocument = await messagesRepository.updateOne(
|
|
349
|
+
findQuery,
|
|
350
|
+
updateObj
|
|
351
|
+
);
|
|
352
|
+
} else {
|
|
353
|
+
throw new Error(
|
|
354
|
+
'Invalid response from Facebook publish endpoints'
|
|
355
|
+
);
|
|
356
|
+
}
|
|
357
|
+
} catch (exception) {
|
|
358
|
+
logger.error(
|
|
359
|
+
documentId + ' - exception details ' + exception,
|
|
360
|
+
exception
|
|
361
|
+
);
|
|
362
|
+
let findQuery = { documentId };
|
|
363
|
+
findQuery['systemData.policies.storage.privateTo'] = companyId;
|
|
364
|
+
|
|
365
|
+
let updateQuery = {};
|
|
366
|
+
updateQuery['systemData.status'] = DOCUMENT_STATUS.FAILED;
|
|
367
|
+
updateQuery['systemData.error'] =
|
|
368
|
+
exception && exception.response && exception.response.error
|
|
369
|
+
? exception.response.error
|
|
370
|
+
: exception;
|
|
371
|
+
updatedDocument = await messagesRepository.updateOne(
|
|
372
|
+
findQuery,
|
|
373
|
+
updateQuery
|
|
374
|
+
);
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
return apiResponse;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
async toggleHide(document) {
|
|
381
|
+
const {
|
|
382
|
+
documentId,
|
|
383
|
+
appData: { hidden: hiddenOnNative },
|
|
384
|
+
metaData: { externalId },
|
|
385
|
+
systemData: {
|
|
386
|
+
connectionsCredential: credentialId,
|
|
387
|
+
policies: { storage: { privateTo: companyId } = {} } = {},
|
|
388
|
+
} = {},
|
|
389
|
+
version,
|
|
390
|
+
} = document;
|
|
391
|
+
let hideResponse;
|
|
392
|
+
|
|
393
|
+
try {
|
|
394
|
+
logger.debug(
|
|
395
|
+
`processing Facebook Version ${version} for documentID ${documentId} on company ${companyId}`
|
|
396
|
+
);
|
|
397
|
+
|
|
398
|
+
const token = await this.credentialsAPI.getToken(
|
|
399
|
+
credentialId,
|
|
400
|
+
companyId
|
|
401
|
+
);
|
|
402
|
+
|
|
403
|
+
logger.debug(
|
|
404
|
+
`finished fetching token for facebook for ${documentId} on company ${companyId} `
|
|
405
|
+
);
|
|
406
|
+
|
|
407
|
+
if (hiddenOnNative) {
|
|
408
|
+
hideResponse = await this.hide(token, {
|
|
409
|
+
externalId,
|
|
410
|
+
documentId,
|
|
411
|
+
});
|
|
412
|
+
} else {
|
|
413
|
+
hideResponse = await this.unhide(token, {
|
|
414
|
+
externalId,
|
|
415
|
+
documentId,
|
|
416
|
+
});
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
logger.debug(
|
|
420
|
+
`finished hiding in facebook for ${documentId} on company ${companyId} `,
|
|
421
|
+
{ hideResponse }
|
|
422
|
+
);
|
|
423
|
+
|
|
424
|
+
return hideResponse;
|
|
425
|
+
} catch (error) {
|
|
426
|
+
logger.error(
|
|
427
|
+
`${documentId} - error recieved - ${error.code}`,
|
|
428
|
+
error
|
|
429
|
+
);
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
async toggleBan(document, banStatus) {
|
|
434
|
+
let {
|
|
435
|
+
documentId,
|
|
436
|
+
metaData: {
|
|
437
|
+
source: { id: sourceId },
|
|
438
|
+
authors: authors,
|
|
439
|
+
},
|
|
440
|
+
systemData: {
|
|
441
|
+
connectionsCredential: credentialId,
|
|
442
|
+
policies: { storage: { privateTo: companyId } = {} } = {},
|
|
443
|
+
} = {},
|
|
444
|
+
version,
|
|
445
|
+
} = document;
|
|
446
|
+
|
|
447
|
+
let banResponse;
|
|
448
|
+
let authorId = authors[0].authorInfo.externalId;
|
|
449
|
+
|
|
450
|
+
try {
|
|
451
|
+
logger.debug(
|
|
452
|
+
`processing Facebook Version ${version} for profileId ${authorId} on company ${companyId}`
|
|
453
|
+
);
|
|
454
|
+
|
|
455
|
+
const token = await this.credentialsAPI.getToken(
|
|
456
|
+
credentialId,
|
|
457
|
+
companyId
|
|
458
|
+
);
|
|
459
|
+
|
|
460
|
+
logger.debug(
|
|
461
|
+
`finished fetching token for facebook for ${authorId} on company ${companyId} `
|
|
462
|
+
);
|
|
463
|
+
|
|
464
|
+
if (!banStatus) {
|
|
465
|
+
banResponse = await this.unban(token, {
|
|
466
|
+
sourceId,
|
|
467
|
+
authorId,
|
|
468
|
+
});
|
|
469
|
+
} else if (banStatus) {
|
|
470
|
+
banResponse = await this.ban(token, {
|
|
471
|
+
sourceId,
|
|
472
|
+
authorId,
|
|
473
|
+
});
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
logger.debug(
|
|
477
|
+
`finished banning in facebook for ${authorId} on company ${companyId} `,
|
|
478
|
+
{ banResponse }
|
|
479
|
+
);
|
|
480
|
+
} catch (error) {
|
|
481
|
+
logger.error(`${authorId} - error recieved - ${error.code}`, error);
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
async toggleLike(document) {
|
|
486
|
+
const {
|
|
487
|
+
documentId,
|
|
488
|
+
enrichments: {
|
|
489
|
+
socialScores: { fb_liked_by_user: likedByUser },
|
|
490
|
+
},
|
|
491
|
+
metaData: { externalId },
|
|
492
|
+
systemData: {
|
|
493
|
+
connectionsCredential: credentialId,
|
|
494
|
+
policies: { storage: { privateTo: companyId } = {} } = {},
|
|
495
|
+
} = {},
|
|
496
|
+
version,
|
|
497
|
+
} = document;
|
|
498
|
+
|
|
499
|
+
try {
|
|
500
|
+
logger.debug(
|
|
501
|
+
`processing Facebook Version ${version} for documentID ${documentId}`
|
|
502
|
+
);
|
|
503
|
+
|
|
504
|
+
logger.debug(
|
|
505
|
+
`starting to fetch tokens for facebook for ${documentId} on company ${companyId} `
|
|
506
|
+
);
|
|
507
|
+
const token = await this.credentialsAPI.getToken(
|
|
508
|
+
credentialId,
|
|
509
|
+
companyId
|
|
510
|
+
);
|
|
511
|
+
|
|
512
|
+
logger.debug(
|
|
513
|
+
`finished fetching token for facebook for ${documentId} on company ${companyId} `
|
|
514
|
+
);
|
|
515
|
+
|
|
516
|
+
let likeResponse = await (likedByUser
|
|
517
|
+
? this.like(token, { externalId, documentId })
|
|
518
|
+
: this.unlike(token, { externalId, documentId }));
|
|
519
|
+
|
|
520
|
+
logger.debug(
|
|
521
|
+
`finished liking in facebook for ${documentId} on company ${companyId} `,
|
|
522
|
+
{ likeResponse }
|
|
523
|
+
);
|
|
524
|
+
} catch (error) {
|
|
525
|
+
logger.error(`${document} - error recieved - ${error.code}`, error);
|
|
526
|
+
throw error;
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
async like(accessToken, command) {
|
|
531
|
+
let response;
|
|
532
|
+
const { externalId, documentId } = command;
|
|
533
|
+
|
|
534
|
+
logger.debug(
|
|
535
|
+
`Starting to call facebook like api for documentId ${documentId}`,
|
|
536
|
+
{ command }
|
|
537
|
+
);
|
|
538
|
+
|
|
539
|
+
response = await this.postApi(
|
|
540
|
+
`${FACEBOOK_URL}/${removePrefix(externalId)}/likes`,
|
|
541
|
+
accessToken.token,
|
|
542
|
+
documentId
|
|
543
|
+
);
|
|
544
|
+
|
|
545
|
+
logger.info(
|
|
546
|
+
`Native Facebook API Like Response for documentId ${documentId}`,
|
|
547
|
+
{ status: response.status, ok: response.ok }
|
|
548
|
+
);
|
|
549
|
+
return response.body;
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
async unlike(accessToken, command) {
|
|
553
|
+
let response;
|
|
554
|
+
const { externalId, documentId } = command;
|
|
555
|
+
|
|
556
|
+
logger.debug(
|
|
557
|
+
`Starting to call facebook unlike api for documentId ${documentId}`,
|
|
558
|
+
command
|
|
559
|
+
);
|
|
560
|
+
|
|
561
|
+
response = await this.deleteApi(
|
|
562
|
+
`${FACEBOOK_URL}/${removePrefix(externalId)}/likes`,
|
|
563
|
+
accessToken.token,
|
|
564
|
+
documentId
|
|
565
|
+
);
|
|
566
|
+
|
|
567
|
+
logger.info(
|
|
568
|
+
`Native Facebook API Unlike Response for documentId ${documentId}`,
|
|
569
|
+
{ status: response.status, ok: response.ok }
|
|
570
|
+
);
|
|
571
|
+
return response.body;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
async hide(accessToken, command) {
|
|
575
|
+
let response;
|
|
576
|
+
const { externalId, documentId } = command;
|
|
577
|
+
|
|
578
|
+
logger.debug(
|
|
579
|
+
`Starting to call facebook hide api for documentId ${documentId}`,
|
|
580
|
+
{ command }
|
|
581
|
+
);
|
|
582
|
+
|
|
583
|
+
response = await this.postApi(
|
|
584
|
+
`${FACEBOOK_URL}/${removePrefix(externalId)}`,
|
|
585
|
+
accessToken.token,
|
|
586
|
+
documentId,
|
|
587
|
+
{ is_hidden: true }
|
|
588
|
+
);
|
|
589
|
+
|
|
590
|
+
logger.info(
|
|
591
|
+
`Native Facebook API Hide Response for documentId ${documentId}`,
|
|
592
|
+
{ status: response.status, ok: response.ok }
|
|
593
|
+
);
|
|
594
|
+
return response.body;
|
|
595
|
+
}
|
|
596
|
+
|
|
597
|
+
async unhide(accessToken, command) {
|
|
598
|
+
let response;
|
|
599
|
+
const { externalId, documentId } = command;
|
|
600
|
+
|
|
601
|
+
logger.debug(
|
|
602
|
+
`Starting to call facebook unhide api for documentId ${documentId}`,
|
|
603
|
+
command
|
|
604
|
+
);
|
|
605
|
+
|
|
606
|
+
response = await this.postApi(
|
|
607
|
+
`${FACEBOOK_URL}/${removePrefix(externalId)}`,
|
|
608
|
+
accessToken.token,
|
|
609
|
+
documentId,
|
|
610
|
+
{ is_hidden: false }
|
|
611
|
+
);
|
|
612
|
+
|
|
613
|
+
logger.info(
|
|
614
|
+
`Native Facebook API Unhide Response for documentId ${documentId}`,
|
|
615
|
+
{ status: response.status, ok: response.ok }
|
|
616
|
+
);
|
|
617
|
+
return response.body;
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
async isUserBanned({ credentialId, companyId, userId, pageId }) {
|
|
621
|
+
const token = await this.credentialsAPI.getToken(
|
|
622
|
+
credentialId,
|
|
623
|
+
companyId
|
|
624
|
+
);
|
|
625
|
+
|
|
626
|
+
const response = await this.getApi(
|
|
627
|
+
`${FACEBOOK_URL}/${pageId}/blocked`,
|
|
628
|
+
token.token,
|
|
629
|
+
`${companyId}-${credentialId}-${userId}-${pageId}`,
|
|
630
|
+
undefined, // payload
|
|
631
|
+
{
|
|
632
|
+
user: removePrefix(userId),
|
|
633
|
+
}
|
|
634
|
+
);
|
|
635
|
+
|
|
636
|
+
if (response && response.body && response.body.data) {
|
|
637
|
+
const userNoPrefix = removePrefix(userId);
|
|
638
|
+
const user = response.body.data.find((user) => {
|
|
639
|
+
if (user.id == userNoPrefix) {
|
|
640
|
+
return user;
|
|
641
|
+
}
|
|
642
|
+
});
|
|
643
|
+
if (user) {
|
|
644
|
+
return true;
|
|
645
|
+
} else {
|
|
646
|
+
return false;
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
logger.info(
|
|
650
|
+
`Native Facebook API is User Banned Response was invalid for userId ${userId} ${credentialId}`,
|
|
651
|
+
{ status: response.status, ok: response.ok }
|
|
652
|
+
);
|
|
653
|
+
return false;
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
async ban(accessToken, command) {
|
|
657
|
+
let response;
|
|
658
|
+
const { sourceId, authorId } = command;
|
|
659
|
+
|
|
660
|
+
logger.debug(
|
|
661
|
+
`Starting to call facebook ban api for externalAuthorId ${authorId}`,
|
|
662
|
+
{ command }
|
|
663
|
+
);
|
|
664
|
+
|
|
665
|
+
response = await this.postApi(
|
|
666
|
+
`${FACEBOOK_URL}/${removePrefix(sourceId)}/blocked`,
|
|
667
|
+
accessToken.token,
|
|
668
|
+
removePrefix(authorId),
|
|
669
|
+
{ psid: [removePrefix(authorId)] }
|
|
670
|
+
);
|
|
671
|
+
|
|
672
|
+
logger.info(
|
|
673
|
+
`Native Facebook API Hide Response for externalAuthorId ${authorId}`,
|
|
674
|
+
{ status: response.status, ok: response.ok }
|
|
675
|
+
);
|
|
676
|
+
return response.body;
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
async unban(accessToken, command) {
|
|
680
|
+
let response;
|
|
681
|
+
const { sourceId, authorId } = command;
|
|
682
|
+
|
|
683
|
+
logger.debug(
|
|
684
|
+
`Starting to call facebook unban api for externalAuthorId ${authorId}`,
|
|
685
|
+
command
|
|
686
|
+
);
|
|
687
|
+
|
|
688
|
+
response = await this.deleteApi(
|
|
689
|
+
`${FACEBOOK_URL}/${removePrefix(sourceId)}/blocked`,
|
|
690
|
+
accessToken.token,
|
|
691
|
+
removePrefix(authorId),
|
|
692
|
+
{ psid: [removePrefix(authorId)] }
|
|
693
|
+
);
|
|
694
|
+
|
|
695
|
+
logger.info(
|
|
696
|
+
`Native Facebook API Unban Response for externalAuthorId ${authorId}`,
|
|
697
|
+
{ status: response.status, ok: response.ok }
|
|
698
|
+
);
|
|
699
|
+
return response.body;
|
|
700
|
+
}
|
|
701
|
+
}
|