Software: Apache/2.4.41 (Ubuntu). PHP/8.0.30 uname -a: Linux apirnd 5.4.0-204-generic #224-Ubuntu SMP Thu Dec 5 13:38:28 UTC 2024 x86_64 uid=33(www-data) gid=33(www-data) groups=33(www-data) Safe-mode: OFF (not secure) /var/www/html/instagram/src/routes/instagram/ drwxr-xr-x | |
| Viewing file: Select action/file-type: const express = require("express");
const router = express.Router();
const {InstaProfile} = require("../../models/InstaProfile");
const { log } = require("node:console");
const axios = require("axios");
const base_url=process.env.INSTAGRAM_URI;
const INSTAGRAM_APP_ID = process.env.INSTAGRAM_APP_ID || "2013934942337923";
const REDIRECT_URI = process.env.REDIRECT_URI || "https://insta.aimanager24.com/auth/instagram/callback";
const CLIENT_SECRET = process.env.CLIENT_SECRET || "199988bfec2f275bbe7f35465d051078";
router.get("/profile", (req, res) => {
res.send("Instagram Profile Endpoint");
});
async function Subscription(ACCESS_TOKEN) {
try {
const url = `${base_url}/me/subscribed_apps`;
const subscribedFields = 'messages,comments,live_comments,messaging_postbacks';
const response = await axios.post(url, null, {
params: {
access_token: ACCESS_TOKEN,
subscribed_fields: subscribedFields
}
});
console.log(response.data);
if (response.data.success) {
console.log(`✅ Successfully subscribed to webhooks.`);
} else {
console.error('Subscription API call failed:', response.data);
}
return response.data.success;
} catch (error) {
console.error('Error enabling Page subscription:', error.response ? error.response.data : error.message);
throw new Error('Webhook subscription failed.');
}
}
async function getShortLivedToken(authCode) {
try {
const tokenExchangeUrl = 'https://api.instagram.com/oauth/access_token';
// 1. Prepare the data payload as URLSearchParams
const data = new URLSearchParams();
data.append('client_id', INSTAGRAM_APP_ID);
data.append('client_secret', CLIENT_SECRET);
data.append('grant_type', 'authorization_code');
data.append('redirect_uri', REDIRECT_URI);
data.append('code', authCode);
// 2. Send the POST request with the data payload in the body
const response = await axios.post(tokenExchangeUrl, data.toString(), {
headers: {
// CRUCIAL: Must specify application/x-www-form-urlencoded
'Content-Type': 'application/x-www-form-urlencoded'
}
});
console.log(response.data);
var pre_permissions = [
'instagram_business_basic',
'instagram_business_manage_messages',
'instagram_business_content_publish',
'instagram_business_manage_comments'
];
const { access_token, user_id , permissions } = response.data;
if (!permissions || pre_permissions.some(perm => !permissions.includes(perm))) {
console.log("Missing required permissions");
return "missing_permissions";
}
// console.log(response.data);
// Exchange short-lived token for a long-lived token and store profile
const savedProfile = await getLongLivedToken(access_token, user_id);
return { profile: savedProfile };
} catch (error) {
console.error('Error exchanging code for token:', error.response ? error.response.data : error.message);
if (error.response) {
const e = new Error('Instagram API error during token exchange');
e.type = 'instagram';
e.status = error.response.status;
e.data = error.response.data;
throw e;
}
const e = new Error(error.message || 'Token exchange failed.');
e.type = 'internal';
throw e;
}
}
async function getLongLivedToken(shortToken, userId) {
try {
const exchangeUrl = 'https://graph.instagram.com/access_token';
const response = await axios.get(exchangeUrl, {
params: {
grant_type: 'ig_exchange_token',
client_secret: CLIENT_SECRET,
access_token: shortToken
}
});
const { access_token, expires_in } = response.data;
console.log(response.data);
// Fetch basic profile info using the long-lived token
let profile = {};
// try {
// const meResp = await axios.get('https://graph.instagram.com/me', {
// params: {
// fields: 'id,username,account_type,media_count,profile_picture_url,followers_count',
// access_token: access_token
// }
// });
// // console.log(meResp.data);
// profile = meResp.data;
// } catch (err) {
// console.warn('Could not fetch profile fields:', err.response ? err.response.data : err.message);
// }
// const expiresAt = Date.now() + (expires_in * 1000)-48*60*60*1000; // subtract 2 day for safety
// // Store or update the InstaProfile using the provided model
// try {
// const userIdValue = userId || profile.id;
// const setFields = {
// token: access_token,
// next_Token: new Date(expiresAt),
// last_Token: new Date(),
// vendor_id: "88000001"
// };
// if (profile.name) setFields.name = profile.name;
// if (profile.profile_picture_url) setFields.picture = profile.profile_picture_url;
// if (profile.followers_count) setFields.followers = profile.followers_count;
// const setOnInsert = { user_id: userIdValue, _id: Date.now() };
// const saved = await InstaProfile.findOneAndUpdate(
// { user_id: userIdValue },
// { $set: setFields, $setOnInsert: setOnInsert },
// { upsert: true, new: true, setDefaultsOnInsert: true }
// );
// await Subscription(access_token);
// return saved;
// } catch (dbErr) {
// console.error('Error saving InstaProfile:', dbErr);
// const e = new Error('Database error saving InstaProfile');
// e.type = 'db';
// e.error = dbErr;
// throw e;
// }
} catch (error) {
console.error('Error exchanging for long-lived token:', error.response ? error.response.data : error.message);
if (error.response) {
const e = new Error('Instagram API error during long-lived token exchange');
e.type = 'instagram';
e.status = error.response.status;
e.data = error.response.data;
throw e;
}
// rethrow structured errors from DB or internal
throw error;
}
}
router.post("/register", async (req, res) => {
try {
var authCode = req.body.authCode;
const result = await getShortLivedToken(authCode);
// console.log("Instagram Registration Data:", authCode);
// Return saved profile if present
if (result && result.profile) return res.status(200).json({ success: true, profile: result.profile });
return res.status(200).json({ success: true });
} catch (err) {
console.error("Registration Error:", err);
// Instagram API error
if (err && err.type === 'instagram') {
const code = err.data && err.data.error && err.data.error.code ? err.data.error.code : err.status || 400;
const message = err.data && err.data.error && err.data.error.message ? err.data.error.message : (err.data && err.data.error_message) || err.message;
return res.status(err.status || 400).json({ error: true, code, message });
}
// Database error
if (err && err.type === 'db') {
return res.status(500).json({ error: true, message: err.message || 'Database error' });
}
return res.status(500).json({ error: true, message: err.message || 'Registration failed' });
}
});
// Helper to retrieve stored long-lived token for a given Instagram user id
router.getTokenForUser = async function (instagramId) {
const prof = await InstaProfile.findOne({ instagramId });
return prof ? prof.accessToken : null;
};
module.exports = router; |
:: Command execute :: | |
--[ c99shell v. 2.5 [PHP 8 Update] [24.05.2025] | Generation time: 0.0064 ]-- |