import { checkApiLimit, incrementApiLimit } from "@/lib/api-limit";
import { auth } from "@clerk/nextjs/server";
import { NextResponse } from "next/server";
import OpenAI from "openai";
import { db } from "@/lib/db";
import { generateThemedEmotePrompt } from "@/app/features/editor/utils";
import AWS from "aws-sdk";
import { env } from "@/env.mjs";
import { v4 as uuidv4 } from "uuid";
import axios from "axios";
export const maxDuration = 300;
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY,
});
export async function POST(req: Request) {
try {
const { userId } = auth();
if (!userId) {
return new NextResponse("Unauthorized", { status: 401 });
}
const id = userId as string;
const body = await req.json();
const { prompt, amount = 1, resolution = "1024x1024", emoteType } = body;
if (!openai.apiKey) {
return new NextResponse("OpenAI API Key not configured.", { status: 500 });
}
if (!prompt || !amount || !resolution) {
return new NextResponse("Prompt, amount, and resolution are required.", { status: 400 });
}
const userCredits = await db.user.findUnique({
where: { id: userId },
});
if (!userCredits || userCredits.credits <= 0) {
return new NextResponse("You have run out of credits.", { status: 403 });
}
const finalPrompt = generateThemedEmotePrompt(prompt, emoteType);
if (!finalPrompt) {
return new NextResponse("Final prompt generation failed.", { status: 400 });
}
// Call OpenAI API
const response = await openai.images.generate({
model: "dall-e-3",
prompt: finalPrompt,
quality: "standard",
});
const imageUrl = response.data[0]?.url;
if (!imageUrl) {
throw new Error("No image URL in response");
}
// Fetch the image data
const imageResponse = await axios.get(imageUrl, { responseType: "arraybuffer" });
const buffer = Buffer.from(imageResponse.data, "binary");
// Configure AWS S3
const s3 = new AWS.S3({
credentials: {
accessKeyId: env.ACCESS_KEY_ID,
secretAccessKey: env.SECRET_ACCESS_KEY,
},
region: "us-east-1",
});
const BUCKET_NAME = "pprcanvas";
const key = `emotes/${id}/${uuidv4()}.png`;
const uploadResult = await s3.upload({
Bucket: BUCKET_NAME,
Key: key,
Body: buffer,
ContentType: "image/png",
}).promise();
// Save the emote data to the database
const emote = await db.emote.create({
data: {
userId: id,
prompt,
imageUrl: uploadResult.Location,
},
});
// Deduct credits
await db.user.update({
where: { id },
data: { credits: userCredits.credits - 1 },
});
return NextResponse.json([uploadResult.Location]);
} catch (error) {
console.error("[EMOTE_GENERATION_ERROR]", error);
return new NextResponse("Internal Error", { status: 500 });
}
}
Stripe Webhook