From 0ddea9ef8695d97a72aec558f04880e84dff4bfd Mon Sep 17 00:00:00 2001 From: Tony Date: Fri, 24 Apr 2026 19:39:30 +0800 Subject: [PATCH] fix(route): apple apps (#21824) --- lib/routes/apple/apps.ts | 14 ++++++-------- lib/routes/apple/utils.ts | 26 -------------------------- lib/routes/appstore/in-app-purchase.ts | 6 ++---- 3 files changed, 8 insertions(+), 38 deletions(-) delete mode 100644 lib/routes/apple/utils.ts diff --git a/lib/routes/apple/apps.ts b/lib/routes/apple/apps.ts index c9fd61023..c782652a3 100644 --- a/lib/routes/apple/apps.ts +++ b/lib/routes/apple/apps.ts @@ -3,8 +3,6 @@ import { ViewType } from '@/types'; import ofetch from '@/utils/ofetch'; import { parseDate } from '@/utils/parse-date'; -import { appstoreBearerToken } from './utils'; - const platformIds = { osx: 'macOS', ios: 'iOS', @@ -87,20 +85,20 @@ async function handler(ctx) { const rootUrl = 'https://apps.apple.com'; const currentUrl = new URL(`${country}/app/${id}`, rootUrl).href; - const bearer = await appstoreBearerToken(); - - const response = await ofetch(`https://amp-api-edge.apps.apple.com/v1/catalog/${country}/apps/${id.replace('id', '')}`, { + const response = await ofetch(`https://apps.apple.com/api/apps/v1/catalog/${country}/apps/${id.replace('id', '')}`, { headers: { - authorization: `Bearer ${bearer}`, + authorization: 'Bearer', origin: 'https://apps.apple.com', }, query: { platform: 'iphone', additionalPlatforms: 'appletv,ipad,iphone,mac,realityDevice,watch', - extend: 'accessibility,accessibilityDetails,ageRating,backgroundAssetsInfo,backgroundAssetsInfoWithOptional,customArtwork,customDeepLink,customIconArtwork,customPromotionalText,customScreenshotsByType,customVideoPreviewsByType,description,expectedReleaseDateDisplayFormat,fileSizeByDevice,gameDisplayName,iconArtwork,installSizeByDeviceInBytes,messagesScreenshots,miniGamesDeepLink,minimumOSVersion,privacy,privacyDetails,privacyPolicyUrl,remoteControllerRequirement,requirementsByDeviceFamily,supportURLForLanguage,supportedGameCenterFeatures,supportsFunCamera,supportsSharePlay,versionHistory,websiteUrl', + extend: 'accessibility,accessibilityDetails,ageRating,backgroundAssetsInfo,backgroundAssetsInfoWithOptional,customArtwork,customDeepLink,customIconArtwork,customPromotionalText,customScreenshotsByType,customVideoPreviewsByType,description,expectedReleaseDateDisplayFormat,fileSizeByDevice,gameDisplayName,iconArtwork,installSizeByDeviceInBytes,macRequiredCapabilities,medicalDeviceInfo,messagesScreenshots,miniGamesDeepLink,minimumOSVersion,privacy,privacyDetails,privacyPolicyUrl,remoteControllerRequirement,requirementsByDeviceFamily,supportURLForLanguage,supportedGameCenterFeatures,supportsFunCamera,supportsSharePlay,versionHistory,websiteUrl', + 'extend[apps]': 'distributionKind,isVerifiedForAppleSiliconMac', 'extend[app-events]': 'description,productArtwork,productVideo', - include: 'alternate-apps,app-bundles,customers-also-bought-apps,developer,developer-other-apps,merchandised-in-apps,related-editorial-items,reviews,top-in-apps', + include: 'alternate-apps,app-bundles,customers-also-bought-apps,developer,developer-other-apps,merchandised-in-apps,related-editorial-items,reviews', 'include[apps]': 'app-events', + views: 'top-in-app-purchasables', 'availableIn[app-events]': 'future', 'sparseLimit[apps:customers-also-bought-apps]': 40, 'sparseLimit[apps:developer-other-apps]': 40, diff --git a/lib/routes/apple/utils.ts b/lib/routes/apple/utils.ts deleted file mode 100644 index 04cbf4b86..000000000 --- a/lib/routes/apple/utils.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { load } from 'cheerio'; - -import { config } from '@/config'; -import cache from '@/utils/cache'; -import ofetch from '@/utils/ofetch'; - -// App Store and Podcast use different bearer tokens -export const appstoreBearerToken = () => - cache.tryGet( - 'apple:podcast:bearer', - async () => { - const baseUrl = 'https://apps.apple.com'; - const response = await ofetch(`${baseUrl}/us/iphone/today`); - const $ = load(response); - - const moduleAddress = new URL($('head script[type="module"]').attr('src'), baseUrl).href; - const modulesResponse = await ofetch(moduleAddress, { - parseResponse: (txt) => txt, - }); - const bearerToken = modulesResponse.match(/="(eyJhbGci.*?)"/)[1]; - - return bearerToken as string; - }, - config.cache.contentExpire, - false - ); diff --git a/lib/routes/appstore/in-app-purchase.ts b/lib/routes/appstore/in-app-purchase.ts index 94688010f..6e1ef7825 100644 --- a/lib/routes/appstore/in-app-purchase.ts +++ b/lib/routes/appstore/in-app-purchase.ts @@ -1,6 +1,5 @@ import { load } from 'cheerio'; -import { appstoreBearerToken } from '@/routes/apple/utils'; import type { Route } from '@/types'; import ofetch from '@/utils/ofetch'; @@ -33,11 +32,10 @@ async function handler(ctx) { const res = await ofetch(link); const $ = load(res); const lang = $('html').attr('lang'); - const mediaToken = await appstoreBearerToken(); - const apiResponse = await ofetch(`https://amp-api-edge.apps.apple.com/v1/catalog/${country}/apps/${id.replace('id', '')}`, { + const apiResponse = await ofetch(`https://apps.apple.com/api/apps/v1/catalog/${country}/apps/${id.replace('id', '')}`, { headers: { - authorization: `Bearer ${mediaToken}`, + authorization: 'Bearer', origin: 'https://apps.apple.com', }, query: {