1 line
3.2 KiB
JSON
1 line
3.2 KiB
JSON
{"repo": "btxmkbtx/next15-youtube-clone", "files": {"src/app/api/videos/workflows/title/route.ts": {"009a335ee524f05aed03e5a5f69412239e2d622b": {"t": 1785745577.1487997, "n": 2756, "h": "c55a6d2d916def8c", "c": "import { db } from \"@/db\";\nimport { videos } from \"@/db/schema\";\nimport { serve } from \"@upstash/workflow/nextjs\";\nimport { and, eq } from \"drizzle-orm\";\n\n/**\n * 这里拿到的参数名是workflow的触发器的请求体决定的\n * src\\modules\\videos\\server\\procedures.ts->generateTitle->workflow.trigger->body\n * */\ninterface InputType {\n userId: string;\n videoId: string;\n}\n\nconst AI_PROMPT_GENERATE_TITLE = `Your task is to generate an SEO-focused title for a YouTube video based on its transcript. Please follow these guidelines:\n- Be concise but descriptive, using relevant keywords to improve discoverability.\n- Highlight the most compelling or unique aspect of the video content.\n- Avoid jargon or overly complex language unless it directly supports searchability.\n- Use action-oriented phrasing or clear value propositions where applicable.\n- Ensure the title is 3-8 words long and no more than 100 characters.\n- ONLY return the title as plain text. Do not add quotes or any additional formatting.`;\n\nexport const { POST } = serve(async (context) => {\n const input = context.requestPayload as InputType;\n const { videoId, userId } = input;\n\n const video = await context.run(\"get-video\", async () => {\n // 解构Array[0]的语法糖写法,这个existingVideo就相当于结果data[0]\n const [existingVideo] = await db\n .select()\n .from(videos)\n .where(and(eq(videos.id, videoId), eq(videos.userId, userId)));\n\n if (!existingVideo) {\n throw new Error(\"Not found\");\n }\n\n return existingVideo;\n });\n\n const transcript = await context.run(\"get-transcript\", async () => {\n const trackUrl = `https://stream.mux.com/${video.muxPlaybackId}/text/${video.muxTrackId}.txt`;\n const response = await fetch(trackUrl);\n const text = await response.text();\n\n if (!text) {\n throw new Error(\"Bad request\");\n }\n\n return text;\n });\n\n /* \n 让AI生成一个标题,chatGPT要钱(429错误),deepseek要钱(Insufficient Balance错误),\n 所以这功能暂时不好用,这就是体验一下wrokflow流程\n */\n const { body } = await context.api.openai.call(\n \"Call Deepseek to generate title\",\n {\n baseURL: \"https://api.deepseek.com\",\n token: process.env.DEEPSEEK_API_KEY!,\n operation: \"chat.completions.create\",\n body: {\n model: \"deepseek-chat\",\n messages: [\n {\n role: \"system\",\n content: AI_PROMPT_GENERATE_TITLE,\n },\n {\n role: \"user\",\n content: transcript,\n },\n ],\n },\n }\n );\n\n const title = body.choices?.[0]?.message.content;\n if (!title) {\n throw new Error(\"Bad request\");\n }\n\n await context.run(\"update-video\", async () => {\n await db\n .update(videos)\n .set({ title: title || video.title })\n .where(and(eq(videos.id, video.id), eq(videos.userId, video.userId)));\n });\n});\n"}}}} |