Khoảng một năm trước, Khánh đã bán template sử dụng Gemini trên Google Sheet với giá 300k. Lúc đó, mình dùng ChatGPT code, nhưng ở thời điểm đó ChatGPT chưa thông minh như bây giờ nên tiện ích còn khá thô sơ, gần như không có giao diện gì cả. Tuy nhiên, lợi thế lớn là Google miễn phí API gần như không giới hạn tốc độ, trong khi API của ChatGPT lại tăng giá mạnh, nên anh em ủng hộ rất nhiệt tình.
Bây giờ, Gemini vẫn miễn phí API, nhưng đã có giới hạn nên không còn “ngon” như trước. Hơn nữa, việc dùng ChatGPT để code đã trở nên quá phổ biến, không còn là “bí kíp” hay “tutorial” độc quyền nữa. Vì vậy, hôm nay KDigital quyết định chia sẻ miễn phí code sử dụng Gemini không giới hạn trên Google Sheet mọi người, đặc biệt là các startup. Dĩ nhiên, phiên bản mới này đã được nâng cấp đáng kể cả về tính năng lẫn giao diện, giúp anh em sử dụng dễ dàng và hiệu quả hơn.
Mình cũng muốn gửi lời cảm ơn đến Đức Lương – giám đốc Ruby Home Việt Nam, cũng là một người bạn cấp 2 của mình đang trong quá trình khởi nghiệp. Chính bạn ấy đã gợi ý mình hoàn thành bài viết này. Phần giới thiệu đã hơi dài, giờ thì chúng ta cùng đi vào nội dung chính của bài viết!

Những ưu điểm khi sử dụng Gemini trên Google Sheet
Nếu bạn đang tìm cách tích hợp AI vào Google Sheet để xử lý công việc nhanh chóng, thì Gemini API là một lựa chọn cực kỳ đáng cân nhắc. Dưới đây là những lợi ích nổi bật:
API miễn phí, gần như không giới hạn
Gemini API hiện tại vẫn miễn phí, dù có giới hạn nhất định cho tài khoản freee. Tuy nhiên, bạn hoàn toàn có thể xoay vòng nhiều tài khoản Google, tạo nhiều Project để lấy khóa API, từ đó sử dụng luân phiên mà không sợ bị giới hạn.
Tích hợp thành công thức Google Sheet – tự động hóa siêu tiện lợi
Với Gemini, bạn có thể sử dụng AI ngay trong Google Sheet thông qua công thức đơn giản. Chỉ cần nhập công thức một lần, rồi kéo thả xuống hàng loạt ô để xử lý dữ liệu nhanh chóng. Ví dụ, bạn muốn viết thơ về 12 con giáp? Chỉ cần nhập danh sách con giáp vào cột A, rồi dùng công thức AI ở cột B – thế là AI tự động sáng tác giúp bạn!
Sử dụng những mô hình AI mới nhất của Google
Template sử dụng Gemini trên Google Sheet mới này không chỉ hỗ trợ các model Gemini mới nhất, mà còn tích hợp cả các mô hình thử nghiệm của Google. Bạn sẽ được trải nghiệm những model AI tiên tiến nhất, giúp xử lý nội dung thông minh hơn, chính xác hơn. Nếu bạn muốn tận dụng sức mạnh AI ngay trong Google Sheet mà không tốn phí, thì đây chính là giải pháp tuyệt vời!

Giới hạn tốc độ khi sử dụng Gemini trên Google Sheet
Khi sử dụng Gemini trên Google Sheet, bạn cần lưu ý đến các giới hạn về tốc độ và số lượng yêu cầu để tránh gặp lỗi. Các giới hạn này được đo lường theo bốn phương diện chính:
- Số yêu cầu mỗi phút (RPM): Giới hạn số lượng yêu cầu có thể gửi đi trong một phút.
- Số yêu cầu mỗi ngày (RPD): Giới hạn số lượng yêu cầu có thể gửi trong một ngày.
- Số mã thông báo mỗi phút (TPM): Giới hạn số lượng mã thông báo xử lý trong một phút.
- Số hình ảnh mỗi phút (IPM): Chỉ áp dụng cho các mô hình có khả năng tạo hình ảnh.
Nếu vượt quá bất kỳ giới hạn nào, hệ thống sẽ kích hoạt lỗi giới hạn tốc độ. Ví dụ, nếu giới hạn RPM là 20, nhưng bạn gửi 21 yêu cầu trong một phút, hệ thống sẽ báo lỗi ngay cả khi bạn chưa vượt quá TPM hoặc RPD.
Lưu ý rằng các giới hạn này được áp dụng theo từng dự án chứ không phải theo khóa API. Bên cạnh đó, mỗi mô hình Gemini có giới hạn khác nhau. Một số giới hạn tiêu biểu của các mô hình hiện tại:
Mẫu | RPM | TPM | RPD |
---|---|---|---|
Gemini 2.0 Flash | 15 | 1.000.000 | Tăng 1.500 |
Gemini 2.0 Flash-Lite | 30 | 1.000.000 | Tăng 1.500 |
Gemini 2.0 Pro Experimental 02-05 | 2 | 1.000.000 | 50 |
Gemini 2.0 Flash Thinking Experimental 01-21 | 10 | 4.000.000 | Tăng 1.500 |
Gemini 1.5 Flash | 15 | 1.000.000 | Tăng 1.500 |
Gemini 1.5 Flash-8B | 15 | 1.000.000 | Tăng 1.500 |
Gemini 1.5 Pro | 2 | 32.000 | 50 |
>>> Xem thêm và cập nhật giới hạn API Gemini tại: https://ai.google.dev/gemini-api/docs/rate-limits?hl=vi
Mặc dù đây là những con số do Google công bố, nhưng thực tế còn một yếu tố khác mà Google không đề cập: server tương ứng với từng region. Khi dùng API qua Vertex AI, có thể thấy dù sử dụng hàng trăm API cùng lúc, thì mỗi region cũng chỉ xử lý được khoảng 15 request/phút. Và bởi vì chúng ta đang chạy ứng dụng trên Apps Script của Google, nó chỉ được tính là một region nên tối đa mỗi phút bạn cũng chỉ có thể gọi API 15 lần.
Ý tưởng và cơ chế sử dụng Gemini trên Google Sheet
Chúng ta sẽ sử dụng Apps Script của Google để kết nối với API Gemini, giúp việc gọi AI trở nên dễ dàng ngay trong Google Sheet.
Cơ chế hoạt động
- Tạo một hàm tùy chỉnh có tên
GeminiAI()
, trong đó tham số đầu vào là prompt. - Khi nhập công thức vào ô trong Google Sheet, hàm này sẽ tự động gửi request đến API Gemini và trả về kết quả ngay trong ô đó.
Lựa chọn mô hình AI
Gemini cung cấp nhiều mô hình khác nhau, mỗi mô hình có ưu nhược điểm riêng. Vì vậy, chúng ta sẽ tạo một Menu Settings để chọn mô hình sử dụng mặc định. Người dùng có thể tùy chỉnh mô hình sao cho phù hợp với từng nhu cầu cụ thể.
- Mô hình Gemini: https://ai.google.dev/gemini-api/docs/models/gemini?hl=vi
- Mô hình thử nghiệm: https://ai.google.dev/gemini-api/docs/models/experimental-models?hl=vi
Cơ chế xoay vòng khóa API
- Trong Cài đặt, chúng ta sẽ nhập nhiều khóa API, phân tách bằng dấu “, “.
- Các khóa này sẽ được lưu vào một mảng, và mỗi lần gọi API, hệ thống sẽ luân phiên sử dụng từng khóa.
- Việc này giúp tránh giới hạn request theo ngày (RPD) hoặc theo phút (RPM), đặc biệt hữu ích với các mô hình có giới hạn thấp như Gemini 1.5 Pro.
- Tuy nhiên, cách này không thể vượt qua giới hạn request tối đa theo từng region, như đã đề cập trước đó.
Với cách tiếp cận này, chúng ta có thể khai thác tối đa sức mạnh của Gemini trên Google Sheet mà không lo bị giới hạn quá nhiều! Mình đã tạo ra một template Google Sheet theo cơ chế trên để bạn chỉ việc sao chép và sử dụng. Hãy đến với những hướng dẫn sử dụng chi tiết ở phần tiếp theo của bài viết.
Hướng dẫn sử dụng Gemini trên Google Sheet
Bước 1: Lấy khoá API Gemini miễn phí từ Google
Để sử dụng Gemini trên Google Sheet, trước tiên bạn cần có khoá API Gemini từ Google, chỉ cần có tài khoản Gmail bạn có thể đăng kí tài khoản này hoàn toàn miễn phí.
Truy cập: https://aistudio.google.com/apikey > Get API Key > Tích chọn để đồng ý với các điều khoản của Google sau đó nhấn Tiếp tục > Create API Key > Gemini API > Nhấn vào Copy để sao chép khoá API và lưu tạm thời vào một chỗ khác.


Một tài khoản Google cũng có thể tạo nhiều khoá API bằng cách tạo nhiều project (tối đa 12 dự án). Bạn có thể tạo Project tại: https://console.cloud.google.com/projectcreate.

Sau khi tạo xong project bạn quay trở lại đường link https://aistudio.google.com/apikey > Chọn Create API Key > Chọn dự án bạn vừa tạo (nếu chưa có thì reload lại trang) > Gemini API > Nhấn vào Copy để sao chép khoá API và lưu tạm thời vào một chỗ khác.
Lưu ý rằng các giới hạn API được áp dụng theo từng dự án (project) chứ không phải theo khóa API. Nên trong một project bạn tạo nhiều khoá API sẽ không có tác dụng tăng giới hạn API khi dùng trong Google Sheet nên bắt buộc phải tạo nhiều dự án, mỗi dự án tạo một khoá API (chi tiết xem tại video Youtube bên dưới).
Nếu bạn muốn tạo nhiều trang tính khác nhau, các trang tính hoạt động riêng rẽ để có thể sử dụng API nhiều hơn, hãy sử dụng nhiều tài khoản Google, mỗi tài khoản tạo full 12 dự án. Mỗi dự án tạo một 1 khoá API. Như thế là bạn sẽ có 12 khoá API dùng cho một trang tính.
Cách làm nhanh nhất là bạn mua khoá API tại Tạp Hoá MMO theo đường link sau: https://taphoammo.net/gian-hang/api-key-gemini_650110. Với mỗi khoá API chưa tới 2 nghìn đồng, bạn mua khoảng 50 nghìn là sử dụng tẹt tèn ten.

Bước 2: Tải template và cấp quyền để sử dụng Gemini trên Sheet
1. Truy cập đường link sau để tạo bản sao template sheet mẫu: https://ngophungkhanh.com/template-google-sheet-use-gemini > Nhấn vào Tạo một bản sao

2. Sau khi đã tạo bản sao, bạn sẽ được chuyển đến trang tính Sheet, tìm đến Gemini trên thanh công cụ, nếu chờ một lúc không thấy hiển thị bạn hãy reload lại trang. Bấm vào Gemini > Cài đặt Model.

3. Ở lần đầu tiên chạy tiện ích, bạn sẽ cần phải uỷ quyền để tập lệnh đính kèm với tài liệu có thể chạy. Chọn OK > Chọn tài khoản Google bất kì để cấp quyền > Nâng cao > Đi tới GeminiAI (không an toàn) > Chọn Cho phép.



Điều này sẽ cho phép GeminiAI làm những việc sau:
- Xem, chỉnh sửa, tạo và xóa tất cả bảng tính của bạn trên Google Trang tính
- Kết nối với dịch vụ bên ngoài
- Hiển thị và chạy nội dung web bên thứ ba trong lời nhắc và thanh bên ở trong các ứng dụng của Google
4. Sau khi bạn đã thực hiện đầy đủ các bước trên, giao diện cài đặt sẽ hiển thị. Nhập danh sách khoá API của bạn các khoá API cách nhau bởi dấu ‘, ‘. Ví dụ:
AIzaSyAa3TC70Ii-vwRWxOMnSkJJ0cIOk3qbMTk, AIzaSyD0WY_6wdO9ZKNZT0tGy5I666iSWjjZ_RA, AIzaSyAa3TC70Ii-vwRWxOMnSkJJ0cIJk5qbMTk, AIzaSyD0WY_6wdO9ZKNZT0tGy5I666iSWjjhyeI
5. Chọn Model Gemini mà bạn muốn sử dụng. Danh sách các model chính thức và thử nghiệm của Gemini, các thông tin như: mã mô hình, tên, tính năng, giới hạn token, ngày cập nhật xem tại:
- Mô hình thử nghiệm: https://ai.google.dev/gemini-api/docs/models/experimental-models?hl=vi
- Mô hình Gemini: https://ai.google.dev/gemini-api/docs/models/gemini?hl=vi

6. Nhấn vào Lưu cấu hình để lưu các giá trị bạn đã nhập. Chờ một lúc để tiện ích chạy và hiển thị thông báo “Cấu hình đã được lưu thành công!”. Nếu bạn không thấy hiển thị thông báo hãy nhấn vào Lưu cấu hình nhiều lần đến khi hiển thị thông báo. Tắt thông báo và nhấn vào dấu x để ẩn hộp thoại cài đặt.
Như vậy là bạn đã hoàn thành cấu hình cho API. Tiện ích có chức năng lưu cache giá trị khoá API và model đã cài đặt nên khi reload trang hay lần sau truy cập lại bạn không cần phải mở Settings để điền các giá trị này nữa, trừ khi bạn muốn thay đổi khoá API và mô hình Gemini.
Bước 3: Cách sử dụng công thức GeminiAI() trên Google Sheet
Nhập công thức GeminiAI()
vào một ô bất kì. Bạn có thể truyền vào tham số là giá trị văn bản trong một ô bất kì, trong nhiều ô thì sử dụng dấu & để nối văn bản trong nhiều ô thành một Prompt. Hoặc có thể truyền vào tham số là văn bản đặt trong cặp dấu “”.
- Ví dụ 1: Nhập hàm = GeminiAI(“cách làm bánh chưng ngày Tết”) vào ô A1
- Ví dụ 2: Tại A1 bạn có văn bản là “cách làm bánh chưng”. Ở B1 bạn sẽ nhập công thức là: = GeminiAI(A1). Công thức này tương đương với công thức ở ví dụ 1: = GeminiAI(“cách làm bánh chưng ngày Tết”)
- Ví dụ 3: Tại A1 bạn có văn bản là “Viết cho tôi một bài viết trên blog hoàn chỉnh cho từ khoá: “. Tại B1 bạn có văn bản là “cách làm bánh chưng”. Ở C1 bạn sẽ nhập công thức là: = GeminiAI(A1 & B1). Công thức này tương đương với = GeminiAI(“Viết cho tôi một bài viết trên blog hoàn chỉnh cho từ khoá: cách làm bánh chưng).
- Ví dụ 4: Tại A1 bạn có văn bản là “Viết cho tôi một bài viết trên blog hoàn chỉnh cho từ khoá: “. Ở C1 bạn sẽ nhập công thức = GeminiAI(A1 & “cách làm bánh chưng”). Công thức này tương đương với = GeminiAI(“Viết cho tôi một bài viết trên blog hoàn chỉnh cho từ khoá: cách làm bánh chưng).
Bạn có thể nhập danh sách từ khoá trong cột A sau đó nhập công thức ở cột B, kéo thả công thức để áp dụng công thức cho cả cột B. Tuy nhiên vì giới hạn của API bạn nên chỉ áp dụng mỗi lần 10 hàng công thức, chờ nó chạy xong và trả về hết kết quả mới tiếp tục áp dụng công thức cho các hàng kế tiếp.

Các lỗi thường gặp khi sử dụng Gemini trên Google Sheet và cách khắc phục
Lỗi phổ biến nhất khi sử dụng hàm GeminiAI()
là trả về giá trị khi thực hiện nhiều công thức cùng một lúc:
Lỗi API (HTTP 429): {
"error": {
"code": 429,
"message": "Resource has been exhausted (e.g. check quota).",
"status": "RESOURCE_EXHAUSTED"
}
}
Lỗi này báo hiệu rằng bạn đã vượt quá hạn mức sử dụng tài nguyên của API. Nghĩa là bạn không thể truy cập hoặc sử dụng API thêm cho đến khi hạn mức được làm mới hoặc tăng lên. Lỗi này là do giới hạn sử dụng API trên phút như đã được trình bày ở phía trên.
Để khắc phục, ô nào lỗi bạn chỉ cần thêm một dấu cách vào trong công thức hoặc văn bản để sheet hiểu rằng bạn đã nhập lại một công thức mới.
Ngoài ra bạn còn có thể gặp lỗi:
Lỗi API (HTTP 400): {
"error": {
"code": 400,
"message": "API key not valid. Please pass a valid API key.",
"status": "INVALID_ARGUMENT",
"details": [
{
"@type": "type.googleapis.com/google.rpc.ErrorInfo",
"reason": "API_KEY_INVALID",
"domain": "googleapis.com",
"metadata": {
"service": "generativelanguage.googleapis.com"
}
},
{
"@type": "type.googleapis.com/google.rpc.LocalizedMessage",
"locale": "en-US",
"message": "API key not valid. Please pass a valid API key."
}
]
}
}
Lỗi này xảy ra khi bạn nhập sai giá trị khoá API hoặc khoá API cũ đã bị xoá, hãy xem lại cài đặt để đảm bảo bạn đã nhập đúng định dạng khoá API. Các khoá cần được cách nhau bởi dấu phẩy và một dấu cách, ví dụ:
AIzaSyAa3TC70Ii-vwRWxOMnSkJJ0cIOk3qbMTk, AIzaSyD0WY_6wdO9ZKNZT0tGy5I666iSWjjZ_RA, AIzaSyAa3TC70Ii-vwRWxOMnSkJJ0cIJk5qbMTk, AIzaSyD0WY_6wdO9ZKNZT0tGy5I666iSWjjhyeI
Ngoài 2 lỗi phổ biến trên có thể còn nhiều lỗi nữa trong quá trình sử dụng, khi gặp lỗi bạn có thể liên hệ với Khánh, mình sẽ hỗ trợ giúp bạn khắc phục lỗi và cập nhật vào bài viết này.
Video Youtube hướng dẫn chi tiết cách dùng Gemini trên Google Sheet
Như bạn thấy, bài viết này khá dài và chi tiết. Mình đã dành cả ngày để hoàn thành với mong muốn giúp các bạn newbie – những người chưa từng tiếp xúc với những kiến thức này – có thể dễ dàng đọc và làm theo.
Để hỗ trợ tốt hơn, mình đã chuẩn bị một video hướng dẫn toàn bộ quá trình chỉ trong 10 phút. Bạn có thể vừa đọc bài viết, vừa xem video để dễ hình dung và hiểu rõ hơn. Còn với những bạn đã có nền tảng về Apps Script và API, mình nghĩ chỉ cần xem nhanh video hoặc đọc lướt bài viết là đã đủ để thực hành ngay.
Source code Java Script đầy đủ cho bạn nào muốn chỉnh sửa hoặc học hỏi thêm
Nếu bạn chỉ cần sử dụng Gemini trên Google Sheet một cách đơn giản, thì những hướng dẫn trên là quá đủ. Nhưng nếu bạn là người thích khám phá AI và lập trình như mình, muốn tùy chỉnh giao diện, mở rộng tính năng, hoặc cập nhật các model Gemini mới nhất trong tương lai, thì dưới đây là source code chi tiết dành cho bạn.
Bạn có thể đưa đoạn code này cho ChatGPT để nhờ giải thích, từ đó hiểu thêm về lập trình Apps Script. Sau đó, bạn cũng có thể nhờ AI tùy chỉnh theo ý muốn để phù hợp với nhu cầu cá nhân.
Cách sử dụng code:
- Mở một trang tính Google Sheet mới (bạn có thể truy cập nhanh bằng cách nhập sheet.new vào thanh địa chỉ trình duyệt).
- Trên thanh công cụ, chọn Tiện ích > Apps Script.
- Khi giao diện Code.js hiện ra, hãy xóa toàn bộ code mặc định và thay thế bằng đoạn code dưới đây.
/**
* Khi mở bảng tính, thêm menu “Gemini” để mở sidebar cài đặt.
*/
function onOpen() {
SpreadsheetApp.getUi()
.createMenu("Gemini")
.addItem("Cài đặt Model", "showConfigSidebar")
.addToUi();
}
/**
* Hiển thị sidebar cấu hình.
*/
function showConfigSidebar() {
const html = HtmlService.createHtmlOutputFromFile("ConfigSidebar")
.setTitle("Cài đặt Gemini");
SpreadsheetApp.getUi().showSidebar(html);
}
/**
* Lưu cấu hình (API keys và Default Model) qua Properties và Cache.
* @param {Object} config - Ví dụ: { apiKeys: "key1, key2, key3", defaultModel: "gemini-2.0-flash" }
* @return {string} Thông báo lưu cấu hình.
*/
function saveConfig(config) {
// Tách API keys (cách nhau bởi dấu phẩy)
let keys = [];
if (config.apiKeys) {
keys = config.apiKeys.split(/\s*,\s*/).filter(function(x) { return x; });
}
const newConfig = {
apiKeys: keys,
defaultModel: config.defaultModel || "gemini-2.0-flash"
};
const configString = JSON.stringify(newConfig);
PropertiesService.getScriptProperties().setProperty("gemini_config", configString);
CacheService.getScriptCache().put("gemini_config", configString, 21600); // cache 6 giờ
return "Cấu hình đã được lưu thành công!";
}
/**
* Lấy cấu hình đã lưu.
* Nếu không có thì trả về cấu hình mặc định.
* @return {Object} { apiKeys: string[], defaultModel: string }
*/
function getConfig() {
const cache = CacheService.getScriptCache();
let configString = cache.get("gemini_config");
if (configString) {
return JSON.parse(configString);
}
configString = PropertiesService.getScriptProperties().getProperty("gemini_config");
if (configString) {
cache.put("gemini_config", configString, 21600);
return JSON.parse(configString);
}
// Nếu chưa được cấu hình
return { apiKeys: [], defaultModel: "gemini-2.0-flash" };
}
/**
* Hàm để load config, được gọi từ client.
*/
function loadConfig() {
return getConfig();
}
/**
* Lấy chỉ số API key hiện hành (để xoay vòng qua các key).
* @return {number} Chỉ số hiện tại.
*/
function getCurrentApiKeyIndex() {
const props = PropertiesService.getScriptProperties();
return parseInt(props.getProperty("currentApiKeyIndex")) || 0;
}
/**
* Cập nhật chỉ số API key hiện hành.
* @param {number} newIndex - Giá trị chỉ số mới.
*/
function updateCurrentApiKeyIndex(newIndex) {
PropertiesService.getScriptProperties().setProperty("currentApiKeyIndex", newIndex.toString());
}
/**
* Kiểm tra và thực hiện delay nếu vượt giới hạn rate cho mỗi loại model.
* Sử dụng PropertiesService để lưu thông tin về minute & daily.
* @param {string} category - "exp" hoặc "official"
*/
function checkRateLimit(category) {
const props = PropertiesService.getScriptProperties();
const now = Date.now();
const minuteKey = "rate_" + category + "_minute_window_start";
const minuteCountKey = "rate_" + category + "_minute_count";
const dayKey = "rate_" + category + "_day";
const dayCountKey = "rate_" + category + "_day_count";
const lastCallKey = "rate_" + category + "_last_call";
// Lấy dữ liệu lưu trữ
let minuteWindowStart = parseInt(props.getProperty(minuteKey)) || now;
let minuteCount = parseInt(props.getProperty(minuteCountKey)) || 0;
let dayStored = props.getProperty(dayKey) || Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "yyyy-MM-dd");
let dayCount = parseInt(props.getProperty(dayCountKey)) || 0;
const today = Utilities.formatDate(new Date(), Session.getScriptTimeZone(), "yyyy-MM-dd");
// Cài đặt giới hạn dựa trên loại model
let minuteLimit, dailyLimit, minInterval;
if (category === "exp") {
minuteLimit = 10;
dailyLimit = 1500;
minInterval = 6000; // 6 giây
} else {
minuteLimit = 2;
dailyLimit = 50;
minInterval = 30000; // 30 giây
}
// Reset minute window nếu đã qua 60 giây
if (now - minuteWindowStart >= 60000) {
minuteWindowStart = now;
minuteCount = 0;
}
// Nếu cuộc gọi trước chưa cách đủ minInterval thì delay
const lastCall = parseInt(props.getProperty(lastCallKey)) || 0;
if (now - lastCall < minInterval) {
const waitTime = minInterval - (now - lastCall);
Utilities.sleep(waitTime);
}
// Kiểm tra giới hạn theo phút
if (minuteCount >= minuteLimit) {
const waitTime = 60000 - (now - minuteWindowStart);
Utilities.sleep(waitTime);
// Sau khi đợi, reset lại window
minuteWindowStart = Date.now();
minuteCount = 0;
}
// Kiểm tra giới hạn theo ngày
if (today !== dayStored) {
dayStored = today;
dayCount = 0;
}
if (dayCount >= dailyLimit) {
throw new Error("Đã vượt quá giới hạn yêu cầu hàng ngày cho loại model " + category);
}
// Cập nhật các thông số
minuteCount++;
dayCount++;
props.setProperty(minuteKey, minuteWindowStart.toString());
props.setProperty(minuteCountKey, minuteCount.toString());
props.setProperty(dayKey, dayStored);
props.setProperty(dayCountKey, dayCount.toString());
props.setProperty(lastCallKey, Date.now().toString());
}
/**
* Hàm GeminiAI()
* - Nối các phần prompt (có thể ghép nối từ nhiều ô).
* - Lấy cấu hình API keys và Default Model từ cache/Properties.
* - Xoay vòng sử dụng API key.
* - Kiểm tra giới hạn rate (theo loại model official/exp).
* - Thử lại tối đa 3 lần nếu response khác 200.
* - Gọi Gemini API và trả về kết quả dạng plain text.
*
* @param {...string} promptParts - Các phần của prompt.
* @return {string} Kết quả phản hồi từ Gemini API.
* @customfunction
*/
function GeminiAI() {
try {
// Nối các tham số đầu vào thành 1 chuỗi prompt.
const prompt = Array.prototype.slice.call(arguments).join('');
if (!prompt) {
return "Vui lòng cung cấp nội dung prompt.";
}
// Lấy cấu hình
const config = getConfig();
if (!config.apiKeys || config.apiKeys.length === 0) {
return "Chưa cấu hình API keys. Vui lòng vào menu Gemini > Cài đặt Model để thiết lập.";
}
const model = config.defaultModel;
// Xác định loại model: nếu chứa "exp" thì xem như experimental, ngược lại là official.
const category = (model.indexOf("exp") !== -1) ? "exp" : "official";
// Kiểm tra rate limit: sẽ tự động delay nếu cần.
checkRateLimit(category);
// Lấy API key theo cơ chế xoay vòng.
const apiKeys = config.apiKeys;
let index = getCurrentApiKeyIndex();
const apiKey = apiKeys[index];
index = (index + 1) % apiKeys.length;
updateCurrentApiKeyIndex(index);
// Xây dựng request body
const requestBody = {
"contents": [{
"parts": [{ "text": prompt }]
}]
};
const requestOptions = {
"method": "POST",
"headers": { "Content-Type": "application/json" },
"payload": JSON.stringify(requestBody),
"muteHttpExceptions": true
};
// Xây dựng URL gọi API dựa trên model đã chọn
const url = "https://generativelanguage.googleapis.com/v1beta/models/" + model + ":generateContent?key=" + apiKey;
// Thử lại tối đa 3 lần nếu response code không phải 200
var maxAttempts = 3;
var attempt = 0;
var response, json, answer;
while (attempt < maxAttempts) {
response = UrlFetchApp.fetch(url, requestOptions);
if (response.getResponseCode() === 200) {
break;
}
attempt++;
if (attempt < maxAttempts) {
Utilities.sleep(2000); // delay 2 giây trước khi thử lại
}
}
if (response.getResponseCode() !== 200) {
return "Lỗi API (HTTP " + response.getResponseCode() + "): " + response.getContentText();
}
json = JSON.parse(response.getContentText());
answer = json && json.candidates && json.candidates[0] && json.candidates[0].content && json.candidates[0].content.parts && json.candidates[0].content.parts[0] && json.candidates[0].content.parts[0].text;
if (!answer) {
return "Không nhận được phản hồi từ API.";
}
return answer;
} catch (error) {
return "Error: " + error.message;
}
}
- Nhấn vào biểu tượng Save 💾 để lưu lại đoạn code vừa thêm.
- Tiếp theo, vào menu Tệp, nhấn vào biểu tượng dấu cộng (+) để tạo một tệp mới.
- Chọn định dạng HTML và đặt tên chính xác là ConfigSidebar.html (việc đặt tên đúng rất quan trọng để code hoạt động).
- Xóa toàn bộ code mặc định trong tệp mới. Sao chép và dán đoạn code dưới đây vào tệp ConfigSidebar.html.
- Nhấn vào biểu tượng Save 💾 để lưu lại tệp HTML.
<!DOCTYPE html>
<html>
<head>
<base target="_top">
<style>
/* Reset cơ bản */
* {
box-sizing: border-box;
}
body {
margin: 0;
padding: 20px;
background: #f5f7fa;
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
color: #333;
}
h2 {
text-align: center;
margin-bottom: 20px;
font-size: 1.8em;
color: #2c3e50;
}
label {
display: block;
margin-top: 15px;
font-weight: bold;
color: #34495e;
}
input[type="text"],
select {
width: 100%;
padding: 10px;
margin-top: 5px;
border: 1px solid #ccc;
border-radius: 4px;
font-size: 1em;
}
button {
display: block;
width: 100%;
padding: 10px;
margin-top: 20px;
background: #3498db;
color: #fff;
border: none;
border-radius: 4px;
font-size: 1em;
cursor: pointer;
transition: background 0.3s ease;
}
button:hover {
background: #2980b9;
}
/* Responsive */
@media (max-width: 600px) {
.container {
padding: 15px;
}
h2 {
font-size: 1.5em;
}
}
</style>
</head>
<body>
<h2>Cài đặt Gemini</h2>
<div>
<label>API Keys (cách nhau bởi dấu ","):</label>
<input type="text" id="apiKeys" placeholder="Nhập API keys, ví dụ: key1, key2, key3" />
<label>Default Model:</label>
<select id="defaultModel">
<option value="gemini-2.0-flash">Gemini 2.0 Flash</option>
<option value="gemini-2.0-flash-lite-preview-02-05">Gemini 2.0 Flash-Lite Preview</option>
<option value="gemini-1.5-flash">Gemini 1.5 Flash</option>
<option value="gemini-1.5-flash-8b">Gemini 1.5 Flash-8B</option>
<option value="gemini-1.5-pro">Gemini 1.5 Pro</option>
<option value="gemini-2.0-pro-exp-02-05">Gemini 2.0 Pro (exp)</option>
<option value="gemini-2.0-flash-thinking-exp-01-21">Gemini 2.0 Flash Thinking (exp)</option>
<option value="gemini-2.0-flash-exp">Gemini 2.0 Flash (exp)</option>
<option value="gemini-exp-1206">Gemini (exp)</option>
</select>
<button onclick="saveConfig()">Lưu cấu hình</button>
</div>
<script>
// Load cấu hình khi trang load
window.onload = function() {
google.script.run.withSuccessHandler(populateFields).loadConfig();
};
function populateFields(config) {
if (config && config.apiKeys) {
document.getElementById('apiKeys').value = config.apiKeys.join(', ');
}
if (config && config.defaultModel) {
document.getElementById('defaultModel').value = config.defaultModel;
}
}
function saveConfig() {
var apiKeys = document.getElementById('apiKeys').value;
var defaultModel = document.getElementById('defaultModel').value;
google.script.run.withSuccessHandler(function(msg) {
alert(msg);
}).saveConfig({ apiKeys: apiKeys, defaultModel: defaultModel });
}
</script>
</body>
</html>
Nếu Google cập nhật model Gemini mới bạn chỉ cần thay đổi các giá trị option trong select với id=”defaultModel”.
Kết luận
Khánh hy vọng bài viết này không chỉ giúp các chủ startup nắm vững cách sử dụng Gemini trên Google Sheet, mà còn trang bị tư duy tự động hóa quy trình với Apps Script, giúp tối ưu chi phí và thời gian khi vận hành doanh nghiệp non trẻ. Mình đã dành nhiều thời gian và tâm huyết để thực hiện bài viết này, mong rằng nó sẽ hữu ích và được mọi người yêu thích, chia sẻ. Nếu bạn trích dẫn nội dung, hãy tôn trọng quyền tác giả. Cảm ơn!
Ủng hộ Khánh ly cà phê qua số tài khoản ngân hàng MB Bank: 0858566936
Nếu bạn muốn mình viết, tư vấn hoặc giải đáp về chủ đề gì tiếp theo hãy liên hệ với mình qua facebook: Ngô Phùng Khánh. Cảm ơn và hẹn gặp lại bạn trong các bài viết tiếp theo!