Skip to content

Instantly share code, notes, and snippets.

@jordonmckoy
Created February 8, 2024 12:49
Show Gist options
  • Save jordonmckoy/59c65046dfabd3f03c51d51c839421ac to your computer and use it in GitHub Desktop.
Save jordonmckoy/59c65046dfabd3f03c51d51c839421ac to your computer and use it in GitHub Desktop.
File upload to Google Cloud Storage (GCS) in Next.js 14 API Route
"use client"
export default function AudioRecorder() {
const [audioBlob, setAudioBlob] = useState<Blob | null>(null);
// ...app code omitted
const uploadAudio = async () => {
if (!audioBlob) {
throw new Error("No audio to upload");
}
// Prepare FormData
let formData = new FormData();
const timestamp = Date.now();
// Append the audio blob to the FormData object. You might want to give it a filename.
formData.append("audio", audioBlob, `${timestamp}.webm`);
// Setup the fetch request options
const requestOptions: RequestInit = {
method: "POST",
body: formData,
};
// Send the request to your API endpoint
try {
const response = await fetch("/api/upload", requestOptions);
if (!response.ok) throw new Error("Failed to upload");
const data = await response.json();
console.log("Upload successful:", data);
} catch (error) {
console.error("Error uploading audio:", error);
}
};
return (
<div className="audio-container">
<form id="uploadForm">
<input type="file" id="fileInput" multiple />
<button type="button" onClick={uploadAudio}>
Upload
</button>
</form>
</div>
);
}
// api/upload/route.ts
export const POST = async (req: Request, res: Response) => {
try {
const data = await req.formData();
const file = data.get("audio") as File;
if (!file || typeof file === "string") {
throw new Error("Audio file not found");
}
const filePath = file?.name;
const storage = new Storage({
projectId: `${GCP_PROJECT_ID}`,
credentials: {
client_email: `${GCP_SERVICE_ACCOUNT_EMAIL}`,
private_key: `${GCP_PRIVATE_KEY}`,
},
});
const bucket = storage.bucket(`${GCP_BUCKET_NAME}`);
const bytes = await file.arrayBuffer();
const buffer = Buffer.from(bytes);
// Wrap the upload logic in a promise
await new Promise((resolve, reject) => {
const blob = bucket.file(filePath);
const blobStream = blob.createWriteStream({
resumable: false,
});
blobStream
.on("error", (err) => reject(err))
.on("finish", () => resolve(true));
blobStream.end(buffer);
});
return new NextResponse(JSON.stringify({ success: true }));
} catch (error) {
return new NextResponse(JSON.stringify(error), { status: 500 });
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment