1. Giới thiệu
Bạn muốn tham gia cuộc gọi qua Meet nhưng không muốn là người đầu tiên tham gia? Nếu bạn thuộc trường hợp này, chúng tôi có giải pháp dành cho bạn!
Sau khi hoàn thành lớp học lập trình này, bạn sẽ tạo một tiện ích của Chrome để cảnh báo cho bạn khi người tham gia đầu tiên tham gia cuộc gọi.
Bạn sẽ tìm hiểu các thành phần khác nhau của tiện ích của Chrome, sau đó nghiên cứu chuyên sâu vào từng phần của tiện ích đó. Bạn sẽ tìm hiểu về các hàm mở rộng như tập lệnh nội dung, trình chạy dịch vụ và truyền tin.
Bạn cần tuân thủ bản phát hành manifest v3 để có thể nhận được thông báo bất cứ khi nào có người tham gia cuộc gọi qua Meet.
2. Trước khi bắt đầu
Điều kiện tiên quyết
Mặc dù lớp học lập trình này phù hợp với người mới bắt đầu, nhưng việc nắm vững kiến thức cơ bản về JavaScript có thể giúp bạn nâng cao đáng kể trải nghiệm của mình.
Thiết lập/Yêu cầu
- Trình duyệt Chrome
- Thiết lập IDE/Trình chỉnh sửa trên hệ thống cục bộ.
- Cài đặt gcloud cli nếu bạn muốn bật Gemini API bằng gcloud.
Bật Gemini API
- Trong Google Cloud Console, trên trang chọn dự án, hãy chọn hoặc tạo một dự án trên Google Cloud.
- Đảm bảo bạn đã bật tính năng thanh toán cho dự án trên Cloud. Tìm hiểu cách kiểm tra xem tính năng thanh toán có được bật trên một dự án hay không.
- Chuyển đến trang Gemini Marketplace để bật API. Bạn cũng có thể dùng gcloud để bật API:
gcloud services enable cloudaicompanion.googleapis.com --project PROJECT_ID - Truy cập vào trang Gemini cho Cloud Console trong một thẻ mới rồi nhấp vào "Bắt đầu trò chuyện".
Note that if you're writing the code in the Cloud Shell editor, then you will have to download the folder somewhere on your local filesystem to test the extension locally.
3. Bắt đầu chơi
Cài đặt tiện ích cơ bản
Hãy tạo một thư mục mà chúng ta sẽ dùng làm thư mục gốc của dự án.
mkdir gemini-chrome-ext
cd gemini-chrome-ext
Trước khi bắt đầu đặt các câu hỏi cụ thể cho Gemini, hãy đặt một số câu hỏi về cấu trúc chung của một tiện ích Chrome.
Câu lệnh:
What are the important parts to build a chrome extension?
Chúng ta nhận được một phản hồi nêu rõ các thông tin chi tiết về tệp manifest, background script và thông tin chi tiết về giao diện người dùng. Hãy cùng tìm hiểu chi tiết hơn về những tệp cụ thể này.
Câu lệnh:
Create a manifest.json file to build a chrome extension. Make the name of the extension "Meet Joinees Notifier" and the author "<YOUR_EMAIL>"
Bạn có thể sử dụng tên và email của mình trong trường tác giả.
Gemini trả về nội dung của tệp kê khai mà chúng ta cần, nhưng chúng ta sẽ nhận được một số trường bổ sung mà chúng ta không cần, chẳng hạn như trường action. Ngoài ra, chúng tôi cần có nội dung mô tả. Hãy khắc phục vấn đề đó.
Câu lệnh:
Remove the "action" field and make the description as "Adds the ability to receive a notification when a participant joins a Google meet".
Hãy đặt nội dung này vào tệp manifest.json trong thư mục gốc của dự án.
Ở giai đoạn này, tệp kê khai sẽ có dạng như sau.
{
"name": "Meet Joinees Notifier",
"version": "1.0",
"manifest_version": 3,
"description": "Adds the ability to receive a notification when a participant joins a Google Meet",
"author": "<YOUR_EMAIL>"
}
Hiện tại, hãy xoá mọi trường bổ sung khác được tạo trong tệp kê khai vì lớp học lập trình này giả định các trường này trong tệp kê khai của bạn.
Bây giờ, làm cách nào để kiểm tra xem tiện ích có hoạt động hay không? Hãy hỏi Gemini xem sao nhé.
Câu lệnh:
Guide me on the steps needed to test a chrome extension on my local filesystem.
Nó cung cấp cho tôi một số bước về cách kiểm thử. Hãy chuyển đến "Extensions Page" bằng cách chuyển đến chrome://extensions và nhớ bật nút "Developer Mode". Nút này sẽ hiển thị nút "Load unpacked" mà chúng ta có thể dùng để chuyển đến thư mục chứa các tệp tiện ích cục bộ. Sau khi hoàn tất, chúng ta sẽ thấy tiện ích trong "Extensions Page".


Tuyệt vời! Chúng ta có thể thấy tiện ích của mình, nhưng hãy bắt đầu thêm một số chức năng.
4. Thêm tập lệnh nội dung
Chúng ta chỉ muốn chạy một số mã javascript trên https://meet.google.com mà chúng ta có thể thực hiện bằng cách sử dụng tập lệnh nội dung. Hãy hỏi Gemini cách đạt được điều đó trong tiện ích của chúng ta.
Câu lệnh:
How to add a content script in our chrome extension?
Hoặc cụ thể hơn:
Câu lệnh:
How to add a content script to run on meet.google.com subdomain in our chrome extension?
Hoặc một phiên bản khác:
Câu lệnh:
Help me add a content script named content.js to run on meet.google.com subdomain in our chrome extension. The content script should simply log "Hello Gemini" when we navigate to "meet.google.com".
Gemini cho chúng ta biết chính xác những thay đổi cần thực hiện trong tệp manifest.json và cả javascript cần thiết trong tệp content.js.
Khi thêm content_scripts, tệp kê khai của chúng ta sẽ trở thành:
{
"name": "Meet Joinees Notifier",
"version": "1.0",
"manifest_version": 3,
"description": "Adds the ability to receive a notification when a participant joins a Google Meet",
"author": "abc@example.com",
"content_scripts": [
{
"matches": ["https://meet.google.com/*"],
"js": ["content.js"]
}
]
}
Điều này cho Chrome biết rằng cần chèn tập lệnh nội dung content.js bất cứ khi nào chúng ta chuyển đến một trang trong miền phụ " https://meet.google.com". Hãy thêm tệp này và kiểm thử nhé?
Hãy thêm đoạn mã này vào tệp content.js.
console.log("Hello Gemini");
Quả nhiên! Khi truy cập vào meet.google.com, chúng ta sẽ thấy "Chào Gemini" trên bảng điều khiển javascript(Mac: Cmd + Opt + J / Win/Linux: Ctrl + Shift + J).
manifest.json
{
"name": "Meet Joinees Notifier",
"version": "1.0",
"manifest_version": 3,
"description": "Adds the ability to receive a notification when a participant joins a Google Meet",
"author": "luke@cloudadvocacyorg.joonix.net",
"permissions": [
"tabs",
"notifications"
],
"content_scripts": [
{
"matches": [
"https://meet.google.com/*"
],
"js": [
"content.js"
]
}
]
}
content.js
console.log("Hello Gemini!");


Tuyệt vời! Giờ đây, chúng ta có thể thêm một số chức năng cụ thể của javascript vào ứng dụng. Hãy dành chút thời gian để suy nghĩ về mục tiêu mà chúng ta đang cố gắng đạt được.
Cải thiện tập lệnh nội dung
Chúng tôi muốn nhận được thông báo khi có người tham gia cuộc họp trong khi chúng tôi đang ở trên trang cuộc họp(nơi chúng tôi có thể chọn tham gia cuộc họp). Để đạt được điều này, hãy quan sát cách màn hình thay đổi về mặt hình ảnh khi cuộc họp không có người tham gia so với khi có người tham gia cuộc họp.
Đây là giao diện khi không có ai trong cuộc họp.

Còn đây là hình ảnh khi có một số người tham gia cuộc họp.

Chúng ta có thể thấy ngay 2 điểm khác biệt đáng chú ý:
- Văn bản trạng thái thay đổi từ "Không có ai khác ở đây" thành "[Người dùng] đang tham gia cuộc gọi này".
- Chúng ta có thể thấy hình ảnh của những người dùng đã tham gia cuộc gọi.
Cả hai thay đổi này đều có tác dụng nếu chúng ta muốn biết có ai đã tham gia cuộc họp hay không, nhưng thay đổi thứ hai có một số khả năng lấy thông tin về những người dùng đã tham gia, vì vậy, hãy thử sử dụng thay đổi đó.
Mở "Trình kiểm tra phần tử" trong Chrome bằng phím nóng ( Mac: Cmd + Opt + C / Win: Ctrl + Shift + C), sau đó nhấp vào hình ảnh của người dùng đã tham gia.
Chúng ta có thể nhận thấy rằng có một hình ảnh có một vài chuỗi lớp và thuộc tính tiêu đề của hình ảnh có tên của người dùng đã tham gia cuộc họp. Ngoài ra, thẻ hình ảnh này được gói trong một div có lớp U04fid. Sau khi thêm một số người tham gia vào cuộc họp thử nghiệm, chúng ta có thể thấy rằng div mẹ này lưu trữ nhiều hình ảnh(tương ứng với nhiều người dùng).
Vì vậy, chúng tôi đã có một chiến lược một phần trong đầu:
- Phát hiện khi div có lớp
U04fidchứa bất kỳ phần tử nào. - Nếu có, tức là cuộc họp của chúng ta có người tham gia.
- Thông báo cho người dùng.
Hãy quay lại Gemini và hỏi cách chúng ta có thể đạt được mục tiêu này từng bước.
Câu lệnh:
How to detect for element changes in the HTML page?
Mặc dù MutationObserver đưa ra một giải pháp, nhưng không có giải pháp nào cụ thể cho yêu cầu của chúng tôi. Hãy thử sửa đổi câu lệnh.
Câu lệnh:
How can I detect if an element "div.U04fid" has any child images in the HTML page?
Lần này, chúng ta sẽ có một giải pháp không bao gồm MutationObserver mà là một giải pháp kiểm tra những người tham gia bằng cách sử dụng div mẹ.
Đây là nội dung chúng tôi nhận được:
const divU04fid = document.querySelector('div.U04fid');
const childImages = divU04fid.querySelectorAll('img');
if (childImages.length > 0) {
// div.U04fid has at least one child image.
}
Hãy thử điều chỉnh cách tiếp cận của chúng ta hơn nữa:
Câu lệnh:
Create a method which checks if the element div.U04fid has any child elements, if it does it should log it on the console. The method should be called checkJoinees and it should be called as a callback for MutationObserver which is observing the document.body.
Thao tác này sẽ trả về đoạn mã sau:
function checkJoinees(mutations) {
for (const mutation of mutations) {
if (mutation.type === 'childList') {
// A child node was added or removed.
if (document.querySelector('div.U04fid') && document.querySelector('div.U04fid').childElementCount > 0) {
// div.U04fid has at least one child element.
console.log('div.U04fid has at least one child element.');
}
}
}
return false;
}
const observer = new MutationObserver(checkJoinees);
observer.observe(document.body, {
childList: true,
delay: 1000
});
Sao chép mã này vào tệp content.js, tải lại tiện ích(rồi tải lại trang Meet).
Giờ đây, khi có người tham gia cuộc họp, chúng ta có thể thấy câu lệnh nhật ký trong bảng điều khiển.
5. Gửi thông báo cho người dùng
Giờ đây, khi đã có thể phát hiện thời điểm người tham gia đã tham gia cuộc họp, hãy thử thêm phần thông báo vào tiện ích Chrome. Chúng ta có thể duyệt xem tài liệu về tiện ích Chrome hoặc thậm chí điều chỉnh các câu lệnh để biết mình đang tìm kiếm nội dung gì. Tuy nhiên, về cơ bản, chúng ta cần sử dụng API chrome.notifications.create và lệnh gọi đến phương thức này phải đến từ một worker dịch vụ chạy trong nền.
Câu lệnh:
Using the documentation for chrome notifications tell me how to use the chrome.notifications.create method.
Chúng ta sẽ thấy một số bước chi tiết, trong đó có những điểm nổi bật chính như sau:
- Thêm quyền
notificationsvào tệp kê khai. - Gọi đến chrome.notifications.create
- Lệnh gọi phải nằm trong một tập lệnh nền.
Để thêm một tập lệnh nền vào tiện ích Chrome trong manifest version 3, chúng ta cần khai báo background.service_worker trong tệp manifest.json.
Vì vậy, chúng ta sẽ tạo một tệp có tên là background.js và thêm nội dung sau vào tệp manifest.json.
"background": {
"service_worker": "background.js"
},
"permissions": [
"notifications"
]
Sau khi thêm các nội dung trên, tệp kê khai của chúng ta sẽ có dạng như sau:
{
"name": "Meet Joinees Notifier",
"version": "1.0",
"manifest_version": 3,
"description": "Adds the ability to receive a notification when a participant joins a Google Meet",
"author": "<YOUR_EMAIL>",
"content_scripts": [
{
"matches": ["https://meet.google.com/*"],
"js": ["content.js"]
}
],
"background": {
"service_worker": "background.js"
},
"permissions": [
"notifications"
]
}
Câu lệnh:
Create a method sendNotification that calls the chrome.notifications.create method with the message, "A user joined the call" for a chrome extension with manifest v3, the code is in the background service worker
Lưu hình ảnh này vào thư mục gốc và đổi tên thành success.png.

Sau đó, hãy thêm đoạn mã sau vào background.js của bạn.
function sendNotification(notificationId, message) {
chrome.notifications.create(notificationId, {
type: "basic",
title: "A user joined the call",
message: message,
iconUrl: "./success.png"
});
}
sendNotification("notif-id", "test message");
Bây giờ, hãy tải lại tiện ích từ trang tiện ích và bạn sẽ thấy ngay một thông báo bật lên.
6. Thêm tính năng truyền thông báo vào tiện ích Chrome
Giờ đây, bước quan trọng cuối cùng mà chúng ta cần thực hiện là kết nối hoạt động phát hiện người tham gia của tập lệnh nội dung và phương thức sendNotification trong tập lệnh nền. Trong bối cảnh của tiện ích Chrome, cách thực hiện việc đó là thông qua một kỹ thuật có tên là message passing.
Điều này cho phép giao tiếp giữa các phần của tiện ích Chrome, trong trường hợp của chúng ta là từ tập lệnh nội dung đến trình chạy dịch vụ nền. Hãy hỏi Gemini xem làm cách nào để đạt được điều đó.
Câu lệnh:
How to send a message from the content script to the background script in a chrome extension
Gemini phản hồi bằng các lệnh gọi có liên quan đến chrome.runtime.sendMessage và chrome.runtime.onMessage.addListener.
Về cơ bản, chúng ta sẽ dùng sendMessage để gửi thông báo từ tập lệnh nội dung rằng có người đã tham gia cuộc gọi qua Meet và dùng onMessage.addListener làm trình nghe sự kiện để phản hồi thông báo do tập lệnh nội dung gửi. Trong trường hợp này, chúng ta sẽ kích hoạt lệnh gọi đến phương thức sendNotification từ trình nghe sự kiện này.
Chúng ta sẽ truyền thông báo và thuộc tính action vào trình chạy dịch vụ nền. Thuộc tính action mô tả những gì mà tập lệnh nền đang phản hồi.
Sau đây là mã content.js của chúng ta:
function checkJoinees(mutations) {
for (const mutation of mutations) {
if (mutation.type === 'childList') {
// A child node was added or removed.
if (document.querySelector('div.U04fid') && document.querySelector('div.U04fid').childElementCount > 0) {
// div.U04fid has at least one child element.
sendMessage();
}
}
}
return false;
}
const observer = new MutationObserver(checkJoinees);
observer.observe(document.body, {
childList: true,
delay: 1000
});
function sendMessage() {
chrome.runtime.sendMessage({
txt: "A user has joined the call!",
action: "people_joined"
});
}
Và đây là mã background.js của chúng ta:
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.action === "people_joined") {
sendNotification("notif-id", message.txt);
}
});
function sendNotification(notificationId, message) {
chrome.notifications.create(notificationId, {
type: "basic",
title: "A user joined the call",
message: message,
iconUrl: "./success.png"
});
}
Hãy thử tuỳ chỉnh thông báo và nhận một mã thông báo duy nhất. Đối với thông báo, chúng ta có thể thêm tên của người dùng. Nếu nhớ lại một bước trước đó, chúng ta có thể thấy tên của người dùng trong thuộc tính tiêu đề của hình ảnh. Vì vậy, chúng ta có thể tìm nạp tên của người tham gia bằng cách sử dụng document.querySelector('div.U04fid > img').getAttribute('title').
Về mã thông báo, chúng ta có thể tìm nạp mã thẻ của tập lệnh nội dung và sử dụng mã đó làm mã thông báo. Bạn có thể thực hiện việc này trong trình nghe sự kiện chrome.runtime.onMessage.addListener bằng cách sử dụng sender.tab.id.
Cuối cùng, các tệp của chúng ta sẽ có dạng như sau:
manifest.json
{
"name": "Meet Joinees Notifier",
"version": "1.0",
"manifest_version": 3,
"description": "Adds the ability to receive a notification when a participant joins a Google Meet",
"author": "<YOUR_EMAIL>",
"content_scripts": [
{
"matches": ["https://meet.google.com/*"],
"js": ["content.js"]
}
],
"background": {
"service_worker": "background.js"
},
"permissions": [
"notifications"
]
}
content.js
function checkJoinees(mutations) {
for (const mutation of mutations) {
if (mutation.type === 'childList') {
// A child node was added or removed.
if (document.querySelector('div.U04fid') && document.querySelector('div.U04fid').childElementCount > 0) {
const name = document.querySelector('div.U04fid > img').getAttribute('title');
sendMessage(name);
}
}
}
return false;
}
const observer = new MutationObserver(checkJoinees);
observer.observe(document.body, {
childList: true,
delay: 1000
});
function sendMessage(name) {
const joinee = (name === null ? 'Someone' : name),
txt = `${joinee} has joined the call!`;
chrome.runtime.sendMessage({
txt,
action: "people_joined",
});
}
background.js
chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
if (message.action === "people_joined") {
sendNotification("" + sender.tab.id, message.txt); // We are casting this to string as notificationId is expected to be a string while sender.tab.id is an integer.
}
});
function sendNotification(notificationId, message) {
chrome.notifications.create(notificationId, {
type: "basic",
title: "A user joined the call",
message: message,
iconUrl: "./success.png"
});
}
7. Xin chúc mừng
Trong thời gian ngắn, chúng tôi đã có thể xây dựng một tiện ích Chrome nhờ sự trợ giúp của Gemini. Dù bạn là nhà phát triển tiện ích Chrome có kinh nghiệm hay mới bắt đầu tìm hiểu về tiện ích, Gemini đều có thể giúp bạn hoàn thành mọi việc bạn muốn.
Bạn nên hỏi về những việc bạn có thể làm với một tiện ích trên Chrome. Có nhiều API đáng để bạn khám phá, chẳng hạn như chrome.storage, alarms, v.v. Bất cứ khi nào bạn cảm thấy bế tắc, hãy sử dụng Gemini hoặc tài liệu để biết bạn đang làm sai điều gì hoặc để thu thập nhiều cách giải quyết vấn đề.
Bạn thường phải sửa đổi câu lệnh để nhận được sự trợ giúp cần thiết, nhưng bạn có thể thực hiện việc này trên một thẻ duy nhất lưu giữ tất cả hành trình theo ngữ cảnh của bạn.