1. Einführung
Sie nehmen an einem Meet-Anruf teil, möchten aber nicht der Erste sein? Dann haben wir die Lösung für Sie!
In diesem Codelab erstellen Sie eine Chrome-Erweiterung, die Sie benachrichtigt, wenn der erste Teilnehmer dem Anruf beitritt.
Sie lernen die verschiedenen Elemente einer Chrome-Erweiterung kennen und erfahren mehr über die einzelnen Teile der Erweiterung. Sie lernen Erweiterungsfunktionen wie Content-Skripts, Service Worker und Nachrichtenübermittlung kennen.
Sie müssen sich an die Manifestversion 3 halten, um eine Benachrichtigung zu erhalten, wenn ein Teilnehmer einem Meet-Anruf beitritt.
2. Hinweis
Vorbereitung
Dieses Codelab ist zwar für Anfänger geeignet, aber grundlegende JavaScript-Kenntnisse können Ihre Erfahrung erheblich verbessern.
Einrichtung/Anforderungen
- Chrome-Browser
- Eine IDE/ein Editor auf Ihrem lokalen System
- Installieren Sie die gcloud CLI, wenn Sie die Gemini API mit gcloud aktivieren möchten.
Gemini API aktivieren
- Wählen Sie in der Google Cloud Console auf der Seite der Projektauswahl ein Google Cloud-Projekt aus oder erstellen Sie eines.
- Die Abrechnung für das Cloud-Projekt muss aktiviert sein. So prüfen Sie, ob die Abrechnung für ein Projekt aktiviert ist.
- Rufen Sie die Gemini Marketplace-Seite auf, um die API zu aktivieren. Sie können die API auch mit gcloud aktivieren:
gcloud services enable cloudaicompanion.googleapis.com --project PROJECT_ID - Rufen Sie in einem neuen Tab die Seite „Gemini for Cloud Console“ auf und klicken Sie auf „Chat starten“.
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. Los gehts
Einfache Erweiterungsinstallation
Erstellen wir ein Verzeichnis, das wir als Stammverzeichnis unseres Projekts verwenden.
mkdir gemini-chrome-ext
cd gemini-chrome-ext
Bevor wir Gemini spezifische Fragen stellen, fragen wir nach der allgemeinen Struktur einer Chrome-Erweiterung.
Prompt:
What are the important parts to build a chrome extension?
Wir erhalten eine Antwort mit Details zur manifest-Datei, zum background script und zur Benutzeroberfläche. Sehen wir uns diese Dateien genauer an.
Prompt:
Create a manifest.json file to build a chrome extension. Make the name of the extension "Meet Joinees Notifier" and the author "<YOUR_EMAIL>"
Sie können im Feld „Autor“ einen gewünschten Namen und Ihre E-Mail-Adresse verwenden.
Gemini gibt die Inhalte der Manifestdatei zurück, die wir benötigen. Wir erhalten aber auch einige zusätzliche Felder, die wir nicht brauchen, z. B. das Feld action. Außerdem benötigen wir eine Beschreibung. Das sollte nicht sein.
Prompt:
Remove the "action" field and make the description as "Adds the ability to receive a notification when a participant joins a Google meet".
Fügen wir diesen Inhalt in die Datei manifest.json im Stammverzeichnis Ihres Projekts ein.
An dieser Stelle sollte die Manifestdatei in etwa so aussehen.
{
"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>"
}
Entfernen Sie vorerst alle anderen zusätzlichen Felder, die in Ihrer Manifestdatei generiert wurden, da in diesem Codelab davon ausgegangen wird, dass diese Felder in Ihrer Manifestdatei vorhanden sind.
Wie testen wir nun, ob die Erweiterung funktioniert? Fragen wir unseren Freund Gemini.
Prompt:
Guide me on the steps needed to test a chrome extension on my local filesystem.
Ich erhalte einige Schritte zum Testen. Rufen wir die "Extensions Page" auf, indem wir zu chrome://extensions gehen. Aktivieren Sie die Schaltfläche "Developer Mode". Dadurch wird die Schaltfläche "Load unpacked" angezeigt, über die wir zum Ordner mit den Erweiterungsdateien auf unserem lokalen Computer navigieren können. Danach sollte die Erweiterung in der "Extensions Page" zu sehen sein.


Sehr gut! Wir sehen unsere Erweiterung, aber fügen wir einige Funktionen hinzu.
4. Content-Skript hinzufügen
Wir möchten JavaScript-Code nur auf https://meet.google.com ausführen. Das können wir mit Content-Skripts tun. Fragen wir Gemini, wie wir das in unserer Erweiterung erreichen können.
Prompt:
How to add a content script in our chrome extension?
Oder genauer:
Prompt:
How to add a content script to run on meet.google.com subdomain in our chrome extension?
Oder eine andere Version:
Prompt:
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 gibt uns die genauen Änderungen, die wir in unserer Datei „manifest.json“ vornehmen müssen, und auch das JavaScript, das wir in unserer Datei content.js benötigen.
Mit dem Hinzufügen von „content_scripts“ sieht unsere Manifestdatei so aus:
{
"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"]
}
]
}
Dadurch wird Chrome angewiesen, das Content-Skript content.js einzufügen, wenn wir zu einer Seite in der Subdomain „https://meet.google.com“ navigieren. Fügen wir diese Datei hinzu und testen wir sie.
Fügen wir diesen Code in die Datei content.js ein.
console.log("Hello Gemini");
Tatsächlich! Wenn wir meet.google.com aufrufen, sehen wir „Hallo Gemini“ in der JavaScript-Konsole(Mac: Cmd + Opt + J / Windows/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("Hallo Gemini!");


Sehr gut! Jetzt können wir unserer App einige spezifische JavaScript-Funktionen hinzufügen. Nehmen wir uns einen Moment Zeit und überlegen wir, was wir erreichen möchten.
Content-Skript verbessern
Wir möchten eine Benachrichtigung erhalten, wenn jemand einem Meeting beitritt, während wir uns auf der Meetingseite befinden(wo wir die Möglichkeit haben, am Meeting teilzunehmen). Dazu beobachten wir, wie sich der Bildschirm visuell ändert, wenn das Meeting leer ist und wenn jemand dem Meeting beigetreten ist.
So sieht es aus, wenn niemand im Meeting ist.

So sieht es aus, wenn einige Teilnehmer im Meeting sind.

Wir sehen auf Anhieb zwei bemerkenswerte Unterschiede:
- Der Statustext ändert sich von „Niemand sonst ist hier“ zu „[Nutzer] ist in diesem Anruf“.
- Wir sehen die Bilder der Nutzer, die dem Anruf beigetreten sind.
Beide Änderungen funktionieren für uns, wenn wir wissen möchten, ob jemand dem Meeting beigetreten ist. Die zweite Änderung bietet jedoch einige Möglichkeiten, Informationen zu den Nutzern zu erhalten, die bereits beigetreten sind. Versuchen wir also, diese zu verwenden.
Öffnen Sie den Elementinspektor in Chrome mit der Tastenkombination ( Mac: Cmd + Opt + C / Win: Ctrl + Shift + C) und klicken Sie dann auf das Bild des Nutzers, der beigetreten ist.
Wir sehen ein Bild mit einigen Klassenzeichenfolgen. Das Attribut „title“ des Bildes enthält den Namen des Nutzers, der dem Meeting beigetreten ist. Außerdem ist dieses Bild-Tag in ein Div mit der Klasse U04fid eingebettet. Wenn wir unserem Testmeeting einige Teilnehmer hinzufügen, sehen wir, dass dieses übergeordnete Div mehrere Bilder enthält(entsprechend den verschiedenen Nutzern).
Wir haben also eine teilweise Strategie:
- Erkennen, wenn das Div mit der Klasse
U04fidElemente enthält. - Wenn das der Fall ist, bedeutet das, dass Teilnehmer in unserem Meeting sind.
- Nutzer benachrichtigen.
Fragen wir Gemini, wie wir das Schritt für Schritt erreichen können.
Prompt:
How to detect for element changes in the HTML page?
Wir erhalten eine Lösung mit MutationObserver, aber nichts Spezifisches für unsere Anforderung. Versuchen wir, den Prompt zu ändern.
Prompt:
How can I detect if an element "div.U04fid" has any child images in the HTML page?
Dieses Mal erhalten wir eine Lösung, die nicht MutationObserver enthält, sondern die Teilnehmer mithilfe des übergeordneten Div prüft.
Das haben wir erhalten:
const divU04fid = document.querySelector('div.U04fid');
const childImages = divU04fid.querySelectorAll('img');
if (childImages.length > 0) {
// div.U04fid has at least one child image.
}
Versuchen wir, unseren Ansatz noch weiter zu ändern:
Prompt:
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.
Wir erhalten das folgende Code-Snippet:
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
});
Kopieren Sie diesen Code in die Datei content.js, laden Sie die Erweiterung neu und laden Sie dann die Meet-Seite neu.
Wenn jetzt jemand unserem Meeting beitritt, können wir die Log-Anweisung in der Konsole sehen.
5. Benachrichtigung an den Nutzer senden
Jetzt, da wir erkennen können, wenn ein Teilnehmer dem Meeting beigetreten ist, fügen wir den Benachrichtigungsteil in unsere Chrome-Erweiterung ein. Wir können die Dokumentation der Chrome-Erweiterung durchsuchen oder die Prompts anpassen, um herauszufinden, was wir suchen. Im Wesentlichen müssen wir die chrome.notifications.create API verwenden. Der Aufruf dieser Methode sollte von einem Hintergrund-Service Worker erfolgen.
Prompt:
Using the documentation for chrome notifications tell me how to use the chrome.notifications.create method.
Wir sehen einige detaillierte Schritte. Die wichtigsten Punkte sind:
- Fügen Sie die Berechtigung
notificationsin der Manifestdatei hinzu. - Rufen Sie chrome.notifications.create auf.
- Der Aufruf sollte in einem Hintergrundskript erfolgen.
Wenn Sie einer Chrome-Erweiterung in manifest version 3 ein Hintergrundskript hinzufügen möchten, benötigen wir die Deklaration background.service_worker in unserer Datei manifest.json.
Erstellen Sie also eine Datei namens „background.js“ und fügen Sie Folgendes in die Datei „manifest.json“ ein.
"background": {
"service_worker": "background.js"
},
"permissions": [
"notifications"
]
Mit den oben genannten Ergänzungen sieht unsere Manifestdatei so aus:
{
"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"
]
}
Prompt:
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
Speichern Sie dieses Bild im Stammverzeichnis Ihres Ordners und benennen Sie es in success.png um.

Fügen Sie dann das folgende Code-Snippet in Ihre Datei background.js ein.
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");
Laden Sie die Erweiterung jetzt auf der Seite mit Erweiterungen neu. Sie sollten sofort ein Benachrichtigungs-Pop-up sehen.
6. Nachrichtenübermittlung in Ihrer Chrome-Erweiterung hinzufügen
Der letzte wichtige Schritt besteht darin, die Erkennung eines Teilnehmers durch das Content-Skript und die Methode sendNotification im Hintergrundskript zu verbinden. Im Kontext von Chrome-Erweiterungen erfolgt dies über eine Technik namens message passing.
Dadurch wird die Kommunikation zwischen verschiedenen Teilen einer Chrome-Erweiterung ermöglicht, in unserem Fall vom Content-Skript zum Hintergrund-Service Worker. Fragen wir unseren Freund Gemini, wie das geht.
Prompt:
How to send a message from the content script to the background script in a chrome extension
Gemini antwortet mit relevanten Aufrufen von chrome.runtime.sendMessage und chrome.runtime.onMessage.addListener.
Im Wesentlichen verwenden wir sendMessage, um eine Nachricht vom Content-Skript zu senden, dass jemand dem Meet-Anruf beigetreten ist, und onMessage.addListener als Ereignis-Listener, um auf die vom Content-Skript gesendete Nachricht zu reagieren. In diesem Fall lösen wir den Aufruf der Methode sendNotification über diesen Ereignis-Listener aus.
Wir übergeben die Benachrichtigungsnachricht und ein Attribut action an den Hintergrund-Service Worker. Das Attribut action beschreibt, worauf das Hintergrundskript reagiert.
Hier ist unser content.js-Code:
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"
});
}
Und das ist unser background.js-Code:
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"
});
}
Passen wir die Benachrichtigungsnachricht an und rufen wir eine eindeutige Benachrichtigungs-ID ab. Für die Benachrichtigungsnachricht können wir den Namen des Nutzers einfügen. Wie wir uns aus einem vorherigen Schritt erinnern, konnten wir den Namen des Nutzers im Attribut „title“ des Bildes sehen. Wir können den Namen des Teilnehmers also mit document.querySelector('div.U04fid > img').getAttribute('title'). abrufen.
Für die Benachrichtigungs-ID können wir die Tab-ID des Content-Skripts abrufen und als Benachrichtigungs-ID verwenden. Das kann in unserem Ereignis-Listener chrome.runtime.onMessage.addListener mit sender.tab.id. erreicht werden.
Schließlich sollten unsere Dateien so aussehen:
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. Glückwunsch
In kurzer Zeit konnten wir mit Gemini eine Chrome-Erweiterung erstellen. Ganz gleich, ob Sie ein erfahrener Entwickler von Chrome-Erweiterungen sind oder neu in der Welt der Erweiterungen, Gemini kann Ihnen bei allen Aufgaben helfen, die Sie erledigen möchten.
Fragen Sie nach den verschiedenen Möglichkeiten, die Sie mit einer Chrome-Erweiterung haben. Es gibt viele APIs, die es wert sind, durchsucht zu werden, z. B. chrome.storage und alarms. Wenn Sie nicht weiterkommen, verwenden Sie Gemini oder die Dokumentation, um herauszufinden, was Sie falsch machen, oder um verschiedene Möglichkeiten zur Lösung des Problems zu finden.
Oft ist es erforderlich, den Prompt zu ändern, um die benötigte Hilfe zu erhalten. Das können wir aber über einen Tab tun, auf dem unsere gesamte kontextbezogene Reise gespeichert ist.