UNPKG

rsshub

Version:
95 lines (93 loc) 5.02 kB
import { n as init_esm_shims, t as __dirname } from "./esm-shims-CzJ_djXG.mjs"; import { t as config } from "./config-C37vj7VH.mjs"; import "./dist-BInvbO1W.mjs"; import "./logger-Czu8UMNd.mjs"; import { t as ofetch_default } from "./ofetch-BIyrKU3Y.mjs"; import { t as parseDate } from "./parse-date-BrP7mxXf.mjs"; import { t as cache_default } from "./cache-Bo__VnGm.mjs"; import { t as art } from "./render-BQo6B4tL.mjs"; import path from "node:path"; import * as cheerio from "cheerio"; //#region lib/routes/patreon/feed.ts init_esm_shims(); const route = { path: "/:creator", categories: ["new-media"], example: "/patreon/straightupsisters", parameters: { creator: "Patreon creator id, can be found in the url" }, features: { requireConfig: [{ name: "PATREON_SESSION_ID", optional: true, description: "The value of the session_id cookie after logging in to Patreon, required to access paid posts" }], nsfw: true }, radar: [{ source: ["patreon.com/:creator"] }], name: "Home", maintainers: ["TonyRL"], handler }; async function handler(ctx) { const { creator } = ctx.req.param(); const link = `https://www.patreon.com/${creator}`; const creatorData = await cache_default.tryGet(`patreon:creator:${creator}`, async () => { const response = await ofetch_default(link); const $ = cheerio.load(response); const bootstrapEnvelope = JSON.parse($("#__NEXT_DATA__").text()).props.pageProps.bootstrapEnvelope; return { id: bootstrapEnvelope.pageBootstrap.campaign.data.id, attributes: bootstrapEnvelope.pageBootstrap.campaign.data.attributes }; }); if (!creatorData.id) throw new Error("Creator not found"); let headers = {}; if (config.patreon?.sessionId) headers = { Cookie: `session_id=${config.patreon.sessionId}` }; const posts = await ofetch_default("https://www.patreon.com/api/posts", { headers, query: { include: "campaign,access_rules,access_rules.tier.null,attachments_media,audio,audio_preview.null,drop,images,media,native_video_insights,poll.choices,poll.current_user_responses.user,poll.current_user_responses.choice,poll.current_user_responses.poll,user,user_defined_tags,ti_checks,video.null,content_unlock_options.product_variant.null", "fields[campaign]": "currency,show_audio_post_download_links,avatar_photo_url,avatar_photo_image_urls,earnings_visibility,is_nsfw,is_monthly,name,url", "fields[post]": "change_visibility_at,comment_count,commenter_count,content,created_at,current_user_can_comment,current_user_can_delete,current_user_can_report,current_user_can_view,current_user_comment_disallowed_reason,current_user_has_liked,embed,image,insights_last_updated_at,is_paid,like_count,meta_image_url,min_cents_pledged_to_view,monetization_ineligibility_reason,post_file,post_metadata,published_at,patreon_url,post_type,pledge_url,preview_asset_type,thumbnail,thumbnail_url,teaser_text,title,upgrade_url,url,was_posted_by_campaign_owner,has_ti_violation,moderation_status,post_level_suspension_removal_date,pls_one_liners_by_category,video,video_preview,view_count,content_unlock_options,is_new_to_current_user,watch_state", "fields[post_tag]": "tag_type,value", "fields[user]": "image_url,full_name,url", "fields[access_rule]": "access_rule_type,amount_cents", "fields[media]": "id,image_urls,display,download_url,metadata,file_name", "fields[native_video_insights]": "average_view_duration,average_view_pct,has_preview,id,last_updated_at,num_views,preview_views,video_duration", "fields[content-unlock-option]": "content_unlock_type", "fields[product-variant]": "price_cents,currency_code,checkout_url,is_hidden,published_at_datetime,content_type,orders_count,access_metadata", "filter[campaign_id]": creatorData.id, "filter[contains_exclusive_posts]": true, "filter[is_draft]": false, sort: "-published_at", "json-api-use-default-includes": false, "json-api-version": "1.0" } }); const items = posts.data.map(({ attributes, relationships }) => { for (const [key, value] of Object.entries(relationships)) if (value.data) relationships[key] = Array.isArray(value.data) ? value.data.map((item) => posts.included.find((i) => i.id === item.id)) : posts.included.find((i) => i.id === value.data.id); if (attributes.video_preview) relationships.video_preview = posts.included.find((i) => Number.parseInt(i.id) === attributes.video_preview?.media_id); return { title: attributes.title, description: art(path.join(__dirname, "templates/description-4c0b7baa.art"), { attributes, relationships, included: posts.included }), link: attributes.url, pubDate: parseDate(attributes.published_at), image: attributes.thumbnail?.url ?? attributes.image?.url, category: relationships.user_defined_tags?.map((tag) => tag.attributes.value) }; }); return { title: creatorData.attributes.name, description: creatorData.attributes.creation_name, link, image: creatorData.attributes.avatar_photo_url, item: items, allowEmpty: true }; } //#endregion export { route };