File size: 3,841 Bytes
7e9ddb1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
const axios = require('axios');
const cheerio = require('cheerio');
const { shannz: cf } = require('bycf');

async function getTurnstileToken() {
    try {
        const token = await cf.turnstileMin(
            "https://claptools.com/tiktok-profile-viewer/",
            "0x4AAAAAAA0aU62HwPRV0j1U"
        );
        return token;
    } catch (error) {
        throw new Error("Gagal mendapatkan Turnstile token: " + error.message);
    }
}

async function getNonce() {
    const response = await axios.get('https://claptools.com/tiktok-profile-viewer/', {
        headers: {
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
        }
    });

    const $ = cheerio.load(response.data);
    const nonce = $('input[name="tt_nonce"]').val();
    return nonce;
}

async function tiktokStalk(username) {
    const token = await getTurnstileToken();
    const nonce = await getNonce();

    const formData = new URLSearchParams();
    formData.append('username', username);
    formData.append('tt_nonce', nonce);
    formData.append('cf-turnstile-response', token);

    const response = await axios.post('https://claptools.com/tiktok-profile-viewer/', formData, {
        headers: {
            'Content-Type': 'application/x-www-form-urlencoded',
            'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36',
            'Referer': 'https://claptools.com/tiktok-profile-viewer/',
            'Origin': 'https://claptools.com'
        }
    });

    const $ = cheerio.load(response.data);

    const avatar = $('.profile img').attr('src');
    const fullText = $('.profile-details h2').text().trim();
    const bio = $('.profile-details p').text().trim();

    const nameMatch = fullText.match(/^(.+?)\s*\(@(.+?)\)$/);
    const nickname = nameMatch ? nameMatch[1].trim() : '';
    const usernameFromPage = nameMatch ? nameMatch[2].trim() : username;

    const followers = $('.stats .box').eq(0).find('.number').text().trim();
    const likes = $('.stats .box').eq(1).find('.number').text().trim();
    const videos = $('.stats .box').eq(2).find('.number').text().trim();

    const videoList = [];
    $('.thumb').each((i, elem) => {
        const thumbnail = $(elem).find('img').attr('src');
        if (thumbnail) {
            videoList.push({
                thumbnail: thumbnail
            });
        }
    });

    return {
        username: usernameFromPage,
        nickname: nickname,
        bio: bio,
        avatar: avatar,
        stats: {
            followers: followers,
            likes: likes,
            videos: videos
        },
        videoList: videoList
    };
}

const handler = async (req, res) => {
    try {
        const { username } = req.query;

        if (!username) {
            return res.status(400).json({
                success: false,
                error: 'Missing required parameter: username'
            });
        }

        const usernameRegex = /^[a-zA-Z0-9._]{1,24}$/;
        if (!usernameRegex.test(username)) {
            return res.status(400).json({
                success: false,
                error: 'Invalid username format'
            });
        }

        const result = await tiktokStalk(username);

        res.json({
            author: "Herza",
            success: true,
            data: result
        });

    } catch (error) {
        res.status(500).json({
            author: "Herza",
            success: false,
            error: error.message
        });
    }
};

module.exports = {
    name: 'TikTok Stalk',
    description: 'Get TikTok user profile information including stats and avatar',
    type: 'GET',
    routes: ['api/stalk/tiktok'],
    tags: ['social', 'tiktok', 'stalk', 'profile'],
    parameters: ['username', 'key'],
    enabled: true,
    main: ['Stalk'],
    handler
};