@meltwater/conversations-api-services 1.0.25 → 1.0.26

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.
@@ -0,0 +1,286 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.comment = comment;
7
+ exports.commentOnMention = commentOnMention;
8
+ exports.getAttachment = getAttachment;
9
+ exports.getLikes = getLikes;
10
+ exports.hide = hide;
11
+ exports.privateMessage = privateMessage;
12
+ exports.reply = reply;
13
+ exports.replyOnMention = replyOnMention;
14
+ exports.unhide = unhide;
15
+ var _superagent = _interopRequireDefault(require("superagent"));
16
+ var _externalIdHelpers = require("../../lib/externalId.helpers.js");
17
+ var _loggerHelpers = require("../../lib/logger.helpers.js");
18
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
19
+ const INSTAGRAM_URL = 'https://graph.facebook.com';
20
+ async function requestApi(apiUrl, accessToken, text, data) {
21
+ let discussionType = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 're';
22
+ let adCampaign = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : undefined;
23
+ let logger = arguments.length > 6 ? arguments[6] : undefined;
24
+ let response = {};
25
+ try {
26
+ let queryStringArgs = {
27
+ access_token: accessToken
28
+ };
29
+ if (adCampaign) {
30
+ queryStringArgs.ad_id = adCampaign.adAccountId;
31
+ }
32
+ if (text) {
33
+ queryStringArgs[discussionType === 'dm' ? 'text' : 'message'] = text;
34
+ }
35
+ response = await _superagent.default.post(apiUrl).set('Accept', 'application/json').set('Content-Type', 'application/json').query(queryStringArgs).send(data);
36
+ } catch (err) {
37
+ if (err && err.response && err.response.body && err.response.body.error) {
38
+ (0, _loggerHelpers.loggerError)(logger, `Failed to call instagram api: ${err.response.body.error.message}`);
39
+ } else {
40
+ (0, _loggerHelpers.loggerError)(logger, `Failed to call instagram api`, err);
41
+ }
42
+ throw err;
43
+ }
44
+ if (response.status !== 200) {
45
+ (0, _loggerHelpers.loggerError)(logger, `Failed to call instagram api`, {
46
+ responseBody: JSON.stringify(response.body)
47
+ });
48
+ let error = new Error(`Failed to call instagram api`);
49
+ error.code = response.status;
50
+ throw error;
51
+ }
52
+ (0, _loggerHelpers.loggerDebug)(logger, 'Instagram Response status', response.status);
53
+ return response;
54
+ }
55
+ async function getPost(apiUrl, accessToken, fields, logger) {
56
+ let response = {};
57
+ try {
58
+ response = await _superagent.default.get(apiUrl).set('Accept', 'application/json').set('Content-Type', 'application/json').query({
59
+ access_token: accessToken
60
+ }).query({
61
+ fields: fields
62
+ }).send();
63
+ } catch (err) {
64
+ if (err && err.response && err.response.body) {
65
+ (0, _loggerHelpers.loggerError)(logger, `Failed to call instagram api`, err.response.body.error);
66
+ } else {
67
+ (0, _loggerHelpers.loggerError)(logger, `Failed to call instagram api`, err);
68
+ }
69
+ throw err;
70
+ }
71
+ if (response.status !== 200) {
72
+ (0, _loggerHelpers.loggerError)(logger, `Failed to call instagram api`, {
73
+ responseBody: JSON.stringify(response.body)
74
+ });
75
+ let error = new Error(`Failed to call instagram api`);
76
+ error.code = response.status;
77
+ throw error;
78
+ }
79
+ return response;
80
+ }
81
+ async function getMessageData(accessToken, sourceId, inReplyToId, logger) {
82
+ let response;
83
+ try {
84
+ response = await getPost(`${INSTAGRAM_URL}/${sourceId}`, accessToken, `mentioned_comment.comment_id(${inReplyToId}){id, text, timestamp, media{id,media_url}}`, logger);
85
+ return response.body;
86
+ } catch (err) {
87
+ (0, _loggerHelpers.loggerError)(logger, `Failed to call instagram api`, err);
88
+ return null;
89
+ }
90
+ }
91
+ async function mentionRequestApi(apiUrl, accessToken, replayObject, text, logger) {
92
+ let response = {};
93
+ try {
94
+ response = await _superagent.default.post(apiUrl).set('Accept', 'application/json').set('Content-Type', 'application/json').query({
95
+ access_token: accessToken
96
+ }).query(replayObject).query({
97
+ message: text
98
+ }).send();
99
+ } catch (err) {
100
+ if (err && err.response && err.response.body && err.response.body.error) {
101
+ (0, _loggerHelpers.loggerError)(logger, `Failed to call instagram api: ${err.response.body.error.message}`);
102
+ } else {
103
+ (0, _loggerHelpers.loggerError)(logger, `Failed to call instagram api`, err);
104
+ }
105
+ throw err;
106
+ }
107
+ if (response.status !== 200) {
108
+ (0, _loggerHelpers.loggerError)(logger, `Failed to call instagram api`, {
109
+ responseBody: JSON.stringify(response.body)
110
+ });
111
+ let error = new Error(`Failed to call instagram api`);
112
+ error.code = response.status;
113
+ throw error;
114
+ }
115
+ return response;
116
+ }
117
+ async function hideApi(apiUrl, accessToken, hideStatus, logger) {
118
+ let response = {};
119
+ try {
120
+ response = await _superagent.default.post(apiUrl).set('Accept', 'application/json').set('Content-Type', 'application/json').query({
121
+ access_token: accessToken
122
+ }).query({
123
+ hide: hideStatus
124
+ }).send();
125
+ } catch (err) {
126
+ if (err && err.response && err.response.body) {
127
+ (0, _loggerHelpers.loggerError)(logger, `Failed to call instagram api`, err.response.body.error);
128
+ } else {
129
+ (0, _loggerHelpers.loggerError)(logger, `Failed to call instagram api`, err);
130
+ }
131
+ throw err;
132
+ }
133
+ if (response.status !== 200) {
134
+ (0, _loggerHelpers.loggerError)(logger, `Failed to call instagram api`, {
135
+ responseBody: JSON.stringify(response.body)
136
+ });
137
+ let error = new Error(`Failed to call instagram api`);
138
+ error.code = response.status;
139
+ throw error;
140
+ }
141
+ return response;
142
+ }
143
+ async function getLikes(accessToken, externalId, logger) {
144
+ let response;
145
+ (0, _loggerHelpers.loggerDebug)(logger, `Starting to call instagram getPost api for externalId ${externalId}`);
146
+ try {
147
+ response = await getPost(`${INSTAGRAM_URL}/${(0, _externalIdHelpers.removePrefix)(externalId)}`, accessToken, 'like_count', logger);
148
+ (0, _loggerHelpers.loggerInfo)(logger, `Native Instagram API getPost Response`, {
149
+ responseBody: JSON.stringify(response.body)
150
+ });
151
+ return response.body;
152
+ } catch (err) {
153
+ (0, _loggerHelpers.loggerError)(logger, 'Error getLikes Instagram ' + externalId, err);
154
+ return 0;
155
+ }
156
+ }
157
+ async function commentOnMention(accessToken, sourceId, inReplyToId, text, logger) {
158
+ return commentHelper(accessToken, inReplyToId, text, true, sourceId, logger);
159
+ }
160
+ async function comment(accessToken, sourceId, inReplyToId, text, logger) {
161
+ return commentHelper(accessToken, inReplyToId, text, false, sourceId, logger);
162
+ }
163
+ async function commentHelper(accessToken, inReplyToId, text, isMention, sourceId, logger) {
164
+ let response;
165
+ if (isMention) {
166
+ response = await mentionRequestApi(`${INSTAGRAM_URL}/${sourceId}/mentions`, accessToken, {
167
+ media_id: (0, _externalIdHelpers.removePrefix)(inReplyToId)
168
+ }, text, logger);
169
+ } else {
170
+ response = await requestApi(`${INSTAGRAM_URL}/${(0, _externalIdHelpers.removePrefix)(inReplyToId)}/comments`, accessToken, text, undefined, 'qt', logger);
171
+ }
172
+ (0, _loggerHelpers.loggerInfo)(logger, `Native Intagram API Publish Comment Response`, {
173
+ responseBody: JSON.stringify(response.body)
174
+ });
175
+ return response.body;
176
+ }
177
+ async function replyOnMention(accessToken, inReplyToId, text, sourceId, threadId, logger) {
178
+ return replyHelper(accessToken, {
179
+ inReplyToId,
180
+ text,
181
+ sourceId,
182
+ threadId,
183
+ isMention: true
184
+ }, logger);
185
+ }
186
+ async function reply(accessToken, inReplyToId, text) {
187
+ let adCampaign = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : undefined;
188
+ let logger = arguments.length > 4 ? arguments[4] : undefined;
189
+ return replyHelper(accessToken, {
190
+ inReplyToId,
191
+ text,
192
+ isMention: false,
193
+ adCampaign
194
+ }, logger);
195
+ }
196
+ async function replyHelper(accessToken, payload, logger) {
197
+ let response;
198
+ const {
199
+ inReplyToId,
200
+ text,
201
+ isMention,
202
+ sourceId,
203
+ threadId,
204
+ adCampaign
205
+ } = payload;
206
+ (0, _loggerHelpers.loggerDebug)(logger, `Starting to call instagram comment api`, {
207
+ payload: JSON.stringify(payload)
208
+ });
209
+ if (isMention) {
210
+ let messageData = await getMessageData(accessToken, sourceId, inReplyToId, logger);
211
+ let media_id = null;
212
+ if (messageData) {
213
+ media_id = messageData.mentioned_comment.media.id;
214
+ }
215
+ response = await mentionRequestApi(`${INSTAGRAM_URL}/${sourceId}/mentions`, accessToken, {
216
+ media_id: media_id ? media_id : (0, _externalIdHelpers.removePrefix)(threadId),
217
+ comment_id: (0, _externalIdHelpers.removePrefix)(inReplyToId)
218
+ }, text, logger);
219
+ } else {
220
+ response = await requestApi(`${INSTAGRAM_URL}/${(0, _externalIdHelpers.removePrefix)(inReplyToId)}/replies`, accessToken, text, undefined, 're', adCampaign, logger);
221
+ }
222
+ (0, _loggerHelpers.loggerInfo)(logger, `Native Instagram API Publish Reply Response`, {
223
+ responseBody: JSON.stringify(response.body)
224
+ });
225
+ return response.body;
226
+ }
227
+ async function privateMessage(accessToken, profileId, text, logger) {
228
+ const response = await requestApi(`${INSTAGRAM_URL}/v10.0/me/messages`, accessToken,
229
+ // this sends in query string leaving out :shrug:
230
+ undefined, {
231
+ recipient: {
232
+ // not :100: this is right
233
+ id: (0, _externalIdHelpers.removePrefix)(profileId)
234
+ },
235
+ message: {
236
+ text
237
+ },
238
+ // this apparently allows up to 7 days after message 🤔
239
+ tag: 'HUMAN_AGENT'
240
+ }, 'dm', logger);
241
+ (0, _loggerHelpers.loggerInfo)(logger, `Native Instagram API Publish Private Message Response`, {
242
+ responseBody: JSON.stringify(response.body)
243
+ });
244
+ return response.body;
245
+ }
246
+ async function hide(accessToken, externalId, logger) {
247
+ let response;
248
+ (0, _loggerHelpers.loggerDebug)(logger, `Starting to call instagram hide api`);
249
+ response = await hideApi(`${INSTAGRAM_URL}/${(0, _externalIdHelpers.removePrefix)(externalId)}`, accessToken, true, logger);
250
+ (0, _loggerHelpers.loggerInfo)(logger, `Native Instagram API Hide Response`, {
251
+ responseBody: JSON.stringify(response.body)
252
+ });
253
+ return response.body;
254
+ }
255
+ async function unhide(accessToken, externalId, logger) {
256
+ let response;
257
+ (0, _loggerHelpers.loggerDebug)(logger, `Starting to call instagram unhide api`);
258
+ response = await hideApi(`${INSTAGRAM_URL}/${(0, _externalIdHelpers.removePrefix)(externalId)}`, accessToken, false, logger);
259
+ (0, _loggerHelpers.loggerInfo)(logger, `Native Instagram API Unhide Response`, {
260
+ responseBody: JSON.stringify(response.body)
261
+ });
262
+ return response.body;
263
+ }
264
+ async function getAttachment(token, externalId, logger) {
265
+ try {
266
+ const result = await getPost(`${INSTAGRAM_URL}/${(0, _externalIdHelpers.removePrefix)(externalId)}`, token, 'media_url,children{media_url}', logger);
267
+ const res = result.body;
268
+ if (res?.children?.data?.length) {
269
+ return {
270
+ images: res.children.data.map(item => {
271
+ return {
272
+ source: item?.media_url
273
+ };
274
+ })
275
+ };
276
+ }
277
+ return {
278
+ images: [{
279
+ source: res?.media_url
280
+ }]
281
+ };
282
+ } catch (error) {
283
+ (0, _loggerHelpers.loggerError)(logger, `Error getting instagram attachment`, error);
284
+ throw error;
285
+ }
286
+ }
@@ -53,6 +53,7 @@ Object.defineProperty(exports, "InstagramApiClient", {
53
53
  return _instagramApiClient.InstagramApiClient;
54
54
  }
55
55
  });
56
+ exports.InstagramNative = void 0;
56
57
  Object.defineProperty(exports, "InstagramVideoClient", {
57
58
  enumerable: true,
58
59
  get: function () {
@@ -126,6 +127,8 @@ var LinkedinNative = _interopRequireWildcard(require("./http/linkedin.native.js"
126
127
  exports.LinkedinNative = LinkedinNative;
127
128
  var TwitterNative = _interopRequireWildcard(require("./http/twitter.native.js"));
128
129
  exports.TwitterNative = TwitterNative;
130
+ var InstagramNative = _interopRequireWildcard(require("./http/instagram.native.js"));
131
+ exports.InstagramNative = InstagramNative;
129
132
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
130
133
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
131
134
  const DocumentHelperFunctions = exports.DocumentHelperFunctions = {
@@ -0,0 +1,271 @@
1
+ import superagent from 'superagent';
2
+ import { removePrefix } from '../../lib/externalId.helpers.js';
3
+ import { loggerDebug, loggerError, loggerInfo } from '../../lib/logger.helpers.js';
4
+ const INSTAGRAM_URL = 'https://graph.facebook.com';
5
+ async function requestApi(apiUrl, accessToken, text, data) {
6
+ let discussionType = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : 're';
7
+ let adCampaign = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : undefined;
8
+ let logger = arguments.length > 6 ? arguments[6] : undefined;
9
+ let response = {};
10
+ try {
11
+ let queryStringArgs = {
12
+ access_token: accessToken
13
+ };
14
+ if (adCampaign) {
15
+ queryStringArgs.ad_id = adCampaign.adAccountId;
16
+ }
17
+ if (text) {
18
+ queryStringArgs[discussionType === 'dm' ? 'text' : 'message'] = text;
19
+ }
20
+ response = await superagent.post(apiUrl).set('Accept', 'application/json').set('Content-Type', 'application/json').query(queryStringArgs).send(data);
21
+ } catch (err) {
22
+ if (err && err.response && err.response.body && err.response.body.error) {
23
+ loggerError(logger, `Failed to call instagram api: ${err.response.body.error.message}`);
24
+ } else {
25
+ loggerError(logger, `Failed to call instagram api`, err);
26
+ }
27
+ throw err;
28
+ }
29
+ if (response.status !== 200) {
30
+ loggerError(logger, `Failed to call instagram api`, {
31
+ responseBody: JSON.stringify(response.body)
32
+ });
33
+ let error = new Error(`Failed to call instagram api`);
34
+ error.code = response.status;
35
+ throw error;
36
+ }
37
+ loggerDebug(logger, 'Instagram Response status', response.status);
38
+ return response;
39
+ }
40
+ async function getPost(apiUrl, accessToken, fields, logger) {
41
+ let response = {};
42
+ try {
43
+ response = await superagent.get(apiUrl).set('Accept', 'application/json').set('Content-Type', 'application/json').query({
44
+ access_token: accessToken
45
+ }).query({
46
+ fields: fields
47
+ }).send();
48
+ } catch (err) {
49
+ if (err && err.response && err.response.body) {
50
+ loggerError(logger, `Failed to call instagram api`, err.response.body.error);
51
+ } else {
52
+ loggerError(logger, `Failed to call instagram api`, err);
53
+ }
54
+ throw err;
55
+ }
56
+ if (response.status !== 200) {
57
+ loggerError(logger, `Failed to call instagram api`, {
58
+ responseBody: JSON.stringify(response.body)
59
+ });
60
+ let error = new Error(`Failed to call instagram api`);
61
+ error.code = response.status;
62
+ throw error;
63
+ }
64
+ return response;
65
+ }
66
+ async function getMessageData(accessToken, sourceId, inReplyToId, logger) {
67
+ let response;
68
+ try {
69
+ response = await getPost(`${INSTAGRAM_URL}/${sourceId}`, accessToken, `mentioned_comment.comment_id(${inReplyToId}){id, text, timestamp, media{id,media_url}}`, logger);
70
+ return response.body;
71
+ } catch (err) {
72
+ loggerError(logger, `Failed to call instagram api`, err);
73
+ return null;
74
+ }
75
+ }
76
+ async function mentionRequestApi(apiUrl, accessToken, replayObject, text, logger) {
77
+ let response = {};
78
+ try {
79
+ response = await superagent.post(apiUrl).set('Accept', 'application/json').set('Content-Type', 'application/json').query({
80
+ access_token: accessToken
81
+ }).query(replayObject).query({
82
+ message: text
83
+ }).send();
84
+ } catch (err) {
85
+ if (err && err.response && err.response.body && err.response.body.error) {
86
+ loggerError(logger, `Failed to call instagram api: ${err.response.body.error.message}`);
87
+ } else {
88
+ loggerError(logger, `Failed to call instagram api`, err);
89
+ }
90
+ throw err;
91
+ }
92
+ if (response.status !== 200) {
93
+ loggerError(logger, `Failed to call instagram api`, {
94
+ responseBody: JSON.stringify(response.body)
95
+ });
96
+ let error = new Error(`Failed to call instagram api`);
97
+ error.code = response.status;
98
+ throw error;
99
+ }
100
+ return response;
101
+ }
102
+ async function hideApi(apiUrl, accessToken, hideStatus, logger) {
103
+ let response = {};
104
+ try {
105
+ response = await superagent.post(apiUrl).set('Accept', 'application/json').set('Content-Type', 'application/json').query({
106
+ access_token: accessToken
107
+ }).query({
108
+ hide: hideStatus
109
+ }).send();
110
+ } catch (err) {
111
+ if (err && err.response && err.response.body) {
112
+ loggerError(logger, `Failed to call instagram api`, err.response.body.error);
113
+ } else {
114
+ loggerError(logger, `Failed to call instagram api`, err);
115
+ }
116
+ throw err;
117
+ }
118
+ if (response.status !== 200) {
119
+ loggerError(logger, `Failed to call instagram api`, {
120
+ responseBody: JSON.stringify(response.body)
121
+ });
122
+ let error = new Error(`Failed to call instagram api`);
123
+ error.code = response.status;
124
+ throw error;
125
+ }
126
+ return response;
127
+ }
128
+ export async function getLikes(accessToken, externalId, logger) {
129
+ let response;
130
+ loggerDebug(logger, `Starting to call instagram getPost api for externalId ${externalId}`);
131
+ try {
132
+ response = await getPost(`${INSTAGRAM_URL}/${removePrefix(externalId)}`, accessToken, 'like_count', logger);
133
+ loggerInfo(logger, `Native Instagram API getPost Response`, {
134
+ responseBody: JSON.stringify(response.body)
135
+ });
136
+ return response.body;
137
+ } catch (err) {
138
+ loggerError(logger, 'Error getLikes Instagram ' + externalId, err);
139
+ return 0;
140
+ }
141
+ }
142
+ export async function commentOnMention(accessToken, sourceId, inReplyToId, text, logger) {
143
+ return commentHelper(accessToken, inReplyToId, text, true, sourceId, logger);
144
+ }
145
+ export async function comment(accessToken, sourceId, inReplyToId, text, logger) {
146
+ return commentHelper(accessToken, inReplyToId, text, false, sourceId, logger);
147
+ }
148
+ async function commentHelper(accessToken, inReplyToId, text, isMention, sourceId, logger) {
149
+ let response;
150
+ if (isMention) {
151
+ response = await mentionRequestApi(`${INSTAGRAM_URL}/${sourceId}/mentions`, accessToken, {
152
+ media_id: removePrefix(inReplyToId)
153
+ }, text, logger);
154
+ } else {
155
+ response = await requestApi(`${INSTAGRAM_URL}/${removePrefix(inReplyToId)}/comments`, accessToken, text, undefined, 'qt', logger);
156
+ }
157
+ loggerInfo(logger, `Native Intagram API Publish Comment Response`, {
158
+ responseBody: JSON.stringify(response.body)
159
+ });
160
+ return response.body;
161
+ }
162
+ export async function replyOnMention(accessToken, inReplyToId, text, sourceId, threadId, logger) {
163
+ return replyHelper(accessToken, {
164
+ inReplyToId,
165
+ text,
166
+ sourceId,
167
+ threadId,
168
+ isMention: true
169
+ }, logger);
170
+ }
171
+ export async function reply(accessToken, inReplyToId, text) {
172
+ let adCampaign = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : undefined;
173
+ let logger = arguments.length > 4 ? arguments[4] : undefined;
174
+ return replyHelper(accessToken, {
175
+ inReplyToId,
176
+ text,
177
+ isMention: false,
178
+ adCampaign
179
+ }, logger);
180
+ }
181
+ async function replyHelper(accessToken, payload, logger) {
182
+ let response;
183
+ const {
184
+ inReplyToId,
185
+ text,
186
+ isMention,
187
+ sourceId,
188
+ threadId,
189
+ adCampaign
190
+ } = payload;
191
+ loggerDebug(logger, `Starting to call instagram comment api`, {
192
+ payload: JSON.stringify(payload)
193
+ });
194
+ if (isMention) {
195
+ let messageData = await getMessageData(accessToken, sourceId, inReplyToId, logger);
196
+ let media_id = null;
197
+ if (messageData) {
198
+ media_id = messageData.mentioned_comment.media.id;
199
+ }
200
+ response = await mentionRequestApi(`${INSTAGRAM_URL}/${sourceId}/mentions`, accessToken, {
201
+ media_id: media_id ? media_id : removePrefix(threadId),
202
+ comment_id: removePrefix(inReplyToId)
203
+ }, text, logger);
204
+ } else {
205
+ response = await requestApi(`${INSTAGRAM_URL}/${removePrefix(inReplyToId)}/replies`, accessToken, text, undefined, 're', adCampaign, logger);
206
+ }
207
+ loggerInfo(logger, `Native Instagram API Publish Reply Response`, {
208
+ responseBody: JSON.stringify(response.body)
209
+ });
210
+ return response.body;
211
+ }
212
+ export async function privateMessage(accessToken, profileId, text, logger) {
213
+ const response = await requestApi(`${INSTAGRAM_URL}/v10.0/me/messages`, accessToken,
214
+ // this sends in query string leaving out :shrug:
215
+ undefined, {
216
+ recipient: {
217
+ // not :100: this is right
218
+ id: removePrefix(profileId)
219
+ },
220
+ message: {
221
+ text
222
+ },
223
+ // this apparently allows up to 7 days after message 🤔
224
+ tag: 'HUMAN_AGENT'
225
+ }, 'dm', logger);
226
+ loggerInfo(logger, `Native Instagram API Publish Private Message Response`, {
227
+ responseBody: JSON.stringify(response.body)
228
+ });
229
+ return response.body;
230
+ }
231
+ export async function hide(accessToken, externalId, logger) {
232
+ let response;
233
+ loggerDebug(logger, `Starting to call instagram hide api`);
234
+ response = await hideApi(`${INSTAGRAM_URL}/${removePrefix(externalId)}`, accessToken, true, logger);
235
+ loggerInfo(logger, `Native Instagram API Hide Response`, {
236
+ responseBody: JSON.stringify(response.body)
237
+ });
238
+ return response.body;
239
+ }
240
+ export async function unhide(accessToken, externalId, logger) {
241
+ let response;
242
+ loggerDebug(logger, `Starting to call instagram unhide api`);
243
+ response = await hideApi(`${INSTAGRAM_URL}/${removePrefix(externalId)}`, accessToken, false, logger);
244
+ loggerInfo(logger, `Native Instagram API Unhide Response`, {
245
+ responseBody: JSON.stringify(response.body)
246
+ });
247
+ return response.body;
248
+ }
249
+ export async function getAttachment(token, externalId, logger) {
250
+ try {
251
+ const result = await getPost(`${INSTAGRAM_URL}/${removePrefix(externalId)}`, token, 'media_url,children{media_url}', logger);
252
+ const res = result.body;
253
+ if (res?.children?.data?.length) {
254
+ return {
255
+ images: res.children.data.map(item => {
256
+ return {
257
+ source: item?.media_url
258
+ };
259
+ })
260
+ };
261
+ }
262
+ return {
263
+ images: [{
264
+ source: res?.media_url
265
+ }]
266
+ };
267
+ } catch (error) {
268
+ loggerError(logger, `Error getting instagram attachment`, error);
269
+ throw error;
270
+ }
271
+ }
@@ -21,6 +21,7 @@ import * as TiktokNative from './http/tiktok.native.js';
21
21
  import * as YoutubeNative from './http/youtube.native.js';
22
22
  import * as LinkedinNative from './http/linkedin.native.js';
23
23
  import * as TwitterNative from './http/twitter.native.js';
24
+ import * as InstagramNative from './http/instagram.native.js';
24
25
  const DocumentHelperFunctions = {
25
26
  ...messageHelpers,
26
27
  ...applicationTagFunctions,
@@ -30,4 +31,4 @@ const LinkedInHelpers = {
30
31
  getOrganization,
31
32
  getProfile
32
33
  };
33
- export { FacebookNative, TiktokNative, YoutubeNative, LinkedinNative, TwitterNative, awsS3Client, assetManagerTvmRepository, CompanyApiClient, CredentialsApiClient, EntitlementsApiClient, FacebookApiClient, FeatureToggleClient, IdentityServicesClient, InstagramApiClient, InstagramVideoClient, IRClient, LinkedInApiClient, TikTokApiClient, MasfClient, WarpZoneApiClient, DocumentHelperFunctions, LinkedInHelpers };
34
+ export { InstagramNative, FacebookNative, TiktokNative, YoutubeNative, LinkedinNative, TwitterNative, awsS3Client, assetManagerTvmRepository, CompanyApiClient, CredentialsApiClient, EntitlementsApiClient, FacebookApiClient, FeatureToggleClient, IdentityServicesClient, InstagramApiClient, InstagramVideoClient, IRClient, LinkedInApiClient, TikTokApiClient, MasfClient, WarpZoneApiClient, DocumentHelperFunctions, LinkedInHelpers };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meltwater/conversations-api-services",
3
- "version": "1.0.25",
3
+ "version": "1.0.26",
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",
@@ -0,0 +1,477 @@
1
+ import superagent from 'superagent';
2
+ import { removePrefix } from '../../lib/externalId.helpers.js';
3
+ import { loggerDebug, loggerError, loggerInfo } from '../../lib/logger.helpers.js';
4
+
5
+
6
+ const INSTAGRAM_URL = 'https://graph.facebook.com';
7
+
8
+
9
+ async function requestApi(
10
+ apiUrl,
11
+ accessToken,
12
+ text,
13
+ data,
14
+ discussionType = 're',
15
+ adCampaign = undefined,
16
+ logger
17
+ ) {
18
+ let response = {};
19
+
20
+ try {
21
+ let queryStringArgs = { access_token: accessToken };
22
+ if (adCampaign) {
23
+ queryStringArgs.ad_id = adCampaign.adAccountId;
24
+ }
25
+ if (text) {
26
+ queryStringArgs[
27
+ discussionType === 'dm' ? 'text' : 'message'
28
+ ] = text;
29
+ }
30
+
31
+ response = await superagent
32
+ .post(apiUrl)
33
+ .set('Accept', 'application/json')
34
+ .set('Content-Type', 'application/json')
35
+ .query(queryStringArgs)
36
+ .send(data);
37
+ } catch (err) {
38
+ if (
39
+ err &&
40
+ err.response &&
41
+ err.response.body &&
42
+ err.response.body.error
43
+ ) {
44
+ loggerError(logger,
45
+ `Failed to call instagram api: ${err.response.body.error.message}`
46
+ );
47
+ } else {
48
+ loggerError(logger,
49
+ `Failed to call instagram api`,
50
+ err
51
+ );
52
+ }
53
+ throw err;
54
+ }
55
+
56
+ if (response.status !== 200) {
57
+ loggerError(logger,
58
+ `Failed to call instagram api`,
59
+ { responseBody: JSON.stringify(response.body) }
60
+ );
61
+ let error = new Error(
62
+ `Failed to call instagram api`
63
+ );
64
+ error.code = response.status;
65
+ throw error;
66
+ }
67
+ loggerDebug(logger,'Instagram Response status', response.status)
68
+ return response;
69
+ }
70
+
71
+ async function getPost(apiUrl, accessToken, fields, logger) {
72
+
73
+ let response = {};
74
+ try {
75
+ response = await superagent
76
+ .get(apiUrl)
77
+ .set('Accept', 'application/json')
78
+ .set('Content-Type', 'application/json')
79
+ .query({ access_token: accessToken })
80
+ .query({ fields: fields })
81
+ .send();
82
+ } catch (err) {
83
+ if (err && err.response && err.response.body) {
84
+ loggerError(logger,
85
+ `Failed to call instagram api`,
86
+ err.response.body.error
87
+ );
88
+ } else {
89
+ loggerError(logger,
90
+ `Failed to call instagram api`,
91
+ err
92
+ );
93
+ }
94
+ throw err;
95
+ }
96
+
97
+ if (response.status !== 200) {
98
+ loggerError(logger,
99
+ `Failed to call instagram api`,
100
+ { responseBody: JSON.stringify(response.body) }
101
+ );
102
+ let error = new Error(
103
+ `Failed to call instagram api`
104
+ );
105
+ error.code = response.status;
106
+ throw error;
107
+ }
108
+ return response;
109
+ }
110
+
111
+ async function getMessageData(accessToken, sourceId, inReplyToId, logger) {
112
+ let response;
113
+
114
+ try {
115
+ response = await getPost(
116
+ `${INSTAGRAM_URL}/${sourceId}`,
117
+ accessToken,
118
+ `mentioned_comment.comment_id(${inReplyToId}){id, text, timestamp, media{id,media_url}}`,
119
+ logger
120
+ );
121
+
122
+ return response.body;
123
+ } catch (err) {
124
+ loggerError(logger,
125
+ `Failed to call instagram api`,
126
+ err
127
+ );
128
+
129
+ return null;
130
+ }
131
+ }
132
+
133
+ async function mentionRequestApi(
134
+ apiUrl,
135
+ accessToken,
136
+ replayObject,
137
+ text,
138
+ logger
139
+ ) {
140
+ let response = {};
141
+
142
+ try {
143
+ response = await superagent
144
+ .post(apiUrl)
145
+ .set('Accept', 'application/json')
146
+ .set('Content-Type', 'application/json')
147
+ .query({ access_token: accessToken })
148
+ .query(replayObject)
149
+ .query({ message: text })
150
+ .send();
151
+ } catch (err) {
152
+ if (
153
+ err &&
154
+ err.response &&
155
+ err.response.body &&
156
+ err.response.body.error
157
+ ) {
158
+ loggerError(logger,
159
+ `Failed to call instagram api: ${err.response.body.error.message}`
160
+ );
161
+ } else {
162
+ loggerError(logger,
163
+ `Failed to call instagram api`,
164
+ err
165
+ );
166
+ }
167
+ throw err;
168
+ }
169
+
170
+ if (response.status !== 200) {
171
+ loggerError(logger,
172
+ `Failed to call instagram api`,
173
+ { responseBody: JSON.stringify(response.body) }
174
+ );
175
+ let error = new Error(
176
+ `Failed to call instagram api`
177
+ );
178
+ error.code = response.status;
179
+ throw error;
180
+ }
181
+ return response;
182
+ }
183
+
184
+ async function hideApi(apiUrl, accessToken, hideStatus, logger) {
185
+ let response = {};
186
+ try {
187
+ response = await superagent
188
+ .post(apiUrl)
189
+ .set('Accept', 'application/json')
190
+ .set('Content-Type', 'application/json')
191
+ .query({ access_token: accessToken })
192
+ .query({ hide: hideStatus })
193
+ .send();
194
+ } catch (err) {
195
+ if (err && err.response && err.response.body) {
196
+ loggerError(logger,
197
+ `Failed to call instagram api`,
198
+ err.response.body.error
199
+ );
200
+ } else {
201
+ loggerError(logger,
202
+ `Failed to call instagram api`,
203
+ err
204
+ );
205
+ }
206
+ throw err;
207
+ }
208
+
209
+ if (response.status !== 200) {
210
+ loggerError(logger,
211
+ `Failed to call instagram api`,
212
+ { responseBody: JSON.stringify(response.body) }
213
+ );
214
+ let error = new Error(
215
+ `Failed to call instagram api`
216
+ );
217
+ error.code = response.status;
218
+ throw error;
219
+ }
220
+ return response;
221
+ }
222
+
223
+ export async function getLikes(accessToken, externalId, logger) {
224
+ let response;
225
+ loggerDebug(logger,
226
+ `Starting to call instagram getPost api for externalId ${externalId}`
227
+ );
228
+ try {
229
+ response = await getPost(
230
+ `${INSTAGRAM_URL}/${removePrefix(externalId)}`,
231
+ accessToken,
232
+ 'like_count',
233
+ logger
234
+ );
235
+
236
+ loggerInfo(logger,
237
+ `Native Instagram API getPost Response`,
238
+ { responseBody: JSON.stringify(response.body) }
239
+ );
240
+ return response.body;
241
+ } catch (err) {
242
+ loggerError(logger,'Error getLikes Instagram '+externalId,err);
243
+ return 0;
244
+ }
245
+ }
246
+
247
+ export async function commentOnMention(accessToken, sourceId, inReplyToId, text, logger) {
248
+ return commentHelper(accessToken, inReplyToId, text, true, sourceId, logger);
249
+ }
250
+
251
+ export async function comment(accessToken, sourceId, inReplyToId, text, logger) {
252
+ return commentHelper(accessToken, inReplyToId, text, false, sourceId, logger);
253
+ }
254
+
255
+ async function commentHelper(accessToken, inReplyToId, text, isMention, sourceId, logger) {
256
+ let response;
257
+
258
+ if (isMention) {
259
+ response = await mentionRequestApi(
260
+ `${INSTAGRAM_URL}/${sourceId}/mentions`,
261
+ accessToken,
262
+ { media_id: removePrefix(inReplyToId) },
263
+ text,
264
+ logger
265
+ );
266
+ } else {
267
+ response = await requestApi(
268
+ `${INSTAGRAM_URL}/${removePrefix(inReplyToId)}/comments`,
269
+ accessToken,
270
+ text,
271
+ undefined,
272
+ 'qt',
273
+ logger
274
+ );
275
+ }
276
+
277
+ loggerInfo(logger,
278
+ `Native Intagram API Publish Comment Response`,
279
+ { responseBody: JSON.stringify(response.body) }
280
+ );
281
+ return response.body;
282
+ }
283
+
284
+ export async function replyOnMention(
285
+ accessToken,
286
+ inReplyToId,
287
+ text,
288
+ sourceId,
289
+ threadId,
290
+ logger
291
+ ) {
292
+ return replyHelper(
293
+ accessToken,
294
+ {
295
+ inReplyToId,
296
+ text,
297
+ sourceId,
298
+ threadId,
299
+ isMention:true
300
+ },
301
+ logger
302
+ );
303
+ }
304
+
305
+ export async function reply(
306
+ accessToken,
307
+ inReplyToId,
308
+ text,
309
+ adCampaign = undefined,
310
+ logger
311
+ ) {
312
+ return replyHelper(
313
+ accessToken,
314
+ {
315
+ inReplyToId,
316
+ text,
317
+ isMention:false,
318
+ adCampaign,
319
+ },
320
+ logger
321
+ );
322
+ }
323
+
324
+ async function replyHelper(accessToken, payload, logger) {
325
+ let response;
326
+ const {
327
+ inReplyToId,
328
+ text,
329
+ isMention,
330
+ sourceId,
331
+ threadId,
332
+ adCampaign,
333
+ } = payload;
334
+
335
+ loggerDebug(logger,
336
+ `Starting to call instagram comment api`,
337
+ { payload: JSON.stringify(payload) }
338
+ );
339
+
340
+ if (isMention) {
341
+ let messageData = await getMessageData(
342
+ accessToken,
343
+ sourceId,
344
+ inReplyToId,
345
+ logger
346
+ );
347
+ let media_id = null;
348
+
349
+ if (messageData) {
350
+ media_id = messageData.mentioned_comment.media.id;
351
+ }
352
+
353
+ response = await mentionRequestApi(
354
+ `${INSTAGRAM_URL}/${sourceId}/mentions`,
355
+ accessToken,
356
+ {
357
+ media_id: media_id ? media_id : removePrefix(threadId),
358
+ comment_id: removePrefix(inReplyToId),
359
+ },
360
+ text,
361
+ logger
362
+ );
363
+ } else {
364
+ response = await requestApi(
365
+ `${INSTAGRAM_URL}/${removePrefix(inReplyToId)}/replies`,
366
+ accessToken,
367
+ text,
368
+ undefined,
369
+ 're',
370
+ adCampaign,
371
+ logger
372
+ );
373
+ }
374
+
375
+ loggerInfo(logger,
376
+ `Native Instagram API Publish Reply Response`,
377
+ { responseBody: JSON.stringify(response.body) }
378
+ );
379
+ return response.body;
380
+ }
381
+
382
+ export async function privateMessage(accessToken, profileId, text, logger) {
383
+ const response = await requestApi(
384
+ `${INSTAGRAM_URL}/v10.0/me/messages`,
385
+ accessToken,
386
+ // this sends in query string leaving out :shrug:
387
+ undefined,
388
+ {
389
+ recipient: {
390
+ // not :100: this is right
391
+ id: removePrefix(profileId),
392
+ },
393
+ message: {
394
+ text,
395
+ },
396
+ // this apparently allows up to 7 days after message 🤔
397
+ tag: 'HUMAN_AGENT',
398
+ },
399
+ 'dm',
400
+ logger
401
+ );
402
+
403
+ loggerInfo(logger,
404
+ `Native Instagram API Publish Private Message Response`,
405
+ { responseBody: JSON.stringify(response.body) }
406
+ );
407
+ return response.body;
408
+ }
409
+
410
+ export async function hide(accessToken, externalId, logger) {
411
+ let response;
412
+
413
+ loggerDebug(logger,
414
+ `Starting to call instagram hide api`,
415
+ );
416
+
417
+ response = await hideApi(
418
+ `${INSTAGRAM_URL}/${removePrefix(externalId)}`,
419
+ accessToken,
420
+ true,
421
+ logger
422
+ );
423
+
424
+ loggerInfo(logger,
425
+ `Native Instagram API Hide Response`,
426
+ { responseBody: JSON.stringify(response.body) }
427
+ );
428
+ return response.body;
429
+ }
430
+
431
+ export async function unhide(accessToken, externalId, logger) {
432
+ let response;
433
+
434
+ loggerDebug(logger,
435
+ `Starting to call instagram unhide api`
436
+ );
437
+
438
+ response = await hideApi(
439
+ `${INSTAGRAM_URL}/${removePrefix(externalId)}`,
440
+ accessToken,
441
+ false,
442
+ logger
443
+ );
444
+
445
+ loggerInfo(logger,
446
+ `Native Instagram API Unhide Response`,
447
+ { responseBody: JSON.stringify(response.body) }
448
+ );
449
+ return response.body;
450
+ }
451
+
452
+ export async function getAttachment(token, externalId, logger) {
453
+ try {
454
+ const result = await getPost(
455
+ `${INSTAGRAM_URL}/${removePrefix(externalId)}`,
456
+ token,
457
+ 'media_url,children{media_url}',
458
+ logger
459
+ );
460
+
461
+ const res = result.body;
462
+ if (res?.children?.data?.length) {
463
+ return {
464
+ images: res.children.data.map((item) => {
465
+ return { source: item?.media_url };
466
+ }),
467
+ };
468
+ }
469
+
470
+ return {
471
+ images: [{ source: res?.media_url }],
472
+ };
473
+ } catch (error) {
474
+ loggerError(logger,`Error getting instagram attachment`, error);
475
+ throw error;
476
+ }
477
+ }
@@ -21,6 +21,7 @@ import * as TiktokNative from './http/tiktok.native.js';
21
21
  import * as YoutubeNative from './http/youtube.native.js';
22
22
  import * as LinkedinNative from './http/linkedin.native.js';
23
23
  import * as TwitterNative from './http/twitter.native.js';
24
+ import * as InstagramNative from './http/instagram.native.js';
24
25
 
25
26
  const DocumentHelperFunctions = {
26
27
  ...messageHelpers,
@@ -33,6 +34,7 @@ const LinkedInHelpers = {
33
34
  }
34
35
 
35
36
  export {
37
+ InstagramNative,
36
38
  FacebookNative,
37
39
  TiktokNative,
38
40
  YoutubeNative,