diff --git a/lib/v2/zhihu/maintainer.js b/lib/v2/zhihu/maintainer.js index 11609cf77..4464fafd0 100644 --- a/lib/v2/zhihu/maintainer.js +++ b/lib/v2/zhihu/maintainer.js @@ -15,5 +15,6 @@ module.exports = { '/timeline': ['SeanChao'], '/topic/:topicId': ['xyqfer'], '/weekly': ['LogicJake'], + '/xhu/topic/:topicId': ['JimenezLi'], '/zhuanlan/:id': ['DIYgod'], }; diff --git a/lib/v2/zhihu/radar.js b/lib/v2/zhihu/radar.js index 6865aff4f..58ee80104 100644 --- a/lib/v2/zhihu/radar.js +++ b/lib/v2/zhihu/radar.js @@ -80,6 +80,12 @@ module.exports = { source: '/column/:id', target: '/zhihu/zhuanlan/:id', }, + { + title: 'xhu - 话题', + docs: 'https://docs.rsshub.app/routes/social-media#zhi-hu', + source: '/topic/:topicId/:type', + target: '/zhihu/xhu/topic/:topicId', + }, ], zhuanlan: [ { diff --git a/lib/v2/zhihu/router.js b/lib/v2/zhihu/router.js index 83658aa12..293704cba 100644 --- a/lib/v2/zhihu/router.js +++ b/lib/v2/zhihu/router.js @@ -15,5 +15,6 @@ module.exports = (router) => { router.get('/timeline', require('./timeline')); router.get('/topic/:topicId', require('./topic')); router.get('/weekly', require('./weekly')); + router.get('/xhu/topic/:topicId', require('./xhu/topic')); router.get('/zhuanlan/:id', require('./zhuanlan')); }; diff --git a/lib/v2/zhihu/xhu/auth.js b/lib/v2/zhihu/xhu/auth.js new file mode 100644 index 000000000..d49b4ece3 --- /dev/null +++ b/lib/v2/zhihu/xhu/auth.js @@ -0,0 +1,38 @@ +const got = require('@/utils/got'); + +const ProcessCookie = (cookie) => cookie.map((cookie) => cookie.split(';')[0]).join('; '); + +const ProcessNewCookie = (oldCookie, newCookie) => { + const oldCookieArray = oldCookie.split('; '); + const newCookieArray = newCookie.map((cookie) => cookie.split(';')[0]); + return oldCookieArray.concat(newCookieArray).join('; '); +}; + +module.exports = { + getCookie: (ctx) => { + const key = 'zhihu-xhu-cookie'; + return ctx.cache.tryGet(key, async () => { + // Get udid + const udidResponse = await got({ + method: 'get', + url: 'https://api.zhihuvvv.workers.dev/appcloud/v1/device', + headers: { + Referer: 'https://api.zhihuvvv.workers.dev', + }, + }); + const udidCookie = ProcessCookie(udidResponse.headers['set-cookie']); + + // Get access token + const accessTokenResponse = await got({ + method: 'get', + url: 'https://api.zhihuvvv.workers.dev/guests/token', + headers: { + Referer: 'https://api.zhihuvvv.workers.dev', + Cookie: udidCookie, + }, + }); + const accessTokenCookie = ProcessNewCookie(udidCookie, accessTokenResponse.headers['set-cookie']); + return accessTokenCookie; + }); + }, +}; diff --git a/lib/v2/zhihu/xhu/topic.js b/lib/v2/zhihu/xhu/topic.js new file mode 100644 index 000000000..b9ccd767f --- /dev/null +++ b/lib/v2/zhihu/xhu/topic.js @@ -0,0 +1,74 @@ +const got = require('@/utils/got'); +const auth = require('./auth'); +const utils = require('../utils'); +const { parseDate } = require('@/utils/parse-date'); + +module.exports = async (ctx) => { + const xhuCookie = await auth.getCookie(ctx); + const { topicId } = ctx.params; + const link = `https://www.zhihu.com/topic/${topicId}/newest`; + const url = `https://api.zhihuvvv.workers.dev/topics/${topicId}/feeds/timeline_activity`; + + const response = await got({ + method: 'get', + url, + searchParams: { + before_id: 0, + limit: 20, + }, + headers: { + Referer: 'https://api.zhihuvvv.workers.dev', + Cookie: xhuCookie, + }, + }); + const listRes = response.data.data; + + ctx.state.data = { + title: `知乎话题-${topicId}`, + link, + item: listRes.map(({ target: item }) => { + const type = item.type; + let title = ''; + let description = ''; + let link = ''; + let pubDate = ''; + let author = ''; + + switch (type) { + case 'answer': + title = `${item.question.title}-${item.author.name}的回答:${item.excerpt}`; + description = `${item.question.title}
${item.author.name}的回答
${utils.ProcessImage(item.content)}`; + link = `https://www.zhihu.com/question/${item.question.id}/answer/${item.id}`; + pubDate = parseDate(item.updated_time * 1000); + author = item.author.name; + break; + + case 'question': + title = item.title; + description = item.title; + link = `https://www.zhihu.com/question/${item.id}`; + pubDate = parseDate(item.created * 1000); + break; + + case 'article': + title = item.title; + description = item.excerpt; + link = item.url; + pubDate = parseDate(item.created * 1000); + break; + + default: + description = `未知类型 ${topicId}.${type},请点击链接提交issue`; + } + + return { + title, + description, + author, + pubDate, + guid: link, + link, + }; + }), + }; +}; diff --git a/website/docs/routes/social-media.md b/website/docs/routes/social-media.md index 6aa47038c..daa027041 100644 --- a/website/docs/routes/social-media.md +++ b/website/docs/routes/social-media.md @@ -1763,6 +1763,7 @@ rule ### 用户关注时间线 {#zhi-hu-yong-hu-guan-zhu-shi-jian-xian} + :::caution 注意 用户关注动态需要登录后的 Cookie 值,所以只能自建,详情见部署页面的配置模块。 @@ -1770,3 +1771,7 @@ rule ::: + +### [xhu](https://github.com/REToys/xhu) - 话题 {#zhi-hu-xhu-hua-ti} + + \ No newline at end of file