UNPKG

rsshub

Version:
322 lines (319 loc) 14.2 kB
import "./esm-shims-CzJ_djXG.mjs"; import { t as config } from "./config-C37vj7VH.mjs"; import { t as ViewType } from "./types-D84BRIt4.mjs"; import "./dist-BInvbO1W.mjs"; import "./logger-Czu8UMNd.mjs"; import "./ofetch-BIyrKU3Y.mjs"; import { t as parseDate } from "./parse-date-BrP7mxXf.mjs"; import "./md5-C8GRvctM.mjs"; import { t as cache_default } from "./cache-Bo__VnGm.mjs"; import { a as parseDuration } from "./helpers-DxBp0Pty.mjs"; import "./render-BQo6B4tL.mjs"; import "./proxy-Db7uGcYb.mjs"; import { t as got_default } from "./got-KxxWdaxq.mjs"; import "./puppeteer-DGmvuGvT.mjs"; import { n as queryToBoolean, t as fallback } from "./readable-social-DoIL4WB3.mjs"; import { n as getVideoUrl, r as utils_default, t as getLiveUrl } from "./utils-XRYoJEu4.mjs"; import { t as cache_default$1 } from "./cache-COvn8_4R.mjs"; import { t as captcha_default } from "./captcha-CMCNYwwK.mjs"; import JSONbig from "json-bigint"; //#region lib/routes/bilibili/dynamic.ts const route = { path: "/user/dynamic/:uid/:routeParams?", categories: ["social-media"], view: ViewType.SocialMedia, example: "/bilibili/user/dynamic/2267573", parameters: { uid: "用户 id, 可在 UP 主主页中找到", routeParams: ` | 键 | 含义 | 接受的值 | 默认值 | | ---------- | --------------------------------- | -------------- | ------ | | showEmoji | 显示或隐藏表情图片 | 0/1/true/false | false | | embed | 默认开启内嵌视频 | 0/1/true/false | true | | useAvid | 视频链接使用 AV 号 (默认为 BV 号) | 0/1/true/false | false | | directLink | 使用内容直链 | 0/1/true/false | false | | hideGoods | 隐藏带货动态 | 0/1/true/false | false | | offset | 偏移状态 | string | "" | 用例:\`/bilibili/user/dynamic/2267573/showEmoji=1&embed=0&useAvid=1\`` }, features: { requireConfig: [{ name: "BILIBILI_COOKIE_*", optional: true, description: `如果没有此配置,那么必须开启 puppeteer 支持;BILIBILI_COOKIE_{uid}: 用于用户关注动态系列路由,对应 uid 的 b 站用户登录后的 Cookie 值,\`{uid}\` 替换为 uid,如 \`BILIBILI_COOKIE_2267573\`,获取方式: 1. 打开 [https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/dynamic_new?uid=0&type=8](https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/dynamic_new?uid=0&type=8) 2. 打开控制台,切换到 Network 面板,刷新 3. 点击 dynamic_new 请求,找到 Cookie 4. 视频和专栏,UP 主粉丝及关注只要求 \`SESSDATA\` 字段,动态需复制整段 Cookie` }], requirePuppeteer: false, antiCrawler: false, supportBT: false, supportPodcast: false, supportScihub: false }, radar: [{ source: ["space.bilibili.com/:uid"], target: "/user/dynamic/:uid" }], name: "UP 主动态", maintainers: [ "DIYgod", "zytomorrow", "CaoMeiYouRen", "JimenezLi" ], handler }; const getTitle = (data) => { const major = data.module_dynamic?.major; if (!major) return ""; if (major.none) return major.none.tips; if (major.courses) return `${major.courses?.title} - ${major.courses?.sub_title}`; if (major.live_rcmd?.content) return JSON.parse(major.live_rcmd.content)?.live_play_info?.title; return major[major.type.replace("MAJOR_TYPE_", "").toLowerCase()]?.title; }; const getDes = (data) => { let desc = ""; if (data.module_dynamic?.desc?.text) desc += data.module_dynamic.desc.text; const major = data.module_dynamic?.major; if (!major) return desc; if (major?.common?.desc) { desc += desc ? `<br>//转发自: ${major.common.desc}` : major.common.desc; return desc; } if (major?.live) return `${major.live?.desc_first}<br>${major.live?.desc_second}`; if (major.live_rcmd?.content) { const live_play_info = JSON.parse(major.live_rcmd.content)?.live_play_info; return `${live_play_info?.area_name}·${live_play_info?.watched_show?.text_large}`; } if (major?.opus) return major?.opus?.summary?.text; return major[major.type.replace("MAJOR_TYPE_", "").toLowerCase()]?.desc; }; const getOriginTitle = (data) => data && getTitle(data); const getOriginDes = (data) => data && getDes(data); const getOriginName = (data) => data?.module_author?.name; const getIframe = (data, embed = true) => { if (!embed) return ""; const aid = data?.module_dynamic?.major?.archive?.aid; const bvid = data?.module_dynamic?.major?.archive?.bvid; if (aid === void 0 && bvid === void 0) return ""; return utils_default.renderUGCDescription(embed, "", "", aid, void 0, bvid); }; const getImgs = (data) => { const imgUrls = []; const major = data?.module_dynamic?.major; if (!major) return ""; if (major.opus?.pics?.length) imgUrls.push(...major.opus.pics.map((e) => ({ url: e.url, width: e.width, height: e.height }))); if (major.article?.covers?.length) imgUrls.push(...major.article.covers.map((e) => ({ url: e }))); if (major.draw?.items?.length) imgUrls.push(...major.draw.items.map((e) => ({ url: e.src, width: e.width, height: e.height }))); if (major.live_rcmd?.content) imgUrls.push({ url: JSON.parse(major.live_rcmd.content)?.live_play_info?.cover }); const type = major.type.replace("MAJOR_TYPE_", "").toLowerCase(); if (major[type]?.cover) imgUrls.push({ url: major[type]?.cover }); return imgUrls.filter(Boolean).map((img) => `<img src="${img.url}" ${img.width ? `width="${img.width}"` : ""} ${img.height ? `height="${img.height}"` : ""}>`).join(""); }; const getUrl = (item, useAvid = false) => { const data = item?.modules; if (!data) return null; let url = ""; let text = ""; let videoPageUrl; const major = data.module_dynamic?.major; if (!major) return null; switch (major?.type) { case "MAJOR_TYPE_UGC_SEASON": url = major?.ugc_season?.jump_url || ""; text = `合集地址:<a href=${url}>${url}</a>`; break; case "MAJOR_TYPE_ARTICLE": url = `https://www.bilibili.com/read/cv${major?.article?.id}`; text = `专栏地址:<a href=${url}>${url}</a>`; break; case "MAJOR_TYPE_ARCHIVE": { const archive = major?.archive; url = `https://www.bilibili.com/video/${useAvid ? `av${archive?.aid}` : archive?.bvid}`; text = `视频地址:<a href=${url}>${url}</a>`; videoPageUrl = getVideoUrl(archive?.bvid); break; } case "MAJOR_TYPE_COMMON": url = major?.common?.jump_url || ""; text = `地址:<a href=${url}>${url}</a>`; break; case "MAJOR_TYPE_OPUS": if (item?.type === "DYNAMIC_TYPE_ARTICLE") { url = `https:${major?.opus?.jump_url}`; text = `专栏地址:<a href=${url}>${url}</a>`; } else if (item?.type === "DYNAMIC_TYPE_DRAW") { url = `https:${major?.opus?.jump_url}`; text = `图文地址:<a href=${url}>${url}</a>`; } break; case "MAJOR_TYPE_PGC": { const pgc = major?.pgc; url = `https://www.bilibili.com/bangumi/play/ep${pgc?.epid}&season_id=${pgc?.season_id}`; text = `剧集地址:<a href=${url}>${url}</a>`; break; } case "MAJOR_TYPE_COURSES": url = `https://www.bilibili.com/cheese/play/ss${major?.courses?.id}`; text = `课程地址:<a href=${url}>${url}</a>`; break; case "MAJOR_TYPE_MUSIC": url = `https://www.bilibili.com/audio/au${major?.music?.id}`; text = `音频地址:<a href=${url}>${url}</a>`; break; case "MAJOR_TYPE_LIVE": url = `https://live.bilibili.com/${major?.live?.id}`; text = `直播间地址:<a href=${url}>${url}</a>`; break; case "MAJOR_TYPE_LIVE_RCMD": { const live_play_info = JSON.parse(major.live_rcmd?.content || "{}")?.live_play_info; url = `https://live.bilibili.com/${live_play_info?.room_id}`; videoPageUrl = getLiveUrl(live_play_info?.room_id); text = `直播间地址:<a href=${url}>${url}</a>`; break; } default: return null; } return { url, text, videoPageUrl }; }; async function handler(ctx) { const isJsonFeed = ctx.req.query("format") === "json"; const uid = ctx.req.param("uid"); const routeParams = Object.fromEntries(new URLSearchParams(ctx.req.param("routeParams"))); const showEmoji = fallback(void 0, queryToBoolean(routeParams.showEmoji), false); const embed = fallback(void 0, queryToBoolean(routeParams.embed), false); const displayArticle = ctx.req.query("mode") === "fulltext"; const offset = fallback(void 0, routeParams.offset, ""); const useAvid = fallback(void 0, queryToBoolean(routeParams.useAvid), false); const directLink = fallback(void 0, queryToBoolean(routeParams.directLink), false); const hideGoods = fallback(void 0, queryToBoolean(routeParams.hideGoods), false); const getDynamic = async (cookie) => { const response = await got_default(`https://api.bilibili.com/x/polymer/web-dynamic/v1/feed/space?${utils_default.addDmVerifyInfo(`offset=${offset}&host_mid=${uid}&platform=web&features=itemOpusStyle,listOnlyfans,opusBigCover,onlyfansVote`, utils_default.getDmImgList())}`, { headers: { Referer: `https://space.bilibili.com/${uid}/`, Cookie: cookie } }); return JSONbig.parse(response.body); }; let body; body = await getDynamic(await cache_default$1.getCookie()); if (body?.code === -352) { body = await getDynamic(await cache_default$1.getCookie(true)); if (body?.code === -352) { cache_default.set("bili-cookie", ""); throw new captcha_default("遇到源站风控校验,请稍后再试"); } } const items = body?.data?.items; let author = items[0]?.modules?.module_author?.name; let face = items[0]?.modules?.module_author?.face; if (!face || !author) { const usernameAndFace = await cache_default$1.getUsernameAndFaceFromUID(uid); author = usernameAndFace[0] || items[0]?.modules?.module_author?.name; face = usernameAndFace[1] || items[0]?.modules?.module_author?.face; } else { cache_default.set(`bili-username-from-uid-${uid}`, author); cache_default.set(`bili-userface-from-uid-${uid}`, face); } const rssItems = await Promise.all(items.filter((item) => { if (hideGoods) return item.modules.module_dynamic?.additional?.type !== "ADDITIONAL_TYPE_GOODS"; return true; }).map(async (item) => { const data = item.modules; const origin = item?.orig?.modules; const bvid = data?.module_dynamic?.major?.archive?.bvid; let link = ""; if (item.id_str) link = `https://t.bilibili.com/${item.id_str}`; const originalDescription = getDes(data) || ""; let description = originalDescription; const title = getTitle(data); const category = []; if (data.module_dynamic?.desc?.rich_text_nodes?.length) { const nodes = data.module_dynamic.desc.rich_text_nodes; for (const node of nodes) { if (showEmoji && node?.emoji) { const emoji = node.emoji; description = description.replaceAll(emoji.text, `<img alt="${emoji.text}" src="${emoji.icon_url}" style="margin: -1px 1px 0px; display: inline-block; width: 20px; height: 20px; vertical-align: text-bottom;" title="" referrerpolicy="no-referrer">`); } if (node?.pics?.length) { const { pics, text } = node; description = description.replaceAll(text, pics.map((pic) => `<img alt="${text}" src="${pic.src}" style="margin: 0px 0px 0px; display: inline-block; width: ${pic.width}px; height: ${pic.height}px; vertical-align: text-bottom;" title="" referrerpolicy="no-referrer">`).join("<br>")); } if (node?.type === "RICH_TEXT_NODE_TYPE_TOPIC") category.push(node.text.match(/#(\S+)#/)?.[1] || ""); } } if (data.module_dynamic?.major?.opus?.summary?.rich_text_nodes?.length) { const nodes = data.module_dynamic.major.opus.summary.rich_text_nodes; for (const node of nodes) if (node?.type === "RICH_TEXT_NODE_TYPE_TOPIC") category.push(node.text.match(/#(\S+)#/)?.[1] || ""); } if (data.module_dynamic?.topic?.name) category.push(data.module_dynamic.topic.name); if (item.type === "DYNAMIC_TYPE_ARTICLE" && displayArticle) { const cvid = data.module_dynamic?.major?.opus?.jump_url?.match?.(/cv(\d+)/)?.[0]; if (cvid) description = (await cache_default$1.getArticleDataFromCvid(cvid, uid)).description || ""; } const urlResult = getUrl(item, useAvid); const urlText = urlResult?.text; if (urlResult && directLink) link = urlResult.url; const originUrlResult = getUrl(item?.orig, useAvid); const originUrlText = originUrlResult?.text; if (originUrlResult && directLink) link = originUrlResult.url; let originDescription = ""; const originName = getOriginName(origin); const originTitle = getOriginTitle(origin); const originDes = getOriginDes(origin); if (originName) originDescription += `//转发自: @${getOriginName(origin)}: `; if (originTitle) originDescription += originTitle; if (originDes) originDescription += `<br>${originDes}`; description = description.replaceAll("\r\n", "<br>").replaceAll("\n", "<br>"); originDescription = originDescription.replaceAll("\r\n", "<br>").replaceAll("\n", "<br>"); const descriptions = [ title, description, getIframe(data, embed), getImgs(data), urlText, originDescription, getIframe(origin, embed), getImgs(origin), originUrlText ].map((e) => e?.trim()).filter(Boolean).join("<br>"); const subtitles = isJsonFeed && !config.bilibili.excludeSubtitles && bvid ? await cache_default$1.getVideoSubtitleAttachment(bvid) : []; return { title: title || originalDescription, description: descriptions, pubDate: data.module_author?.pub_ts ? parseDate(data.module_author.pub_ts, "X") : void 0, link, author, category: category.length ? [...new Set(category)] : void 0, attachments: urlResult?.videoPageUrl || originUrlResult?.videoPageUrl ? [{ url: urlResult?.videoPageUrl || originUrlResult?.videoPageUrl, mime_type: "text/html", duration_in_seconds: data.module_dynamic?.major?.archive?.duration_text ? parseDuration(data.module_dynamic.major.archive.duration_text) : void 0 }, ...subtitles] : void 0 }; })); return { title: `${author} 的 bilibili 动态`, link: `https://space.bilibili.com/${uid}/dynamic`, description: `${author} 的 bilibili 动态`, image: face, logo: face, icon: face, item: rssItems }; } //#endregion export { route };