Google डेटा गैजेट बनाना

एरिक बिडलमैन, Google डेटा एपीआई टीम
अक्टूबर 2008

सुविधा के बारे में जानकारी

दर्शक

यह लेख आपको Blogger गैजेट बनाने की जानकारी देगा. इसमें यह मान लिया जाता है कि आप Google Data API और JavaScript क्लाइंट लाइब्रेरी के बारे में जानते हैं. आपको JavaScript में अच्छी समझ होनी चाहिए और आपको विजेट* इस्तेमाल करके OpenSocial गैजेट लागू करने का अनुभव होना चाहिए. एपीआई.

यह उदाहरण आपके गैजेट में बाहरी लाइब्रेरी का सफलतापूर्वक इस्तेमाल करने का तरीका भी दिखाता है. मैंने jQuery (मुख्य तौर पर इसके यूज़र इंटरफ़ेस (यूआई) इफ़ेक्ट के लिए) और TinyMCE का इस्तेमाल किया है. यह एक बेहतरीन WYSIWYG रिच टेक्स्ट एडिटर प्लग इन है.

वजह

किसी एक Google Data API के साथ JSON का इस्तेमाल करने वाला गैजेट बनाने के लिए, बहुत कम JavaScript की ज़रूरत होती है. ऐसे गैजेट की मुख्य परेशानी यह है कि डेटा सार्वजनिक और रीड-ओनली है. ज़्यादा दिलचस्प गैजेट बनाने के लिए, आपके पास उपयोगकर्ता के निजी डेटा का ऐक्सेस होना चाहिए (कुछ ऐसा जिसके लिए पुष्टि करने की ज़रूरत होती है). अब तक, Google खाता API का लाभ उठाने का कोई शानदार तरीका नहीं है. AuthSub के लिए ब्राउज़र रीडायरेक्ट की ज़रूरत होती है और ClientLogin पर उपयोगकर्ता के क्रेडेंशियल, क्लाइंट-साइड, दिखाई देते हैं. type="url" गैजेट को हैकिंग करना भी सुविधाजनक नहीं रहा है.

OAuth प्रॉक्सी डालें.

OAuth प्रॉक्सी

अगर आपको OAuth के बारे में जानकारी नहीं है, तो यह एक पुष्टि करने वाला स्टैंडर्ड है जो उपयोगकर्ता को अपना निजी डेटा, किसी दूसरी वेबसाइट या गैजेट के साथ शेयर करने की अनुमति देता है. OAuth की खास बातों के लिए ज़रूरी है कि सभी डेटा अनुरोधों पर डिजिटल हस्ताक्षर किए जाएं. यह सुरक्षा के लिए बहुत अच्छा है, लेकिन JavaScript गैजेट के मामले में, निजी कुंजियों को मैनेज करना और डिजिटल हस्ताक्षर बनाना असुरक्षित होता है. क्रॉस-डोमेन समस्याओं को और जटिल बनाया गया है.

अच्छी बात यह है कि इन समस्याओं को हल करने के लिए, OAuth प्रॉक्सी वाले गैजेट प्लैटफ़ॉर्म का इस्तेमाल किया जा सकता है. OAuth प्रॉक्सी को इस तरह डिज़ाइन किया गया है कि गैजेट डेवलपर की ज़िंदगी आसान हो सके. यह OAuth की पुष्टि करने से जुड़ी ज़्यादातर जानकारी छिपाता है. साथ ही, यह आपके लिए मुश्किल काम भी करता है. प्रॉक्सी, आपके गैजेट की ओर से डेटा अनुरोधों को साइन करता है, इसलिए निजी कुंजियों को प्रबंधित करने या अनुरोधों पर हस्ताक्षर करने के बारे में चिंता करने की कोई ज़रूरत नहीं है. यह काम करता है!

OAuth प्रॉक्सी, Shindig नाम के एक ओपन सोर्स प्रोजेक्ट पर आधारित है, जो गैजेट विवरण को लागू करता है.

ध्यान दें: OAuth प्रॉक्सी सिर्फ़ उन गैजेट के लिए काम करती है जो gadgets.* एपीआई का इस्तेमाल करते हैं और OpenSocial कंटेनर में चलते हैं. यह लेगसी गैजेट एपीआई के लिए काम नहीं करता.

शुरू करें

इस ट्यूटोरियल का बाकी हिस्सा, उपयोगकर्ता के Blogger डेटा को ऐक्सेस करने के लिए गैजेट बनाने पर फ़ोकस करेगा. हम JavaScript क्लाइंट लाइब्रेरी का इस्तेमाल करके, पुष्टि करने और OAuth प्रॉक्सी का इस्तेमाल करके, Blogger पर एंट्री पोस्ट करेंगे.

पुष्टि करना

सबसे पहले, हमें गैजेट को OAuth का इस्तेमाल करने के लिए बताना होगा. ऐसा करने के लिए, गैजेट के <ModulePrefs> सेक्शन में <OAuth> एलिमेंट जोड़ें:

<ModulePrefs>
...
<OAuth>
  <Service name="google">
    <Access url="https://www.google.com/accounts/OAuthGetAccessToken" method="GET" /> 
    <Request url="https://www.google.com/accounts/OAuthGetRequestToken?scope=http://www.blogger.com/feeds/" method="GET" /> 
    <Authorization url="https://www.google.com/accounts/OAuthAuthorizeToken?
                        oauth_callback=http://oauth.gmodules.com/gadgets/oauthcallback" /> 
  </Service>
</OAuth>
...
</ModulePrefs>

<Service> एलिमेंट में मौजूद तीन यूआरएल एंडपॉइंट, Google के OAuth टोकन एंडपॉइंट के मुताबिक हैं. क्वेरी पैरामीटर के बारे में यहां बताया गया है:

  • scope

    अनुरोध के यूआरएल में यह पैरामीटर ज़रूरी है. आपका गैजेट केवल इस पैरामीटर में उपयोग किए गए scope(s) से डेटा ऐक्सेस कर सकेगा. इस उदाहरण में, गैजेट ब्लॉगर तक पहुँच करेगा. अगर आपका गैजेट एक से ज़्यादा Google Data API ऐक्सेस करना चाहता है, तो अतिरिक्त %20 के साथ scope जोड़ें. उदाहरण के लिए, अगर आपको Calendar और Blogger, दोनों को ऐक्सेस करना है, तो दायरे को http://www.blogger.com/feeds/%20http://www.google.com/calendar/feeds/ पर सेट करें.

  • oauth_callback

    अनुमति वाले यूआरएल में यह पैरामीटर ज़रूरी नहीं है. उपयोगकर्ता के अपने डेटा को ऐक्सेस करने की अनुमति देने के बाद, OAuth मंज़ूरी पेज इस यूआरएल पर रीडायरेक्ट करेगा. आपके पास इस पैरामीटर को छोड़ने का विकल्प है. इसे अपने "स्वीकार किए गए पेज" पर सेट करें. इसके अलावा, http://oauth.gmodules.com/gadgets/oauthcallback का इस्तेमाल भी किया जा सकता है. बाद में, उपयोगकर्ताओं को आपका गैजेट इंस्टॉल करने पर सबसे अच्छा अनुभव मिलता है. वह पेज JavaScript का स्निपेट देता है जो पॉप-अप विंडो को अपने-आप बंद कर देता है.

अब जब हमारे पास OAuth का इस्तेमाल करने वाला अपना गैजेट है, तो उपयोगकर्ता को अपने डेटा के ऐक्सेस की मंज़ूरी देनी होगी. पुष्टि करने के लिए यह तरीका अपनाएं:

  1. गैजेट पहली बार लोड होता है और उपयोगकर्ता के ब्लॉगर डेटा तक पहुंचने का प्रयास करता है.
  2. अनुरोध विफल हो गया क्योंकि उपयोगकर्ता ने गैजेट को पहुंच नहीं दी है. अच्छी बात यह है कि रिस्पॉन्स में मिले ऑब्जेक्ट में एक यूआरएल (response.oauthApprovalUrl) है, जहां हम उपयोगकर्ता को लॉगिन करने के लिए भेजेंगे. यह गैजेट "Blogger में साइन इन करें" को दिखाता है और इसकी वैल्यू को oauthApprovalUrl की वैल्यू पर सेट करता है.
  3. इसके बाद, उपयोगकर्ता "Blogger में साइन इन करें" पर क्लिक करता है और OAuth की मंज़ूरी वाला पेज अलग विंडो में खुल जाता है. गैजेट, उपयोगकर्ता के एक लिंक प्रदर्शित करके अनुमति प्रक्रिया पूरी किए जाने की प्रतीक्षा करता है: "मैंने ऐक्सेस को अनुमति दे दी है".
  4. पॉप-अप में, उपयोगकर्ता हमारे गैजेट को ऐक्सेस देने या न देने का विकल्प चुनेगा. "ऐक्सेस दें" पर क्लिक करने के बाद, उन्हें http://oauth.gmodules.com/gadgets/oauthcallback पर ले जाया जाता है और इसके बाद विंडो बंद हो जाती है.
  5. गैजेट विंडो को पहचान लेता है और उपयोगकर्ता के डेटा के लिए फिर से अनुरोध करके दूसरी बार Blogger पर पहुंचने की कोशिश करता है. विंडो बंद होने का पता लगाने के लिए, मैंने पॉप-अप हैंडलर का इस्तेमाल किया है. अगर इस तरह के कोड का इस्तेमाल नहीं किया जाता है, तो उपयोगकर्ता मैन्युअल तौर पर "मैंने ऐक्सेस को अनुमति दे दी है" पर क्लिक कर सकते हैं.
  6. गैजेट अब अपना सामान्य यूज़र इंटरफ़ेस (यूआई) दिखाता है. यह व्यू तब तक बना रहेगा, जब तक कि पुष्टि करने से जुड़ा टोकन, समस्या क्रम के तहत निरस्त नहीं किया जाता.

इसलिए ऊपर बताए गए तरीकों से, गैजेट को तीन अलग-अलग स्थितियों के बारे में बताया गया है:

  1. पुष्टि नहीं की गई. उपयोगकर्ता को अनुमति की प्रोसेस शुरू करनी होगी.
  2. उपयोगकर्ता के डेटा को ऐक्सेस करने की अनुमति मिलना बाकी है.
  3. पुष्टि की गई. गैजेट इसकी सामान्य फ़ंक्शनल स्थिति दिखाते हैं.

अपने गैजेट में, मैंने हर चरण को अलग करने के लिए <div> कंटेनर का इस्तेमाल किया है:

<Content type="html">
<![CDATA[

<!-- Normal state of the gadget. The user is authenticated -->       
<div id="main" style="display:none">
  <form id="postForm" name="postForm" onsubmit="savePost(this); return false;">
     <div id="messages" style="display: none"></div>
     <div class="selectFeed">Publish to:
       <select id="postFeedUri" name="postFeedUri" disabled="disabled"><option>loading blog list...</option></select>
     </div>
     <h4 style="clear:both">Title</h4>
     <input type="text" id="title" name="title"/>
     <h4>Content</h4>
     <textarea id="content" name="content" style="width:100%;height:200px;"></textarea>
     <h4 style="float:left;">Labels (comma separated)</h4><img src="blogger.png" style="float:right"/>
     <input type="text" id="categories" name="categories"/>
     <p><input type="submit" id="submitButton" value="Save"/> 
     <input type="checkbox" id="draft" name="draft" checked="checked"/> <label for="draft">Draft?</label></p>
  </form>
</div>

<div id="approval" style="display: none">
  <a href="#" id="personalize">Sign in to Blogger</a>
</div>

<div id="waiting" style="display: none">
  <a href="#" id="approvalLink">I've approved access</a>
</di

<!-- An errors section is not necessary but great to have -->
<div id="errors" style="display: none"></div>
 
<!-- Also not necessary, but great for informing users -->     
<div id="loading">
  <h3>Loading...</h3>
  <p><img src="ajax-loader.gif"></p>
</div>

]]> 
</Content>

हर <div> को showOnly() का इस्तेमाल करके दिखाया जाता है. उस फ़ंक्शन पर विवरण के लिए पूरा उदाहरण गैजेट देखें.

JavaScript क्लाइंट लाइब्रेरी का इस्तेमाल करना

OpenSocial में दूरस्थ सामग्री लाने के लिए, आप gadgets.* API का उपयोग करके gadgets.io.makeRequest विधि को कॉल करते हैं. हालांकि, हम Google डेटा गैजेट बना रहे हैं, इसलिए gadgets.io.* एपीआई को छूना ज़रूरी नहीं है. इसके बजाय, JavaScript क्लाइंट लाइब्रेरी का इस्तेमाल करें. इसमें Google की हर डेटा सेवा के लिए अनुरोध करने के खास तरीके होते हैं.

ध्यान दें: यह लेख लिखने के दौरान, JavaScript लाइब्रेरी सिर्फ़ Blogger, Calendar, संपर्क, वित्त, और Google Base की सुविधा देती है. किसी दूसरे एपीआई का इस्तेमाल करने के लिए, लाइब्रेरी के बिना gadgets.io.makeRequest का इस्तेमाल करें.

लाइब्रेरी लोड हो रही है

JavaScript लाइब्रेरी को लोड करने के लिए, <Content> सेक्शन में कॉमन लोडर को शामिल करें. साथ ही, जब गैजेट शुरू हो जाए, तब लाइब्रेरी को इंपोर्ट करें. gadgets.util.registerOnLoadHandler() को कॉलबैक फ़ीड देने से, यह तय करने में मदद मिलती है कि गैजेट कब तैयार होगा:

<Content type="html">
<![CDATA[
  ...
  <script src="https://www.google.com/jsapi"></script>
  <script type="text/javascript">
  var blogger = null;  // make our service object global for later
  
  // Load the JS library and try to fetch data once it's ready
  function initGadget() {  
    google.load('gdata', '1.x', {packages: ['blogger']});  // Save overhead, only load the Blogger service
    google.setOnLoadCallback(function () {
      blogger = new google.gdata.blogger.BloggerService('google-BloggerGadget-v1.0');
      blogger.useOAuth('google');
      fetchData();
    });
  }
  gadgets.util.registerOnLoadHandler(initGadget);
  </script>
  ...
]]> 
</Content>

blogger.useOAuth('google') पर किया जाने वाला कॉल, लाइब्रेरी को OAuth प्रॉक्सी (इसके सामान्य पुष्टि करने के तरीके - AuthSubJS के बजाय) का इस्तेमाल करने के लिए कहता है. आखिर में, गैजेट fetchData() को कॉल करके उपयोगकर्ता के Blogger डेटा को पाने की कोशिश करता है. यह तरीका नीचे बताया गया है.

डेटा फ़ेच हो रहा है

अब जब सभी चीज़ें सेट अप हो गई हैं, तो हम असल में Blogger का GET या POST डेटा कैसे रखते हैं?

OpenSocial में एक सामान्य उदाहरण अपने गैजेट में fetchData() नाम के फ़ंक्शन को परिभाषित करना है. यह तरीका आम तौर पर, पुष्टि करने के अलग-अलग चरणों को मैनेज करता है और gadgets.io.makeRequest का इस्तेमाल करके, डेटा फ़ेच करता है. हम JavaScript क्लाइंट लाइब्रेरी का इस्तेमाल कर रहे हैं. इसलिए, gadgets.io.makeRequest की जगह blogger.getBlogFeed() को कॉल किया जा रहा है:

function fetchData() {
  jQuery('#errors').hide();
  
  var callback = function(response) {
    if (response.oauthApprovalUrl) {
      // You can set the sign in link directly:
      // jQuery('#personalize').get(0).href = response.oauthApprovalUrl
      
      // OR use the popup.js handler
      var popup = shindig.oauth.popup({
        destination: response.oauthApprovalUrl,
        windowOptions: 'height=600,width=800',
        onOpen: function() {
          showOnly('waiting');
        },
        onClose: function() {
          showOnly('loading');
          fetchData();
        }
      });
      jQuery('#personalize').get(0).onclick = popup.createOpenerOnClick();
      jQuery('#approvalLink').get(0).onclick = popup.createApprovedOnClick();
      
      showOnly('approval');
    } else if (response.feed) {
      showResults(response);
      showOnly('main');
    } else {
      jQuery('#errors').html('Something went wrong').fadeIn();
      showOnly('errors');
    }
  };
  
  blogger.getBlogFeed('http://www.blogger.com/feeds/default/blogs', callback, callback);
}

इस फ़ंक्शन को दूसरी बार कॉल करने पर, response.feed में डेटा मौजूद होता है.

ध्यान दें: getBlogFeed(), अपने कॉलबैक और गड़बड़ी हैंडलर के लिए, एक ही फ़ंक्शन का इस्तेमाल करता है.

Blogger पर कोई जानकारी पोस्ट करना

आखिरी चरण में किसी ब्लॉग में नई एंट्री पोस्ट करें. नीचे दिया गया कोड यह दिखाता है कि उपयोगकर्ता "सेव करें" बटन पर क्लिक करने पर क्या होता है.

function savePost(form) { 
  jQuery('#messages').fadeOut();
  jQuery('#submitButton').val('Publishing...').attr('disabled', 'disabled');
  
  // trim whitespace from the input tags
  var input = form.categories.value;
  var categories = jQuery.trim(input) != '' ? input.split(',') : [];   
  jQuery.each(categories, function(i, value) {
    var label = jQuery.trim(value);
    categories[i] = {
      scheme: 'http://www.blogger.com/atom/ns#',
      term: label
    };
  });

  // construct the blog post entry
  var newEntry = new google.gdata.blogger.BlogPostEntry({
    title: {
      type: 'text', 
      text: form.title.value
    },
    content: {
      type: 'text', 
      text: form.content.value
    },
    categories: categories
  });
  
  // publish as draft?
  var isDraft = form.draft.checked;
  if (isDraft) {
    newEntry.setControl({draft: {value: google.gdata.Draft.VALUE_YES}});
  }
  
  // callback for insertEntry()
  var handleInsert = function(entryRoot) {
    var entry = entryRoot.entry;
    var str = isDraft ? '(as draft)' : '<a href="' + entry.getHtmlLink().getHref() + '" target="_blankt">View it</a>';

    jQuery('#messages').html('Post published! ' + str).fadeIn();
    jQuery('#submitButton').val('Save').removeAttr('disabled');
  };
  
  // error handler for insertEntry()
  var handleError = function(e) {
    var msg = e.cause ? e.cause.statusText + ': ' : '';
    msg += e.message;
    alert('Error: ' + msg);
  };
  
  blogger.insertEntry(form.postFeedUri.value, newEntry, handleInsert, handleError);
}

नतीजा

अब आपके पास Google Data API के ऊपर किसी गैजेट को कोड करने के लिए बिल्डिंग ब्लॉक हैं.

उम्मीद है कि इस लेख से आपको सराहना मिली होगी कि OAuth प्रॉक्सी से गैजेट को आसानी से पुष्टि करने में आसानी होती है. इस पावर टूल को Google डेटा JavaScript क्लाइंट लाइब्रेरी से जोड़ने से दिलचस्प, इंटरैक्टिव, और शानदार गैजेट बनाना आसान हो जाता है.

अगर इस लेख के बारे में आपका कोई सवाल या टिप्पणी है, तो कृपया Google खाता API चर्चा फ़ोरम में हमसे संपर्क करें.

रिसॉर्स