UNPKG

media-scraper

Version:

TypeScript-first multi-platform social media scraper without API keys

65 lines (64 loc) 2.54 kB
import { $fetch } from "ofetch"; import { instagramHeaders } from "../utils/helpers.mjs"; import { instagramRegex } from "../utils/regex.mjs"; export default async (url) => { const match = url.match(instagramRegex); if (!match) throw new Error("Invalid Instagram URL"); if (url.includes("/share")) { url = (await $fetch.raw(url, { method: "HEAD", headers: instagramHeaders }).catch(() => null))?.url || url; } const regexId = /instagram.com\/(?:[A-Za-z0-9_.]+\/)?(p|reels|reel|share)\/([A-Za-z0-9-_]+)/; const matchId = url.match(regexId); if (!matchId) throw new Error("Invalid Instagram URL format"); const postId = matchId[2]; const post = await $fetch("https://www.instagram.com/api/graphql", { method: "POST", query: { doc_id: "10015901848480474", lsd: "AVqbxe3J_YA", variables: { shortcode: postId } }, headers: instagramHeaders, responseType: "json" }).catch(() => null); if (!post) throw new Error("Failed to fetch the Instagram URL"); const data = post?.data?.xdt_shortcode_media; return { id: data?.id, code: data?.shortcode, caption: data?.edge_media_to_caption?.edges?.[0]?.node?.text?.trim(), permalink_url: `https://www.instagram.com/p/${data?.shortcode}/`, thumnail_url: data?.display_url || data?.thumbnail_src, author: { id: data?.owner?.id, name: data?.owner?.full_name, username: data?.owner?.username, avatar_url: data?.owner?.profile_pic_url }, width: data?.dimensions?.width, height: data?.dimensions?.height, likes_count: data?.edge_media_preview_like?.count, type: data?.__typename === "XDTGraphSidecar" ? "carousel" : data?.__typename === "XDTGraphVideo" ? "video" : "image", created_at: data?.taken_at_timestamp, ...data?.video_url && { video: { duration: data?.video_duration ? data?.video_duration * 1e3 : void 0, url: data?.video_url } }, carousel_media: data?.edge_sidecar_to_children?.edges?.map((item) => ({ id: item?.node?.id, code: item?.node?.shortcode, thumbnail_url: item?.node?.display_url || item?.node?.thumbnail_src, width: item?.node?.dimensions?.width, height: item?.node?.dimensions?.height, type: item?.node?.__typename === "XDTGraphVideo" ? "video" : "image", ...item?.node?.video_url && { video: { duration: item?.node?.video_duration ? item?.node?.video_duration * 1e3 : void 0, url: item?.node?.video_url } } })) }; };