1. مقدمه
آیا به یک تماس ملاقات میپیوندید اما نمیخواهید اولین کسی باشید که این کار را انجام میدهد؟ اگر این شما را توصیف می کند، ما راه حلی برای شما داریم!
با پیروی از این لبه کد، یک برنامه افزودنی کروم ایجاد میکنید که زمانی که اولین شرکتکننده به تماس میپیوندد به شما هشدار میدهد.
عناصر مختلف یک افزونه کروم را یاد خواهید گرفت و سپس در هر قسمت از افزونه غواصی عمیق خواهید داشت. شما در مورد توابع برنامه افزودنی مانند اسکریپت های محتوا، کارکنان خدمات و ارسال پیام یاد خواهید گرفت.
باید به نسخه مانیفست نسخه 3 پایبند باشید تا بتوانید هر زمان که یک شرکتکننده به تماس ملاقات میپیوندد، اعلان دریافت کنید.
2. قبل از شروع
پیش نیازها
در حالی که این کد برای مبتدیان مناسب است، داشتن یک درک اساسی از جاوا اسکریپت می تواند تجربه شما را بسیار افزایش دهد.
راه اندازی / الزامات
- مرورگر کروم
- راه اندازی IDE/Editor در سیستم محلی شما.
- اگر میخواهید Gemini API را با استفاده از gcloud فعال کنید ، gcloud cli را نصب کنید.
Gemini API را فعال کنید
- در Google Cloud Console ، در صفحه انتخاب پروژه، یک پروژه Google Cloud را انتخاب یا ایجاد کنید.
- مطمئن شوید که صورتحساب برای پروژه Cloud شما فعال است. با نحوه بررسی فعال بودن صورتحساب در پروژه آشنا شوید.
- برای فعال کردن API به صفحه Gemini Marketplace بروید. همچنین میتوانید از gcloud برای فعال کردن API استفاده کنید:
gcloud services enable cloudaicompanion.googleapis.com --project PROJECT_ID
- از صفحه کنسول Gemini for 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 کنیم، اجازه دهید چند سؤال در مورد ساختار عمومی یک افزونه کروم بپرسیم.
اعلان:
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>"
}
هر فیلد اضافی دیگری که در فایل مانیفست شما ایجاد شده است را فعلا حذف کنید زیرا این کد لبه این فیلدها را در فایل مانیفست شما فرض می کند.
حال، چگونه آزمایش کنیم که افزونه کار می کند؟ بیایید از دوستمان جوزا بپرسیم، درست است؟
اعلان:
Guide me on the steps needed to test a chrome extension on my local filesystem.
چند مرحله در مورد نحوه تست کردن آن به من می دهد. بیایید با رفتن به chrome://extensions
به "Extensions Page"
بروید و مطمئن شوید که دکمه "Developer Mode"
فعال کردهاید، که باید دکمه "Load unpacked"
را نشان دهد، که میتوانیم از آن برای پیمایش به پوشهای که حاوی فایل های پسوند به صورت محلی وقتی این کار را انجام دادیم، باید بتوانیم برنامه افزودنی را در "Extensions Page"
ببینیم.
عالیه ما میتوانیم برنامه افزودنی خود را ببینیم، اما بیایید شروع به اضافه کردن برخی عملکردها کنیم.
4. یک اسکریپت محتوا اضافه کنید
ما می خواهیم تعدادی کد جاوا اسکریپت را فقط در 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 تغییرات دقیقی را به ما می دهد که باید در فایل manifest.json و همچنین جاوا اسکریپتی که در فایل 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"]
}
]
}
این به کروم میگوید هر زمان که به صفحهای در زیر دامنه « https://meet.google.com » میرویم، محتوای اسکریپت content.js
را تزریق کند. بیایید این فایل را اضافه کنیم و آن را آزمایش کنیم؟
بیایید این کد را در فایل content.js
اضافه کنیم.
console.log("Hello Gemini");
مطمئنا به اندازه کافی! وقتی از meet.google.com بازدید می کنیم، "Hello Gemini" را در کنسول جاوا اسکریپت می بینیم (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!");
عالیه اکنون در موقعیتی هستیم که می توانیم برخی از قابلیت های خاص جاوا اسکریپت را به برنامه خود اضافه کنیم. بیایید لحظه ای وقت بگذاریم و به آنچه می خواهیم دست یابیم فکر کنیم.
بهبود اسکریپت محتوا
ما میخواهیم زمانی که شخصی به جلسه میپیوندد، زمانی که در صفحه جلسه هستیم (جایی که گزینهای برای پیوستن به جلسه داریم)، بتوانیم اعلان دریافت کنیم. برای دستیابی به این، بیایید مشاهده کنیم که چگونه صفحه نمایش از نظر بصری وقتی جلسه خالی است در مقابل زمانی که شخصی به جلسه میپیوندد، تغییر میکند.
وقتی کسی در جلسه نیست اینطور به نظر می رسد.
در حالی که اینها تصاویر زمانی است که برخی از شرکت کنندگان در جلسه هستند.
ما می توانیم 2 تفاوت قابل توجه را در همان لحظه مشاهده کنیم:
- متن وضعیت از "هیچ کس دیگری اینجا نیست" به "[کاربر] در این تماس است" تغییر می کند.
- ما می توانیم تصاویر کاربرانی که به این تماس ملحق شده اند را مشاهده کنیم.
اگر بخواهیم بدانیم آیا کسی به جلسه پیوسته است یا خیر، هر دوی این تغییرات برای ما کارساز خواهد بود، اما دومی امکاناتی برای دریافت اطلاعات در مورد کاربرانی که قبلاً پیوستهاند را دارد، بنابراین بیایید سعی کنیم از آن استفاده کنیم.
"Elements Inspector" را در کروم با کلید میانبر باز کنید ( Mac: Cmd + Opt + C / Win: Ctrl + Shift + C
) سپس روی تصویر کاربری که به آن پیوسته کلیک کنید.
میتوانیم متوجه شویم که یک تصویر با رشتههای کلاسی کمی وجود دارد و ویژگی عنوان تصویر، نام کاربری دارد که به جلسه ملحق شده است. علاوه بر این، این تگ تصویر در یک div با کلاس U04fid
پیچیده شده است. هنگامی که تعدادی عضو به جلسه آزمایشی خود اضافه می کنیم، می توانیم ببینیم که این div والد چندین تصویر (مرتبط با کاربران مختلف) را میزبانی می کند.
بنابراین، ما یک استراتژی جزئی در ذهن داریم:
- تشخیص دهید که div با کلاس
U04fid
دارای هر عنصری است. - اگر این کار را کرد، به این معنی است که ما در جلسه خود اعضایی داریم.
- به کاربر اطلاع دهید.
بیایید به جمینی برگردیم و بپرسیم که چگونه میتوانیم قدم به قدم به این هدف برسیم.
اعلان:
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 را دوباره بارگیری کنید).
اکنون هنگامی که شخصی به جلسه ما میپیوندد، میتوانیم عبارت log را در کنسول ببینیم.
5. یک اعلان برای کاربر ارسال کنید
اکنون که میتوانیم تشخیص دهیم که یک شرکتکننده چه زمانی به جلسه ملحق شده است، بیایید سعی کنیم بخش اعلان را در برنامه افزودنی کروم خود اضافه کنیم. ما میتوانیم اسناد افزونه کروم را مرور کنیم یا حتی درخواستها را تغییر دهیم تا بدانیم به دنبال چه چیزی هستیم، اما اساساً باید از API chrome.notifications.create
استفاده کنیم و تماس با این روش باید از طرف یک سرویسدهنده پسزمینه باشد.
اعلان:
Using the documentation for chrome notifications tell me how to use the chrome.notifications.create method.
ما برخی از مراحل دقیق را مشاهده می کنیم که مهمترین آنها عبارتند از:
- مجوز
notifications
را در فایل مانیفست اضافه کنید. - با chrome.notifications.create تماس بگیرید
- تماس باید در یک اسکریپت پس زمینه باشد.
برای افزودن یک اسکریپت پسزمینه به افزونه کروم در manifest version 3
، به اعلان background.service_worker
در فایل manifest.json
نیاز داریم.
بنابراین، یک فایل به نام background.js ایجاد می کنیم و موارد زیر را به فایل manifest.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. ارسال پیام را در برنامه افزودنی کروم خود اضافه کنید
اکنون، آخرین مرحله مهمی که نیاز داریم این است که شناسایی یک شرکتکننده توسط اسکریپت محتوا و روش sendNotification
را در اسکریپت پسزمینه وصل کنیم. در زمینه افزونههای کروم، راه انجام این کار از طریق تکنیکی به نام message passing
است.
این امکان برقراری ارتباط بین بخشهای مختلف یک برنامه افزودنی کروم را فراهم میکند، در مورد ما از اسکریپت محتوا تا کارگر خدمات پسزمینه. بیایید از دوستمان جوزا بپرسیم که چگونه می توان به آن دست یافت.
اعلان:
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
برای ارسال پیامی از اسکریپت محتوا مبنی بر اینکه شخصی به تماس meet ملحق شده است و onMessage.addListener
به عنوان شنونده رویداد برای واکنش به پیام ارسال شده توسط اسکریپت محتوا استفاده خواهیم کرد. در این صورت، تماس با متد sendNotification
را از این شنونده رویداد آغاز خواهیم کرد.
ما پیام اعلان و یک ویژگی action
را به کارمند خدمات پسزمینه ارسال میکنیم. ویژگی 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').
در مورد شناسه اعلان، میتوانیم شناسه برگه اسکریپت محتوا را واکشی کنیم و از آن به عنوان شناسه اعلان استفاده کنیم. با استفاده از sender.tab.id می توان این کار را در شنونده رویداد 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. تبریک می گویم
در مدت کوتاهی توانستیم با کمک Gemini یک افزونه کروم بسازیم. چه یک توسعهدهنده برنامههای افزودنی کروم با تجربه باشید، یا تازه وارد دنیای برنامههای افزودنی باشید، Gemini میتواند در انجام هر کاری که میخواهید به شما کمک کند.
من شما را تشویق می کنم در مورد کارهای مختلفی که می توانید با افزونه کروم انجام دهید بپرسید. API های زیادی مانند chrome.storage
، alarms
و غیره ارزش مرور دارند. هر جا که احساس کردید گیر کرده اید، از Gemini یا اسناد استفاده کنید تا بدانید چه اشتباهی انجام می دهید یا راه های مختلفی برای حل مشکل جمع آوری کنید.
برای دریافت کمک مورد نیاز، اغلب نیاز به تغییر اعلان است، اما میتوانیم این کار را از یک برگه انجام دهیم که تمام سفر متنی ما را حفظ میکند.