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

1. परिचय

क्या आपको किसी मीटिंग में शामिल होना है, लेकिन आप पहले व्यक्ति के तौर पर शामिल नहीं होना चाहते? अगर ऐसा है, तो हमारे पास आपके लिए एक समाधान है!

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

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

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

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

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

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

सेटअप/ज़रूरी चीज़ें

  • Chrome ब्राउज़र
  • आपके लोकल सिस्टम पर IDE/एडिटर का सेटअप.
  • अगर आपको 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.

यह मुझे इसे टेस्ट करने के कुछ तरीके बताता है. chrome://extensions पर जाकर, "Extensions Page" पर जाएं. साथ ही, "Developer Mode" बटन को चालू करें. इससे "Load unpacked" बटन दिखेगा. इसका इस्तेमाल करके, हम उस फ़ोल्डर पर जा सकते हैं जिसमें एक्सटेंशन की फ़ाइलें स्थानीय तौर पर मौजूद हैं. ऐसा करने के बाद, हमें "Extensions Page" में एक्सटेंशन दिखना चाहिए.

3d802a497ce0cfc2.png92db1999a1800ecd.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 कंसोल पर "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!");

6216bab627c31e6c.png

d61631cd9962ffe5.png

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

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

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

मीटिंग में कोई न होने पर, स्क्रीन इस तरह दिखती है.

fe5a0c95b20e7f72.png

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

7a5ef60521d961cc.png

हमें दो अहम अंतर दिखते हैं:

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

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

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

हम देख सकते हैं कि कुछ क्लास स्ट्रिंग वाली एक इमेज है. साथ ही, इमेज के टाइटल एट्रिब्यूट में उस उपयोगकर्ता का नाम है जो मीटिंग में शामिल हुआ है. इसके अलावा, इस इमेज टैग को U04fid क्लास वाले div में रैप किया गया है. जब हम अपनी टेस्ट मीटिंग में कुछ लोगों को शामिल करते हैं, तो हम देख सकते हैं कि इस पैरंट 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 शामिल नहीं है. हालांकि, यह एक ऐसा समाधान है जो पैरंट 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 फ़ाइल में कॉपी करें. इसके बाद, एक्सटेंशन को फिर से लोड करें. फिर, मीटिंग वाले पेज को फिर से लोड करें.

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

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'). का इस्तेमाल करके, मीटिंग में हिस्सा लेने वाले व्यक्ति का नाम फ़ेच किया जा सकता है.

सूचना की आईडी के लिए, हम कॉन्टेंट स्क्रिप्ट की टैब आईडी फ़ेच कर सकते हैं और उसे सूचना की आईडी के तौर पर इस्तेमाल कर सकते हैं. sender.tab.id. का इस्तेमाल करके, इसे अपने इवेंट लिसनर chrome.runtime.onMessage.addListener में पूरा किया जा सकता है.

आखिर में, हमारी फ़ाइलें कुछ इस तरह दिखनी चाहिए:

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 या दस्तावेज़ का इस्तेमाल करके यह जानें कि आपसे क्या गलती हो रही है या समस्या को हल करने के अलग-अलग तरीके जानें.

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