Chao!
Đến hẹn lại lên, hôm nay mình xin giới thiệu đến các bạn một cách để connect trực tiếp đến Google và gọi ra những API open của nó dễ dàng.
Như các bạn đã trải nghiệm thực tế. Trong quá trình phát triển một ứng dụng, đôi lúc với những yêu cầu đặc thù, chúng ta phải làm việc với các app develop của những hệ thống lớn như Google với các ứng dụng như send email…Và thường với những người mới bắt đầu sẽ gặp một vài khó khăn khi tiến hành config chổ này-làm sao cho ứng dụng có thể gửi nhận request với các nền tảng khác.
Vậy không để các bạn chờ lâu nữa, chúng ta bắt đầu ngay với: Google Data on Rails
PS. Mình lấy ngôn ngữ là Ruby, framework Rails để làm bài hướng dẫn ạ
Ghét-đing xờ-ta-tít
Chúng ta cần có những cấu hình required: Ruby, RubyGems, Rails trước khi muốn sử dụng gdata cho ứng dụng. Một lưu ý nhỏ ở đây là trên trang tài liệu của Google đang để những phiên bản của Ruby cũng như Rails rất cũ so với thời điểm hiện tại. Nên mọi người khi đọc tài liệu thì có thể linh động chổ này nhé. Dùng version nào đấy cho mới mẻ hơn.
Sau khi có môi trường tốt, bên trong ứng dụng đang phát triển, ta chạy:
1 2 | sudo gem install gdata |
Sau khi chạy xong câu lệnh quốc dân này, nếu ai cẩn thận thì có thể chạy tiếp lệnh:
1 2 | gem list --local |
để check xem gem đã install okie hay là chưa
Cài đặt xong rồi đấy, bạn có thể check version các thứ xem dư lào. Bây giờ mình đi tiếp tới phần Authenticate
Authentication
Hình dung đơn giản như này nhé: Hiện tại mình đang muốn lấy api từ một ứng dụng đang có sẵn. Bời vậy nên ở góc nhìn của ứng dụng đấy, rõ ràng họ muộn kiểm định và cấp quyền tuy cập cho những request từ bên ngoài rồi. Vậy nên chúng ta cần đăng nhập để có thể access được các request.
À, mình thấy ở chổ này nhà phát triển Google nó có lưu ý như thế này: Nếu đang phát triển các ứng dụng cho máy tính để bàn các kiểu(cái ni lâu rồi nè, hồi xưa mình có học java swing á thì có thể login bằng CliendLogin. Còn đối với các ứng dụng Web, nên ưu tiền dùng AuthSub hoặc OAuth.
Chúng ta lần lượt đi qua từng kiểu login xem nó như thế nào nhé!
ClientLogin
Google nó có rất nhiều nền tảng cung cấp api cho khách hàng sử dụng. Những ví dụ điển hình như Gmail, Youtube…Chúng ta sẽ lần lượt login vào từng nền tảng đấy.
Giả vờ như ta có một account Google có:
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') |
Nếu bạn muộn login để dùng full list service của Google. Bạn có thể login thằng vô class Base của nó. Nhưng trong trường hợp này thì nên dùng G Suite
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) |
Lại có một chổ lưu ý ở đây nữa. Đại loại ClientLogin khó có thể passing qua được những login cần CAPTCHA. Điều mình cần làm là add thêm condition CAPTCHA cho các trường hợp này bằng cách gọi method clientlogin()
1 2 | client.clientlogin(username, password, captcha_token, captcha_answer) |
Trong trang tài liệu hướng dẫn của Google, nó có add thêm một link khá hay để các bạn tìm hiểu thêm, mình để lên ĐÂY nhé!
AuthSub
Để dùng AuthSub, đầu tiên các bạn cần generate AuthSubRequest URL trước đã
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) |
Nó sẽ tạo ra link bên dưới trong 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 |
Bạn cũng có thể dùng thêm authsub_url cho client object. Mỗi service class đã được set một authsub_scope
mặc định như bên dưới
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) |
URL tương ứng:
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 |
Dùng session thay cho các authenticate cho single-request.
Bài toán đặt ra ở đây cũng đơn giản thôi. Thay vì với mỗi request lên api. Bạn cần có một token add theo request để thực hiện authent. Và công việc add token được thực hiện lặp đi lặp lại. Thì chúng ta có thể tạo ra một session với một lần access authent duy nhất. Sau đấy trong phiên đăng nhập của session, chúng ta có thể access request thoải mái.
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] |
Như đoạn code bên trên ghi rõ. Sau khi nhận parrams token-single request. Ta thực hiện add token đó cho token của một session và tiến hành kiểm tra authent trên session đó. Nếu token tồn tại thì request pass được authenticate.
Sau khi thực hiện tạo được session rồi. Ta cần đưa các giá trị cần bảo mật vào biến môi trường. Trên VD gốc của tài liệu đang viết như này:
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 cung cấp thêm cho ta 2 handlers để quản lý token: AuthSubTokenInfor và AuthSubRevokeToken. Chứng năng của 2 thằng khỉ này là để check thông tin, tính hợp lệ của token và thu hồi.
Bạn có thể nhìn qua 2 ví dụ dười để thấy nhé
1 2 | client.auth_handler.info |
1 2 | client.auth_handler.revoke |
Accessing feeds
Bây giờ ta xem xét các phương thức gửi request lên api với những ví dụ cụ thể.
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)
VD này đang dùng phương thức POST để tạo mới một data trên server. Cụ thể nó thêm mới thằng [email protected]
vào docs với id là 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)
Tương tự POST. Bạn có thể dùng PUT để update những data mới bạn cần
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
Cuối cùng là 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) |
Trên đây mình vừa giới thiệu tới các bạn một Lib khá hay hổ trợ cho việc connect và sự dụng api của Google từ ứng dụng đang phát triển của bạn. Mình hy vọng nó sẽ giúp ích cho các bạn khi cần