UNPKG

rsshub

Version:
79 lines (78 loc) 2.74 kB
import { t as parseDate } from "./parse-date-Cr0wQjV_.mjs"; import { t as cache_default } from "./cache-BkqOokyU.mjs"; import { t as got_default } from "./got-BTowW50G.mjs"; import { t as parseItem } from "./utils-DnLmBu8o.mjs"; import { load } from "cheerio"; //#region lib/routes/scmp/topic.ts const route = { path: "/topics/:topic", categories: ["traditional-media"], example: "/scmp/topics/coronavirus-pandemic-all-stories", parameters: { topic: "Topic, can be found in URL" }, features: { requireConfig: false, requirePuppeteer: false, antiCrawler: false, supportBT: false, supportPodcast: false, supportScihub: false }, radar: [{ source: ["scmp.com/topics/:topic"] }], name: "Topics", maintainers: ["TonyRL"], handler }; async function handler(ctx) { const topic = ctx.req.param("topic"); const limit = Number(ctx.req.query("limit")) || 30; const pageUrl = `https://www.scmp.com/topics/${topic}`; const { data: pageResponse } = await got_default(pageUrl); const $ = load(pageResponse); const nextData = JSON.parse($("script#__NEXT_DATA__").text()); const topicData = nextData.props.pageProps.payload.data.topic; const variables = nextData.props.pageProps.operationDescriptor.root.variables; const { data: apiResponse } = await got_default("https://apigw.scmp.com/content-delivery/v2", { headers: { apikey: "MyYvyg8M9RTaevVlcIRhN5yRIqqVssNY", "content-type": "application/json" }, searchParams: { extensions: JSON.stringify({ persistedQuery: { sha256Hash: "8c951c1c2d4e94bc37d06dd94571552da4c0440c744acd00f2af84d3d8b6e2cf", version: 1 } }), operationName: "topicContentListPaginationQuery", variables: JSON.stringify({ applicationIds: variables.applicationIds, count: limit, scmpPlusPaywallTypeIds: variables.scmpPlusPaywallTypeIds, id: topicData.id }) } }); const list = apiResponse.data.node.contents.edges.map(({ node }) => ({ title: node.headline, summary: node.summary.text, link: `https://www.scmp.com${node.urlAlias}`, author: node.authors.map((a) => a.name).join(", "), pubDate: parseDate(node.publishedDate, "x"), updated: parseDate(node.updatedDate, "x") })); const items = await Promise.all(list.map((item) => cache_default.tryGet(item.link, () => parseItem(item)))); ctx.set("json", { nextData, apiResponse }); return { title: topicData.name, link: pageUrl, description: topicData.description.text, item: items, language: "en-hk", icon: "https://assets.i-scmp.com/static/img/icons/scmp-icon-256x256.png", logo: "https://customerservice.scmp.com/img/logo_scmp@2x.png", image: "https://assets-v2.i-scmp.com/production/_next/static/media/default-image.d1be8967.png" }; } //#endregion export { route };