Loading snippets...
Node.js ESM script untuk mengambil data Reels Instagram dari IQSaved dan menampilkan metadata serta link download.
import { io } from "socket.io-client";
import crypto from "node:crypto";
const CONFIG = {
BASE_URL: "https://iqsaved.com",
DEFAULT_LOCALE: "id",
USER_AGENT: "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/147.0.0.0 Mobile Safari/537.36",
IMAGE_RESOLVER: "https://cdn.iqsaved.com/img.php?url=",
SOCKET_TIMEOUT: 30000
};
const TARGET_URL = "https://www.instagram.com/reel/DXje0lrgZNu/?igsh=MWNsNWV3aHczdnMyZA==";
const CryptoUtils = {
generateNumericString: (length = 10) => {
return Array.from({ length }, () => Math.floor(Math.random() * 10)).join("");
},
generateAnalyticsId: () => {
const randomId = Math.floor(Math.random() * 2_000_000_000);
const timestamp = Math.floor(Date.now() / 1000);
return `GA1.1.${randomId}.${timestamp}`;
},
generateSessionToken: () => {
return crypto.randomBytes(13).toString("hex");
}
};
const getInstagramShortcode = (url) => {
const regex = /instagram\.com\/(?:reel|p|tv)\/([^/?#]+)/i;
const match = String(url).match(regex);
if (!match) throw new Error("Shortcode Instagram tidak ditemukan");
return match[1];
};
const sanitizeInstagramUrl = (url) => {
return `https://www.instagram.com/reel/${getInstagramShortcode(url)}/`;
};
const generateInitialCookies = () => {
const epoch = Math.floor(Date.now() / 1000);
return [
`PHPSESSID=${CryptoUtils.generateSessionToken()}`,
`_ga=${CryptoUtils.generateAnalyticsId()}`,
`_ym_uid=${epoch}${CryptoUtils.generateNumericString()}`,
`_ym_d=${epoch}`,
"_ym_isad=2",
"_ym_visorc=w",
`_ga_RWNEPS7JVV=GS2.1.s${epoch}$o1$g0$t${epoch}$j60$l0$h0`,
].join("; ");
};
const extractCookiesFromHeaders = (headers) => {
const list = [];
if (typeof headers.getSetCookie === "function") {
headers.getSetCookie().forEach(item => list.push(item.split(";")[0]));
} else {
const rawCookie = headers.get("set-cookie");
if (rawCookie) {
rawCookie.split(/,(?=[^;,]+=)/).forEach(v => list.push(v.split(";")[0].trim()));
}
}
return list;
};
const updateCookieString = (currentCookie, newCookies = []) => {
const cookieMap = new Map();
currentCookie.split(";").forEach(part => {
const trimmed = part.trim();
if (trimmed) cookieMap.set(trimmed.split("=")[0], trimmed);
});
newCookies.forEach(cookie => {
if (cookie) cookieMap.set(cookie.split("=")[0], cookie);
});
return [...cookieMap.values()].join("; ");
};
const buildRequestHeaders = (cookieValue = "") => ({
"user-agent": CONFIG.USER_AGENT,
"sec-ch-ua": `"Google Chrome";v="147", "Not.A/Brand";v="8", "Chromium";v="147"`,
"sec-ch-ua-mobile": "?1",
"sec-ch-ua-platform": `"Android"`,
"accept-language": "id-ID,id;q=0.9,en-US;q=0.8,en;q=0.7",
...(cookieValue ? { cookie: cookieValue } : {}),
});
const generateMediaDownloadLink = (rawUrl, filename = "") => {
if (!rawUrl) return null;
const encodedUrl = encodeURIComponent(rawUrl);
return filename
? `${CONFIG.IMAGE_RESOLVER}${encodedUrl}&filename=${encodeURIComponent(filename)}`
: `${CONFIG.IMAGE_RESOLVER}${encodedUrl}`;
};
const formatResponseData = (payload) => {
const rawItems = Array.isArray(payload.items) ? payload.items : [];
const extractedFiles = [];
rawItems.forEach((item, index) => {
if (item.imageSrc) {
extractedFiles.push({
type: "thumbnail",
url: generateMediaDownloadLink(item.imageSrc, `thumbnail-${index + 1}.jpg`),
});
}
if (Array.isArray(item.downloadLink)) {
item.downloadLink.forEach(file => {
extractedFiles.push({
type: item.type || "unknown",
url: generateMediaDownloadLink(file.value, file.filename),
});
});
}
});
return {
linkValue: payload.linkValue || null,
id: payload.id || null,
username: payload.username || null,
text: payload.text || null,
avatarData: payload.avatarData || null,
avatarSrc: payload.avatarSrc || null,
countViews: payload.countViews ?? null,
countComments: payload.countComments ?? null,
countLikes: payload.countLikes ?? null,
comments: payload.comments || [],
takenAt: payload.takenAt || null,
resultUrl: extractedFiles,
};
};
async function establishSession() {
let cookie = generateInitialCookies();
const response = await fetch(`${CONFIG.BASE_URL}/${CONFIG.DEFAULT_LOCALE}/`, {
method: "GET",
headers: {
...buildRequestHeaders(cookie),
accept: "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8",
"upgrade-insecure-requests": "1",
},
});
return updateCookieString(cookie, extractCookiesFromHeaders(response.headers));
}
async function submitTargetToLandingPage(targetUrl, currentCookie) {
const code = getInstagramShortcode(targetUrl);
const targetEndpoint = `${CONFIG.BASE_URL}/${CONFIG.DEFAULT_LOCALE}/download-reels/${code}/`;
const response = await fetch(targetEndpoint, {
method: "POST",
headers: {
...buildRequestHeaders(currentCookie),
"cache-control": "max-age=0",
origin: CONFIG.BASE_URL,
referer: `${CONFIG.BASE_URL}/${CONFIG.DEFAULT_LOCALE}/`,
"content-type": "application/x-www-form-urlencoded",
"upgrade-insecure-requests": "1",
accept: "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8",
"sec-fetch-site": "same-origin",
"sec-fetch-mode": "navigate",
"sec-fetch-dest": "document",
},
body: new URLSearchParams({ url: targetUrl }).toString(),
});
await response.text();
return {
endpoint: targetEndpoint,
cookie: updateCookieString(currentCookie, extractCookiesFromHeaders(response.headers)),
};
}
async function fetchSecurityToken(currentCookie) {
const response = await fetch(`${CONFIG.BASE_URL}/connect/`, {
method: "GET",
headers: {
...buildRequestHeaders(currentCookie),
accept: "application/json, text/plain, */*",
referer: `${CONFIG.BASE_URL}/${CONFIG.DEFAULT_LOCALE}/`,
"sec-fetch-site": "same-origin",
"sec-fetch-mode": "cors",
"sec-fetch-dest": "empty",
},
});
const responseText = await response.text();
if (!response.ok) throw new Error(`Handshake gagal [${response.status}]: ${responseText}`);
const parsedJson = JSON.parse(responseText);
if (!parsedJson.token) throw new Error(`Token otentikasi kosong.`);
return parsedJson.token;
}
async function executeSocketHandshake({ linkValue, token, cookie }) {
return new Promise((resolve, reject) => {
const clientSocket = io(CONFIG.BASE_URL, {
reconnection: false,
transports: ["websocket", "polling"],
extraHeaders: {
...buildRequestHeaders(cookie),
origin: CONFIG.BASE_URL,
referer: `${CONFIG.BASE_URL}/${CONFIG.DEFAULT_LOCALE}/download-reels/${getInstagramShortcode(linkValue)}/`,
},
timeout: CONFIG.SOCKET_TIMEOUT,
});
const watchdogTimer = setTimeout(() => {
clientSocket.disconnect();
reject(new Error("Koneksi gateway mengalami timeout (searchResult)"));
}, CONFIG.SOCKET_TIMEOUT);
clientSocket.on("connect", () => {
clientSocket.emit("search", {
date: Date.now(),
token,
requestType: "2",
linkValue,
});
});
clientSocket.on("searchResult", (payload) => {
clearTimeout(watchdogTimer);
clientSocket.disconnect();
resolve(payload);
});
const handleFailure = (message) => {
clearTimeout(watchdogTimer);
clientSocket.disconnect();
reject(new Error(message));
};
clientSocket.on("connect_error", (err) => handleFailure(`Socket connect_error: ${err.message}`));
clientSocket.on("error", (err) => handleFailure(`Socket error: ${err?.message || String(err)}`));
});
}
async function fetchInstagramMedia(targetUrl) {
try {
let sessionCookie = await establishSession();
const landingState = await submitTargetToLandingPage(targetUrl, sessionCookie);
sessionCookie = landingState.cookie;
const sessionToken = await fetchSecurityToken(sessionCookie);
const sanitizedUrl = sanitizeInstagramUrl(targetUrl);
const socketRawResponse = await executeSocketHandshake({
linkValue: sanitizedUrl,
token: sessionToken,
cookie: sessionCookie,
});
const isSuccess = socketRawResponse?.data?.status === "success" || socketRawResponse?.data?.code === 200;
const extractedPayload = socketRawResponse?.data?.data || socketRawResponse;
return {
Status: isSuccess,
Code: socketRawResponse?.data?.code || (isSuccess ? 200 : 404),
Input: targetUrl,
Result: isSuccess ? formatResponseData(extractedPayload) : extractedPayload,
};
} catch (error) {
return {
Status: false,
Code: 500,
Input: targetUrl,
Result: error.message,
};
}
}
fetchInstagramMedia(TARGET_URL).then((output) => {
console.log(JSON.stringify(output, null, 2));
});