@pakoor/n8n-nodes-instagram 0.1.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/README.md +271 -0
- package/dist/__tests__/helpers/index.d.ts +2 -0
- package/dist/__tests__/helpers/index.d.ts.map +1 -0
- package/dist/__tests__/helpers/index.js +18 -0
- package/dist/__tests__/helpers/index.js.map +1 -0
- package/dist/__tests__/helpers/testUtils.d.ts +104 -0
- package/dist/__tests__/helpers/testUtils.d.ts.map +1 -0
- package/dist/__tests__/helpers/testUtils.js +175 -0
- package/dist/__tests__/helpers/testUtils.js.map +1 -0
- package/dist/credentials/InstagramAccessTokenApi.credentials.d.ts +19 -0
- package/dist/credentials/InstagramAccessTokenApi.credentials.d.ts.map +1 -0
- package/dist/credentials/InstagramAccessTokenApi.credentials.js +130 -0
- package/dist/credentials/InstagramAccessTokenApi.credentials.js.map +1 -0
- package/dist/credentials/InstagramOAuth2Api.credentials.d.ts +20 -0
- package/dist/credentials/InstagramOAuth2Api.credentials.d.ts.map +1 -0
- package/dist/credentials/InstagramOAuth2Api.credentials.js +177 -0
- package/dist/credentials/InstagramOAuth2Api.credentials.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/nodes/Instagram/Instagram.node.d.ts +10 -0
- package/dist/nodes/Instagram/Instagram.node.d.ts.map +1 -0
- package/dist/nodes/Instagram/Instagram.node.js +1152 -0
- package/dist/nodes/Instagram/Instagram.node.js.map +1 -0
- package/dist/nodes/Instagram/InstagramTrigger.node.d.ts +61 -0
- package/dist/nodes/Instagram/InstagramTrigger.node.d.ts.map +1 -0
- package/dist/nodes/Instagram/InstagramTrigger.node.js +315 -0
- package/dist/nodes/Instagram/InstagramTrigger.node.js.map +1 -0
- package/dist/nodes/Instagram/instagram.svg +15 -0
- package/dist/services/InstagramApiClient.d.ts +261 -0
- package/dist/services/InstagramApiClient.d.ts.map +1 -0
- package/dist/services/InstagramApiClient.js +548 -0
- package/dist/services/InstagramApiClient.js.map +1 -0
- package/dist/services/TokenManager.d.ts +73 -0
- package/dist/services/TokenManager.d.ts.map +1 -0
- package/dist/services/TokenManager.js +150 -0
- package/dist/services/TokenManager.js.map +1 -0
- package/dist/services/ValidationUtils.d.ts +44 -0
- package/dist/services/ValidationUtils.d.ts.map +1 -0
- package/dist/services/ValidationUtils.js +203 -0
- package/dist/services/ValidationUtils.js.map +1 -0
- package/dist/services/WebhookHandler.d.ts +206 -0
- package/dist/services/WebhookHandler.d.ts.map +1 -0
- package/dist/services/WebhookHandler.js +261 -0
- package/dist/services/WebhookHandler.js.map +1 -0
- package/dist/services/index.d.ts +5 -0
- package/dist/services/index.d.ts.map +1 -0
- package/dist/services/index.js +21 -0
- package/dist/services/index.js.map +1 -0
- package/package.json +69 -0
|
@@ -0,0 +1,548 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Instagram API Client
|
|
4
|
+
* Handles all Instagram Graph API interactions
|
|
5
|
+
*/
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
exports.InstagramApiClient = exports.InstagramApiError = void 0;
|
|
8
|
+
const ValidationUtils_1 = require("./ValidationUtils");
|
|
9
|
+
class InstagramApiError extends Error {
|
|
10
|
+
constructor(error) {
|
|
11
|
+
super(error.message);
|
|
12
|
+
this.name = 'InstagramApiError';
|
|
13
|
+
this.code = error.code;
|
|
14
|
+
this.subcode = error.subcode;
|
|
15
|
+
this.fbtrace_id = error.fbtrace_id;
|
|
16
|
+
this.type = error.type;
|
|
17
|
+
this.suggestion = error.suggestion;
|
|
18
|
+
this.retryable = error.retryable ?? false;
|
|
19
|
+
this.retryAfter = error.retryAfter;
|
|
20
|
+
}
|
|
21
|
+
toJSON() {
|
|
22
|
+
return {
|
|
23
|
+
code: this.code,
|
|
24
|
+
message: this.message,
|
|
25
|
+
subcode: this.subcode,
|
|
26
|
+
fbtrace_id: this.fbtrace_id,
|
|
27
|
+
type: this.type,
|
|
28
|
+
suggestion: this.suggestion,
|
|
29
|
+
retryable: this.retryable,
|
|
30
|
+
retryAfter: this.retryAfter,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
exports.InstagramApiError = InstagramApiError;
|
|
35
|
+
class InstagramApiClient {
|
|
36
|
+
constructor(accessToken, accountId) {
|
|
37
|
+
this.baseUrl = 'https://graph.facebook.com/v18.0';
|
|
38
|
+
this.accessToken = accessToken;
|
|
39
|
+
this.accountId = accountId;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Parse API error response and return enhanced error object
|
|
43
|
+
* Requirements: 14.1, 14.2, 14.3
|
|
44
|
+
*/
|
|
45
|
+
parseErrorResponse(response) {
|
|
46
|
+
const { error } = response;
|
|
47
|
+
const errorCode = error.code;
|
|
48
|
+
let suggestion;
|
|
49
|
+
let retryable = false;
|
|
50
|
+
let retryAfter;
|
|
51
|
+
// Rate limit error (code 4 or 17)
|
|
52
|
+
if (errorCode === 4 || errorCode === 17) {
|
|
53
|
+
suggestion = 'Rate limit exceeded. Please wait before making more requests.';
|
|
54
|
+
retryable = true;
|
|
55
|
+
retryAfter = 60; // Default 60 seconds
|
|
56
|
+
}
|
|
57
|
+
// Authentication errors (code 190, 102)
|
|
58
|
+
else if (errorCode === 190 || errorCode === 102) {
|
|
59
|
+
suggestion = 'Authentication failed. Please refresh your token or reconnect your account.';
|
|
60
|
+
retryable = false;
|
|
61
|
+
}
|
|
62
|
+
// Validation error (code 100)
|
|
63
|
+
else if (errorCode === 100) {
|
|
64
|
+
suggestion = 'Invalid request parameters. Please check your input values.';
|
|
65
|
+
retryable = false;
|
|
66
|
+
}
|
|
67
|
+
// Permission errors (code 10, 200)
|
|
68
|
+
else if (errorCode === 10 || errorCode === 200) {
|
|
69
|
+
suggestion = 'Permission denied. Please check that your app has the required permissions.';
|
|
70
|
+
retryable = false;
|
|
71
|
+
}
|
|
72
|
+
return {
|
|
73
|
+
code: errorCode,
|
|
74
|
+
message: error.message,
|
|
75
|
+
subcode: error.error_subcode,
|
|
76
|
+
fbtrace_id: error.fbtrace_id,
|
|
77
|
+
type: error.type,
|
|
78
|
+
suggestion,
|
|
79
|
+
retryable,
|
|
80
|
+
retryAfter,
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Make authenticated GET request to Instagram Graph API
|
|
85
|
+
*/
|
|
86
|
+
async get(endpoint, params) {
|
|
87
|
+
const url = new URL(`${this.baseUrl}${endpoint}`);
|
|
88
|
+
url.searchParams.set('access_token', this.accessToken);
|
|
89
|
+
if (params) {
|
|
90
|
+
for (const [key, value] of Object.entries(params)) {
|
|
91
|
+
if (value !== undefined && value !== null) {
|
|
92
|
+
url.searchParams.set(key, value);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
const response = await fetch(url.toString(), {
|
|
97
|
+
method: 'GET',
|
|
98
|
+
headers: {
|
|
99
|
+
'Content-Type': 'application/json',
|
|
100
|
+
},
|
|
101
|
+
});
|
|
102
|
+
const data = (await response.json());
|
|
103
|
+
if (!response.ok || data.error) {
|
|
104
|
+
const parsedError = this.parseErrorResponse({ error: data.error });
|
|
105
|
+
throw new InstagramApiError(parsedError);
|
|
106
|
+
}
|
|
107
|
+
return data;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Make authenticated POST request to Instagram Graph API
|
|
111
|
+
*/
|
|
112
|
+
async post(endpoint, body) {
|
|
113
|
+
const url = new URL(`${this.baseUrl}${endpoint}`);
|
|
114
|
+
url.searchParams.set('access_token', this.accessToken);
|
|
115
|
+
const response = await fetch(url.toString(), {
|
|
116
|
+
method: 'POST',
|
|
117
|
+
headers: {
|
|
118
|
+
'Content-Type': 'application/json',
|
|
119
|
+
},
|
|
120
|
+
body: body ? JSON.stringify(body) : undefined,
|
|
121
|
+
});
|
|
122
|
+
const data = (await response.json());
|
|
123
|
+
if (!response.ok || data.error) {
|
|
124
|
+
const parsedError = this.parseErrorResponse({ error: data.error });
|
|
125
|
+
throw new InstagramApiError(parsedError);
|
|
126
|
+
}
|
|
127
|
+
return data;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Make authenticated DELETE request to Instagram Graph API
|
|
131
|
+
*/
|
|
132
|
+
async delete(endpoint) {
|
|
133
|
+
const url = new URL(`${this.baseUrl}${endpoint}`);
|
|
134
|
+
url.searchParams.set('access_token', this.accessToken);
|
|
135
|
+
const response = await fetch(url.toString(), {
|
|
136
|
+
method: 'DELETE',
|
|
137
|
+
headers: {
|
|
138
|
+
'Content-Type': 'application/json',
|
|
139
|
+
},
|
|
140
|
+
});
|
|
141
|
+
const data = (await response.json());
|
|
142
|
+
if (!response.ok || data.error) {
|
|
143
|
+
const parsedError = this.parseErrorResponse({ error: data.error });
|
|
144
|
+
throw new InstagramApiError(parsedError);
|
|
145
|
+
}
|
|
146
|
+
return data;
|
|
147
|
+
}
|
|
148
|
+
// Messaging operations - Requirements: 3.1, 3.3, 3.4, 4.1, 4.2, 4.3, 4.5, 5.1, 5.3, 5.6
|
|
149
|
+
/**
|
|
150
|
+
* Send a text message to a user
|
|
151
|
+
* Requirements: 3.1, 3.2, 3.4
|
|
152
|
+
*/
|
|
153
|
+
async sendTextMessage(recipientId, text) {
|
|
154
|
+
const validation = (0, ValidationUtils_1.validateTextMessage)(text);
|
|
155
|
+
if (!validation.valid) {
|
|
156
|
+
throw new InstagramApiError({
|
|
157
|
+
code: 100,
|
|
158
|
+
message: validation.error,
|
|
159
|
+
suggestion: 'Please ensure message text is within 1000 characters.',
|
|
160
|
+
retryable: false,
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
return this.post(`/${this.accountId}/messages`, {
|
|
164
|
+
recipient: { id: recipientId },
|
|
165
|
+
message: { text },
|
|
166
|
+
});
|
|
167
|
+
}
|
|
168
|
+
/**
|
|
169
|
+
* Send a media message (image, audio, video)
|
|
170
|
+
* Requirements: 4.1, 4.2, 4.3, 4.4, 4.5
|
|
171
|
+
*/
|
|
172
|
+
async sendMediaMessage(recipientId, mediaType, mediaUrl) {
|
|
173
|
+
const validation = (0, ValidationUtils_1.validateMediaUrl)(mediaUrl);
|
|
174
|
+
if (!validation.valid) {
|
|
175
|
+
throw new InstagramApiError({
|
|
176
|
+
code: 100,
|
|
177
|
+
message: validation.error,
|
|
178
|
+
suggestion: 'Media URL must be a valid HTTPS URL.',
|
|
179
|
+
retryable: false,
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
return this.post(`/${this.accountId}/messages`, {
|
|
183
|
+
recipient: { id: recipientId },
|
|
184
|
+
message: {
|
|
185
|
+
attachment: {
|
|
186
|
+
type: mediaType,
|
|
187
|
+
payload: { url: mediaUrl },
|
|
188
|
+
},
|
|
189
|
+
},
|
|
190
|
+
});
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* Send a button template message
|
|
194
|
+
* Requirements: 5.1, 5.2, 5.6
|
|
195
|
+
*/
|
|
196
|
+
async sendButtonTemplate(recipientId, text, buttons) {
|
|
197
|
+
const buttonValidation = (0, ValidationUtils_1.validateButtons)(buttons);
|
|
198
|
+
if (!buttonValidation.valid) {
|
|
199
|
+
throw new InstagramApiError({
|
|
200
|
+
code: 100,
|
|
201
|
+
message: buttonValidation.error,
|
|
202
|
+
suggestion: 'Please ensure buttons meet constraints: max 3 buttons, max 20 chars per title.',
|
|
203
|
+
retryable: false,
|
|
204
|
+
});
|
|
205
|
+
}
|
|
206
|
+
return this.post(`/${this.accountId}/messages`, {
|
|
207
|
+
recipient: { id: recipientId },
|
|
208
|
+
message: {
|
|
209
|
+
attachment: {
|
|
210
|
+
type: 'template',
|
|
211
|
+
payload: {
|
|
212
|
+
template_type: 'button',
|
|
213
|
+
text,
|
|
214
|
+
buttons: buttons.map((btn) => ({
|
|
215
|
+
type: btn.type,
|
|
216
|
+
title: btn.title,
|
|
217
|
+
...(btn.type === 'web_url' ? { url: btn.url } : { payload: btn.payload }),
|
|
218
|
+
})),
|
|
219
|
+
},
|
|
220
|
+
},
|
|
221
|
+
},
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
/**
|
|
225
|
+
* Send a generic template (carousel) message
|
|
226
|
+
* Requirements: 5.3, 5.6
|
|
227
|
+
*/
|
|
228
|
+
async sendGenericTemplate(recipientId, elements) {
|
|
229
|
+
// Validate buttons within each element
|
|
230
|
+
for (const element of elements) {
|
|
231
|
+
if (element.buttons && element.buttons.length > 0) {
|
|
232
|
+
const buttonValidation = (0, ValidationUtils_1.validateButtons)(element.buttons);
|
|
233
|
+
if (!buttonValidation.valid) {
|
|
234
|
+
throw new InstagramApiError({
|
|
235
|
+
code: 100,
|
|
236
|
+
message: buttonValidation.error,
|
|
237
|
+
suggestion: 'Please ensure element buttons meet constraints.',
|
|
238
|
+
retryable: false,
|
|
239
|
+
});
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
if (element.image_url) {
|
|
243
|
+
const urlValidation = (0, ValidationUtils_1.validateMediaUrl)(element.image_url);
|
|
244
|
+
if (!urlValidation.valid) {
|
|
245
|
+
throw new InstagramApiError({
|
|
246
|
+
code: 100,
|
|
247
|
+
message: urlValidation.error,
|
|
248
|
+
suggestion: 'Element image URL must be a valid HTTPS URL.',
|
|
249
|
+
retryable: false,
|
|
250
|
+
});
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
return this.post(`/${this.accountId}/messages`, {
|
|
255
|
+
recipient: { id: recipientId },
|
|
256
|
+
message: {
|
|
257
|
+
attachment: {
|
|
258
|
+
type: 'template',
|
|
259
|
+
payload: {
|
|
260
|
+
template_type: 'generic',
|
|
261
|
+
elements: elements.map((el) => ({
|
|
262
|
+
title: el.title,
|
|
263
|
+
subtitle: el.subtitle,
|
|
264
|
+
image_url: el.image_url,
|
|
265
|
+
buttons: el.buttons?.map((btn) => ({
|
|
266
|
+
type: btn.type,
|
|
267
|
+
title: btn.title,
|
|
268
|
+
...(btn.type === 'web_url' ? { url: btn.url } : { payload: btn.payload }),
|
|
269
|
+
})),
|
|
270
|
+
})),
|
|
271
|
+
},
|
|
272
|
+
},
|
|
273
|
+
},
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
/**
|
|
277
|
+
* Send quick replies
|
|
278
|
+
* Requirements: 5.4, 5.5, 5.6
|
|
279
|
+
*/
|
|
280
|
+
async sendQuickReplies(recipientId, text, quickReplies) {
|
|
281
|
+
const validation = (0, ValidationUtils_1.validateQuickReplies)(quickReplies);
|
|
282
|
+
if (!validation.valid) {
|
|
283
|
+
throw new InstagramApiError({
|
|
284
|
+
code: 100,
|
|
285
|
+
message: validation.error,
|
|
286
|
+
suggestion: 'Please ensure quick replies meet constraints: max 13 items.',
|
|
287
|
+
retryable: false,
|
|
288
|
+
});
|
|
289
|
+
}
|
|
290
|
+
return this.post(`/${this.accountId}/messages`, {
|
|
291
|
+
recipient: { id: recipientId },
|
|
292
|
+
message: {
|
|
293
|
+
text,
|
|
294
|
+
quick_replies: quickReplies.map((qr) => ({
|
|
295
|
+
content_type: qr.content_type,
|
|
296
|
+
title: qr.title,
|
|
297
|
+
payload: qr.payload,
|
|
298
|
+
image_url: qr.image_url,
|
|
299
|
+
})),
|
|
300
|
+
},
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
// User Profile operations - Requirements: 6.1, 6.2, 6.3
|
|
304
|
+
/**
|
|
305
|
+
* Get user profile by IGSID
|
|
306
|
+
* Requirements: 6.1, 6.3
|
|
307
|
+
*/
|
|
308
|
+
async getUserProfile(userId) {
|
|
309
|
+
return this.get(`/${userId}`, {
|
|
310
|
+
fields: 'id,name,username,profile_pic',
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
/**
|
|
314
|
+
* Get authenticated account profile
|
|
315
|
+
* Requirements: 6.2, 6.3
|
|
316
|
+
*/
|
|
317
|
+
async getMyProfile() {
|
|
318
|
+
return this.get(`/${this.accountId}`, {
|
|
319
|
+
fields: 'id,username,name,profile_picture_url,followers_count,media_count',
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
// Comment operations - Requirements: 7.1, 7.2, 7.3, 7.4, 7.5, 7.6, 7.7
|
|
323
|
+
/**
|
|
324
|
+
* Get comments on a media with pagination
|
|
325
|
+
* Requirements: 7.1
|
|
326
|
+
*/
|
|
327
|
+
async getComments(mediaId, options) {
|
|
328
|
+
const params = {
|
|
329
|
+
fields: 'id,text,timestamp,from{id,username},like_count,hidden',
|
|
330
|
+
};
|
|
331
|
+
if (options?.limit) {
|
|
332
|
+
params.limit = options.limit.toString();
|
|
333
|
+
}
|
|
334
|
+
if (options?.after) {
|
|
335
|
+
params.after = options.after;
|
|
336
|
+
}
|
|
337
|
+
if (options?.before) {
|
|
338
|
+
params.before = options.before;
|
|
339
|
+
}
|
|
340
|
+
return this.get(`/${mediaId}/comments`, params);
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Get replies to a comment
|
|
344
|
+
* Requirements: 7.2
|
|
345
|
+
*/
|
|
346
|
+
async getReplies(commentId) {
|
|
347
|
+
return this.get(`/${commentId}/replies`, {
|
|
348
|
+
fields: 'id,text,timestamp,from{id,username},like_count,hidden',
|
|
349
|
+
});
|
|
350
|
+
}
|
|
351
|
+
/**
|
|
352
|
+
* Reply to a comment publicly
|
|
353
|
+
* Requirements: 7.3
|
|
354
|
+
*/
|
|
355
|
+
async replyToComment(commentId, message) {
|
|
356
|
+
return this.post(`/${commentId}/replies`, {
|
|
357
|
+
message,
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
/**
|
|
361
|
+
* Send private reply to a commenter (DM)
|
|
362
|
+
* Requirements: 7.4, 7.5
|
|
363
|
+
*/
|
|
364
|
+
async sendPrivateReply(commentId, message) {
|
|
365
|
+
// First get the comment to check timestamp
|
|
366
|
+
const comment = await this.get(`/${commentId}`, { fields: 'id,timestamp,from{id}' });
|
|
367
|
+
// Check 7-day window
|
|
368
|
+
const commentDate = new Date(comment.timestamp);
|
|
369
|
+
const now = new Date();
|
|
370
|
+
const daysDiff = (now.getTime() - commentDate.getTime()) / (1000 * 60 * 60 * 24);
|
|
371
|
+
if (daysDiff > 7) {
|
|
372
|
+
throw new InstagramApiError({
|
|
373
|
+
code: 100,
|
|
374
|
+
message: 'Private reply window expired. Comments older than 7 days cannot receive private replies.',
|
|
375
|
+
suggestion: 'Private replies must be sent within 7 days of the comment.',
|
|
376
|
+
retryable: false,
|
|
377
|
+
});
|
|
378
|
+
}
|
|
379
|
+
// Send private reply via messages endpoint
|
|
380
|
+
return this.post(`/${this.accountId}/messages`, {
|
|
381
|
+
recipient: { comment_id: commentId },
|
|
382
|
+
message: { text: message },
|
|
383
|
+
});
|
|
384
|
+
}
|
|
385
|
+
/**
|
|
386
|
+
* Delete a comment
|
|
387
|
+
* Requirements: 7.6
|
|
388
|
+
*/
|
|
389
|
+
async deleteComment(commentId) {
|
|
390
|
+
return this.delete(`/${commentId}`);
|
|
391
|
+
}
|
|
392
|
+
/**
|
|
393
|
+
* Hide or unhide a comment
|
|
394
|
+
* Requirements: 7.7
|
|
395
|
+
*/
|
|
396
|
+
async toggleCommentVisibility(commentId, hide) {
|
|
397
|
+
const result = await this.post(`/${commentId}`, {
|
|
398
|
+
hide,
|
|
399
|
+
});
|
|
400
|
+
return { success: result.success, hidden: hide };
|
|
401
|
+
}
|
|
402
|
+
// Content Publishing operations - Requirements: 8.1, 8.2, 8.3, 9.4, 9.5, 10.1, 10.2, 10.4, 10.5
|
|
403
|
+
/**
|
|
404
|
+
* Create a media container for single posts, stories, or reels
|
|
405
|
+
* Requirements: 8.1, 8.2, 10.1, 10.2, 10.4
|
|
406
|
+
*/
|
|
407
|
+
async createMediaContainer(mediaType, mediaUrl, options) {
|
|
408
|
+
const urlValidation = (0, ValidationUtils_1.validateMediaUrl)(mediaUrl);
|
|
409
|
+
if (!urlValidation.valid) {
|
|
410
|
+
throw new InstagramApiError({
|
|
411
|
+
code: 100,
|
|
412
|
+
message: urlValidation.error,
|
|
413
|
+
suggestion: 'Media URL must be a valid HTTPS URL.',
|
|
414
|
+
retryable: false,
|
|
415
|
+
});
|
|
416
|
+
}
|
|
417
|
+
// Validate user tags if provided
|
|
418
|
+
if (options?.user_tags && options.user_tags.length > 0) {
|
|
419
|
+
const tagValidation = (0, ValidationUtils_1.validateUserTags)(options.user_tags);
|
|
420
|
+
if (!tagValidation.valid) {
|
|
421
|
+
throw new InstagramApiError({
|
|
422
|
+
code: 100,
|
|
423
|
+
message: tagValidation.error,
|
|
424
|
+
suggestion: 'Please ensure user tags meet constraints: max 20 tags, positions 0-1.',
|
|
425
|
+
retryable: false,
|
|
426
|
+
});
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
const body = {};
|
|
430
|
+
// Set media type specific fields
|
|
431
|
+
if (mediaType === 'IMAGE') {
|
|
432
|
+
body.image_url = mediaUrl;
|
|
433
|
+
}
|
|
434
|
+
else if (mediaType === 'VIDEO') {
|
|
435
|
+
body.video_url = mediaUrl;
|
|
436
|
+
body.media_type = 'VIDEO';
|
|
437
|
+
}
|
|
438
|
+
else if (mediaType === 'REELS') {
|
|
439
|
+
body.video_url = mediaUrl;
|
|
440
|
+
body.media_type = 'REELS';
|
|
441
|
+
if (options?.audio_name) {
|
|
442
|
+
body.audio_name = options.audio_name;
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
else if (mediaType === 'STORIES') {
|
|
446
|
+
if (mediaUrl.match(/\.(mp4|mov)$/i)) {
|
|
447
|
+
body.video_url = mediaUrl;
|
|
448
|
+
}
|
|
449
|
+
else {
|
|
450
|
+
body.image_url = mediaUrl;
|
|
451
|
+
}
|
|
452
|
+
body.media_type = 'STORIES';
|
|
453
|
+
}
|
|
454
|
+
// Add optional fields
|
|
455
|
+
if (options?.caption) {
|
|
456
|
+
body.caption = options.caption;
|
|
457
|
+
}
|
|
458
|
+
if (options?.location_id) {
|
|
459
|
+
body.location_id = options.location_id;
|
|
460
|
+
}
|
|
461
|
+
if (options?.user_tags && options.user_tags.length > 0) {
|
|
462
|
+
body.user_tags = options.user_tags.map((tag) => ({
|
|
463
|
+
username: tag.username,
|
|
464
|
+
x: tag.x,
|
|
465
|
+
y: tag.y,
|
|
466
|
+
}));
|
|
467
|
+
}
|
|
468
|
+
if (options?.collaborators && options.collaborators.length > 0) {
|
|
469
|
+
body.collaborators = options.collaborators;
|
|
470
|
+
}
|
|
471
|
+
if (options?.thumb_offset !== undefined) {
|
|
472
|
+
body.thumb_offset = options.thumb_offset;
|
|
473
|
+
}
|
|
474
|
+
return this.post(`/${this.accountId}/media`, body);
|
|
475
|
+
}
|
|
476
|
+
/**
|
|
477
|
+
* Create a carousel container from child media containers
|
|
478
|
+
* Requirements: 9.4, 9.5
|
|
479
|
+
*/
|
|
480
|
+
async createCarouselContainer(childrenIds, caption) {
|
|
481
|
+
const validation = (0, ValidationUtils_1.validateCarouselItems)(childrenIds);
|
|
482
|
+
if (!validation.valid) {
|
|
483
|
+
throw new InstagramApiError({
|
|
484
|
+
code: 100,
|
|
485
|
+
message: validation.error,
|
|
486
|
+
suggestion: 'Carousel must have 2-10 items.',
|
|
487
|
+
retryable: false,
|
|
488
|
+
});
|
|
489
|
+
}
|
|
490
|
+
const body = {
|
|
491
|
+
media_type: 'CAROUSEL',
|
|
492
|
+
children: childrenIds,
|
|
493
|
+
};
|
|
494
|
+
if (caption) {
|
|
495
|
+
body.caption = caption;
|
|
496
|
+
}
|
|
497
|
+
return this.post(`/${this.accountId}/media`, body);
|
|
498
|
+
}
|
|
499
|
+
/**
|
|
500
|
+
* Publish a media container
|
|
501
|
+
* Requirements: 8.3, 9.5, 10.5
|
|
502
|
+
*/
|
|
503
|
+
async publishMedia(containerId) {
|
|
504
|
+
return this.post(`/${this.accountId}/media_publish`, {
|
|
505
|
+
creation_id: containerId,
|
|
506
|
+
});
|
|
507
|
+
}
|
|
508
|
+
// Media Management operations - Requirements: 11.1, 11.2, 11.3
|
|
509
|
+
/**
|
|
510
|
+
* List media with pagination
|
|
511
|
+
* Requirements: 11.1
|
|
512
|
+
*/
|
|
513
|
+
async listMedia(options) {
|
|
514
|
+
const params = {
|
|
515
|
+
fields: 'id,media_type,media_url,permalink,caption,timestamp,like_count,comments_count',
|
|
516
|
+
};
|
|
517
|
+
if (options?.limit) {
|
|
518
|
+
params.limit = options.limit.toString();
|
|
519
|
+
}
|
|
520
|
+
if (options?.after) {
|
|
521
|
+
params.after = options.after;
|
|
522
|
+
}
|
|
523
|
+
if (options?.before) {
|
|
524
|
+
params.before = options.before;
|
|
525
|
+
}
|
|
526
|
+
return this.get(`/${this.accountId}/media`, params);
|
|
527
|
+
}
|
|
528
|
+
/**
|
|
529
|
+
* Get media details by ID
|
|
530
|
+
* Requirements: 11.2
|
|
531
|
+
*/
|
|
532
|
+
async getMedia(mediaId) {
|
|
533
|
+
return this.get(`/${mediaId}`, {
|
|
534
|
+
fields: 'id,media_type,media_url,permalink,caption,timestamp,like_count,comments_count',
|
|
535
|
+
});
|
|
536
|
+
}
|
|
537
|
+
/**
|
|
538
|
+
* Get carousel children
|
|
539
|
+
* Requirements: 11.3
|
|
540
|
+
*/
|
|
541
|
+
async getMediaChildren(mediaId) {
|
|
542
|
+
return this.get(`/${mediaId}/children`, {
|
|
543
|
+
fields: 'id,media_type,media_url,permalink,timestamp',
|
|
544
|
+
});
|
|
545
|
+
}
|
|
546
|
+
}
|
|
547
|
+
exports.InstagramApiClient = InstagramApiClient;
|
|
548
|
+
//# sourceMappingURL=InstagramApiClient.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InstagramApiClient.js","sourceRoot":"","sources":["../../src/services/InstagramApiClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TokenManager Service
|
|
3
|
+
* Handles token exchange and refresh for Instagram OAuth2 authentication
|
|
4
|
+
*
|
|
5
|
+
* Requirements:
|
|
6
|
+
* - 1.3: Exchange short-lived token for long-lived token (60 days validity)
|
|
7
|
+
* - 1.4: Auto-refresh when token is older than 24h AND expiring within 7 days
|
|
8
|
+
* - 1.5: Fallback to OAuth token exchange when refresh fails
|
|
9
|
+
*/
|
|
10
|
+
export interface ILongLivedTokenResponse {
|
|
11
|
+
access_token: string;
|
|
12
|
+
token_type: string;
|
|
13
|
+
expires_in: number;
|
|
14
|
+
}
|
|
15
|
+
export interface IInstagramOAuth2Credentials {
|
|
16
|
+
clientId: string;
|
|
17
|
+
clientSecret: string;
|
|
18
|
+
accessToken?: string;
|
|
19
|
+
refreshToken?: string;
|
|
20
|
+
expiresAt?: number;
|
|
21
|
+
instagramAccountId?: string;
|
|
22
|
+
longLivedToken?: string;
|
|
23
|
+
longLivedTokenExpiresAt?: number;
|
|
24
|
+
longLivedTokenCreatedAt?: number;
|
|
25
|
+
}
|
|
26
|
+
export interface ITokenManagerOptions {
|
|
27
|
+
baseUrl?: string;
|
|
28
|
+
}
|
|
29
|
+
export declare class TokenManager {
|
|
30
|
+
private static readonly REFRESH_THRESHOLD_DAYS;
|
|
31
|
+
private static readonly MIN_TOKEN_AGE_HOURS;
|
|
32
|
+
private static readonly GRAPH_API_VERSION;
|
|
33
|
+
private readonly baseUrl;
|
|
34
|
+
constructor(options?: ITokenManagerOptions);
|
|
35
|
+
/**
|
|
36
|
+
* Exchange short-lived token for long-lived token (60 days validity)
|
|
37
|
+
* Requirement 1.3: WHEN a short-lived token is received, THE OAuth2_Credential
|
|
38
|
+
* SHALL automatically exchange it for a long-lived token (60 days validity)
|
|
39
|
+
*
|
|
40
|
+
* @param shortLivedToken - The short-lived access token (1 hour validity)
|
|
41
|
+
* @param appSecret - The Facebook App Secret
|
|
42
|
+
* @returns Long-lived token response with 60 days validity
|
|
43
|
+
*/
|
|
44
|
+
exchangeForLongLivedToken(shortLivedToken: string, appSecret: string): Promise<ILongLivedTokenResponse>;
|
|
45
|
+
/**
|
|
46
|
+
* Refresh long-lived token (must be at least 24h old)
|
|
47
|
+
* Requirement 1.4: WHEN a long-lived token is older than 24 hours AND expiring
|
|
48
|
+
* within 7 days, THE OAuth2_Credential SHALL automatically refresh the token
|
|
49
|
+
*
|
|
50
|
+
* @param longLivedToken - The current long-lived access token
|
|
51
|
+
* @returns New long-lived token response
|
|
52
|
+
*/
|
|
53
|
+
refreshLongLivedToken(longLivedToken: string): Promise<ILongLivedTokenResponse>;
|
|
54
|
+
/**
|
|
55
|
+
* Check if token needs refresh (expiring within 7 days AND older than 24 hours)
|
|
56
|
+
* Requirement 1.4: Token should be refreshed when it's older than 24 hours
|
|
57
|
+
* AND expiring within 7 days
|
|
58
|
+
*
|
|
59
|
+
* @param expiresAt - Token expiration timestamp in milliseconds
|
|
60
|
+
* @param createdAt - Token creation timestamp in milliseconds (optional)
|
|
61
|
+
* @returns true if token should be refreshed
|
|
62
|
+
*/
|
|
63
|
+
shouldRefreshToken(expiresAt: number, createdAt?: number): boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Get valid token (auto-refresh if needed)
|
|
66
|
+
* Requirement 1.4 & 1.5: Auto-refresh token when needed, with fallback
|
|
67
|
+
*
|
|
68
|
+
* @param credentials - The OAuth2 credentials object
|
|
69
|
+
* @returns Valid access token
|
|
70
|
+
*/
|
|
71
|
+
getValidToken(credentials: IInstagramOAuth2Credentials): Promise<string>;
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=TokenManager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TokenManager.d.ts","sourceRoot":"","sources":["../../src/services/TokenManager.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,MAAM,WAAW,uBAAuB;IACtC,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,2BAA2B;IAC1C,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,uBAAuB,CAAC,EAAE,MAAM,CAAC;CAClC;AAED,MAAM,WAAW,oBAAoB;IACnC,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAiBD,qBAAa,YAAY;IACvB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,sBAAsB,CAAK;IACnD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CAAM;IACjD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAW;IAEpD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;gBAErB,OAAO,CAAC,EAAE,oBAAoB;IAI1C;;;;;;;;OAQG;IACG,yBAAyB,CAC7B,eAAe,EAAE,MAAM,EACvB,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,uBAAuB,CAAC;IA4BnC;;;;;;;OAOG;IACG,qBAAqB,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,uBAAuB,CAAC;IA2BrF;;;;;;;;OAQG;IACH,kBAAkB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO;IAkBlE;;;;;;OAMG;IACG,aAAa,CAAC,WAAW,EAAE,2BAA2B,GAAG,OAAO,CAAC,MAAM,CAAC;CAiD/E"}
|