Skip to content

proxy_upload.js #5113

@longdangviet-code

Description

@longdangviet-code

// 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

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions