@meltwater/conversations-api-services 1.0.4 → 1.0.6
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/package.json +1 -1
- package/src/data-access/http/facebookApi.client.js +27 -62
- package/src/data-access/http/instagramApi.client.js +32 -84
- package/src/data-access/http/linkedInApi.client.js +41 -86
- package/src/data-access/http/tiktokApi.client.js +477 -0
- package/src/data-access/index.js +2 -0
package/package.json
CHANGED
|
@@ -107,7 +107,7 @@ export class FacebookApiClient {
|
|
|
107
107
|
);
|
|
108
108
|
logger.info(
|
|
109
109
|
`Native Facebook API Publish Comment Response for documentId ${documentId}`,
|
|
110
|
-
{
|
|
110
|
+
{ status: response.status, ok: response.ok }
|
|
111
111
|
);
|
|
112
112
|
return response.body;
|
|
113
113
|
}
|
|
@@ -147,7 +147,7 @@ export class FacebookApiClient {
|
|
|
147
147
|
);
|
|
148
148
|
logger.info(
|
|
149
149
|
`Native Facebook API Publish Private Message Response for documentId ${documentId}`,
|
|
150
|
-
{
|
|
150
|
+
{ status: response.status, ok: response.ok }
|
|
151
151
|
);
|
|
152
152
|
return response.body;
|
|
153
153
|
}
|
|
@@ -162,23 +162,21 @@ export class FacebookApiClient {
|
|
|
162
162
|
.query({ access_token: accessToken, ...queryParams })
|
|
163
163
|
.send(payload);
|
|
164
164
|
} catch (err) {
|
|
165
|
+
let errorText = '';
|
|
165
166
|
if (
|
|
166
167
|
err &&
|
|
167
168
|
err.response &&
|
|
168
169
|
err.response.body &&
|
|
169
170
|
err.response.body.error
|
|
170
171
|
) {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
);
|
|
172
|
+
errorText = `Failed to call facebook api for documentId ${documentId}: ${err.response.body.error.message}`;
|
|
173
|
+
logger.error(errorText);
|
|
174
174
|
} else {
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
err
|
|
178
|
-
);
|
|
175
|
+
errorText = `Failed to call facebook api for documentId ${documentId}`;
|
|
176
|
+
logger.error(errorText, err);
|
|
179
177
|
}
|
|
180
178
|
|
|
181
|
-
throw
|
|
179
|
+
throw new Error(errorText);
|
|
182
180
|
}
|
|
183
181
|
|
|
184
182
|
if (response.status !== 200) {
|
|
@@ -206,23 +204,21 @@ export class FacebookApiClient {
|
|
|
206
204
|
.query({ access_token: accessToken })
|
|
207
205
|
.send(payload);
|
|
208
206
|
} catch (err) {
|
|
207
|
+
let errorText = '';
|
|
209
208
|
if (
|
|
210
209
|
err &&
|
|
211
210
|
err.response &&
|
|
212
211
|
err.response.body &&
|
|
213
212
|
err.response.body.error
|
|
214
213
|
) {
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
);
|
|
214
|
+
errorText = `Failed to call facebook api for documentId ${documentId}: ${err.response.body.error.message}`;
|
|
215
|
+
logger.error(errorText);
|
|
218
216
|
} else {
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
err
|
|
222
|
-
);
|
|
217
|
+
errorText = `Failed to call facebook api for documentId ${documentId}`;
|
|
218
|
+
logger.error(errorText, err);
|
|
223
219
|
}
|
|
224
220
|
|
|
225
|
-
throw
|
|
221
|
+
throw new Error(errorText);
|
|
226
222
|
}
|
|
227
223
|
|
|
228
224
|
if (response.status !== 200) {
|
|
@@ -250,23 +246,21 @@ export class FacebookApiClient {
|
|
|
250
246
|
.query({ access_token: accessToken })
|
|
251
247
|
.send(payload);
|
|
252
248
|
} catch (err) {
|
|
249
|
+
let errorText = '';
|
|
253
250
|
if (
|
|
254
251
|
err &&
|
|
255
252
|
err.response &&
|
|
256
253
|
err.response.body &&
|
|
257
254
|
err.response.body.error
|
|
258
255
|
) {
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
);
|
|
256
|
+
errorText = `Failed to call facebook api for documentId ${documentId}: ${err.response.body.error.message}`;
|
|
257
|
+
logger.error(errorText);
|
|
262
258
|
} else {
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
err
|
|
266
|
-
);
|
|
259
|
+
errorText = `Failed to call facebook api for documentId ${documentId}`;
|
|
260
|
+
logger.error(errorText, err);
|
|
267
261
|
}
|
|
268
262
|
|
|
269
|
-
throw
|
|
263
|
+
throw new Error(errorText);
|
|
270
264
|
}
|
|
271
265
|
|
|
272
266
|
if (response.status !== 200) {
|
|
@@ -380,13 +374,6 @@ export class FacebookApiClient {
|
|
|
380
374
|
);
|
|
381
375
|
}
|
|
382
376
|
|
|
383
|
-
//sendNotification -> needs to wait for temp document to reach user
|
|
384
|
-
setTimeout(() => {
|
|
385
|
-
PushRepository.publish(
|
|
386
|
-
`${companyId}-${documentId}`,
|
|
387
|
-
updatedDocument
|
|
388
|
-
);
|
|
389
|
-
}, 5000);
|
|
390
377
|
return apiResponse;
|
|
391
378
|
}
|
|
392
379
|
|
|
@@ -458,7 +445,6 @@ export class FacebookApiClient {
|
|
|
458
445
|
} = document;
|
|
459
446
|
|
|
460
447
|
let banResponse;
|
|
461
|
-
let notificationPayload = document;
|
|
462
448
|
let authorId = authors[0].authorInfo.externalId;
|
|
463
449
|
|
|
464
450
|
try {
|
|
@@ -491,30 +477,9 @@ export class FacebookApiClient {
|
|
|
491
477
|
`finished banning in facebook for ${authorId} on company ${companyId} `,
|
|
492
478
|
{ banResponse }
|
|
493
479
|
);
|
|
494
|
-
|
|
495
|
-
notificationPayload.banStatus = {
|
|
496
|
-
code: banResponse.success === true ? 200 : 500,
|
|
497
|
-
message:
|
|
498
|
-
banResponse.success === true ? 'Success' : 'Failed to Ban',
|
|
499
|
-
};
|
|
500
|
-
logger.debug(
|
|
501
|
-
`Notification payload for ${authorId} on company ${companyId} `,
|
|
502
|
-
notificationPayload
|
|
503
|
-
);
|
|
504
480
|
} catch (error) {
|
|
505
481
|
logger.error(`${authorId} - error recieved - ${error.code}`, error);
|
|
506
|
-
// message failed ot send, mark as such
|
|
507
|
-
notificationPayload.banStatus = {
|
|
508
|
-
code: 405,
|
|
509
|
-
message: 'Exception Occurred',
|
|
510
|
-
};
|
|
511
482
|
}
|
|
512
|
-
setTimeout(() => {
|
|
513
|
-
PushRepository.publish(
|
|
514
|
-
`${companyId}-${authorId}`,
|
|
515
|
-
notificationPayload
|
|
516
|
-
);
|
|
517
|
-
}, 5000);
|
|
518
483
|
}
|
|
519
484
|
|
|
520
485
|
async toggleLike(document) {
|
|
@@ -579,7 +544,7 @@ export class FacebookApiClient {
|
|
|
579
544
|
|
|
580
545
|
logger.info(
|
|
581
546
|
`Native Facebook API Like Response for documentId ${documentId}`,
|
|
582
|
-
{
|
|
547
|
+
{ status: response.status, ok: response.ok }
|
|
583
548
|
);
|
|
584
549
|
return response.body;
|
|
585
550
|
}
|
|
@@ -601,7 +566,7 @@ export class FacebookApiClient {
|
|
|
601
566
|
|
|
602
567
|
logger.info(
|
|
603
568
|
`Native Facebook API Unlike Response for documentId ${documentId}`,
|
|
604
|
-
{
|
|
569
|
+
{ status: response.status, ok: response.ok }
|
|
605
570
|
);
|
|
606
571
|
return response.body;
|
|
607
572
|
}
|
|
@@ -624,7 +589,7 @@ export class FacebookApiClient {
|
|
|
624
589
|
|
|
625
590
|
logger.info(
|
|
626
591
|
`Native Facebook API Hide Response for documentId ${documentId}`,
|
|
627
|
-
{
|
|
592
|
+
{ status: response.status, ok: response.ok }
|
|
628
593
|
);
|
|
629
594
|
return response.body;
|
|
630
595
|
}
|
|
@@ -647,7 +612,7 @@ export class FacebookApiClient {
|
|
|
647
612
|
|
|
648
613
|
logger.info(
|
|
649
614
|
`Native Facebook API Unhide Response for documentId ${documentId}`,
|
|
650
|
-
{
|
|
615
|
+
{ status: response.status, ok: response.ok }
|
|
651
616
|
);
|
|
652
617
|
return response.body;
|
|
653
618
|
}
|
|
@@ -683,7 +648,7 @@ export class FacebookApiClient {
|
|
|
683
648
|
}
|
|
684
649
|
logger.info(
|
|
685
650
|
`Native Facebook API is User Banned Response was invalid for userId ${userId} ${credentialId}`,
|
|
686
|
-
{
|
|
651
|
+
{ status: response.status, ok: response.ok }
|
|
687
652
|
);
|
|
688
653
|
return false;
|
|
689
654
|
}
|
|
@@ -706,7 +671,7 @@ export class FacebookApiClient {
|
|
|
706
671
|
|
|
707
672
|
logger.info(
|
|
708
673
|
`Native Facebook API Hide Response for externalAuthorId ${authorId}`,
|
|
709
|
-
{
|
|
674
|
+
{ status: response.status, ok: response.ok }
|
|
710
675
|
);
|
|
711
676
|
return response.body;
|
|
712
677
|
}
|
|
@@ -729,7 +694,7 @@ export class FacebookApiClient {
|
|
|
729
694
|
|
|
730
695
|
logger.info(
|
|
731
696
|
`Native Facebook API Unban Response for externalAuthorId ${authorId}`,
|
|
732
|
-
{
|
|
697
|
+
{ status: response.status, ok: response.ok }
|
|
733
698
|
);
|
|
734
699
|
return response.body;
|
|
735
700
|
}
|
|
@@ -3,9 +3,6 @@ import logger from '../../lib/logger.js';
|
|
|
3
3
|
import { removePrefix } from '../../lib/externalId.helpers.js';
|
|
4
4
|
import assert from 'assert';
|
|
5
5
|
import { CredentialsApiClient } from '../http/credentialsApi.client.js';
|
|
6
|
-
// import { messagesRepository } from '@data-access/mongo/repository/messages.js';
|
|
7
|
-
// import PushRepository from '@data-access/redis/repository/push.repository.js';
|
|
8
|
-
// import { DOCUMENT_STATUS } from '@data-access/mongo/query.helpers.js';
|
|
9
6
|
|
|
10
7
|
const INSTAGRAM_URL = 'https://graph.facebook.com';
|
|
11
8
|
export class InstagramApiClient {
|
|
@@ -47,22 +44,22 @@ export class InstagramApiClient {
|
|
|
47
44
|
.query(queryStringArgs)
|
|
48
45
|
.send(data);
|
|
49
46
|
} catch (err) {
|
|
47
|
+
let errorText = '';
|
|
50
48
|
if (
|
|
51
49
|
err &&
|
|
52
50
|
err.response &&
|
|
53
51
|
err.response.body &&
|
|
54
52
|
err.response.body.error
|
|
55
53
|
) {
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
);
|
|
54
|
+
errorText =
|
|
55
|
+
'Failed to call instagram api for documentId ${documentId}: ${err.response.body.error.message}';
|
|
56
|
+
logger.error(errorText);
|
|
59
57
|
} else {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
);
|
|
58
|
+
errorText =
|
|
59
|
+
'Failed to call instagram api for documentId ${documentId}';
|
|
60
|
+
logger.error(errorText, err);
|
|
64
61
|
}
|
|
65
|
-
throw
|
|
62
|
+
throw new Error(errorText);
|
|
66
63
|
}
|
|
67
64
|
|
|
68
65
|
if (response.status !== 200) {
|
|
@@ -100,7 +97,7 @@ export class InstagramApiClient {
|
|
|
100
97
|
|
|
101
98
|
logger.info(
|
|
102
99
|
`Native Instagram API getPost Response for documentId ${documentId}`,
|
|
103
|
-
{
|
|
100
|
+
{ status: response.status, ok: response.ok }
|
|
104
101
|
);
|
|
105
102
|
return response.body;
|
|
106
103
|
} catch (err) {
|
|
@@ -127,22 +124,20 @@ export class InstagramApiClient {
|
|
|
127
124
|
.query({ message: text })
|
|
128
125
|
.send();
|
|
129
126
|
} catch (err) {
|
|
127
|
+
let errorText = '';
|
|
130
128
|
if (
|
|
131
129
|
err &&
|
|
132
130
|
err.response &&
|
|
133
131
|
err.response.body &&
|
|
134
132
|
err.response.body.error
|
|
135
133
|
) {
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
);
|
|
134
|
+
errorText = `Failed to call instagram api for documentId ${documentId}: ${err.response.body.error.message}`;
|
|
135
|
+
logger.error(errorText);
|
|
139
136
|
} else {
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
err
|
|
143
|
-
);
|
|
137
|
+
errorText = `Failed to call instagram api for documentId ${documentId}`;
|
|
138
|
+
logger.error(errorText, err);
|
|
144
139
|
}
|
|
145
|
-
throw
|
|
140
|
+
throw new Error(errorText);
|
|
146
141
|
}
|
|
147
142
|
|
|
148
143
|
if (response.status !== 200) {
|
|
@@ -173,18 +168,15 @@ export class InstagramApiClient {
|
|
|
173
168
|
.query({ hide: hideStatus })
|
|
174
169
|
.send();
|
|
175
170
|
} catch (err) {
|
|
171
|
+
let errorText = '';
|
|
176
172
|
if (err && err.response && err.response.body) {
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
err.response.body.error
|
|
180
|
-
);
|
|
173
|
+
errorText = `Failed to call instagram api for documentId ${documentId}: ${err.response.body.error.message}`;
|
|
174
|
+
logger.error(errorText, err.response.body.error);
|
|
181
175
|
} else {
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
err
|
|
185
|
-
);
|
|
176
|
+
errorText = `Failed to call instagram api for documentId ${documentId}`;
|
|
177
|
+
logger.error(errorText, err);
|
|
186
178
|
}
|
|
187
|
-
throw
|
|
179
|
+
throw new Error(errorText);
|
|
188
180
|
}
|
|
189
181
|
|
|
190
182
|
if (response.status !== 200) {
|
|
@@ -215,18 +207,15 @@ export class InstagramApiClient {
|
|
|
215
207
|
.query({ fields: fields })
|
|
216
208
|
.send();
|
|
217
209
|
} catch (err) {
|
|
210
|
+
let errorText = '';
|
|
218
211
|
if (err && err.response && err.response.body) {
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
err.response.body.error
|
|
222
|
-
);
|
|
212
|
+
errorText = `Failed to call instagram api for documentId ${documentId}: ${err.response.body.error.message}`;
|
|
213
|
+
logger.error(errorText, err.response.body.error);
|
|
223
214
|
} else {
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
err
|
|
227
|
-
);
|
|
215
|
+
errorText = `Failed to call instagram api for documentId ${documentId}`;
|
|
216
|
+
logger.error(errorText, err);
|
|
228
217
|
}
|
|
229
|
-
throw
|
|
218
|
+
throw new Error(errorText);
|
|
230
219
|
}
|
|
231
220
|
|
|
232
221
|
if (response.status !== 200) {
|
|
@@ -278,7 +267,7 @@ export class InstagramApiClient {
|
|
|
278
267
|
|
|
279
268
|
logger.info(
|
|
280
269
|
`Native Intagram API Publish Comment Response for documentId ${documentId}`,
|
|
281
|
-
{
|
|
270
|
+
{ status: response.status, ok: response.ok }
|
|
282
271
|
);
|
|
283
272
|
return response.body;
|
|
284
273
|
}
|
|
@@ -327,7 +316,7 @@ export class InstagramApiClient {
|
|
|
327
316
|
|
|
328
317
|
logger.info(
|
|
329
318
|
`Native Instagram API Publish Reply Response for documentId ${documentId}`,
|
|
330
|
-
{
|
|
319
|
+
{ status: response.status, ok: response.ok }
|
|
331
320
|
);
|
|
332
321
|
return response.body;
|
|
333
322
|
}
|
|
@@ -413,51 +402,10 @@ export class InstagramApiClient {
|
|
|
413
402
|
default:
|
|
414
403
|
throw new Error('Unsupported discussion type');
|
|
415
404
|
}
|
|
416
|
-
|
|
417
|
-
if (apiResponse) {
|
|
418
|
-
let findQuery = { documentId };
|
|
419
|
-
findQuery['systemData.policies.storage.privateTo'] = companyId;
|
|
420
|
-
let updateObj = {};
|
|
421
|
-
updateObj['systemData.status'] = DOCUMENT_STATUS.SUCCESS;
|
|
422
|
-
// update with the new id from instagram reply/comment or direct message
|
|
423
|
-
updateObj['metaData.externalId'] =
|
|
424
|
-
apiResponse.id || `${apiResponse.message_id}`;
|
|
425
|
-
updateObj.documentId = Buffer.from(
|
|
426
|
-
`${updateObj['metaData.externalId']}`
|
|
427
|
-
).toString('base64');
|
|
428
|
-
updatedDocument = await messagesRepository.updateOne(
|
|
429
|
-
findQuery,
|
|
430
|
-
updateObj
|
|
431
|
-
);
|
|
432
|
-
} else {
|
|
433
|
-
throw new Error(
|
|
434
|
-
'Invalid response from instagram publish endpoints'
|
|
435
|
-
);
|
|
436
|
-
}
|
|
437
405
|
} catch (err) {
|
|
438
406
|
logger.error(documentId + ' - exception details ' + err, err);
|
|
439
|
-
let findQuery = { documentId };
|
|
440
|
-
findQuery['systemData.policies.storage.privateTo'] = companyId;
|
|
441
|
-
|
|
442
|
-
let updateQuery = {};
|
|
443
|
-
updateQuery['systemData.status'] = DOCUMENT_STATUS.FAILED;
|
|
444
|
-
updateQuery['systemData.error'] =
|
|
445
|
-
err && err.response && err.response.error
|
|
446
|
-
? err.response.error
|
|
447
|
-
: err;
|
|
448
|
-
updatedDocument = await messagesRepository.updateOne(
|
|
449
|
-
findQuery,
|
|
450
|
-
updateQuery
|
|
451
|
-
);
|
|
452
407
|
}
|
|
453
408
|
|
|
454
|
-
//sendNotification -> needs to wait for temp document to reach user
|
|
455
|
-
setTimeout(() => {
|
|
456
|
-
PushRepository.publish(
|
|
457
|
-
`${companyId}-${documentId}`,
|
|
458
|
-
updatedDocument
|
|
459
|
-
);
|
|
460
|
-
}, 5000);
|
|
461
409
|
return apiResponse;
|
|
462
410
|
}
|
|
463
411
|
|
|
@@ -479,7 +427,7 @@ export class InstagramApiClient {
|
|
|
479
427
|
|
|
480
428
|
logger.info(
|
|
481
429
|
`Native Instagram API Hide Response for documentId ${documentId}`,
|
|
482
|
-
{
|
|
430
|
+
{ status: response.status, ok: response.ok }
|
|
483
431
|
);
|
|
484
432
|
return response.body;
|
|
485
433
|
}
|
|
@@ -502,7 +450,7 @@ export class InstagramApiClient {
|
|
|
502
450
|
|
|
503
451
|
logger.info(
|
|
504
452
|
`Native Instagram API Unhide Response for documentId ${documentId}`,
|
|
505
|
-
{
|
|
453
|
+
{ status: response.status, ok: response.ok }
|
|
506
454
|
);
|
|
507
455
|
return response.body;
|
|
508
456
|
}
|
|
@@ -541,7 +489,7 @@ export class InstagramApiClient {
|
|
|
541
489
|
|
|
542
490
|
logger.info(
|
|
543
491
|
`Native Instagram API Publish Private Message Response for documentId ${documentId}`,
|
|
544
|
-
{
|
|
492
|
+
{ status: response.status, ok: response.ok }
|
|
545
493
|
);
|
|
546
494
|
return response.body;
|
|
547
495
|
}
|
|
@@ -1,13 +1,10 @@
|
|
|
1
1
|
import superagent from 'superagent';
|
|
2
2
|
import configuration from '../../lib/configuration.js';
|
|
3
|
-
|
|
4
|
-
// import { messagesRepository } from '@data-access/mongo/repository/messages.js';
|
|
5
|
-
// import PushRepositoryfrom from '@data-access/redis/repository/push.repository.js';
|
|
3
|
+
import { CredentialsApiClient } from '../http/credentialsApi.client.js';
|
|
6
4
|
|
|
7
5
|
export class LinkedInApiClient {
|
|
8
|
-
constructor(
|
|
9
|
-
this.
|
|
10
|
-
this.logger = services.logger;
|
|
6
|
+
constructor() {
|
|
7
|
+
this.credentialsAPI = new CredentialsApiClient();
|
|
11
8
|
}
|
|
12
9
|
|
|
13
10
|
async likeMessage(document) {
|
|
@@ -43,12 +40,12 @@ export class LinkedInApiClient {
|
|
|
43
40
|
)}?actor=${fixedEncodeURIComponent(payload.actor)}`;
|
|
44
41
|
|
|
45
42
|
try {
|
|
46
|
-
let credential = await this.
|
|
43
|
+
let credential = await this.credentialsAPI.getToken(
|
|
47
44
|
credentialId,
|
|
48
45
|
companyId
|
|
49
46
|
);
|
|
50
47
|
if (!likedByUser) {
|
|
51
|
-
|
|
48
|
+
logger.debug(`${documentId} - trying Delete `, {
|
|
52
49
|
query,
|
|
53
50
|
payload,
|
|
54
51
|
});
|
|
@@ -63,7 +60,7 @@ export class LinkedInApiClient {
|
|
|
63
60
|
'LinkedIn-Version': '202305',
|
|
64
61
|
});
|
|
65
62
|
} else {
|
|
66
|
-
|
|
63
|
+
logger.debug(`${documentId} - sending to linkedin `, {
|
|
67
64
|
query,
|
|
68
65
|
payload,
|
|
69
66
|
});
|
|
@@ -80,7 +77,7 @@ export class LinkedInApiClient {
|
|
|
80
77
|
.send(payload);
|
|
81
78
|
}
|
|
82
79
|
|
|
83
|
-
|
|
80
|
+
logger.info(
|
|
84
81
|
`Native Linkedin API Like Comment Response for documentId ${documentId}`,
|
|
85
82
|
{
|
|
86
83
|
ok: response.ok,
|
|
@@ -90,7 +87,7 @@ export class LinkedInApiClient {
|
|
|
90
87
|
}
|
|
91
88
|
);
|
|
92
89
|
} catch (err) {
|
|
93
|
-
|
|
90
|
+
logger.error(documentId + ' - exception details', {
|
|
94
91
|
err,
|
|
95
92
|
});
|
|
96
93
|
throw err;
|
|
@@ -125,12 +122,12 @@ export class LinkedInApiClient {
|
|
|
125
122
|
)}/comments/${commentId}?actor=${fixedEncodeURIComponent(actorURN)}`;
|
|
126
123
|
|
|
127
124
|
try {
|
|
128
|
-
let credential = await this.
|
|
125
|
+
let credential = await this.credentialsAPI.getToken(
|
|
129
126
|
credentialId,
|
|
130
127
|
companyId
|
|
131
128
|
);
|
|
132
129
|
|
|
133
|
-
|
|
130
|
+
logger.debug(`${documentId} - trying Delete `, {
|
|
134
131
|
query,
|
|
135
132
|
});
|
|
136
133
|
response = await superagent
|
|
@@ -144,23 +141,22 @@ export class LinkedInApiClient {
|
|
|
144
141
|
'LinkedIn-Version': '202305',
|
|
145
142
|
});
|
|
146
143
|
|
|
147
|
-
|
|
144
|
+
logger.info(
|
|
148
145
|
`Native Linkedin API Delete Comment Response for documentId ${documentId}`,
|
|
149
146
|
{ status: response.status, ok: response.ok }
|
|
150
147
|
);
|
|
151
148
|
} catch (err) {
|
|
149
|
+
let errorText = '';
|
|
152
150
|
if (err && err.response && err.response.text) {
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
);
|
|
151
|
+
errorText = `Call to linkedin api with documentId ${documentId} failed`;
|
|
152
|
+
logger.error(errorText, {
|
|
153
|
+
message: JSON.parse(err.response.text),
|
|
154
|
+
});
|
|
157
155
|
} else {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
err
|
|
161
|
-
);
|
|
156
|
+
errorText = `Call to linkedin api with documentId ${documentId} failed`;
|
|
157
|
+
logger.error(errorText, err);
|
|
162
158
|
}
|
|
163
|
-
throw
|
|
159
|
+
throw new Error(errorText);
|
|
164
160
|
}
|
|
165
161
|
return response;
|
|
166
162
|
}
|
|
@@ -222,7 +218,7 @@ export class LinkedInApiClient {
|
|
|
222
218
|
// data-listener -> linkedin_api.client sendComment
|
|
223
219
|
let response, updatedDocument;
|
|
224
220
|
try {
|
|
225
|
-
let credential = await this.
|
|
221
|
+
let credential = await this.credentialsAPI.getToken(
|
|
226
222
|
credentialId,
|
|
227
223
|
companyId
|
|
228
224
|
);
|
|
@@ -244,52 +240,13 @@ export class LinkedInApiClient {
|
|
|
244
240
|
status: 200,
|
|
245
241
|
message: JSON.parse(response.text),
|
|
246
242
|
};
|
|
247
|
-
|
|
248
|
-
//markMessageAsSuccess
|
|
249
|
-
let findQuery = { documentId };
|
|
250
|
-
findQuery['systemData.policies.storage.privateTo'] = companyId;
|
|
251
|
-
let updateQuery = {};
|
|
252
|
-
const { $URN: externalId, actor } = response.message;
|
|
253
|
-
|
|
254
|
-
updateQuery['systemData.status'] = DOCUMENT_STATUS.SUCCESS;
|
|
255
|
-
updateQuery['authors[0].authorInfo.externalId'] = actor;
|
|
256
|
-
updateQuery['metaData.externalId'] = externalId;
|
|
257
|
-
updateQuery.documentId = Buffer.from(`${externalId}`).toString(
|
|
258
|
-
'base64'
|
|
259
|
-
);
|
|
260
|
-
|
|
261
|
-
updatedDocument = await messagesRepository.updateOne(
|
|
262
|
-
findQuery,
|
|
263
|
-
updateQuery
|
|
264
|
-
);
|
|
265
243
|
} catch (err) {
|
|
266
|
-
|
|
244
|
+
logger.error(
|
|
267
245
|
documentId + ' - exception linkedin publish ' + err,
|
|
268
246
|
err
|
|
269
247
|
);
|
|
270
|
-
|
|
271
|
-
let findQuery = { documentId };
|
|
272
|
-
findQuery['systemData.policies.storage.privateTo'] = companyId;
|
|
273
|
-
let updateQuery = {};
|
|
274
|
-
updateQuery['systemData.status'] = DOCUMENT_STATUS.FAILED;
|
|
275
|
-
updateQuery['systemData.error'] =
|
|
276
|
-
err && err.response && err.response.error
|
|
277
|
-
? err.response.error
|
|
278
|
-
: err;
|
|
279
|
-
updatedDocument = await messagesRepository.updateOne(
|
|
280
|
-
findQuery,
|
|
281
|
-
updateQuery
|
|
282
|
-
);
|
|
283
248
|
}
|
|
284
249
|
|
|
285
|
-
//sendNotification -> needs to wait for temp document to reach user
|
|
286
|
-
setTimeout(() => {
|
|
287
|
-
PushRepository.publish(
|
|
288
|
-
`${companyId}-${documentId}`,
|
|
289
|
-
updatedDocument
|
|
290
|
-
);
|
|
291
|
-
}, 5000);
|
|
292
|
-
|
|
293
250
|
return response;
|
|
294
251
|
}
|
|
295
252
|
|
|
@@ -310,7 +267,7 @@ export class LinkedInApiClient {
|
|
|
310
267
|
|
|
311
268
|
let response;
|
|
312
269
|
try {
|
|
313
|
-
let credential = await this.
|
|
270
|
+
let credential = await this.credentialsAPI.getToken(
|
|
314
271
|
credentialId,
|
|
315
272
|
companyId
|
|
316
273
|
);
|
|
@@ -334,7 +291,7 @@ export class LinkedInApiClient {
|
|
|
334
291
|
};
|
|
335
292
|
return response;
|
|
336
293
|
} catch (err) {
|
|
337
|
-
|
|
294
|
+
logger.error(
|
|
338
295
|
documentId + ' - exception linkedin media register ' + err,
|
|
339
296
|
err
|
|
340
297
|
);
|
|
@@ -362,16 +319,14 @@ export class LinkedInApiClient {
|
|
|
362
319
|
})
|
|
363
320
|
.then((result) => result.body);
|
|
364
321
|
} catch (error) {
|
|
365
|
-
|
|
322
|
+
logger.error(
|
|
366
323
|
`Failed requesting LinkedIn API for profileId ${urn}`,
|
|
367
324
|
error
|
|
368
325
|
);
|
|
369
326
|
return;
|
|
370
327
|
}
|
|
371
328
|
|
|
372
|
-
|
|
373
|
-
`Finished requesting LinkedIn API for profileId ${urn}`
|
|
374
|
-
);
|
|
329
|
+
logger.info(`Finished requesting LinkedIn API for profileId ${urn}`);
|
|
375
330
|
|
|
376
331
|
return profile;
|
|
377
332
|
}
|
|
@@ -397,13 +352,13 @@ export class LinkedInApiClient {
|
|
|
397
352
|
})
|
|
398
353
|
.then((result) => result.body);
|
|
399
354
|
} catch (error) {
|
|
400
|
-
|
|
355
|
+
logger.error(
|
|
401
356
|
`Failed requesting LinkedIn API for organizationId ${urn}`,
|
|
402
357
|
error
|
|
403
358
|
);
|
|
404
359
|
}
|
|
405
360
|
|
|
406
|
-
|
|
361
|
+
logger.info(
|
|
407
362
|
`Finished requesting LinkedIn API for organizationId ${urn}`
|
|
408
363
|
);
|
|
409
364
|
|
|
@@ -429,14 +384,14 @@ export class LinkedInApiClient {
|
|
|
429
384
|
'LinkedIn-Version': '202305',
|
|
430
385
|
});
|
|
431
386
|
} catch (error) {
|
|
432
|
-
|
|
387
|
+
logger.error('Error in getAllStats ' + error, error);
|
|
433
388
|
}
|
|
434
389
|
|
|
435
390
|
let { commentSummary, reactionSummaries } = response.body || {};
|
|
436
391
|
if (commentSummary && reactionSummaries) {
|
|
437
392
|
return { commentSummary, reactionSummaries };
|
|
438
393
|
} else {
|
|
439
|
-
|
|
394
|
+
logger.error(
|
|
440
395
|
`Invalid response getting all Linkedin Stats for externalId = ${externalId} ` +
|
|
441
396
|
response,
|
|
442
397
|
response
|
|
@@ -457,14 +412,14 @@ export class LinkedInApiClient {
|
|
|
457
412
|
reactionSummaries,
|
|
458
413
|
};
|
|
459
414
|
} catch (error) {
|
|
460
|
-
|
|
415
|
+
logger.error('Error in getSocialStats: ' + error, error);
|
|
461
416
|
}
|
|
462
417
|
}
|
|
463
418
|
|
|
464
419
|
async getImageMedia(mediaId, credentialId, companyId) {
|
|
465
420
|
let response = {};
|
|
466
421
|
|
|
467
|
-
let credential = await this.
|
|
422
|
+
let credential = await this.credentialsAPI.getToken(
|
|
468
423
|
credentialId,
|
|
469
424
|
companyId
|
|
470
425
|
);
|
|
@@ -492,14 +447,14 @@ export class LinkedInApiClient {
|
|
|
492
447
|
'LinkedIn-Version': '202305',
|
|
493
448
|
});
|
|
494
449
|
} catch (error) {
|
|
495
|
-
|
|
450
|
+
logger.error('Error in getImageMedia ' + error, error);
|
|
496
451
|
}
|
|
497
452
|
|
|
498
453
|
let { downloadUrl } = response.body || {};
|
|
499
454
|
if (downloadUrl) {
|
|
500
455
|
return { downloadUrl };
|
|
501
456
|
} else {
|
|
502
|
-
|
|
457
|
+
logger.error(
|
|
503
458
|
`Invalid response getting Linkedin media for mediaId = ${mediaId} ` +
|
|
504
459
|
response,
|
|
505
460
|
response
|
|
@@ -512,7 +467,7 @@ export class LinkedInApiClient {
|
|
|
512
467
|
let response = {};
|
|
513
468
|
let tempValue;
|
|
514
469
|
|
|
515
|
-
let credential = await this.
|
|
470
|
+
let credential = await this.credentialsAPI.getToken(
|
|
516
471
|
credentialId,
|
|
517
472
|
companyId
|
|
518
473
|
);
|
|
@@ -548,14 +503,14 @@ export class LinkedInApiClient {
|
|
|
548
503
|
'LinkedIn-Version': '202305',
|
|
549
504
|
});
|
|
550
505
|
} catch (error) {
|
|
551
|
-
|
|
506
|
+
logger.error('Error in getVideoMedia ' + error, error);
|
|
552
507
|
}
|
|
553
508
|
|
|
554
509
|
let { thumbnail, downloadUrl } = response.body || {};
|
|
555
510
|
if (downloadUrl) {
|
|
556
511
|
return { thumbnail, downloadUrl };
|
|
557
512
|
} else {
|
|
558
|
-
|
|
513
|
+
logger.error(
|
|
559
514
|
`Invalid response getting Linkedin media for mediaId = ${mediaId} ` +
|
|
560
515
|
response,
|
|
561
516
|
response
|
|
@@ -596,7 +551,7 @@ export class LinkedInApiClient {
|
|
|
596
551
|
|
|
597
552
|
return {};
|
|
598
553
|
} catch (error) {
|
|
599
|
-
|
|
554
|
+
logger.error('Error in getMedia: ' + error, error);
|
|
600
555
|
}
|
|
601
556
|
}
|
|
602
557
|
|
|
@@ -608,7 +563,7 @@ export class LinkedInApiClient {
|
|
|
608
563
|
) {
|
|
609
564
|
let result;
|
|
610
565
|
try {
|
|
611
|
-
let credential = await this.
|
|
566
|
+
let credential = await this.credentialsAPI.getToken(
|
|
612
567
|
credentialId,
|
|
613
568
|
companyId
|
|
614
569
|
);
|
|
@@ -630,7 +585,7 @@ export class LinkedInApiClient {
|
|
|
630
585
|
})
|
|
631
586
|
.then((result) => result.body);
|
|
632
587
|
} catch (error) {
|
|
633
|
-
|
|
588
|
+
logger.error('Error in getLikesByUser: ' + error, error);
|
|
634
589
|
return false;
|
|
635
590
|
}
|
|
636
591
|
return true;
|
|
@@ -639,7 +594,7 @@ export class LinkedInApiClient {
|
|
|
639
594
|
async uploadMedia(query) {
|
|
640
595
|
const { socialAccountId, url, token, data } = query;
|
|
641
596
|
|
|
642
|
-
|
|
597
|
+
logger.info(
|
|
643
598
|
`Starting to upload media to linkedin for ${socialAccountId}`,
|
|
644
599
|
{ url: query.url }
|
|
645
600
|
);
|
|
@@ -657,7 +612,7 @@ export class LinkedInApiClient {
|
|
|
657
612
|
})
|
|
658
613
|
.send(data)
|
|
659
614
|
.catch((err) => {
|
|
660
|
-
|
|
615
|
+
logger.error(err);
|
|
661
616
|
throw err;
|
|
662
617
|
});
|
|
663
618
|
}
|
|
@@ -0,0 +1,477 @@
|
|
|
1
|
+
import superagent from 'superagent';
|
|
2
|
+
import configuration from '../../lib/configuration.js';
|
|
3
|
+
import logger from '../../lib/logger.js';
|
|
4
|
+
import { removePrefix } from '../../lib/externalId.helpers.js';
|
|
5
|
+
import { CredentialsApiClient } from '../http/credentialsApi.client.js';
|
|
6
|
+
|
|
7
|
+
export class TikTokApiClient {
|
|
8
|
+
constructor() {
|
|
9
|
+
this.tiktokURL = configuration.get('TIKTOK_API_URL');
|
|
10
|
+
this.credentialsAPI = new CredentialsApiClient();
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
async getAuthorization(document) {
|
|
14
|
+
const {
|
|
15
|
+
documentId,
|
|
16
|
+
systemData: {
|
|
17
|
+
connectionsCredential: credentialId,
|
|
18
|
+
policies: { storage: { privateTo: companyId } = {} } = {},
|
|
19
|
+
} = {},
|
|
20
|
+
} = document;
|
|
21
|
+
|
|
22
|
+
try {
|
|
23
|
+
const credential = await this.credentialsAPI.getToken(
|
|
24
|
+
credentialId,
|
|
25
|
+
companyId
|
|
26
|
+
);
|
|
27
|
+
return `${credential.token}`;
|
|
28
|
+
} catch (error) {
|
|
29
|
+
logger.error(
|
|
30
|
+
`${documentId} - error getting tiktok token - ${error.code}`,
|
|
31
|
+
error
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
async sendPost({
|
|
37
|
+
paramString = '',
|
|
38
|
+
headers = {},
|
|
39
|
+
document,
|
|
40
|
+
postData = undefined,
|
|
41
|
+
}) {
|
|
42
|
+
let response = {};
|
|
43
|
+
try {
|
|
44
|
+
response = await superagent
|
|
45
|
+
.post(this.tiktokURL + paramString)
|
|
46
|
+
.set('Accept', 'application/json')
|
|
47
|
+
.set('Content-Type', 'application/json')
|
|
48
|
+
.set('Access-Token', await this.getAuthorization(document))
|
|
49
|
+
.send(postData);
|
|
50
|
+
} catch (err) {
|
|
51
|
+
let errorText = '';
|
|
52
|
+
if (
|
|
53
|
+
err &&
|
|
54
|
+
err.response &&
|
|
55
|
+
err.response.body &&
|
|
56
|
+
err.response.body.error
|
|
57
|
+
) {
|
|
58
|
+
errorText = `Failed to call tiktok api for paramString ${paramString}: ${err.response.body.error.message}`;
|
|
59
|
+
logger.error(errorText);
|
|
60
|
+
} else {
|
|
61
|
+
errorText = `Failed to call tiktok api for paramString ${paramString}`;
|
|
62
|
+
logger.error(errorText, err);
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
throw new Error(errorText);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
return response;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// assumes batch calls are using the same credential
|
|
72
|
+
async sendRequest({ paramString = '', headers = {}, document }) {
|
|
73
|
+
let response = {};
|
|
74
|
+
try {
|
|
75
|
+
response = await superagent
|
|
76
|
+
.get(this.tiktokURL + paramString)
|
|
77
|
+
.set('Accept', 'application/json')
|
|
78
|
+
.set('Content-Type', 'application/json')
|
|
79
|
+
.set('Access-Token', await this.getAuthorization(document))
|
|
80
|
+
.send();
|
|
81
|
+
} catch (err) {
|
|
82
|
+
let errorText = '';
|
|
83
|
+
if (
|
|
84
|
+
err &&
|
|
85
|
+
err.response &&
|
|
86
|
+
err.response.body &&
|
|
87
|
+
err.response.body.error
|
|
88
|
+
) {
|
|
89
|
+
errorText = `Failed to call tiktok api for paramString ${paramString}: ${err.response.body.error.message}`;
|
|
90
|
+
logger.error(errorText);
|
|
91
|
+
} else {
|
|
92
|
+
errorText = `Failed to call tiktok api for paramString ${paramString}`;
|
|
93
|
+
logger.error(errorText, err);
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
throw new Error(errorText);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
if (response.status !== 200) {
|
|
100
|
+
logger.error(
|
|
101
|
+
`Failed to call tiktok api for documentId ${documentId}`,
|
|
102
|
+
response.body
|
|
103
|
+
);
|
|
104
|
+
let error = new Error(
|
|
105
|
+
`Failed to call tiktok api for documentId ${documentId}`
|
|
106
|
+
);
|
|
107
|
+
error.code = response.status;
|
|
108
|
+
throw error;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
return response.body;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
async getChannelInfoForDocuments(documents) {
|
|
115
|
+
const channelInfo = await this.getStatsForDocuments(
|
|
116
|
+
documents,
|
|
117
|
+
'metaData.authors.0.authorInfo.externalId',
|
|
118
|
+
{
|
|
119
|
+
og: ['video/list/'],
|
|
120
|
+
}
|
|
121
|
+
);
|
|
122
|
+
return channelInfo;
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
async getStatsForDocuments(
|
|
126
|
+
documents,
|
|
127
|
+
externalIdFrom = 'metaData.externalId',
|
|
128
|
+
paramsByType = {
|
|
129
|
+
og: ['video/list/'],
|
|
130
|
+
}
|
|
131
|
+
) {
|
|
132
|
+
// for batching separate og and comment/reply requests per credential
|
|
133
|
+
const documentsByTypeAndCredentials = documents.reduce(
|
|
134
|
+
(retObj, document, index) => {
|
|
135
|
+
const paramArray =
|
|
136
|
+
paramsByType[document.metaData.discussionType];
|
|
137
|
+
if (paramArray) {
|
|
138
|
+
paramArray.forEach((paramString) => {
|
|
139
|
+
let discussionTypeBucket =
|
|
140
|
+
retObj[
|
|
141
|
+
`${paramString}${document.systemData.connectionsCredential}`
|
|
142
|
+
];
|
|
143
|
+
if (!discussionTypeBucket) {
|
|
144
|
+
discussionTypeBucket = {
|
|
145
|
+
paramString,
|
|
146
|
+
document,
|
|
147
|
+
externalIds: [],
|
|
148
|
+
externalIdToDocumentIndex: {},
|
|
149
|
+
};
|
|
150
|
+
retObj[
|
|
151
|
+
`${paramString}${document.systemData.connectionsCredential}`
|
|
152
|
+
] = discussionTypeBucket;
|
|
153
|
+
}
|
|
154
|
+
const externalIdTrimmed = removePrefix(
|
|
155
|
+
// javascript weirdness to get around '.' notation
|
|
156
|
+
externalIdFrom
|
|
157
|
+
.split('.')
|
|
158
|
+
.reduce((a, b) => a[b], document)
|
|
159
|
+
);
|
|
160
|
+
discussionTypeBucket.externalIds.push(
|
|
161
|
+
externalIdTrimmed
|
|
162
|
+
);
|
|
163
|
+
discussionTypeBucket.externalIdToDocumentIndex[
|
|
164
|
+
externalIdTrimmed
|
|
165
|
+
] = index;
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
return retObj;
|
|
169
|
+
},
|
|
170
|
+
{}
|
|
171
|
+
);
|
|
172
|
+
|
|
173
|
+
const sortedResults = Array(documents.length).fill();
|
|
174
|
+
await Promise.all(
|
|
175
|
+
Object.values(documentsByTypeAndCredentials).map(
|
|
176
|
+
async (documentsByTypeAndCredential) => {
|
|
177
|
+
if (documentsByTypeAndCredential.externalIds.length) {
|
|
178
|
+
const {
|
|
179
|
+
metaData: {
|
|
180
|
+
inReplyTo: { profileId: business_id },
|
|
181
|
+
},
|
|
182
|
+
} = documentsByTypeAndCredential.document;
|
|
183
|
+
const trimmedBusinessId = removePrefix(business_id);
|
|
184
|
+
const requestResult = await this.sendRequest({
|
|
185
|
+
paramString: `${
|
|
186
|
+
documentsByTypeAndCredential.paramString
|
|
187
|
+
}?business_id=${trimmedBusinessId}&fields=["item_id","create_time","thumbnail_url","share_url","embed_url","caption","video_views","likes","comments","shares"]&filters=${JSON.stringify(
|
|
188
|
+
{
|
|
189
|
+
video_ids:
|
|
190
|
+
documentsByTypeAndCredential.externalIds,
|
|
191
|
+
}
|
|
192
|
+
)}`,
|
|
193
|
+
document: documentsByTypeAndCredential.document,
|
|
194
|
+
});
|
|
195
|
+
requestResult.data.videos.forEach(
|
|
196
|
+
({
|
|
197
|
+
item_id,
|
|
198
|
+
create_time,
|
|
199
|
+
thumbnail_url,
|
|
200
|
+
share_url,
|
|
201
|
+
embed_url,
|
|
202
|
+
caption,
|
|
203
|
+
video_views,
|
|
204
|
+
likes,
|
|
205
|
+
comments,
|
|
206
|
+
shares,
|
|
207
|
+
...args
|
|
208
|
+
}) => {
|
|
209
|
+
const documentIndex =
|
|
210
|
+
documentsByTypeAndCredential
|
|
211
|
+
.externalIdToDocumentIndex[item_id];
|
|
212
|
+
sortedResults[documentIndex] = {
|
|
213
|
+
...sortedResults[documentIndex],
|
|
214
|
+
item_id,
|
|
215
|
+
create_time,
|
|
216
|
+
thumbnail_url,
|
|
217
|
+
externalId:
|
|
218
|
+
documents[documentIndex].metaData
|
|
219
|
+
.externalId,
|
|
220
|
+
share_url,
|
|
221
|
+
embed_url,
|
|
222
|
+
caption,
|
|
223
|
+
video_views,
|
|
224
|
+
likes,
|
|
225
|
+
comments,
|
|
226
|
+
shares,
|
|
227
|
+
};
|
|
228
|
+
}
|
|
229
|
+
);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
)
|
|
233
|
+
);
|
|
234
|
+
return sortedResults;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
async publish(message, videoId, markMessageAsCompleteDocumentId) {
|
|
238
|
+
const {
|
|
239
|
+
metaData: { discussionType },
|
|
240
|
+
} = message;
|
|
241
|
+
let publishedMessage;
|
|
242
|
+
|
|
243
|
+
switch (discussionType) {
|
|
244
|
+
case 'qt':
|
|
245
|
+
publishedMessage = await this.insertComment(message);
|
|
246
|
+
break;
|
|
247
|
+
case 're':
|
|
248
|
+
publishedMessage = await this.insertReply(
|
|
249
|
+
videoId,
|
|
250
|
+
message,
|
|
251
|
+
markMessageAsCompleteDocumentId
|
|
252
|
+
);
|
|
253
|
+
break;
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
return publishedMessage;
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
async insertComment(document) {
|
|
260
|
+
const {
|
|
261
|
+
body: {
|
|
262
|
+
content: { text: text },
|
|
263
|
+
},
|
|
264
|
+
metaData: {
|
|
265
|
+
source: { id: business_id },
|
|
266
|
+
inReplyTo: { id: video_id },
|
|
267
|
+
},
|
|
268
|
+
} = document;
|
|
269
|
+
const { body: publishedMessage } =
|
|
270
|
+
(await this.sendPost({
|
|
271
|
+
paramString: 'comment/create/',
|
|
272
|
+
postData: {
|
|
273
|
+
business_id,
|
|
274
|
+
video_id,
|
|
275
|
+
text,
|
|
276
|
+
},
|
|
277
|
+
document,
|
|
278
|
+
})) || {};
|
|
279
|
+
return publishedMessage;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
async insertReply(videoId, document, markMessageAsCompleteDocumentId) {
|
|
283
|
+
const {
|
|
284
|
+
body: {
|
|
285
|
+
content: { text: text },
|
|
286
|
+
},
|
|
287
|
+
metaData: {
|
|
288
|
+
inReplyTo: { id: comment_id, profileId: business_id },
|
|
289
|
+
},
|
|
290
|
+
} = document;
|
|
291
|
+
|
|
292
|
+
const { body: publishedMessage } =
|
|
293
|
+
(await this.sendPost({
|
|
294
|
+
paramString: 'comment/reply/create/',
|
|
295
|
+
postData: {
|
|
296
|
+
business_id: document.metaData.source.id,
|
|
297
|
+
comment_id: markMessageAsCompleteDocumentId || comment_id,
|
|
298
|
+
video_id: removePrefix(videoId),
|
|
299
|
+
text,
|
|
300
|
+
},
|
|
301
|
+
document,
|
|
302
|
+
})) || {};
|
|
303
|
+
|
|
304
|
+
return publishedMessage;
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
async toggleLike(document) {
|
|
308
|
+
const {
|
|
309
|
+
enrichments: {
|
|
310
|
+
socialScores: { tt_liked_by_user: likedByUser },
|
|
311
|
+
},
|
|
312
|
+
} = document;
|
|
313
|
+
|
|
314
|
+
try {
|
|
315
|
+
let likeResponse = await (!likedByUser
|
|
316
|
+
? this.like(document)
|
|
317
|
+
: this.unlike(document));
|
|
318
|
+
return likeResponse;
|
|
319
|
+
} catch (error) {
|
|
320
|
+
logger.error(`${document} - error recieved - ${error.code}`, error);
|
|
321
|
+
throw error;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
async toggleHide(document) {
|
|
326
|
+
const {
|
|
327
|
+
documentId,
|
|
328
|
+
appData: { hidden: hiddenOnNative },
|
|
329
|
+
} = document;
|
|
330
|
+
|
|
331
|
+
let response;
|
|
332
|
+
try {
|
|
333
|
+
if (hiddenOnNative) {
|
|
334
|
+
response = await this.hide(document);
|
|
335
|
+
} else {
|
|
336
|
+
response = await this.unhide(document);
|
|
337
|
+
}
|
|
338
|
+
logger.info(
|
|
339
|
+
`Native Tiktok API Hide Response for documentId ${documentId}`,
|
|
340
|
+
{ status: response.status, ok: response.ok }
|
|
341
|
+
);
|
|
342
|
+
|
|
343
|
+
if (response.message === 'OK') {
|
|
344
|
+
return response;
|
|
345
|
+
}
|
|
346
|
+
} catch (error) {
|
|
347
|
+
logger.error(
|
|
348
|
+
`${documentId} - error recieved - ${error.code}`,
|
|
349
|
+
error
|
|
350
|
+
);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
async like(document) {
|
|
355
|
+
const {
|
|
356
|
+
metaData: {
|
|
357
|
+
externalId: comment_id,
|
|
358
|
+
source: { id: sourceId },
|
|
359
|
+
},
|
|
360
|
+
} = document;
|
|
361
|
+
const { body: publishedMessage } =
|
|
362
|
+
(await this.sendPost({
|
|
363
|
+
paramString: 'comment/like/',
|
|
364
|
+
postData: {
|
|
365
|
+
business_id: removePrefix(sourceId),
|
|
366
|
+
comment_id: removePrefix(comment_id),
|
|
367
|
+
action: 'LIKE',
|
|
368
|
+
},
|
|
369
|
+
document,
|
|
370
|
+
})) || {};
|
|
371
|
+
return publishedMessage;
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
async unlike(document) {
|
|
375
|
+
const {
|
|
376
|
+
metaData: {
|
|
377
|
+
inReplyTo: { id: comment_id },
|
|
378
|
+
source: { id: sourceId },
|
|
379
|
+
},
|
|
380
|
+
} = document;
|
|
381
|
+
const { body: publishedMessage } =
|
|
382
|
+
(await this.sendPost({
|
|
383
|
+
paramString: 'comment/like/',
|
|
384
|
+
postData: {
|
|
385
|
+
business_id: removePrefix(sourceId),
|
|
386
|
+
comment_id: removePrefix(comment_id),
|
|
387
|
+
action: 'unlike',
|
|
388
|
+
},
|
|
389
|
+
document,
|
|
390
|
+
})) || {};
|
|
391
|
+
return publishedMessage;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
async hide(document) {
|
|
395
|
+
const {
|
|
396
|
+
metaData: {
|
|
397
|
+
externalId: comment_id,
|
|
398
|
+
source: { id: sourceId },
|
|
399
|
+
inReplyTo: { id: video_id },
|
|
400
|
+
},
|
|
401
|
+
} = document;
|
|
402
|
+
const { body: publishedMessage } =
|
|
403
|
+
(await this.sendPost({
|
|
404
|
+
paramString: 'comment/hide/',
|
|
405
|
+
postData: {
|
|
406
|
+
business_id: removePrefix(sourceId),
|
|
407
|
+
comment_id: removePrefix(comment_id),
|
|
408
|
+
video_id: removePrefix(video_id),
|
|
409
|
+
action: 'HIDE',
|
|
410
|
+
},
|
|
411
|
+
document,
|
|
412
|
+
})) || {};
|
|
413
|
+
return publishedMessage;
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
async unhide(document) {
|
|
417
|
+
const {
|
|
418
|
+
metaData: {
|
|
419
|
+
externalId: comment_id,
|
|
420
|
+
source: { id: sourceId },
|
|
421
|
+
inReplyTo: { id: video_id },
|
|
422
|
+
},
|
|
423
|
+
} = document;
|
|
424
|
+
const { body: publishedMessage } =
|
|
425
|
+
(await this.sendPost({
|
|
426
|
+
paramString: 'comment/hide/',
|
|
427
|
+
postData: {
|
|
428
|
+
business_id: removePrefix(sourceId),
|
|
429
|
+
comment_id: removePrefix(comment_id),
|
|
430
|
+
video_id: removePrefix(video_id),
|
|
431
|
+
action: 'UNHIDE',
|
|
432
|
+
},
|
|
433
|
+
document,
|
|
434
|
+
})) || {};
|
|
435
|
+
return publishedMessage;
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
async deleteComment(document) {
|
|
439
|
+
const {
|
|
440
|
+
metaData: {
|
|
441
|
+
inReplyTo: { id: comment_id, profileId: business_id },
|
|
442
|
+
},
|
|
443
|
+
} = document;
|
|
444
|
+
const { body: publishedMessage } =
|
|
445
|
+
(await this.sendPost({
|
|
446
|
+
paramString: 'comment/delete/',
|
|
447
|
+
postData: {
|
|
448
|
+
business_id,
|
|
449
|
+
comment_id,
|
|
450
|
+
},
|
|
451
|
+
document,
|
|
452
|
+
})) || {};
|
|
453
|
+
return publishedMessage;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
async getProfile(business_id, document) {
|
|
457
|
+
const fields = '["username", "display_name", "profile_image"]';
|
|
458
|
+
const profile =
|
|
459
|
+
(await this.sendRequest({
|
|
460
|
+
paramString: `get/?business_id=${business_id}&fields=${fields}`,
|
|
461
|
+
document,
|
|
462
|
+
})) || {};
|
|
463
|
+
return profile;
|
|
464
|
+
}
|
|
465
|
+
|
|
466
|
+
async getPostData(business_id, video_id, document) {
|
|
467
|
+
const fields =
|
|
468
|
+
'["item_id", "thumbnail_url", "create_time", "username", "display_name", "profile_image"]';
|
|
469
|
+
const video_ids = `["${video_id}"]`;
|
|
470
|
+
const profile =
|
|
471
|
+
(await this.sendRequest({
|
|
472
|
+
paramString: `video/list?business_id=${business_id}&fields=${fields}&filters={"video_ids":${video_ids}}`,
|
|
473
|
+
document,
|
|
474
|
+
})) || {};
|
|
475
|
+
return profile;
|
|
476
|
+
}
|
|
477
|
+
}
|
package/src/data-access/index.js
CHANGED
|
@@ -10,6 +10,7 @@ import { InstagramApiClient } from './http/instagramApi.client.js';
|
|
|
10
10
|
import { InstagramVideoClient } from './http/InstagramVideoClient.js';
|
|
11
11
|
import { IRClient } from './http/ir.client.js';
|
|
12
12
|
import { LinkedInApiClient } from './http/linkedInApi.client.js';
|
|
13
|
+
import { TikTokApiClient } from './http/tiktokApi.client.js';
|
|
13
14
|
import { MasfClient } from './http/masf.client.js';
|
|
14
15
|
import { WarpZoneApiClient } from './http/WarpZoneApi.client.js';
|
|
15
16
|
|
|
@@ -26,6 +27,7 @@ export {
|
|
|
26
27
|
InstagramVideoClient,
|
|
27
28
|
IRClient,
|
|
28
29
|
LinkedInApiClient,
|
|
30
|
+
TikTokApiClient,
|
|
29
31
|
MasfClient,
|
|
30
32
|
WarpZoneApiClient,
|
|
31
33
|
};
|