Xây Dựng Add-on & Best Practices

Thời gian đọc: ~35 phút

Batch Operations — Quan Trọng Nhất

Đây là best practice số 1 trong Apps Script. Mỗi lần gọi Spreadsheet API đều tốn thời gian do round-trip đến server Google. Minimize số lần gọi API là chìa khóa hiệu suất.

// BAD: 1000 API calls — chay ~30 giay
function slowVersion() {
  const sheet = SpreadsheetApp.getActiveSheet();
  for (var i = 1; i <= 1000; i++) {
    sheet.getRange(i, 1).setValue(i * 2); // moi lan la 1 API call
  }
}

// GOOD: 1 API call — chay <1 giay
function fastVersion() {
  const sheet = SpreadsheetApp.getActiveSheet();
  const values = [];
  for (var i = 1; i <= 1000; i++) {
    values.push([i * 2]);
  }
  sheet.getRange(1, 1, 1000, 1).setValues(values); // chi 1 call
}
Quy tac vang: Doc toan bo du lieu 1 lan vao bien → xu ly trong memory JavaScript → ghi ket qua 1 lan. Tranh doc/ghi trong vong lap!

CacheService — Cache Dữ Liệu Tốn Thời Gian

// Cache ket qua API / du lieu Sheet de tai su dung
function getProductsWithCache() {
  const cache = CacheService.getScriptCache();
  const cacheKey = 'products_list';
  const cached = cache.get(cacheKey);

  if (cached) {
    Logger.log('Cache hit!');
    return JSON.parse(cached);
  }

  // Lay du lieu that (cham)
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName('Products');
  const data = sheet.getDataRange().getValues();

  // Luu vao cache 5 phut (300 giay)
  cache.put(cacheKey, JSON.stringify(data), 300);
  return data;
}

// Xoa cache khi co cap nhat
function clearProductsCache() {
  CacheService.getScriptCache().remove('products_list');
}

PropertiesService — Lưu Cấu Hình

// Luu cau hinh theo cap do

// Script properties: chung cho tat ca user
function setScriptConfig() {
  const props = PropertiesService.getScriptProperties();
  props.setProperty('API_KEY', 'your-api-key-here');
  props.setProperty('VERSION', '1.2.0');
}

// User properties: rieng tung user
function saveUserPrefs(email, notifyEnabled) {
  const props = PropertiesService.getUserProperties();
  props.setProperty('email', email);
  props.setProperty('notify', String(notifyEnabled));
}

// Doc cau hinh
function getConfig() {
  return {
    apiKey: PropertiesService.getScriptProperties().getProperty('API_KEY'),
    userEmail: PropertiesService.getUserProperties().getProperty('email')
  };
}

LockService — Tránh Xung Đột

// Khi nhieu trigger chay dong thoi, can khoa de tranh xung dot
function safeAppendRow(data) {
  const lock = LockService.getScriptLock();
  try {
    lock.waitLock(10000); // cho toi 10 giay
    const sheet = SpreadsheetApp.getActiveSheet();
    sheet.appendRow(data);
    SpreadsheetApp.flush(); // dam bao ghi xong
  } catch (err) {
    Logger.log('Khong lay duoc lock: ' + err.message);
  } finally {
    lock.releaseLock();
  }
}

Error Handling Chuẩn

function robustScript() {
  try {
    const sheet = SpreadsheetApp.getActiveSheet();
    if (!sheet) throw new Error('Khong tim thay sheet hien tai');

    const data = sheet.getDataRange().getValues();
    if (data.length < 2) throw new Error('Sheet khong co du lieu');

    // xu ly chinh...
    processData(data);

    SpreadsheetApp.getUi().alert('Hoan thanh!');
  } catch (err) {
    console.error('[ERROR] ' + err.message + ' ' + err.stack);
    SpreadsheetApp.getUi().alert('Loi: ' + err.message);
    // Gui email thong bao loi cho admin
    MailApp.sendEmail('admin@company.com', 'Script Error', err.message + '\n' + err.stack);
  }
}

Xây Dựng & Deploy Add-on

Add-on là cách đóng gói script để phân phối rộng rãi. Có 2 loại phân phối:

  • Internal (Domain-wide): Cho toàn bộ domain Google Workspace — không cần review
  • Public (Marketplace): Cho mọi người — cần Google review (1-2 tuần)
// Cau truc bat buoc cho Add-on
function onInstall(e) {
  onOpen(e);
}

function onOpen(e) {
  const authMode = e.authMode;
  const menu = SpreadsheetApp.getUi().createAddonMenu();

  if (authMode === ScriptApp.AuthMode.NONE) {
    menu.addItem('Cai dat Add-on', 'requestAuth');
  } else {
    menu.addItem('Mo cong cu', 'showSidebar');
    menu.addItem('Cai dat', 'showSettings');
  }
  menu.addToUi();
}

// Steps de deploy:
// 1. Deploy > New deployment > Type: Add-on
// 2. Dien Name, Description, Scope
// 3. Internal: Admin Console > Apps > Add-ons > Upload
// 4. Public: Google Workspace Marketplace SDK setup

Performance Checklist

  • Dung getValues() / setValues() thay vi loop doc/ghi tung o
  • Dung CacheService cho du lieu it thay doi
  • Goi SpreadsheetApp.flush() sau khi ghi nhieu du lieu
  • Kiem tra dieu kien som trong onEdit de return nhanh neu khong can xu ly
  • Dung LockService khi nhieu user co the chay script dong thoi
  • Dat muteHttpExceptions: true cho moi UrlFetchApp.fetch()
  • Log bang console.error() cho loi, console.log() cho debug
Chuc mung hoan thanh khoa hoc Apps Script A-Z! Ban da nam vung toan bo nen tang: tu SpreadsheetApp, Trigger, Email, API cho den Add-on va Best Practices. Buoc tiep theo: ap dung vao du an thuc te cua ban va kham pha them tai developers.google.com/apps-script.