/***
@ Base: https://pindown.cc/
@ Author: Shannz
@ Note: Pinterest Video/Image/GIF Downloader.
***/
import axios from 'axios';
import * as cheerio from 'cheerio';
import qs from 'qs';
const CONFIG = {
BASE_URL: "https://pindown.cc",
ENDPOINTS: {
HOME: "/en/",
DOWNLOAD: "/en/download"
},
HEADERS: {
"User-Agent": "Mozilla/5.0 (Linux; Android 10; K) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Mobile Safari/537.36",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
"Accept-Encoding": "gzip, deflate, br",
"Cache-Control": "max-age=0",
"Upgrade-Insecure-Requests": "1",
"Origin": "https://pindown.cc",
"Referer": "https://pindown.cc/en/",
"Sec-Fetch-Site": "same-origin",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Dest": "document",
"Priority": "u=0, i"
}
};
const cleanText = (str) => {
return str ? str.replace(/\s+/g, ' ').trim() : '';
};
export const pindown = {
download: async (pinUrl) => {
try {
if (!pinUrl) return { error: 'URL Pinterest tidak boleh kosong.' };
const homeResponse = await axios.get(CONFIG.BASE_URL + CONFIG.ENDPOINTS.HOME, {
headers: CONFIG.HEADERS
});
const cookies = homeResponse.headers['set-cookie'];
const sessionCookie = cookies ? cookies.join('; ') : '';
const $home = cheerio.load(homeResponse.data);
const csrfToken = $home('input[name="csrf_token"]').val();
if (!csrfToken) {
return { error: 'Gagal mendapatkan CSRF Token.' };
}
const postData = qs.stringify({
'csrf_token': csrfToken,
'url': pinUrl
});
const downloadResponse = await axios.post(
CONFIG.BASE_URL + CONFIG.ENDPOINTS.DOWNLOAD,
postData,
{
headers: {
...CONFIG.HEADERS,
'Content-Type': 'application/x-www-form-urlencoded',
'Cookie': sessionCookie,
'Referer': CONFIG.BASE_URL + CONFIG.ENDPOINTS.HOME
}
}
);
const $ = cheerio.load(downloadResponse.data);
const alertError = $('.alert-danger').text();
if (alertError) {
return { error: cleanText(alertError) };
}
const resultContainer = $('.square-box');
if (resultContainer.length === 0) {
return { error: 'Konten tidak ditemukan atau URL tidak valid.' };
}
const title = cleanText(resultContainer.find('.font-weight-bold').text());
const duration = cleanText(resultContainer.find('.text-muted').text());
const thumbnail = resultContainer.find('.square-box-img img').attr('src');
const result = {
title: title,
duration: duration || null,
thumbnail: thumbnail,
medias: []
};
resultContainer.find('.square-box-btn a').each((i, el) => {
const link = $(el).attr('href');
const text = cleanText($(el).text());
let type = 'unknown';
if (text.includes('Video')) type = 'video';
else if (text.includes('Image')) type = 'image';
else if (text.includes('GIF')) type = 'gif';
let ext = 'jpg';
if (link.includes('.mp4')) ext = 'mp4';
else if (link.includes('.gif')) ext = 'gif';
else if (link.includes('.png')) ext = 'png';
result.medias.push({
type: type,
extension: ext,
quality: text.replace('Download ', ''),
url: link
});
});
return result;
} catch (error) {
console.error(`Pindown Error: ${error.message}`);
if (error.response) {
console.error(`Status: ${error.response.status}`);
}
return { error: error.message };
}
}
};