📋 Giới thiệu

Trong Bài 1, chúng ta đã tìm hiểu về TNTT Management - hệ thống quản lý học viên “không cần cài đặt”. Bây giờ, đến phần thực hành: thiết lập backend của hệ thống.

Điều tuyệt vời là:

  • Miễn phí 100% - Không tốn phí server, database
  • Dễ dàng - Chỉ cần copy-paste code
  • Nhanh chóng - Hoàn thành trong 15 phút
  • An toàn - Dữ liệu lưu trên Google Drive của bạn

Backend này bao gồm:

  • 📊 Google Sheets - Database lưu trữ học viên, điểm số, điểm danh
  • Google Apps Script - API xử lý logic, authentication, báo cáo
  • 🔐 Google OAuth - Đăng nhập an toàn bằng tài khoản Google

🎯 Yêu cầu chuẩn bị

Trước khi bắt đầu, bạn cần:

Yêu cầuMô tảThời gian
Tài khoản GoogleGmail bất kỳ (tạo miễn phí)0 phút
Google SheetsFile spreadsheet mới1 phút
Trình duyệtChrome, Firefox, Safari, Edge-
Kết nối InternetĐể deploy Apps Script-

Không cần:

  • ❌ Kiến thức lập trình
  • ❌ Kinh nghiệm quản trị server
  • ❌ Chi phí mua hosting/domain

🚀 Bước 1: Tạo Google Sheets Database

1.1 Tạo file mới

  1. Truy cập Google Sheets
  2. Nhấn "+" Blank để tạo file mới
  3. Đặt tên: TNTT Management - Database (hoặc tên bất kỳ)

1.2 Tạo các sheet (tabs) cần thiết

Hệ thống cần 5 sheets để hoạt động. Bạn có thể tạo thủ công hoặc để hệ thống tự tạo:

Cách 1: Tạo thủ công (Khuyên dùng cho người mới)

Tạo 5 tabs với tên chính xác như sau:

Tên SheetMô tảCột (Header)
StudentsDanh sách học viênID, TenThanh, HoDem, Ten, Lop, NgaySinh, NgayRuaToi, PhuHuynh, GiaoKhu, SDT
GradesĐiểm sốStudentID, Type, Score, Timestamp, Teacher
UsersNgười dùngEmail, Role, FullName, AssignedClasses
NotificationsThông báoID, Email, Subject, Message, Date
AttendanceĐiểm danhTimestamp, StudentID, FullName, Class, Teacher

Lưu ý quan trọng:

  • Tên sheet phải viết hoa chữ cái đầu (Students, Grades, Users…)
  • Header phải nằm ở dòng 1 (dòng đầu tiên)
  • Thứ tự cột không quan trọng - hệ thống sẽ tự nhận diện

Cách 2: Để hệ thống tự tạo (Nhanh hơn)

Để trống file, khi chạy code lần đầu, hệ thống sẽ tự động tạo các sheet và header!

1.3 Ghi lại Spreadsheet ID

Spreadsheet ID là “chìa khóa” để kết nối frontend với backend:

  1. Mở file Google Sheets vừa tạo
  2. Nhìn lên thanh địa chỉ, bạn sẽ thấy URL dạng:
    https://docs.google.com/spreadsheets/d/ABC123xyz456_EDIT...
    
  3. Copy phần giữa /d//edit:
    ABC123xyz456
    

📌 Ghi lại ID này! Bạn sẽ cần ở Bước 3.


⚙️ Bước 2: Triển khai Google Apps Script

2.1 Mở Apps Script Editor

  1. Trong Google Sheets, vào menu Extensions (Tải mở rộng)
  2. Chọn Apps Script

Apps Script Menu

Một tab mới sẽ mở ra với Script Editor.

2.2 Xóa code mẫu

Script Editor sẽ có sẵn file Code.js với code mẫu:

function myFunction() {
  Logger.log("Hello World")
}

Xóa toàn bộ code này đi (không cần!).

2.3 Copy code backend vào

Cách 1: Clone toàn bộ repository (Khuyên dùng)

git clone https://github.com/dongthinhlong/TNTT-MANAGEMENT.git
cd TNTT-MANAGEMENT

Sau đó mở file gas/backend.js để copy code.

Cách 2: Tải file trực tiếp

Cách 3: Copy từ file trong thư mục dự án

  1. Mở file gas/backend.js trong thư mục dự án

  2. Copy toàn bộ nội dung

  3. Paste vào Script Editor:

    • Copy toàn bộ nội dung file backend.js
    • Paste vào editor (thay thế code mẫu đã xóa)
  4. Lưu project:

    • Nhấn Ctrl+S (Windows) hoặc Cmd+S (Mac)
    • Đặt tên project: TNTT Management Backend

2.4 Cấu hình Admin Email

Tìm dòng này trong code (khoảng dòng 35):

const ADMIN_EMAIL = 'your-admin-email@gmail.com';

Thay your-admin-email@gmail.com bằng email của bạn (người quản trị).

Tại sao cần?

  • Nhận thông báo khi có học viên mới được thêm
  • Nhận báo cáo lỗi hệ thống
  • Nhận yêu cầu cấp quyền từ giáo lý viên

🌐 Bước 3: Deploy làm Web App

3.1 Mở cửa sổ Deploy

  1. Nhấn nút Deploy (triển khai) góc trên phải
  2. Chọn New deployment (triển khai mới)

Deploy Menu

3.2 Cấu hình deployment

Một cửa sổ sẽ hiện ra. Click vào icon bánh răng ⚙️ bên cạnh “Select type”:

  1. Loại: Chọn Web app
  2. Điền thông tin:
TrườngGiá trịGhi chú
DescriptionTNTT Management API v1Mô tả tự đặt
Execute asMe (Tôi)Quan trọng!
Who has accessAnyone (Bất kỳ ai)Quan trọng!

Giải thích:

  • Execute as: Me → Code chạy với quyền của BẠN (chủ sở hữu), có quyền truy cập Google Sheets
  • Who has access: Anyone → Frontend có thể gọi API mà không cần đăng nhập
  1. Nhấn Deploy

3.3 Cấp quyền (Authorize)

Lần đầu deploy, Google sẽ yêu cầu cấp quyền:

  1. Click Review permissions (Xem lại quyền)

  2. Chọn tài khoản Google của bạn

  3. Warning hiện ra? Click Advanced (Nâng cao)

  4. Click Go to TNTT Management Backend (unsafe)

    • An toàn 100% - đây là code của bạn, Google chỉ cảnh báo vì chưa verified
  5. Cấp các quyền:

    • View and manage your spreadsheets
    • View your email address
    • Manage your own Apps Script projects
  6. Nhấn Allow (Cho phép)

3.4 Copy Web App URL

Sau khi deploy thành công, bạn sẽ thấy:

Web app URL: https://script.google.com/macros/s/ABC123xyz456/exec

Copy toàn bộ URL này! Đây là API Endpoint của bạn.

📌 Ghi lại URL này! Bạn sẽ cần ở Bước 4.

Lưu ý quan trọng:

  • URL có dạng: https://script.google.com/macros/s/[DEPLOYMENT_ID]/exec
  • KHÔNG dùng URL edit hay trigger - phải là URL có /exec cuối cùng
  • Nếu sau này sửa code, nhớ Deploy new version để cập nhật

🔗 Bước 4: Kết nối Frontend với Backend

4.1 Tạo file môi trường (.env)

Trên máy tính của bạn (nơi có code frontend):

  1. Tạo file .env trong thư mục gốc (cùng folder với package.json)
  2. Thêm nội dung:
VITE_GAS_API_URL=https://script.google.com/macros/s/ABC123xyz456/exec

Thay ABC123xyz456 bằng deployment ID bạn vừa copy.

4.2 Cấu hình Google OAuth Client ID

Để đăng nhập bằng Google, bạn cần Client ID:

  1. Truy cập Google Cloud Console
  2. Tạo project mới (hoặc chọn project có sẵn)
  3. Vào APIs & ServicesCredentials
  4. Nhấn Create CredentialsOAuth client ID
  5. Chọn Web application
  6. Thêm Authorized JavaScript origins:
    • Local: http://localhost:3000
    • Production: https://your-domain.vercel.app (nếu có)
  7. Nhấn Create
  8. Copy Client ID (dạng: 123456789-abc...apps.googleusercontent.com)

4.3 Cập nhật file constants.ts

Trong dự án frontend, mở file constants.ts:

export const GOOGLE_CLIENT_ID = 'YOUR_CLIENT_ID_HERE';

Thay YOUR_CLIENT_ID_HERE bằng Client ID vừa tạo.


✅ Bước 5: Kiểm tra backend

5.1 Test API trực tiếp

Để đảm bảo backend hoạt động, test bằng cách gọi API:

  1. Mở trình duyệt

  2. Truy cập URL:

    https://script.google.com/macros/s/ABC123xyz456/exec?functionName=getAcademicYears
    
  3. Kết quả đúng:

    {"2025-2026": "ABC123xyz456"}
    

5.2 Chạy frontend

  1. Mở terminal trong thư mục dự án
  2. Chạy lệnh:
    npm install
    npm run dev
    
  3. Mở trình duyệt tại http://localhost:3000

5.3 Kiểm tra các tính năng

Tính năngCách testKết quả mong đợi
Đăng nhậpClick “Đăng nhập với Google”Đăng nhập thành công
Xem học viênVào tab “Học viên”Hiện danh sách (nếu có dữ liệu)
Điểm danh QRQuét mã QRGhi nhận thành công
Nhập điểmNhập điểm cho học sinhLưu vào Google Sheets

Kiểm tra Google Sheets:

  • Mở file Google Sheets của bạn
  • Các sheet sẽ tự động có dữ liệu sau khi test

🎨 Cấu hình nâng cao (Tùy chọn)

Thêm năm học mới

Hệ thống hỗ trợ nhiều năm học trên cùng 1 backend:

  1. Vào Google Apps ScriptScript Editor
  2. Mở Project Settings (biểu tượng bánh răng)
  3. Trong Script Properties, thêm:
    TNTT_DB_MAP = {"2025-2026":"SHEET_ID_1","2026-2027":"SHEET_ID_2"}
    
  4. Deploy new version

Hoặc dùng giao diện frontend (Admin):

  • Vào tab “Quản lý năm học”
  • Nhấn “Thêm năm học”
  • Nhập tên năm và Spreadsheet ID

Phân quyền giáo lý viên

Để giáo lý viên chỉ quản lý được lớp của mình:

  1. Vào Google Sheets → Sheet Users
  2. Thêm dòng mới:
    email@giavoer.com | TEACHER | Nguyễn Văn A | Lớp 1, Lớp 2
    
CộtGiá trịGhi chú
EmailGmail của giáo lý viênPhải chính xác
RoleTEACHERHoặc ADMIN, GUEST
FullNameTên hiển thịTự đặt
AssignedClassesLớp được quản lýPhân cách bằng dấu phẩy

Thêm email admin nhận thông báo

Trong code backend.js, tìm và sửa:

const ADMIN_EMAIL = 'your-email@gmail.com';

Admin sẽ nhận email khi:

  • Có học viên mới được thêm
  • Có giáo lý viên yêu cầu cấp quyền
  • Có lỗi hệ thống cần xử lý

🐛 Xử lý sự cố

Lỗi “Từ chối truy cập: Quyền GUEST không được phép”

Nguyên nhân: Chưa thêm email vào sheet Users với role phù hợp

Giải pháp:

  1. Mở Google Sheets
  2. Sheet Users → Thêm dòng:
    your-email@gmail.com | ADMIN | Tên của bạn | 
    
  3. Refresh frontend

Lỗi “HỆ THỐNG: Chưa được cấu hình CSDL cho năm học…”

Nguyên nhân: Chưa liên kết Spreadsheet ID với năm học

Giải pháp:

  1. Vào Script Editor → Script Properties
  2. Thêm TNTT_DB_MAP:
    {"2025-2026":"YOUR_SPREADSHEET_ID_HERE"}
    
  3. Deploy new version

Lỗi “CORS” hoặc “Network Error”

Nguyên nhân: Chưa cấu hình đúng CORS hoặc URL sai

Giải pháp:

  1. Kiểm tra .env có đúng URL không
  2. Đảm bảo URL có /exec cuối cùng
  3. Xóa cache trình duyệt (Ctrl+Shift+Delete)

Lỗi “Quota exceeded”

Nguyên nhân: Vượt quá số lần gọi API miễn phí của Google Apps Script

Giải pháp:

  • Giới hạn: 20,000 calls/ngày (tài khoản free)
  • Tối ưu: Sử dụng CacheService (đã có trong code)
  • Nâng cao: Upgrade lên Google Workspace

Không thấy dữ liệu sau khi thêm học viên

Nguyên nhân: Cache chưa làm mới

Giải pháp:

  1. Vào tab “Quản lý database”
  2. Nhấn “Làm mới cache”
  3. Hoặc đợi 5 phút (cache tự hết hạn)

📊 Cấu trúc backend giải thích chi tiết

File backend.js gồm những gì?

PhầnDòng codeChức năng
Cấu hình năm học1-30Quản lý nhiều database
Biến toàn cục32-38Cache, user info
API Gateway40-88Nhận request, phân tuyến
Core Helpers90-168Lấy data, cache, format
Quản lý Users170-220Auth, role, permissions
Quản lý Học viên222-290CRUD students
Quản lý Điểm292-420Nhập điểm, tính TB
Dashboard422-530Thống kê, biểu đồ
Điểm danh660-800QR scan, attendance
Xuất Excel802-958Tạo file báo cáo
Quản lý Năm học960-995Add/delete years

Flow xử lý một request

Frontend (React)
    ↓ POST với JSON
Google Apps Script (doPost)
    ↓ Parse request
    ↓ Check userEmail & academicYear
    ↓ Gọi hàm tương ứng (VD: recordAttendance)
    ↓ Truy cập Google Sheets
    ↓ Trả về JSON
Frontend nhận kết quả
    ↓ Cập nhật UI

Tại sao dùng Google Apps Script?

Ưu điểmGiải thích
Miễn phíKhông tốn phí server
Tích hợp sẵnGoogle Sheets, Drive, Mail
Bảo mậtGoogle OAuth, permission
Auto-scaleGoogle lo phần cứng
Easy deployCopy-paste, click Deploy
Nhược điểmKhắc phục
Rate limitDùng CacheService (đã có)
Timeout 6sTối ưu query (đã có)
Cold startGiữ warm bằng trigger

🎯 Tổng kết

Những gì bạn đã làm được:

Tạo Google Sheets làm database
Triển khai Google Apps Script làm backend API
Cấu hình OAuth cho đăng nhập Google
Kết nối frontend-backend
Kiểm tra hệ thống hoạt động

Bước tiếp theo:

📝 Bài 3: Hướng dẫn deploy frontend lên Vercel/Netlify
📝 Bài 4: Hướng dẫn sử dụng chi tiết các tính năng


Chúc bạn thành công! 🎉

Nếu gặp khó khăn, hãy:

  • Đọc lại phần Xử lý sự cố
  • Kiểm tra log trong Apps Script EditorExecution log
  • Tạo issue trên GitHub

Bài viết bởi @dongthinhlong - Người phát triển TNTT Management
Năm cập nhật: 2026