1. Introduzione
Partecipi a una chiamata di Meet ma non vuoi essere la prima persona a farlo? Se questo è il tuo caso, abbiamo la soluzione che fa per te.
Seguendo questo codelab, creerai un'estensione di Chrome che ti avvisa quando il primo partecipante partecipa alla chiamata.
Imparerai i diversi elementi di un'estensione di Chrome e quindi approfondirai ogni parte dell'estensione. Imparerai a conoscere le funzioni delle estensioni, come gli script dei contenuti, i service worker e la trasmissione dei messaggi.
Devi rispettare la versione 3 del file manifest per poter ricevere una notifica ogni volta che un partecipante partecipa a una chiamata di Meet.
2. Prima di iniziare
Prerequisiti
Sebbene questo codelab sia adatto ai principianti, una conoscenza di base di JavaScript può migliorare notevolmente la tua esperienza.
Configurazione/requisiti
- Il browser Chrome
- Una configurazione IDE/Editor sul sistema locale.
- Installa gcloud cli se vuoi abilitare l'API Gemini utilizzando gcloud.
Abilita l'API Gemini
- Nella pagina del selettore dei progetti della console Google Cloud, seleziona o crea un progetto Google Cloud.
- Verifica che la fatturazione sia attivata per il tuo progetto Cloud. Scopri come controllare se la fatturazione è abilitata per un progetto.
- Vai alla pagina Gemini Marketplace per abilitare l'API. Puoi anche utilizzare gcloud per abilitare l'API:
gcloud services enable cloudaicompanion.googleapis.com --project PROJECT_ID
- Visita la pagina della console Gemini per Cloud in una nuova scheda e fai clic su "Inizia a chattare".
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. Che il divertimento abbia inizio
Installazione di estensioni di base
Creiamo una directory che utilizzeremo come radice del progetto.
mkdir gemini-chrome-ext
cd gemini-chrome-ext
Prima di iniziare a porre domande specifiche a Gemini, facciamo alcune domande sulla struttura generica di un'estensione di Chrome.
Prompt:
What are the important parts to build a chrome extension?
Riceviamo una risposta che specifica piccoli dettagli sul file manifest
, background script
e dettagli sull'interfaccia utente. Diamo un'occhiata più da vicino a questi file specifici.
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>"
Puoi utilizzare un nome e il tuo indirizzo email nel campo dell'autore.
Gemini restituisce i contenuti del file manifest di cui abbiamo bisogno, ma riceviamo alcuni campi aggiuntivi che non ci servono, come il campo action
. Abbiamo anche bisogno di una descrizione. Risolviamo il problema.
Prompt:
Remove the "action" field and make the description as "Adds the ability to receive a notification when a participant joins a Google meet".
Inseriamo questi contenuti nel file manifest.json
all'interno della directory principale del progetto.
A questo punto, il file manifest dovrebbe avere un aspetto simile al seguente.
{
"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>"
}
Per il momento rimuovi eventuali altri campi aggiuntivi generati nel file manifest, poiché questo codelab li prevede nel file manifest.
Come possiamo verificare il funzionamento dell'estensione? Chiediamo al nostro amico Gemini, che ne dici?
Prompt:
Guide me on the steps needed to test a chrome extension on my local filesystem.
Ecco alcuni passaggi per testarla. Accediamo a "Extensions Page"
andando su chrome://extensions
e assicurati di attivare il pulsante "Developer Mode"
, che dovrebbe mostrare il pulsante "Load unpacked"
, che possiamo utilizzare per andare alla cartella che contiene i file dell'estensione localmente. Una volta eseguita questa operazione, dovremmo essere in grado di vedere l'estensione nel "Extensions Page"
.
Bene. Vediamo l'estensione, ma iniziamo ad aggiungere alcune funzionalità.
4. Aggiungi uno script dei contenuti
Vogliamo eseguire del codice JavaScript solo su https://meet.google.com
, cosa che possiamo fare utilizzando gli script di contenuti. Chiediamo a Gemini come ottenere questo risultato nella nostra estensione.
Prompt:
How to add a content script in our chrome extension?
O più nello specifico:
Prompt:
How to add a content script to run on meet.google.com subdomain in our chrome extension?
O un'altra versione:
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 ci fornisce le modifiche esatte che dobbiamo apportare nel file manifest.json, nonché il codice JavaScript necessario nel file content.js
.
Con l'aggiunta di content_scripts, il nostro file manifest diventa:
{
"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"]
}
]
}
Questo indica a Chrome di inserire lo script dei contenuti content.js
ogni volta che accediamo a una pagina del sottodominio " https://meet.google.com". Aggiungiamo questo file e testiamolo, giusto?
Aggiungiamo questo codice nel file content.js
.
console.log("Hello Gemini");
Certamente. Quando visitiamo meet.google.com vediamo "Hello Gemini" nella console 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!");
Ⰲ
Bene. Ora siamo in grado di aggiungere alcune funzionalità specifiche di JavaScript alla nostra app. Fermiamoci un attimo a pensare a ciò che stiamo cercando di ottenere.
Migliorare il copione dei contenuti
Vogliamo essere in grado di ricevere una notifica quando qualcuno partecipa a una riunione, quando siamo sulla pagina della riunione(dove è disponibile l'opzione per partecipare alla riunione). A questo scopo, osserviamo come cambia visivamente lo schermo quando la riunione è vuota rispetto a quando qualcuno partecipa.
Ecco come appare quando non c'è nessuno in riunione.
mentre queste sono le immagini di alcuni partecipanti alla riunione.
Possiamo notare subito due importanti differenze:
- Il testo dello stato cambia da "Non c'è nessun altro qui" a "[Utente] è presente nella chiamata".
- Possiamo vedere le immagini degli utenti che partecipano alla chiamata.
Entrambe queste modifiche sono utili se vogliamo sapere se qualcuno si è unito alla riunione, ma quest'ultima ha alcune possibilità di ottenere informazioni sugli utenti che si sono già uniti, quindi proviamo a utilizzarla.
Apri "Controllo elementi" in Chrome con la scorciatoia ( Mac: Cmd + Opt + C / Win: Ctrl + Shift + C
), quindi fai clic sull'immagine dell'utente che si è unito.
Possiamo notare che c'è un'immagine con poche stringhe di classe e l'attributo title dell'immagine ha il nome dell'utente che si è unito alla riunione. Inoltre, questo tag immagine è aggregato in un div con classe U04fid
. Dopo aver aggiunto alcuni partecipanti alla riunione di prova, possiamo vedere che questo div principale ospita più immagini(corrispondenti a utenti diversi).
Pertanto, abbiamo in mente una strategia parziale:
- Rileva quando l'elemento div con la classe
U04fid
contiene elementi. - In caso affermativo, significa che abbiamo dei partecipanti alla riunione.
- Invia una notifica all'utente.
Torniamo a Gemini e ti chiediamo come possiamo farlo passo passo.
Prompt:
How to detect for element changes in the HTML page?
Viene fornita una soluzione che prevede MutationObserver
, ma non c'è nulla di specifico per il nostro requisito. Proviamo a modificare il prompt.
Prompt:
How can I detect if an element "div.U04fid" has any child images in the HTML page?
Questa volta otteniamo una soluzione che non include MutationObserver
, ma una soluzione che controlla i join utilizzando l'elemento div padre.
Ecco cosa abbiamo ricevuto:
const divU04fid = document.querySelector('div.U04fid');
const childImages = divU04fid.querySelectorAll('img');
if (childImages.length > 0) {
// div.U04fid has at least one child image.
}
Proviamo a modificare ulteriormente il nostro approccio:
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.
Viene restituito con il seguente snippet di codice:
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
});
Copia questo codice nel file content.js
, ricarica l'estensione(quindi ricarica la pagina di Meet).
Ora, quando qualcuno partecipa alla riunione, possiamo vedere l'istruzione di log nella console.
5. Invia una notifica all'utente
Ora che siamo in grado di rilevare quando un partecipante si è unito alla riunione, proviamo ad aggiungere la parte relativa alle notifiche nella nostra estensione di Chrome. Possiamo sfogliare la documentazione dell'estensione di Chrome o persino modificare le richieste per sapere cosa stiamo cercando, ma sostanzialmente dobbiamo utilizzare l'API chrome.notifications.create
e la chiamata a questo metodo deve essere effettuata da un service worker in background.
Prompt:
Using the documentation for chrome notifications tell me how to use the chrome.notifications.create method.
Vediamo alcuni passaggi dettagliati, i cui punti salienti sono i seguenti:
- Aggiungi l'autorizzazione
notifications
nel file manifest. - Chiama il file chrome.notifications.create
- La chiamata deve essere in uno script in background.
Per aggiungere uno script in background a un'estensione di Chrome in manifest version 3
, abbiamo bisogno della dichiarazione background.service_worker
nel file manifest.json
.
Pertanto, creiamo un file denominato background.js e aggiungiamo quanto segue al file manifest.json.
"background": {
"service_worker": "background.js"
},
"permissions": [
"notifications"
]
Con le aggiunte di cui sopra, il nostro file manifest diventa:
{
"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
Salva questa immagine nella directory principale della cartella e rinominala in success.png
.
Poi aggiungi il seguente snippet di codice a background.js
.
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");
Ora ricarica l'estensione dalla pagina delle estensioni. Dovresti vedere subito una notifica popup.
6. Aggiungi la trasmissione di messaggi nell'estensione di Chrome
L'ultimo passaggio importante di cui abbiamo bisogno è collegare il rilevamento di un partecipante tramite lo script dei contenuti al metodo sendNotification
nello script in background. Nel contesto delle estensioni di Chrome, questo è possibile attraverso una tecnica chiamata message passing
.
Ciò consente la comunicazione tra diverse parti di un'estensione di Chrome, nel nostro caso dallo script dei contenuti al service worker in background. Chiediamo al nostro amico Gemini come ottenere questo risultato.
Prompt:
How to send a message from the content script to the background script in a chrome extension
Gemini risponde con chiamate pertinenti a chrome.runtime.sendMessage
e chrome.runtime.onMessage.addListener
.
Essenzialmente, utilizzeremo sendMessage
per inviare un messaggio dallo script di contenuti che informa che qualcuno ha partecipato alla chiamata di Meet e onMessage.addListener
come listener di eventi per reagire al messaggio inviato dallo script dei contenuti. In questo caso attiveremo la chiamata al metodo sendNotification
da questo listener di eventi.
Trasmetteremo il messaggio di notifica e una proprietà action
al service worker in background. La proprietà action
descrive a cosa risponde lo script in background.
Quindi, ecco il nostro codice 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) {
// 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"
});
}
E questo è il nostro codice per background.js
:
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"
});
}
Proviamo a personalizzare il messaggio di notifica in modo da ottenere un ID notifica univoco. Per il messaggio di notifica, possiamo includere il nome dell'utente. Se richiamiamo da un passaggio precedente, potremmo vedere il nome dell'utente nell'attributo titolo dell'immagine. Possiamo quindi recuperare il nome del partecipante utilizzando document.querySelector('div.U04fid > img').getAttribute('title').
Per quanto riguarda l'ID notifica, possiamo recuperare l'ID scheda dello script dei contenuti e utilizzarlo come ID notifica. A questo scopo, usa sender.tab.id.
nel nostro listener di eventi chrome.runtime.onMessage.addListener
.
Infine, i file dovrebbero avere un aspetto simile al seguente:
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. Complimenti
In breve tempo siamo riusciti a creare un'estensione di Chrome con l'aiuto di Gemini. Che tu sia uno sviluppatore esperto di estensioni di Chrome o un nuovo mondo delle estensioni, Gemini può aiutarti a svolgere qualsiasi attività tu voglia svolgere.
Ti invito a chiedere informazioni sulle varie cose che puoi fare con un'estensione di Chrome. Ci sono molte API che vale la pena esplorare, come chrome.storage
, alarms
e così via. Ovunque ti senti bloccato, utilizza Gemini o la documentazione per sapere cosa stai facendo male o per raccogliere diversi modi per risolvere il problema.
Spesso è necessario modificare il prompt per ottenere l'aiuto necessario, ma è possibile farlo da una scheda che conserva tutto il nostro percorso contestuale.