Chao!
Come to see you again, today I would like to introduce to you a way to connect directly to Google and call its open API easily.
As you have experience. In the process of developing an application, sometimes with specific requirements, we have to work with the develop apps of large systems like Google with applications like sending email … and often with newcomers. Beginners will have some difficulty configuring this place – so that the application can send and receive requests with other platforms.
So don’t let you wait any longer, we start right away: Google Data on Rails
PS. I used Ruby, the Rails framework for the tutorial
Hate-ding-ting-titit
We need the configuration required: Ruby, RubyGems, Rails before we want to use gdata for our application. A small note here is that on Google’s documentation page, versions of Ruby and Rails are very old compared to the present time. So everyone when reading the document can be flexible in this place. Use some new version for newer.
After having a good environment, inside the developing application, we run:
1 2 | sudo gem install gdata |
After running this national command, if anyone is careful, you can run the following command:
1 2 | gem list --local |
to check whether the gem has been installed okie or not
Installation is complete, you can check the version of things to see the remainder. Now I go to the Authenticate section
Authentication
Simple visualization like this: Currently I want to get api from an existing application. Therefore, from the perspective of the application, it is clear that they are late to verify and grant access to the requests from outside. So we need to log in to be able to access the requests.
Well, I see in this place the Google developer has a note like this: If I am developing desktop applications of all kinds (it’s been a long time, I used to learn java swing. you can login using CliendLogin. As for Web applications, AuthSub or OAuth should be preferred.
We in turn go through each type of login to see how it looks!
ClientLogin
Google it has a lot of platforms that provide API for customers to use. Typical examples like Gmail, Youtube … We will in turn login to each platform there.
Pretend we have a Google account that has:
Email: [email protected]
Password: “pa $$ word”
Login DocList
1 2 3 | client = GData::Client::DocList.new client.clientlogin(' <a class="__cf_email__" href="/cdn-cgi/l/email-protection">[email protected]</a> ', 'pa$$word') |
Login Youtube
1 2 3 | client = GData::Client::YouTube.new client.clientlogin(' <a class="__cf_email__" href="/cdn-cgi/l/email-protection">[email protected]</a> ', 'pa$$word') |
If you are late to login to use Google’s full list service. You can login directly to its Base class. But in this case G Suite should be used
1 2 3 4 | client_login_handler = GData::Auth::ClientLogin.new('writely', :account_type => 'HOSTED') token = client_login_handler.get_token(' <a class="__cf_email__" href="/cdn-cgi/l/email-protection">[email protected]</a> ', 'pa$$word', 'google-RailsArticleSample-v1') client = GData::Client::Base.new(:auth_handler => client_login_handler) |
There is another place to note here. It is difficult for ClientLogin to pass through the logines that need CAPTCHA. What I need to do is add the CAPTCHA condition to these cases by calling the clientlogin()
method clientlogin()
1 2 | client.clientlogin(username, password, captcha_token, captcha_answer) |
In the Google documentation page, it adds a pretty good link for you to learn more, I put it HERE !
AuthSub
To use AuthSub, first you need to generate AuthSubRequest URL first
1 2 3 4 5 6 | 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) |
It will generate the below link in authsub_link
:
1 2 | 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 |
You can also add authsub_url to the client object. Each service class has been set a default authsub_scope
as shown below
1 2 3 4 5 6 7 | 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) |
Corresponding URL:
1 2 | 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 |
Use session instead of authenticate ones for single-request.
The problem set out here is also simple. Instead of with each request to api. You need a token add on request to do authent. And the add token work is done again and again. Then we can create a session with a single access authent. Later in the session log, we can access the request comfortably.
1 2 3 4 | 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] |
As the above code clearly states. After receiving token-single request parrams. We add that token for the token of a session and authenticate on that session. If the token exists, the request pass is authenticate.
Once done, create the session. We need to put the values to be secured in environment variables. On the original VD of the document being written like this:
1 2 3 4 5 6 7 | 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] |
Token management
AuthSub provides us with 2 additional handlers to manage tokens: AuthSubTokenInfor and AuthSubRevokeToken. The function of these two monkeys is to check the information, the validity of the token and withdraw.
You can look at the 2 examples below to see
1 2 | client.auth_handler.info |
1 2 | client.auth_handler.revoke |
Accessing feeds
Now we look at the methods to send requests to the api with specific examples.
GET (fetching data)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | 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 (creating new data)
This example is using the POST method to create a new data on the server. Specifically, it adds new [email protected]
to docs with id is doc_id
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | # 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=' <a class="__cf_email__" href="/cdn-cgi/l/email-protection">[email protected]</a> '/> </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 (updating data)
Similar to POST. You can use PUT to update the new data you need
1 2 3 4 5 6 7 8 9 10 | 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) |
Delete
Finally, Delete
1 2 3 4 5 | 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) |
Above I just introduced to you a pretty Lib that supports the connection and application of Google api from your developing application. I hope it will be of help to you when needed