Spaces:
Running
Running
"use server" | |
import { v4 as uuidv4 } from "uuid" | |
import { CreatePostResponse, GetAppPostsResponse, Post, PostVisibility } from "@/types" | |
import { filterOutBadWords } from "./censorship" | |
const apiUrl = `${process.env.COMMUNITY_API_URL || ""}` | |
const apiToken = `${process.env.COMMUNITY_API_TOKEN || ""}` | |
const appId = `${process.env.COMMUNITY_API_ID || ""}` | |
export async function postToCommunity({ | |
prompt, | |
assetUrl, | |
}: { | |
prompt: string | |
assetUrl: string | |
}): Promise<Post> { | |
prompt = filterOutBadWords(prompt) | |
// if the community API is disabled, | |
// we don't fail, we just mock | |
if (!apiUrl) { | |
const mockPost: Post = { | |
postId: uuidv4(), | |
appId: "mock", | |
prompt, | |
previewUrl: assetUrl, | |
assetUrl, | |
createdAt: new Date().toISOString(), | |
visibility: "normal", | |
upvotes: 0, | |
downvotes: 0 | |
} | |
return mockPost | |
} | |
if (!prompt) { | |
console.error(`cannot call the community API without a prompt, aborting..`) | |
throw new Error(`cannot call the community API without a prompt, aborting..`) | |
} | |
if (!assetUrl) { | |
console.error(`cannot call the community API without an assetUrl, aborting..`) | |
throw new Error(`cannot call the community API without an assetUrl, aborting..`) | |
} | |
try { | |
console.log(`calling POST ${apiUrl}/posts/${appId} with prompt: ${prompt}`) | |
const postId = uuidv4() | |
const post: Partial<Post> = { postId, appId, prompt, assetUrl } | |
console.table(post) | |
const res = await fetch(`${apiUrl}/posts/${appId}`, { | |
method: "POST", | |
headers: { | |
Accept: "application/json", | |
"Content-Type": "application/json", | |
Authorization: `Bearer ${apiToken}`, | |
}, | |
body: JSON.stringify(post), | |
cache: 'no-store', | |
// we can also use this (see https://vercel.com/blog/vercel-cache-api-nextjs-cache) | |
// next: { revalidate: 1 } | |
}) | |
// console.log("res:", res) | |
// The return value is *not* serialized | |
// You can return Date, Map, Set, etc. | |
// Recommendation: handle errors | |
if (res.status !== 200) { | |
// This will activate the closest `error.js` Error Boundary | |
throw new Error('Failed to fetch data') | |
} | |
const response = (await res.json()) as CreatePostResponse | |
// console.log("response:", response) | |
return response.post | |
} catch (err) { | |
const error = `failed to post to community: ${err}` | |
console.error(error) | |
throw new Error(error) | |
} | |
} | |
export async function getLatestPosts(visibility?: PostVisibility): Promise<Post[]> { | |
let posts: Post[] = [] | |
// if the community API is disabled we don't fail, | |
// we just mock | |
if (!apiUrl) { | |
return posts | |
} | |
try { | |
// console.log(`calling GET ${apiUrl}/posts with renderId: ${renderId}`) | |
const res = await fetch(`${apiUrl}/posts/${appId}/${ | |
visibility || "all" | |
}`, { | |
method: "GET", | |
headers: { | |
Accept: "application/json", | |
"Content-Type": "application/json", | |
Authorization: `Bearer ${apiToken}`, | |
}, | |
cache: 'no-store', | |
// we can also use this (see https://vercel.com/blog/vercel-cache-api-nextjs-cache) | |
// next: { revalidate: 1 } | |
}) | |
// console.log("res:", res) | |
// The return value is *not* serialized | |
// You can return Date, Map, Set, etc. | |
// Recommendation: handle errors | |
if (res.status !== 200) { | |
// This will activate the closest `error.js` Error Boundary | |
throw new Error('Failed to fetch data') | |
} | |
const response = (await res.json()) as GetAppPostsResponse | |
// console.log("response:", response) | |
return Array.isArray(response?.posts) ? response?.posts : [] | |
} catch (err) { | |
// const error = `failed to get posts: ${err}` | |
// console.error(error) | |
// throw new Error(error) | |
return [] | |
} | |
} |