@meltwater/conversations-api-services 1.0.19 → 1.0.21

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/.github/workflows/release.yml +2 -0
  2. package/babel.config.js +18 -0
  3. package/dist/cjs/data-access/http/InstagramVideoClient.js +42 -0
  4. package/dist/cjs/data-access/http/WarpZoneApi.client.js +32 -0
  5. package/dist/cjs/data-access/http/amazonS3.js +44 -0
  6. package/dist/cjs/data-access/http/asset-manager-tvm.client.js +35 -0
  7. package/dist/cjs/data-access/http/companiesApi.client.js +38 -0
  8. package/dist/cjs/data-access/http/credentialsApi.client.js +102 -0
  9. package/dist/cjs/data-access/http/entitlementsApi.client.js +40 -0
  10. package/dist/cjs/data-access/http/facebook.native.js +344 -0
  11. package/dist/cjs/data-access/http/facebookApi.client.js +631 -0
  12. package/dist/cjs/data-access/http/featureToggleApi.client.js +31 -0
  13. package/dist/cjs/data-access/http/identityServices.client.js +97 -0
  14. package/dist/cjs/data-access/http/instagramApi.client.js +428 -0
  15. package/dist/cjs/data-access/http/ir.client.js +242 -0
  16. package/dist/cjs/data-access/http/linkedInApi.client.js +491 -0
  17. package/dist/cjs/data-access/http/masf.client.js +101 -0
  18. package/dist/cjs/data-access/http/tiktok.native.js +162 -0
  19. package/dist/cjs/data-access/http/tiktokApi.client.js +441 -0
  20. package/dist/cjs/data-access/index.js +132 -0
  21. package/dist/cjs/errors/engage-error.js +16 -0
  22. package/dist/cjs/errors/http-error.js +23 -0
  23. package/dist/cjs/lib/applicationTags.helpers.js +30 -0
  24. package/dist/cjs/lib/configuration.js +14 -0
  25. package/dist/cjs/lib/document-action-events.js +12 -0
  26. package/dist/cjs/lib/externalId.helpers.js +19 -0
  27. package/dist/cjs/lib/hidden.helpers.js +13 -0
  28. package/dist/cjs/lib/hiddenComment.helper.js +119 -0
  29. package/dist/cjs/lib/logger.helpers.js +68 -0
  30. package/dist/cjs/lib/logger.js +23 -0
  31. package/dist/cjs/lib/message.helpers.js +58 -0
  32. package/dist/cjs/lib/metrics.helper.js +97 -0
  33. package/dist/esm/data-access/http/InstagramVideoClient.js +34 -0
  34. package/dist/esm/data-access/http/WarpZoneApi.client.js +24 -0
  35. package/dist/esm/data-access/http/amazonS3.js +37 -0
  36. package/dist/esm/data-access/http/asset-manager-tvm.client.js +28 -0
  37. package/dist/esm/data-access/http/companiesApi.client.js +30 -0
  38. package/dist/esm/data-access/http/credentialsApi.client.js +92 -0
  39. package/dist/esm/data-access/http/entitlementsApi.client.js +32 -0
  40. package/dist/esm/data-access/http/facebook.native.js +325 -0
  41. package/dist/esm/data-access/http/facebookApi.client.js +621 -0
  42. package/dist/esm/data-access/http/featureToggleApi.client.js +23 -0
  43. package/dist/esm/data-access/http/identityServices.client.js +89 -0
  44. package/dist/esm/data-access/http/instagramApi.client.js +420 -0
  45. package/dist/esm/data-access/http/ir.client.js +234 -0
  46. package/dist/esm/data-access/http/linkedInApi.client.js +481 -0
  47. package/dist/esm/data-access/http/masf.client.js +93 -0
  48. package/dist/esm/data-access/http/tiktok.native.js +146 -0
  49. package/dist/esm/data-access/http/tiktokApi.client.js +433 -0
  50. package/dist/esm/data-access/index.js +30 -0
  51. package/dist/esm/errors/engage-error.js +9 -0
  52. package/dist/esm/errors/http-error.js +16 -0
  53. package/dist/esm/lib/applicationTags.helpers.js +22 -0
  54. package/dist/esm/lib/configuration.js +8 -0
  55. package/dist/esm/lib/document-action-events.js +6 -0
  56. package/dist/esm/lib/externalId.helpers.js +12 -0
  57. package/dist/esm/lib/hidden.helpers.js +6 -0
  58. package/dist/esm/lib/hiddenComment.helper.js +112 -0
  59. package/dist/esm/lib/logger.helpers.js +60 -0
  60. package/dist/esm/lib/logger.js +16 -0
  61. package/dist/esm/lib/message.helpers.js +52 -0
  62. package/dist/esm/lib/metrics.helper.js +90 -0
  63. package/package.json +14 -4
  64. package/src/data-access/http/facebook.native.js +542 -0
  65. package/src/data-access/http/tiktok.native.js +248 -0
  66. package/src/data-access/index.js +4 -0
  67. package/src/errors/engage-error.js +11 -0
  68. package/src/errors/http-error.js +19 -0
  69. package/src/lib/logger.helpers.js +15 -0
  70. package/src/lib/message.helpers.js +7 -1
@@ -0,0 +1,146 @@
1
+ import superagent from 'superagent';
2
+ import { loggerError } from '../../lib/logger.helpers.js';
3
+ import { removePrefix } from '../../lib/externalId.helpers.js';
4
+ const TIKTOK_API_URL = "https://business-api.tiktok.com/open_api/v1.3/business/";
5
+ export async function comment(token, business_id, video_id, text, logger) {
6
+ const {
7
+ body: publishedMessage
8
+ } = (await sendPost(token, 'comment/create/', {
9
+ business_id: business_id,
10
+ video_id: video_id.startsWith('tt_') ? video_id.split('_')[2] : video_id,
11
+ text
12
+ }, logger)) || {};
13
+ return publishedMessage;
14
+ }
15
+ export async function reply(token, videoId, sourceId, inReplyToId, text, logger) {
16
+ const {
17
+ body: publishedMessage
18
+ } = (await sendPost(token, 'comment/reply/create/', {
19
+ business_id: sourceId,
20
+ comment_id: inReplyToId,
21
+ video_id: removePrefix(videoId),
22
+ text
23
+ }, logger)) || {};
24
+ return publishedMessage;
25
+ }
26
+ export async function like(token, externalId, sourceId, logger) {
27
+ const {
28
+ body: publishedMessage
29
+ } = (await sendPost(token, 'comment/like/', {
30
+ business_id: removePrefix(sourceId),
31
+ comment_id: removePrefix(externalId),
32
+ action: 'LIKE'
33
+ }, logger)) || {};
34
+ return publishedMessage;
35
+ }
36
+
37
+ // Conversations says this is only allowed on Native...
38
+ export async function unlike(token, inReplyToId, sourceId, logger) {
39
+ const {
40
+ body: publishedMessage
41
+ } = (await sendPost(token, 'comment/like/', {
42
+ business_id: removePrefix(sourceId),
43
+ comment_id: removePrefix(inReplyToId),
44
+ action: 'unlike'
45
+ }, logger)) || {};
46
+ return publishedMessage;
47
+ }
48
+
49
+ // Conversations says this is only allowed on Native...
50
+ export async function hide(token, externalId, sourceId, video_id, logger) {
51
+ const {
52
+ body: publishedMessage
53
+ } = (await sendPost(token, 'comment/hide/', {
54
+ business_id: removePrefix(sourceId),
55
+ comment_id: removePrefix(externalId),
56
+ video_id: removePrefix(video_id),
57
+ action: 'HIDE'
58
+ }, logger)) || {};
59
+ return publishedMessage;
60
+ }
61
+ export async function unhide(token, externalId, sourceId, video_id, logger) {
62
+ const {
63
+ body: publishedMessage
64
+ } = (await sendPost(token, 'comment/hide/', {
65
+ business_id: removePrefix(sourceId),
66
+ comment_id: removePrefix(externalId),
67
+ video_id: removePrefix(video_id),
68
+ action: 'UNHIDE'
69
+ }, logger)) || {};
70
+ return publishedMessage;
71
+ }
72
+ export async function deleteComment(token, inReplyToId, profileId, logger) {
73
+ const {
74
+ body: publishedMessage
75
+ } = (await sendPost(token, 'comment/delete/', {
76
+ business_id: profileId,
77
+ comment_id: inReplyToId
78
+ }, logger)) || {};
79
+ return publishedMessage;
80
+ }
81
+ export async function getProfile(token, business_id) {
82
+ let fields = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '["username", "display_name", "profile_image"]';
83
+ let logger = arguments.length > 3 ? arguments[3] : undefined;
84
+ const profile = (await sendRequest(token, `get/?business_id=${business_id}&fields=${fields}`, logger)) || {};
85
+ return profile;
86
+ }
87
+ export async function getStats(token, business_id, externalIds) {
88
+ let paramString = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : 'video/list/';
89
+ let logger = arguments.length > 4 ? arguments[4] : undefined;
90
+ const profile = (await sendRequest(token, `${paramString}?business_id=${business_id}&fields=["item_id","create_time","thumbnail_url","share_url","embed_url","caption","video_views","likes","comments","shares"]&filters=${JSON.stringify({
91
+ video_ids: externalIds
92
+ })}`, logger)) || {};
93
+ return profile;
94
+ }
95
+
96
+ // This doesn't appear to be used in Conversations either
97
+ export async function getPostData(token, business_id, video_id) {
98
+ let fields = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : '["item_id", "thumbnail_url", "create_time", "username", "display_name", "profile_image"]';
99
+ let logger = arguments.length > 4 ? arguments[4] : undefined;
100
+ const video_ids = `["${video_id}"]`;
101
+ const profile = (await sendRequest(token, `video/list?business_id=${business_id}&fields=${fields}&filters={"video_ids":${video_ids}}`, logger)) || {};
102
+ return profile;
103
+ }
104
+
105
+ // assumes batch calls are using the same credential
106
+ async function sendRequest(token) {
107
+ let paramString = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
108
+ let logger = arguments.length > 2 ? arguments[2] : undefined;
109
+ let response = {};
110
+ try {
111
+ response = await superagent.get(TIKTOK_API_URL + paramString).set('Accept', 'application/json').set('Content-Type', 'application/json').set('Access-Token', token).send();
112
+ } catch (err) {
113
+ if (err && err.response && err.response.body && err.response.body.error) {
114
+ loggerError(logger, `Failed to call tiktok api for paramString ${paramString}: ${err.response.body.error.message}`);
115
+ } else {
116
+ loggerError(logger, `Failed to call tiktok api for paramString ${paramString}`, err);
117
+ }
118
+ throw err;
119
+ }
120
+ if (response.status !== 200) {
121
+ loggerError(logger, `Failed to call tiktok api`, {
122
+ responseBody: JSON.stringify(response.body)
123
+ });
124
+ let error = new Error(`Failed to call tiktok api`);
125
+ error.code = response.status;
126
+ throw error;
127
+ }
128
+ return response.body;
129
+ }
130
+ async function sendPost(token) {
131
+ let paramString = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '';
132
+ let postData = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : undefined;
133
+ let logger = arguments.length > 3 ? arguments[3] : undefined;
134
+ let response = {};
135
+ try {
136
+ response = await superagent.post(TIKTOK_API_URL + paramString).set('Accept', 'application/json').set('Content-Type', 'application/json').set('Access-Token', token).send(postData);
137
+ } catch (err) {
138
+ if (err && err.response && err.response.body && err.response.body.error) {
139
+ loggerError(logger, `Failed to call tiktok api for paramString ${paramString}: ${err.response.body.error.message}`);
140
+ } else {
141
+ loggerError(logger, `Failed to call tiktok api for paramString ${paramString}`, err);
142
+ }
143
+ throw err;
144
+ }
145
+ return response;
146
+ }
@@ -0,0 +1,433 @@
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
+ import { MeltwaterAttributes } from '../../lib/logger.helpers.js';
7
+ export class TikTokApiClient {
8
+ constructor() {
9
+ this.tiktokURL = configuration.get('TIKTOK_API_URL');
10
+ this.credentialsAPI = new CredentialsApiClient();
11
+ }
12
+ async getAuthorization(document) {
13
+ const {
14
+ documentId,
15
+ systemData: {
16
+ connectionsCredential: credentialId,
17
+ policies: {
18
+ storage: {
19
+ privateTo: companyId
20
+ } = {}
21
+ } = {}
22
+ } = {}
23
+ } = document;
24
+ try {
25
+ const credential = await this.credentialsAPI.getToken(credentialId, companyId);
26
+ return `${credential.token}`;
27
+ } catch (error) {
28
+ logger.error(`${documentId} - error getting tiktok token - ${error.code}`, error, {
29
+ [MeltwaterAttributes.DOCUMENTID]: documentId,
30
+ [MeltwaterAttributes.COMPANYID]: companyId,
31
+ [MeltwaterAttributes.CREDENTIALID]: credentialId
32
+ });
33
+ }
34
+ }
35
+ async sendPost(_ref) {
36
+ let {
37
+ paramString = '',
38
+ headers = {},
39
+ document,
40
+ postData = undefined
41
+ } = _ref;
42
+ let response = {};
43
+ try {
44
+ response = await superagent.post(this.tiktokURL + paramString).set('Accept', 'application/json').set('Content-Type', 'application/json').set('Access-Token', await this.getAuthorization(document)).send(postData);
45
+ } catch (err) {
46
+ let errorText = '';
47
+ if (err && err.response && err.response.body && err.response.body.error) {
48
+ errorText = `Failed to call tiktok api for paramString ${paramString}: ${err.response.body.error.message}`;
49
+ logger.error(errorText);
50
+ } else {
51
+ errorText = `Failed to call tiktok api for paramString ${paramString}`;
52
+ logger.error(errorText, err);
53
+ }
54
+ throw new Error(errorText);
55
+ }
56
+ return response;
57
+ }
58
+
59
+ // assumes batch calls are using the same credential
60
+ async sendRequest(_ref2) {
61
+ let {
62
+ paramString = '',
63
+ headers = {},
64
+ document
65
+ } = _ref2;
66
+ let response = {};
67
+ try {
68
+ response = await superagent.get(this.tiktokURL + paramString).set('Accept', 'application/json').set('Content-Type', 'application/json').set('Access-Token', await this.getAuthorization(document)).send();
69
+ } catch (err) {
70
+ let errorText = '';
71
+ if (err && err.response && err.response.body && err.response.body.error) {
72
+ errorText = `Failed to call tiktok api for paramString ${paramString}: ${err.response.body.error.message}`;
73
+ logger.error(errorText);
74
+ } else {
75
+ errorText = `Failed to call tiktok api for paramString ${paramString}`;
76
+ logger.error(errorText, err);
77
+ }
78
+ throw new Error(errorText);
79
+ }
80
+ if (response.status !== 200) {
81
+ logger.error(`Failed to call tiktok api for documentId ${document.documentId}`, response.body, {
82
+ [MeltwaterAttributes.DOCUMENTID]: document.documentId
83
+ });
84
+ let error = new Error(`Failed to call tiktok api for documentId ${document.documentId}`);
85
+ error.code = response.status;
86
+ throw error;
87
+ }
88
+ return response.body;
89
+ }
90
+ async getChannelInfoForDocuments(documents) {
91
+ const channelInfo = await this.getStatsForDocuments(documents, 'metaData.authors.0.authorInfo.externalId', {
92
+ og: ['video/list/']
93
+ });
94
+ return channelInfo;
95
+ }
96
+ async getStatsForDocuments(documents) {
97
+ let externalIdFrom = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'metaData.externalId';
98
+ let paramsByType = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {
99
+ og: ['video/list/']
100
+ };
101
+ // for batching separate og and comment/reply requests per credential
102
+ const documentsByTypeAndCredentials = documents.reduce((retObj, document, index) => {
103
+ const paramArray = paramsByType[document.metaData.discussionType];
104
+ if (paramArray) {
105
+ paramArray.forEach(paramString => {
106
+ let discussionTypeBucket = retObj[`${paramString}${document.systemData.connectionsCredential}`];
107
+ if (!discussionTypeBucket) {
108
+ discussionTypeBucket = {
109
+ paramString,
110
+ document,
111
+ externalIds: [],
112
+ externalIdToDocumentIndex: {}
113
+ };
114
+ retObj[`${paramString}${document.systemData.connectionsCredential}`] = discussionTypeBucket;
115
+ }
116
+ const externalIdTrimmed = removePrefix(
117
+ // javascript weirdness to get around '.' notation
118
+ externalIdFrom.split('.').reduce((a, b) => a[b], document));
119
+ discussionTypeBucket.externalIds.push(externalIdTrimmed);
120
+ discussionTypeBucket.externalIdToDocumentIndex[externalIdTrimmed] = index;
121
+ });
122
+ }
123
+ return retObj;
124
+ }, {});
125
+ const sortedResults = Array(documents.length).fill();
126
+ await Promise.all(Object.values(documentsByTypeAndCredentials).map(async documentsByTypeAndCredential => {
127
+ if (documentsByTypeAndCredential.externalIds.length) {
128
+ const {
129
+ metaData: {
130
+ inReplyTo: {
131
+ profileId: business_id
132
+ }
133
+ }
134
+ } = documentsByTypeAndCredential.document;
135
+ const trimmedBusinessId = removePrefix(business_id);
136
+ const requestResult = await this.sendRequest({
137
+ paramString: `${documentsByTypeAndCredential.paramString}?business_id=${trimmedBusinessId}&fields=["item_id","create_time","thumbnail_url","share_url","embed_url","caption","video_views","likes","comments","shares"]&filters=${JSON.stringify({
138
+ video_ids: documentsByTypeAndCredential.externalIds
139
+ })}`,
140
+ document: documentsByTypeAndCredential.document
141
+ });
142
+ requestResult.data.videos.forEach(_ref3 => {
143
+ let {
144
+ item_id,
145
+ create_time,
146
+ thumbnail_url,
147
+ share_url,
148
+ embed_url,
149
+ caption,
150
+ video_views,
151
+ likes,
152
+ comments,
153
+ shares,
154
+ ...args
155
+ } = _ref3;
156
+ const documentIndex = documentsByTypeAndCredential.externalIdToDocumentIndex[item_id];
157
+ sortedResults[documentIndex] = {
158
+ ...sortedResults[documentIndex],
159
+ item_id,
160
+ create_time,
161
+ thumbnail_url,
162
+ externalId: documents[documentIndex].metaData.externalId,
163
+ share_url,
164
+ embed_url,
165
+ caption,
166
+ video_views,
167
+ likes,
168
+ comments,
169
+ shares
170
+ };
171
+ });
172
+ }
173
+ }));
174
+ return sortedResults;
175
+ }
176
+ async publish(message, videoId, markMessageAsCompleteDocumentId) {
177
+ const {
178
+ metaData: {
179
+ discussionType
180
+ }
181
+ } = message;
182
+ let publishedMessage;
183
+ switch (discussionType) {
184
+ case 'qt':
185
+ publishedMessage = await this.insertComment(message);
186
+ break;
187
+ case 're':
188
+ publishedMessage = await this.insertReply(videoId, message, markMessageAsCompleteDocumentId);
189
+ break;
190
+ }
191
+ return publishedMessage;
192
+ }
193
+ async insertComment(document) {
194
+ const {
195
+ body: {
196
+ content: {
197
+ text: text
198
+ }
199
+ },
200
+ metaData: {
201
+ source: {
202
+ id: business_id
203
+ },
204
+ inReplyTo: {
205
+ id: video_id
206
+ }
207
+ }
208
+ } = document;
209
+ const {
210
+ body: publishedMessage
211
+ } = (await this.sendPost({
212
+ paramString: 'comment/create/',
213
+ postData: {
214
+ business_id,
215
+ video_id,
216
+ text
217
+ },
218
+ document
219
+ })) || {};
220
+ return publishedMessage;
221
+ }
222
+ async insertReply(videoId, document, markMessageAsCompleteDocumentId) {
223
+ const {
224
+ body: {
225
+ content: {
226
+ text: text
227
+ }
228
+ },
229
+ metaData: {
230
+ inReplyTo: {
231
+ id: comment_id,
232
+ profileId: business_id
233
+ }
234
+ }
235
+ } = document;
236
+ const {
237
+ body: publishedMessage
238
+ } = (await this.sendPost({
239
+ paramString: 'comment/reply/create/',
240
+ postData: {
241
+ business_id: document.metaData.source.id,
242
+ comment_id: markMessageAsCompleteDocumentId || comment_id,
243
+ video_id: removePrefix(videoId),
244
+ text
245
+ },
246
+ document
247
+ })) || {};
248
+ return publishedMessage;
249
+ }
250
+ async toggleLike(document) {
251
+ const {
252
+ enrichments: {
253
+ socialScores: {
254
+ tt_liked_by_user: likedByUser
255
+ }
256
+ }
257
+ } = document;
258
+ try {
259
+ let likeResponse = await (!likedByUser ? this.like(document) : this.unlike(document));
260
+ return likeResponse;
261
+ } catch (error) {
262
+ logger.error(`${document} - error recieved - ${error.code}`, error);
263
+ throw error;
264
+ }
265
+ }
266
+ async toggleHide(document) {
267
+ let parentDoc = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined;
268
+ const {
269
+ documentId,
270
+ appData: {
271
+ hidden: hiddenOnNative
272
+ }
273
+ } = document;
274
+ let response;
275
+ try {
276
+ if (hiddenOnNative) {
277
+ response = await this.hide(document, parentDoc);
278
+ } else {
279
+ response = await this.unhide(document, parentDoc);
280
+ }
281
+ logger.info(`Native Tiktok API Hide Response for documentId ${documentId}`, {
282
+ status: response.status,
283
+ ok: response.ok,
284
+ [MeltwaterAttributes.DOCUMENTID]: documentId
285
+ });
286
+ if (response.message === 'OK') {
287
+ return response;
288
+ }
289
+ } catch (error) {
290
+ logger.error(`${documentId} - error recieved - ${error.code}`, error, {
291
+ [MeltwaterAttributes.DOCUMENTID]: documentId
292
+ });
293
+ }
294
+ }
295
+ async like(document) {
296
+ const {
297
+ metaData: {
298
+ externalId: comment_id,
299
+ source: {
300
+ id: sourceId
301
+ }
302
+ }
303
+ } = document;
304
+ const {
305
+ body: publishedMessage
306
+ } = (await this.sendPost({
307
+ paramString: 'comment/like/',
308
+ postData: {
309
+ business_id: removePrefix(sourceId),
310
+ comment_id: removePrefix(comment_id),
311
+ action: 'LIKE'
312
+ },
313
+ document
314
+ })) || {};
315
+ return publishedMessage;
316
+ }
317
+ async unlike(document) {
318
+ const {
319
+ metaData: {
320
+ inReplyTo: {
321
+ id: comment_id
322
+ },
323
+ source: {
324
+ id: sourceId
325
+ }
326
+ }
327
+ } = document;
328
+ const {
329
+ body: publishedMessage
330
+ } = (await this.sendPost({
331
+ paramString: 'comment/like/',
332
+ postData: {
333
+ business_id: removePrefix(sourceId),
334
+ comment_id: removePrefix(comment_id),
335
+ action: 'unlike'
336
+ },
337
+ document
338
+ })) || {};
339
+ return publishedMessage;
340
+ }
341
+ async hide(document) {
342
+ let parentDoc = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined;
343
+ const {
344
+ metaData: {
345
+ externalId: comment_id,
346
+ source: {
347
+ id: sourceId
348
+ },
349
+ discussionType
350
+ }
351
+ } = document;
352
+
353
+ //very small chance we get externalid instead of id
354
+ const video_id = discussionType === 're' ? parentDoc?.metaData?.inReplyTo?.id || parentDoc?.metaData?.inReplyTo?.externalId : document?.metaData?.inReplyTo?.id || document?.metaData?.inReplyTo?.externalId;
355
+ const {
356
+ body: publishedMessage
357
+ } = (await this.sendPost({
358
+ paramString: 'comment/hide/',
359
+ postData: {
360
+ business_id: removePrefix(sourceId),
361
+ comment_id: removePrefix(comment_id),
362
+ video_id: removePrefix(video_id),
363
+ action: 'HIDE'
364
+ },
365
+ document
366
+ })) || {};
367
+ return publishedMessage;
368
+ }
369
+ async unhide(document) {
370
+ let parentDoc = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : undefined;
371
+ const {
372
+ metaData: {
373
+ externalId: comment_id,
374
+ source: {
375
+ id: sourceId
376
+ },
377
+ discussionType
378
+ }
379
+ } = document;
380
+ const video_id = discussionType === 're' ? parentDoc?.metaData?.inReplyTo?.id : document?.metaData?.inReplyTo?.id;
381
+ const {
382
+ body: publishedMessage
383
+ } = (await this.sendPost({
384
+ paramString: 'comment/hide/',
385
+ postData: {
386
+ business_id: removePrefix(sourceId),
387
+ comment_id: removePrefix(comment_id),
388
+ video_id: removePrefix(video_id),
389
+ action: 'UNHIDE'
390
+ },
391
+ document
392
+ })) || {};
393
+ return publishedMessage;
394
+ }
395
+ async deleteComment(document) {
396
+ const {
397
+ metaData: {
398
+ inReplyTo: {
399
+ id: comment_id,
400
+ profileId: business_id
401
+ }
402
+ }
403
+ } = document;
404
+ const {
405
+ body: publishedMessage
406
+ } = (await this.sendPost({
407
+ paramString: 'comment/delete/',
408
+ postData: {
409
+ business_id,
410
+ comment_id
411
+ },
412
+ document
413
+ })) || {};
414
+ return publishedMessage;
415
+ }
416
+ async getProfile(business_id, document) {
417
+ const fields = '["username", "display_name", "profile_image"]';
418
+ const profile = (await this.sendRequest({
419
+ paramString: `get/?business_id=${business_id}&fields=${fields}`,
420
+ document
421
+ })) || {};
422
+ return profile;
423
+ }
424
+ async getPostData(business_id, video_id, document) {
425
+ const fields = '["item_id", "thumbnail_url", "create_time", "username", "display_name", "profile_image"]';
426
+ const video_ids = `["${video_id}"]`;
427
+ const profile = (await this.sendRequest({
428
+ paramString: `video/list?business_id=${business_id}&fields=${fields}&filters={"video_ids":${video_ids}}`,
429
+ document
430
+ })) || {};
431
+ return profile;
432
+ }
433
+ }
@@ -0,0 +1,30 @@
1
+ import { awsS3Client } from './http/amazonS3.js';
2
+ import { assetManagerTvmRepository } from './http/asset-manager-tvm.client.js';
3
+ import { CompanyApiClient } from './http/companiesApi.client.js';
4
+ import { CredentialsApiClient } from './http/credentialsApi.client.js';
5
+ import { EntitlementsApiClient } from './http/entitlementsApi.client.js';
6
+ import { FacebookApiClient } from './http/facebookApi.client.js';
7
+ import { FeatureToggleClient } from './http/featureToggleApi.client.js';
8
+ import { IdentityServicesClient } from './http/identityServices.client.js';
9
+ import { InstagramApiClient } from './http/instagramApi.client.js';
10
+ import { InstagramVideoClient } from './http/InstagramVideoClient.js';
11
+ import { IRClient } from './http/ir.client.js';
12
+ import { LinkedInApiClient, getOrganization, getProfile } from './http/linkedInApi.client.js';
13
+ import { TikTokApiClient } from './http/tiktokApi.client.js';
14
+ import { MasfClient } from './http/masf.client.js';
15
+ import { WarpZoneApiClient } from './http/WarpZoneApi.client.js';
16
+ import * as messageHelpers from '../lib/message.helpers.js';
17
+ import * as applicationTagFunctions from '../lib/applicationTags.helpers.js';
18
+ import * as hiddenHelpers from '../lib/hidden.helpers.js';
19
+ import * as FacebookNative from './http/facebook.native.js';
20
+ import * as TiktokNative from './http/tiktok.native.js';
21
+ const DocumentHelperFunctions = {
22
+ ...messageHelpers,
23
+ ...applicationTagFunctions,
24
+ ...hiddenHelpers
25
+ };
26
+ const LinkedInHelpers = {
27
+ getOrganization,
28
+ getProfile
29
+ };
30
+ export { FacebookNative, TiktokNative, awsS3Client, assetManagerTvmRepository, CompanyApiClient, CredentialsApiClient, EntitlementsApiClient, FacebookApiClient, FeatureToggleClient, IdentityServicesClient, InstagramApiClient, InstagramVideoClient, IRClient, LinkedInApiClient, TikTokApiClient, MasfClient, WarpZoneApiClient, DocumentHelperFunctions, LinkedInHelpers };
@@ -0,0 +1,9 @@
1
+ export class EngageError extends Error {
2
+ code;
3
+ constructor(code, message) {
4
+ super(message);
5
+ Object.setPrototypeOf(this, new.target.prototype);
6
+ this.name = this.constructor.name;
7
+ this.code = code;
8
+ }
9
+ }
@@ -0,0 +1,16 @@
1
+ import { EngageError } from "./engage-error";
2
+ export class EngageHttpError extends EngageError {
3
+ status;
4
+ statusText;
5
+ response;
6
+ headers;
7
+ constructor(status, statusText, response, headers) {
8
+ super(`HTTP ${status}: ${statusText}`, statusText);
9
+ Object.setPrototypeOf(this, new.target.prototype);
10
+ this.name = this.constructor.name;
11
+ this.status = status;
12
+ this.statusText = statusText;
13
+ this.response = response;
14
+ this.headers = headers;
15
+ }
16
+ }
@@ -0,0 +1,22 @@
1
+ export function parseApplicationTags(tags) {
2
+ const parsedTags = {};
3
+ if (!tags) {
4
+ return parsedTags;
5
+ }
6
+ tags.map(tag => {
7
+ const [key, value] = tag.split('=');
8
+ parsedTags[key] = value;
9
+ });
10
+ return parsedTags;
11
+ }
12
+ export function checkApplicationTagsForUserLikes(applicationTags) {
13
+ const appTags = parseApplicationTags(applicationTags);
14
+ if (appTags.userLikes === 'true') {
15
+ return true;
16
+ } else {
17
+ return false;
18
+ }
19
+ }
20
+ export function getCredentialIdFromApplicationTags(applicationTags) {
21
+ return applicationTags.find(appTag => appTag.startsWith('connectionsCredential=') || appTag.startsWith('connectionscredential='))?.substring(22);
22
+ }
@@ -0,0 +1,8 @@
1
+ export default {
2
+ get: varName => {
3
+ const value = process.env[varName];
4
+ if (value === 'true') return true;
5
+ if (value === 'false') return false;
6
+ return value;
7
+ }
8
+ };
@@ -0,0 +1,6 @@
1
+ export default {
2
+ MARK_AS_TODO: 'MARK_AS_TODO',
3
+ MARK_AS_COMPLETE: 'MARK_AS_COMPLETE',
4
+ USER_STARTED_RESPONDING: 'USER_STARTED_RESPONDING',
5
+ USER_STOPPED_RESPONDING: 'USER_STOPPED_RESPONDING'
6
+ };
@@ -0,0 +1,12 @@
1
+ export function removePrefix(document) {
2
+ return document && document.replace(/id\:[a-zA-Z]+\.com:/g, '');
3
+ }
4
+ export function twitterPrefixCheck(socialOriginType, value) {
5
+ let result = value;
6
+ if (socialOriginType === 'twitter') {
7
+ if (!value.includes('id:twitter.com:')) {
8
+ result = 'id:twitter.com:' + value;
9
+ }
10
+ }
11
+ return result;
12
+ }