UNPKG

rsshub

Version:
114 lines (101 loc) 4.33 kB
import { Route } from '@/types'; import cache from '@/utils/cache'; import ofetch from '@/utils/ofetch'; import { parseDate } from '@/utils/parse-date'; import { BoardsFeedResource, UserActivityPinsResource, UserProfile } from './types'; export const route: Route = { path: '/user/:username/:type?', categories: ['picture'], example: '/pinterest/user/howieserious', parameters: { username: 'Username', type: { description: 'Type, default to `_created`', default: '_created', options: [ { value: '_created', label: 'Created' }, { value: '_saved', label: 'Saved' }, ], }, }, radar: [ { source: ['www.pinterest.com/:id/:type?', 'www.pinterest.com/:id'], target: '/user/:id/:type?', }, ], name: 'User', maintainers: ['TonyRL'], handler, }; const baseUrl = 'https://www.pinterest.com'; async function handler(ctx) { const { username, type = '_created' } = ctx.req.param(); const profile = await getUserResource(username); const response = type === '_created' ? await getUserActivityPinsResource(username, profile.id) : await getBoardsFeedResource(username); const items = type === '_created' ? (response as UserActivityPinsResource[]).map((item) => ({ title: item.title || item.seo_title, description: `${item.grid_description}<br><img src="${item.images.orig.url}">`, link: `${baseUrl}${item.seo_url}`, author: item.pinner.full_name, pubDate: parseDate(item.created_at), image: item.images.orig.url, })) : (response as BoardsFeedResource[]).map((item) => ({ title: item.name, description: item.description + (item.images?.['170x'] ? '<br>' + item.images['170x'].map((img) => `<img src="${img.url}">`).join('') : ''), link: `${baseUrl}${item.url}`, author: item.owner.full_name, pubDate: parseDate(item.created_at), image: item.image_cover_hd_url, })); return { title: profile.seo_title, description: profile.seo_description, image: profile.image_xlarge_url ?? profile.image_medium_url, link: `${baseUrl}/${username}/`, item: items, }; } const getUserResource = (username: string) => cache.tryGet(`pinterest:user:${username}`, async () => { const response = await ofetch(`${baseUrl}/resource/UserResource/get/`, { headers: { 'x-pinterest-pws-handler': 'www/[username]/_created.js', }, query: { source_url: `/${username}/_created`, data: JSON.stringify({ options: { username, field_set_key: 'unauth_profile' }, context: {} }), _: Date.now(), }, }); return response.resource_response.data; }) as Promise<UserProfile>; const getUserActivityPinsResource = async (username: string, userId: string) => { const response = await ofetch(`${baseUrl}/resource/UserActivityPinsResource/get/`, { headers: { 'x-pinterest-pws-handler': 'www/[username]/_created.js', }, query: { source_url: `/${username}/_created`, data: JSON.stringify({ options: { exclude_add_pin_rep: true, field_set_key: 'grid_item', is_own_profile_pins: false, user_id: userId, username }, context: {} }), _: Date.now(), }, }); return response.resource_response.data as UserActivityPinsResource[]; }; const getBoardsFeedResource = async (username: string) => { const response = await ofetch(`${baseUrl}/resource/BoardsFeedResource/get/`, { headers: { 'x-pinterest-pws-handler': 'www/[username]/_saved.js', }, query: { source_url: `/${username}/_saved`, data: JSON.stringify({ options: { field_set_key: 'profile_grid_item', filter_stories: false, sort: 'last_pinned_to', username }, context: {} }), _: Date.now(), }, }); return (response.resource_response.data as BoardsFeedResource[]).filter((item) => item.node_id); };