@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.
- package/.github/workflows/release.yml +2 -0
- package/babel.config.js +18 -0
- package/dist/cjs/data-access/http/InstagramVideoClient.js +42 -0
- package/dist/cjs/data-access/http/WarpZoneApi.client.js +32 -0
- package/dist/cjs/data-access/http/amazonS3.js +44 -0
- package/dist/cjs/data-access/http/asset-manager-tvm.client.js +35 -0
- package/dist/cjs/data-access/http/companiesApi.client.js +38 -0
- package/dist/cjs/data-access/http/credentialsApi.client.js +102 -0
- package/dist/cjs/data-access/http/entitlementsApi.client.js +40 -0
- package/dist/cjs/data-access/http/facebook.native.js +344 -0
- package/dist/cjs/data-access/http/facebookApi.client.js +631 -0
- package/dist/cjs/data-access/http/featureToggleApi.client.js +31 -0
- package/dist/cjs/data-access/http/identityServices.client.js +97 -0
- package/dist/cjs/data-access/http/instagramApi.client.js +428 -0
- package/dist/cjs/data-access/http/ir.client.js +242 -0
- package/dist/cjs/data-access/http/linkedInApi.client.js +491 -0
- package/dist/cjs/data-access/http/masf.client.js +101 -0
- package/dist/cjs/data-access/http/tiktok.native.js +162 -0
- package/dist/cjs/data-access/http/tiktokApi.client.js +441 -0
- package/dist/cjs/data-access/index.js +132 -0
- package/dist/cjs/errors/engage-error.js +16 -0
- package/dist/cjs/errors/http-error.js +23 -0
- package/dist/cjs/lib/applicationTags.helpers.js +30 -0
- package/dist/cjs/lib/configuration.js +14 -0
- package/dist/cjs/lib/document-action-events.js +12 -0
- package/dist/cjs/lib/externalId.helpers.js +19 -0
- package/dist/cjs/lib/hidden.helpers.js +13 -0
- package/dist/cjs/lib/hiddenComment.helper.js +119 -0
- package/dist/cjs/lib/logger.helpers.js +68 -0
- package/dist/cjs/lib/logger.js +23 -0
- package/dist/cjs/lib/message.helpers.js +58 -0
- package/dist/cjs/lib/metrics.helper.js +97 -0
- package/dist/esm/data-access/http/InstagramVideoClient.js +34 -0
- package/dist/esm/data-access/http/WarpZoneApi.client.js +24 -0
- package/dist/esm/data-access/http/amazonS3.js +37 -0
- package/dist/esm/data-access/http/asset-manager-tvm.client.js +28 -0
- package/dist/esm/data-access/http/companiesApi.client.js +30 -0
- package/dist/esm/data-access/http/credentialsApi.client.js +92 -0
- package/dist/esm/data-access/http/entitlementsApi.client.js +32 -0
- package/dist/esm/data-access/http/facebook.native.js +325 -0
- package/dist/esm/data-access/http/facebookApi.client.js +621 -0
- package/dist/esm/data-access/http/featureToggleApi.client.js +23 -0
- package/dist/esm/data-access/http/identityServices.client.js +89 -0
- package/dist/esm/data-access/http/instagramApi.client.js +420 -0
- package/dist/esm/data-access/http/ir.client.js +234 -0
- package/dist/esm/data-access/http/linkedInApi.client.js +481 -0
- package/dist/esm/data-access/http/masf.client.js +93 -0
- package/dist/esm/data-access/http/tiktok.native.js +146 -0
- package/dist/esm/data-access/http/tiktokApi.client.js +433 -0
- package/dist/esm/data-access/index.js +30 -0
- package/dist/esm/errors/engage-error.js +9 -0
- package/dist/esm/errors/http-error.js +16 -0
- package/dist/esm/lib/applicationTags.helpers.js +22 -0
- package/dist/esm/lib/configuration.js +8 -0
- package/dist/esm/lib/document-action-events.js +6 -0
- package/dist/esm/lib/externalId.helpers.js +12 -0
- package/dist/esm/lib/hidden.helpers.js +6 -0
- package/dist/esm/lib/hiddenComment.helper.js +112 -0
- package/dist/esm/lib/logger.helpers.js +60 -0
- package/dist/esm/lib/logger.js +16 -0
- package/dist/esm/lib/message.helpers.js +52 -0
- package/dist/esm/lib/metrics.helper.js +90 -0
- package/package.json +14 -4
- package/src/data-access/http/facebook.native.js +542 -0
- package/src/data-access/http/tiktok.native.js +248 -0
- package/src/data-access/index.js +4 -0
- package/src/errors/engage-error.js +11 -0
- package/src/errors/http-error.js +19 -0
- package/src/lib/logger.helpers.js +15 -0
- package/src/lib/message.helpers.js +7 -1
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
Object.defineProperty(exports, "__esModule", {
|
|
4
|
+
value: true
|
|
5
|
+
});
|
|
6
|
+
exports.IRClient = void 0;
|
|
7
|
+
var _uuid = require("uuid");
|
|
8
|
+
var _superagent = _interopRequireDefault(require("superagent"));
|
|
9
|
+
var _logger = _interopRequireDefault(require("../../lib/logger.js"));
|
|
10
|
+
var _configuration = _interopRequireDefault(require("../../lib/configuration.js"));
|
|
11
|
+
var _metricsHelper = require("../../lib/metrics.helper.js");
|
|
12
|
+
var _loggerHelpers = require("../../lib/logger.helpers.js");
|
|
13
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
14
|
+
class IRClient {
|
|
15
|
+
RETRY_COUNT = 50;
|
|
16
|
+
constructor(context) {
|
|
17
|
+
const {
|
|
18
|
+
company,
|
|
19
|
+
user,
|
|
20
|
+
traceId,
|
|
21
|
+
metrics
|
|
22
|
+
} = context;
|
|
23
|
+
this.company = company;
|
|
24
|
+
this.user = user;
|
|
25
|
+
this.traceId = traceId;
|
|
26
|
+
this.metrics = metrics;
|
|
27
|
+
}
|
|
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
|
+
async addRevisionsToDocuments(operations) {
|
|
39
|
+
await this.init();
|
|
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;
|
|
63
|
+
}
|
|
64
|
+
async modifyDocuments(operations) {
|
|
65
|
+
let retryAttempt = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
|
|
66
|
+
await this.init();
|
|
67
|
+
const wait = 100;
|
|
68
|
+
const url = `${this.documentServiceUrl}/`;
|
|
69
|
+
const loggerChild = _logger.default.child({
|
|
70
|
+
[_loggerHelpers.MeltwaterAttributes.COMPANYID]: this.company._id
|
|
71
|
+
});
|
|
72
|
+
let result;
|
|
73
|
+
try {
|
|
74
|
+
result = await _superagent.default.patch(url).query({
|
|
75
|
+
wait,
|
|
76
|
+
apikey: this.documentServiceKey
|
|
77
|
+
}).set('x-client-name', 'engage-conversations').send(operations).then(result => result.body);
|
|
78
|
+
} catch (err) {
|
|
79
|
+
retryAttempt++;
|
|
80
|
+
if (retryAttempt > this.RETRY_COUNT) {
|
|
81
|
+
loggerChild.error(`Maximum Retrys hit for method modifyDocuments ${err.status} ${err.message}`, err, {
|
|
82
|
+
[_loggerHelpers.MeltwaterAttributes.COMPANYID]: this.company._id
|
|
83
|
+
});
|
|
84
|
+
} else if (await this.retryBecauseRateLimiting(err, 'modifyDocuments')) {
|
|
85
|
+
return await this.modifyDocuments(operations, retryAttempt);
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
loggerChild.info(`Finished modifying documents operations`, {
|
|
89
|
+
operations: JSON.stringify(operations)
|
|
90
|
+
});
|
|
91
|
+
return result;
|
|
92
|
+
}
|
|
93
|
+
async getDocumentById(id) {
|
|
94
|
+
let retryAttempt = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
|
|
95
|
+
await this.init();
|
|
96
|
+
try {
|
|
97
|
+
const uri = `${this.documentServiceUrl}/${id}/revisions/${this.company._id}?apikey=${this.documentServiceKey}`;
|
|
98
|
+
const metric = this.metrics.count(metricNames.irGetByDocumentId);
|
|
99
|
+
const result = await _superagent.default.get(uri);
|
|
100
|
+
this.metrics.finishOperation(metricNames.irGetByDocumentId, metric);
|
|
101
|
+
return result.body;
|
|
102
|
+
} catch (err) {
|
|
103
|
+
retryAttempt++;
|
|
104
|
+
if (retryAttempt > this.RETRY_COUNT) {
|
|
105
|
+
_logger.default.error(`Maximum Retrys hit for method getDocumentById ${err.status} ${err.message}`, err, {
|
|
106
|
+
[_loggerHelpers.MeltwaterAttributes.COMPANYID]: this.company._id
|
|
107
|
+
});
|
|
108
|
+
} else if (await this.retryBecauseRateLimiting(err, 'getDocumentById')) {
|
|
109
|
+
return await this.getDocumentById(id, retryAttempt);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
async retryBecauseRateLimiting(err, name) {
|
|
114
|
+
const loggerChild = _logger.default.child({
|
|
115
|
+
[_loggerHelpers.MeltwaterAttributes.COMPANYID]: this.company._id
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
// rate limit error
|
|
119
|
+
if (err.status === 429) {
|
|
120
|
+
this.metrics.count(metricNames.irRatelimited);
|
|
121
|
+
loggerChild.error(`Error Accessing ir.client method because rate limit: trying again ${name}`, err);
|
|
122
|
+
// should not be hitting rate limit in production
|
|
123
|
+
// this is a patch for staging testing
|
|
124
|
+
await new Promise(resolve => setTimeout(resolve, 100));
|
|
125
|
+
return true;
|
|
126
|
+
}
|
|
127
|
+
if (err.status == 404) {
|
|
128
|
+
loggerChild.info(`Document Not Found ir.client method ${name} ${err.status} ${err.message}`, err);
|
|
129
|
+
} else {
|
|
130
|
+
loggerChild.info(`Could not access ir.client method ${name} ${err.status} ${err.message}`, err);
|
|
131
|
+
}
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
async export(rune) {
|
|
135
|
+
await this.init();
|
|
136
|
+
const traceId = this.generateTraceId();
|
|
137
|
+
try {
|
|
138
|
+
let uri = `${this.exportApiUrl}?apikey=${this.exportApiKey}`;
|
|
139
|
+
_logger.default.info(`Starting call to : ${this.exportApiUrl}`, {
|
|
140
|
+
rune
|
|
141
|
+
});
|
|
142
|
+
this.addCompanyToRuneForHorace(rune);
|
|
143
|
+
let result = await _superagent.default.post(uri).query({
|
|
144
|
+
traceId
|
|
145
|
+
}).send(rune);
|
|
146
|
+
_logger.default.info(`Finished calling Export API: ${result.body.exportKey}`, {
|
|
147
|
+
irTraceId: traceId
|
|
148
|
+
});
|
|
149
|
+
return result.body.exportKey;
|
|
150
|
+
} catch (err) {
|
|
151
|
+
_logger.default.error('Error executing search against Export API', err);
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
async search(rune) {
|
|
155
|
+
await this.init();
|
|
156
|
+
const traceId = this.generateTraceId();
|
|
157
|
+
try {
|
|
158
|
+
let uri = `${this.searchServicesUrl}?apikey=${this.searchServicesKey}`;
|
|
159
|
+
|
|
160
|
+
// todo: remove changing rune searchResults size
|
|
161
|
+
// todo: remove reduce ( dedupes and trims to original rune limit )
|
|
162
|
+
// rune limit is a bandaid, hopefully better solution can be worked out with Horace
|
|
163
|
+
let limitActual = rune.viewRequests.searchResults.size;
|
|
164
|
+
rune.viewRequests.searchResults.size = limitActual * 2;
|
|
165
|
+
this.addCompanyToRuneForHorace(rune);
|
|
166
|
+
const metric = this.metrics.count(metricNames.irSearch);
|
|
167
|
+
let result = await _superagent.default.post(uri).query({
|
|
168
|
+
traceId
|
|
169
|
+
}).send(rune);
|
|
170
|
+
this.metrics.finishOperation(metricNames.irSearch, metric);
|
|
171
|
+
rune.viewRequests.searchResults.size = limitActual;
|
|
172
|
+
const finalResults = result.body.views.searchResults.results.reduce((acc, document, index) => {
|
|
173
|
+
if (!index || acc.length <= limitActual && acc[acc.length - 1].documentId !== document.quiddity.id) {
|
|
174
|
+
acc.push(document.quiddity);
|
|
175
|
+
} else if (index && acc.length <= limitActual && acc[acc.length - 1].documentId === document.quiddity.id) {
|
|
176
|
+
_logger.default.info(`Duplicates in IR Search Results for DocumentId`, {
|
|
177
|
+
irTraceId: traceId,
|
|
178
|
+
document: JSON.stringify(document),
|
|
179
|
+
[_loggerHelpers.MeltwaterAttributes.DOCUMENTID]: document.quiddity.id
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
return acc;
|
|
183
|
+
}, []);
|
|
184
|
+
_logger.default.info(`Final Results Calculated, ${finalResults ? finalResults.length : 'no results'}`, {
|
|
185
|
+
irTraceId: traceId,
|
|
186
|
+
rune
|
|
187
|
+
});
|
|
188
|
+
return finalResults;
|
|
189
|
+
// original return function
|
|
190
|
+
// return result.body.views.searchResults.results.map(document => {
|
|
191
|
+
// return document.quiddity;
|
|
192
|
+
// })
|
|
193
|
+
} catch (err) {
|
|
194
|
+
_logger.default.error('Error executing search against Search Service', err, {
|
|
195
|
+
irTraceId: traceId,
|
|
196
|
+
rune
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
async latest(rune) {
|
|
201
|
+
let retryAttempt = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 0;
|
|
202
|
+
try {
|
|
203
|
+
const result = await this.executeSearch(rune);
|
|
204
|
+
return result.body.views.searchResults.results.length && [result.body.views.searchResults.results[0].quiddity] || [];
|
|
205
|
+
} catch (err) {
|
|
206
|
+
retryAttempt++;
|
|
207
|
+
if (retryAttempt > this.RETRY_COUNT) {
|
|
208
|
+
_logger.default.error(`Maximum Retrys hit for method latest ${err.status} ${err.message}`, err, {
|
|
209
|
+
[_loggerHelpers.MeltwaterAttributes.COMPANYID]: this.company._id
|
|
210
|
+
});
|
|
211
|
+
} else if (await this.retryBecauseRateLimiting(err, 'latest')) {
|
|
212
|
+
return await this.latest(rune, retryAttempt);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
async count(rune) {
|
|
217
|
+
try {
|
|
218
|
+
const result = await this.executeSearch(rune);
|
|
219
|
+
return result.body.views.documentCount.totalCount;
|
|
220
|
+
} catch (err) {
|
|
221
|
+
_logger.default.error('Error getting count from Search Service', err);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
async executeSearch(rune) {
|
|
225
|
+
await this.init();
|
|
226
|
+
this.addCompanyToRuneForHorace(rune);
|
|
227
|
+
const uri = `${this.searchServicesUrl}?apikey=${this.searchServicesKey}`;
|
|
228
|
+
return await _superagent.default.post(uri).send(rune);
|
|
229
|
+
}
|
|
230
|
+
addCompanyToRuneForHorace(rune) {
|
|
231
|
+
if (!rune.metaData) {
|
|
232
|
+
rune.metaData = {};
|
|
233
|
+
}
|
|
234
|
+
|
|
235
|
+
// Horace requires this for tracking purposes
|
|
236
|
+
rune.metaData.companyId = this.company._id;
|
|
237
|
+
}
|
|
238
|
+
generateTraceId() {
|
|
239
|
+
return `engage_${this.company._id}_${this.traceId}_${(0, _uuid.v4)()}`;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
exports.IRClient = IRClient;
|