Class: Contacts::Google
- Inherits:
-
Object
- Object
- Contacts::Google
- Defined in:
- lib/contacts/google.rb
Overview
Fetching Google Contacts
First, get the user to follow the following URL:
Contacts::Google.authentication_url('http://mysite.com/invite')
After he authenticates successfully to Google, it will redirect him back to the target URL (specified as argument above) and provide the token GET parameter. Use it to create a new instance of this class and request the contact list:
gmail = Contacts::Google.new(params[:token])
contacts = gmail.contacts
#-> [ ['Fitzgerald', '[email protected]', '[email protected]'],
['William Paginate', '[email protected]'], ...
]
Storing a session token
The basic token that you will get after the user has authenticated on Google is valid for only one request. However, you can specify that you want a session token which doesn’t expire:
Contacts::Google.authentication_url('http://mysite.com/invite', :session => true)
When the user authenticates, he will be redirected back with a token that can be exchanged for a session token with the following method:
token = Contacts::Google.sesion_token(params[:token])
Now you have a permanent token. Store it with other user data so you can query the API on his behalf without him having to authenticate on Google each time.
Direct Known Subclasses
Constant Summary collapse
- DOMAIN =
'www.google.com'- AuthSubPath =
all variants go over HTTPS
'/accounts/AuthSub'- ClientLogin =
'/accounts/ClientLogin'- FeedsPath =
'/m8/feeds/contacts/'- GroupsPath =
'/m8/feeds/groups/'
Instance Attribute Summary collapse
-
#headers ⇒ Object
readonly
Returns the value of attribute headers.
-
#projection ⇒ Object
Returns the value of attribute projection.
-
#token ⇒ Object
readonly
Returns the value of attribute token.
-
#user ⇒ Object
readonly
Returns the value of attribute user.
Class Method Summary collapse
-
.authentication_url(target, options = {}) ⇒ Object
URL to Google site where user authenticates.
-
.authentication_url_options ⇒ Object
default options for #authentication_url.
-
.client_login(email, password) ⇒ Object
Alternative to AuthSub: using email and password.
-
.client_login_options ⇒ Object
default options for #client_login.
- .response_body(response) ⇒ Object
-
.session_token(token) ⇒ Object
Makes an HTTPS request to exchange the given token with a session one.
Instance Method Summary collapse
-
#all_contacts(options = {}, chunk_size = 200) ⇒ Object
Fetches contacts using multiple API calls when necessary.
-
#contacts(options = {}) ⇒ Object
Fetches, parses and returns the contact list.
-
#get(params = {}) ⇒ Object
:nodoc:.
- #get_groups(params = {}) ⇒ Object
- #groups(options = {}) ⇒ Object
-
#initialize(token, user_id = 'default', client = false) ⇒ Google
constructor
A token is required here.
- #response_body(response) ⇒ Object
-
#updated_at ⇒ Object
Timestamp of last update.
-
#updated_at_string ⇒ Object
Timestamp of last update as it appeared in the XML document.
Constructor Details
#initialize(token, user_id = 'default', client = false) ⇒ Google
A token is required here. By default, an AuthSub token from Google is one-time only, which means you can only make a single request with it.
118 119 120 121 122 123 124 125 126 127 |
# File 'lib/contacts/google.rb', line 118 def initialize(token, user_id = 'default', client = false) @user = user_id.to_s @token = token.to_s @headers = { 'Accept-Encoding' => 'gzip', 'User-Agent' => Identifier + ' (gzip)', 'GData-Version' => '3.0' }.update(self.class.(@token, client)) @projection = 'thin' end |
Instance Attribute Details
#headers ⇒ Object (readonly)
Returns the value of attribute headers.
113 114 115 |
# File 'lib/contacts/google.rb', line 113 def headers @headers end |
#projection ⇒ Object
Returns the value of attribute projection.
114 115 116 |
# File 'lib/contacts/google.rb', line 114 def projection @projection end |
#token ⇒ Object (readonly)
Returns the value of attribute token.
113 114 115 |
# File 'lib/contacts/google.rb', line 113 def token @token end |
#user ⇒ Object (readonly)
Returns the value of attribute user.
113 114 115 |
# File 'lib/contacts/google.rb', line 113 def user @user end |
Class Method Details
.authentication_url(target, options = {}) ⇒ Object
URL to Google site where user authenticates. Afterwards, Google redirects to your site with the URL specified as target.
Options are:
-
:scope– the AuthSub scope in which the resulting token is valid (default: “www.google.com/m8/feeds/contacts/”) -
:secure– boolean indicating whether the token will be secure. Only available for registered domains. (default: false) -
:session– boolean indicating if the token can be exchanged for a session token (default: false)
80 81 82 83 84 85 |
# File 'lib/contacts/google.rb', line 80 def self.authentication_url(target, = {}) params = .merge() params[:next] = target query = query_string(params) "https://#{DOMAIN}#{AuthSubPath}Request?#{query}" end |
.authentication_url_options ⇒ Object
default options for #authentication_url
52 53 54 55 56 57 58 |
# File 'lib/contacts/google.rb', line 52 def self. ||= { :scope => "http://#{DOMAIN}#{FeedsPath}", :secure => false, :session => false } end |
.client_login(email, password) ⇒ Object
Alternative to AuthSub: using email and password.
102 103 104 105 106 107 108 109 110 111 |
# File 'lib/contacts/google.rb', line 102 def self.client_login(email, password) response = http_start do |google| query = query_string(.merge(:Email => email, :Passwd => password)) puts "posting #{query} to #{ClientLogin}" if Contacts::verbose? google.post(ClientLogin, query) end pair = response.body.split(/\n/).detect { |p| p.index('Auth=') == 0 } pair.split('=').last if pair end |
.client_login_options ⇒ Object
default options for #client_login
61 62 63 64 65 66 67 |
# File 'lib/contacts/google.rb', line 61 def self. ||= { :accountType => 'GOOGLE', :service => 'cp', :source => 'Contacts-Ruby' } end |
.response_body(response) ⇒ Object
191 192 193 194 195 196 197 198 |
# File 'lib/contacts/google.rb', line 191 def self.response_body(response) unless response['Content-Encoding'] == 'gzip' response.body else gzipped = StringIO.new(response.body) Zlib::GzipReader.new(gzipped).read end end |
.session_token(token) ⇒ Object
Makes an HTTPS request to exchange the given token with a session one. Session tokens never expire, so you can store them in the database alongside user info.
Returns the new token as string or nil if the parameter couldn’t be found in response body.
92 93 94 95 96 97 98 99 |
# File 'lib/contacts/google.rb', line 92 def self.session_token(token) response = http_start do |google| google.get(AuthSubPath + 'SessionToken', (token)) end pair = response.body.split(/\n/).detect { |p| p.index('Token=') == 0 } pair.split('=').last if pair end |
Instance Method Details
#all_contacts(options = {}, chunk_size = 200) ⇒ Object
Fetches contacts using multiple API calls when necessary
177 178 179 |
# File 'lib/contacts/google.rb', line 177 def all_contacts( = {}, chunk_size = 200) in_chunks(, :contacts, chunk_size) end |
#contacts(options = {}) ⇒ Object
Fetches, parses and returns the contact list.
Options
-
:limit– use a large number to fetch a bigger contact list (default: 200) -
:offset– 0-based value, can be used for pagination -
:order– currently the only value support by Google is “lastmodified” -
:descending– boolean -
:updated_after– string or time-like object, use to only fetch contacts that were updated after this date
170 171 172 173 174 |
# File 'lib/contacts/google.rb', line 170 def contacts( = {}) params = { :limit => 200 }.update() response = get(params) parse_contacts response_body(response) end |
#get(params = {}) ⇒ Object
:nodoc:
129 130 131 132 133 134 135 136 137 |
# File 'lib/contacts/google.rb', line 129 def get(params={}) # :nodoc: self.class.http_start(false) do |google| path = FeedsPath + CGI.escape(@user) google_params = translate_parameters(params) query = self.class.query_string(google_params) #puts "get query: #{query}" google.get("#{path}/#{@projection}?#{query}", @headers) end end |
#get_groups(params = {}) ⇒ Object
139 140 141 142 143 144 145 146 147 148 |
# File 'lib/contacts/google.rb', line 139 def get_groups(params={}) self.class.http_start(false) do |google| path = GroupsPath + CGI.escape(@user) google_params = translate_parameters(params) query = self.class.query_string(google_params) url = "#{path}/full?#{query}" #puts "get_groups url: #{url}" google.get(url, @headers) end end |
#groups(options = {}) ⇒ Object
181 182 183 184 185 |
# File 'lib/contacts/google.rb', line 181 def groups( = {}) params = {}.update() response = get_groups(params) parse_groups response_body(response) end |
#response_body(response) ⇒ Object
187 188 189 |
# File 'lib/contacts/google.rb', line 187 def response_body(response) self.class.response_body(response) end |
#updated_at ⇒ Object
Timestamp of last update. This value is available only after the XML document has been parsed; for instance after fetching the contact list.
152 153 154 |
# File 'lib/contacts/google.rb', line 152 def updated_at @updated_at ||= Time.parse @updated_string if @updated_string end |
#updated_at_string ⇒ Object
Timestamp of last update as it appeared in the XML document
157 158 159 |
# File 'lib/contacts/google.rb', line 157 def updated_at_string @updated_string end |