const axios = require("axios"); const { load } = require("cheerio"); const BASE = "https://snaptik.kim/tiktok-story-viewer/?sdl=1"; function parseUsername(input) { input = input.trim(); try { const url = new URL(input.startsWith("http") ? input : "https://" + input); if (url.hostname.includes("tiktok.com")) { const match = url.pathname.match(/\/@?([^/]+)/); if (match) return match[1].replace(/^@/, ""); } } catch {} return input.replace(/^@/, ""); } function parseStats(spans) { const nums = []; spans.each((_, el) => { const text = load(el).text().trim().replace(/,/g, ""); nums.push(isNaN(text) ? text : Number(text)); }); return { likes: nums[0] ?? 0, views: nums[1] ?? 0, comments: nums[2] ?? 0 }; } async function fetchStories(input) { const username = parseUsername(input); const { data: html } = await axios.post( BASE, new URLSearchParams({ page: username, ftype: "all", gres: "", ajax: "1" }).toString(), { headers: { "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8", Accept: "*/*", "X-Requested-With": "XMLHttpRequest", "User-Agent": "Mozilla/5.0 (Linux; Android 10) AppleWebKit/537.36 Chrome/124 Mobile Safari/537.36", Referer: "https://snaptik.kim/tiktok-story-viewer/", }, } ); const $ = load(html); const stories = []; $(".icard").each((i, card) => { const $card = $(card); const thumbnail = $card.find("img.list_media").attr("src") || null; const dlAnchor = $card.find("a.btn-dl"); const downloadUrl = dlAnchor.attr("href") || null; const label = dlAnchor.text().trim().replace(/\s+/g, " "); const stats = parseStats($card.find(".meta span")); stories.push({ index: i + 1, thumbnail, download_url: downloadUrl, size_label: label.replace("Download", "").trim(), ...stats, }); }); return { username, count: stories.length, stories }; } const input = process.argv[2]; if (!input) { console.error(JSON.stringify({ error: "Usage: node tiktok-story.js " }, null, 2)); process.exit(1); } fetchStories(input) .then((result) => console.log(JSON.stringify(result, null, 2))) .catch((err) => { console.error(JSON.stringify({ error: err.message }, null, 2)); process.exit(1); });