instagram: use different endpoint and fallback to two other options
This commit is contained in:
parent
f48a1d9af6
commit
1ff49f0669
1 changed files with 112 additions and 28 deletions
|
@ -60,39 +60,99 @@ async function request(url, cookie, method = 'GET', requestData) {
|
|||
return data.json();
|
||||
}
|
||||
|
||||
async function getPost(id) {
|
||||
let data;
|
||||
try {
|
||||
const cookie = getCookie('instagram');
|
||||
let dtsgId;
|
||||
|
||||
if (cookie) {
|
||||
dtsgId = await findDtsgId(cookie);
|
||||
async function requestHTML(id, cookie = {}) {
|
||||
const data = await fetch(`https://www.instagram.com/p/${id}/embed/captioned/`, {
|
||||
headers: {
|
||||
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
|
||||
"Accept-Language": "en-GB,en;q=0.9",
|
||||
"Cache-Control": "max-age=0",
|
||||
"Dnt": "1",
|
||||
"Priority": "u=0, i",
|
||||
"Sec-Ch-Ua": 'Chromium";v="124", "Google Chrome";v="124", "Not-A.Brand";v="99',
|
||||
"Sec-Ch-Ua-Mobile": "?0",
|
||||
"Sec-Ch-Ua-Platform": "macOS",
|
||||
"Sec-Fetch-Dest": "document",
|
||||
"Sec-Fetch-Mode": "navigate",
|
||||
"Sec-Fetch-Site": "none",
|
||||
"Sec-Fetch-User": "?1",
|
||||
"Upgrade-Insecure-Requests": "1",
|
||||
"User-Agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36",
|
||||
...cookie
|
||||
}
|
||||
}).then(r => r.text());
|
||||
|
||||
const url = new URL('https://www.instagram.com/api/graphql/');
|
||||
let embedData = JSON.parse(data?.match(/"init",\[\],\[(.*?)\]\],/)[1]);
|
||||
|
||||
const requestData = {
|
||||
jazoest: '26406',
|
||||
variables: JSON.stringify({
|
||||
shortcode: id,
|
||||
__relay_internal__pv__PolarisShareMenurelayprovider: false
|
||||
}),
|
||||
doc_id: '7153618348081770'
|
||||
};
|
||||
if (dtsgId) {
|
||||
requestData.fb_dtsg = dtsgId;
|
||||
if (!embedData || !embedData?.contextJSON) return false;
|
||||
|
||||
embedData = JSON.parse(embedData.contextJSON);
|
||||
|
||||
return embedData;
|
||||
}
|
||||
async function requestGQL(id, cookie) {
|
||||
let dtsgId;
|
||||
|
||||
if (cookie) {
|
||||
dtsgId = await findDtsgId(cookie);
|
||||
}
|
||||
const url = new URL('https://www.instagram.com/api/graphql/');
|
||||
|
||||
const requestData = {
|
||||
jazoest: '26406',
|
||||
variables: JSON.stringify({
|
||||
shortcode: id,
|
||||
__relay_internal__pv__PolarisShareMenurelayprovider: false
|
||||
}),
|
||||
doc_id: '7153618348081770'
|
||||
};
|
||||
if (dtsgId) {
|
||||
requestData.fb_dtsg = dtsgId;
|
||||
}
|
||||
|
||||
return (await request(url, cookie, 'POST', requestData))
|
||||
.data
|
||||
?.xdt_api__v1__media__shortcode__web_info
|
||||
?.items
|
||||
?.[0];
|
||||
}
|
||||
|
||||
async function extractOldPost(data, id) {
|
||||
const sidecar = data?.gql_data?.shortcode_media?.edge_sidecar_to_children;
|
||||
if (sidecar) {
|
||||
const picker = sidecar.edges.filter(e => e.node?.display_url)
|
||||
.map(e => {
|
||||
const type = e.node?.is_video ? "video" : "photo";
|
||||
const url = type === "video" ? e.node?.video_url : e.node?.display_url;
|
||||
|
||||
return {
|
||||
type, url,
|
||||
/* thumbnails have `Cross-Origin-Resource-Policy`
|
||||
** set to `same-origin`, so we need to proxy them */
|
||||
thumb: createStream({
|
||||
service: "instagram",
|
||||
type: "default",
|
||||
u: e.node?.display_url,
|
||||
filename: "image.jpg"
|
||||
})
|
||||
}
|
||||
});
|
||||
|
||||
if (picker.length) return { picker }
|
||||
} else if (data?.gql_data?.shortcode_media?.video_url) {
|
||||
return {
|
||||
urls: data.shortcode_media.video_url,
|
||||
filename: `instagram_${id}.mp4`,
|
||||
audioFilename: `instagram_${id}_audio`
|
||||
}
|
||||
} else if (data?.gql_data?.shortcode_media?.display_url) {
|
||||
return {
|
||||
urls: data.gql_data?.shortcode_media.display_url,
|
||||
isPhoto: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data = (await request(url, cookie, 'POST', requestData))
|
||||
.data
|
||||
?.xdt_api__v1__media__shortcode__web_info
|
||||
?.items
|
||||
?.[0];
|
||||
} catch {}
|
||||
|
||||
if (!data) return { error: 'ErrorCouldntFetch' };
|
||||
|
||||
async function extractNewPost(data, id) {
|
||||
const carousel = data.carousel_media;
|
||||
if (carousel) {
|
||||
const picker = carousel.filter(e => e?.image_versions2)
|
||||
|
@ -133,7 +193,31 @@ async function getPost(id) {
|
|||
isPhoto: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function getPost(id) {
|
||||
let data, result, dataType = 'old';
|
||||
try {
|
||||
const cookie = getCookie('instagram');
|
||||
|
||||
data = await requestHTML(id);
|
||||
if (!data) data = await requestHTML(id, cookie);
|
||||
|
||||
if (!data) {
|
||||
dataType = 'new';
|
||||
data = await requestGQL(id, cookie);
|
||||
}
|
||||
} catch {}
|
||||
|
||||
if (!data) return { error: 'ErrorCouldntFetch' };
|
||||
|
||||
if (dataType === 'new') {
|
||||
result = extractNewPost(data, id)
|
||||
} else {
|
||||
result = extractOldPost(data, id)
|
||||
}
|
||||
|
||||
if (result) return result;
|
||||
return { error: 'ErrorEmptyDownload' }
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue