fix(source): producthunt by offical api
This commit is contained in:
@@ -3,3 +3,4 @@ G_CLIENT_SECRET=
|
|||||||
JWT_SECRET=
|
JWT_SECRET=
|
||||||
INIT_TABLE=true
|
INIT_TABLE=true
|
||||||
ENABLE_CACHE=true
|
ENABLE_CACHE=true
|
||||||
|
PRODUCTHUNT_API_TOKEN=
|
||||||
@@ -35,7 +35,6 @@ export default defineSource(async () => {
|
|||||||
Accept: "application/json, text/plain, */*",
|
Accept: "application/json, text/plain, */*",
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
console.log(res)
|
|
||||||
return res.items.map(movie => ({
|
return res.items.map(movie => ({
|
||||||
id: movie.id,
|
id: movie.id,
|
||||||
title: movie.title,
|
title: movie.title,
|
||||||
|
|||||||
@@ -1,28 +1,56 @@
|
|||||||
import * as cheerio from "cheerio"
|
import process from "node:process"
|
||||||
import type { NewsItem } from "@shared/types"
|
import type { NewsItem } from "@shared/types"
|
||||||
|
|
||||||
|
const apiKey = process.env.PRODUCTHUNT_API_TOKEN
|
||||||
|
const token = `Bearer ${apiKey}`
|
||||||
export default defineSource(async () => {
|
export default defineSource(async () => {
|
||||||
const baseURL = "https://www.producthunt.com"
|
if (!apiKey) {
|
||||||
const html: any = await myFetch(baseURL)
|
throw new Error("PRODUCTHUNT_API_TOKEN is not set")
|
||||||
const $ = cheerio.load(html)
|
}
|
||||||
const $main = $("[data-test=homepage-section-0] [data-test^=post-item]")
|
const query = `
|
||||||
|
query {
|
||||||
|
posts(first: 30, order: VOTES) {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
tagline
|
||||||
|
votesCount
|
||||||
|
url
|
||||||
|
slug
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
const response: any = await myFetch("https://api.producthunt.com/v2/api/graphql", {
|
||||||
|
method: "POST",
|
||||||
|
headers: {
|
||||||
|
"Authorization": token,
|
||||||
|
"Content-Type": "application/json",
|
||||||
|
"Accept": "application/json",
|
||||||
|
},
|
||||||
|
body: JSON.stringify({ query }),
|
||||||
|
})
|
||||||
|
|
||||||
const news: NewsItem[] = []
|
const news: NewsItem[] = []
|
||||||
$main.each((_, el) => {
|
const posts = response?.data?.posts?.edges || []
|
||||||
const a = $(el).find("a").first()
|
|
||||||
const url = a.attr("href")
|
for (const edge of posts) {
|
||||||
const title = $(el).find("a[data-test^=post-name]").text().replace(/^\d+\.\s*/, "")
|
const post = edge.node
|
||||||
const id = $(el).attr("data-test")?.replace("post-item-", "")
|
if (post.id && post.name) {
|
||||||
const vote = $(el).find("[data-test=vote-button]").text()
|
|
||||||
if (url && id && title) {
|
|
||||||
news.push({
|
news.push({
|
||||||
url: `${baseURL}${url}`,
|
id: post.id,
|
||||||
title,
|
title: post.name,
|
||||||
id,
|
url: post.url || `https://www.producthunt.com/posts/${post.slug}`,
|
||||||
extra: {
|
extra: {
|
||||||
info: `△︎ ${vote}`,
|
info: ` △︎ ${post.votesCount || 0}`,
|
||||||
|
hover: post.tagline,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
}
|
||||||
|
|
||||||
return news
|
return news
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user