rebreak-monorepo/backend/server/api/admin/set-lyra-avatar.post.ts

73 lines
2.4 KiB
TypeScript

import { updateProfile } from "../../db/profile";
/** POST /api/admin/set-lyra-avatar — PNG aus Canvas hochladen und als Bot-Avatar setzen */
export default defineEventHandler(async (event) => {
const config = useRuntimeConfig();
const adminSecret = getHeader(event, "x-admin-secret");
if (!config.adminSecret || adminSecret !== config.adminSecret) {
throw createError({ statusCode: 401, message: "Unauthorized" });
}
const body = await readBody<{ author: "lyra" | "rebreak"; dataUrl: string }>(
event,
);
if (!body?.dataUrl?.startsWith("data:image/")) {
throw createError({ statusCode: 400, message: "Invalid dataUrl" });
}
const author = body.author === "rebreak" ? "rebreak" : "lyra";
const userId =
author === "rebreak" ? config.rebreakBotUserId : config.lyraBotUserId;
if (!userId) {
throw createError({
statusCode: 400,
message: `Bot user ID for ${author} not configured`,
});
}
// base64 → Buffer
const base64 = body.dataUrl.replace(/^data:image\/\w+;base64,/, "");
const buffer = Buffer.from(base64, "base64");
const supabaseUrl = "https://db-staging.rebreak.org";
const serviceKey =
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsImF1ZCI6ImF1dGhlbnRpY2F0ZWQiLCJyb2xlIjoic2VydmljZV9yb2xlIiwiZXhwIjoyMDkxMDE4OTU1LCJpYXQiOjE3NzU2NTg5NTV9.45fB5DC0-RMrYQXhlB0mI-bjtFAiHhjdBeBY9X8B8b8";
const storagePath = `${author}-bot/avatar.png`;
const storageUrl = `${supabaseUrl}/storage/v1/object/rebreak-avatars/${storagePath}`;
// Erst versuchen zu updaten, dann als neu anlegen
const uploadRes = await $fetch<{ Key?: string; error?: string }>(storageUrl, {
method: "PUT",
headers: {
apikey: serviceKey,
Authorization: `Bearer ${serviceKey}`,
"Content-Type": "image/png",
"x-upsert": "true",
},
body: buffer,
}).catch(() => null);
if (!uploadRes?.Key && !uploadRes) {
// Fallback: POST (create)
await $fetch(storageUrl, {
method: "POST",
headers: {
apikey: serviceKey,
Authorization: `Bearer ${serviceKey}`,
"Content-Type": "image/png",
},
body: buffer,
});
}
const avatarPublicUrl = `${supabaseUrl}/storage/v1/object/public/rebreak-avatars/${storagePath}?t=${Date.now()}`;
await updateProfile(userId, { avatar: avatarPublicUrl });
return { success: true, avatar: avatarPublicUrl };
});