Created
January 1, 2026 19:14
-
-
Save ONLym22/b5c38869d67ff24258485ac9214afc3f to your computer and use it in GitHub Desktop.
Uploaded via ONLym Bot
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| case 'douyindl': | |
| case 'douyin': | |
| case 'ttcn': { | |
| const axios = require('axios'); | |
| const cheerio = require('cheerio'); | |
| const qs = require('qs'); | |
| const vm = require('vm'); | |
| const [subcmd, ...args] = text.split(' '); | |
| const query = args.join(' ').trim(); | |
| if (!subcmd) | |
| return m.reply(`Gunakan format:\n> *ttcn search <kata kunci>*\n> *ttcn down <url>*`); | |
| // ========== FUNGSI SEARCH ========== | |
| if (subcmd.toLowerCase() === 'search') { | |
| if (!query) | |
| return xreply('Masukkan kata kunci pencarian!\nContoh: ttcn search newjeans'); | |
| class DouyinSearchPage { | |
| constructor() { | |
| this.baseURL = 'https://so.douyin.com/'; | |
| this.cookies = {}; | |
| this.defaultParams = { | |
| search_entrance: 'aweme', | |
| enter_method: 'normal_search', | |
| innerWidth: '431', | |
| innerHeight: '814', | |
| reloadNavStart: String(Date.now()), | |
| is_no_width_reload: '1', | |
| keyword: '', | |
| }; | |
| this.api = axios.create({ | |
| baseURL: this.baseURL, | |
| headers: { | |
| 'accept': | |
| 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8', | |
| 'accept-language': 'id-ID,id;q=0.9', | |
| 'referer': 'https://so.douyin.com/', | |
| 'upgrade-insecure-requests': '1', | |
| 'user-agent': | |
| 'Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Mobile Safari/537.36', | |
| }, | |
| }); | |
| this.api.interceptors.response.use((res) => { | |
| const setCookies = res.headers['set-cookie']; | |
| if (setCookies) { | |
| setCookies.forEach((c) => { | |
| const [name, value] = c.split(';')[0].split('='); | |
| if (name && value) this.cookies[name] = value; | |
| }); | |
| } | |
| return res; | |
| }); | |
| this.api.interceptors.request.use((config) => { | |
| if (Object.keys(this.cookies).length) { | |
| config.headers['Cookie'] = Object.entries(this.cookies) | |
| .map(([k, v]) => `${k}=${v}`) | |
| .join('; '); | |
| } | |
| return config; | |
| }); | |
| } | |
| async initialize() { | |
| try { | |
| await this.api.get('/'); | |
| return true; | |
| } catch { | |
| return false; | |
| } | |
| } | |
| async search({ query }) { | |
| await this.initialize(); | |
| const params = { | |
| ...this.defaultParams, | |
| keyword: query, | |
| reloadNavStart: String(Date.now()), | |
| }; | |
| const res = await this.api.get('s', { params }); | |
| const $ = cheerio.load(res.data); | |
| let scriptWithData = ''; | |
| $('script').each((_, el) => { | |
| const text = $(el).html(); | |
| if (text.includes('let data =') && text.includes('"business_data":')) | |
| scriptWithData = text; | |
| }); | |
| const match = scriptWithData.match(/let\s+data\s*=\s*(\{[\s\S]+?\});/); | |
| if (!match) throw 'Data tidak ditemukan di halaman.'; | |
| const dataCode = `data = ${match[1]}`; | |
| const sandbox = {}; | |
| vm.createContext(sandbox); | |
| vm.runInContext(dataCode, sandbox); | |
| const awemeInfos = sandbox.data?.business_data | |
| ?.map((entry) => entry?.data?.aweme_info) | |
| .filter(Boolean); | |
| return awemeInfos; | |
| } | |
| } | |
| try { | |
| const douyin = new DouyinSearchPage(); | |
| const results = await douyin.search({ query }); | |
| if (!results.length) return xreply('Tidak ditemukan hasil.'); | |
| const message = results | |
| .slice(0, 5) | |
| .map((v, i) => { | |
| return `*${i + 1}.* ${v.desc || 'Tanpa deskripsi'}\n👤: ${ | |
| v.author?.nickname | |
| }\n❤️: ${v.statistics?.digg_count} | 💬: ${ | |
| v.statistics?.comment_count | |
| }\n🔗: https://www.douyin.com/video/${v.aweme_id}`; | |
| }) | |
| .join('\n\n'); | |
| m.reply(message); | |
| } catch (err) { | |
| console.error(err); | |
| xreply('❌ Gagal mengambil hasil pencarian Douyin.'); | |
| } | |
| return; | |
| } | |
| // ========== FUNGSI DOWNLOAD ========== | |
| if (subcmd.toLowerCase() === 'down') { | |
| if (!query.startsWith('http')) | |
| return xreply('Masukkan URL Douyin!\nContoh: ttcn down https://v.douyin.com/abcdef/'); | |
| async function douyinDownload(url) { | |
| const postData = qs.stringify({ q: url, lang: 'id', cftoken: '' }); | |
| const response = await axios.post('https://tikvideo.app/api/ajaxSearch', postData, { | |
| headers: { | |
| 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8', | |
| Accept: '*/*', | |
| 'X-Requested-With': 'XMLHttpRequest', | |
| }, | |
| }); | |
| if (response.data.status !== 'ok') throw new Error('Gagal mendapatkan data video.'); | |
| const html = response.data.data; | |
| const $ = cheerio.load(html); | |
| const result = { | |
| status: true, | |
| title: $('.thumbnail .content h3').text().trim(), | |
| duration: $('.thumbnail .content p').first().text().trim(), | |
| thumbnail: $('.thumbnail img').attr('src'), | |
| downloadLinks: [], | |
| }; | |
| $('.dl-action a').each((i, link) => { | |
| const title = $(link).text().trim(); | |
| const url = $(link).attr('href'); | |
| result.downloadLinks.push({ title, url }); | |
| }); | |
| result.noWatermark = | |
| result.downloadLinks.find((x) => /mp4/i.test(x.title))?.url || null; | |
| return result; | |
| } | |
| try { | |
| const result = await douyinDownload(query); | |
| if (!result.status || !result.noWatermark) | |
| return xreply('❌ Video tidak ditemukan atau tidak bisa diambil.'); | |
| let caption = `*✅ ᴅᴏᴜʏɪɴ ʙᴇʀʜᴀꜱɪʟ ᴅɪᴜɴᴅᴜʜ!*\n\n*🎬 Title:* ${result.title}\n*⏱ Durasi:* ${result.duration}\n\n`; | |
| caption += '*🔗 Link Download:* \n'; | |
| for (const dl of result.downloadLinks) { | |
| caption += `- ${dl.title}: ${dl.url}\n`; | |
| } | |
| await vellia.sendMessage( | |
| m.chat, | |
| { | |
| video: { url: result.noWatermark }, | |
| caption, | |
| footer: wm, | |
| contextInfo: { | |
| mentionedJid: [m.sender], | |
| forwardingScore: 9999, | |
| isForwarded: true, | |
| externalAdReply: { | |
| title: '「ᴅᴏᴜʏɪɴ ᴅᴏᴡɴʟᴏᴀᴅᴇʀ」', | |
| body: sig, | |
| thumbnailUrl: result.thumbnail || '', | |
| sourceUrl: query, | |
| mediaType: 1, | |
| renderLargerThumbnail: false, | |
| showAdAttribution: false, | |
| }, | |
| }, | |
| }, | |
| { quoted: ftoko } | |
| ); | |
| } catch (err) { | |
| console.error(err); | |
| xreply('❌ Terjadi kesalahan saat mengunduh video Douyin.'); | |
| } | |
| return; | |
| } | |
| xreply( | |
| `Subcommand tidak valid!\nGunakan:\n- *ttcn search <kata kunci>*\n- *ttcn down <url>*` | |
| ); | |
| } | |
| break; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment