RSSHub/lib/v2/bilibili/followings_dynamic.js

153 lines
7.2 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

const got = require('@/utils/got');
const cache = require('./cache');
const config = require('@/config').value;
const utils = require('./utils');
const JSONbig = require('json-bigint');
const { fallback, queryToBoolean } = require('@/utils/readable-social');
const querystring = require('querystring');
module.exports = async (ctx) => {
const uid = String(ctx.params.uid);
const routeParams = querystring.parse(ctx.params.routeParams);
const showEmoji = fallback(undefined, queryToBoolean(routeParams.showEmoji), false);
const disableEmbed = fallback(undefined, queryToBoolean(routeParams.disableEmbed), false);
const displayArticle = fallback(undefined, queryToBoolean(routeParams.displayArticle), false);
const name = await cache.getUsernameFromUID(ctx, uid);
const cookie = config.bilibili.cookies[uid];
if (cookie === undefined) {
throw Error('缺少对应 uid 的 Bilibili 用户登录后的 Cookie 值');
}
const response = await got({
method: 'get',
url: `https://api.vc.bilibili.com/dynamic_svr/v1/dynamic_svr/dynamic_new?uid=${uid}&type_list=268435455`,
headers: {
Referer: `https://space.bilibili.com/${uid}/`,
Cookie: cookie,
},
});
if (response.data.code === -6) {
throw Error('对应 uid 的 Bilibili 用户的 Cookie 已过期');
}
const data = JSONbig.parse(response.body).data.cards;
const items = await Promise.all(
data.map(async (item) => {
const getTitle = (data) => (data ? data.title || data.description || data.content || (data.vest && data.vest.content) || '' : '');
const getDes = (data) =>
data.dynamic || data.desc || data.description || data.content || data.summary || (data.vest && data.vest.content) + (data.sketch && `<br>${data.sketch.title}<br>${data.sketch.desc_text}`) || data.intro || '';
const getOriginDes = (data) => (data && (data.apiSeasonInfo && data.apiSeasonInfo.title && `//转发自: ${data.apiSeasonInfo.title}`) + (data.index_title && `<br>${data.index_title}`)) || '';
const getOriginName = (data) => data.uname || (data.author && data.author.name) || (data.upper && data.upper.name) || (data.user && (data.user.uname || data.user.name)) || (data.owner && data.owner.name) || '';
const getOriginTitle = (data) => (data.title ? `${data.title}<br>` : '');
const getIframe = (data) => (!disableEmbed && data && data.aid ? `<br><br>${utils.iframe(data.aid)}<br>` : '');
const parsed = JSONbig.parse(item.card);
const data = parsed.apiSeasonInfo || (getTitle(parsed.item) ? parsed.item : parsed);
const origin = parsed.origin ? JSONbig.parse(parsed.origin) : null;
// img
let imgHTML = '';
const getImgs = (data) => {
let imgs = '';
// 动态图片
if (data.pictures) {
for (let i = 0; i < data.pictures.length; i++) {
imgs += `<img src="${data.pictures[i].img_src}">`;
}
}
// 专栏封面
if (data.image_urls) {
for (let i = 0; i < data.image_urls.length; i++) {
imgs += `<img src="${data.image_urls[i]}">`;
}
}
// 视频封面
if (data.pic) {
imgs += `<img src="${data.pic}">`;
}
// 音频/番剧/直播间封面/小视频封面
if (data.cover && data.cover.unclipped) {
imgs += `<img src="${data.cover.unclipped}">`;
} else if (data.cover) {
imgs += `<img src="${data.cover}">`;
}
// 专题页封面
if (data.sketch && data.sketch.cover_url) {
imgs += `<img src="${data.sketch.cover_url}">`;
}
return imgs;
};
imgHTML += getImgs(data);
if (origin) {
imgHTML += getImgs(origin.item || origin);
}
// video小视频
let videoHTML = '';
if (data.video_playurl) {
videoHTML += `<video width="${data.width}" height="${data.height}" controls><source src="${unescape(data.video_playurl).replace(/^http:/, 'https:')}"><source src="${unescape(data.video_playurl)}"></video>`;
}
// some rss readers disallow http content.
// 部分 RSS 阅读器要求内容必须使用https传输
// bilibili short video does support https request, but https request may timeout ocassionally.
// to maximize content availability, here add two source tags.
// bilibili的API中返回的视频地址采用http然而经验证短视频地址支持https访问但偶尔会返回超时错误(可能是网络原因)。
// 因此保险起见加入两个source标签
// link
let link = '';
if (data.dynamic_id) {
link = `https://t.bilibili.com/${data.dynamic_id}`;
} else if (item.desc?.dynamic_id) {
link = `https://t.bilibili.com/${item.desc.dynamic_id}`;
}
// emoji
let data_content = getDes(data);
if (item.display && item.display.emoji_info && showEmoji) {
const emoji = item.display.emoji_info.emoji_details;
emoji.forEach((item) => {
data_content = data_content.replace(
new RegExp(`\\${item.text}`, 'g'),
`<img alt="${item.text}" src="${item.url}"style="margin: -1px 1px 0px; display: inline-block; width: 20px; height: 20px; vertical-align: text-bottom;" title="" referrerpolicy="no-referrer">`
);
});
}
// 作者信息
let author = '';
if (item.desc?.user_profile) {
author = item.desc.user_profile.info.uname;
}
if (data.image_urls && displayArticle) {
data_content = (await cache.getArticleDataFromCvid(ctx, data.id, uid)).description;
}
return {
title: getTitle(data),
author,
description: (() => {
const description = parsed.new_desc || data_content || getDes(data);
const originName = origin && getOriginName(origin) ? `<br><br>//转发自: @${getOriginName(origin)}: ${getOriginTitle(origin.item || origin)}${getDes(origin.item || origin)}` : getOriginDes(origin);
const imgHTMLSource = imgHTML ? `<br>${imgHTML}` : '';
const videoHTMLSource = videoHTML ? `<br>${videoHTML}` : '';
return `${description}${originName}${getIframe(data)}${getIframe(origin)}${imgHTMLSource}${videoHTMLSource}`;
})(),
pubDate: new Date(item.desc?.timestamp * 1000).toUTCString(),
link,
};
})
);
ctx.state.data = {
title: `${name} 关注的动态`,
link: `https://t.bilibili.com`,
description: `${name} 关注的动态`,
item: items,
};
};