rsshub
Version:
Make RSS Great Again!
96 lines (95 loc) • 3.91 kB
JavaScript
import { t as config } from "./config-CCmw1BNE.mjs";
import { t as logger } from "./logger-BKy98Y8B.mjs";
import { t as parseDate } from "./parse-date-Cr0wQjV_.mjs";
import { t as cache_default } from "./cache-BkqOokyU.mjs";
import { t as InvalidParameterError } from "./invalid-parameter-CGxhjomn.mjs";
import { n as queryToBoolean, t as fallback } from "./readable-social-DP5kGwF5.mjs";
import { n as outPlaywright } from "./playwright-o20DiLNh.mjs";
import { i as templates, n as proxyVideo, r as resolveUrl, t as getOriginAvatar } from "./utils-DfBGSYqu.mjs";
//#region lib/routes/douyin/user.ts
const route = {
path: "/user/:uid/:routeParams?",
categories: ["social-media"],
example: "/douyin/user/MS4wLjABAAAARcAHmmF9mAG3JEixq_CdP72APhBlGlLVbN-1eBcPqao",
parameters: {
uid: "uid,可在用户页面 URL 中找到",
routeParams: "额外参数,query string 格式,请参阅上面的表格"
},
features: {
requireConfig: false,
requirePuppeteer: true,
antiCrawler: true,
supportBT: false,
supportPodcast: false,
supportScihub: false
},
radar: [{
source: ["douyin.com/user/:uid"],
target: "/user/:uid"
}],
name: "博主",
maintainers: ["Max-Tortoise", "Rongronggg9"],
handler
};
async function handler(ctx) {
const uid = ctx.req.param("uid");
if (!uid.startsWith("MS4wLjABAAAA")) throw new InvalidParameterError("Invalid UID. UID should start with <b>MS4wLjABAAAA</b>.");
const routeParams = Object.fromEntries(new URLSearchParams(ctx.req.param("routeParams")));
const embed = fallback(void 0, queryToBoolean(routeParams.embed), false);
const iframe = fallback(void 0, queryToBoolean(routeParams.iframe), false);
const relay = resolveUrl(routeParams.relay, true, true);
const pageUrl = `https://www.douyin.com/user/${uid}`;
const pageData = await cache_default.tryGet(`douyin:user:${uid}`, async () => {
let postData;
const context = await outPlaywright();
const page = await context.newPage();
await page.route("**/*", (route) => {
const request = route.request();
request.resourceType() === "document" || request.resourceType() === "script" || request.resourceType() === "xhr" ? route.continue() : route.abort();
});
page.on("response", async (response) => {
if (response.request().url().includes("/web/aweme/post") && !postData) postData = await response.json();
});
logger.http(`Requesting ${pageUrl}`);
await page.goto(pageUrl, { waitUntil: "networkidle" });
await context.close();
if (!postData) throw new Error("Empty post data. The request may be filtered by WAF.");
return postData;
}, config.cache.routeExpire, false);
if (!pageData.aweme_list?.length) throw new Error("Empty post data. The request may be filtered by WAF.");
const userInfo = pageData.aweme_list[0].author;
return {
title: userInfo.nickname,
image: getOriginAvatar(userInfo.avatar_thumb.url_list.at(-1)),
link: pageUrl,
item: pageData.aweme_list.map((post) => {
let videoList = post.video?.bit_rate?.map((item) => resolveUrl(item.play_addr.url_list.at(-1)));
if (relay) videoList = videoList.map((item) => proxyVideo(item, relay));
let duration = post.video?.duration;
duration &&= duration / 1e3;
let img;
img ||= post.video?.cover?.url_list.at(-1) || post.video?.origin_cover?.url_list.at(-1);
img &&= resolveUrl(img);
const desc = post.desc?.replaceAll("\n", "<br>");
let media = (embed && videoList ? templates.embed : templates.cover)({
img,
videoList,
duration
});
media = embed && videoList && iframe ? templates.iframe({ content: media }) : media;
const description = templates.desc({
desc,
media
});
return {
title: post.desc.split("\n", 1)[0],
description,
link: `https://www.douyin.com/video/${post.aweme_id}`,
pubDate: parseDate(post.create_time * 1e3),
category: post.video_tag.map((t) => t.tag_name)
};
})
};
}
//#endregion
export { route };