একটি Google ডেটা গ্যাজেট তৈরি করা হচ্ছে

এরিক বিডেলম্যান, Google Data APIs টিম
অক্টোবর 2008

ভূমিকা

শ্রোতা

এই নিবন্ধটি আপনাকে একটি ব্লগার গ্যাজেট তৈরির মাধ্যমে নিয়ে যাবে। এটা ধরে নেয় আপনি Google Data APIs এবং JavaScript ক্লায়েন্ট লাইব্রেরির সাথে পরিচিত। এছাড়াও আপনার জাভাস্ক্রিপ্টে সাবলীল হতে হবে এবং গ্যাজেটগুলি ব্যবহার করে একটি OpenSocial গ্যাজেট বাস্তবায়ন করার কিছু অভিজ্ঞতা থাকতে হবে।* API

এই উদাহরণটি আপনার গ্যাজেটগুলিতে বহিরাগত লাইব্রেরিগুলিকে সফলভাবে কীভাবে ব্যবহার করতে হয় তাও দেখায়৷ আমি jQuery ব্যবহার করেছি (প্রধানত এর UI প্রভাবের জন্য) এবং TinyMCE , একটি দুর্দান্ত WYSIWYG সমৃদ্ধ পাঠ্য সম্পাদক প্লাগইন।

প্রেরণা

Google Data API-এর সাথে JSON ব্যবহার করে এমন একটি গ্যাজেট তৈরি করতে খুব কম জাভাস্ক্রিপ্ট লাগে। এই ধরনের একটি গ্যাজেটের প্রধান বিরক্তি হল যে ডেটা সর্বজনীন এবং শুধুমাত্র পঠনযোগ্য। আরও আকর্ষণীয় গ্যাজেট তৈরি করতে, আপনাকে একজন ব্যবহারকারীর ব্যক্তিগত ডেটা অ্যাক্সেস করতে হবে (যার জন্য প্রমাণীকরণ প্রয়োজন)। এখন পর্যন্ত, Google অ্যাকাউন্ট API- এর সুবিধা নেওয়ার একটি দুর্দান্ত উপায় নেই। AuthSub-এর জন্য ব্রাউজার পুনঃনির্দেশ প্রয়োজন এবং ClientLogin একজন ব্যবহারকারীর শংসাপত্র, ক্লায়েন্ট-সাইডকে প্রকাশ করে। এমনকি একটি type="url" গ্যাজেট হ্যাক করা অসুবিধাজনক হয়েছে।

OAuth প্রক্সি লিখুন।

OAuth প্রক্সি

আপনি যদি OAuth এর সাথে পরিচিত না হন তবে এটি একটি প্রমাণীকরণ মান যা একজন ব্যবহারকারীকে তাদের ব্যক্তিগত ডেটা অন্য ওয়েবসাইট বা গ্যাজেটের সাথে ভাগ করতে দেয়৷ OAuth স্পেসিফিকেশনের জন্য প্রয়োজন যে সমস্ত ডেটা অনুরোধ ডিজিটালভাবে স্বাক্ষরিত। এটি নিরাপত্তার জন্য দুর্দান্ত, কিন্তু একটি JavaScript গ্যাজেটের ক্ষেত্রে, ব্যক্তিগত কীগুলি পরিচালনা করা এবং ডিজিটাল স্বাক্ষর তৈরি করা অনিরাপদ৷ ক্রস-ডোমেন সমস্যাগুলির অতিরিক্ত জটিলতাও রয়েছে।

সৌভাগ্যবশত, OAuth Proxy নামক গ্যাজেট প্ল্যাটফর্ম থেকে একটি বৈশিষ্ট্যের সুবিধা গ্রহণ করে এই সমস্যাগুলি সমাধান করা হয়৷ OAuth প্রক্সি গ্যাজেট ডেভেলপারদের জীবন সহজ করার জন্য ডিজাইন করা হয়েছে। এটি OAuth-এর প্রমাণীকরণের অনেক বিবরণ লুকিয়ে রাখে এবং আপনার জন্য ভারী উত্তোলন করে। প্রক্সি আপনার গ্যাজেটের পক্ষ থেকে ডেটা অনুরোধগুলি স্বাক্ষর করে, তাই ব্যক্তিগত কীগুলি পরিচালনা করার বা অনুরোধ স্বাক্ষর করার বিষয়ে চিন্তা করার দরকার নেই৷ এটা শুধু কাজ করে!

OAuth প্রক্সিটি Shindig নামক একটি ওপেন-সোর্স প্রকল্পের উপর ভিত্তি করে তৈরি, যা গ্যাজেট স্পেসিফিকেশনের একটি বাস্তবায়ন।

দ্রষ্টব্য: OAuth প্রক্সি শুধুমাত্র গ্যাজেট ব্যবহার করে gadgets.* API এবং OpenSocial পাত্রে চলমান। এটি লিগ্যাসি গ্যাজেট API- এর জন্য সমর্থিত নয়।

শুরু হচ্ছে

এই টিউটোরিয়ালের বাকি অংশটি ব্যবহারকারীর ব্লগার ডেটা অ্যাক্সেস করার জন্য একটি গ্যাজেট তৈরি করার উপর ফোকাস করবে। আমরা জাভাস্ক্রিপ্ট ক্লায়েন্ট লাইব্রেরি ব্যবহার করে প্রমাণীকরণ (OAuth প্রক্সি ব্যবহার করে), এবং অবশেষে, ব্লগারে একটি এন্ট্রি পোস্ট করব।

প্রমাণীকরণ

প্রথম জিনিস প্রথমে, আমাদের গ্যাজেটটিকে 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> উপাদানের তিনটি url এন্ডপয়েন্ট Google এর OAuth টোকেন এন্ডপয়েন্টের সাথে মিলে যায়। এখানে ক্যোয়ারী প্যারামিটারের ব্যাখ্যা:

  • scope

    অনুরোধ URL-এ এই প্যারামিটারটি প্রয়োজন। আপনার গ্যাজেট শুধুমাত্র এই প্যারামিটারে ব্যবহৃত scope (গুলি) থেকে ডেটা অ্যাক্সেস করতে সক্ষম হবে৷ এই উদাহরণে, গ্যাজেটটি ব্লগার অ্যাক্সেস করবে। যদি আপনার গ্যাজেট একাধিক Google ডেটা API অ্যাক্সেস করতে চায়, তাহলে একটি %20 দিয়ে অতিরিক্ত scope (গুলি) সংযুক্ত করুন। উদাহরণ হিসেবে, আপনি যদি ক্যালেন্ডার এবং ব্লগার উভয়ই অ্যাক্সেস করতে চান, তাহলে সুযোগটি http://www.blogger.com/feeds/%20http://www.google.com/calendar/feeds/ এ সেট করুন।

  • oauth_callback

    এই প্যারামিটার অনুমোদন URL-এ ঐচ্ছিক। ব্যবহারকারী তাদের ডেটাতে অ্যাক্সেস অনুমোদন করার পরে OAuth অনুমোদন পৃষ্ঠাটি এই URL-এ পুনঃনির্দেশিত হবে। আপনি এই প্যারামিটারটি ছেড়ে দিতে, এটিকে আপনার নিজের "অনুমোদিত পৃষ্ঠাতে" সেট করতে বা পছন্দ করে, http://oauth.gmodules.com/gadgets/oauthcallback ব্যবহার করতে পারেন। ব্যবহারকারীরা যখন প্রথমবার আপনার গ্যাজেট ইনস্টল করে তখন পরেরটি সেরা ব্যবহারকারীর অভিজ্ঞতা প্রদান করে। সেই পৃষ্ঠাটি জাভাস্ক্রিপ্টের একটি স্নিপেট প্রদান করে যা স্বয়ংক্রিয়ভাবে পপআপ উইন্ডো বন্ধ করে দেয়।

এখন যেহেতু OAuth ব্যবহার করে আমাদের গ্যাজেট আছে, ব্যবহারকারীকে তাদের ডেটাতে অ্যাক্সেস অনুমোদন করতে হবে। এখানে প্রমাণীকরণ প্রবাহ:

  1. গ্যাজেটটি প্রথমবার লোড হয় এবং ব্যবহারকারীর ব্লগার ডেটা অ্যাক্সেস করার চেষ্টা করে৷
  2. অনুরোধটি ব্যর্থ হয়েছে কারণ ব্যবহারকারী গ্যাজেটে অ্যাক্সেস দেয়নি৷ সৌভাগ্যবশত, প্রতিক্রিয়াতে ফিরে আসা বস্তুটিতে একটি URL ( response.oauthApprovalUrl ) রয়েছে যেখানে আমরা ব্যবহারকারীকে লগইন করতে পাঠাব। গ্যাজেটটি "ব্লগারে সাইন ইন করুন" প্রদর্শন করে এবং এর href কে oauthApprovalUrl এর মান নির্ধারণ করে।
  3. এরপরে, ব্যবহারকারী "ব্লগারে সাইন ইন করুন" ক্লিক করেন এবং OAuth অনুমোদন পৃষ্ঠাটি একটি পৃথক উইন্ডোতে খোলে৷ গ্যাজেটটি একটি লিঙ্ক প্রদর্শন করে ব্যবহারকারীর অনুমোদন প্রক্রিয়া শেষ করার জন্য অপেক্ষা করে: "আমি অ্যাক্সেস অনুমোদন করেছি"।
  4. পপআপে, ব্যবহারকারী আমাদের গ্যাজেটে অ্যাক্সেস মঞ্জুর/অস্বীকার করতে বেছে নেবে। একবার তারা "অ্যাক্সেস মঞ্জুর করুন" এ ক্লিক করলে, তাদের http://oauth.gmodules.com/gadgets/oauthcallback এ নিয়ে যাওয়া হবে এবং উইন্ডোটি বন্ধ হয়ে যাবে।
  5. গ্যাজেটটি উইন্ডোটি বন্ধ হয়ে যাওয়াকে শনাক্ত করে এবং ব্যবহারকারীর ডেটা পুনরায় অনুরোধ করে ব্লগারকে দ্বিতীয়বার অ্যাক্সেস করার চেষ্টা করে। উইন্ডো বন্ধ শনাক্ত করতে, আমি একটি পপআপ হ্যান্ডলার ব্যবহার করেছি। আপনি যদি এই ধরনের কোড ব্যবহার না করেন, ব্যবহারকারী ম্যানুয়ালি "আমি অ্যাক্সেস অনুমোদন করেছি" ক্লিক করতে পারেন।
  6. গ্যাজেটটি এখন তার স্বাভাবিক UI প্রদর্শন করে। IssuedAuthSubTokens- এর অধীনে প্রমাণীকরণ টোকেন প্রত্যাহার না করা পর্যন্ত এই দৃশ্যটি বজায় থাকবে।

সুতরাং উপরের ধাপগুলি থেকে, গ্যাজেটগুলির তিনটি ভিন্ন অবস্থার ধারণা রয়েছে:

  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() ব্যবহার করে নিজেই প্রদর্শিত হয়। সেই ফাংশনের বিস্তারিত জানার জন্য সম্পূর্ণ উদাহরণ গ্যাজেটটি দেখুন।

জাভাস্ক্রিপ্ট ক্লায়েন্ট লাইব্রেরি ব্যবহার করে

OpenSocial-এ দূরবর্তী বিষয়বস্তু আনতে, আপনি গ্যাজেট ব্যবহার করে gadgets.io.makeRequest পদ্ধতিতে একটি কল করুন gadgets.* API। যাইহোক, যেহেতু আমরা একটি Google ডেটা গ্যাজেট তৈরি করছি, gadgets.io.* APIগুলি স্পর্শ করার দরকার নেই৷ পরিবর্তে, JavaScript ক্লায়েন্ট লাইব্রেরি ব্যবহার করুন যাতে প্রতিটি Google ডেটা পরিষেবাতে অনুরোধ করার জন্য বিশেষ পদ্ধতি রয়েছে।

দ্রষ্টব্য : এই নিবন্ধটি লেখার সময়, জাভাস্ক্রিপ্ট লাইব্রেরি শুধুমাত্র ব্লগার , ক্যালেন্ডার , পরিচিতি , ফাইন্যান্স , এবং Google বেস সমর্থন করে৷ অন্য APIগুলির একটি ব্যবহার করতে, লাইব্রেরি ছাড়া gadgets.io.makeRequest ব্যবহার করুন৷

লাইব্রেরি লোড হচ্ছে

জাভাস্ক্রিপ্ট লাইব্রেরি লোড করতে, <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() কল করে ব্যবহারকারীর ব্লগার ডেটা পুনরুদ্ধার করার চেষ্টা করে। সেই পদ্ধতি নিচে সংজ্ঞায়িত করা হল।

তথ্য আনয়ন

এখন যেহেতু সবকিছু সেটআপ করা হয়েছে, আমরা আসলে ব্লগারে কীভাবে ডেটা GET বা POST ?

OpenSocial-এ একটি সাধারণ দৃষ্টান্ত হল আপনার গ্যাজেটে fetchData() নামক একটি ফাংশন সংজ্ঞায়িত করা। এই পদ্ধতিটি সাধারণত প্রমাণীকরণের বিভিন্ন ধাপ পরিচালনা করে এবং gadgets.io.makeRequest ব্যবহার করে ডেটা আনে। যেহেতু আমরা জাভাস্ক্রিপ্ট ক্লায়েন্ট লাইব্রেরি ব্যবহার করছি, 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() এটির কলব্যাক এবং ত্রুটি হ্যান্ডলারের জন্য একই ফাংশন ব্যবহার করে।

ব্লগারে একটি এন্ট্রি পোস্ট করুন

শেষ ধাপ হল একটি ব্লগে একটি নতুন এন্ট্রি পোস্ট করা। ব্যবহারকারী "সংরক্ষণ করুন" বোতামে ক্লিক করলে কী ঘটে তা নীচের কোডটি প্রদর্শন করে৷

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 Data JavaScript ক্লায়েন্ট লাইব্রেরির সাথে এই পাওয়ার টুলের সমন্বয় আকর্ষণীয়, ইন্টারেক্টিভ এবং অত্যাধুনিক গ্যাজেট তৈরি করা সহজ করে তোলে।

এই নিবন্ধে আপনার যদি কোনো প্রশ্ন বা মন্তব্য থাকে, তাহলে অনুগ্রহ করে Google অ্যাকাউন্ট API আলোচনা ফোরামে আমাদের যান।

সম্পদ