@resultcrafter/aimanager-instagram-connector 0.3.0 → 0.4.1
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/aimanager/FacebookClient.js +18 -6
- package/aimanager/TiledeskChannel.js +1 -1
- package/aimanager/TiledeskInstagramTranslator.js +7 -27
- package/index.js +157 -134
- package/package.json +1 -1
- package/template/configure.html +13 -1
|
@@ -45,21 +45,33 @@ class FacebookClient {
|
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
async send(message, page_access_token) {
|
|
48
|
-
|
|
49
48
|
winston.debug("(fbm) [FacebookClient] Sending message...");
|
|
50
|
-
|
|
51
49
|
return await axios({
|
|
52
50
|
url: this.graph_url + "me/messages?access_token=" + page_access_token,
|
|
53
|
-
header: {
|
|
54
|
-
'Content-Type': 'application/json'
|
|
55
|
-
},
|
|
51
|
+
header: { 'Content-Type': 'application/json' },
|
|
56
52
|
method: "POST",
|
|
57
53
|
data: message
|
|
58
54
|
}).then((response) => {
|
|
59
55
|
winston.debug("(fbm) [FacebookClient] Message sent!");
|
|
60
56
|
return response
|
|
61
57
|
}).catch((err) => {
|
|
62
|
-
winston.error("(fbm) [FacebookClient] error send message: ", err.response.
|
|
58
|
+
winston.error("(fbm) [FacebookClient] error send message: ", err.response?.data || err.message);
|
|
59
|
+
throw err;
|
|
60
|
+
})
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
async sendToInstagram(message, accessToken) {
|
|
64
|
+
winston.debug("(ig) [FacebookClient] Sending to Instagram Graph API...");
|
|
65
|
+
return await axios({
|
|
66
|
+
url: "https://graph.instagram.com/v23.0/me/messages?access_token=" + accessToken,
|
|
67
|
+
header: { 'Content-Type': 'application/json' },
|
|
68
|
+
method: "POST",
|
|
69
|
+
data: message
|
|
70
|
+
}).then((response) => {
|
|
71
|
+
winston.debug("(ig) [FacebookClient] Instagram message sent!");
|
|
72
|
+
return response
|
|
73
|
+
}).catch((err) => {
|
|
74
|
+
winston.error("(ig) [FacebookClient] Instagram send error: ", err.response?.data || err.message);
|
|
63
75
|
throw err;
|
|
64
76
|
})
|
|
65
77
|
}
|
|
@@ -58,7 +58,7 @@ class TiledeskChannel {
|
|
|
58
58
|
|
|
59
59
|
} else if (messageInfo.channel == "instagram") {
|
|
60
60
|
channel = messageInfo.instagram;
|
|
61
|
-
new_request_id = "support-group-" + this.settings.project_id + "-" + uuidv4().substring(0, 8) + "-
|
|
61
|
+
new_request_id = "support-group-" + this.settings.project_id + "-" + uuidv4().substring(0, 8) + "-ig-" + channel.page_id + "-" + channel.sender_id;
|
|
62
62
|
|
|
63
63
|
} else {
|
|
64
64
|
winston.verbose("(fbm) [TiledeskChannel] Channel not supported");
|
|
@@ -50,7 +50,7 @@ const path = require('path');
|
|
|
50
50
|
}
|
|
51
51
|
|
|
52
52
|
let instagram_message = {
|
|
53
|
-
|
|
53
|
+
messaging_product: TiledeskInstagramTranslator.INSTAGRAM_MESSAGING_PRODUCT,
|
|
54
54
|
recipient: { id: instagram_receiver }
|
|
55
55
|
}
|
|
56
56
|
|
|
@@ -82,40 +82,20 @@ const path = require('path');
|
|
|
82
82
|
|
|
83
83
|
instagram_message.message = {
|
|
84
84
|
attachment: {
|
|
85
|
-
type: "
|
|
85
|
+
type: "video",
|
|
86
86
|
payload: {
|
|
87
|
-
|
|
88
|
-
elements: [
|
|
89
|
-
{
|
|
90
|
-
//media_type: "video",
|
|
91
|
-
url: tiledeskChannelMessage.metadata.src
|
|
92
|
-
//url: tiledeskChannelMessage.metadata.src
|
|
93
|
-
//url: // facebook url:
|
|
94
|
-
// https://developers.facebook.com/docs/instagram-platform/send-messages/template/media
|
|
95
|
-
// https://developers.facebook.com/docs/instagram-platform/reference/attachment-upload-api
|
|
96
|
-
}
|
|
97
|
-
]
|
|
87
|
+
url: tiledeskChannelMessage.metadata.src
|
|
98
88
|
}
|
|
99
89
|
}
|
|
100
90
|
}
|
|
101
|
-
|
|
102
|
-
/*
|
|
103
|
-
instagram_message.type = 'video'
|
|
104
|
-
instagram_message.video = {
|
|
105
|
-
link: tiledeskChannelMessage.metadata.src,
|
|
106
|
-
//caption: tiledeskChannelMessage.metadata.name || tiledeskChannelMessage.text
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
*/
|
|
110
91
|
}
|
|
111
92
|
|
|
112
93
|
else if (tiledeskChannelMessage.metadata.type && tiledeskChannelMessage.metadata.type.startsWith('application')) {
|
|
113
94
|
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
}
|
|
95
|
+
var docText = tiledeskChannelMessage.text || '';
|
|
96
|
+
if (tiledeskChannelMessage.metadata.name) docText += '\n' + tiledeskChannelMessage.metadata.name;
|
|
97
|
+
docText += '\n' + tiledeskChannelMessage.metadata.src;
|
|
98
|
+
instagram_message.message = { text: docText };
|
|
119
99
|
}
|
|
120
100
|
|
|
121
101
|
else {
|
package/index.js
CHANGED
|
@@ -113,7 +113,7 @@ router.post('/install', async (req, res) => {
|
|
|
113
113
|
"project_id": project_id,
|
|
114
114
|
"app_id": app_id,
|
|
115
115
|
"token": token,
|
|
116
|
-
"oauth_url": BASE_URL + '/auth/instagram/start'
|
|
116
|
+
"oauth_url": BASE_URL + '/auth/instagram/start?project_id=' + project_id + '&token=' + token + '&app_id=' + app_id
|
|
117
117
|
}
|
|
118
118
|
}));
|
|
119
119
|
|
|
@@ -328,17 +328,60 @@ router.post('/update_advanced', async (req, res) => {
|
|
|
328
328
|
})
|
|
329
329
|
})
|
|
330
330
|
|
|
331
|
+
function getOutboundToken(settings, entryId) {
|
|
332
|
+
if (settings && settings.pages && settings.pages.length > 0) {
|
|
333
|
+
var page = settings.pages.find(function(p) { return p.id === entryId; });
|
|
334
|
+
if (page && page.access_token) {
|
|
335
|
+
return { token: page.access_token, type: 'facebook_page' };
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
if (settings && settings.ig_oauth_token && settings.ig_oauth_token.access_token) {
|
|
339
|
+
return { token: settings.ig_oauth_token.access_token, type: 'instagram_oauth' };
|
|
340
|
+
}
|
|
341
|
+
return null;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
function parseRecipient(recipient_id) {
|
|
345
|
+
var result = { entry_id: null, ig_receiver: null, prefix: 'ig' };
|
|
346
|
+
if (!recipient_id) return result;
|
|
347
|
+
|
|
348
|
+
if (recipient_id.indexOf('ig-') > -1) {
|
|
349
|
+
result.entry_id = recipient_id.substring(recipient_id.lastIndexOf('ig-') + 3, recipient_id.lastIndexOf('-'));
|
|
350
|
+
result.ig_receiver = recipient_id.substring(recipient_id.lastIndexOf('-') + 1);
|
|
351
|
+
result.prefix = 'ig';
|
|
352
|
+
} else if (recipient_id.indexOf('fbm-') > -1) {
|
|
353
|
+
result.entry_id = recipient_id.substring(recipient_id.lastIndexOf('fbm-') + 4, recipient_id.lastIndexOf('-'));
|
|
354
|
+
result.ig_receiver = recipient_id.substring(recipient_id.lastIndexOf('-') + 1);
|
|
355
|
+
result.prefix = 'fbm';
|
|
356
|
+
}
|
|
357
|
+
return result;
|
|
358
|
+
}
|
|
359
|
+
|
|
360
|
+
async function sendInstagramMessage(instagramJsonMessage, accessToken, authType, fbClient) {
|
|
361
|
+
if (!isValidIGSID(instagramJsonMessage.recipient.id)) {
|
|
362
|
+
winston.error("(ig) Invalid IGSID format: " + instagramJsonMessage.recipient.id);
|
|
363
|
+
return { success: false, error: "Invalid IGSID format" };
|
|
364
|
+
}
|
|
365
|
+
if (authType === 'instagram_oauth') {
|
|
366
|
+
return await fbClient.sendToInstagram(instagramJsonMessage, accessToken);
|
|
367
|
+
}
|
|
368
|
+
return await fbClient.send(instagramJsonMessage, accessToken);
|
|
369
|
+
}
|
|
370
|
+
|
|
331
371
|
router.post('/tiledesk', async (req, res) => {
|
|
332
|
-
winston.verbose("(
|
|
333
|
-
winston.debug("(fbm) Message received from AI Manager body: ", req.body);
|
|
372
|
+
winston.verbose("(ig) Message received from AI Manager");
|
|
334
373
|
|
|
335
374
|
let tiledeskChannelMessage = req.body.payload;
|
|
336
375
|
let project_id = req.body.payload.id_project;
|
|
337
376
|
|
|
338
|
-
// get settings from mongo
|
|
339
377
|
let CONTENT_KEY = "instagram-" + project_id;
|
|
340
378
|
let settings = await db.get(CONTENT_KEY);
|
|
341
379
|
|
|
380
|
+
if (!settings) {
|
|
381
|
+
winston.warn("(ig) No settings found for project " + project_id);
|
|
382
|
+
return res.sendStatus(200);
|
|
383
|
+
}
|
|
384
|
+
|
|
342
385
|
var text = req.body.payload.text;
|
|
343
386
|
let sender_id = req.body.payload.sender;
|
|
344
387
|
let attributes = req.body.payload.attributes;
|
|
@@ -348,171 +391,129 @@ router.post('/tiledesk', async (req, res) => {
|
|
|
348
391
|
commands = attributes.commands;
|
|
349
392
|
}
|
|
350
393
|
|
|
351
|
-
if (sender_id.indexOf("fbm") > -1) {
|
|
352
|
-
winston.debug("(
|
|
394
|
+
if (sender_id && (sender_id.indexOf("fbm") > -1 || sender_id.indexOf("ig") > -1)) {
|
|
395
|
+
winston.debug("(ig) Skip same sender");
|
|
353
396
|
return res.sendStatus(200);
|
|
354
397
|
}
|
|
355
398
|
|
|
356
|
-
if (attributes && attributes.subtype === "info") {
|
|
357
|
-
winston.debug("(
|
|
358
|
-
return res.sendStatus(200);
|
|
359
|
-
}
|
|
360
|
-
|
|
361
|
-
if (attributes && attributes.subtype === "private") {
|
|
362
|
-
winston.verbose("(wab) Skip subtype (private)");
|
|
399
|
+
if (attributes && (attributes.subtype === "info" || attributes.subtype === "private" || attributes.subtype === 'info/support')) {
|
|
400
|
+
winston.debug("(ig) Skip subtype: " + attributes.subtype);
|
|
363
401
|
return res.sendStatus(200);
|
|
364
402
|
}
|
|
365
403
|
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
}
|
|
404
|
+
var parsed = parseRecipient(tiledeskChannelMessage.recipient);
|
|
405
|
+
var entry_id = parsed.entry_id;
|
|
406
|
+
var ig_receiver = parsed.ig_receiver;
|
|
370
407
|
|
|
371
|
-
|
|
372
|
-
let sender = tiledeskChannelMessage.sender;
|
|
373
|
-
let page_id = recipient_id.substring(recipient_id.lastIndexOf("fbm-") + 4, recipient_id.lastIndexOf("-"));
|
|
374
|
-
let instagram_receiver = recipient_id.substring(recipient_id.lastIndexOf("-") + 1);
|
|
375
|
-
|
|
376
|
-
winston.verbose("(fbm) sender: " + sender);
|
|
377
|
-
winston.verbose("(fbm) text: " + text);
|
|
378
|
-
winston.verbose("(fbm) attributes: ", attributes);
|
|
379
|
-
winston.verbose("(fbm) tiledesk sender_id: " + sender_id);
|
|
380
|
-
winston.verbose("(fbm) recipient_id: " + recipient_id);
|
|
381
|
-
winston.verbose("(fbm) page_id: " + page_id);
|
|
382
|
-
winston.verbose("(fbm) instagram_receiver: " + instagram_receiver);
|
|
408
|
+
winston.verbose("(ig) entry_id: " + entry_id + ", ig_receiver: " + ig_receiver + ", prefix: " + parsed.prefix);
|
|
383
409
|
|
|
384
410
|
// Return an info message option
|
|
385
|
-
if (settings.expired
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
winston.verbose("settings expired: " + settings.expired);
|
|
411
|
+
if (settings.expired === true) {
|
|
412
|
+
winston.verbose("(ig) Settings expired");
|
|
389
413
|
let tiledeskJsonMessage = {
|
|
390
414
|
text: 'Expired. Upgrade Plan.',
|
|
391
415
|
sender: "system",
|
|
392
416
|
senderFullname: "System",
|
|
393
|
-
attributes: {
|
|
394
|
-
subtype: 'info',
|
|
395
|
-
messagelabel: { key: 'PLAN_EXPIRED' } // for translation
|
|
396
|
-
},
|
|
417
|
+
attributes: { subtype: 'info', messagelabel: { key: 'PLAN_EXPIRED' } },
|
|
397
418
|
channel: { name: 'instagram' }
|
|
398
419
|
}
|
|
399
420
|
let message_info = {
|
|
400
421
|
channel: "instagram",
|
|
401
|
-
instagram: {
|
|
402
|
-
page_id: page_id,
|
|
403
|
-
sender_id: instagram_receiver
|
|
404
|
-
}
|
|
422
|
+
instagram: { page_id: entry_id, sender_id: ig_receiver }
|
|
405
423
|
}
|
|
406
|
-
|
|
407
424
|
const tdChannel = new TiledeskChannel({ settings: settings, API_URL: API_URL })
|
|
408
425
|
try {
|
|
409
426
|
await tdChannel.send(tiledeskJsonMessage, message_info, settings.department_id);
|
|
410
|
-
winston.verbose("(wab) Expiration message sent to AI Manager")
|
|
411
427
|
return res.sendStatus(200);
|
|
412
428
|
} catch (err) {
|
|
413
|
-
return res.status(500).send({ success: false, error: "Error sending
|
|
429
|
+
return res.status(500).send({ success: false, error: "Error sending expiration message" });
|
|
414
430
|
}
|
|
415
431
|
}
|
|
416
432
|
|
|
417
|
-
|
|
433
|
+
var tokenInfo = getOutboundToken(settings, entry_id);
|
|
434
|
+
if (!tokenInfo) {
|
|
435
|
+
winston.error("(ig) No access token available for outbound message (no pages, no OAuth)");
|
|
436
|
+
return res.status(200).send({ message: "skipped - no token" });
|
|
437
|
+
}
|
|
438
|
+
|
|
418
439
|
const fbClient = new FacebookClient({ GRAPH_URL: GRAPH_URL, FB_APP_ID: FB_APP_ID, APP_SECRET: APP_SECRET, BASE_URL: BASE_URL });
|
|
419
440
|
const messageHandler = new MessageHandler({ tiledeskChannelMessage: tiledeskChannelMessage });
|
|
420
441
|
const tlr = new TiledeskInstagramTranslator();
|
|
421
442
|
|
|
443
|
+
function sendMessageViaInstagram(jsonMsg, cb) {
|
|
444
|
+
sendInstagramMessage(jsonMsg, tokenInfo.token, tokenInfo.type, fbClient).then(function(response) {
|
|
445
|
+
winston.debug("(ig) Message sent via " + tokenInfo.type);
|
|
446
|
+
if (cb) cb(null, response);
|
|
447
|
+
}).catch(function(err) {
|
|
448
|
+
winston.error("(ig) Send error: ", err?.response?.data || err.message);
|
|
449
|
+
if (cb) cb(err);
|
|
450
|
+
});
|
|
451
|
+
}
|
|
452
|
+
|
|
422
453
|
if (commands) {
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
// message
|
|
454
|
+
var cmdIdx = 0;
|
|
455
|
+
function executeCommand(command) {
|
|
426
456
|
if (command.type === "message") {
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
winston.debug("(fbm) End of splitted message -> go to next command")
|
|
447
|
-
i += 1;
|
|
448
|
-
if (i < commands.length) {
|
|
449
|
-
execute(commands[i]);
|
|
457
|
+
messageHandler.generateMessageObject(command).then(function(tiledeskCommandMessage) {
|
|
458
|
+
messageHandler.splitMessageFromTiledesk(tiledeskCommandMessage).then(function(messagesList) {
|
|
459
|
+
var msgIdx = 0;
|
|
460
|
+
function sendNextMessage(msg) {
|
|
461
|
+
tlr.toInstagram(msg, ig_receiver).then(function(instagramJsonMessage) {
|
|
462
|
+
if (instagramJsonMessage) {
|
|
463
|
+
sendMessageViaInstagram(instagramJsonMessage, function(err) {
|
|
464
|
+
if (!err) {
|
|
465
|
+
msgIdx++;
|
|
466
|
+
if (msgIdx < messagesList.length) {
|
|
467
|
+
sendNextMessage(messagesList[msgIdx]);
|
|
468
|
+
} else {
|
|
469
|
+
cmdIdx++;
|
|
470
|
+
if (cmdIdx < commands.length) {
|
|
471
|
+
executeCommand(commands[cmdIdx]);
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
});
|
|
450
476
|
} else {
|
|
451
|
-
|
|
477
|
+
cmdIdx++;
|
|
478
|
+
if (cmdIdx < commands.length) executeCommand(commands[cmdIdx]);
|
|
452
479
|
}
|
|
453
|
-
}
|
|
454
|
-
}
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
// wait
|
|
465
|
-
if (command.type === "wait") {
|
|
466
|
-
setTimeout(() => {
|
|
467
|
-
i += 1;
|
|
468
|
-
if (i < commands.length) {
|
|
469
|
-
execute(commands[i]);
|
|
470
|
-
} else {
|
|
471
|
-
winston.debug("(fbm) End of commands")
|
|
472
|
-
}
|
|
473
|
-
}, command.time)
|
|
480
|
+
});
|
|
481
|
+
}
|
|
482
|
+
sendNextMessage(messagesList[0]);
|
|
483
|
+
});
|
|
484
|
+
});
|
|
485
|
+
} else if (command.type === "wait") {
|
|
486
|
+
setTimeout(function() {
|
|
487
|
+
cmdIdx++;
|
|
488
|
+
if (cmdIdx < commands.length) executeCommand(commands[cmdIdx]);
|
|
489
|
+
}, command.time);
|
|
474
490
|
}
|
|
475
491
|
}
|
|
476
|
-
|
|
477
|
-
}
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
winston.verbose("(fbm) instagramJsonMessage", instagramJsonMessage)
|
|
488
|
-
|
|
489
|
-
if (instagramJsonMessage) {
|
|
490
|
-
fbClient.send(instagramJsonMessage, page_detail.access_token).then((response) => {
|
|
491
|
-
winston.verbose("(fbm) Message sent to Instagram!" + response.status + " " + response.statusText);
|
|
492
|
-
j += 1;
|
|
493
|
-
if (j < messagesList.length) {
|
|
494
|
-
send(messagesList[j])
|
|
495
|
-
} else {
|
|
496
|
-
winston.debug("(fbm) End of splitted message")
|
|
492
|
+
executeCommand(commands[0]);
|
|
493
|
+
} else if (tiledeskChannelMessage.text || tiledeskChannelMessage.metadata) {
|
|
494
|
+
messageHandler.splitMessageFromTiledesk(tiledeskChannelMessage).then(function(messagesList) {
|
|
495
|
+
var msgIdx = 0;
|
|
496
|
+
function sendNext(msg) {
|
|
497
|
+
tlr.toInstagram(msg, ig_receiver).then(function(instagramJsonMessage) {
|
|
498
|
+
if (instagramJsonMessage) {
|
|
499
|
+
sendMessageViaInstagram(instagramJsonMessage, function() {
|
|
500
|
+
msgIdx++;
|
|
501
|
+
if (msgIdx < messagesList.length) sendNext(messagesList[msgIdx]);
|
|
502
|
+
});
|
|
497
503
|
}
|
|
498
|
-
})
|
|
499
|
-
winston.error("(fbm) error send message: ", err)
|
|
500
|
-
})
|
|
501
|
-
} else {
|
|
502
|
-
winston.error("(fbm) instagramJsonMessage is undefined!")
|
|
504
|
+
});
|
|
503
505
|
}
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
}
|
|
508
|
-
|
|
509
|
-
else {
|
|
510
|
-
winston.debug("(fbm) no command, no text --> skip")
|
|
506
|
+
sendNext(messagesList[0]);
|
|
507
|
+
});
|
|
511
508
|
}
|
|
512
509
|
|
|
513
510
|
return res.status(200).send({ message: "sent" });
|
|
514
511
|
})
|
|
515
512
|
|
|
513
|
+
function isValidIGSID(id) {
|
|
514
|
+
return /^\d{10,20}$/.test(String(id));
|
|
515
|
+
}
|
|
516
|
+
|
|
516
517
|
function convertTestWebhook(body) {
|
|
517
518
|
if (body.field && body.value) {
|
|
518
519
|
winston.info("(ig) Converting test webhook from Meta dashboard");
|
|
@@ -727,6 +728,25 @@ router.get('/auth/instagram/start', async (req, res) => {
|
|
|
727
728
|
}
|
|
728
729
|
});
|
|
729
730
|
|
|
731
|
+
function oauthCallbackResponse(res, success, data) {
|
|
732
|
+
var username = data && data.username ? data.username : '';
|
|
733
|
+
var error = data && data.error ? data.error : '';
|
|
734
|
+
var redirectUri = data && data.redirect_uri ? data.redirect_uri : '';
|
|
735
|
+
res.send('<!DOCTYPE html><html><body><script>' +
|
|
736
|
+
'if (window.opener) {' +
|
|
737
|
+
' window.opener.postMessage({' +
|
|
738
|
+
' type: "oauth-complete",' +
|
|
739
|
+
' success: ' + (success ? 'true' : 'false') + ',' +
|
|
740
|
+
(username ? ' username: "' + username.replace(/"/g, '\\"') + '",' : '') +
|
|
741
|
+
(error ? ' error: "' + error.replace(/"/g, '\\"') + '"' : '') +
|
|
742
|
+
' }, "*");' +
|
|
743
|
+
' window.close();' +
|
|
744
|
+
'} else {' +
|
|
745
|
+
' window.location.href = "' + redirectUri.replace(/"/g, '') + '";' +
|
|
746
|
+
'}' +
|
|
747
|
+
'</script></body></html>');
|
|
748
|
+
}
|
|
749
|
+
|
|
730
750
|
router.get('/oauth-callback', async (req, res) => {
|
|
731
751
|
winston.verbose("(ig) /oauth-callback");
|
|
732
752
|
|
|
@@ -734,16 +754,17 @@ router.get('/oauth-callback', async (req, res) => {
|
|
|
734
754
|
var stateStr = req.query.state;
|
|
735
755
|
if (!code || !stateStr) {
|
|
736
756
|
winston.error("(ig) Missing code or state parameter");
|
|
737
|
-
return res
|
|
757
|
+
return oauthCallbackResponse(res, false, { error: 'Missing authorization code or state' });
|
|
738
758
|
}
|
|
739
759
|
|
|
740
760
|
var state = instagramOAuth.verifyState(stateStr);
|
|
741
761
|
if (!state) {
|
|
742
762
|
winston.error("(ig) Invalid or expired state");
|
|
743
|
-
return res
|
|
763
|
+
return oauthCallbackResponse(res, false, { error: 'Invalid or expired state parameter' });
|
|
744
764
|
}
|
|
745
765
|
|
|
746
766
|
var projectId = state.project_id;
|
|
767
|
+
var redirect_uri = DASHBOARD_BASE_URL + "/#/project/" + projectId + "/integrations?name=instagram";
|
|
747
768
|
|
|
748
769
|
try {
|
|
749
770
|
var tokenData = await instagramOAuth.exchangeCodeForToken(code);
|
|
@@ -757,11 +778,10 @@ router.get('/oauth-callback', async (req, res) => {
|
|
|
757
778
|
settings.connected = true;
|
|
758
779
|
await db.set(CONTENT_KEY, settings);
|
|
759
780
|
|
|
760
|
-
|
|
761
|
-
res.redirect(redirect_uri);
|
|
781
|
+
oauthCallbackResponse(res, true, { username: tokenData.username, redirect_uri: redirect_uri });
|
|
762
782
|
} catch (err) {
|
|
763
783
|
winston.error("(ig) OAuth callback error: ", err?.response?.data || err.message || err);
|
|
764
|
-
res
|
|
784
|
+
oauthCallbackResponse(res, false, { error: err.message || 'Authentication failed', redirect_uri: redirect_uri });
|
|
765
785
|
}
|
|
766
786
|
})
|
|
767
787
|
|
|
@@ -820,7 +840,8 @@ router.post('/enablePage', async (req, res) => {
|
|
|
820
840
|
brand_name: BRAND_NAME,
|
|
821
841
|
show_info_message: settings.show_info_message !== undefined ? settings.show_info_message : true,
|
|
822
842
|
instagram_username: settings.instagram_username || settings.user_info?.username || 'Instagram Account',
|
|
823
|
-
subscription_id: settings.subscription_id
|
|
843
|
+
subscription_id: settings.subscription_id,
|
|
844
|
+
oauth_url: BASE_URL + '/auth/instagram/start?project_id=' + project_id + '&token=' + token + '&app_id=' + app_id
|
|
824
845
|
}
|
|
825
846
|
var html = template(replacements)
|
|
826
847
|
return res.send(html);
|
|
@@ -845,7 +866,8 @@ router.post('/enablePage', async (req, res) => {
|
|
|
845
866
|
show_alert_modal: true,
|
|
846
867
|
show_info_message: settings.show_info_message !== undefined ? settings.show_info_message : true,
|
|
847
868
|
instagram_username: settings.instagram_username || settings.user_info?.username || 'Instagram Account',
|
|
848
|
-
subscription_id: settings.subscription_id
|
|
869
|
+
subscription_id: settings.subscription_id,
|
|
870
|
+
oauth_url: BASE_URL + '/auth/instagram/start?project_id=' + project_id + '&token=' + token + '&app_id=' + app_id
|
|
849
871
|
}
|
|
850
872
|
var html = template(replacements)
|
|
851
873
|
return res.send(html);
|
|
@@ -893,7 +915,8 @@ router.post('/disablePage', async (req, res) => {
|
|
|
893
915
|
brand_name: BRAND_NAME,
|
|
894
916
|
show_info_message: settings.show_info_message !== undefined ? settings.show_info_message : true,
|
|
895
917
|
instagram_username: settings.instagram_username || settings.user_info?.username || 'Instagram Account',
|
|
896
|
-
subscription_id: settings.subscription_id
|
|
918
|
+
subscription_id: settings.subscription_id,
|
|
919
|
+
oauth_url: BASE_URL + '/auth/instagram/start?project_id=' + project_id + '&token=' + token + '&app_id=' + app_id
|
|
897
920
|
}
|
|
898
921
|
var html = template(replacements)
|
|
899
922
|
return res.send(html);
|
package/package.json
CHANGED
package/template/configure.html
CHANGED
|
@@ -242,6 +242,18 @@
|
|
|
242
242
|
|
|
243
243
|
<script>
|
|
244
244
|
|
|
245
|
+
var oauthPopup = null;
|
|
246
|
+
|
|
247
|
+
window.addEventListener('message', function(event) {
|
|
248
|
+
if (event.data && event.data.type === 'oauth-complete') {
|
|
249
|
+
if (event.data.success) {
|
|
250
|
+
window.location.reload();
|
|
251
|
+
} else {
|
|
252
|
+
alert('Instagram connection failed: ' + (event.data.error || 'Unknown error'));
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
});
|
|
256
|
+
|
|
245
257
|
function connectInstagram() {
|
|
246
258
|
var width = 600;
|
|
247
259
|
var height = 700;
|
|
@@ -259,7 +271,7 @@
|
|
|
259
271
|
} catch (e) {
|
|
260
272
|
|
|
261
273
|
}
|
|
262
|
-
},
|
|
274
|
+
}, 2000);
|
|
263
275
|
}
|
|
264
276
|
|
|
265
277
|
function update_advanced() {
|