57 lines
1.2 KiB
TypeScript
57 lines
1.2 KiB
TypeScript
import process from "node:process"
|
|
import type { NewsItem } from "@shared/types"
|
|
|
|
const apiKey = process.env.PRODUCTHUNT_API_TOKEN
|
|
const token = `Bearer ${apiKey}`
|
|
export default defineSource(async () => {
|
|
if (!apiKey) {
|
|
throw new Error("PRODUCTHUNT_API_TOKEN is not set")
|
|
}
|
|
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 posts = response?.data?.posts?.edges || []
|
|
|
|
for (const edge of posts) {
|
|
const post = edge.node
|
|
if (post.id && post.name) {
|
|
news.push({
|
|
id: post.id,
|
|
title: post.name,
|
|
url: post.url || `https://www.producthunt.com/posts/${post.slug}`,
|
|
extra: {
|
|
info: ` △︎ ${post.votesCount || 0}`,
|
|
hover: post.tagline,
|
|
},
|
|
})
|
|
}
|
|
}
|
|
|
|
return news
|
|
})
|