Courses
Nhập liệu thủ công là kẻ thù của năng suất. Nếu đội ngũ của bạn phụ thuộc vào việc trích xuất dữ liệu từ các email vận hành như hóa đơn, xác nhận đặt chỗ hoặc biểu mẫu phản hồi khách hàng, hẳn bạn đã quá quen với cơn ác mộng của các phương pháp phân tích cú pháp truyền thống.
Trước đây, các nhà phát triển dựa vào Regular Expressions (Regex) để trích xuất các chi tiết như số hóa đơn hoặc số tiền thanh toán. Nhưng Regex vô cùng mong manh; chỉ cần nhà cung cấp thay đổi mẫu email hoặc thêm một xuống dòng ngẫu nhiên, toàn bộ bộ phân tích sẽ âm thầm hỏng hóc.
Trong hướng dẫn này, tôi sẽ chỉ bạn cách xây dựng một pipeline tự động hoàn toàn, không cần giao diện, giải quyết vấn đề này bằng Generative AI. Chúng ta sẽ viết một script gọn nhẹ đọc các thư Gmail chưa đọc, chuyển văn bản phi cấu trúc sang Gemini API để trích xuất thông minh, và ghi dữ liệu JSON được cấu trúc hoàn hảo trực tiếp vào Google Sheet.
Yêu cầu tiên quyết:
- Một tài khoản Google
- Hiểu biết cơ bản về JavaScript (Google Apps Script)
- Một khóa API Gemini
Google Apps Script là gì?
Google Apps Script là một nền tảng phát triển ứng dụng nhanh trên nền tảng đám mây dựa trên JavaScript, cho phép bạn tự động hóa, tùy biến và mở rộng các ứng dụng Google Workspace như Google Docs, Sheets, Slides, và hơn thế nữa.
Vì nền tảng chạy trực tiếp trên máy chủ của Google, bạn không cần cài đặt phần mềm, cấu hình môi trường cục bộ hoặc quản lý hạ tầng.
Apps Script trao khả năng cho nhà phát triển/nhà phát triển low-code tương tác theo lập trình với các công cụ Google Workspace như Docs, Sheets, Slides, Drive và nhiều hơn nữa. Bạn có thể xây dựng và vận hành tự động hóa thông qua menu tùy chỉnh, nút bấm hoặc lịch chạy theo thời gian, hoặc dùng dịch vụ này để xây dựng và xuất bản add-on lên Google Workspace Marketplace.
Cách Google Apps Script hoạt động
Google Apps Script loại bỏ phần nặng nhọc của cấu hình backend và xác thực API, cho phép bạn tập trung trực tiếp vào logic và dữ liệu. Nó làm điều này thông qua một số tính năng:
- Trình soạn thảo gốc đám mây: Bạn viết, gỡ lỗi và triển khai mã JavaScript hoàn toàn trong IDE dựa trên web ngay trong trình duyệt.
- Dịch vụ tích hợp sẵn: Thay vì vật lộn với OAuth và các lời gọi API phức tạp, bạn dùng các đối tượng toàn cục dựng sẵn (như SpreadsheetApp, MailApp, hoặc DriveApp) để tương tác tự nhiên với các dịch vụ của Google.
- Trigger theo sự kiện: Script có thể được chạy thủ công qua các nút menu tùy chỉnh, hoặc được lập lịch tự động bằng trigger theo thời gian (ví dụ, mỗi nửa đêm) và trigger theo sự kiện (ví dụ, khi người dùng gửi Google Form).
Kiến trúc Google Apps Script: Pipeline từ Gmail đến Sheets
Trước khi viết script, hãy phác thảo cách dữ liệu di chuyển qua pipeline này. Kiến trúc dựa trên bốn thành phần riêng biệt phối hợp với nhau:
- Gmail (Nguồn): Quy trình bắt đầu bằng việc truy vấn hộp thư đến của bạn bằng các toán tử tìm kiếm tiêu chuẩn (như is:unread label:invoices). Script xác định đúng các chuỗi email và trích xuất cả nội dung văn bản thuần và mọi tệp PDF đính kèm.
- Apps Script (Tính toán): Đóng vai trò lớp điều phối. Nó lặp qua các chuỗi chưa đọc, định dạng tệp đính kèm thành dữ liệu base64 và xử lý logic báo lỗi cùng xử lý theo lô.
- Gemini API (Động cơ chuyển đổi): Apps Script gửi payload đa phương thức (văn bản email cộng với các PDF) đến mô hình Gemini 2.5 Flash. Bằng cách truyền một schema phản hồi JSON nghiêm ngặt trong lời gọi API, chúng ta buộc mô hình trích xuất các giá trị chính xác như nhà cung cấp, tổng số tiền và đơn vị tiền tệ, thay vì tạo văn bản đối thoại.
- Google Sheets (Điểm đến): Khi Gemini trả về JSON có cấu trúc, Apps Script phân tích kết quả, gom chúng vào một mảng duy nhất và chèn lô dữ liệu vào hàng trống tiếp theo của bảng tính đang hoạt động bằng setValues().

Vì sao dùng Google Apps Script làm lớp tính toán cho bản dựng này?
Lợi ích chính là loại bỏ hoàn toàn chi phí hạ tầng. Không cần cấp phát máy chủ, và bạn cũng không phải cấu hình container Docker hoặc thiết lập các luồng OAuth phức tạp chỉ để đọc email hay ghi vào bảng tính.
Vì Apps Script tích hợp gốc với các dịch vụ như GmailApp và SpreadsheetApp, Google xử lý xác thực nội bộ. Bạn chỉ cần viết mã và kết nối các điểm cuối.
Bước 1: Chuẩn bị môi trường Google Apps Script
Trước khi viết mã, chúng ta cần chuẩn bị các phụ thuộc bên ngoài. Điều này bao gồm bảo đảm quyền truy cập Gemini API, tạo bảng tính đích và cấu hình hộp thư Gmail để gắn nhãn đúng cho hóa đơn đến.
Tạo khóa API Gemini
Để vận hành trích xuất dữ liệu thông minh, chúng ta cần quyền truy cập Gemini API.
- Đi đến Google AI Studio và đăng nhập bằng tài khoản Google của bạn.
- Trong menu điều hướng bên trái, nhấp vào Get API key.
- Nhấp nút Create API key. Bạn có thể chọn tạo khóa này trong một dự án Google Cloud hiện có hoặc để AI Studio tạo mới cho bạn.
- Sao chép chuỗi được tạo.
Thực hành bảo mật tốt: Đừng làm mất khóa này, nhưng quan trọng hơn, đừng dự định hardcode nó ở dạng văn bản thuần trong mã của bạn. Hãy giữ nó trên clipboard hoặc trong một ghi chú an toàn; ở bước tiếp theo, chúng ta sẽ khóa nó an toàn trong môi trường Apps Script.

Chuẩn bị Google Sheet và bảo mật khóa
Chúng ta cần nơi để lưu dữ liệu trích xuất. Trang tính này cũng sẽ là bệ phóng cho script tự động của chúng ta.
1. Thiết lập tiêu đề cơ sở dữ liệu Tạo một Google Sheet trống mới. Ở hàng đầu tiên, tạo các tiêu đề cột sau để khớp với schema JSON chúng ta sẽ định nghĩa trong script:
- Date
- Vendor
- Invoice Number
- Total Amount
- Currency
- Items Summary
- Email Link
Đóng băng hàng trên cùng để tiêu đề luôn hiển thị khi dữ liệu của bạn tăng lên.

2. Truy cập Apps Script và lưu khóa API Bây giờ trang tính đã tồn tại, chúng ta có thể mở trình chỉnh sửa Apps Script trực tiếp từ đó. Điều này tự động liên kết mã của chúng ta với bảng tính cụ thể này.
- Trong Google Sheet của bạn, nhấp Extensions > Apps Script từ menu trên cùng.

- Khi trình chỉnh sửa mở ra, hãy nhìn thanh bên trái và nhấp biểu tượng bánh răng để mở Project Settings.

- Cuộn xuống cuối để tìm phần Script Properties.
- Nhấp Add script property.
- Trong mục Property, nhập chính xác
GEMINI_API_KEY. - Trong mục Value, dán khóa API bạn đã sao chép từ AI Studio trước đó.
- Nhấp Save script properties.

Mã chúng ta viết sau này sẽ truy xuất giá trị này một cách an toàn khi chạy mà không làm lộ thông tin xác thực của bạn.
Bước 2: Viết mã Google Apps Script
Khi bạn đang ở trong trình chỉnh sửa Apps Script, hãy xóa bất kỳ mã mặc định nào. Chúng ta sẽ xây dựng động cơ tự động hóa theo từng khối.
1. Cấu hình và thiết lập giao diện
Chúng ta bắt đầu bằng cách định nghĩa một đối tượng cấu hình toàn cục. Đây là thực hành mã sạch giúp nhóm tất cả biến hardcode vào một nơi, để bạn chỉ cần chỉnh sửa khối trên cùng này.
Chúng ta cũng thêm hàm onOpen(). Trigger tích hợp sẵn của Apps Script này tự động tạo một menu tùy chỉnh trong Google Sheet, cho phép người dùng không chuyên kỹ thuật chạy script thủ công mà không cần mở trình chỉnh sửa mã.
const CONFIG = {
searchQuery: "is:unread label:invoices",
model: "gemini-2.5-flash",
adminEmail: Session.getActiveUser().getEmail() // Automatically emails the script owner if it crashes
};
/**
* Creates a custom menu in Google Sheets so non-technical users can run the script manually.
*/
function onOpen() {
const ui = SpreadsheetApp.getUi();
ui.createMenu('🤖 AI Automations')
.addItem('Fetch New Invoices', 'processInvoices')
.addToUi();
}
2. Thiết lập điều phối
Hàm processInvoices() đóng vai trò dàn nhạc chính. Nó bắt đầu bằng cách kéo khóa API của bạn một cách an toàn từ Script Properties mà chúng ta đã thiết lập trước đó.
Sau đó, nó sử dụng dịch vụ tích hợp GmailApp để truy vấn hộp thư đến của bạn.
Bằng cách gọi GmailApp.search(CONFIG.searchQuery), script truy xuất một mảng các chuỗi email khớp với quy tắc is:unread label:invoices.
Nếu tìm thấy khớp, nó sẽ lặp qua từng chuỗi, lấy email mới nhất, trích xuất nội dung văn bản thuần và tách riêng mọi tệp PDF đính kèm.
function processInvoices() {
const apiKey = PropertiesService.getScriptProperties().getProperty("GEMINI_API_KEY");
if (!apiKey) {
throw new Error("GEMINI_API_KEY is missing! Please set it in Script Properties.");
}
const threads = GmailApp.search(CONFIG.searchQuery);
if (threads.length === 0) return;
const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
const batchData = [];
const processedThreads = [];
3. Xử lý email và PDF đa phương thức
Khi lặp qua các chuỗi email, chúng ta lấy thư mới nhất. Tuy nhiên, hóa đơn hiếm khi đến dưới dạng văn bản thuần; chúng gần như luôn được đính kèm dưới dạng PDF.
Bằng cách tận dụng Gemini 2.5 Flash, vốn đa phương thức nguyên bản, script của chúng ta lặp qua latestMessage.getAttachments(), lấy mọi PDF, chuyển đổi chúng thành chuỗi Base64 và chuyển trực tiếp vào payload API dưới dạng inlineData.
Gemini “đọc” PDF bằng trực quan và trích xuất dữ liệu dễ dàng như đọc văn bản.
for (let i = 0; i < threads.length; i++) {
const thread = threads[i];
const latestMessage = thread.getMessages().pop();
const emailBody = latestMessage.getPlainBody();
const emailDate = latestMessage.getDate();
const emailLink = https://mail.google.com/mail/u/0/#inbox/${thread.getId()};
const attachments = latestMessage.getAttachments();
try {
const geminiParts = [];
geminiParts.push({ text: "Extract invoice details from this email and any attached documents:\n\n" + emailBody });
// Add PDF attachments as base64 to the prompt
for (const attachment of attachments) {
if (attachment.getContentType() === "application/pdf") {
geminiParts.push({
inlineData: {
mimeType: "application/pdf",
data: Utilities.base64Encode(attachment.getBytes())
}
});
}
}
// Invoke Gemini API
const extractedData = callGeminiAPI(apiKey, geminiParts);
4. Chèn theo lô và xử lý lỗi
Để tối ưu hiệu năng, chúng ta không ghi vào bảng tính từng hàng một.
Thay vào đó, chúng ta đẩy dữ liệu JSON đã trích xuất vào một mảng (batchData) và ghi tất cả cùng lúc ở cuối bằng setValues().
Lưu ý khối try...catch.
Nếu Gemini “ảo tưởng” hoặc lỗi trên một email cụ thể, script sẽ không sập hoàn toàn. Thay vào đó, nó bắt lỗi một cách mềm mại và dùng MailApp.sendEmail() để cảnh báo quản trị viên ngay lập tức, đảm bảo khả năng quan sát cao.
// Push to batch array instead of writing one-by-one
batchData.push([
emailDate,
extractedData.vendor || "Unknown Vendor",
extractedData.invoiceNumber || "N/A",
extractedData.totalAmount || 0.00,
extractedData.currency || "USD",
extractedData.itemsSummary || "N/A",
emailLink
]);
processedThreads.push(thread);
} catch (error) {
MailApp.sendEmail(CONFIG.adminEmail, "🚨 Invoice Pipeline Error", error.toString());
}
}
// Batch Write to Sheets
if (batchData.length > 0) {
const lastRow = Math.max(sheet.getLastRow(), 1);
sheet.getRange(lastRow + 1, 1, batchData.length, batchData[0].length).setValues(batchData);
}
// Mark all processed threads as read so they aren't parsed again
processedThreads.forEach(t => t.markRead());
}
Cuối cùng, script gọi thread.markRead() cho mọi email đã xử lý. Điều này đảm bảo lần chạy tiếp theo, script sẽ bỏ qua hoàn toàn các email này và chỉ tìm email mới.
5. Hàm trợ giúp Gemini API (chế độ JSON)
Khi gọi LLM, các nhà phát triển thường dùng kỹ thuật Prompt như "Trả về một khối JSON". Tuy nhiên, các mô hình thường phản hồi kèm “lời dẫn” đối thoại (ví dụ: "Chắc chắn rồi, đây là dữ liệu của bạn: [JSON]"), khiến các bộ phân tích JSON phía sau bị lỗi.
Bằng cách đặt responseMimeType: "application/json" và cung cấp một responseSchema nghiêm ngặt, chúng ta buộc Gemini REST API chỉ trả về một đối tượng JSON đảm bảo chứa đúng các tiêu đề cột bảng tính của chúng ta.
function callGeminiAPI(apiKey, partsArray) {
const url = https://generativelanguage.googleapis.com/v1beta/models/${CONFIG.model}:generateContent?key=${apiKey};
const responseSchema = {
type: "OBJECT",
properties: {
vendor: { type: "STRING" },
invoiceNumber: { type: "STRING" },
totalAmount: { type: "NUMBER" },
currency: { type: "STRING" },
itemsSummary: { type: "STRING" }
},
required: ["vendor", "totalAmount"]
};
const payload = {
contents: [{ parts: partsArray }],
generationConfig: {
responseMimeType: "application/json",
responseSchema: responseSchema
}
};
const options = {
method: "POST",
contentType: "application/json",
payload: JSON.stringify(payload),
muteHttpExceptions: true
};
const response = UrlFetchApp.fetch(url, options);
const jsonResponse = JSON.parse(response.getContentText());
return JSON.parse(jsonResponse.candidates[0].content.parts[0].text);
}
Bước 3: Tự động hóa pipeline Google Apps Script của bạn
Mã chỉ có giá trị khi nó giúp cuộc sống bạn dễ dàng hơn.
Google Apps Script cung cấp các môi trường thực thi mạnh mẽ, từ các nút tương tác hướng tới người dùng đến các cron job chạy nền hoàn toàn không giao diện.
Phương pháp 1: Kích hoạt qua giao diện bảng tính
Nếu bạn xây dựng công cụ này cho đội kế toán không chuyên kỹ thuật, họ có lẽ không muốn mở trình chỉnh sửa mã Apps Script chỉ để xử lý hóa đơn hôm nay.
Nhờ chúng ta đã bao gồm hàm onOpen() trong mã, Apps Script tự động gắn một menu tùy chỉnh trực tiếp vào giao diện Google Sheets mỗi khi bảng tính được mở.
- Quay lại Google Sheet và làm mới trang.
- Chờ vài giây, và nhìn thanh menu trên cùng. Bạn sẽ thấy một menu thả xuống mới tên là 🤖 AI Automations.
- Nhấp vào đó và chọn Fetch New Invoices.

- Lần đầu bạn chạy, Google sẽ yêu cầu bạn ủy quyền cho script (để đọc Gmail và gửi email thay bạn). Sau khi ủy quyền, script sẽ chạy theo thời gian thực. Bạn có thể xem dữ liệu JSON trích xuất đổ vào các hàng ngay trước mắt!
Phương pháp 2: Tự động hóa không giao diện qua trigger theo thời gian
Nếu bạn muốn tự động hóa đúng nghĩa thiết lập một lần rồi quên đi, bạn có thể dùng Time-Driven Triggers gốc để chạy pipeline tự chủ ở chế độ nền.
- Trong trình chỉnh sửa Apps Script, nhấp Triggers (biểu tượng Đồng hồ) ở thanh bên trái.

- Nhấp Add Trigger ở góc dưới bên phải.

- Đặt hàm thành processInvoices.
- Chuyển nguồn sự kiện sang Time-driven và đặt chạy theo giờ (ví dụ, mỗi 6 giờ).
- Nhấp Lưu.

Pipeline AI không giao diện của bạn giờ đã hoàn toàn tự động.
Ngay cả khi máy tính của bạn tắt hoàn toàn, máy chủ của Google vẫn sẽ thức dậy mỗi sáu giờ, quét hộp thư đến, phân tích hóa đơn qua Gemini, ghi dữ liệu vào Sheets, rồi quay lại trạng thái ngủ.
Bạn có thể theo dõi thành công hay thất bại của các lần thực thi nền này bằng cách nhấp tab Executions trong trình chỉnh sửa Apps Script để xem log.
Bước 4: Kiểm thử trích xuất dữ liệu AI
Giờ khi mã đã sẵn sàng, chúng ta cần kiểm thử để đảm bảo pipeline trích xuất hoạt động như mong đợi.
Hãy xem hai kịch bản thực tế để thấy Gemini API xử lý các định dạng dữ liệu khác nhau ra sao và phản hồi thực tế trông như thế nào.
Kiểm thử 1: Trích xuất email văn bản thuần
Đầu tiên, chúng ta sẽ thử một hóa đơn được nhúng trực tiếp trong nội dung email.
- Tự gửi cho mình một email với tiêu đề "Invoice INV-2023-88493".
- Trong nội dung, viết văn bản phi cấu trúc như: "Chào đội, vui lòng thanh toán cho Acme Corp 450,00 USD cho giấy phép phần mềm quý 3."
- Áp dụng nhãn invoices cho email và đảm bảo nó vẫn chưa đọc.

- Chạy script qua menu tùy chỉnh.

Ở hậu trường, Gemini nhận văn bản phi cấu trúc này và tuân thủ nghiêm ngặt schema JSON của chúng ta.
Thay vì phản hồi với lời dẫn đối thoại, nó trả về một payload thô.
Vì phản hồi là JSON có cấu trúc hoàn hảo, mảng batchData.push() của chúng ta đọc mượt extractedData.totalAmount và ghi 6550 thẳng vào Google Sheet mà không cần bất kỳ logic Regex phức tạp nào.

Kiểm thử 2: Trích xuất từ tệp đính kèm PDF
Tiếp theo, hãy thử sức mạnh thực sự của Gemini 2.5 Flash bằng cách gửi cho nó một tài liệu PDF.
- Tạo hoặc tải về một hóa đơn PDF mẫu (ví dụ, 20.700,00 USD từ ProTech Cloud Services).
- Tự gửi email cho mình với tài liệu PDF đính kèm. Bạn có thể để nội dung email hoàn toàn trống!
- Áp dụng nhãn invoices và đánh dấu chưa đọc.

- Chạy script. Pipeline sẽ phát hiện tệp đính kèm, chuyển nó thành Base64, và Gemini sẽ đọc trực quan tài liệu để trích xuất nhà cung cấp và tổng số tiền.

Đây là lúc kiến trúc chứng tỏ giá trị.
Bạn không phải viết logic OCR (Nhận dạng ký tự quang học) tùy chỉnh, quản lý một thư viện phân tích PDF riêng, hoặc viết biểu thức chính quy để tìm tổng số tiền.
LLM xử lý dữ liệu trực quan phi cấu trúc một cách nguyên bản.
Kết luận
Tự động hóa quy trình công việc kinh doanh không đòi hỏi phải quản lý hạ tầng cồng kềnh hay vật lộn với các vòng lặp ủy quyền phức tạp.
Bằng cách kết hợp Google Apps Script với Gemini API, chúng ta đã xây dựng một pipeline dữ liệu thông minh, không máy chủ, chạy hoàn toàn trong hệ sinh thái đám mây mà bạn đã sử dụng hằng ngày.
Điểm mạnh của kiến trúc này nằm ở sự đơn giản. Thay vì cấp phát máy chủ, cấu hình webhook hoặc quản lý tệp thông tin xác thực an toàn trên máy chủ ngoài, Apps Script xử lý ngữ cảnh, xác thực và thực thi một cách nguyên bản.
Trong khi đó, Gemini loại bỏ nhu cầu về biểu thức chính quy mong manh hoặc phần mềm OCR đắt đỏ, biến các nội dung email lộn xộn và PDF phi cấu trúc thành các hàng cơ sở dữ liệu dự đoán được chỉ với một lời gọi API.
Để nâng cao kỹ năng và khám phá thêm những gì bạn có thể xây dựng với quyền truy cập lập trình vào LLM, tôi khuyến nghị xem Giới thiệu về API trong Python của DataCamp hoặc đào sâu vào thiết kế quy trình làm việc thông minh với khóa học AI Agent Fundamentals .
Tôi viết và sáng tạo trên internet. Chuyên gia Nhà phát triển Google (GDE) cho Google Workspace, tốt nghiệp Khoa học Máy tính tại NMIMS, và là người đam mê xây dựng trong lĩnh vực tự động hóa và Trí tuệ nhân tạo sinh tạo.
