Skip to content

Instantly share code, notes, and snippets.

@ONLym22
Created January 1, 2026 19:14
Show Gist options
  • Select an option

  • Save ONLym22/b5c38869d67ff24258485ac9214afc3f to your computer and use it in GitHub Desktop.

Select an option

Save ONLym22/b5c38869d67ff24258485ac9214afc3f to your computer and use it in GitHub Desktop.
Uploaded via ONLym Bot
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