1. מבוא
הצטרפת לשיחה ב-Meet אבל לא רוצה להיות הראשון שעושה זאת? אם תיאור זה מתאים לך, יש לנו פתרון שמתאים לך.
בהמשך ל-Codelab הזה, יוצרים תוסף ל-Chrome ששולח התראה כשהמשתתף הראשון מצטרף לשיחה.
תלמדו על הרכיבים השונים של תוסף ל-Chrome ותעמקו בכל חלק של התוסף. תלמדו על פונקציות של תוספים כגון סקריפטים של תוכן, Service Worker והעברת הודעות.
כדי לקבל התראה בכל פעם שמשתתף מצטרף לשיחה ב-Meet, צריך לפעול בהתאם לגרסה 3 של המניפסט.
2. לפני שמתחילים
דרישות מוקדמות
ה-Codelab הזה מתאים למתחילים, אבל הבנה בסיסית של JavaScript יכולה לשפר מאוד את החוויה שלך.
הגדרה/דרישות
- דפדפן Chrome
- הגדרת סביבת פיתוח משולבת (IDE)/עריכה במערכת המקומית.
- כדי להפעיל את Gemini API באמצעות gcloud, מתקינים את gcloud cli.
הפעלת Gemini API
- במסוף Google Cloud, בדף בורר הפרויקטים, בוחרים או יוצרים פרויקט ב-Google Cloud.
- הקפידו לוודא שהחיוב מופעל בפרויקט שלכם ב-Cloud. איך בודקים אם החיוב מופעל בפרויקט
- מפעילים את ה-API דרך הדף של Gemini Marketplace. אפשר להשתמש ב-gcloud גם כדי להפעיל את ה-API:
gcloud services enable cloudaicompanion.googleapis.com --project PROJECT_ID
- נכנסים לדף של Gemini למסוף Cloud בכרטיסייה חדשה ולוחצים על 'התחלת צ'אט'.
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. אני רוצה להתחיל
התקנה בסיסית של תוסף
בואו ניצור ספרייה שנשתמש בה בתור השורש של הפרויקט שלנו.
mkdir gemini-chrome-ext
cd gemini-chrome-ext
לפני שנתחיל לשאול את Gemini שאלות ספציפיות, נשאל כמה שאלות על המבנה הגנרי של תוסף ל-Chrome.
הנחיה:
What are the important parts to build a chrome extension?
אנחנו מקבלים תשובה שמציינת פרטים קטנים על הקובץ manifest
, background script
ופרטים על ממשק המשתמש. עכשיו ניכנס לפרטים נוספים לגבי הקבצים הספציפיים האלה.
הנחיה:
Create a manifest.json file to build a chrome extension. Make the name of the extension "Meet Joinees Notifier" and the author "<YOUR_EMAIL>"
בשדה המחבר אפשר להשתמש בשם ובכתובת האימייל שלכם.
Gemini מחזיר את התוכן של קובץ המניפסט שאנחנו צריכים, אבל כן מקבלים כמה שדות נוספים שאנחנו לא צריכים, כמו השדה action
. כמו כן, אנחנו צריכים תיאור. יחד נפתור את זה.
הנחיה:
Remove the "action" field and make the description as "Adds the ability to receive a notification when a participant joins a Google meet".
נכניס את התוכן הזה לקובץ 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>"
}
מסירים בינתיים את כל השדות הנוספים שנוצרו בקובץ המניפסט, כי ה-Codelab הזה מניח את השדות האלה בקובץ המניפסט.
איך אנחנו בודקים שהתוסף פועל? שנשאל את החבר שלנו, Gemini?
הנחיה:
Guide me on the steps needed to test a chrome extension on my local filesystem.
כן, יוצגו לי כמה שלבים לבדיקה. כדי לנווט אל "Extensions Page"
, צריך לעבור אל chrome://extensions
ולוודא שהפעלת את הלחצן "Developer Mode"
. הפעולה הזו אמורה לחשוף את הלחצן "Load unpacked"
. נוכל להשתמש בו כדי לנווט לתיקייה שמכילה את קובצי התוספים באופן מקומי. אחרי שנעשה את זה, נוכל לראות את התוסף ב"Extensions Page"
.
נהדר! אנחנו יכולים לראות את התוסף שלנו, אבל נתחיל להוסיף פונקציונליות.
4. הוספת סקריפט תוכן
אנחנו רוצים להריץ קוד JavaScript רק ב-https://meet.google.com
. אפשר לעשות את זה באמצעות סקריפטים של תוכן. בואו נשאל את Gemini איך להשיג את זה בתוסף שלנו.
הנחיה:
How to add a content script in our chrome extension?
או באופן ספציפי יותר:
הנחיה:
How to add a content script to run on meet.google.com subdomain in our chrome extension?
או גרסה אחרת:
הנחיה:
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 מספק לנו את השינויים המדויקים שאנחנו צריכים לבצע בקובץ המניפסט.json, וגם את קוד ה-JavaScript שדרוש לנו בקובץ content.js
.
לאחר ההוספה של content_scripts, קובץ המניפסט הופך ל:
{
"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"]
}
]
}
הפעולה הזו מורה ל-Chrome להחדיר את סקריפט התוכן content.js
בכל פעם שאנחנו עוברים לדף בתת-הדומיין " https://meet.google.com". בואו נוסיף את הקובץ הזה ונבדוק אותו?
עכשיו נוסיף את הקוד הזה לקובץ content.js
.
console.log("Hello Gemini");
בהחלט! כשאנחנו נכנסים לאתר meet.google.com, אנחנו רואים את ההודעה 'שלום Gemini' במסוף 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!");
Ⰲ
נהדר! עכשיו אנחנו נמצאים במצב שבו אנחנו יכולים להוסיף לאפליקציה שלנו פונקציונליות שספציפית ל-JavaScript. נחשוב רגע על מה שאנחנו מנסים להשיג.
שיפור של סקריפט התוכן
אנחנו רוצים להיות מסוגלים לקבל התראה כשמישהו מצטרף לפגישה כשאנחנו נמצאים בדף הפגישה(שבו יש לנו אפשרות להצטרף לפגישה). כדי לעשות זאת, נראה איך המסך משתנה באופן חזותי כשהפגישה ריקה לעומת כשמישהו הצטרף לפגישה.
כך זה נראה כשאין אף אחד בפגישה.
אלה הרכיבים החזותיים שיש בפגישה רק חלק מהמשתתפים.
ניתן לראות מיד שני הבדלים עיקריים:
- טקסט הסטטוס משתנה מ'אין כאן אף אחד אחר'. ל"[משתמש] נמצא בשיחה הזו".
- אנחנו יכולים לראות את התמונות של המשתמשים שהצטרפו לשיחה.
שני השינויים האלה יעזרו לנו אם נרצה לדעת אם מישהו הצטרף לפגישה, אבל כדי לעשות זאת יש כמה אפשרויות לקבל מידע על המשתמשים שכבר הצטרפו. ננסה להשתמש בזה.
פתיחת הכלי לבדיקת הרכיבים ב-Chrome באמצעות מקש הקיצור ( Mac: Cmd + Opt + C / Win: Ctrl + Shift + C
), ולאחר מכן לוחצים על התמונה של המשתמש שהצטרף.
שמנו לב שיש תמונה עם מעט מחרוזות כיתתיות, ובמאפיין הכותרת של התמונה מופיע השם של המשתמש שהצטרף לפגישה. בנוסף, תג התמונה הזה מוקף ב-div עם מחלקה U04fid
. אחרי שנוסיף כמה משתתפים לפגישת הניסיון, נוכל לראות שה-div הזה, ההורה, מארח כמה תמונות(בהתאם למשתמשים שונים).
לכן, יש לנו אסטרטגיה חלקית:
- זיהוי מקרים שבהם ה-div עם המחלקה
U04fid
מכיל רכיבים. - אם כן, סימן שיש לנו משתתפים בפגישה.
- הודעה למשתמש.
נחזור אל Gemini ונשאל איך אפשר לעשות את זה שלב אחרי שלב.
הנחיה:
How to detect for element changes in the HTML page?
כן זה נותן לנו פתרון שקשור ל-MutationObserver
, אבל לא משהו ספציפי לדרישה שלנו. ננסה לשנות את ההנחיה.
הנחיה:
How can I detect if an element "div.U04fid" has any child images in the HTML page?
הפעם אנחנו מקבלים פתרון שלא כולל את MutationObserver
, אלא פתרון שמחפש את המצטרפים החדשים באמצעות פקודת ההורה div.
קיבלנו את הפרטים הבאים:
const divU04fid = document.querySelector('div.U04fid');
const childImages = divU04fid.querySelectorAll('img');
if (childImages.length > 0) {
// div.U04fid has at least one child image.
}
בואו ננסה לשנות את הגישה שלנו עוד יותר:
הנחיה:
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.
הוא מוחזר עם קטע הקוד הבא:
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
});
צריך להעתיק את הקוד הזה לקובץ content.js
, לטעון מחדש את התוסף(ואז לטעון מחדש את דף ה-Meet).
מעכשיו, כשמישהו מצטרף לפגישה שלנו, אנחנו יכולים לראות את דוח היומן במסוף.
5. שליחת התראה למשתמש
עכשיו, כשאנחנו מזהים אם משתתף הצטרף לפגישה, ננסה להוסיף את החלק של ההתראות בתוסף ל-Chrome. אנחנו יכולים לעיין בתיעוד של התוסף ל-Chrome או אפילו לשנות את ההנחיות כדי להבין מה אנחנו מחפשים, אבל בעיקרון אנחנו צריכים להשתמש ב-API של chrome.notifications.create
, והקריאה לשיטה הזו צריכה להתבצע על ידי קובץ שירות ברקע.
הנחיה:
Using the documentation for chrome notifications tell me how to use the chrome.notifications.create method.
ניתן לראות כמה שלבים מפורטים, והעיקרים העיקריים הם:
- מוסיפים את ההרשאה
notifications
בקובץ המניפסט. - אפשר לבצע שיחה אל chrome.notifications.create
- הקריאה צריכה להיות בסקריפט ברקע.
כדי להוסיף סקריפט רקע לתוסף ל-Chrome ב-manifest version 3
, יש צורך בהצהרה background.service_worker
בקובץ manifest.json
שלנו.
לכן, אנחנו יוצרים קובץ בשם background.js ומוסיפים את הקוד הבא לקובץ המניפסט.json.
"background": {
"service_worker": "background.js"
},
"permissions": [
"notifications"
]
בעקבות התוספות שלמעלה, קובץ המניפסט הופך ל:
{
"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"
]
}
הנחיה:
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
שומרים את התמונה הזאת ברמה הבסיסית של התיקייה ומשנים את השם שלה ל-success.png
.
לאחר מכן צריך להוסיף את קטע הקוד הבא ל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");
עכשיו טוענים מחדש את התוסף מדף התוספים ומיד אמור להופיע חלון קופץ של התראה.
6. הוספה של העברת הודעות בתוסף ל-Chrome
עכשיו, השלב העיקרי האחרון שאנחנו צריכים הוא חיבור הזיהוי של משתתף מסוים בסקריפט התוכן והשיטה sendNotification
בסקריפט הרקע. בהקשר של תוספים ל-Chrome, הדרך לעשות זאת היא באמצעות שיטה שנקראת message passing
.
כך מתאפשרת התקשורת בין חלקים שונים של תוסף ל-Chrome, במקרה שלנו, מהסקריפט של התוכן ועד ל-service worker ברקע. נשאל את החבר שלנו Gemini איך לעשות את זה.
הנחיה:
How to send a message from the content script to the background script in a chrome extension
Gemini משיב קריאות רלוונטיות אל chrome.runtime.sendMessage
ואל chrome.runtime.onMessage.addListener
.
למעשה, נשתמש ב-sendMessage
כדי לשלוח הודעה מתסריט התוכן שמישהו הצטרף לשיחה בפגישה, וב-onMessage.addListener
כמאזינים לאירוע כדי להגיב להודעה שנשלחה על ידי תסריט התוכן. במקרה הזה, נפעיל את הקריאה ל-method sendNotification
מה-event listener הזה.
אנחנו נעביר את הודעת ההתראה והמאפיין action
ל-Worker Service ברקע. המאפיין action
מתאר למה סקריפט הרקע מגיב.
הנה קוד 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"
});
}
וזה הקוד 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"
});
}
ננסה להתאים אישית את הודעת ההתראה ולקבל מזהה ייחודי של התראה. בהודעת ההתראה, אנחנו יכולים לכלול את שם המשתמש. אם נזכור את השלב הקודם, נוכל לראות את שם המשתמש במאפיין הכותרת של התמונה. לכן נוכל לאחזר את שם המשתתף באמצעות document.querySelector('div.U04fid > img').getAttribute('title').
בנוגע למזהה ההתראה, אנחנו יכולים לאחזר את מזהה הכרטיסייה של סקריפט התוכן ולהשתמש בו כמזהה התראה. ניתן לעשות זאת מתוך ה-event listener chrome.runtime.onMessage.addListener
באמצעות שימוש ב-sender.tab.id.
לבסוף, הקבצים שלנו אמורים להיראות בערך כך:
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. מזל טוב
תוך זמן קצר הצלחנו לפתח תוסף ל-Chrome בעזרת Gemini. גם מפתחים מנוסים של תוספים ל-Chrome וגם מפתחים חדשים בעולם התוספים – Gemini יכול לעזור לכם בביצוע כל המשימות שרוצים.
אני ממליץ לך לשאול מה אפשר לעשות באמצעות תוסף ל-Chrome. יש הרבה ממשקי API ששווה לעיין בהם, כמו chrome.storage
, alarms
וכו'. בכל מקום שבו נתקלת בבעיה, אפשר להשתמש ב-Gemini או במסמכי התיעוד כדי לדעת מה הייתה הבעיה או לאסוף דרכים שונות לפתרון הבעיה.
לעיתים קרובות צריך לשנות את ההנחיה כדי לקבל את העזרה הנדרשת, אבל אפשר לעשות את זה דרך כרטיסייה אחת ששומרת את כל התהליך לאורך ההקשר.