Google Apps Script

Tạo REST API Tùy Chỉnh Với Apps Script (doGet/doPost)

Tuân HoangTuân Hoang
14 tháng 5, 2026
Cập nhật: 20 tháng 9, 2026
5 phút đọc
Ảnh minh họa bài viết: Tạo REST API Tùy Chỉnh Với Apps Script (doGet/doPost)

Apps Script Như Một Backend API

Google Apps Script có thể deploy thành Web App, hoạt động như một REST API endpoint miễn phí. Mọi request từ website, app mobile hay công cụ automation đều có thể gọi vào API này để đọc/ghi dữ liệu Google Sheets. Chi tiết hơn tại: tự dựng URL shortener trên Google Sheets.

Cấu Trúc doGet() — Endpoint Đọc Dữ Liệu

/**
 * GET /exec?action=list&sheet=Orders&limit=50&token=xxx
 */
function doGet(e) {
  try {
    const token = PropertiesService.getScriptProperties().getProperty('API_TOKEN');
    if (token && e.parameter.token !== token) {
      return respond({ error: 'Unauthorized' }, 401);
    }
const action = e.parameter.action || 'list';
const sheetName = e.parameter.sheet || 'Data';
const limit = parseInt(e.parameter.limit) || 100;
const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName(sheetName);

if (!sheet) return respond({ error: 'Sheet not found: ' + sheetName }, 404);

if (action === 'count') {
  return respond({ count: Math.max(0, sheet.getLastRow() - 1) });
}

const raw = sheet.getDataRange().getValues();
if (raw.length <= 1) return respond({ data: [], total: 0 });

const headers = raw[0];
const data = raw.slice(1, limit + 1).map(row => {
  const obj = {};
  headers.forEach((h, i) => { obj[h] = row[i]; });
  return obj;
});

return respond({ data, total: raw.length - 1 });

} catch (err) { return respond({ error: err.toString() }, 500); } }

function respond(data, status) { return ContentService .createTextOutput(JSON.stringify({ ...data, status: status || 200 })) .setMimeType(ContentService.MimeType.JSON); }

Cấu Trúc doPost() — Endpoint Ghi Dữ Liệu

/**
 * POST /exec  body: { token, sheet, ...fields }
 */
function doPost(e) {
  try {
    let payload;
    if (e.postData && e.postData.type === 'application/json') {
      payload = JSON.parse(e.postData.contents);
    } else {
      payload = e.parameter;
    }
const token = PropertiesService.getScriptProperties().getProperty('API_TOKEN');
if (token && payload.token !== token) return respond({ error: 'Unauthorized' }, 401);

const sheetName = payload.sheet || 'Data';
const ss = SpreadsheetApp.getActiveSpreadsheet();
let sheet = ss.getSheetByName(sheetName);
if (!sheet) sheet = ss.insertSheet(sheetName);

// Auto-create headers nếu sheet trống
if (sheet.getLastRow() === 0) {
  const headers = ['timestamp', ...Object.keys(payload).filter(k => k !== 'token' && k !== 'sheet')];
  sheet.appendRow(headers);
  sheet.getRange(1, 1, 1, headers.length).setFontWeight('bold').setBackground('#f0f0f0');
}

const headers = sheet.getRange(1, 1, 1, sheet.getLastColumn()).getValues()[0];
const newRow = headers.map(h => h === 'timestamp' ? new Date() : (payload[h] ?? ''));
sheet.appendRow(newRow);

return respond({ success: true, row: sheet.getLastRow() });

} catch (err) { console.error('doPost error: ' + err.toString()); return respond({ error: err.toString() }, 500); } }

Deploy Web App Và Cài Token

  1. Apps Script Editor → Deploy → New deployment
  2. Type: Web app | Execute as: Me | Access: Anyone
  3. Copy URL → Dùng trong curl, Postman hay code client
// Chạy một lần để tạo token
function setupApiToken() {
  const token = Utilities.getUuid();
  PropertiesService.getScriptProperties().setProperty('API_TOKEN', token);
  Logger.log('API_TOKEN: ' + token);
}

Test Với curl

# Đọc dữ liệu
curl "https://script.google.com/macros/s/AKfy.../exec?action=list&sheet=Orders&token=YOUR_TOKEN&limit=10"

Ghi dữ liệu

curl -X POST "https://script.google.com/macros/s/AKfy.../exec" -H "Content-Type: application/json" -d '{"token":"YOUR_TOKEN","sheet":"Orders","name":"Nguyen Van A","amount":500000}'

Giới Hạn Cần Biết

  • Không hỗ trợ custom HTTP status codes — status trả trong JSON body.
  • Quota: 20.000 request/ngày (tài khoản cá nhân), không giới hạn với Workspace.
  • Execution time tối đa 6 phút/request — không phù hợp tác vụ nặng.
  • CORS: Apps Script tự xử lý, dùng được từ browser.

Câu Hỏi Thường Gặp

Apps Script Web App có dùng được cho production thật không?

Dùng được cho các ứng dụng nội bộ, MVP, hoặc tích hợp quy mô vừa. Với hệ thống cần uptime cao và không giới hạn quota, nên cân nhắc backend riêng — nhưng với hầu hết nhu cầu ghi/đọc dữ liệu vào Sheets, Apps Script đã đủ ổn định.

Làm sao bảo mật endpoint doPost để tránh bị spam request?

Ngoài kiểm tra token trong body request, nên thêm giới hạn tần suất bằng cách lưu timestamp request gần nhất vào PropertiesService và từ chối nếu gọi quá nhanh. Không nên public URL Web App công khai nếu không có xác thực.

Tại sao gọi API từ trình duyệt bị lỗi CORS dù đã deploy đúng?

Kiểm tra lại quyền truy cập khi deploy là "Anyone" (không phải "Anyone with Google account"), vì Apps Script chỉ tự xử lý CORS khi Web App cho phép truy cập ẩn danh.

Web App URL có thay đổi sau mỗi lần deploy lại không?

Nếu dùng "Manage deployments" và chọn deploy bản mới cho cùng deployment ID, URL giữ nguyên. Nếu tạo "New deployment" mới, URL sẽ đổi — cần cập nhật lại ở phía gọi API.

💡 Giải pháp sẵn có cho bạn

Không muốn tự làm? Dùng ngay Phần Mềm Quản Lý Bán Hàng bằng Google Sheet — đầy đủ tính năng, cài đặt nhanh.

Xem sản phẩm →

📚 Bài Viết Liên Quan

Chia sẻ bài viết:

Tuân Hoang

Tuân Hoang

Đội ngũ SheetStore

Google SheetsGoogle Apps ScriptCRMAutomationPhần mềm quản lý doanh nghiệp

Google Workspace Certified, 5+ years experience

Bạn thấy bài viết hữu ích?

Đăng ký nhận thông báo khi có bài viết mới.

Nhận thông báo khi có bài viết mới. Không spam, hứa luôn! 😊

Bình luận (0)

Vui lòng đăng nhập để tham gia thảo luận