Google Data on Rails

एरिक बिडेलमैन, Google Data APIs टीम
फ़रवरी 2009

परिचय

"क्लाइंट लाइब्रेरी की सूची में Ruby कहां है?"

हमारे डेवलपर की बढ़ती मांग और Ruby on Rails (RoR) की लोकप्रियता को देखते हुए, मेरे सहयोगी जेफ़ फ़िशर ने माउंट डूम की गहराई से Ruby यूटिलिटी लाइब्रेरी बनाई है. ध्यान दें कि यह पूरी तरह से क्लाइंट लाइब्रेरी नहीं है. हालांकि, यह पुष्टि करने और एक्सएमएल में बुनियादी बदलाव करने जैसे काम करती है. इसके लिए, आपको REXML मॉड्यूल और XPath का इस्तेमाल करके, सीधे तौर पर ऐटम फ़ीड के साथ काम करना होगा.

ऑडियंस

यह लेख उन डेवलपर के लिए है जो Ruby, खास तौर पर Ruby on Rails का इस्तेमाल करके Google Data API को ऐक्सेस करना चाहते हैं. इसमें यह मान लिया गया है कि पढ़ने वाले व्यक्ति को Ruby प्रोग्रामिंग भाषा और Rails वेब-डेवलपमेंट फ़्रेमवर्क के बारे में कुछ जानकारी है. मैंने ज़्यादातर सैंपल के लिए, Documents List API पर फ़ोकस किया है. हालांकि, यही कॉन्सेप्ट किसी भी Data API पर लागू किए जा सकते हैं.

शुरू करें

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

Google Data Ruby Utility Library इंस्टॉल करना

लाइब्रेरी पाने के लिए, सीधे प्रोजेक्ट होस्टिंग से लाइब्रेरी का सोर्स डाउनलोड करें या gem इंस्टॉल करें:

sudo gem install gdata

अहम जानकारी: यह पक्का करने के लिए कि Gem सही तरीके से इंस्टॉल हुआ है, gem list --local चलाएं.

पुष्टि करना

ClientLogin

ClientLogin की मदद से, आपका ऐप्लिकेशन उपयोगकर्ताओं को उनके Google या G Suite खाते में प्रोग्राम के तौर पर लॉग इन करने की अनुमति देता है. उपयोगकर्ता के क्रेडेंशियल की पुष्टि करने के बाद, Google एक पुष्टि करने वाला टोकन जारी करता है. इसका इस्तेमाल, एपीआई के अगले अनुरोधों में किया जाता है. यह टोकन, तय की गई अवधि तक मान्य रहता है. यह अवधि, उस Google सेवा के हिसाब से तय होती है जिसका इस्तेमाल किया जा रहा है. सुरक्षा की वजहों से और उपयोगकर्ताओं को बेहतरीन अनुभव देने के लिए, आपको इंस्टॉल किए गए डेस्कटॉप ऐप्लिकेशन डेवलप करते समय, सिर्फ़ ClientLogin का इस्तेमाल करना चाहिए. वेब ऐप्लिकेशन के लिए, AuthSub या OAuth का इस्तेमाल करना बेहतर होता है.

Ruby लाइब्रेरी में, हर एपीआई के लिए एक क्लाइंट क्लास होती है. उदाहरण के लिए, Documents List Data API में लॉग इन user@gmail.com करने के लिए, इस कोड स्निपेट का इस्तेमाल करें:

client = GData::Client::DocList.new
client.clientlogin('user@gmail.com', 'pa$$word')

The YouTube Data API would be:

client = GData::Client::YouTube.new
client.clientlogin('user@gmail.com', 'pa$$word')

लागू की गई सेवा क्लास की पूरी सूची देखें. अगर किसी सेवा में क्लाइंट क्लास नहीं है, तो GData::Client::Base क्लास का इस्तेमाल करें. उदाहरण के लिए, इस कोड में उपयोगकर्ताओं को G Suite खाते से लॉग इन करने के लिए कहा गया है.

client_login_handler = GData::Auth::ClientLogin.new('writely', :account_type => 'HOSTED')
token = client_login_handler.get_token('user@example.com', 'pa$$word', 'google-RailsArticleSample-v1')
client = GData::Client::Base.new(:auth_handler => client_login_handler)

ध्यान दें: डिफ़ॉल्ट रूप से, लाइब्रेरी accountType के लिए HOSTED_OR_GOOGLE का इस्तेमाल करती है. संभावित वैल्यू HOSTED_OR_GOOGLE, HOSTED या GOOGLE हैं.

ClientLogin का इस्तेमाल करने का एक नुकसान यह है कि लॉगिन करने की कोशिशें असफल होने पर, आपके ऐप्लिकेशन को CAPTCHA चैलेंज भेजे जा सकते हैं. अगर ऐसा होता है, तो clientlogin() तरीके को उसके अतिरिक्त पैरामीटर के साथ कॉल करके गड़बड़ी को ठीक किया जा सकता है: client.clientlogin(username, password, captcha_token, captcha_answer). CAPTCHA से जुड़ी समस्याओं को हल करने के बारे में ज़्यादा जानने के लिए, इंस्टॉल किए गए ऐप्लिकेशन के लिए पुष्टि करने की सुविधा से जुड़ा पूरा दस्तावेज़ देखें.

AuthSub

AuthSubRequest यूआरएल जनरेट करना

scope = 'http://www.google.com/calendar/feeds/'
next_url = 'http://example.com/change/to/your/app'
secure = false  # set secure = true for signed AuthSub requests
sess = true
authsub_link = GData::Auth::AuthSub.get_url(next_url, scope, secure, sess)

ऊपर दिया गया कोड, authsub_link में यह यूआरएल बनाता है:

https://www.google.com/accounts/AuthSubRequest?next=http%3A%2F%2Fexample.com%2Fchange%2Fto%2Fyour%2Fapp&scope=http%3A%2F%2Fwww.google.com%2Fcalendar%2Ffeeds%2F&session=1&secure=0

क्लाइंट ऑब्जेक्ट के authsub_url तरीके का भी इस्तेमाल किया जा सकता है. हर सेवा क्लास के लिए, डिफ़ॉल्ट authsub_scope एट्रिब्यूट सेट किया गया है. इसलिए, आपको अपना एट्रिब्यूट तय करने की ज़रूरत नहीं है.

client = GData::Client::DocList.new
next_url = 'http://example.com/change/to/your/app'
secure = false  # set secure = true for signed AuthSub requests
sess = true
domain = 'example.com'  # force users to login to a G Suite hosted domain
authsub_link = client.authsub_url(next_url, secure, sess, domain)

ऊपर दिया गया कोड, यह यूआरएल बनाता है:

https://www.google.com/accounts/AuthSubRequest?next=http%3A%2F%2Fexample.com%2Fchange%2Fto%2Fyour%2Fapp&scope=http%3A%2F%2Fdocs.google.com%2Ffeeds%2F&session=1&secure=0&hd=example.com

एक बार इस्तेमाल किए जाने वाले टोकन को सेशन टोकन में अपग्रेड करना

उपयोगकर्ता के डेटा का ऐक्सेस मिलने के बाद, AuthSub उसे वापस http://example.com/change/to/your/app?token=SINGLE_USE_TOKEN पर रीडायरेक्ट कर देगा. ध्यान दें कि यूआरएल सिर्फ़ हमारा next_url है. इसमें क्वेरी पैरामीटर के तौर पर, एक बार इस्तेमाल किया जा सकने वाला टोकन जोड़ा गया है.

इसके बाद, एक बार इस्तेमाल किए जा सकने वाले टोकन को लंबे समय तक मान्य रहने वाले सेशन टोकन के लिए बदलें:

client.authsub_token = params[:token] # extract the single-use token from the URL query params
session[:token] = client.auth_handler.upgrade()
client.authsub_token = session[:token] if session[:token]

Secure AuthSub भी इसी तरह काम करता है. टोकन को अपग्रेड करने से पहले, आपको सिर्फ़ अपनी निजी पासकोड सेट करना होगा:

PRIVATE_KEY = '/path/to/private_key.pem'

client.authsub_token = params[:token]
client.authsub_private_key = PRIVATE_KEY
session[:token] = client.auth_handler.upgrade()
client.authsub_token = session[:token] if session[:token]

ध्यान दें: सुरक्षित टोकन का इस्तेमाल करने के लिए, पक्का करें कि एक बार इस्तेमाल किया जा सकने वाला टोकन का अनुरोध करते समय, आपने secure=true सेट किया हो. ऊपर AuthSubRequest यूआरएल जनरेट करना देखें.

टोकन मैनेजमेंट

AuthSub, टोकन मैनेज करने के लिए दो और हैंडलर उपलब्ध कराता है: AuthSubTokenInfo और AuthSubRevokeToken. AuthSubTokenInfo का इस्तेमाल, टोकन की वैधता की जाँच करने के लिए किया जाता है. AuthSubRevokeToken उपयोगकर्ताओं को अपने डेटा का ऐक्सेस बंद करने का विकल्प देता है. आपके ऐप्लिकेशन को सबसे सही तरीके के तौर पर, AuthSubRevokeToken का इस्तेमाल करना चाहिए. दोनों तरीकों का इस्तेमाल Ruby लाइब्रेरी में किया जा सकता है.

किसी टोकन के मेटाडेटा के बारे में क्वेरी करने के लिए:

client.auth_handler.info

सेशन टोकन रद्द करने के लिए:

client.auth_handler.revoke

AuthSub के बारे में पूरी जानकारी पाने के लिए, वेब ऐप्लिकेशन के लिए AuthSub की पुष्टि करने की सुविधा से जुड़ा पूरा दस्तावेज़ देखें.

OAuth

इस लेख को लिखते समय, OAuth को GData::Auth मॉड्यूल में नहीं जोड़ा गया था.

Rails oauth-plugin या Ruby oauth gem का इस्तेमाल करते समय, यूटिलिटी लाइब्रेरी में OAuth का इस्तेमाल करना आसान होना चाहिए. दोनों ही मामलों में, आपको एक GData::HTTP::Request ऑब्जेक्ट बनाना होगा. साथ ही, हर लाइब्रेरी से जनरेट किए गए Authorization हेडर को पास करना होगा.

फ़ीड ऐक्सेस करना

GET (डेटा फ़ेच करना)

क्लाइंट ऑब्जेक्ट सेट अप करने के बाद, Google Data फ़ीड से क्वेरी करने के लिए, इसके get() तरीके का इस्तेमाल करें. एक्सपाथ का इस्तेमाल करके, खास ऐटम एलिमेंट वापस पाए जा सकते हैं. यहां किसी उपयोगकर्ता के Google दस्तावेज़ों को वापस पाने का एक उदाहरण दिया गया है:

feed = client.get('http://docs.google.com/feeds/documents/private/full').to_xml

feed.elements.each('entry') do |entry|
  puts 'title: ' + entry.elements['title'].text
  puts 'type: ' + entry.elements['category'].attribute('label').value
  puts 'updated: ' + entry.elements['updated'].text
  puts 'id: ' + entry.elements['id'].text
  
  # Extract the href value from each <atom:link>
  links = {}
  entry.elements.each('link') do |link|
    links[link.attribute('rel').value] = link.attribute('href').value
  end
  puts links.to_s
end

POST (नया डेटा बनाना)

सर्वर पर नया डेटा बनाने के लिए, क्लाइंट के post() तरीके का इस्तेमाल करें. यहां दिए गए उदाहरण में, new_writer@example.com को doc_id आईडी वाले दस्तावेज़ में सहयोगी के तौर पर जोड़ा जाएगा.

# Return documents the authenticated user owns
feed = client.get('http://docs.google.com/feeds/documents/private/full/-/mine').to_xml
entry = feed.elements['entry']  # first <atom:entry>

acl_entry = <<-EOF
<entry xmlns="http://www.w3.org/2005/Atom" xmlns:gAcl='http://schemas.google.com/acl/2007'>
  <category scheme='http://schemas.google.com/g/2005#kind'
    term='http://schemas.google.com/acl/2007#accessRule'/>
  <gAcl:role value='writer'/>
  <gAcl:scope type='user' value='new_writer@example.com'/>
</entry>
EOF

# Regex the document id out from the full <atom:id>.
# http://docs.google.com/feeds/documents/private/full/document%3Adfrk14g25fdsdwf -> document%3Adfrk14g25fdsdwf
doc_id = entry.elements['id'].text[/full\/(.*%3[aA].*)$/, 1]
response = client.post("http://docs.google.com/feeds/acl/private/full/#{doc_id}", acl_entry)

PUT (डेटा अपडेट करना)

सर्वर पर डेटा अपडेट करने के लिए, क्लाइंट के put() तरीके का इस्तेमाल करें. यहां दिए गए उदाहरण में, किसी दस्तावेज़ का टाइटल अपडेट किया जाएगा. इससे यह माना जाता है कि आपके पास पिछली क्वेरी का फ़ीड है.

entry = feed.elements['entry'] # first <atom:entry>

# Update the document's title
entry.elements['title'].text = 'Updated title'
entry.add_namespace('http://www.w3.org/2005/Atom')
entry.add_namespace('gd','http://schemas.google.com/g/2005')

edit_uri = entry.elements["link[@rel='edit']"].attributes['href']
response = client.put(edit_uri, entry.to_s)

मिटाएं

सर्वर से किसी <atom:entry> या अन्य डेटा को मिटाने के लिए, delete() तरीके का इस्तेमाल करें. इस उदाहरण में, किसी दस्तावेज़ को मिटाया जाएगा. इस कोड में यह माना गया है कि आपके पास पिछली क्वेरी से कोई दस्तावेज़ एंट्री है.

entry = feed.elements['entry'] # first <atom:entry>
edit_uri = entry.elements["link[@rel='edit']"].attributes['href']
client.headers['If-Match'] = entry.attribute('etag').value  # make sure we don't nuke another client's updates
client.delete(edit_uri)

नया Rails ऐप्लिकेशन बनाना

आम तौर पर, नया Rails ऐप्लिकेशन बनाने के लिए, सबसे पहले स्कैफ़ोल्ड जनरेटर चलाकर एमवीसी फ़ाइलें बनाई जाती हैं. इसके बाद, यह rake db:migrate आपके डेटाबेस टेबल सेट अप करने के लिए काम करता है. हालांकि, हमारा ऐप्लिकेशन डेटा के लिए Google Documents List API से क्वेरी करेगा. इसलिए, हमें सामान्य स्केफ़ोल्डिंग या डेटाबेस की ज़रूरत नहीं है. इसके बजाय, एक नया ऐप्लिकेशन और सामान्य कंट्रोलर बनाएं:

rails doclist
cd doclist
ruby script/generate controller doclist

और config/environment.rb में ये बदलाव करें:

config.frameworks -= [ :active_record, :active_resource, :action_mailer ]
config.gem 'gdata', :lib => 'gdata'

पहली लाइन, ऐप्लिकेशन से ActiveRecord को हटा देती है. दूसरी लाइन, स्टार्टअप के समय gdata gem को लोड करती है.

आखिर में, मैंने डिफ़ॉल्ट रूट ('/') को DoclistController में मौजूद documents कार्रवाई से कनेक्ट किया. config/routes.rb में यह लाइन जोड़ें:

map.root :controller => 'doclist', :action => 'all'

कंट्रोलर शुरू करना

हमने स्केफ़ोल्डिंग जनरेट नहीं की है. इसलिए, app/controllers/doclist_controller.rb में मौजूद DoclistController में, 'all' नाम का ऐक्शन मैन्युअल तरीके से जोड़ें.

class DoclistController < ApplicationController
  def all
    @foo = 'I pity the foo!'
  end
end

और all.html.erb में जाकर all.html.erb बनाएं:app/views/doclist/

<%= @foo %>

वेब सर्वर चालू करें और डेवलपमेंट शुरू करें

अब आपको ruby script/server को शुरू करके, डिफ़ॉल्ट वेब सर्वर शुरू करने का विकल्प मिलेगा. अगर सब कुछ ठीक है, तो अपने ब्राउज़र पर http://localhost:3000/ खोलने पर 'I pity the foo!' दिखना चाहिए.

अहम जानकारी: public/index.html को हटाना या उसका नाम बदलना न भूलें.

जब सब कुछ काम करने लगे, तब DocList Manager प्रोजेक्ट के मुख्य हिस्से के लिए, मेरे फ़ाइनल DoclistController और ApplicationController को देखें. आपको ContactsController को भी देखना होगा. यह Google Contacts API को कॉल मैनेज करता है.

नतीजा

Google Data Rails ऐप्लिकेशन बनाने का सबसे मुश्किल हिस्सा, Rails को कॉन्फ़िगर करना है! हालांकि, इसके बाद सबसे ज़रूरी काम है अपने ऐप्लिकेशन को डिप्लॉय करना. इसके लिए, हम Apache के लिए mod_rails इस्तेमाल करने का सुझाव देते हैं. इसे सेट अप करना, इंस्टॉल करना, और चलाना बहुत आसान है. आपको जल्द ही इसका इस्तेमाल करने का मौका मिलेगा!

संसाधन

अन्य जानकारी

उदाहरण

DocList Manager, Ruby on Rails का एक पूरा सैंपल है. इसमें इस लेख में बताए गए विषयों के बारे में जानकारी दी गई है. पूरा सोर्स कोड, प्रोजेक्ट होस्टिंग से उपलब्ध है.