File size: 1,525 Bytes
3929273
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
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) {
    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();

        const json = TwitterDLResponseSchema.parse(data);
        const media = json.includes?.media?.find((m) => m.type === 'video');

        if (!media || !media.variants) {
            throw new Error("No video found in this tweet.");
        }

        const result = media.variants
            .filter((variant) => variant.content_type !== 'application/x-mpegURL')
            .filter(Boolean);

        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.");
    }
}