@meltwater/conversations-api-services 1.3.2 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/release.yml +4 -6
- package/CLAUDE.md +70 -0
- package/dist/cjs/data-access/http/facebook.native.js +122 -106
- package/dist/cjs/data-access/http/instagram.native.js +92 -49
- package/dist/cjs/data-access/http/linkedin.native.js +135 -56
- package/dist/cjs/data-access/http/threads.native.js +53 -18
- package/dist/cjs/data-access/http/tiktok.native.js +18 -12
- package/dist/cjs/data-access/http/twitter.native.js +142 -40
- package/dist/cjs/data-access/http/youtube.native.js +19 -13
- package/dist/esm/data-access/http/facebook.native.js +123 -107
- package/dist/esm/data-access/http/instagram.native.js +93 -50
- package/dist/esm/data-access/http/linkedin.native.js +136 -57
- package/dist/esm/data-access/http/threads.native.js +54 -19
- package/dist/esm/data-access/http/tiktok.native.js +19 -13
- package/dist/esm/data-access/http/twitter.native.js +143 -41
- package/dist/esm/data-access/http/youtube.native.js +20 -14
- package/package.json +1 -3
- package/src/data-access/http/README.md +50 -0
- package/src/data-access/http/facebook.native.js +122 -144
- package/src/data-access/http/instagram.native.js +113 -93
- package/src/data-access/http/linkedin.native.js +144 -83
- package/src/data-access/http/threads.native.js +58 -27
- package/src/data-access/http/tiktok.native.js +19 -39
- package/src/data-access/http/twitter.native.js +145 -65
- package/src/data-access/http/youtube.native.js +21 -40
- package/dist/cjs/lib/hiddenComment.helper.js +0 -119
- package/dist/esm/lib/hiddenComment.helper.js +0 -112
- package/src/lib/hiddenComment.helper.js +0 -107
|
@@ -21,20 +21,18 @@ jobs:
|
|
|
21
21
|
uses: actions/checkout@v3
|
|
22
22
|
with:
|
|
23
23
|
fetch-depth: 0
|
|
24
|
-
persist-
|
|
24
|
+
persist-credentials: false
|
|
25
25
|
token: ${{ secrets.GH_TOKEN }}
|
|
26
26
|
- name: Setup Node.js
|
|
27
|
-
uses: actions/setup-node@
|
|
27
|
+
uses: actions/setup-node@v4
|
|
28
28
|
with:
|
|
29
29
|
node-version: "lts/*"
|
|
30
|
-
- name: NPM Auth Setup
|
|
31
|
-
run: echo "//registry.npmjs.org/:_authToken=${{ secrets.NPM_TOKEN }}" > ~/.npmrc
|
|
32
30
|
- name: Install dependencies
|
|
31
|
+
env:
|
|
32
|
+
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
|
33
33
|
run: npm clean-install
|
|
34
34
|
- name: Run Babel Build
|
|
35
35
|
run: npm run build
|
|
36
|
-
- name: Verify signatures
|
|
37
|
-
run: npm audit signatures
|
|
38
36
|
- name: Release
|
|
39
37
|
env:
|
|
40
38
|
NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
|
package/CLAUDE.md
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# conversations-api-services — Claude Code Instructions
|
|
2
|
+
|
|
3
|
+
## `.native` files (`src/data-access/http/*.native.js`)
|
|
4
|
+
|
|
5
|
+
These modules call third-party social platform APIs (Instagram, Facebook, Twitter, etc.) that we do not control. Errors from these APIs are expected and noisy; they should **not** be treated as application errors.
|
|
6
|
+
|
|
7
|
+
### Logging rules for `.native` files
|
|
8
|
+
|
|
9
|
+
- **Never use `loggerError`** in `.native` files. Use `loggerInfo` instead.
|
|
10
|
+
- **`loggerWarn` is allowed** for expected/known failure cases (e.g. a comment that was probably deleted).
|
|
11
|
+
- **Every log call must include a `PAYLOADDATA` block** with all relevant context available at that point.
|
|
12
|
+
- **Never include tokens, access keys, or credentials** in `PAYLOADDATA`.
|
|
13
|
+
|
|
14
|
+
### Log message format
|
|
15
|
+
|
|
16
|
+
Log messages must follow this pattern:
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
'Failed to call <platform> api - <functionName>' // catch block (request threw)
|
|
20
|
+
'Failed to call <platform> api - <functionName> bad status' // non-200 status check
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
For example:
|
|
24
|
+
- `'Failed to call instagram api - requestApi'`
|
|
25
|
+
- `'Failed to call instagram api - getPost bad status'`
|
|
26
|
+
|
|
27
|
+
This makes logs searchable and distinguishable when multiple helper functions exist in the same file.
|
|
28
|
+
|
|
29
|
+
### PAYLOADDATA pattern
|
|
30
|
+
|
|
31
|
+
```js
|
|
32
|
+
import { loggerInfo, loggerWarn, MeltwaterAttributes } from '../../lib/logger.helpers.js';
|
|
33
|
+
|
|
34
|
+
// Catch block (request threw):
|
|
35
|
+
loggerInfo(logger, `Failed to call <platform> api - <functionName>`, {
|
|
36
|
+
[MeltwaterAttributes.PAYLOADDATA]: JSON.stringify({
|
|
37
|
+
apiUrl, // the URL called (no query string tokens)
|
|
38
|
+
someId, // any IDs relevant to the operation
|
|
39
|
+
error: err?.response?.body?.error?.message ?? err?.message,
|
|
40
|
+
}),
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// Non-200 status check:
|
|
44
|
+
loggerInfo(logger, `Failed to call <platform> api - <functionName> bad status`, {
|
|
45
|
+
[MeltwaterAttributes.PAYLOADDATA]: JSON.stringify({
|
|
46
|
+
apiUrl,
|
|
47
|
+
status: response.status,
|
|
48
|
+
responseBody: response.body,
|
|
49
|
+
}),
|
|
50
|
+
});
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
> **Do not pre-stringify nested objects** (e.g. `adCampaign`, `responseBody`) before passing them into `JSON.stringify({...})` — the outer call handles serialization. Pre-stringifying causes double-encoding.
|
|
54
|
+
|
|
55
|
+
### What to include in PAYLOADDATA
|
|
56
|
+
|
|
57
|
+
Include whichever of these are available and relevant to the function:
|
|
58
|
+
- `apiUrl` — the endpoint called
|
|
59
|
+
- `externalId`, `sourceId`, `inReplyToId`, `profileId` — IDs involved in the operation
|
|
60
|
+
- `discussionType`, `hideStatus`, `fields` — operation parameters
|
|
61
|
+
- `status` — HTTP response status code
|
|
62
|
+
- `responseBody` — response body on non-200 status
|
|
63
|
+
- `error` — the error message (`err?.response?.body?.error ?? err?.message`)
|
|
64
|
+
|
|
65
|
+
### What NOT to include
|
|
66
|
+
|
|
67
|
+
- `accessToken`, `token`, or any credential/key
|
|
68
|
+
- Raw `err` objects (extract `.message` instead)
|
|
69
|
+
|
|
70
|
+
See `instagram.native.js` as the reference implementation.
|
|
@@ -22,21 +22,12 @@ var _loggerHelpers = require("../../lib/logger.helpers.js");
|
|
|
22
22
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
23
23
|
const FACEBOOK_URL = 'https://graph.facebook.com';
|
|
24
24
|
async function shareCount(token, externalId, logger) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
return response.body.shares && response.body.shares.count;
|
|
28
|
-
} catch (error) {
|
|
29
|
-
(0, _loggerHelpers.loggerError)(logger, `Facebook shareCount error recieved - ${error.code}`, error);
|
|
30
|
-
}
|
|
25
|
+
const response = await getApi(`${FACEBOOK_URL}/${(0, _externalIdHelpers.removePrefix)(externalId)}/?fields=shares`, token, undefined, {}, logger);
|
|
26
|
+
return response.body.shares && response.body.shares.count;
|
|
31
27
|
}
|
|
32
28
|
async function reactions(token, externalIds, logger) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
return response.body;
|
|
36
|
-
} catch (error) {
|
|
37
|
-
(0, _loggerHelpers.loggerError)(logger, `Facebook reactions error recieved - ${error.code}`, error);
|
|
38
|
-
return undefined;
|
|
39
|
-
}
|
|
29
|
+
const response = await getApi(`${FACEBOOK_URL}?ids=${externalIds.map(externalId => (0, _externalIdHelpers.removePrefix)(externalId)).join(',')}&fields=` + `reactions.limit(0).summary(viewer_reaction).as(fb_post_reaction_of_user),` + `reactions.type(LOVE).limit(0).summary(total_count).as(fb_post_reactions_love),` + `reactions.type(WOW).limit(0).summary(total_count).as(fb_post_reactions_wow),` + `reactions.type(SAD).limit(0).summary(total_count).as(fb_post_reactions_sad),` + `reactions.type(LIKE).limit(0).summary(total_count).as(fb_post_reactions_like),` + `reactions.type(ANGRY).limit(0).summary(total_count).as(fb_post_reactions_angry),` + `reactions.type(HAHA).limit(0).summary(total_count).as(fb_post_reactions_haha)`, token, undefined, {}, logger);
|
|
30
|
+
return response.body;
|
|
40
31
|
}
|
|
41
32
|
async function comment(token, _ref) {
|
|
42
33
|
let {
|
|
@@ -83,8 +74,12 @@ async function privateMessage(token, _ref2, logger) {
|
|
|
83
74
|
});
|
|
84
75
|
const imageResponse = await _superagent.default.get(attachment.link).responseType('arrayBuffer');
|
|
85
76
|
if (imageResponse.status !== 200) {
|
|
86
|
-
(0, _loggerHelpers.
|
|
87
|
-
|
|
77
|
+
(0, _loggerHelpers.loggerInfo)(logger, 'Failed to fetch image from CDN', {
|
|
78
|
+
[_loggerHelpers.MeltwaterAttributes.PAYLOADDATA]: JSON.stringify({
|
|
79
|
+
recipientId,
|
|
80
|
+
status: imageResponse.status,
|
|
81
|
+
responseBody: imageResponse.body
|
|
82
|
+
})
|
|
88
83
|
});
|
|
89
84
|
throw new Error('Failed to fetch image from CDN');
|
|
90
85
|
}
|
|
@@ -180,37 +175,36 @@ async function unlike(token, externalId, logger) {
|
|
|
180
175
|
return response.body;
|
|
181
176
|
}
|
|
182
177
|
async function isUserBanned(token, authorId, pageId, logger) {
|
|
183
|
-
|
|
184
|
-
if
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
return user;
|
|
199
|
-
}
|
|
200
|
-
});
|
|
201
|
-
if (user) {
|
|
202
|
-
return true;
|
|
203
|
-
} else {
|
|
204
|
-
return false;
|
|
178
|
+
if (!pageId) {
|
|
179
|
+
// if no pageId to check this call will fail
|
|
180
|
+
// should only happen with temp edge docs
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
const response = await getApi(`${FACEBOOK_URL}/${pageId}/blocked`, token, undefined,
|
|
184
|
+
// payload
|
|
185
|
+
{
|
|
186
|
+
user: (0, _externalIdHelpers.removePrefix)(authorId)
|
|
187
|
+
}, logger);
|
|
188
|
+
if (response && response.body && response.body.data) {
|
|
189
|
+
const userNoPrefix = (0, _externalIdHelpers.removePrefix)(authorId);
|
|
190
|
+
const user = response.body.data.find(user => {
|
|
191
|
+
if (user.id == userNoPrefix) {
|
|
192
|
+
return user;
|
|
205
193
|
}
|
|
206
|
-
}
|
|
207
|
-
(0, _loggerHelpers.loggerInfo)(logger, `Native Facebook API is User Banned Response was invalid`, {
|
|
208
|
-
responseBody: JSON.stringify(response.body)
|
|
209
194
|
});
|
|
210
|
-
|
|
211
|
-
|
|
195
|
+
if (user) {
|
|
196
|
+
return true;
|
|
197
|
+
} else {
|
|
198
|
+
return false;
|
|
199
|
+
}
|
|
212
200
|
}
|
|
213
|
-
|
|
201
|
+
(0, _loggerHelpers.loggerInfo)(logger, `Native Facebook API is User Banned Response was invalid`, {
|
|
202
|
+
[_loggerHelpers.MeltwaterAttributes.PAYLOADDATA]: JSON.stringify({
|
|
203
|
+
authorId,
|
|
204
|
+
pageId,
|
|
205
|
+
responseBody: response.body
|
|
206
|
+
})
|
|
207
|
+
});
|
|
214
208
|
}
|
|
215
209
|
async function getProfile(token, authorId, fields, logger) {
|
|
216
210
|
if (!authorId) {
|
|
@@ -227,16 +221,21 @@ async function getProfile(token, authorId, fields, logger) {
|
|
|
227
221
|
try {
|
|
228
222
|
response = await _superagent.default.get(`${FACEBOOK_URL}/${userNoPrefix}`).set('Accept', 'application/json').set('Content-Type', 'application/json').query(queryParams).send();
|
|
229
223
|
} catch (err) {
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
224
|
+
(0, _loggerHelpers.loggerInfo)(logger, `Failed to call facebook api for userId`, {
|
|
225
|
+
[_loggerHelpers.MeltwaterAttributes.PAYLOADDATA]: JSON.stringify({
|
|
226
|
+
userNoPrefix,
|
|
227
|
+
error: err?.response?.body?.error?.message ?? err?.message
|
|
228
|
+
})
|
|
229
|
+
});
|
|
235
230
|
return null;
|
|
236
231
|
}
|
|
237
232
|
if (response.status !== 200) {
|
|
238
|
-
(0, _loggerHelpers.
|
|
239
|
-
|
|
233
|
+
(0, _loggerHelpers.loggerInfo)(logger, `Failed to call facebook api for userId`, {
|
|
234
|
+
[_loggerHelpers.MeltwaterAttributes.PAYLOADDATA]: JSON.stringify({
|
|
235
|
+
userNoPrefix,
|
|
236
|
+
status: response.status,
|
|
237
|
+
responseBody: response.body
|
|
238
|
+
})
|
|
240
239
|
});
|
|
241
240
|
let error = new Error(`Failed to call facebook api for userId ${userNoPrefix}`);
|
|
242
241
|
error.code = response.status;
|
|
@@ -266,49 +265,44 @@ async function unban(token, sourceId, authorId, logger) {
|
|
|
266
265
|
}
|
|
267
266
|
async function getAttachment(token, externalId, discussionType, logger) {
|
|
268
267
|
let result;
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
268
|
+
switch (discussionType) {
|
|
269
|
+
case 're':
|
|
270
|
+
case 'qt':
|
|
271
|
+
result = await getApi(`${FACEBOOK_URL}/${(0, _externalIdHelpers.removePrefix)(externalId)}?fields=attachment`, token, undefined, undefined, logger);
|
|
272
|
+
return {
|
|
273
|
+
images: [{
|
|
274
|
+
source: result?.body?.attachment?.media?.source || result?.body?.attachment?.media?.image?.src
|
|
275
|
+
}]
|
|
276
|
+
};
|
|
277
|
+
case 'dm':
|
|
278
|
+
result = await getApi(`${FACEBOOK_URL}/${(0, _externalIdHelpers.removePrefix)(externalId)}?fields=attachments`, token, undefined, undefined, logger);
|
|
279
|
+
return {
|
|
280
|
+
images: result?.body?.attachments?.data.map(item => {
|
|
281
|
+
return {
|
|
282
|
+
source: item.image_data?.url
|
|
283
|
+
};
|
|
284
|
+
})
|
|
285
|
+
};
|
|
286
|
+
default:
|
|
287
|
+
// og
|
|
288
|
+
result = await getApi(`${FACEBOOK_URL}/${(0, _externalIdHelpers.removePrefix)(externalId)}/attachments?fields=media,subattachments,file_url`, token, undefined, undefined, logger);
|
|
289
|
+
|
|
290
|
+
// if subattachments exist, use them
|
|
291
|
+
const res = result?.body?.data[0];
|
|
292
|
+
if (res?.subattachments) {
|
|
281
293
|
return {
|
|
282
|
-
images:
|
|
294
|
+
images: res?.subattachments.data.map(item => {
|
|
283
295
|
return {
|
|
284
|
-
source: item
|
|
296
|
+
source: item?.media?.source || item?.media?.image?.src
|
|
285
297
|
};
|
|
286
298
|
})
|
|
287
299
|
};
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
if (res?.subattachments) {
|
|
295
|
-
return {
|
|
296
|
-
images: res?.subattachments.data.map(item => {
|
|
297
|
-
return {
|
|
298
|
-
source: item?.media?.source || item?.media?.image?.src
|
|
299
|
-
};
|
|
300
|
-
})
|
|
301
|
-
};
|
|
302
|
-
}
|
|
303
|
-
return {
|
|
304
|
-
images: [{
|
|
305
|
-
source: res?.media?.source || res?.media?.image?.src
|
|
306
|
-
}]
|
|
307
|
-
};
|
|
308
|
-
}
|
|
309
|
-
} catch (error) {
|
|
310
|
-
(0, _loggerHelpers.loggerError)(logger, `Error getting facebook attachment`, error);
|
|
311
|
-
throw error;
|
|
300
|
+
}
|
|
301
|
+
return {
|
|
302
|
+
images: [{
|
|
303
|
+
source: res?.media?.source || res?.media?.image?.src
|
|
304
|
+
}]
|
|
305
|
+
};
|
|
312
306
|
}
|
|
313
307
|
}
|
|
314
308
|
async function getApi(apiUrl, accessToken, payload) {
|
|
@@ -321,16 +315,21 @@ async function getApi(apiUrl, accessToken, payload) {
|
|
|
321
315
|
...queryParams
|
|
322
316
|
}).send(payload);
|
|
323
317
|
} catch (err) {
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
318
|
+
(0, _loggerHelpers.loggerInfo)(logger, `Failed to call facebook getApi`, {
|
|
319
|
+
[_loggerHelpers.MeltwaterAttributes.PAYLOADDATA]: JSON.stringify({
|
|
320
|
+
apiUrl,
|
|
321
|
+
error: err?.response?.body?.error?.message ?? err?.message
|
|
322
|
+
})
|
|
323
|
+
});
|
|
329
324
|
throw err;
|
|
330
325
|
}
|
|
331
326
|
if (response.status !== 200) {
|
|
332
|
-
(0, _loggerHelpers.
|
|
333
|
-
|
|
327
|
+
(0, _loggerHelpers.loggerInfo)(logger, `Failed to call facebook api`, {
|
|
328
|
+
[_loggerHelpers.MeltwaterAttributes.PAYLOADDATA]: JSON.stringify({
|
|
329
|
+
apiUrl,
|
|
330
|
+
status: response.status,
|
|
331
|
+
responseBody: response.body
|
|
332
|
+
})
|
|
334
333
|
});
|
|
335
334
|
let error = new Error(`Failed to call facebook api ${apiUrl}`);
|
|
336
335
|
error.code = response.status;
|
|
@@ -364,7 +363,10 @@ async function postApi(apiUrl, accessToken, payload, logger) {
|
|
|
364
363
|
// Handle specific case where content is already marked as spam
|
|
365
364
|
if (err?.response?.body?.error?.error_subcode === 1446036 && err?.response?.body?.error?.error_user_title === "Duplicate Mark Spam Request") {
|
|
366
365
|
(0, _loggerHelpers.loggerInfo)(logger, `Content already marked as spam - treating as successful hide operation`, {
|
|
367
|
-
|
|
366
|
+
[_loggerHelpers.MeltwaterAttributes.PAYLOADDATA]: JSON.stringify({
|
|
367
|
+
apiUrl,
|
|
368
|
+
responseBody: err.response.body
|
|
369
|
+
})
|
|
368
370
|
});
|
|
369
371
|
return {
|
|
370
372
|
status: 200,
|
|
@@ -374,12 +376,21 @@ async function postApi(apiUrl, accessToken, payload, logger) {
|
|
|
374
376
|
}
|
|
375
377
|
};
|
|
376
378
|
}
|
|
377
|
-
(0, _loggerHelpers.loggerDebug)(logger, `Failed to call facebook api`,
|
|
379
|
+
(0, _loggerHelpers.loggerDebug)(logger, `Failed to call facebook api`, {
|
|
380
|
+
[_loggerHelpers.MeltwaterAttributes.PAYLOADDATA]: JSON.stringify({
|
|
381
|
+
apiUrl,
|
|
382
|
+
error: err?.message
|
|
383
|
+
})
|
|
384
|
+
});
|
|
378
385
|
throw err;
|
|
379
386
|
}
|
|
380
387
|
if (response.status !== 200) {
|
|
381
|
-
(0, _loggerHelpers.
|
|
382
|
-
|
|
388
|
+
(0, _loggerHelpers.loggerInfo)(logger, `Failed to call facebook api`, {
|
|
389
|
+
[_loggerHelpers.MeltwaterAttributes.PAYLOADDATA]: JSON.stringify({
|
|
390
|
+
apiUrl,
|
|
391
|
+
status: response.status,
|
|
392
|
+
responseBody: response.body
|
|
393
|
+
})
|
|
383
394
|
});
|
|
384
395
|
throw new Error(`Failed to call facebook api ${response.body}`);
|
|
385
396
|
}
|
|
@@ -392,16 +403,21 @@ async function deleteApi(apiUrl, accessToken, payload, logger) {
|
|
|
392
403
|
access_token: accessToken
|
|
393
404
|
}).send(payload);
|
|
394
405
|
} catch (err) {
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
406
|
+
(0, _loggerHelpers.loggerInfo)(logger, `Failed to call facebook api delete`, {
|
|
407
|
+
[_loggerHelpers.MeltwaterAttributes.PAYLOADDATA]: JSON.stringify({
|
|
408
|
+
apiUrl,
|
|
409
|
+
error: err?.response?.body?.error?.message ?? err?.message
|
|
410
|
+
})
|
|
411
|
+
});
|
|
400
412
|
throw err;
|
|
401
413
|
}
|
|
402
414
|
if (response.status !== 200) {
|
|
403
|
-
(0, _loggerHelpers.
|
|
404
|
-
|
|
415
|
+
(0, _loggerHelpers.loggerInfo)(logger, `Failed to call facebook api delete`, {
|
|
416
|
+
[_loggerHelpers.MeltwaterAttributes.PAYLOADDATA]: JSON.stringify({
|
|
417
|
+
apiUrl,
|
|
418
|
+
status: response.status,
|
|
419
|
+
responseBody: response.body
|
|
420
|
+
})
|
|
405
421
|
});
|
|
406
422
|
let error = new Error(`Failed to call facebook api delete`);
|
|
407
423
|
error.code = response.status;
|
|
@@ -38,16 +38,26 @@ async function requestApi(apiUrl, accessToken, text, data) {
|
|
|
38
38
|
response = await _superagent.default.post(apiUrl).set('Accept', 'application/json').set('Content-Type', 'application/json').send(data);
|
|
39
39
|
}
|
|
40
40
|
} catch (err) {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
41
|
+
(0, _loggerHelpers.loggerInfo)(logger, `Failed to call instagram api - requestApi`, {
|
|
42
|
+
[_loggerHelpers.MeltwaterAttributes.PAYLOADDATA]: JSON.stringify({
|
|
43
|
+
apiUrl,
|
|
44
|
+
discussionType,
|
|
45
|
+
adCampaign: adCampaign || undefined,
|
|
46
|
+
text: text || undefined,
|
|
47
|
+
error: err?.response?.body?.error?.message ?? err?.message
|
|
48
|
+
})
|
|
49
|
+
});
|
|
46
50
|
throw err;
|
|
47
51
|
}
|
|
48
52
|
if (response.status !== 200) {
|
|
49
|
-
(0, _loggerHelpers.
|
|
50
|
-
|
|
53
|
+
(0, _loggerHelpers.loggerInfo)(logger, `Failed to call instagram api - requestApi bad status`, {
|
|
54
|
+
[_loggerHelpers.MeltwaterAttributes.PAYLOADDATA]: JSON.stringify({
|
|
55
|
+
apiUrl,
|
|
56
|
+
discussionType,
|
|
57
|
+
adCampaign: adCampaign || undefined,
|
|
58
|
+
status: response.status,
|
|
59
|
+
responseBody: response.body
|
|
60
|
+
})
|
|
51
61
|
});
|
|
52
62
|
let error = new Error(`Failed to call instagram api`);
|
|
53
63
|
error.code = response.status;
|
|
@@ -65,16 +75,24 @@ async function getPost(apiUrl, accessToken, fields, logger) {
|
|
|
65
75
|
fields: fields
|
|
66
76
|
}).send();
|
|
67
77
|
} catch (err) {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
}
|
|
78
|
+
const errObject = {
|
|
79
|
+
apiUrl,
|
|
80
|
+
fields,
|
|
81
|
+
error: err?.response?.body?.error ?? err?.message
|
|
82
|
+
};
|
|
83
|
+
(0, _loggerHelpers.loggerInfo)(logger, `Failed to call instagram api - getPost`, {
|
|
84
|
+
[_loggerHelpers.MeltwaterAttributes.PAYLOADDATA]: JSON.stringify(errObject)
|
|
85
|
+
});
|
|
73
86
|
throw err;
|
|
74
87
|
}
|
|
75
88
|
if (response.status !== 200) {
|
|
76
|
-
(0, _loggerHelpers.
|
|
77
|
-
|
|
89
|
+
(0, _loggerHelpers.loggerInfo)(logger, `Failed to call instagram api - getPost bad status`, {
|
|
90
|
+
[_loggerHelpers.MeltwaterAttributes.PAYLOADDATA]: JSON.stringify({
|
|
91
|
+
apiUrl,
|
|
92
|
+
fields,
|
|
93
|
+
status: response.status,
|
|
94
|
+
responseBody: response.body
|
|
95
|
+
})
|
|
78
96
|
});
|
|
79
97
|
let error = new Error(`Failed to call instagram api`);
|
|
80
98
|
error.code = response.status;
|
|
@@ -88,7 +106,13 @@ async function getMessageData(accessToken, sourceId, inReplyToId, logger) {
|
|
|
88
106
|
response = await getPost(`${INSTAGRAM_URL}/${sourceId}`, accessToken, `mentioned_comment.comment_id(${inReplyToId}){id, text, timestamp, media{id,media_url}}`, logger);
|
|
89
107
|
return response.body;
|
|
90
108
|
} catch (err) {
|
|
91
|
-
(0, _loggerHelpers.
|
|
109
|
+
(0, _loggerHelpers.loggerInfo)(logger, `Failed to call instagram api - getMessageData`, {
|
|
110
|
+
[_loggerHelpers.MeltwaterAttributes.PAYLOADDATA]: JSON.stringify({
|
|
111
|
+
sourceId,
|
|
112
|
+
inReplyToId,
|
|
113
|
+
error: err?.message
|
|
114
|
+
})
|
|
115
|
+
});
|
|
92
116
|
return null;
|
|
93
117
|
}
|
|
94
118
|
}
|
|
@@ -101,16 +125,25 @@ async function mentionRequestApi(apiUrl, accessToken, replayObject, text, logger
|
|
|
101
125
|
message: text
|
|
102
126
|
}).send();
|
|
103
127
|
} catch (err) {
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
128
|
+
const errObject = {
|
|
129
|
+
apiUrl,
|
|
130
|
+
replayObject,
|
|
131
|
+
text,
|
|
132
|
+
error: err?.response?.body?.error?.message ?? err?.message
|
|
133
|
+
};
|
|
134
|
+
(0, _loggerHelpers.loggerInfo)(logger, `Failed to call instagram api - mentionRequestApi`, {
|
|
135
|
+
[_loggerHelpers.MeltwaterAttributes.PAYLOADDATA]: JSON.stringify(errObject)
|
|
136
|
+
});
|
|
109
137
|
throw err;
|
|
110
138
|
}
|
|
111
139
|
if (response.status !== 200) {
|
|
112
|
-
(0, _loggerHelpers.
|
|
113
|
-
|
|
140
|
+
(0, _loggerHelpers.loggerInfo)(logger, `Failed to call instagram api - mentionRequestApi bad status`, {
|
|
141
|
+
[_loggerHelpers.MeltwaterAttributes.PAYLOADDATA]: JSON.stringify({
|
|
142
|
+
apiUrl,
|
|
143
|
+
replayObject,
|
|
144
|
+
status: response.status,
|
|
145
|
+
responseBody: response.body
|
|
146
|
+
})
|
|
114
147
|
});
|
|
115
148
|
let error = new Error(`Failed to call instagram api`);
|
|
116
149
|
error.code = response.status;
|
|
@@ -127,16 +160,24 @@ async function hideApi(apiUrl, accessToken, hideStatus, logger) {
|
|
|
127
160
|
hide: hideStatus
|
|
128
161
|
}).send();
|
|
129
162
|
} catch (err) {
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
}
|
|
163
|
+
const errObject = {
|
|
164
|
+
apiUrl,
|
|
165
|
+
hideStatus,
|
|
166
|
+
error: err?.response?.body?.error ?? err?.message
|
|
167
|
+
};
|
|
168
|
+
(0, _loggerHelpers.loggerInfo)(logger, `Failed to call instagram api - hideApi`, {
|
|
169
|
+
[_loggerHelpers.MeltwaterAttributes.PAYLOADDATA]: JSON.stringify(errObject)
|
|
170
|
+
});
|
|
135
171
|
throw err;
|
|
136
172
|
}
|
|
137
173
|
if (response.status !== 200) {
|
|
138
|
-
(0, _loggerHelpers.
|
|
139
|
-
|
|
174
|
+
(0, _loggerHelpers.loggerInfo)(logger, `Failed to call instagram api - hideApi bad status`, {
|
|
175
|
+
[_loggerHelpers.MeltwaterAttributes.PAYLOADDATA]: JSON.stringify({
|
|
176
|
+
apiUrl,
|
|
177
|
+
hideStatus,
|
|
178
|
+
status: response.status,
|
|
179
|
+
responseBody: response.body
|
|
180
|
+
})
|
|
140
181
|
});
|
|
141
182
|
let error = new Error(`Failed to call instagram api`);
|
|
142
183
|
error.code = response.status;
|
|
@@ -154,10 +195,17 @@ async function getLikes(accessToken, externalId, logger) {
|
|
|
154
195
|
});
|
|
155
196
|
return response.body;
|
|
156
197
|
} catch (err) {
|
|
198
|
+
const errPayload = {
|
|
199
|
+
[_loggerHelpers.MeltwaterAttributes.PAYLOADDATA]: JSON.stringify({
|
|
200
|
+
externalId,
|
|
201
|
+
status: err?.status,
|
|
202
|
+
error: err?.message
|
|
203
|
+
})
|
|
204
|
+
};
|
|
157
205
|
if (err?.status === 400) {
|
|
158
|
-
(0, _loggerHelpers.loggerWarn)(logger, 'Warn getLikes Instagram Comment probably deleted on native',
|
|
206
|
+
(0, _loggerHelpers.loggerWarn)(logger, 'Warn getLikes Instagram Comment probably deleted on native', errPayload);
|
|
159
207
|
} else {
|
|
160
|
-
(0, _loggerHelpers.
|
|
208
|
+
(0, _loggerHelpers.loggerInfo)(logger, 'Error getLikes Instagram', errPayload);
|
|
161
209
|
}
|
|
162
210
|
return 0;
|
|
163
211
|
}
|
|
@@ -270,25 +318,20 @@ async function unhide(accessToken, externalId, logger) {
|
|
|
270
318
|
return response.body;
|
|
271
319
|
}
|
|
272
320
|
async function getAttachment(token, externalId, logger) {
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
if (res?.children?.data?.length) {
|
|
277
|
-
return {
|
|
278
|
-
images: res.children.data.map(item => {
|
|
279
|
-
return {
|
|
280
|
-
source: item?.media_url
|
|
281
|
-
};
|
|
282
|
-
})
|
|
283
|
-
};
|
|
284
|
-
}
|
|
321
|
+
const result = await getPost(`${INSTAGRAM_URL}/${(0, _externalIdHelpers.removePrefix)(externalId)}`, token, 'media_url,children{media_url}', logger);
|
|
322
|
+
const res = result.body;
|
|
323
|
+
if (res?.children?.data?.length) {
|
|
285
324
|
return {
|
|
286
|
-
images:
|
|
287
|
-
|
|
288
|
-
|
|
325
|
+
images: res.children.data.map(item => {
|
|
326
|
+
return {
|
|
327
|
+
source: item?.media_url
|
|
328
|
+
};
|
|
329
|
+
})
|
|
289
330
|
};
|
|
290
|
-
} catch (error) {
|
|
291
|
-
(0, _loggerHelpers.loggerError)(logger, `Error getting instagram attachment`, error);
|
|
292
|
-
throw error;
|
|
293
331
|
}
|
|
332
|
+
return {
|
|
333
|
+
images: [{
|
|
334
|
+
source: res?.media_url
|
|
335
|
+
}]
|
|
336
|
+
};
|
|
294
337
|
}
|