diff --git a/lib/v2/taptap/templates/imagePost.art b/lib/v2/taptap/templates/imagePost.art
new file mode 100644
index 0000000000..7d3bc49f2a
--- /dev/null
+++ b/lib/v2/taptap/templates/imagePost.art
@@ -0,0 +1,3 @@
+{{ each images image }}
+
+{{ /each }}
diff --git a/lib/v2/taptap/templates/videoPost.art b/lib/v2/taptap/templates/videoPost.art
index db000e9094..184bcecb2b 100644
--- a/lib/v2/taptap/templates/videoPost.art
+++ b/lib/v2/taptap/templates/videoPost.art
@@ -1,2 +1,3 @@
{{ if intro }}{{@ intro }}{{ /if }}
-
+
Preview
+
diff --git a/lib/v2/taptap/topic.js b/lib/v2/taptap/topic.js
index f592a15eb6..dc489ffcff 100644
--- a/lib/v2/taptap/topic.js
+++ b/lib/v2/taptap/topic.js
@@ -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 论坛`,
diff --git a/lib/v2/taptap/utils.js b/lib/v2/taptap/utils.js
index e1e8d31bbb..20a33666e1 100644
--- a/lib/v2/taptap/utils.js
+++ b/lib/v2/taptap/utils.js
@@ -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,
};