import { onObjectFinalized } from "firebase-functions/storage"; import { logger } from "firebase-functions"; import { getStorage } from "firebase-admin/storage"; import "../firebase"; import { OPTIMIZED_FLAG, optimizeRewardImage, targetForPath } from "../services/imageOptimizeService"; /** * reward-products/ 아래에 업로드된 이미지를 리사이즈 + WebP로 변환해 같은 경로에 덮어쓴다. * 커스텀 메타데이터(다운로드 토큰 포함)를 보존하므로 기존 URL은 그대로 유효하다. * 버킷(US-CENTRAL1)과 같은 리전이어야 Eventarc 트리거가 생성된다. */ export const onRewardImageUploaded = onObjectFinalized( { bucket: "mmday-panit.firebasestorage.app", region: "us-central1", memory: "1GiB", timeoutSeconds: 300, }, async (event) => { const object = event.data; const target = targetForPath(object.name); if (!target) return; if (!object.contentType?.startsWith("image/")) return; if (object.metadata?.[OPTIMIZED_FLAG] === "true") return; const file = getStorage().bucket(object.bucket).file(object.name); const [input] = await file.download(); const output = await optimizeRewardImage(input, target); if (output.data.length >= input.length) { // 이미 충분히 작은 파일은 재업로드 없이 플래그만 남긴다(메타데이터 변경은 finalize를 다시 발생시키지 않음). await file.setMetadata({ metadata: { [OPTIMIZED_FLAG]: "true" } }); logger.info(`[rewardImage] skip (already small) ${object.name} ${input.length}B`); return; } await file.save(output.data, { contentType: "image/webp", metadata: { metadata: { ...object.metadata, [OPTIMIZED_FLAG]: "true" } }, }); logger.info( `[rewardImage] optimized ${object.name} ` + `${input.length}B -> ${output.data.length}B (${output.width}x${output.height})`, ); }, );