1. Einführung
Sie möchten an einem Meet-Anruf teilnehmen, aber nicht als Erster? Wenn das auf Sie zutrifft, 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 befassen sich dann eingehend mit den einzelnen Teilen der Erweiterung. Sie lernen Erweiterungsfunktionen wie Content-Scripts, Service Worker und Message Passing kennen.
Sie müssen sich an die Manifest V3-Version 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 Kenntnisse in JavaScript können Ihnen sehr helfen.
Einrichtung/Anforderungen
- Chrome-Browser
- Eine IDE/einen 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 zur 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 die Seite „Gemini für Cloud Console“ in einem neuen Tab 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 Installation von Erweiterungen
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 erst einmal nach der allgemeinen Struktur einer Chrome-Erweiterung.
Prompt:
What are the important parts to build a chrome extension?
Wir erhalten eine Antwort mit geringfügigen Details zur Datei manifest, 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 einen beliebigen Namen und Ihre E-Mail-Adresse im Feld „Autor“ verwenden.
Gemini gibt den Inhalt der Manifestdatei zurück, den wir benötigen. Allerdings erhalten wir auch einige zusätzliche Felder, die wir nicht brauchen, z. B. das Feld action. Außerdem benötigen wir eine Beschreibung. Das können wir ändern.
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.
Die Manifestdatei sollte jetzt 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 doch einfach Gemini.
Prompt:
Guide me on the steps needed to test a chrome extension on my local filesystem.
Ich habe einige Schritte zum Testen erhalten. Rufen wir "Extensions Page" auf, indem wir zu chrome://extensions wechseln. Aktivieren Sie die Schaltfläche "Developer Mode", damit die Schaltfläche "Load unpacked" angezeigt wird. Über diese Schaltfläche können wir zu dem Ordner wechseln, der die Erweiterungsdateien lokal enthält. Danach sollte die Erweiterung in "Extensions Page" zu sehen sein.


Sehr gut! Wir können unsere Erweiterung sehen, aber wir wollen erst einmal einige Funktionen hinzufügen.
4. Inhaltskript hinzufügen
Wir möchten JavaScript-Code nur auf https://meet.google.com ausführen. Das ist mit Inhaltsskripts möglich. Fragen wir Gemini, wie wir das in unserer Erweiterung erreichen können.
Prompt:
How to add a content script in our chrome extension?
Oder noch 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 genaue Änderungen an, die wir in unserer Datei „manifest.json“ vornehmen müssen, sowie den JavaScript-Code, den wir in unserer content.js-Datei 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 Inhaltsscript content.js immer dann 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 in der JavaScript-Konsole(Mac: Cmd + Opt + J / Win/Linux: Ctrl + Shift + J) „Hallo Gemini“.
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!");


Sehr gut! Jetzt können wir unserer App einige JavaScript-spezifische Funktionen hinzufügen. Nehmen wir uns einen Moment Zeit, um darüber nachzudenken, was wir erreichen möchten.
Inhaltskript verbessern
Wir möchten benachrichtigt werden, wenn jemand einer Besprechung beitritt, während wir uns auf der Besprechungsseite befinden(wo wir die Möglichkeit haben, der Besprechung beizutreten). Sehen wir uns dazu an, wie sich der Bildschirm visuell ändert, wenn die Besprechung leer ist und wenn jemand der Besprechung beigetreten ist.
So sieht es aus, wenn niemand an der Besprechung teilnimmt.

So sieht es aus, wenn einige Teilnehmer an der Besprechung teilnehmen.

Gleich zu Beginn fallen zwei wesentliche Unterschiede auf:
- Der Statustext ändert sich von „Niemand sonst ist hier“ zu „[Nutzer] ist in diesem Anruf“.
- Wir können die Bilder der Nutzer sehen, die dem Anruf beigetreten sind.
Beide Änderungen funktionieren für uns, wenn wir wissen möchten, ob jemand der Besprechung beigetreten ist. Die zweite Option bietet jedoch einige Möglichkeiten, Informationen über die Nutzer zu erhalten, die bereits beigetreten sind. Wir versuchen es also damit.
Öffnen Sie die „Elementuntersuchung“ in Chrome mit dem Tastenkürzel ( Mac: Cmd + Opt + C / Win: Ctrl + Shift + C) und klicken Sie dann auf das Bild des Nutzers, der beigetreten ist.
Wir sehen, dass es ein Bild mit wenigen Klassenstrings gibt und das Attribut title des Bildes den Namen des Nutzers enthält, der der Besprechung beigetreten ist. Außerdem ist dieses Bild-Tag in ein Div-Element mit der Klasse U04fid eingeschlossen. Nachdem wir unserem Testmeeting einige Teilnehmer hinzugefügt haben, sehen wir, dass dieses übergeordnete DIV-Element mehrere Bilder(entsprechend verschiedenen Nutzern) enthält.
Wir haben also eine Teilstrategie im Blick:
- Erkennen, wenn das div-Element mit der Klasse
U04fidElemente enthält. - Wenn ja, bedeutet das, dass Teilnehmer an unserer Besprechung teilnehmen.
- Benachrichtigen Sie den Nutzer.
Ich kehre zu Gemini zurück und frage, wie ich das Schritt für Schritt erreichen kann.
Prompt:
How to detect for element changes in the HTML page?
Wir erhalten zwar eine Lösung mit MutationObserver, aber nichts, was unseren Anforderungen entspricht. Wir versuchen, 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-Elements 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 modifizieren:
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.
Es wird mit dem folgenden Code-Snippet zurückgegeben:
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 aktualisieren Sie dann die Meet-Seite.
Wenn jemand unserer Videokonferenz beitritt, können wir die Protokollausgabe jetzt in der Konsole sehen.
5. Benachrichtigung an den Nutzer senden
Nachdem wir nun erkennen können, wenn ein Teilnehmer der Besprechung beigetreten ist, fügen wir der Chrome-Erweiterung den Benachrichtigungsteil hinzu. Wir können die Dokumentation der Chrome-Erweiterung durchsuchen oder die Prompts anpassen, um herauszufinden, wonach wir suchen. Im Grunde müssen wir jedoch die chrome.notifications.create API verwenden und 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.
Hier sind einige detaillierte Schritte mit den wichtigsten Highlights:
- Fügen Sie die Berechtigung
notificationsin der Manifestdatei hinzu. - Rufen Sie chrome.notifications.create auf.
- Der Aufruf sollte in einem Hintergrundskript erfolgen.
Wenn wir einer Chrome-Erweiterung in manifest version 3 ein Hintergrundskript hinzufügen möchten, benötigen wir die background.service_worker-Deklaration in unserer manifest.json-Datei.
Wir erstellen also eine Datei namens background.js und fügen Folgendes in unsere manifest.json-Datei 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 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 nun auf der Seite „Erweiterungen“ neu. Sie sollten sofort ein Benachrichtigungs-Pop-up sehen.
6. Nachrichtenübermittlung in Ihre Chrome-Erweiterung einfügen
Der letzte wichtige Schritt besteht darin, die Erkennung eines Teilnehmers durch das Content-Script mit der Methode sendNotification im Hintergrundskript zu verknüpfen. 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-Script zum Hintergrunddienst-Service Worker. Fragen wir 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 an chrome.runtime.sendMessage und chrome.runtime.onMessage.addListener.
Im Wesentlichen verwenden wir sendMessage, um eine Nachricht vom Content-Script zu senden, dass jemand der Videokonferenz beigetreten ist, und onMessage.addListener als Event-Listener, um auf die vom Content-Script gesendete Nachricht zu reagieren. In diesem Fall wird der Aufruf der sendNotification-Methode über diesen Event-Listener ausgelöst.
Wir übergeben die Benachrichtigungsnachricht und die action-Property an den Hintergrunddienst-Service Worker. Das Attribut action beschreibt, worauf das Hintergrundskript reagiert.
Hier ist der 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"
});
}
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"
});
}
Wir versuchen jetzt, die Benachrichtigungsnachricht anzupassen und eine eindeutige Benachrichtigungs-ID zu erhalten. In der Benachrichtigung können wir den Namen des Nutzers angeben. Wie wir uns aus einem vorherigen Schritt erinnern, konnten wir den Namen des Nutzers im title-Attribut des Bildes sehen. Wir können den Namen des Teilnehmers also mit document.querySelector('div.U04fid > img').getAttribute('title'). abrufen.
Bezüglich der Benachrichtigungs-ID können wir die Tab-ID des Inhaltsskripts abrufen und als Benachrichtigungs-ID verwenden. Das kann in unserem Event-Listener chrome.runtime.onMessage.addListener mit sender.tab.id. erreicht werden.
Die Dateien sollten dann in etwa 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 entwickeln. Ganz gleich, ob Sie ein erfahrener Entwickler von Chrome-Erweiterungen sind oder sich gerade erst mit Erweiterungen vertraut machen – Gemini kann Sie bei allen Aufgaben unterstützen.
Ich empfehle dir, nach den verschiedenen Möglichkeiten zu fragen, die du mit einer Chrome-Erweiterung hast. Es gibt viele APIs, die es sich lohnt, zu durchsuchen, z. B. chrome.storage und alarms. Wenn Sie nicht weiterkommen, können Sie Gemini oder die Dokumentation verwenden, um herauszufinden, was Sie falsch machen, oder um verschiedene Möglichkeiten zur Lösung des Problems zu finden.
Oft muss der Prompt angepasst werden, um die benötigte Hilfe zu erhalten. Das ist aber alles auf einem Tab möglich, auf dem der gesamte Kontext erhalten bleibt.