fix(route): taptap, topic failed to respond (#10485)

* fix(taptap) topic: add some null detection

* fix(taptap) topic: in videoPost, use an animated image instead of video

Since the videoUrl seems always be undefined

* Update lib/v2/taptap/utils.js

- use a better resolution preview image
- remove unused properties

Co-authored-by: Tony <TonyRL@users.noreply.github.com>

* fix: app_name and app_img look up

Co-authored-by: ETiV Wang <1926860+ETiV@users.noreply.github.com>
This commit is contained in:
ETiV
2022-08-19 01:29:45 +08:00
committed by GitHub
parent 8279d9e341
commit 2bcddf44c3
4 changed files with 51 additions and 36 deletions

View File

@@ -0,0 +1,3 @@
{{ each images image }}
<img src="{{ image.original_url || image.url }}">
{{ /each }}

View File

@@ -1,2 +1,3 @@
{{ if intro }}{{@ intro }}{{ /if }}
<video controls src="{{@ videoUrl }}" {{ if posterUrl }}poster="{{@ posterUrl }}"{{ /if }}>Sorry, your browser doesn't support embedded videos.</video>
<p>Preview</p>
<p><img src="{{@ previewUrl }}" /></p>

View File

@@ -1,6 +1,6 @@
const got = require('@/utils/got');
const { parseDate } = require('@/utils/parse-date');
const { rootUrl, X_UA, appId2GroupId, textPost, videoPost } = require('./utils');
const { rootUrl, X_UA, appDetail, imagePost, topicPost, videoPost } = require('./utils');
const typeMap = {
feed: {
@@ -24,41 +24,47 @@ const typeMap = {
module.exports = async (ctx) => {
const lang = ctx.params.lang ?? 'zh_CN';
const appId = ctx.params.id;
const groupId = await appId2GroupId(appId, lang);
const appData = await appDetail(appId, lang);
const type = ctx.params.type ?? 'feed';
const sort = ctx.params.sort ?? 'created';
const groupId = appData.group.id;
const app_img = appData.app.icon.original_url || appData.app.icon.url;
const app_name = appData.app.title;
const url = `${rootUrl}/webapiv2/feed/v6/by-group?group_id=${groupId}&type=${type}&sort=${sort}&${X_UA(lang)}`;
const topics_list_response = await got(url);
const topics_list = topics_list_response.data;
const app_img = topics_list.data.list[0].moment.app.icon.url;
const app_name = topics_list.data.list[0].moment.app.title;
const out = await Promise.all(
topics_list.data.list.map((list) => {
const link = list.moment.sharing?.url || list.moment.extended_entities?.topics?.[0].sharing.url || list.moment.extended_entities?.videos?.[0].sharing.url;
const out = topics_list.data.list.map(async (list) => {
const author = list.moment.author.user.name;
const topicId = list.moment.extended_entities?.topics?.[0].id;
// raw_text sometimes is "" so || is better than ??
const title = list.moment.contents.raw_text || list.moment.extended_entities?.topics?.[0].title || list.moment.extended_entities?.videos?.[0].title;
const createdTime = list.moment.created_time * 1000;
const link = list.moment.sharing?.url || list.moment.extended_entities?.topics?.[0].sharing.url || list.moment.extended_entities?.videos?.[0].sharing.url;
let description = '';
try {
description = await textPost(appId, topicId, lang);
} catch (e) {
// fallback if 400 bad request
description = list.moment.extended_entities?.topics?.[0].summary || list.moment.contents.raw_text || videoPost(list.moment.extended_entities?.videos?.[0]);
}
return ctx.cache.tryGet(link, async () => {
const author = list.moment.author.user.name;
const topicId = list.moment.extended_entities?.topics?.[0].id;
// raw_text sometimes is "" so || is better than ??
const title = list.moment.contents?.raw_text || list.moment.extended_entities?.topics?.[0].title || list.moment.extended_entities?.videos?.[0].title;
const createdTime = list.moment.created_time;
let description = '';
if (topicId) {
description = await topicPost(appId, topicId, lang);
} else {
description = list.moment.extended_entities?.topics?.[0].summary || list.moment.contents?.raw_text || videoPost(list.moment.extended_entities?.videos?.[0]);
if (list.moment.extended_entities?.images) {
description += imagePost(list.moment.extended_entities.images);
}
}
return {
title,
description,
author,
link,
pubDate: parseDate(createdTime),
};
});
return {
title,
description,
author,
link,
pubDate: parseDate(createdTime, 'X'),
};
});
})
);
ctx.state.data = {
title: `${app_name} - ${typeMap[type][lang]} - TapTap 论坛`,

View File

@@ -7,16 +7,21 @@ const rootUrl = 'https://www.taptap.com';
// Please do not change %26 to &
const X_UA = (lang = 'zh_CN') => `X-UA=V=1%26PN=WebApp%26VN=0.1.0%26LANG=${lang}%26PLT=PC`;
const appId2GroupId = async (appId, lang = 'zh_CN') => {
const res = await got(`${rootUrl}/webapiv2/group/v1/detail?app_id=${appId}&${X_UA(lang)}`, {
const appDetail = async (appId, lang = 'zh_CN') => {
const { data } = await got(`${rootUrl}/webapiv2/group/v1/detail?app_id=${appId}&${X_UA(lang)}`, {
headers: {
Referer: `${rootUrl}/app/${appId}`,
},
});
return res.data.data.group.id;
return data.data;
};
const textPost = async (appId, topicId, lang = 'zh_CN') => {
const imagePost = (images) =>
art(path.join(__dirname, 'templates/imagePost.art'), {
images,
});
const topicPost = async (appId, topicId, lang = 'zh_CN') => {
const res = await got(`${rootUrl}/webapiv2/topic/v1/detail?id=${topicId}&${X_UA(lang)}`, {
headers: {
Referer: `${rootUrl}/app/${appId}`,
@@ -35,14 +40,14 @@ const textPost = async (appId, topicId, lang = 'zh_CN') => {
const videoPost = (video) =>
art(path.join(__dirname, 'templates/videoPost.art'), {
intro: video?.intro?.text,
videoUrl: video?.url,
posterUrl: video?.raw_cover.url,
previewUrl: video?.video_resource.preview_animation.original_url,
});
module.exports = {
rootUrl,
X_UA,
appId2GroupId,
textPost,
appDetail,
imagePost,
topicPost,
videoPost,
};