diff --git a/lib/routes/producthunt/templates/description.art b/lib/routes/producthunt/templates/description.art
index 8139b84c8..6d568aa12 100644
--- a/lib/routes/producthunt/templates/description.art
+++ b/lib/routes/producthunt/templates/description.art
@@ -1,5 +1,5 @@
-{{ if headerImage }}
-
+{{ if tagline }}
+
{{ tagline }}{{ /if }} {{ if description }} diff --git a/lib/routes/producthunt/today.ts b/lib/routes/producthunt/today.ts index 04d8ebc72..cd1804e6d 100644 --- a/lib/routes/producthunt/today.ts +++ b/lib/routes/producthunt/today.ts @@ -6,6 +6,7 @@ import { load } from 'cheerio'; import { parseDate } from '@/utils/parse-date'; import { art } from '@/utils/render'; import path from 'node:path'; +import { config } from '@/config'; export const route: Route = { path: '/today', @@ -24,23 +25,28 @@ export const route: Route = { source: ['www.producthunt.com/'], }, ], - name: 'Today Popular', + name: 'Top Products Launching Today', maintainers: ['miaoyafeng', 'Fatpandac'], handler, url: 'www.producthunt.com/', }; async function handler() { - const response = await ofetch('https://www.producthunt.com/'); + const response = await ofetch('https://www.producthunt.com/', { + headers: { + 'User-Agent': config.trueUA, + }, + }); const $ = load(response); const match = $('script:contains("ApolloSSRDataTransport")') .text() .match(/"events":(\[.+\])\}\)/)?.[1] + ?.trim() .replaceAll('undefined', 'null'); const data = JSON.parse(match); - const todayList = data.find((event) => event.type === 'data' && event.result.data.homefeed).result.data.homefeed.edges.find((edge) => edge.node.id === 'FEATURED-0').node; + const todayList = data.find((event) => event.type === 'next' && event.value.data.homefeed).value.data.homefeed.edges.find((edge) => edge.node.id === 'FEATURED-0').node; // 0: Top Products Launching Today // 1: Yesterday's Top Products // 2: Last Week's Top Products @@ -50,8 +56,8 @@ async function handler() { .filter((i) => i.__typename === 'Post') .map((item) => ({ title: item.name, - link: `https://www.producthunt.com/posts/${item.slug}`, - slug: item.slug, + link: `https://www.producthunt.com/products/${item.product.slug}`, + postSlug: item.slug, description: item.tagline, pubDate: parseDate(item.createdAt), image: `https://ph-files.imgix.net/${item.thumbnailImageUuid}`, @@ -63,15 +69,18 @@ async function handler() { cache.tryGet(item.link, async () => { const response = await ofetch('https://www.producthunt.com/frontend/graphql', { method: 'POST', + headers: { + 'User-Agent': config.trueUA, + }, body: { operationName: 'PostPage', variables: { - slug: item.slug, + slug: item.postSlug, }, extensions: { persistedQuery: { version: 1, - sha256Hash: '3d56ad0687ad82922d71fca238e5081853609dd7b16207a5aa042dee884edaea', + sha256Hash: '488585149898ee974a51884b11e205c34ea8ad34ee01d47d7936a66a6db799ff', }, }, }, @@ -80,7 +89,7 @@ async function handler() { item.author = post.user.name; item.description = art(path.join(__dirname, 'templates/description.art'), { - headerImage: post.headerImage?.uuid, + tagline: post.tagline, description: post.description, media: post.media, });