@meltwater/conversations-api-services 1.0.40 → 1.0.41
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/dist/cjs/data-access/http/ir.client.js +123 -44
- package/dist/cjs/data-access/http/twitter.native.js +3 -7
- package/dist/cjs/data-access/index.js +5 -3
- package/dist/esm/data-access/http/ir.client.js +119 -44
- package/dist/esm/data-access/http/twitter.native.js +3 -7
- package/dist/esm/data-access/index.js +3 -2
- package/package.json +1 -1
- package/src/data-access/http/ir.client.js +159 -59
- package/src/data-access/http/twitter.native.js +3 -7
- package/src/data-access/index.js +2 -1
|
@@ -3,14 +3,25 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.
|
|
6
|
+
exports.addRevisionsToDocuments = addRevisionsToDocuments;
|
|
7
|
+
exports.default = void 0;
|
|
8
|
+
exports.markAsComplete = markAsComplete;
|
|
9
|
+
exports.markAsHasDMReply = markAsHasDMReply;
|
|
10
|
+
exports.markAsToDo = markAsToDo;
|
|
7
11
|
var _uuid = require("uuid");
|
|
8
12
|
var _superagent = _interopRequireDefault(require("superagent"));
|
|
9
13
|
var _logger = _interopRequireDefault(require("../../lib/logger.js"));
|
|
10
14
|
var _configuration = _interopRequireDefault(require("../../lib/configuration.js"));
|
|
11
|
-
var _metricsHelper = require("../../lib/metrics.helper.js");
|
|
12
15
|
var _loggerHelpers = require("../../lib/logger.helpers.js");
|
|
13
16
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
17
|
+
const searchServicesUrl = _configuration.default.get('SEARCH_SERVICE_URL');
|
|
18
|
+
const searchServicesKey = process.env.IR_API_KEY;
|
|
19
|
+
const documentRevisionsServiceUrl = _configuration.default.get('DOCUMENT_REVISIONS_SERVICE_URL');
|
|
20
|
+
const documentServiceUrl = _configuration.default.get('DOCUMENT_SERVICE_URL');
|
|
21
|
+
const documentServiceKey = process.env.IR_API_KEY;
|
|
22
|
+
const exportApiUrl = _configuration.default.get('EXPORT_API_URL');
|
|
23
|
+
const exportApiKey = process.env.IR_API_KEY;
|
|
24
|
+
const chunkSize = process.env.REVISION_CHUNK_SIZE || 200;
|
|
14
25
|
class IRClient {
|
|
15
26
|
RETRY_COUNT = 50;
|
|
16
27
|
constructor(context) {
|
|
@@ -25,47 +36,14 @@ class IRClient {
|
|
|
25
36
|
this.traceId = traceId;
|
|
26
37
|
this.metrics = metrics;
|
|
27
38
|
}
|
|
28
|
-
async init() {
|
|
29
|
-
let irApiKey = _configuration.default.get('IR_API_KEY');
|
|
30
|
-
this.searchServicesUrl = _configuration.default.get('SEARCH_SERVICE_URL');
|
|
31
|
-
this.searchServicesKey = irApiKey;
|
|
32
|
-
this.documentRevisionsServiceUrl = _configuration.default.get('DOCUMENT_REVISIONS_SERVICE_URL');
|
|
33
|
-
this.documentServiceUrl = _configuration.default.get('DOCUMENT_SERVICE_URL');
|
|
34
|
-
this.documentServiceKey = irApiKey;
|
|
35
|
-
this.exportApiUrl = _configuration.default.get('EXPORT_API_URL');
|
|
36
|
-
this.exportApiKey = irApiKey;
|
|
37
|
-
}
|
|
38
39
|
async addRevisionsToDocuments(operations) {
|
|
39
|
-
await this.
|
|
40
|
-
const wait = 100;
|
|
41
|
-
const url = `${this.documentRevisionsServiceUrl}/${this.company._id}/`;
|
|
42
|
-
const loggerChild = _logger.default.child({
|
|
43
|
-
[_loggerHelpers.MeltwaterAttributes.COMPANYID]: this.company._id
|
|
44
|
-
});
|
|
45
|
-
let result;
|
|
46
|
-
try {
|
|
47
|
-
result = await _superagent.default.patch(url).query({
|
|
48
|
-
wait,
|
|
49
|
-
apikey: this.documentServiceKey
|
|
50
|
-
}).set('x-client-name', 'engage-conversations').send(operations).then(result => result.body);
|
|
51
|
-
} catch (error) {
|
|
52
|
-
loggerChild.error(`Failed adding a revisions with operations`, error, {
|
|
53
|
-
url,
|
|
54
|
-
[_loggerHelpers.MeltwaterAttributes.COMPANYID]: this.company._id,
|
|
55
|
-
operations: JSON.stringify(operations)
|
|
56
|
-
});
|
|
57
|
-
return;
|
|
58
|
-
}
|
|
59
|
-
loggerChild.info(`Finished adding revision operations`, {
|
|
60
|
-
operations: JSON.stringify(operations)
|
|
61
|
-
});
|
|
62
|
-
return result;
|
|
40
|
+
return await addRevisionsToDocuments(operations, this.company._id, _logger.default);
|
|
63
41
|
}
|
|
64
42
|
async modifyDocuments(operations) {
|
|
65
43
|
let retryAttempt = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
|
|
66
44
|
await this.init();
|
|
67
45
|
const wait = 100;
|
|
68
|
-
const url = `${
|
|
46
|
+
const url = `${documentServiceUrl}/`;
|
|
69
47
|
const loggerChild = _logger.default.child({
|
|
70
48
|
[_loggerHelpers.MeltwaterAttributes.COMPANYID]: this.company._id
|
|
71
49
|
});
|
|
@@ -73,7 +51,7 @@ class IRClient {
|
|
|
73
51
|
try {
|
|
74
52
|
result = await _superagent.default.patch(url).query({
|
|
75
53
|
wait,
|
|
76
|
-
apikey:
|
|
54
|
+
apikey: documentServiceKey
|
|
77
55
|
}).set('x-client-name', 'engage-conversations').send(operations).then(result => result.body);
|
|
78
56
|
} catch (err) {
|
|
79
57
|
retryAttempt++;
|
|
@@ -94,7 +72,7 @@ class IRClient {
|
|
|
94
72
|
let retryAttempt = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
|
|
95
73
|
await this.init();
|
|
96
74
|
try {
|
|
97
|
-
const uri = `${
|
|
75
|
+
const uri = `${documentServiceUrl}/${id}/revisions/${this.company._id}?apikey=${documentServiceKey}`;
|
|
98
76
|
const metric = this.metrics.count(metricNames.irGetByDocumentId);
|
|
99
77
|
const result = await _superagent.default.get(uri);
|
|
100
78
|
this.metrics.finishOperation(metricNames.irGetByDocumentId, metric);
|
|
@@ -135,8 +113,8 @@ class IRClient {
|
|
|
135
113
|
await this.init();
|
|
136
114
|
const traceId = this.generateTraceId();
|
|
137
115
|
try {
|
|
138
|
-
let uri = `${
|
|
139
|
-
_logger.default.info(`Starting call to : ${
|
|
116
|
+
let uri = `${exportApiUrl}?apikey=${exportApiKey}`;
|
|
117
|
+
_logger.default.info(`Starting call to : ${exportApiUrl}`, {
|
|
140
118
|
rune
|
|
141
119
|
});
|
|
142
120
|
this.addCompanyToRuneForHorace(rune);
|
|
@@ -155,7 +133,7 @@ class IRClient {
|
|
|
155
133
|
await this.init();
|
|
156
134
|
const traceId = this.generateTraceId();
|
|
157
135
|
try {
|
|
158
|
-
let uri = `${
|
|
136
|
+
let uri = `${searchServicesUrl}?apikey=${searchServicesKey}`;
|
|
159
137
|
|
|
160
138
|
// todo: remove changing rune searchResults size
|
|
161
139
|
// todo: remove reduce ( dedupes and trims to original rune limit )
|
|
@@ -224,7 +202,7 @@ class IRClient {
|
|
|
224
202
|
async executeSearch(rune) {
|
|
225
203
|
await this.init();
|
|
226
204
|
this.addCompanyToRuneForHorace(rune);
|
|
227
|
-
const uri = `${
|
|
205
|
+
const uri = `${searchServicesUrl}?apikey=${searchServicesKey}`;
|
|
228
206
|
return await _superagent.default.post(uri).send(rune);
|
|
229
207
|
}
|
|
230
208
|
addCompanyToRuneForHorace(rune) {
|
|
@@ -239,4 +217,105 @@ class IRClient {
|
|
|
239
217
|
return `engage_${this.company._id}_${this.traceId}_${(0, _uuid.v4)()}`;
|
|
240
218
|
}
|
|
241
219
|
}
|
|
242
|
-
exports.
|
|
220
|
+
exports.default = IRClient;
|
|
221
|
+
async function addRevisionsToDocuments(operations, companyId, logger) {
|
|
222
|
+
const url = `${documentRevisionsServiceUrl}/${companyId}/`;
|
|
223
|
+
let result;
|
|
224
|
+
try {
|
|
225
|
+
result = await _superagent.default.patch(url).query({
|
|
226
|
+
apikey: documentServiceKey
|
|
227
|
+
}).set('x-client-name', 'engage-conversations').send(operations).then(result => result.body);
|
|
228
|
+
} catch (error) {
|
|
229
|
+
(0, _loggerHelpers.loggerError)(logger, `Failed adding a revisions with operations`, error, {
|
|
230
|
+
url,
|
|
231
|
+
[_loggerHelpers.MeltwaterAttributes.COMPANYID]: companyId,
|
|
232
|
+
operations: JSON.stringify(operations)
|
|
233
|
+
});
|
|
234
|
+
return;
|
|
235
|
+
}
|
|
236
|
+
return result;
|
|
237
|
+
}
|
|
238
|
+
async function markAsComplete(messageIds, companyId, logger) {
|
|
239
|
+
return reviseDocumentHelper(messageIds, 'markAsComplete', companyId, logger);
|
|
240
|
+
}
|
|
241
|
+
async function markAsHasDMReply(messageIds, companyId, logger) {
|
|
242
|
+
return reviseDocumentHelper(messageIds, 'markAsHasDMReply', companyId, logger);
|
|
243
|
+
}
|
|
244
|
+
async function markAsToDo(messageIds, companyId, logger) {
|
|
245
|
+
return reviseDocumentHelper(messageIds, 'markAsToDo', companyId, logger);
|
|
246
|
+
}
|
|
247
|
+
async function reviseDocumentHelper(messageIds, revisionType, companyId, logger) {
|
|
248
|
+
const messageIdsChunks = chunkArray(messageIds, chunkSize);
|
|
249
|
+
const revisionPromises = [];
|
|
250
|
+
for (const messageIdChunk of messageIdsChunks) {
|
|
251
|
+
const operations = {};
|
|
252
|
+
// build operation list for each document
|
|
253
|
+
switch (revisionType) {
|
|
254
|
+
case "markAsComplete":
|
|
255
|
+
messageIdChunk.forEach(message => {
|
|
256
|
+
operations[message.documentId] = [{
|
|
257
|
+
operation: 'addToSet',
|
|
258
|
+
fieldPath: 'metaData.applicationTags',
|
|
259
|
+
value: [generateCompanyAppDataKey({
|
|
260
|
+
companyId: companyId,
|
|
261
|
+
key: `${message.searchId || `credential:${message.credentialId}`}:status`,
|
|
262
|
+
value: 'complete'
|
|
263
|
+
})]
|
|
264
|
+
}];
|
|
265
|
+
});
|
|
266
|
+
break;
|
|
267
|
+
case "markAsHasDMReply":
|
|
268
|
+
messageIdChunk.forEach(message => {
|
|
269
|
+
operations[message.documentId] = [{
|
|
270
|
+
operation: 'addToSet',
|
|
271
|
+
fieldPath: 'metaData.applicationTags',
|
|
272
|
+
value: [generateCompanyAppDataKey({
|
|
273
|
+
companyId: companyId,
|
|
274
|
+
key: `${message.searchId || `credential:${message.credentialId}`}:hasBrandReply`,
|
|
275
|
+
value: 'true'
|
|
276
|
+
})]
|
|
277
|
+
}];
|
|
278
|
+
});
|
|
279
|
+
break;
|
|
280
|
+
case "markAsToDo":
|
|
281
|
+
messageIdChunk.forEach(message => {
|
|
282
|
+
operations[message.documentId] = [{
|
|
283
|
+
operation: 'removeFromSet',
|
|
284
|
+
fieldPath: 'metaData.applicationTags',
|
|
285
|
+
value: [generateCompanyAppDataKey({
|
|
286
|
+
companyId: companyId,
|
|
287
|
+
key: `${message.searchId || `credential:${message.credentialId}`}:status`,
|
|
288
|
+
value: `complete`
|
|
289
|
+
})]
|
|
290
|
+
}];
|
|
291
|
+
});
|
|
292
|
+
break;
|
|
293
|
+
}
|
|
294
|
+
try {
|
|
295
|
+
(0, _loggerHelpers.loggerInfo)(logger, `Sending revision for ${revisionType} for companyId: ${companyId}`, {
|
|
296
|
+
operations: JSON.stringify(operations)
|
|
297
|
+
});
|
|
298
|
+
revisionPromises.push(addRevisionsToDocuments(operations, companyId, logger));
|
|
299
|
+
} catch (error) {
|
|
300
|
+
(0, _loggerHelpers.loggerError)(logger, `Error marking as ${revisionType} in IR for ${messageIds.length} document(s). Unable to save revision.`, error, {
|
|
301
|
+
messageIds
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
return await Promise.all(revisionPromises);
|
|
306
|
+
}
|
|
307
|
+
function chunkArray(array, size) {
|
|
308
|
+
return array.reduce((chunks, item, index) => {
|
|
309
|
+
const chunkIndex = Math.floor(index / size);
|
|
310
|
+
chunks[chunkIndex] = (chunks[chunkIndex] || []).concat(item);
|
|
311
|
+
return chunks;
|
|
312
|
+
}, []);
|
|
313
|
+
}
|
|
314
|
+
function generateCompanyAppDataKey(_ref) {
|
|
315
|
+
let {
|
|
316
|
+
companyId,
|
|
317
|
+
key,
|
|
318
|
+
value
|
|
319
|
+
} = _ref;
|
|
320
|
+
return `conversations:${companyId}:${key}=${value}`;
|
|
321
|
+
}
|
|
@@ -28,11 +28,7 @@ var _crypto = _interopRequireDefault(require("crypto"));
|
|
|
28
28
|
var _axios = _interopRequireDefault(require("axios"));
|
|
29
29
|
var _fs = _interopRequireDefault(require("fs"));
|
|
30
30
|
var _socialTwit = _interopRequireDefault(require("@meltwater/social-twit"));
|
|
31
|
-
var _url = require("url");
|
|
32
|
-
var _path = require("path");
|
|
33
31
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
34
|
-
const _filename = (0, _url.fileURLToPath)(import.meta.url);
|
|
35
|
-
const _dirname = (0, _path.dirname)(_filename);
|
|
36
32
|
function addOAuthToToken(token, TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET) {
|
|
37
33
|
if (!token.oauth) {
|
|
38
34
|
token.oauth = (0, _oauth.default)({
|
|
@@ -534,8 +530,8 @@ async function downloadImage(url, fileName) {
|
|
|
534
530
|
}
|
|
535
531
|
|
|
536
532
|
// local
|
|
537
|
-
function generateFilePath(mimeType) {
|
|
538
|
-
let dir = `${
|
|
533
|
+
function generateFilePath(mimeType, dirname) {
|
|
534
|
+
let dir = `${dirname}/temporaryTwitterMedia`;
|
|
539
535
|
if (!_fs.default.existsSync(dir)) {
|
|
540
536
|
_fs.default.mkdirSync(dir);
|
|
541
537
|
}
|
|
@@ -549,7 +545,7 @@ function generateFilePath(mimeType) {
|
|
|
549
545
|
// local
|
|
550
546
|
async function uploadMedia(attachment, token, discussionType, logger) {
|
|
551
547
|
return new Promise(async (resolve, reject) => {
|
|
552
|
-
let filePath = generateFilePath(attachment.mimeType);
|
|
548
|
+
let filePath = generateFilePath(attachment.mimeType, attachment.__dirname);
|
|
553
549
|
await downloadImage(attachment.url, filePath);
|
|
554
550
|
const T = new _socialTwit.default({
|
|
555
551
|
consumer_key: token.consumer_key,
|
|
@@ -14,7 +14,8 @@ var _featureToggleApiClient = require("./http/featureToggleApi.client.js");
|
|
|
14
14
|
var _identityServicesClient = require("./http/identityServices.client.js");
|
|
15
15
|
var _instagramApiClient = require("./http/instagramApi.client.js");
|
|
16
16
|
var _InstagramVideoClient = require("./http/InstagramVideoClient.js");
|
|
17
|
-
var _irClient = require("./http/ir.client.js");
|
|
17
|
+
var _irClient = _interopRequireWildcard(require("./http/ir.client.js"));
|
|
18
|
+
var IRClientHelpers = _irClient;
|
|
18
19
|
var _linkedInApiClient = require("./http/linkedInApi.client.js");
|
|
19
20
|
var _tiktokApiClient = require("./http/tiktokApi.client.js");
|
|
20
21
|
var _masfClient = require("./http/masf.client.js");
|
|
@@ -59,11 +60,12 @@ var _default = exports.default = {
|
|
|
59
60
|
IdentityServicesClient: _identityServicesClient.IdentityServicesClient,
|
|
60
61
|
InstagramApiClient: _instagramApiClient.InstagramApiClient,
|
|
61
62
|
InstagramVideoClient: _InstagramVideoClient.InstagramVideoClient,
|
|
62
|
-
IRClient: _irClient.
|
|
63
|
+
IRClient: _irClient.default,
|
|
63
64
|
LinkedInApiClient: _linkedInApiClient.LinkedInApiClient,
|
|
64
65
|
TikTokApiClient: _tiktokApiClient.TikTokApiClient,
|
|
65
66
|
MasfClient: _masfClient.MasfClient,
|
|
66
67
|
WarpZoneApiClient: _WarpZoneApiClient.WarpZoneApiClient,
|
|
67
68
|
DocumentHelperFunctions,
|
|
68
|
-
LinkedInHelpers
|
|
69
|
+
LinkedInHelpers,
|
|
70
|
+
IRClientHelpers
|
|
69
71
|
};
|
|
@@ -2,9 +2,16 @@ import { v4 } from 'uuid';
|
|
|
2
2
|
import superagent from 'superagent';
|
|
3
3
|
import logger from '../../lib/logger.js';
|
|
4
4
|
import configuration from '../../lib/configuration.js';
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
import { loggerError, loggerInfo, MeltwaterAttributes } from '../../lib/logger.helpers.js';
|
|
6
|
+
const searchServicesUrl = configuration.get('SEARCH_SERVICE_URL');
|
|
7
|
+
const searchServicesKey = process.env.IR_API_KEY;
|
|
8
|
+
const documentRevisionsServiceUrl = configuration.get('DOCUMENT_REVISIONS_SERVICE_URL');
|
|
9
|
+
const documentServiceUrl = configuration.get('DOCUMENT_SERVICE_URL');
|
|
10
|
+
const documentServiceKey = process.env.IR_API_KEY;
|
|
11
|
+
const exportApiUrl = configuration.get('EXPORT_API_URL');
|
|
12
|
+
const exportApiKey = process.env.IR_API_KEY;
|
|
13
|
+
const chunkSize = process.env.REVISION_CHUNK_SIZE || 200;
|
|
14
|
+
export default class IRClient {
|
|
8
15
|
RETRY_COUNT = 50;
|
|
9
16
|
constructor(context) {
|
|
10
17
|
const {
|
|
@@ -18,47 +25,14 @@ export class IRClient {
|
|
|
18
25
|
this.traceId = traceId;
|
|
19
26
|
this.metrics = metrics;
|
|
20
27
|
}
|
|
21
|
-
async init() {
|
|
22
|
-
let irApiKey = configuration.get('IR_API_KEY');
|
|
23
|
-
this.searchServicesUrl = configuration.get('SEARCH_SERVICE_URL');
|
|
24
|
-
this.searchServicesKey = irApiKey;
|
|
25
|
-
this.documentRevisionsServiceUrl = configuration.get('DOCUMENT_REVISIONS_SERVICE_URL');
|
|
26
|
-
this.documentServiceUrl = configuration.get('DOCUMENT_SERVICE_URL');
|
|
27
|
-
this.documentServiceKey = irApiKey;
|
|
28
|
-
this.exportApiUrl = configuration.get('EXPORT_API_URL');
|
|
29
|
-
this.exportApiKey = irApiKey;
|
|
30
|
-
}
|
|
31
28
|
async addRevisionsToDocuments(operations) {
|
|
32
|
-
await this.
|
|
33
|
-
const wait = 100;
|
|
34
|
-
const url = `${this.documentRevisionsServiceUrl}/${this.company._id}/`;
|
|
35
|
-
const loggerChild = logger.child({
|
|
36
|
-
[MeltwaterAttributes.COMPANYID]: this.company._id
|
|
37
|
-
});
|
|
38
|
-
let result;
|
|
39
|
-
try {
|
|
40
|
-
result = await superagent.patch(url).query({
|
|
41
|
-
wait,
|
|
42
|
-
apikey: this.documentServiceKey
|
|
43
|
-
}).set('x-client-name', 'engage-conversations').send(operations).then(result => result.body);
|
|
44
|
-
} catch (error) {
|
|
45
|
-
loggerChild.error(`Failed adding a revisions with operations`, error, {
|
|
46
|
-
url,
|
|
47
|
-
[MeltwaterAttributes.COMPANYID]: this.company._id,
|
|
48
|
-
operations: JSON.stringify(operations)
|
|
49
|
-
});
|
|
50
|
-
return;
|
|
51
|
-
}
|
|
52
|
-
loggerChild.info(`Finished adding revision operations`, {
|
|
53
|
-
operations: JSON.stringify(operations)
|
|
54
|
-
});
|
|
55
|
-
return result;
|
|
29
|
+
return await addRevisionsToDocuments(operations, this.company._id, logger);
|
|
56
30
|
}
|
|
57
31
|
async modifyDocuments(operations) {
|
|
58
32
|
let retryAttempt = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
|
|
59
33
|
await this.init();
|
|
60
34
|
const wait = 100;
|
|
61
|
-
const url = `${
|
|
35
|
+
const url = `${documentServiceUrl}/`;
|
|
62
36
|
const loggerChild = logger.child({
|
|
63
37
|
[MeltwaterAttributes.COMPANYID]: this.company._id
|
|
64
38
|
});
|
|
@@ -66,7 +40,7 @@ export class IRClient {
|
|
|
66
40
|
try {
|
|
67
41
|
result = await superagent.patch(url).query({
|
|
68
42
|
wait,
|
|
69
|
-
apikey:
|
|
43
|
+
apikey: documentServiceKey
|
|
70
44
|
}).set('x-client-name', 'engage-conversations').send(operations).then(result => result.body);
|
|
71
45
|
} catch (err) {
|
|
72
46
|
retryAttempt++;
|
|
@@ -87,7 +61,7 @@ export class IRClient {
|
|
|
87
61
|
let retryAttempt = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
|
|
88
62
|
await this.init();
|
|
89
63
|
try {
|
|
90
|
-
const uri = `${
|
|
64
|
+
const uri = `${documentServiceUrl}/${id}/revisions/${this.company._id}?apikey=${documentServiceKey}`;
|
|
91
65
|
const metric = this.metrics.count(metricNames.irGetByDocumentId);
|
|
92
66
|
const result = await superagent.get(uri);
|
|
93
67
|
this.metrics.finishOperation(metricNames.irGetByDocumentId, metric);
|
|
@@ -128,8 +102,8 @@ export class IRClient {
|
|
|
128
102
|
await this.init();
|
|
129
103
|
const traceId = this.generateTraceId();
|
|
130
104
|
try {
|
|
131
|
-
let uri = `${
|
|
132
|
-
logger.info(`Starting call to : ${
|
|
105
|
+
let uri = `${exportApiUrl}?apikey=${exportApiKey}`;
|
|
106
|
+
logger.info(`Starting call to : ${exportApiUrl}`, {
|
|
133
107
|
rune
|
|
134
108
|
});
|
|
135
109
|
this.addCompanyToRuneForHorace(rune);
|
|
@@ -148,7 +122,7 @@ export class IRClient {
|
|
|
148
122
|
await this.init();
|
|
149
123
|
const traceId = this.generateTraceId();
|
|
150
124
|
try {
|
|
151
|
-
let uri = `${
|
|
125
|
+
let uri = `${searchServicesUrl}?apikey=${searchServicesKey}`;
|
|
152
126
|
|
|
153
127
|
// todo: remove changing rune searchResults size
|
|
154
128
|
// todo: remove reduce ( dedupes and trims to original rune limit )
|
|
@@ -217,7 +191,7 @@ export class IRClient {
|
|
|
217
191
|
async executeSearch(rune) {
|
|
218
192
|
await this.init();
|
|
219
193
|
this.addCompanyToRuneForHorace(rune);
|
|
220
|
-
const uri = `${
|
|
194
|
+
const uri = `${searchServicesUrl}?apikey=${searchServicesKey}`;
|
|
221
195
|
return await superagent.post(uri).send(rune);
|
|
222
196
|
}
|
|
223
197
|
addCompanyToRuneForHorace(rune) {
|
|
@@ -231,4 +205,105 @@ export class IRClient {
|
|
|
231
205
|
generateTraceId() {
|
|
232
206
|
return `engage_${this.company._id}_${this.traceId}_${v4()}`;
|
|
233
207
|
}
|
|
208
|
+
}
|
|
209
|
+
export async function addRevisionsToDocuments(operations, companyId, logger) {
|
|
210
|
+
const url = `${documentRevisionsServiceUrl}/${companyId}/`;
|
|
211
|
+
let result;
|
|
212
|
+
try {
|
|
213
|
+
result = await superagent.patch(url).query({
|
|
214
|
+
apikey: documentServiceKey
|
|
215
|
+
}).set('x-client-name', 'engage-conversations').send(operations).then(result => result.body);
|
|
216
|
+
} catch (error) {
|
|
217
|
+
loggerError(logger, `Failed adding a revisions with operations`, error, {
|
|
218
|
+
url,
|
|
219
|
+
[MeltwaterAttributes.COMPANYID]: companyId,
|
|
220
|
+
operations: JSON.stringify(operations)
|
|
221
|
+
});
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
return result;
|
|
225
|
+
}
|
|
226
|
+
export async function markAsComplete(messageIds, companyId, logger) {
|
|
227
|
+
return reviseDocumentHelper(messageIds, 'markAsComplete', companyId, logger);
|
|
228
|
+
}
|
|
229
|
+
export async function markAsHasDMReply(messageIds, companyId, logger) {
|
|
230
|
+
return reviseDocumentHelper(messageIds, 'markAsHasDMReply', companyId, logger);
|
|
231
|
+
}
|
|
232
|
+
export async function markAsToDo(messageIds, companyId, logger) {
|
|
233
|
+
return reviseDocumentHelper(messageIds, 'markAsToDo', companyId, logger);
|
|
234
|
+
}
|
|
235
|
+
async function reviseDocumentHelper(messageIds, revisionType, companyId, logger) {
|
|
236
|
+
const messageIdsChunks = chunkArray(messageIds, chunkSize);
|
|
237
|
+
const revisionPromises = [];
|
|
238
|
+
for (const messageIdChunk of messageIdsChunks) {
|
|
239
|
+
const operations = {};
|
|
240
|
+
// build operation list for each document
|
|
241
|
+
switch (revisionType) {
|
|
242
|
+
case "markAsComplete":
|
|
243
|
+
messageIdChunk.forEach(message => {
|
|
244
|
+
operations[message.documentId] = [{
|
|
245
|
+
operation: 'addToSet',
|
|
246
|
+
fieldPath: 'metaData.applicationTags',
|
|
247
|
+
value: [generateCompanyAppDataKey({
|
|
248
|
+
companyId: companyId,
|
|
249
|
+
key: `${message.searchId || `credential:${message.credentialId}`}:status`,
|
|
250
|
+
value: 'complete'
|
|
251
|
+
})]
|
|
252
|
+
}];
|
|
253
|
+
});
|
|
254
|
+
break;
|
|
255
|
+
case "markAsHasDMReply":
|
|
256
|
+
messageIdChunk.forEach(message => {
|
|
257
|
+
operations[message.documentId] = [{
|
|
258
|
+
operation: 'addToSet',
|
|
259
|
+
fieldPath: 'metaData.applicationTags',
|
|
260
|
+
value: [generateCompanyAppDataKey({
|
|
261
|
+
companyId: companyId,
|
|
262
|
+
key: `${message.searchId || `credential:${message.credentialId}`}:hasBrandReply`,
|
|
263
|
+
value: 'true'
|
|
264
|
+
})]
|
|
265
|
+
}];
|
|
266
|
+
});
|
|
267
|
+
break;
|
|
268
|
+
case "markAsToDo":
|
|
269
|
+
messageIdChunk.forEach(message => {
|
|
270
|
+
operations[message.documentId] = [{
|
|
271
|
+
operation: 'removeFromSet',
|
|
272
|
+
fieldPath: 'metaData.applicationTags',
|
|
273
|
+
value: [generateCompanyAppDataKey({
|
|
274
|
+
companyId: companyId,
|
|
275
|
+
key: `${message.searchId || `credential:${message.credentialId}`}:status`,
|
|
276
|
+
value: `complete`
|
|
277
|
+
})]
|
|
278
|
+
}];
|
|
279
|
+
});
|
|
280
|
+
break;
|
|
281
|
+
}
|
|
282
|
+
try {
|
|
283
|
+
loggerInfo(logger, `Sending revision for ${revisionType} for companyId: ${companyId}`, {
|
|
284
|
+
operations: JSON.stringify(operations)
|
|
285
|
+
});
|
|
286
|
+
revisionPromises.push(addRevisionsToDocuments(operations, companyId, logger));
|
|
287
|
+
} catch (error) {
|
|
288
|
+
loggerError(logger, `Error marking as ${revisionType} in IR for ${messageIds.length} document(s). Unable to save revision.`, error, {
|
|
289
|
+
messageIds
|
|
290
|
+
});
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
return await Promise.all(revisionPromises);
|
|
294
|
+
}
|
|
295
|
+
function chunkArray(array, size) {
|
|
296
|
+
return array.reduce((chunks, item, index) => {
|
|
297
|
+
const chunkIndex = Math.floor(index / size);
|
|
298
|
+
chunks[chunkIndex] = (chunks[chunkIndex] || []).concat(item);
|
|
299
|
+
return chunks;
|
|
300
|
+
}, []);
|
|
301
|
+
}
|
|
302
|
+
function generateCompanyAppDataKey(_ref) {
|
|
303
|
+
let {
|
|
304
|
+
companyId,
|
|
305
|
+
key,
|
|
306
|
+
value
|
|
307
|
+
} = _ref;
|
|
308
|
+
return `conversations:${companyId}:${key}=${value}`;
|
|
234
309
|
}
|
|
@@ -6,10 +6,6 @@ import crypto from 'crypto';
|
|
|
6
6
|
import axios from 'axios';
|
|
7
7
|
import fs from 'fs';
|
|
8
8
|
import Twit from '@meltwater/social-twit';
|
|
9
|
-
import { fileURLToPath } from 'url';
|
|
10
|
-
import { dirname } from 'path';
|
|
11
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
12
|
-
const __dirname = dirname(__filename);
|
|
13
9
|
export function addOAuthToToken(token, TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET) {
|
|
14
10
|
if (!token.oauth) {
|
|
15
11
|
token.oauth = OAuth({
|
|
@@ -511,8 +507,8 @@ async function downloadImage(url, fileName) {
|
|
|
511
507
|
}
|
|
512
508
|
|
|
513
509
|
// local
|
|
514
|
-
function generateFilePath(mimeType) {
|
|
515
|
-
let dir = `${
|
|
510
|
+
function generateFilePath(mimeType, dirname) {
|
|
511
|
+
let dir = `${dirname}/temporaryTwitterMedia`;
|
|
516
512
|
if (!fs.existsSync(dir)) {
|
|
517
513
|
fs.mkdirSync(dir);
|
|
518
514
|
}
|
|
@@ -526,7 +522,7 @@ function generateFilePath(mimeType) {
|
|
|
526
522
|
// local
|
|
527
523
|
async function uploadMedia(attachment, token, discussionType, logger) {
|
|
528
524
|
return new Promise(async (resolve, reject) => {
|
|
529
|
-
let filePath = generateFilePath(attachment.mimeType);
|
|
525
|
+
let filePath = generateFilePath(attachment.mimeType, attachment.__dirname);
|
|
530
526
|
await downloadImage(attachment.url, filePath);
|
|
531
527
|
const T = new Twit({
|
|
532
528
|
consumer_key: token.consumer_key,
|
|
@@ -8,7 +8,7 @@ import { FeatureToggleClient } from './http/featureToggleApi.client.js';
|
|
|
8
8
|
import { IdentityServicesClient } from './http/identityServices.client.js';
|
|
9
9
|
import { InstagramApiClient } from './http/instagramApi.client.js';
|
|
10
10
|
import { InstagramVideoClient } from './http/InstagramVideoClient.js';
|
|
11
|
-
import
|
|
11
|
+
import IRClient, * as IRClientHelpers from './http/ir.client.js';
|
|
12
12
|
import { LinkedInApiClient, getOrganization, getProfile, getOrganizations } from './http/linkedInApi.client.js';
|
|
13
13
|
import { TikTokApiClient } from './http/tiktokApi.client.js';
|
|
14
14
|
import { MasfClient } from './http/masf.client.js';
|
|
@@ -57,5 +57,6 @@ export default {
|
|
|
57
57
|
MasfClient,
|
|
58
58
|
WarpZoneApiClient,
|
|
59
59
|
DocumentHelperFunctions,
|
|
60
|
-
LinkedInHelpers
|
|
60
|
+
LinkedInHelpers,
|
|
61
|
+
IRClientHelpers
|
|
61
62
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@meltwater/conversations-api-services",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.41",
|
|
4
4
|
"description": "Repository to contain all conversations api services shared across our services",
|
|
5
5
|
"main": "dist/cjs/data-access/index.js",
|
|
6
6
|
"module": "dist/esm/data-access/index.js",
|
|
@@ -2,10 +2,22 @@ import { v4 } from 'uuid';
|
|
|
2
2
|
import superagent from 'superagent';
|
|
3
3
|
import logger from '../../lib/logger.js';
|
|
4
4
|
import configuration from '../../lib/configuration.js';
|
|
5
|
-
import {
|
|
6
|
-
import { MeltwaterAttributes } from '../../lib/logger.helpers.js';
|
|
5
|
+
import { loggerError, loggerInfo, MeltwaterAttributes } from '../../lib/logger.helpers.js';
|
|
7
6
|
|
|
8
|
-
|
|
7
|
+
const searchServicesUrl = configuration.get('SEARCH_SERVICE_URL');
|
|
8
|
+
const searchServicesKey = process.env.IR_API_KEY;
|
|
9
|
+
|
|
10
|
+
const documentRevisionsServiceUrl = configuration.get(
|
|
11
|
+
'DOCUMENT_REVISIONS_SERVICE_URL'
|
|
12
|
+
);
|
|
13
|
+
const documentServiceUrl = configuration.get('DOCUMENT_SERVICE_URL');
|
|
14
|
+
const documentServiceKey = process.env.IR_API_KEY;
|
|
15
|
+
|
|
16
|
+
const exportApiUrl = configuration.get('EXPORT_API_URL');
|
|
17
|
+
const exportApiKey = process.env.IR_API_KEY;
|
|
18
|
+
const chunkSize = process.env.REVISION_CHUNK_SIZE || 200;
|
|
19
|
+
|
|
20
|
+
export default class IRClient {
|
|
9
21
|
RETRY_COUNT = 50;
|
|
10
22
|
constructor(context) {
|
|
11
23
|
const { company, user, traceId, metrics } = context;
|
|
@@ -15,62 +27,14 @@ export class IRClient {
|
|
|
15
27
|
this.metrics = metrics;
|
|
16
28
|
}
|
|
17
29
|
|
|
18
|
-
async init() {
|
|
19
|
-
let irApiKey = configuration.get('IR_API_KEY');
|
|
20
|
-
|
|
21
|
-
this.searchServicesUrl = configuration.get('SEARCH_SERVICE_URL');
|
|
22
|
-
this.searchServicesKey = irApiKey;
|
|
23
|
-
|
|
24
|
-
this.documentRevisionsServiceUrl = configuration.get(
|
|
25
|
-
'DOCUMENT_REVISIONS_SERVICE_URL'
|
|
26
|
-
);
|
|
27
|
-
this.documentServiceUrl = configuration.get('DOCUMENT_SERVICE_URL');
|
|
28
|
-
this.documentServiceKey = irApiKey;
|
|
29
|
-
|
|
30
|
-
this.exportApiUrl = configuration.get('EXPORT_API_URL');
|
|
31
|
-
this.exportApiKey = irApiKey;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
30
|
async addRevisionsToDocuments(operations) {
|
|
35
|
-
await this.
|
|
36
|
-
const wait = 100;
|
|
37
|
-
const url = `${this.documentRevisionsServiceUrl}/${this.company._id}/`;
|
|
38
|
-
const loggerChild = logger.child({
|
|
39
|
-
[MeltwaterAttributes.COMPANYID]: this.company._id,
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
let result;
|
|
43
|
-
|
|
44
|
-
try {
|
|
45
|
-
result = await superagent
|
|
46
|
-
.patch(url)
|
|
47
|
-
.query({
|
|
48
|
-
wait,
|
|
49
|
-
apikey: this.documentServiceKey,
|
|
50
|
-
})
|
|
51
|
-
.set('x-client-name', 'engage-conversations')
|
|
52
|
-
.send(operations)
|
|
53
|
-
.then((result) => result.body);
|
|
54
|
-
} catch (error) {
|
|
55
|
-
loggerChild.error(`Failed adding a revisions with operations`, error, {
|
|
56
|
-
url,
|
|
57
|
-
[MeltwaterAttributes.COMPANYID]: this.company._id,
|
|
58
|
-
operations: JSON.stringify(operations)
|
|
59
|
-
});
|
|
60
|
-
return;
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
loggerChild.info(`Finished adding revision operations`, {
|
|
64
|
-
operations: JSON.stringify(operations)
|
|
65
|
-
});
|
|
66
|
-
|
|
67
|
-
return result;
|
|
31
|
+
return await addRevisionsToDocuments(operations,this.company._id,logger);
|
|
68
32
|
}
|
|
69
33
|
|
|
70
34
|
async modifyDocuments(operations, retryAttempt = 0) {
|
|
71
35
|
await this.init();
|
|
72
36
|
const wait = 100;
|
|
73
|
-
const url = `${
|
|
37
|
+
const url = `${documentServiceUrl}/`;
|
|
74
38
|
const loggerChild = logger.child({
|
|
75
39
|
[MeltwaterAttributes.COMPANYID]: this.company._id,
|
|
76
40
|
});
|
|
@@ -81,7 +45,7 @@ export class IRClient {
|
|
|
81
45
|
.patch(url)
|
|
82
46
|
.query({
|
|
83
47
|
wait,
|
|
84
|
-
apikey:
|
|
48
|
+
apikey: documentServiceKey,
|
|
85
49
|
})
|
|
86
50
|
.set('x-client-name', 'engage-conversations')
|
|
87
51
|
.send(operations)
|
|
@@ -111,7 +75,7 @@ export class IRClient {
|
|
|
111
75
|
await this.init();
|
|
112
76
|
|
|
113
77
|
try {
|
|
114
|
-
const uri = `${
|
|
78
|
+
const uri = `${documentServiceUrl}/${id}/revisions/${this.company._id}?apikey=${documentServiceKey}`;
|
|
115
79
|
const metric = this.metrics.count(metricNames.irGetByDocumentId);
|
|
116
80
|
const result = await superagent.get(uri);
|
|
117
81
|
this.metrics.finishOperation(metricNames.irGetByDocumentId, metric);
|
|
@@ -164,9 +128,9 @@ export class IRClient {
|
|
|
164
128
|
const traceId = this.generateTraceId();
|
|
165
129
|
|
|
166
130
|
try {
|
|
167
|
-
let uri = `${
|
|
131
|
+
let uri = `${exportApiUrl}?apikey=${exportApiKey}`;
|
|
168
132
|
|
|
169
|
-
logger.info(`Starting call to : ${
|
|
133
|
+
logger.info(`Starting call to : ${exportApiUrl}`, {
|
|
170
134
|
rune,
|
|
171
135
|
});
|
|
172
136
|
|
|
@@ -197,7 +161,7 @@ export class IRClient {
|
|
|
197
161
|
const traceId = this.generateTraceId();
|
|
198
162
|
|
|
199
163
|
try {
|
|
200
|
-
let uri = `${
|
|
164
|
+
let uri = `${searchServicesUrl}?apikey=${searchServicesKey}`;
|
|
201
165
|
|
|
202
166
|
// todo: remove changing rune searchResults size
|
|
203
167
|
// todo: remove reduce ( dedupes and trims to original rune limit )
|
|
@@ -294,7 +258,7 @@ export class IRClient {
|
|
|
294
258
|
async executeSearch(rune) {
|
|
295
259
|
await this.init();
|
|
296
260
|
this.addCompanyToRuneForHorace(rune);
|
|
297
|
-
const uri = `${
|
|
261
|
+
const uri = `${searchServicesUrl}?apikey=${searchServicesKey}`;
|
|
298
262
|
return await superagent.post(uri).send(rune);
|
|
299
263
|
}
|
|
300
264
|
|
|
@@ -311,3 +275,139 @@ export class IRClient {
|
|
|
311
275
|
return `engage_${this.company._id}_${this.traceId}_${v4()}`;
|
|
312
276
|
}
|
|
313
277
|
}
|
|
278
|
+
|
|
279
|
+
export async function addRevisionsToDocuments(operations, companyId, logger) {
|
|
280
|
+
const url = `${documentRevisionsServiceUrl}/${companyId}/`;
|
|
281
|
+
let result;
|
|
282
|
+
|
|
283
|
+
try {
|
|
284
|
+
result = await superagent
|
|
285
|
+
.patch(url)
|
|
286
|
+
.query({
|
|
287
|
+
apikey: documentServiceKey,
|
|
288
|
+
})
|
|
289
|
+
.set('x-client-name', 'engage-conversations')
|
|
290
|
+
.send(operations)
|
|
291
|
+
.then((result) => result.body);
|
|
292
|
+
} catch (error) {
|
|
293
|
+
loggerError(logger,`Failed adding a revisions with operations`, error, {
|
|
294
|
+
url,
|
|
295
|
+
[MeltwaterAttributes.COMPANYID]: companyId,
|
|
296
|
+
operations: JSON.stringify(operations)
|
|
297
|
+
});
|
|
298
|
+
return;
|
|
299
|
+
}
|
|
300
|
+
|
|
301
|
+
return result;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
export async function markAsComplete(messageIds, companyId, logger) {
|
|
305
|
+
return reviseDocumentHelper(messageIds,'markAsComplete',companyId,logger);
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
export async function markAsHasDMReply(messageIds, companyId, logger) {
|
|
309
|
+
return reviseDocumentHelper(messageIds,'markAsHasDMReply',companyId,logger);
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
export async function markAsToDo(messageIds, companyId, logger) {
|
|
313
|
+
return reviseDocumentHelper(messageIds,'markAsToDo',companyId,logger);
|
|
314
|
+
}
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
async function reviseDocumentHelper(messageIds, revisionType, companyId, logger) {
|
|
318
|
+
const messageIdsChunks = chunkArray(messageIds, chunkSize);
|
|
319
|
+
const revisionPromises = [];
|
|
320
|
+
for (const messageIdChunk of messageIdsChunks) {
|
|
321
|
+
const operations = {};
|
|
322
|
+
// build operation list for each document
|
|
323
|
+
switch(revisionType){
|
|
324
|
+
case "markAsComplete":
|
|
325
|
+
messageIdChunk.forEach((message) => {
|
|
326
|
+
operations[message.documentId] = [
|
|
327
|
+
{
|
|
328
|
+
operation: 'addToSet',
|
|
329
|
+
fieldPath: 'metaData.applicationTags',
|
|
330
|
+
value: [
|
|
331
|
+
generateCompanyAppDataKey({
|
|
332
|
+
companyId: companyId,
|
|
333
|
+
key: `${
|
|
334
|
+
message.searchId || `credential:${message.credentialId}`
|
|
335
|
+
}:status`,
|
|
336
|
+
value: 'complete',
|
|
337
|
+
}),
|
|
338
|
+
],
|
|
339
|
+
},
|
|
340
|
+
];
|
|
341
|
+
})
|
|
342
|
+
break;
|
|
343
|
+
case "markAsHasDMReply":
|
|
344
|
+
messageIdChunk.forEach((message) => {
|
|
345
|
+
operations[message.documentId] = [
|
|
346
|
+
{
|
|
347
|
+
operation: 'addToSet',
|
|
348
|
+
fieldPath: 'metaData.applicationTags',
|
|
349
|
+
value: [
|
|
350
|
+
generateCompanyAppDataKey({
|
|
351
|
+
companyId: companyId,
|
|
352
|
+
key: `${
|
|
353
|
+
message.searchId || `credential:${message.credentialId}`
|
|
354
|
+
}:hasBrandReply`,
|
|
355
|
+
value: 'true',
|
|
356
|
+
}),
|
|
357
|
+
],
|
|
358
|
+
},
|
|
359
|
+
];
|
|
360
|
+
})
|
|
361
|
+
break;
|
|
362
|
+
case "markAsToDo":
|
|
363
|
+
messageIdChunk.forEach((message) => {
|
|
364
|
+
operations[message.documentId] = [
|
|
365
|
+
{
|
|
366
|
+
operation: 'removeFromSet',
|
|
367
|
+
fieldPath: 'metaData.applicationTags',
|
|
368
|
+
value: [
|
|
369
|
+
generateCompanyAppDataKey({
|
|
370
|
+
companyId: companyId,
|
|
371
|
+
key: `${
|
|
372
|
+
message.searchId || `credential:${message.credentialId}`
|
|
373
|
+
}:status`,
|
|
374
|
+
value: `complete`,
|
|
375
|
+
}),
|
|
376
|
+
],
|
|
377
|
+
},
|
|
378
|
+
];
|
|
379
|
+
});
|
|
380
|
+
break;
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
try {
|
|
384
|
+
loggerInfo(logger,
|
|
385
|
+
`Sending revision for ${revisionType} for companyId: ${companyId}`,
|
|
386
|
+
{ operations: JSON.stringify(operations) }
|
|
387
|
+
);
|
|
388
|
+
revisionPromises.push(
|
|
389
|
+
addRevisionsToDocuments(operations,companyId,logger)
|
|
390
|
+
);
|
|
391
|
+
} catch (error) {
|
|
392
|
+
loggerError(logger,
|
|
393
|
+
`Error marking as ${revisionType} in IR for ${messageIds.length} document(s). Unable to save revision.`,
|
|
394
|
+
error,
|
|
395
|
+
{ messageIds }
|
|
396
|
+
);
|
|
397
|
+
}
|
|
398
|
+
}
|
|
399
|
+
return await Promise.all(revisionPromises);
|
|
400
|
+
}
|
|
401
|
+
|
|
402
|
+
|
|
403
|
+
function chunkArray(array, size) {
|
|
404
|
+
return array.reduce((chunks, item, index) => {
|
|
405
|
+
const chunkIndex = Math.floor(index / size);
|
|
406
|
+
chunks[chunkIndex] = (chunks[chunkIndex] || []).concat(item);
|
|
407
|
+
return chunks;
|
|
408
|
+
}, []);
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
function generateCompanyAppDataKey({ companyId, key, value }) {
|
|
412
|
+
return `conversations:${companyId}:${key}=${value}`;
|
|
413
|
+
}
|
|
@@ -7,11 +7,7 @@ import axios from 'axios';
|
|
|
7
7
|
import fs from 'fs';
|
|
8
8
|
import Twit from '@meltwater/social-twit';
|
|
9
9
|
|
|
10
|
-
import { fileURLToPath } from 'url';
|
|
11
|
-
import { dirname } from 'path';
|
|
12
10
|
|
|
13
|
-
const __filename = fileURLToPath(import.meta.url);
|
|
14
|
-
const __dirname = dirname(__filename);
|
|
15
11
|
|
|
16
12
|
export function addOAuthToToken(token, TWITTER_CONSUMER_KEY, TWITTER_CONSUMER_SECRET) {
|
|
17
13
|
if(!token.oauth){
|
|
@@ -610,8 +606,8 @@ async function downloadImage(url, fileName) {
|
|
|
610
606
|
}
|
|
611
607
|
|
|
612
608
|
// local
|
|
613
|
-
function generateFilePath(mimeType) {
|
|
614
|
-
let dir = `${
|
|
609
|
+
function generateFilePath(mimeType, dirname) {
|
|
610
|
+
let dir = `${dirname}/temporaryTwitterMedia`;
|
|
615
611
|
if (!fs.existsSync(dir)) {
|
|
616
612
|
fs.mkdirSync(dir);
|
|
617
613
|
}
|
|
@@ -625,7 +621,7 @@ function generateFilePath(mimeType) {
|
|
|
625
621
|
// local
|
|
626
622
|
async function uploadMedia(attachment, token, discussionType, logger) {
|
|
627
623
|
return new Promise(async (resolve, reject) => {
|
|
628
|
-
let filePath = generateFilePath(attachment.mimeType);
|
|
624
|
+
let filePath = generateFilePath(attachment.mimeType, attachment.__dirname);
|
|
629
625
|
await downloadImage(attachment.url, filePath);
|
|
630
626
|
const T = new Twit({
|
|
631
627
|
consumer_key: token.consumer_key,
|
package/src/data-access/index.js
CHANGED
|
@@ -8,7 +8,7 @@ import { FeatureToggleClient } from './http/featureToggleApi.client.js';
|
|
|
8
8
|
import { IdentityServicesClient } from './http/identityServices.client.js';
|
|
9
9
|
import { InstagramApiClient } from './http/instagramApi.client.js';
|
|
10
10
|
import { InstagramVideoClient } from './http/InstagramVideoClient.js';
|
|
11
|
-
import
|
|
11
|
+
import IRClient, * as IRClientHelpers from './http/ir.client.js';
|
|
12
12
|
import {
|
|
13
13
|
LinkedInApiClient,
|
|
14
14
|
getOrganization,
|
|
@@ -65,4 +65,5 @@ export default {
|
|
|
65
65
|
WarpZoneApiClient,
|
|
66
66
|
DocumentHelperFunctions,
|
|
67
67
|
LinkedInHelpers,
|
|
68
|
+
IRClientHelpers,
|
|
68
69
|
};
|