Spaces:
Paused
Paused
import got from 'got'; | |
import * as cheerio from 'cheerio'; | |
import { TwitterDlArgsSchema, TwitterDLResponseSchema, TwitterDlSchema } from '../types/twitter-v1.js'; | |
import { DEFAULT_HEADERS } from '../constant.js'; | |
import { stringifyCookies, generateTokenId } from './util.js'; | |
export async function twitterdl(url) { | |
if (!url || typeof url !== 'string') { | |
throw new Error("Invalid or missing URL parameter."); | |
} | |
TwitterDlArgsSchema.parse([url]); | |
const idMatch = url.match(/status\/(\d+)/) || url.match(/(\d+)/); | |
if (!idMatch) { | |
throw new Error("Invalid Twitter URL: Cannot extract tweet ID."); | |
} | |
const id = idMatch[1]; | |
const token = generateTokenId(id); | |
try { | |
const data = await got(`https://api.redketchup.io/tweetAttachments-v6?id=${encodeURIComponent(token)}`, { | |
headers: { | |
...DEFAULT_HEADERS, | |
origin: 'https://redketchup.io', | |
referer: 'https://redketchup.io/', | |
} | |
}).json(); | |
if (!data || !data.includes || !data.includes.media) { | |
throw new Error("Invalid API response: Missing media data."); | |
} | |
const json = TwitterDLResponseSchema.parse(data); | |
const videos = json.includes.media | |
.filter((m) => m.type === 'video') | |
.flatMap((m) => m.variants) | |
.filter((v) => v.content_type !== 'application/x-mpegURL'); | |
const result = Array.isArray(videos) ? videos : [videos]; | |
return result | |
// return TwitterDlSchema.parse(result); | |
} catch (error) { | |
console.error("Error fetching Twitter video:", error.message); | |
throw new Error("Failed to fetch Twitter video. Please try again later."); | |
} | |
} | |