कोडलैब (कोड बनाना सीखना): Gemini का इस्तेमाल करके JavaScript में Chrome एक्सटेंशन बनाना

1. परिचय

क्या आपको किसी मीटिंग कॉल में शामिल होना है, लेकिन आपको सबसे पहले शामिल नहीं होना है? अगर आप भी इनमें से किसी समस्या का सामना कर रहे हैं, तो हमारे पास आपके लिए इसका समाधान है!

इस कोडलैब को पूरा करने के बाद, आपको एक Chrome एक्सटेंशन बनाना होगा. यह एक्सटेंशन, कॉल में पहले व्यक्ति के शामिल होने पर आपको सूचना देगा.

आपको Chrome एक्सटेंशन के अलग-अलग एलिमेंट के बारे में जानकारी मिलेगी. इसके बाद, एक्सटेंशन के हर हिस्से के बारे में ज़्यादा जानकारी मिलेगी. आपको एक्सटेंशन के फ़ंक्शन के बारे में जानकारी मिलेगी. जैसे, कॉन्टेंट स्क्रिप्ट, सर्विस वर्कर, और मैसेज पास करना.

मीटिंग में शामिल होने वाले हर व्यक्ति की सूचना पाने के लिए, आपको Manifest v3 रिलीज़ का पालन करना होगा.

2. शुरू करने से पहले

ज़रूरी शर्तें

यह कोडलैब, शुरुआती लोगों के लिए सही है. हालांकि, JavaScript की बुनियादी जानकारी होने से, आपको बेहतर अनुभव मिल सकता है.

सेटअप/ज़रूरी शर्तें

  • Chrome ब्राउज़र
  • आपके लोकल सिस्टम पर आईडीई/एडिटर सेटअप होना चाहिए.
  • अगर आपको gcloud का इस्तेमाल करके Gemini API चालू करना है, तो gcloud cli इंस्टॉल करें.

Gemini API को चालू करना

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>"
}

फ़िलहाल, अपनी मेनिफ़ेस्ट फ़ाइल में जनरेट किए गए किसी भी अन्य फ़ील्ड को हटाएं. ऐसा इसलिए, क्योंकि इस कोडलैब में यह माना गया है कि ये फ़ील्ड आपकी मेनिफ़ेस्ट फ़ाइल में मौजूद हैं.

अब हम यह कैसे जांचें कि एक्सटेंशन काम कर रहा है या नहीं? आइए, अपने दोस्त 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" में एक्सटेंशन दिखना चाहिए.

3d802a497ce0cfc2.png

92db1999a1800ecd.png

बढ़िया! हमें अपना एक्सटेंशन दिख रहा है. अब इसमें कुछ सुविधाएं जोड़ते हैं.

4. कॉन्टेंट स्क्रिप्ट जोड़ना

हमें सिर्फ़ https://meet.google.com पर कुछ JavaScript कोड चलाना है. इसके लिए, हम कॉन्टेंट स्क्रिप्ट का इस्तेमाल कर सकते हैं. आइए, 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 फ़ाइल में इस्तेमाल की जाने वाली JavaScript के बारे में भी बताता है.

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 को यह पता चलता है कि जब भी हम " https://meet.google.com" सबडोमेन में किसी पेज पर जाते हैं, तो कॉन्टेंट स्क्रिप्ट content.js को इंजेक्ट करना है. चलिए, इस फ़ाइल को जोड़ते हैं और इसकी जाँच करते हैं.

आइए, इस कोड को content.js फ़ाइल में जोड़ते हैं.

console.log("Hello Gemini");

बिलकुल! जब हम meet.google.com पर जाते हैं, तो हमें JavaScript कंसोल(Mac: Cmd + Opt + J / Win/Linux: Ctrl + Shift + J) पर "Hello 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!");

6216bab627c31e6c.png

d61631cd9962ffe5.png

बढ़िया! अब हम अपने ऐप्लिकेशन में, JavaScript की कुछ खास सुविधाएं जोड़ सकते हैं. आइए, एक पल के लिए सोचें कि हमें क्या हासिल करना है.

कॉन्टेंट स्क्रिप्ट को बेहतर बनाना

हमें मीटिंग पेज पर होने पर, किसी व्यक्ति के मीटिंग में शामिल होने की सूचना मिलनी चाहिए. मीटिंग पेज पर, मीटिंग में शामिल होने का विकल्प होता है. इसके लिए, आइए देखते हैं कि मीटिंग में कोई व्यक्ति न होने पर स्क्रीन कैसी दिखती है और जब कोई व्यक्ति मीटिंग में शामिल हो जाता है, तब स्क्रीन कैसी दिखती है.

मीटिंग में किसी के शामिल न होने पर, स्क्रीन ऐसी दिखती है.

fe5a0c95b20e7f72.png

वहीं, मीटिंग में कुछ लोगों के शामिल होने पर ये विज़ुअल दिखते हैं.

7a5ef60521d961cc.png

हमें यहां दो मुख्य अंतर दिख रहे हैं:

  1. स्टेटस टेक्स्ट "कोई और नहीं है" से बदलकर "[उपयोगकर्ता] इस कॉल में है" हो जाता है.
  2. हम कॉल में शामिल हुए लोगों की इमेज देख सकते हैं.

अगर हमें यह जानना है कि मीटिंग में कौन शामिल हुआ है, तो ये दोनों बदलाव हमारे लिए काम करेंगे. हालांकि, दूसरे बदलाव से हमें उन उपयोगकर्ताओं के बारे में जानकारी मिल सकती है जो पहले ही शामिल हो चुके हैं. इसलिए, आइए इसका इस्तेमाल करके देखें.

Chrome में हॉटकी ( Mac: Cmd + Opt + C / Win: Ctrl + Shift + C) की मदद से "Elements Inspector" खोलें. इसके बाद, शामिल हुए उपयोगकर्ता की इमेज पर क्लिक करें.

हम देख सकते हैं कि यहां कुछ क्लास स्ट्रिंग वाली एक इमेज है. साथ ही, इमेज के टाइटल एट्रिब्यूट में उस उपयोगकर्ता का नाम है जिसने मीटिंग में हिस्सा लिया है. इसके अलावा, इस इमेज टैग को U04fid क्लास वाले div में रैप किया गया है. टेस्ट मीटिंग में कुछ लोगों को शामिल करने के बाद, हम देख सकते हैं कि इस पैरंट डिव में कई इमेज हैं. ये इमेज अलग-अलग उपयोगकर्ताओं की हैं.

इसलिए, हमने एक रणनीति तैयार की है:

  1. यह पता लगाना कि क्लास U04fid वाला div किसी भी एलिमेंट को शामिल करता है या नहीं.
  2. अगर ऐसा होता है, तो इसका मतलब है कि हमारी मीटिंग में लोग शामिल हो गए हैं.
  3. उपयोगकर्ता को सूचना दें.

आइए, 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 शामिल नहीं है. हालांकि, इसमें पैरंट डिव का इस्तेमाल करके, शामिल होने वाले लोगों की जांच की जाती है.

हमें यह जानकारी मिली है:

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 फ़ाइल में कॉपी करें. इसके बाद, एक्सटेंशन को फिर से लोड करें. इसके बाद, मीटिंग पेज को फिर से लोड करें.

अब जब कोई व्यक्ति हमारी मीटिंग में शामिल होता है, तो हमें कंसोल में लॉग स्टेटमेंट दिखता है.

5. उपयोगकर्ता को सूचना भेजें

अब हम यह पता लगा सकते हैं कि कोई व्यक्ति मीटिंग में कब शामिल हुआ. इसलिए, अब हम अपने Chrome एक्सटेंशन में सूचना वाला हिस्सा जोड़ते हैं. हम Chrome एक्सटेंशन के दस्तावेज़ को ब्राउज़ कर सकते हैं. इसके अलावा, हमें जो जानकारी चाहिए उसे पाने के लिए, हम प्रॉम्प्ट में बदलाव भी कर सकते हैं. हालांकि, हमें 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 में किसी Chrome एक्सटेंशन में बैकग्राउंड स्क्रिप्ट जोड़ने के लिए, हमें अपनी manifest.json फ़ाइल में background.service_worker के बारे में जानकारी देनी होगी.

इसलिए, हम 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 कर दें.

b2c22f064a3f2d9c.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 एक्सटेंशन के अलग-अलग हिस्सों के बीच कम्यूनिकेशन हो पाता है. हमारे मामले में, कॉन्टेंट स्क्रिप्ट से बैकग्राउंड सर्विस वर्कर तक कम्यूनिकेशन हो पाता है. आइए, अपने दोस्त 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 का इस्तेमाल इवेंट लिसनर के तौर पर करेंगे. इस मामले में, हम इस इवेंट लिसनर से 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'). का इस्तेमाल करके, मीटिंग में हिस्सा लेने वाले व्यक्ति का नाम फ़ेच कर सकते हैं

सूचना आईडी के बारे में, हम कॉन्टेंट स्क्रिप्ट का टैब आईडी फ़ेच कर सकते हैं और उसे सूचना आईडी के तौर पर इस्तेमाल कर सकते हैं. इसे हमारे इवेंट लिसनर 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 की मदद से, Chrome एक्सटेंशन बनाया. चाहे आप Chrome एक्सटेंशन डेवलपर हों या एक्सटेंशन की दुनिया में नए हों, Gemini आपकी हर काम में मदद कर सकता है.

हमारा सुझाव है कि आप Chrome एक्सटेंशन की मदद से किए जा सकने वाले अलग-अलग कामों के बारे में पूछें. ब्राउज़ करने लायक कई एपीआई हैं, जैसे कि chrome.storage, alarms वगैरह. जहां भी आपको समस्या हो, वहां Gemini या दस्तावेज़ों का इस्तेमाल करके यह जानें कि आपसे क्या गलती हो रही है या समस्या को हल करने के अलग-अलग तरीके जानें.

ज़रूरत के मुताबिक मदद पाने के लिए, अक्सर प्रॉम्प्ट में बदलाव करना पड़ता है. हालांकि, हम ऐसा एक ही टैब से कर सकते हैं. इससे हमें अपने कॉन्टेक्स्ट के हिसाब से पूरी जानकारी मिलती है.