-
Notifications
You must be signed in to change notification settings - Fork 300
Closed as not planned
Description
// proxy_upload.js
// Dùng để upload ảnh Base64 lên SharePoint AttendancePhotos/TOA/
// Chạy được trên Cloudflare Functions, Vercel, Netlify, Azure Functions...
import fetch from "node-fetch";
export default async function handler(req, res) {
if (req.method !== "POST") {
return res.status(405).json({ error: "Method Not Allowed" });
}
try {
const { filename, photoBase64 } = req.body;
if (!photoBase64) {
return res.status(400).json({ error: "Missing photo data" });
}
// ====== CONFIGURATION ======
const tenant = "vietnamairports.sharepoint.com";
const sitePath = "/sites/ttdthlhan-team-TANHK";
const library = "AttendancePhotos";
const folder = "TOA"; // lớp Tổ A
const token = process.env.SHAREPOINT_TOKEN; // lưu token trong biến môi trường
// ===========================
const buffer = Buffer.from(photoBase64, "base64");
const uploadName = filename || `checkin_${Date.now()}.jpg`;
const uploadUrl = `https://${tenant}${sitePath}/_api/web/GetFolderByServerRelativeUrl('${library}/${folder}')/Files/add(overwrite=true, url='${uploadName}')`;
const uploadRes = await fetch(uploadUrl, {
method: "POST",
headers: {
"Authorization": `Bearer ${token}`,
"Accept": "application/json;odata=verbose",
"Content-Type": "application/octet-stream"
},
body: buffer
});
if (!uploadRes.ok) {
const text = await uploadRes.text();
return res.status(uploadRes.status).json({ error: "Upload failed", details: text });
}
const photoUrl = `https://${tenant}${sitePath}/${library}/${folder}/${uploadName}`;
return res.status(200).json({ success: true, photoUrl });
} catch (err) {
console.error(err);
return res.status(500).json({ error: err.message });
}
}
Metadata
Metadata
Assignees
Labels
No labels