1. Einführung
Nehmen Sie an einem Meet-Anruf teil, möchten aber nicht der Erste sein? Wenn dies auf Sie zutrifft, haben wir die Lösung für Sie.
Nach diesem Codelab erstellen Sie eine Chrome-Erweiterung, die Sie benachrichtigt, wenn der erste Teilnehmer am Anruf teilnimmt.
Sie lernen die verschiedenen Elemente von Chrome-Erweiterungen kennen und sehen uns die einzelnen Bestandteile dann genauer an. Sie lernen Erweiterungsfunktionen wie Inhaltsskripte, Service Worker und die Nachrichtenweitergabe kennen.
Sie müssen sich an die Version 3 des Manifests halten, um jedes Mal eine Benachrichtigung zu erhalten, wenn ein Teilnehmer an einem Meet-Anruf teilnimmt.
2. Hinweis
Vorbereitung
Dieses Codelab ist zwar für Einsteiger geeignet, ein grundlegendes Verständnis von JavaScript kann jedoch zu erheblichen Verbesserungen bei der Nutzung führen.
Einrichtung/Anforderungen
- Chrome-Browser
- Eine IDE/ein Editor, die auf Ihrem lokalen System eingerichtet ist.
- Installieren Sie 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 für die Projektauswahl ein Google Cloud-Projekt aus oder erstellen Sie eines.
- Die Abrechnung für das Cloud-Projekt muss aktiviert sein. Hier erfahren Sie, wie Sie prüfen, 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 für die 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
Grundlegende Installation von Erweiterungen
Lassen Sie uns ein Verzeichnis erstellen, das wir als Stammverzeichnis Ihres Projekts verwenden.
mkdir gemini-chrome-ext
cd gemini-chrome-ext
Bevor wir konkrete Fragen an Gemini stellen, sollten wir einige Fragen zur allgemeinen Struktur einer Chrome-Erweiterung stellen.
Prompt:
What are the important parts to build a chrome extension?
Wir erhalten eine Antwort mit kleineren Details zur Datei manifest
, zum background script
und Details zur Benutzeroberfläche. Sehen wir uns diese Dateien etwas 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 gewünschten Namen und Ihre E-Mail-Adresse im Feld für den Autor eingeben.
Gemini gibt den benötigten Inhalt der Manifestdatei zurück, aber wir erhalten einige zusätzliche Felder, die wir nicht benötigen, 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 Sie diesen Inhalt in die Datei manifest.json
im Stammverzeichnis Ihres Projekts ein.
Die Manifestdatei sollte nun 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 zusätzlichen Felder, die in Ihrer Manifestdatei generiert wurden, da in diesem Codelab von diesen Feldern in Ihrer Manifestdatei ausgegangen wird.
Wie testen wir nun, ob die Erweiterung funktioniert? Fragen wir unsere Freundin Gemini, ok?
Prompt:
Guide me on the steps needed to test a chrome extension on my local filesystem.
Es gibt mir einige Schritte, wie ich es testen kann. Rufen Sie die "Extensions Page"
auf, indem Sie zu chrome://extensions
gehen. Achten Sie darauf, die Schaltfläche "Developer Mode"
zu aktivieren. Dadurch sollte die Schaltfläche "Load unpacked"
angezeigt werden, mit der wir zum Ordner wechseln können, der lokal die Erweiterungsdateien enthält. Danach sollten wir die Erweiterung in "Extensions Page"
sehen können.
Sehr gut! Wir sehen unsere Erweiterung, fügen aber jetzt einige Funktionen hinzu.
4. Inhaltsskript hinzufügen
Wir möchten JavaScript-Code nur auf https://meet.google.com
ausführen, was wir mithilfe von Inhaltsskripten tun können. Fragen wir Gemini, wie wir das mit 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 liefert uns die genauen Änderungen, die wir an der Datei „manifest.json“ und im JavaScript-Code in der content.js
-Datei vornehmen müssen.
Durch das Hinzufügen von „content_scripts“ wird unsere Manifestdatei zu:
{
"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
jedes Mal einzuschleusen, wenn wir eine Seite der Subdomain aufrufen https://meet.google.com“. Lassen Sie uns diese Datei hinzufügen und testen, oder?
Fügen wir diesen Code in die Datei content.js
ein.
console.log("Hello Gemini");
Ja, klar. Wenn wir meet.google.com aufrufen, sehen wir „Hallo Gemini“ in der JavaScript-Konsole(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("Hallo Gemini!").
à
Sehr gut! Jetzt können wir unserer App JavaScript-spezifische Funktionen hinzufügen. Nehmen wir uns einen Moment Zeit, um darüber nachzudenken, was wir erreichen möchten.
Script für Inhalte optimieren
Wir möchten eine Benachrichtigung erhalten, wenn jemand an einer Besprechung teilnimmt, wenn wir uns auf der Besprechungsseite befinden(wo wir die Möglichkeit haben, an der Besprechung teilzunehmen). Dazu sehen wir uns an, wie sich der Bildschirm visuell verändert, wenn die Besprechung leer ist und wenn jemand der Besprechung beigetreten ist.
So sieht es aus, wenn niemand im Meeting ist.
Dagegen sind dies die visuellen Elemente, wenn einige Teilnehmer an dem Meeting teilnehmen.
Zwei wichtige Unterschiede sind sofort erkennbar:
- Der Statustext ändert sich von „Keine andere Person ist hier“. zu „[Nutzer] nimmt an diesem Anruf teil“.
- Wir sehen die Bilder der Nutzer, die am Anruf teilnehmen.
Beide Änderungen sind für uns geeignet, wenn wir wissen möchten, ob jemand der Besprechung beigetreten ist. Letzteres hat jedoch einige Möglichkeiten, Informationen über die Nutzer abzurufen, die bereits beigetreten sind. Versuchen wir also, diese zu verwenden.
Elements Inspector öffnen in Chrome mit dem Hotkey ( Mac: Cmd + Opt + C / Win: Ctrl + Shift + C
) und klicken Sie dann auf das Bild des beigetretenen Nutzers.
Wir sehen, dass ein Bild mit wenigen Klassenzeichenfolgen vorhanden ist und das Titelattribut des Bildes den Namen des Nutzers enthält, der an der Besprechung teilnimmt. Darüber hinaus ist dieses Bild-Tag in ein div-Element der Klasse U04fid
eingeschlossen. Nachdem wir einige Teilnehmer zu unserer Testbesprechung hinzugefügt haben, sehen wir, dass dieses übergeordnete div-Element mehrere Images hostet, die verschiedenen Nutzern entsprechen.
Wir haben also eine Teilstrategie im Kopf:
- Erkennt, wenn das div-Element mit der Klasse
U04fid
Elemente enthält. - Wenn dies der Fall ist, bedeutet das, dass wir Teilnehmer an unserem Meeting haben.
- Benachrichtigen Sie den Nutzer.
Kehren wir zu Gemini zurück und fragen wir, wie wir dies Schritt für Schritt erreichen können.
Prompt:
How to detect for element changes in the HTML page?
Es liefert uns eine Lösung mit MutationObserver
, aber nichts speziell 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 MutationObserver
nicht enthält, sondern eine Lösung, die mithilfe des übergeordneten div-Elements nach den Joinees sucht.
Wir haben Folgendes 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.
Sie gibt das folgende Code-Snippet zurück:
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
, aktualisieren Sie die Erweiterung und aktualisieren Sie dann die Meet-Seite.
Wenn jetzt jemand an unserer Besprechung teilnimmt, sehen wir die Protokollanweisung in der Konsole.
5. Benachrichtigung an den Nutzer senden
Jetzt können wir erkennen, wenn ein Teilnehmer der Videokonferenz beigetreten ist. Als Nächstes fügen wir der Chrome-Erweiterung den Benachrichtigungsteil hinzu. Wir können in der Dokumentation der Chrome-Erweiterung nachsehen oder sogar die Eingabeaufforderungen optimieren, um zu wissen, wonach wir suchen. Im Wesentlichen müssen wir jedoch die chrome.notifications.create
API verwenden und der Aufruf dieser Methode sollte von einem Hintergrunddienst-Worker stammen.
Prompt:
Using the documentation for chrome notifications tell me how to use the chrome.notifications.create method.
Wir sehen hier einige detaillierte Schritte. Die wichtigsten sind:
- Fügen Sie der Manifestdatei die Berechtigung
notifications
hinzu. - Rufen Sie chrome.notifications.create auf.
- Der Aufruf sollte sich in einem Hintergrundskript befinden.
Um einer Chrome-Erweiterung in manifest version 3
ein Hintergrundskript hinzuzufügen, benötigen wir die background.service_worker
-Deklaration in unserer manifest.json
-Datei.
Also erstellen wir eine Datei namens background.js und fügen der Datei „manifest.json“ Folgendes hinzu:
"background": {
"service_worker": "background.js"
},
"permissions": [
"notifications"
]
Durch die oben genannten Ergänzungen wird unsere Manifestdatei zu:
{
"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 das Bild im Stammverzeichnis Ihres Ordners und benennen Sie es in success.png
um.
Fügen Sie dann das folgende Code-Snippet in die 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");
Wenn Sie die Erweiterung jetzt über die Seite „Erweiterungen“ aktualisieren, sollte sofort ein Pop-up-Benachrichtigungs-Pop-up angezeigt werden.
6. Nachrichtenübergabe in der Chrome-Erweiterung hinzufügen
Der letzte große Schritt besteht darin, die Erkennung eines Teilnehmers durch das Inhaltsskript mit der Methode sendNotification
im Hintergrundskript zu verbinden. Bei Chrome-Erweiterungen erfolgt dies über eine Technik namens message passing
.
Dies ermöglicht die Kommunikation zwischen verschiedenen Teilen einer Chrome-Erweiterung, in unserem Fall vom Content-Skript bis zum Hintergrund-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 Anrufen an chrome.runtime.sendMessage
und chrome.runtime.onMessage.addListener
.
Im Wesentlichen verwenden wir sendMessage
, um über das Inhaltsskript eine Nachricht zu senden, dass eine Person am Meet-Anruf teilnimmt, und onMessage.addListener
als Ereignis-Listener, um auf die vom Inhaltsskript gesendete Nachricht zu reagieren. In diesem Fall lösen wir den Aufruf der Methode sendNotification
von diesem Ereignis-Listener aus.
Wir übergeben die Benachrichtigung und die Eigenschaft action
an den Hintergrund-Service-Worker. Die Eigenschaft action
beschreibt, worauf das Hintergrundskript reagiert.
Hier ist also 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"
});
}
Versuchen wir, die Benachrichtigungsnachricht anzupassen, um eine eindeutige Benachrichtigungs-ID zu erhalten. In der Benachrichtigungsnachricht können wir den Namen des Nutzers angeben. Wenn wir uns aus einem vorherigen Schritt erinnern, können wir den Namen des Nutzers im Titelattribut des Bildes sehen. Wir können also den Namen des Teilnehmers mithilfe von document.querySelector('div.U04fid > img').getAttribute('title').
abrufen.
In Bezug auf die Benachrichtigungs-ID können wir die Tab-ID des Content-Skripts abrufen und als Benachrichtigungs-ID verwenden. Hierzu können Sie in unserem Event-Listener chrome.runtime.onMessage.addListener
die Funktion sender.tab.id.
verwenden.
Die Dateien sollten 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 mithilfe von Gemini eine Chrome-Erweiterung erstellen. Ganz gleich, ob du ein erfahrener Entwickler von Chrome-Erweiterungen bist oder noch keine Erfahrung mit Erweiterungen hast – Gemini kann dir bei allen Aufgaben helfen,die du erreichen möchtest.
Ich empfehle Ihnen, sich nach den verschiedenen Möglichkeiten zu erkundigen, die eine Chrome-Erweiterung bietet. Es gibt viele APIs, die sich lohnen, z. B. chrome.storage
oder alarms
. Wenn du nicht weiterkommst, verwende Gemini oder die Dokumentation, um zu erfahren, was du falsch machst, oder um verschiedene Lösungsmöglichkeiten zu finden.
Oft müssen Prompts angepasst werden, um die benötigte Hilfe zu erhalten. Wir können dies aber über einen Tab tun, auf dem alle unsere kontextbezogenen Schritte gespeichert bleiben.