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.
Constant Summary collapse
- DOMAIN =
'www.google.com'
- AuthSubPath =
all variants go over HTTPS
'/accounts/AuthSub'
- ClientLogin =
'/accounts/ClientLogin'
- FeedsPath =
'/m8/feeds/contacts/'
Instance Attribute Summary collapse
-
#author ⇒ Object
readonly
Returns the value of attribute author.
-
#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.
-
.session_token(token) ⇒ Object
Makes an HTTPS request to exchange the given token with a session one.
-
.set_private_key(key) ⇒ Object
Sets the private key for a secure AuthSub request.
-
.unset_private_key ⇒ Object
Unsets the private key.
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:.
-
#initialize(token, user_id = 'default', client = false) ⇒ Google
constructor
A token is required here.
-
#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.
143 144 145 146 147 148 149 150 151 152 |
# File 'lib/contacts/google.rb', line 143 def initialize(token, user_id = 'default', client = false) @user = user_id.to_s @token = token.to_s @client = client @headers = { 'Accept-Encoding' => 'gzip', 'User-Agent' => Identifier + ' (gzip)' }.update(self.class.(@token, client)) @projection = 'thin' end |
Instance Attribute Details
#author ⇒ Object (readonly)
Returns the value of attribute author.
138 139 140 |
# File 'lib/contacts/google.rb', line 138 def @author end |
#headers ⇒ Object (readonly)
Returns the value of attribute headers.
138 139 140 |
# File 'lib/contacts/google.rb', line 138 def headers @headers end |
#projection ⇒ Object
Returns the value of attribute projection.
139 140 141 |
# File 'lib/contacts/google.rb', line 139 def projection @projection end |
#token ⇒ Object (readonly)
Returns the value of attribute token.
138 139 140 |
# File 'lib/contacts/google.rb', line 138 def token @token end |
#user ⇒ Object (readonly)
Returns the value of attribute user.
138 139 140 |
# File 'lib/contacts/google.rb', line 138 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 86 87 88 89 |
# File 'lib/contacts/google.rb', line 80 def self.authentication_url(target, = {}) params = .merge() if key = params.delete(:key) params[:secure] = true set_private_key(key) end 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. @authentication_url_options ||= { :scope => "https://#{DOMAIN}#{FeedsPath}", :secure => false, :session => false } end |
.client_login(email, password) ⇒ Object
Alternative to AuthSub: using email and password.
128 129 130 131 132 133 134 135 136 |
# File 'lib/contacts/google.rb', line 128 def self.client_login(email, password) response = http_start do |google| query = query_string(.merge(:Email => email, :Passwd => password)) 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. @client_login_options ||= { :accountType => 'GOOGLE', :service => 'cp', :source => 'Contacts-Ruby' } 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.
117 118 119 120 121 122 123 124 125 |
# File 'lib/contacts/google.rb', line 117 def self.session_token(token) response = http_start(true) do |google| uri = AuthSubPath + 'SessionToken' header = (token, false, uri) google.get(uri, header) end pair = response.body.split(/\n/).detect { |p| p.index('Token=') == 0 } pair.split('=').last if pair end |
.set_private_key(key) ⇒ Object
Sets the private key for a secure AuthSub request. key
may be an IO, String or OpenSSL::PKey::RSA. Stolen from github.com/stuart/google-authsub/lib/googleauthsub.rb
94 95 96 97 98 99 100 101 102 103 104 105 |
# File 'lib/contacts/google.rb', line 94 def self.set_private_key(key) case key when OpenSSL::PKey::RSA @@pkey = key when File @@pkey = OpenSSL::PKey::RSA.new(key.read) when String @@pkey = OpenSSL::PKey::RSA.new(key) else raise "Private Key in wrong format. Require IO, String or OpenSSL::PKey::RSA, you gave me #{key.class}" end end |
.unset_private_key ⇒ Object
Unsets the private key. Only used for test teardowns.
108 109 110 |
# File 'lib/contacts/google.rb', line 108 def self.unset_private_key @@pkey = nil end |
Instance Method Details
#all_contacts(options = {}, chunk_size = 200) ⇒ Object
Fetches contacts using multiple API calls when necessary
192 193 194 |
# File 'lib/contacts/google.rb', line 192 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
185 186 187 188 189 |
# File 'lib/contacts/google.rb', line 185 def contacts( = {}) params = { :limit => 200 }.update() response = get(params) parse_contacts response_body(response) end |
#get(params) ⇒ Object
:nodoc:
154 155 156 157 158 159 160 161 162 163 |
# File 'lib/contacts/google.rb', line 154 def get(params) # :nodoc: self.class.http_start(true) do |google| path = FeedsPath + CGI.escape(@user) google_params = translate_parameters(params) query = self.class.query_string(google_params) uri = "#{path}/#{@projection}?#{query}" headers = @headers.update(self.class.(@token, @client, uri)) google.get(uri, headers) end 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.
167 168 169 |
# File 'lib/contacts/google.rb', line 167 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
172 173 174 |
# File 'lib/contacts/google.rb', line 172 def updated_at_string @updated_string end |