Tự Động Hóa Quản Lý Công Việc Với Google Sheets & Apps Script: Hướng Dẫn Từ A-Z
Tự động hóa hoàn toàn quy trình quản lý công việc với Google Sheets và Apps Script — không cần lập trình phức tạp.
Từ gửi email nhắc deadline tự động, cập nhật trạng thái task, đến thông báo Telegram cho team — tất cả đều làm được với Google Apps Script miễn phí. Bài viết này hướng dẫn từng bước với code mẫu copy-paste ngay.
📋 Mục lục bài viết:
- 1. Tại sao cần tự động hóa quản lý công việc?
- 2. Google Apps Script là gì? Cách bắt đầu
- 3. Automation #1: Gửi email nhắc deadline tự động
- 4. Automation #2: Tự động cập nhật trạng thái và màu sắc
- 5. Automation #3: Gửi thông báo Telegram/Slack
- 6. Automation #4: Google Form → Task list tự động
- 7. Automation #5: Dashboard auto-refresh và báo cáo tuần
- 8. Setup Triggers — Lịch chạy tự động
- 9. SheetStore — Template có sẵn automation
- 10. FAQ — Câu hỏi thường gặp
1. Tại Sao Cần Tự Động Hóa Quản Lý Công Việc?
Một team 10 người thường mất trung bình 4-6 giờ mỗi tuần cho các công việc lặp đi lặp lại liên quan đến quản lý task: gửi reminder, cập nhật trạng thái, tổng hợp báo cáo, thông báo cho team. Nhân 52 tuần, đó là 200-300 giờ lãng phí mỗi năm — tương đương 12-18 tuần làm việc của một nhân viên.
Với Google Apps Script — hoàn toàn miễn phí và tích hợp sẵn trong Google Workspace — bạn có thể tự động hóa phần lớn những công việc này mà không cần kỹ sư phần mềm.
Chi phí Apps Script
Miễn phí hoàn toàn với Google account
Thời gian tiết kiệm
Trung bình cho team 10 người
Thời gian setup
Copy-paste code, chạy ngay
2. Google Apps Script Là Gì? Cách Bắt Đầu
Google Apps Script là nền tảng scripting dựa trên JavaScript, cho phép bạn tự động hóa và mở rộng các sản phẩm Google (Sheets, Gmail, Calendar, Drive, Forms...). Không cần server, không cần deploy — chạy trực tiếp trên Google Cloud.
Cách mở Apps Script Editor
- 1 Mở Google Sheets của bạn (file task management)
- 2 Vào menu Extensions → Apps Script
- 3 Apps Script Editor sẽ mở ra trong tab mới — đây là nơi bạn viết và chạy code
- 4 Copy code từ bài viết này, paste vào editor, nhấn Save rồi Run
Cấu trúc Google Sheets cho task management
Trước khi viết automation, hãy đảm bảo Sheets của bạn có cấu trúc chuẩn. Các automation dưới đây giả định file có cấu trúc sau:
// Cột A-H trong sheet "Tasks"
A: Task ID | B: Tên task | C: Người phụ trách
D: Deadline | E: Trạng thái | F: Ưu tiên
G: Email người phụ trách | H: Ghi chú
// Trạng thái: "Chưa làm" | "Đang làm" | "Chờ duyệt" | "Hoàn thành" | "Trễ hạn"
3. Automation #1: Gửi Email Nhắc Deadline Tự Động
Automation quan trọng nhất: tự động gửi email cho người phụ trách khi deadline còn 1-3 ngày. Không cần ai nhớ, không cần ai nhắc thủ công.
// === AUTOMATION #1: Email nhắc deadline ===
function
sendDeadlineReminders() {
const sheet = SpreadsheetApp.getActiveSpreadsheet()
.getSheetByName('Tasks');
const data = sheet.getDataRange().getValues();
const today = new Date();
today.setHours(0, 0, 0, 0);
// Bỏ qua hàng tiêu đề (hàng 1)
for (let i = 1; i < data.length; i++) {
const taskName = data[i][1]; // Cột B
const assignee = data[i][2]; // Cột C
const deadline = new Date(data[i][3]); // Cột D
const status = data[i][4]; // Cột E
const email = data[i][6]; // Cột G
// Bỏ qua task đã hoàn thành
if (status === 'Hoàn thành' || !email) continue;
deadline.setHours(0, 0, 0, 0);
const daysLeft = Math.round(
(deadline - today) / (1000 * 60 * 60 * 24)
);
// Nhắc khi còn 3 ngày, 1 ngày, hoặc đã trễ
if (daysLeft === 3 || daysLeft === 1 || daysLeft < 0) {
const subject = daysLeft < 0
? '[TRE HAN ' + Math.abs(daysLeft) + ' ngay] ' + taskName
: 'Deadline con ' + daysLeft + ' ngay: ' + taskName;
const body = 'Xin chao ' + assignee + ',
'
+ (daysLeft < 0
? 'Task da TRE HAN ' + Math.abs(daysLeft) + ' ngay!'
: 'Deadline task sap den!')
+ '
Task: ' + taskName
+ '
Deadline: ' + deadline.toLocaleDateString('vi-VN')
+ '
Trang thai: ' + status
+ '
Vui long cap nhat tien do.
Tran trong';
GmailApp.sendEmail(email, subject, body);
console.log('Da gui reminder cho ' + assignee + ': ' + taskName);
}
}
}
📌 Cách setup trigger để chạy mỗi ngày:
Vào Apps Script Editor → Triggers (biểu tượng đồng hồ) → Add Trigger → Function: sendDeadlineReminders → Event source: Time-driven → Type: Day timer → Time: 8:00 AM → Save
4. Automation #2: Tự Động Cập Nhật Trạng Thái Và Màu Sắc
Script này tự động đánh dấu task là "Trễ hạn" khi qua deadline và tô màu ô để dễ nhìn thấy ngay lập tức.
// === AUTOMATION #2: Tự động cập nhật trạng thái và màu ===
function autoUpdateTaskStatus() {
const sheet = SpreadsheetApp.getActiveSpreadsheet()
.getSheetByName('Tasks');
const lastRow = sheet.getLastRow();
if (lastRow < 2) return;
const today = new Date();
today.setHours(0, 0, 0, 0);
for (let row = 2; row <= lastRow; row++) {
const deadlineCell = sheet.getRange(row, 4); // Cột D
const statusCell = sheet.getRange(row, 5); // Cột E
const rowRange = sheet.getRange(row, 1, 1, 8);
const deadline = new Date(deadlineCell.getValue());
const status = statusCell.getValue();
deadline.setHours(0, 0, 0, 0);
// Bỏ qua hàng trống hoặc task đã xong
if (!deadlineCell.getValue() || status === 'Hoàn thành') {
if (status === 'Hoàn thành') {
// Tô màu xanh lá cho task hoàn thành
rowRange.setBackground('#d4edda');
}
continue;
}
const daysLeft = Math.round(
(deadline - today) / (1000 * 60 * 60 * 24)
);
if (daysLeft < 0 && status !== 'Trễ hạn') {
// Tự động mark trễ hạn + tô màu đỏ
statusCell.setValue('Trễ hạn');
rowRange.setBackground('#f8d7da');
} else if (daysLeft === 0) {
// Hôm nay deadline + tô màu vàng cam
rowRange.setBackground('#fff3cd');
} else if (daysLeft <= 3) {
// Sắp deadline + tô màu vàng nhạt
rowRange.setBackground('#fff9c4');
} else if (status === 'Đang làm') {
// Đang làm bình thường + tô màu xanh nhạt
rowRange.setBackground('#d1ecf1');
} else {
// Reset về trắng nếu không có điều kiện nào
rowRange.setBackground('#ffffff');
}
}
// Cập nhật timestamp lần cuối chạy
const infoSheet = SpreadsheetApp.getActiveSpreadsheet()
.getSheetByName('Info');
if (infoSheet) {
infoSheet.getRange('B1').setValue(
'Cập nhật lúc: ' + new Date().toLocaleString('vi-VN')
);
}
}
✅ Kết quả:
- • Màu đỏ = task trễ hạn (tự động cập nhật status)
- • Màu vàng cam = hôm nay là deadline
- • Màu vàng nhạt = còn 1-3 ngày
- • Màu xanh nhạt = đang làm, còn nhiều thời gian
- • Màu xanh lá = hoàn thành
5. Automation #3: Gửi Thông Báo Telegram/Slack
Email đôi khi bị bỏ qua. Thông báo qua Telegram/Slack thì không. Script này gửi daily digest vào Telegram group của team mỗi sáng.
5.1 Setup Telegram Bot (5 phút)
-
1
Mở Telegram → tìm @BotFather → gõ
/newbot - 2 Đặt tên bot (ví dụ: "TaskBot_CtyBan") → lấy Bot Token (dạng: 123456789:ABCdef...)
-
3
Add bot vào group Telegram của team → lấy Chat ID bằng cách gọi API:
https://api.telegram.org/bot<TOKEN>/getUpdates - 4 Lưu Token và Chat ID vào Apps Script → chạy function bên dưới
// === AUTOMATION #3: Telegram daily digest ===
const TELEGRAM_TOKEN = 'THAY_BANG_BOT_TOKEN_CUA_BAN';
const TELEGRAM_CHAT_ID = 'THAY_BANG_CHAT_ID_CUA_BAN';
function sendTelegramDailyDigest() {
const sheet = SpreadsheetApp.getActiveSpreadsheet()
.getSheetByName('Tasks');
const data = sheet.getDataRange().getValues();
const today = new Date();
today.setHours(0, 0, 0, 0);
const overdue = [];
const dueToday = [];
const dueSoon = []; // 1-3 ngày
for (let i = 1; i < data.length; i++) {
const taskName = data[i][1];
const assignee = data[i][2];
const deadline = new Date(data[i][3]);
const status = data[i][4];
if (!taskName || status === 'Hoàn thành') continue;
deadline.setHours(0, 0, 0, 0);
const daysLeft = Math.round(
(deadline - today) / (1000 * 60 * 60 * 24)
);
if (daysLeft < 0) {
overdue.push(`❌ ${taskName} - ${assignee} (trễ ${Math.abs(daysLeft)} ngày)`);
} else if (daysLeft === 0) {
dueToday.push(`🔴 ${taskName} - ${assignee}`);
} else if (daysLeft <= 3) {
dueSoon.push(`🟡 ${taskName} - ${assignee} (còn ${daysLeft} ngày)`);
}
}
// Tạo nội dung message
let message = `📊 *DAILY TASK DIGEST*
`;
message += `📅 ${today.toLocaleDateString('vi-VN')}
`;
if (overdue.length > 0) {
message += `*⚠️ TRỄ HẠN (${overdue.length} task):*
`;
message += overdue.join('
') + '
';
}
if (dueToday.length > 0) {
message += `*🔴 HÔM NAY DEADLINE (${dueToday.length} task):*
`;
message += dueToday.join('
') + '
';
}
if (dueSoon.length > 0) {
message += `*🟡 SẮP ĐẾN HẠN (${dueSoon.length} task):*
`;
message += dueSoon.join('
') + '
';
}
if (overdue.length === 0 && dueToday.length === 0 && dueSoon.length === 0) {
message += '✅ Tất cả task đều on track! Tiếp tục cố gắng nhé! 💪';
}
// Gửi qua Telegram API
const url = `https://api.telegram.org/bot${TELEGRAM_TOKEN}/sendMessage`;
const payload = {
chat_id: TELEGRAM_CHAT_ID,
text: message,
parse_mode: 'Markdown'
};
UrlFetchApp.fetch(url, {
method: 'post',
contentType: 'application/json',
payload: JSON.stringify(payload)
});
console.log('Đã gửi Telegram digest thành công');
}
5.2 Thông báo Slack (tương tự)
// === Gửi thông báo Slack qua Incoming Webhook ===
const SLACK_WEBHOOK_URL = 'https://hooks.slack.com/services/THAY_BANG_WEBHOOK_CUA_BAN';
function sendSlackNotification(message) {
const payload = { text: message };
UrlFetchApp.fetch(SLACK_WEBHOOK_URL, {
method: 'post',
contentType: 'application/json',
payload: JSON.stringify(payload)
});
}
// Gọi hàm này khi muốn gửi thông báo
// sendSlackNotification('🔔 Task X đã hoàn thành bởi Nguyễn Văn A');
6. Automation #4: Google Form → Task List Tự Động
Khi nhân viên submit một yêu cầu công việc qua Google Form, script tự động tạo task mới trong Sheets và gửi thông báo xác nhận. Không cần ai nhập tay.
Setup Google Form
Tạo Google Form với các trường:
- Tên công việc cần làm (Short answer)
- Mô tả chi tiết (Paragraph)
- Deadline mong muốn (Date)
- Mức độ ưu tiên: Cao / Trung bình / Thấp (Multiple choice)
- Email người yêu cầu (Short answer)
// === AUTOMATION #4: Form → Task (chạy khi có Form submission) ===
function onFormSubmit(e) {
// e.values là mảng dữ liệu từ Form theo thứ tự cột
const [timestamp, taskName, description,
deadline, priority, requesterEmail] = e.values;
// Mở sheet Tasks
const ss = SpreadsheetApp.getActiveSpreadsheet();
const taskSheet = ss.getSheetByName('Tasks');
const lastRow = taskSheet.getLastRow();
// Tạo Task ID tự động
const taskId = 'TASK-' + String(lastRow).padStart(4, '0');
// Thêm row mới
taskSheet.appendRow([
taskId, // A: Task ID
taskName, // B: Tên task
'', // C: Người phụ trách (chưa assign)
new Date(deadline), // D: Deadline
'Chưa làm', // E: Trạng thái
priority, // F: Ưu tiên
requesterEmail, // G: Email
description // H: Ghi chú
]);
// Gửi email xác nhận cho người yêu cầu
GmailApp.sendEmail(
requesterEmail,
`✅ Đã nhận yêu cầu: ${taskName}`,
`Xin chào,
Yêu cầu công việc của bạn đã được ghi nhận:
Task ID: ${taskId}
Task: ${taskName}
Deadline: ${deadline}
Ưu tiên: ${priority}
Chúng tôi sẽ assign người phụ trách và phản hồi trong vòng 24 giờ.
Trân trọng`
);
// Gửi thông báo Telegram cho team lead
const telegramMsg =
`📥 *YÊU CẦU MỚI*
` +
`ID: ${taskId}
` +
`Task: ${taskName}
` +
`Deadline: ${deadline}
` +
`Ưu tiên: ${priority}
` +
`Từ: ${requesterEmail}`;
sendTelegramDailyDigest(); // Hoặc gọi hàm send riêng
}
⚠️ Quan trọng — Setup trigger cho Form submission:
Trigger này phải được setup từ file Spreadsheet (không phải Form): Apps Script → Triggers → Add Trigger → Function: onFormSubmit → Event source: Spreadsheet → Event type: On form submit
7. Automation #5: Dashboard Auto-Refresh Và Báo Cáo Tuần
Script này tự động tính toán và cập nhật dashboard mỗi giờ, đồng thời tạo báo cáo tuần gửi email cho quản lý mỗi thứ Sáu.
// === AUTOMATION #5: Dashboard refresh + Weekly report ===
function refreshDashboard() {
const ss = SpreadsheetApp.getActiveSpreadsheet();
const taskSheet = ss.getSheetByName('Tasks');
const dashSheet = ss.getSheetByName('Dashboard');
if (!dashSheet) {
console.log('Không tìm thấy sheet Dashboard');
return;
}
const data = taskSheet.getDataRange().getValues();
const today = new Date();
today.setHours(0, 0, 0, 0);
// Đếm theo trạng thái
let stats = {
total: 0,
chuaLam: 0,
dangLam: 0,
choaDuyet: 0,
hoanThanh: 0,
treLan: 0
};
let completedThisWeek = 0;
const weekStart = new Date(today);
weekStart.setDate(today.getDate() - today.getDay()); // Đầu tuần (Chủ nhật)
for (let i = 1; i < data.length; i++) {
if (!data[i][1]) continue; // Bỏ hàng trống
stats.total++;
switch(data[i][4]) {
case 'Chưa làm': stats.chuaLam++; break;
case 'Đang làm': stats.dangLam++; break;
case 'Chờ duyệt': stats.choaDuyet++; break;
case 'Hoàn thành': stats.hoanThanh++; break;
case 'Trễ hạn': stats.treLan++; break;
}
// Đếm hoàn thành trong tuần này
const deadline = new Date(data[i][3]);
if (data[i][4] === 'Hoàn thành' && deadline >= weekStart) {
completedThisWeek++;
}
}
// Cập nhật Dashboard sheet
dashSheet.getRange('B2').setValue(stats.total);
dashSheet.getRange('B3').setValue(stats.dangLam);
dashSheet.getRange('B4').setValue(stats.hoanThanh);
dashSheet.getRange('B5').setValue(stats.treLan);
dashSheet.getRange('B6').setValue(completedThisWeek);
dashSheet.getRange('B7').setValue(
stats.total > 0
? Math.round((stats.hoanThanh / stats.total) * 100) + '%'
: '0%'
);
dashSheet.getRange('B8').setValue(
'Cập nhật: ' + new Date().toLocaleString('vi-VN')
);
console.log('Dashboard đã được refresh:', JSON.stringify(stats));
}
// Gửi báo cáo tuần mỗi thứ Sáu 17:00
function sendWeeklyReport() {
const today = new Date();
if (today.getDay() !== 5) return; // Chỉ chạy vào thứ Sáu
// Refresh dashboard trước
refreshDashboard();
const ss = SpreadsheetApp.getActiveSpreadsheet();
const dashSheet = ss.getSheetByName('Dashboard');
const total = dashSheet.getRange('B2').getValue();
const inProgress = dashSheet.getRange('B3').getValue();
const completed = dashSheet.getRange('B4').getValue();
const overdue = dashSheet.getRange('B5').getValue();
const completedThisWk = dashSheet.getRange('B6').getValue();
const completionRate = dashSheet.getRange('B7').getValue();
const reportBody = `
BÁO CÁO TUẦN - ${today.toLocaleDateString('vi-VN')}
================================================
TỔNG QUAN:
• Tổng task: ${total}
• Đang thực hiện: ${inProgress}
• Hoàn thành: ${completed}
• Trễ hạn: ${overdue}
TUẦN NÀY:
• Task hoàn thành tuần này: ${completedThisWk}
• Tỷ lệ hoàn thành: ${completionRate}
Link Sheets: ${ss.getUrl()}
`.trim();
// Gửi cho quản lý (thay email bên dưới)
GmailApp.sendEmail(
'manager@company.com', // ← Thay email quản lý
`📊 Báo cáo tuần ${today.toLocaleDateString('vi-VN')}`,
reportBody
);
}
8. Setup Triggers — Lịch Chạy Tự Động
Sau khi có tất cả 5 automation trên, bạn cần setup triggers để chúng chạy tự động theo lịch. Đây là cấu hình gợi ý:
| Function | Trigger type | Lịch chạy | Mục đích |
|---|---|---|---|
| sendDeadlineReminders | Time-driven, Daily | 8:00 AM mỗi ngày | Nhắc email deadline |
| autoUpdateTaskStatus | Time-driven, Daily | 7:30 AM mỗi ngày | Cập nhật màu sắc |
| sendTelegramDailyDigest | Time-driven, Daily | 9:00 AM mỗi ngày | Digest sáng cho team |
| onFormSubmit | On form submit | Ngay khi có submission | Tạo task từ Form |
| refreshDashboard | Time-driven, Hourly | Mỗi 1 giờ | Cập nhật dashboard |
| sendWeeklyReport | Time-driven, Daily | 5:00 PM (chỉ chạy T6) | Báo cáo tuần cho manager |
📌 Cách tạo trigger trong Apps Script Editor:
- 1. Click biểu tượng đồng hồ (Triggers) ở sidebar trái
- 2. Click "+ Add Trigger" góc dưới phải
- 3. Chọn Function cần chạy
- 4. Event source: Time-driven
- 5. Type: Day timer / Hour timer / Week timer
- 6. Chọn giờ/ngày → Save
- 7. Google sẽ yêu cầu cấp quyền — Accept để cho phép gửi email, đọc Sheets
9. SheetStore — Template Có Sẵn Automation, Dùng Ngay
Nếu bạn không muốn tự viết code từ đầu, các template quản lý công việc trên SheetStore đã tích hợp sẵn tất cả các automation trên — đã được test kỹ và có hướng dẫn chi tiết.
Template SheetStore đã bao gồm:
Email reminder tự động
Nhắc deadline 1, 3, 7 ngày trước — có thể tùy chỉnh
Dashboard tự cập nhật
Biểu đồ và số liệu tự động refresh theo dữ liệu thực
Màu sắc trạng thái tự động
Visual rõ ràng — đỏ/vàng/xanh theo deadline và status
Báo cáo tuần/tháng
Export báo cáo PDF hoặc gửi email summary tự động
Telegram notification
Digest sáng cho team, alert ngay khi task trễ hạn
Form → Task tự động
Google Form submit → tạo task ngay, xác nhận email
Xem thêm hướng dẫn: Quản lý công việc cho startup từ 2 đến 50 người để hiểu rõ hơn cách kết hợp automation với quy trình quản lý phù hợp từng giai đoạn.
10. FAQ — Câu Hỏi Thường Gặp
Google Apps Script có miễn phí không?
Cần biết lập trình mới dùng được Apps Script không?
Apps Script có thể tích hợp với Zalo không?
Có thể tự động hóa Google Sheets không cần Apps Script không?
Tự động hóa quản lý công việc ngay hôm nay
Template Google Sheets + Apps Script sẵn sàng dùng — email reminder, Telegram notification, dashboard tự động. Không cần viết code.
Tải Template Ngay Xem Bảng Giá📚 Bài Viết Liên Quan
- So Sánh Trello vs Asana vs Notion: Chọn Phần Mềm Quản Lý Công Việc Nào Cho Team?
- Phần Mềm Quản Lý Công Việc Miễn Phí: 7 Lựa Chọn Tốt Nhất Cho Doanh Nghiệp Nhỏ
- Top 10 Phần Mềm Quản Lý Công Việc Tốt Nhất 2026 [So Sánh Chi Tiết]
- Hướng Dẫn Quản Lý Công Việc Bằng Google Sheets: Template Miễn Phí + Hướng Dẫn A-Z
Chia sẻ bài viết:
Tuân Hoang
Đội ngũ SheetStore
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.