-
-
Save dsisnero/5a0e1b85f998c61d0dac to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2.1.2 :004 > pp Google::Contacts.new(client).contacts | |
[{:emails=>{:other=>{:address=>"fake@gmail.com", :primary=>true}}, | |
:phone_numbers=> | |
{:main=>"(555) 123-1234", :home=>"123-123-1234", :mobile=>"555-555-5555"}, | |
:handles=> | |
{:home=>{:address=>"something", :protocol=>"AIM"}, | |
:other=>{:address=>"something-else", :protocol=>"AIM"}}, | |
:nickname=>nil, | |
:websites=>[], | |
:organizations=>[], | |
:events=>[], | |
:birthday=>nil, | |
:addresses=> | |
{:home=> | |
{:formatted_address=>"123 Fake St, New York, NY 12345", | |
:street=>"123 Fake St", | |
:city=>"New York", | |
:region=>"NY", | |
:postcode=>"12345"}}, | |
:name_data=> | |
{:full_name=>"John Smith", | |
:given_name=>"John", | |
:family_name=>"Smith"}, | |
:full_name=>"John Smith", | |
:primary_email=>"fake@gmail.com"}, | |
... | |
] | |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Google | |
class Contacts | |
attr_reader :client | |
def initialize(client) | |
@client = client | |
end | |
def execute(options = {}) | |
client.execute({ headers: { 'GData-Version' => '3.0', 'Content-Type' => 'application/json' } }.merge(options)) | |
end | |
def fetch_all(options = {}) | |
execute(uri: "https://www.google.com/m8/feeds/contacts/default/full", | |
parameters: { 'alt' => 'json', | |
'updated-min' => options[:since] || '2011-03-16T00:00:00', | |
'max-results' => '100000' }).data | |
end | |
def contacts | |
fetch_all['feed']['entry'].map do |contact| | |
{ | |
emails: extract_schema(contact['gd$email']), | |
phone_numbers: extract_schema(contact['gd$phoneNumber']), | |
handles: extract_schema(contact['gd$im']), | |
addresses: extract_schema(contact['gd$structuredPostalAddress']), | |
name_data: cleanse_gdata(contact['gd$name']), | |
nickname: contact['gContact$nickname'] && contact['gContact$nickname']['$t'], | |
websites: extract_schema(contact['gContact$website']), | |
organizations: extract_schema(contact['gd$organization']), | |
events: extract_schema(contact['gContact$event']), | |
birthday: contact['gContact$birthday'].try(:[], "when") | |
}.tap do |basic_data| | |
# Extract a few useful bits from the basic data | |
basic_data[:full_name] = basic_data[:name_data].try(:[], :full_name) | |
primary_email_data = basic_data[:emails].find { |type, email| email[:primary] } | |
if primary_email_data | |
basic_data[:primary_email] = primary_email_data.last[:address] | |
end | |
end | |
end | |
end | |
protected | |
# Turn an array of hashes into a hash with keys based on the original hash's 'rel' values, flatten, and cleanse. | |
def extract_schema(records) | |
(records || []).inject({}) do |memo, record| | |
key = (record['rel'] || 'unknown').split('#').last.to_sym | |
value = cleanse_gdata(record.except('rel')) | |
value[:primary] = true if value[:primary] == 'true' # cast to a boolean for primary entries | |
value[:protocol] = value[:protocol].split('#').last if value[:protocol].present? # clean namespace from handle protocols | |
value = value[:$t] if value[:$t].present? # flatten out entries with keys of '$t' | |
value = value[:href] if value.is_a?(Hash) && value.keys == [:href] # flatten out entries with keys of 'href' | |
memo[key] = value | |
memo | |
end | |
end | |
# Transform this | |
# {"gd$fullName"=>{"$t"=>"Bob Smith"}, | |
# "gd$givenName"=>{"$t"=>"Bob"}, | |
# "gd$familyName"=>{"$t"=>"Smith"}} | |
# into this | |
# { :full_name => "Bob Smith", | |
# :given_name => "Bob", | |
# :family_name => "Smith" } | |
def cleanse_gdata(hash) | |
(hash || {}).inject({}) do |m, (k, v)| | |
k = k.gsub(/\Agd\$/, '').underscore # remove leading 'gd$' on key names and switch to underscores | |
v = v['$t'] if v.is_a?(Hash) && v.keys == ['$t'] # flatten out { '$t' => "value" } results | |
m[k.to_sym] = v | |
m | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment