diff --git a/lib/routes/twitter/api/web-api/utils.ts b/lib/routes/twitter/api/web-api/utils.ts index d3902425deecc8..a8632757ddb09f 100644 --- a/lib/routes/twitter/api/web-api/utils.ts +++ b/lib/routes/twitter/api/web-api/utils.ts @@ -222,32 +222,49 @@ export const twitterGot = async ( }; export const paginationTweets = async (endpoint: string, userId: number | undefined, variables: Record, path?: string[]) => { - const { data } = await twitterGot(baseUrl + gqlMap[endpoint], { - variables: JSON.stringify({ - ...variables, - userId, - }), + const params = { + variables: JSON.stringify({ ...variables, userId }), features: JSON.stringify(gqlFeatures[endpoint]), - }); - let instructions; - if (path) { - instructions = data; - for (const p of path) { - instructions = instructions[p]; + }; + + const fetchData = async () => { + if (config.twitter.thirdPartyApi) { + const { data } = await ofetch(`${config.twitter.thirdPartyApi}${gqlMap[endpoint]}`, { + method: 'GET', + params, + }); + return data; } - instructions = instructions.instructions; - } else { - if (data?.user?.result?.timeline_v2?.timeline?.instructions) { - instructions = data.user.result.timeline_v2.timeline.instructions; - } else { - // throw new Error('Because Twitter Premium has features that hide your likes, this RSS link is not available for Twitter Premium accounts.'); + const { data } = await twitterGot(baseUrl + gqlMap[endpoint], params); + return data; + }; + + const getInstructions = (data: any) => { + if (path) { + let instructions = data; + for (const p of path) { + instructions = instructions[p]; + } + return instructions.instructions; + } + + const instructions = data?.user?.result?.timeline_v2?.timeline?.instructions; + if (!instructions) { logger.debug(`twitter debug: instructions not found in data: ${JSON.stringify(data)}`); } + return instructions; + }; + + const data = await fetchData(); + const instructions = getInstructions(data); + if (!instructions) { + return []; } - const entries1 = instructions?.find((i) => i.type === 'TimelineAddToModule')?.moduleItems; // Media - const entries2 = instructions?.find((i) => i.type === 'TimelineAddEntries').entries; - return entries1 || entries2 || []; + const moduleItems = instructions.find((i) => i.type === 'TimelineAddToModule')?.moduleItems; + const entries = instructions.find((i) => i.type === 'TimelineAddEntries')?.entries; + + return moduleItems || entries || []; }; export function gatherLegacyFromData(entries: any[], filterNested?: string[], userId?: number | string) { diff --git a/lib/routes/twitter/user.ts b/lib/routes/twitter/user.ts index 277ba339b6f056..eebff2a7b685b9 100644 --- a/lib/routes/twitter/user.ts +++ b/lib/routes/twitter/user.ts @@ -2,6 +2,7 @@ import { Route, ViewType } from '@/types'; import utils from './utils'; import api from './api'; import logger from '@/utils/logger'; +import { config } from '@/config'; export const route: Route = { path: '/user/:id/:routeParams?', @@ -45,7 +46,7 @@ export const route: Route = { supportScihub: false, }, name: 'User timeline', - maintainers: ['DIYgod', 'yindaheng98', 'Rongronggg9', 'CaoMeiYouRen'], + maintainers: ['DIYgod', 'yindaheng98', 'Rongronggg9', 'CaoMeiYouRen', 'pseudoyu'], handler, radar: [ { @@ -59,9 +60,15 @@ async function handler(ctx) { const id = ctx.req.param('id'); // For compatibility - const { count, exclude_replies, include_rts } = utils.parseRouteParams(ctx.req.param('routeParams')); + const { count, exclude_replies: initialExcludeReplies, include_rts } = utils.parseRouteParams(ctx.req.param('routeParams')); const params = count ? { count } : {}; + // Third party API does not support replies for now + let exclude_replies = initialExcludeReplies; + if (config.twitter.thirdPartyApi) { + exclude_replies = true; + } + await api.init(); const userInfo = await api.getUser(id); let data;