src/pixiv.js
// ======== CMJS ========
const axios = require("axios")
// ========= Esm ==========
// import axios from 'axios';
// =========== Esm - cmjs ==========
// import { createRequire } from 'module';
// const require = createRequire(import.meta.url);
// const axios = require("axios")
> Ini Versi Pixiv Yang Udah Lengkap Ku Perdetail lagi sama ada beberap perubah dari Versi Sebelumnya Di Buat Jadi Lebih Lengkap Tentunya Bisa Kalian Set Cookie ya!
> *Refactored code By:* _*Bobby Ajah*_
const baseRes = {
author_skrep: 'JH a.k.a Dhika',
kesayangan: 'Fiony Alveriaβ‘',
refactored_by: 'Bobby Ajah'
};
const headers = {
'Accept': 'application/json',
'Accept-Language': 'id-ID,id;q=0.9,en-US;q=0.8,en;q=0.7',
// Cookie Opsional Kalau Mau Ngambil search pixiv semua media termasuk yang ada nsfwnya/r18 pake cookie ya. pastikan di akunnya udh di aktifkan r18 nya di settings akunya.
'Cookie': '',
'Origin': 'https://www.pixiv.net',
'Sec-Ch-Ua': '"Chromium";v="137", "Not/A)Brand";v="24"',
'Sec-Ch-Ua-Mobile': '?0',
'Sec-Ch-Ua-Platform': '"Windows"',
'Sec-Fetch-Dest': 'empty',
'Sec-Fetch-Mode': 'cors',
'Sec-Fetch-Site': 'same-origin',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/137.0.0.0 Safari/537.36'
};
// Helper
function parseTags(tags = []) {
return tags.map(tag => ({
tag: tag.tag || null,
romaji: tag.romaji || null,
translation:
tag.translation?.en ||
tag.translation ||
null
}));
}
function parsePages(manga = []) {
return manga.map(v => ({
page: v.page,
preview: v.url,
small: v.url_small,
original: v.url_big
}));
}
// Search
async function pixivSearch(query, page = 1) {
try {
if (!query) {
throw new Error('Query search gak boleh kosong wak!');
}
page = Number(page) || 1;
if (page < 1) {
page = 1;
}
headers['Referer'] = `https://www.pixiv.net/en/tags/${encodeURIComponent(query)}/artworks`;
const firstUrl = `https://www.pixiv.net/ajax/search/artworks/${encodeURIComponent(query)}?word=${encodeURIComponent(query)}&order=date_d&mode=all&p=1&s_mode=s_tag&type=all&lang=en`;
const { data: firstData } = await axios.get(firstUrl, { headers });
if (firstData.error) {
throw new Error(firstData.message || 'Error dari API Pixiv!');
}
const maxPage =
firstData.body?.illustManga?.lastPage || 1;
if (page > maxPage) {
page = maxPage;
}
const finalUrl = `https://www.pixiv.net/ajax/search/artworks/${encodeURIComponent(query)}?word=${encodeURIComponent(query)}&order=date_d&mode=all&p=${page}&s_mode=s_tag&type=all&lang=en`;
const { data } = await axios.get(finalUrl, { headers });
if (data.error) {
throw new Error(data.message || 'Error dari API Pixiv!');
}
const body = data.body || {};
const illust = body.illustManga || {};
const results = (illust.data || [])
.filter(v => v.id)
.map(v => ({
id: v.id,
title: v.title,
type:
v.illustType === 0 ? 'Illustration' :
v.illustType === 1 ? 'Manga' :
v.illustType === 2 ? 'Ugoira' :
'Unknown',
illust_type: v.illustType,
author: {
id: v.userId,
name: v.userName,
profile_picture: v.profileImageUrl
},
image: {
thumbnail: v.url,
width: v.width,
height: v.height,
ratio: `${v.width}x${v.height}`
},
page_count: v.pageCount,
tags: v.tags || [],
caption: v.alt || '',
description: v.description || '',
create_date: v.createDate,
update_date: v.updateDate,
ai_type:
v.aiType === 0 ? 'Unknown' :
v.aiType === 1 ? 'AI Assisted' :
v.aiType === 2 ? 'AI Generated' :
'Unknown',
x_restrict: v.xRestrict,
restrict: v.restrict,
is_r18: v.xRestrict === 1,
is_bookmarkable: v.isBookmarkable,
bookmark_data: v.bookmarkData,
is_original: v.isOriginal,
is_unlisted: v.isUnlisted,
is_masked: v.isMasked,
is_howto: v.is_howto,
visibility_scope: v.visibilityScope,
title_caption_translation:
v.titleCaptionTranslation || {}
}));
const resultsNah = {
...baseRes,
status: true,
type: 'search',
query,
current_page: page,
max_page: maxPage,
total: illust.total || 0,
total_result: results.length,
related_tags:
body.relatedTags || [],
tag_translation:
body.tagTranslation || {},
data: results
}
return resultsNah
} catch (e) {
let err = e.response?.data || e.message;
if (Buffer.isBuffer(err)) {
err = err.toString('utf-8');
}
return {
...baseRes,
status: false,
error: err
}
}
}
// Detail
async function pixivDetail(id) {
try {
if (!id) {
throw new Error('ID artwork wajib diisi wak!');
}
headers['Referer'] = `https://www.pixiv.net/en/artworks/${id}`;
const { data: detailData } = await axios.get(`https://www.pixiv.net/ajax/illust/${id}`, { headers });
if (detailData.error) {
throw new Error(
detailData.message || 'Gagal narik detail!'
);
}
const info = detailData.body || {};
const touchUrl = `https://www.pixiv.net/touch/ajax/illust/details?illust_id=${id}&ref=&lang=en&version=60714fe62bb4943c447667fb6a4f9eef6d4edeaa`;
const { data: touchData } = await axios.get(touchUrl, { headers });
if (touchData.error) {
throw new Error(
touchData.message || 'Gagal narik raw detail!'
);
}
const detail = touchData.body?.illust_details || {};
const mangaPages = parsePages(detail.manga_a || []);
const resultsNah = {
...baseRes,
status: true,
type: 'detail',
data: {
id:
detail.id || info.illustId,
title:
detail.title || info.illustTitle,
description:
detail.comment || '',
share_text:
detail.share_text || null,
type:
info.illustType === 0 ? 'Illustration' :
info.illustType === 1 ? 'Manga' :
info.illustType === 2 ? 'Ugoira' :
'Unknown',
illust_type:
info.illustType,
author: {
id:
detail.author_details?.user_id ||
info.userId,
name:
detail.author_details?.user_name ||
info.userName,
account:
detail.author_details?.user_account ||
null,
profile_picture:
touchData.body?.author_details?.profile_img?.main ||
null
},
image: {
preview:
detail.url || null,
thumbnail:
detail.url_s || null,
square:
detail.url_ss || null,
placeholder:
detail.url_placeholder || null,
original:
detail.url_big || null
},
pages:
mangaPages,
total_pages:
mangaPages.length,
dimensions: {
width:
Number(detail.width || info.width),
height:
Number(detail.height || info.height),
ratio:
`${detail.width || info.width}x${detail.height || info.height}`
},
stats: {
views:
Number(detail.rating_view || info.viewCount || 0),
bookmarks:
Number(detail.bookmark_user_total || info.bookmarkCount || 0),
likes:
Number(info.likeCount || 0),
comments:
Number(detail.rating_count || info.commentCount || 0)
},
tags:
parseTags(detail.display_tags || []),
raw_tags:
detail.tags || [],
page_count:
Number(detail.page_count || info.pageCount || 1),
restrict:
Number(detail.restrict || 0),
x_restrict:
Number(detail.x_restrict || 0),
is_r18:
Number(detail.x_restrict || 0) === 1,
is_original:
detail.is_original || false,
ai_type:
detail.ai_type || 0,
upload_timestamp:
detail.upload_timestamp || null,
upload_date:
detail.upload_timestamp
? new Date(detail.upload_timestamp * 1000).toISOString()
: null,
create_date:
info.createDate || null,
upload_date_full:
info.uploadDate || null,
title_caption_translation:
detail.title_caption_translation || {},
}
}
return resultsNah
} catch (e) {
let err = e.response?.data || e.message;
if (Buffer.isBuffer(err)) {
err = err.toString('utf-8');
}
return {
...baseRes,
status: false,
error: err
}
}
}
// Download
async function pixivDownload(url) {
try {
if (!url) {
throw new Error(
'URL gambar wajib diisi wak!'
);
}
headers['Referer'] = 'https://www.pixiv.net/';
const { data, headers: resHeaders } = await axios.get(url, {
headers,
responseType: 'arraybuffer'
});
return {
...baseRes,
status: true,
type: 'download',
data: {
mime:
resHeaders['content-type'] ||
'image/jpeg',
size:
Buffer.byteLength(data),
buffer:
Buffer.from(data)
}
};
} catch (e) {
let err = e.response?.data || e.message;
if (Buffer.isBuffer(err)) {
err = err.toString('utf-8');
}
return {
...baseRes,
status: false,
error: err
}
}
}
// Author
async function pixivAuthor(authorId) {
try {
if (!authorId) {
throw new Error(
'ID Author wajib diisi wak!'
);
}
headers['Referer'] = `https://www.pixiv.net/en/users/${authorId}`;
// ===== PROFILE ALL =====
const { data: authorData } = await axios.get(`https://www.pixiv.net/ajax/user/${authorId}/profile/all`, { headers });
if (authorData.error) {
throw new Error(
authorData.message ||
'Gagal narik profile!'
);
}
// ===== TOUCH DETAIL =====
const detailUrl = `https://www.pixiv.net/touch/ajax/user/details?id=${authorId}&lang=en&version=689bdfbbc5bda11acacc0952055721d8a78e51fd`;
const { data: touchData } = await axios.get(detailUrl, { headers });
if (touchData.error) {
throw new Error(
touchData.message ||
'Gagal narik detail author!'
);
}
const user =
touchData.body?.user_details || {};
// ===== WORK IDS =====
const combinedIds = [
...Object.keys(
authorData.body?.illusts || {}
),
...Object.keys(
authorData.body?.manga || {}
)
]
.sort((a, b) => b - a)
.slice(0, 15);
if (!combinedIds.length) {
return JSON.stringify({
...baseRes,
status: false,
message: 'Gak ada karya wak!'
}, null, 2);
}
// ===== WORK DETAIL =====
const idsQuery = combinedIds.map(id => `ids%5B%5D=${id}`).join('&');
const { data: worksData } = await axios.get(`https://www.pixiv.net/ajax/user/${authorId}/profile/illusts?${idsQuery}&work_category=illustManga&is_first_page=1`, { headers });
const results = combinedIds
.map(id => {
const work =
worksData.body?.works?.[id];
if (!work) return null;
return {
id: work.id,
title: work.title,
type:
work.illustType === 0 ? 'Illustration' :
work.illustType === 1 ? 'Manga' :
work.illustType === 2 ? 'Ugoira' :
'Unknown',
illust_type:
work.illustType,
thumbnail:
work.url,
tags:
work.tags || [],
page_count:
work.pageCount,
dimensions: {
width:
work.width,
height:
work.height,
ratio:
`${work.width}x${work.height}`
},
stats: {
total_bookmark:
work.bookmarkCount || 0,
total_view:
work.viewCount || 0
},
restrict:
work.xRestrict || 0,
is_r18:
work.tags?.includes('R-18') || false
};
})
.filter(Boolean);
const resultsNah = {
...baseRes,
status: true,
type: 'author',
author: {
id:
user.user_id || authorId,
name:
user.user_name || null,
account:
user.user_account || null,
premium:
Number(user.user_premium || 0) === 1,
comment:
user.user_comment || null,
comment_html:
user.user_comment_html || null,
webpage:
user.user_webpage || null,
avatar: {
main:
user.profile_img?.main || null,
small:
user.profile_img?.main_s || null
},
cover_image:
user.cover_image
?.profile_cover_image?.['720x360'] || null,
social:
user.social || {},
commission:
user.commission || {},
follows:
Number(user.follows || 0),
flags: {
followed:
user.is_followed || false,
following:
user.is_following || false,
mypixiv:
user.is_mypixiv || false,
blocking:
user.is_blocking || false,
blocked:
user.is_blocked || false,
official:
user.is_official || false,
publisher:
user.is_publisher || false
},
availability: {
has_illusts:
user.has_illusts || false,
has_mangas:
user.has_mangas || false,
has_novels:
user.has_novels || false,
has_bookmarks:
user.has_bookmarks || false,
has_collections:
user.has_collections || false
}
},
total:
results.length,
data:
results
}
return resultsNah
} catch (e) {
let err = e.response?.data || e.message;
if (Buffer.isBuffer(err)) {
err = err.toString('utf-8');
}
return {
...baseRes,
status: false,
error: err
}
}
}
// Beberapa Example Cobain aja Satu Satu π
// SEARCH
// pixivSearch('Hatsune Miku')
// pixivSearch('Hatsune Miku', 5)
// DETAIL
// pixivDetail('98079929')
// DOWNLOAD
// pixivDownload('https://i.pximg.net/img-original/img/2022/05/03/22/46/41/98079929_p0.jpg')
// AUTHOR
// pixivAuthor('38819785')
Direct URL
Disalin!