class GoogleContactsApi::Contact

Represents a single contact. Methods we could implement: :categories, (:content again), :links, (:title again), :email :extended_properties, :deleted, :im, :name, :organizations, :phone_numbers, :structured_postal_addresses, :where

Public Instance Methods

additional_name() click to toggle source
# File lib/google_contacts_api/contact.rb, line 134
def additional_name
  nested_field_name_only 'gd$name', 'gd$additionalName'
end
additional_name_yomi() click to toggle source
# File lib/google_contacts_api/contact.rb, line 137
def additional_name_yomi
  nested_field_yomi_only 'gd$name', 'gd$additionalName'
end
addresses() click to toggle source

Return an Array of Hashes representing addresses with formatted metadata.

# File lib/google_contacts_api/contact.rb, line 164
def addresses
  format_entities('gd$structuredPostalAddress', :format_address)
end
birthday() click to toggle source
# File lib/google_contacts_api/contact.rb, line 146
def birthday
  if self['gContact$birthday']
    day, month, year = self['gContact$birthday']['when'].split('-').reverse
    { year: year == '' ? nil : year.to_i, month: month.to_i, day: day.to_i }
  end
end
deleted_group_memberships() click to toggle source
# File lib/google_contacts_api/contact.rb, line 203
def deleted_group_memberships
  group_membership_info.select { |info| info[:deleted] }.map { |info| info[:href] }
end
emails() click to toggle source

Returns all email addresses for the contact

# File lib/google_contacts_api/contact.rb, line 77
def emails
  self["gd$email"] ? self["gd$email"].map { |e| e.address } : []
end
emails_full() click to toggle source

Return an Array of Hashes representing emails with formatted metadata.

# File lib/google_contacts_api/contact.rb, line 186
def emails_full
  format_entities('gd$email')
end
etag() click to toggle source
# File lib/google_contacts_api/contact.rb, line 25
def etag
  self['gd$etag']
end
family_name() click to toggle source
# File lib/google_contacts_api/contact.rb, line 125
def family_name
  nested_field_name_only 'gd$name', 'gd$familyName'
end
family_name_yomi() click to toggle source
# File lib/google_contacts_api/contact.rb, line 128
def family_name_yomi
  nested_field_yomi_only 'gd$name', 'gd$familyName'
end
format_group_membership(membership) click to toggle source
# File lib/google_contacts_api/contact.rb, line 197
def format_group_membership(membership)
  { deleted: membership['deleted'] == 'true', href: membership['href'] }
end
full_name() click to toggle source
# File lib/google_contacts_api/contact.rb, line 131
def full_name
  nested_t_field_or_nil 'gd$name', 'gd$fullName'
end
given_name() click to toggle source
# File lib/google_contacts_api/contact.rb, line 119
def given_name
  nested_field_name_only 'gd$name', 'gd$givenName'
end
given_name_yomi() click to toggle source
# File lib/google_contacts_api/contact.rb, line 122
def given_name_yomi
  nested_field_yomi_only 'gd$name', 'gd$givenName'
end
group_membership_info() click to toggle source
# File lib/google_contacts_api/contact.rb, line 190
def group_membership_info
  if self['gContact$groupMembershipInfo']
    self['gContact$groupMembershipInfo'].map(&method(:format_group_membership))
  else
    []
  end
end
group_memberships() click to toggle source
# File lib/google_contacts_api/contact.rb, line 200
def group_memberships
  group_membership_info.select { |info| !info[:deleted] }.map { |info| info[:href] }
end
ims() click to toggle source

Returns all instant messaging addresses for the contact. Doesn’t yet distinguish protocols

# File lib/google_contacts_api/contact.rb, line 93
def ims
  self["gd$im"] ? self["gd$im"].map { |i| i.address } : []
end
name_prefix() click to toggle source
# File lib/google_contacts_api/contact.rb, line 140
def name_prefix
  nested_t_field_or_nil 'gd$name', 'gd$namePrefix'
end
name_suffix() click to toggle source
# File lib/google_contacts_api/contact.rb, line 143
def name_suffix
  nested_t_field_or_nil 'gd$name', 'gd$nameSuffix'
end
nested_t_field_or_nil(level1, level2) click to toggle source

Convenience method to return a nested $t field. If the field doesn’t exist, return nil

# File lib/google_contacts_api/contact.rb, line 114
def nested_t_field_or_nil(level1, level2)
  if self[level1]
    self[level1][level2] ? self[level1][level2]['$t']: nil
  end
end
organizations() click to toggle source
# File lib/google_contacts_api/contact.rb, line 167
def organizations
  format_entities('gd$organization').map do |org|
    if org[:org_name]
      org[:org_name_yomi] = org[:org_name]['yomi'] if org[:org_name]['yomi']
      org[:org_name] = name_only(org[:org_name])
    end
    org
  end
end
phone_numbers() click to toggle source

Returns all phone numbers for the contact

# File lib/google_contacts_api/contact.rb, line 72
def phone_numbers
  self["gd$phoneNumber"] ? self["gd$phoneNumber"].map { |e| e['$t'] } : []
end
phone_numbers_full() click to toggle source

Return an Array of Hashes representing phone numbers with formatted metadata.

# File lib/google_contacts_api/contact.rb, line 181
def phone_numbers_full
  format_entities('gd$phoneNumber', :format_phone_number)
end
photo() click to toggle source

Returns binary data for the photo. You can probably use it in a data-uri. This is in PNG format.

# File lib/google_contacts_api/contact.rb, line 43
def photo
  return nil unless @api && photo_link
  response = @api.oauth.get(photo_link)

  case GoogleContactsApi::Api.parse_response_code(response)
  # maybe return a placeholder instead of nil
  when 400; return nil
  when 401; return nil
  when 403; return nil
  when 404; return nil
  when 400...500; return nil
  when 500...600; return nil
  else; return response.body
  end
end
photo_link_entry() click to toggle source

Returns link entry for the photo

# File lib/google_contacts_api/contact.rb, line 30
def photo_link_entry
  self["link"].find { |l| l.rel == "http://schemas.google.com/contacts/2008/rel#photo" }
end
photo_with_metadata() click to toggle source
# File lib/google_contacts_api/contact.rb, line 97
def photo_with_metadata
  # etag is always specified if actual photo is present
  _link = photo_link_entry
  return nil unless @api && _link['gd$etag']

  response = @api.oauth.get(_link.href)
  if GoogleContactsApi::Api.parse_response_code(response) == 200
    {
        etag: _link['gd$etag'].gsub('"',''),
        content_type: response.headers['content-type'],
        data: response.body
    }
  end
end
primary_email() click to toggle source

Returns primary email for the contact

# File lib/google_contacts_api/contact.rb, line 82
def primary_email
  if self["gd$email"]
    _email = self["gd$email"].find { |e| e.primary == "true" }
    _email ? _email.address : nil
  else
    nil # no emails at all
  end
end
relations() click to toggle source
# File lib/google_contacts_api/contact.rb, line 153
def relations
  self['gContact$relation'] ? self['gContact$relation'] : []
end
spouse() click to toggle source

Returns the spouse of the contact. (Assumes there’s only one.)

# File lib/google_contacts_api/contact.rb, line 158
def spouse
  spouse_rel = relations.find {|r| r.rel = 'spouse'}
  spouse_rel['$t'] if spouse_rel
end
websites() click to toggle source
# File lib/google_contacts_api/contact.rb, line 176
def websites
  format_entities('gContact$website')
end

Private Instance Methods

format_address(unformatted) click to toggle source
# File lib/google_contacts_api/contact.rb, line 248
def format_address(unformatted)
  address = format_entity(unformatted, 'work')
  address[:street] ||= nil
  address[:city] ||= nil
  address[:region] ||= nil
  address[:postcode] ||= nil
  address[:country] = format_country(unformatted['gd$country'])
  address.delete :formatted_address
  address
end
format_country(country) click to toggle source
# File lib/google_contacts_api/contact.rb, line 259
def format_country(country)
  return nil unless country
  country['$t'].nil? || country['$t'] == '' ? country['code'] : country['$t']
end
format_entities(key, format_method=:format_entity) click to toggle source
# File lib/google_contacts_api/contact.rb, line 226
def format_entities(key, format_method=:format_entity)
  self[key] ? self[key].map(&method(format_method)) : []
end
format_entity(unformatted, default_rel=nil, text_key=nil) click to toggle source
# File lib/google_contacts_api/contact.rb, line 230
def format_entity(unformatted, default_rel=nil, text_key=nil)
  attrs = Hash[unformatted.map { |key, value|
    case key
    when 'primary'
      [:primary, value == true || value == 'true']
    when 'rel'
      [:rel, value.gsub('http://schemas.google.com/g/2005#', '')]
    when '$t'
      [text_key || key.underscore.to_sym, value]
    else
      [key.sub('gd$', '').underscore.to_sym, value['$t'] ? value['$t'] : value]
    end
  }]
  attrs[:rel] ||= default_rel
  attrs[:primary] = false if attrs[:primary].nil?
  attrs
end
format_phone_number(unformatted) click to toggle source
# File lib/google_contacts_api/contact.rb, line 264
def format_phone_number(unformatted)
  format_entity unformatted, nil, :number
end
name_only(name) click to toggle source

Certain fields allow an optional Japanese yomigana subfield (making it sometimes be a hash which can cause a bug if you’re expecteding a string) This normalizes the field to a string whether the yomi is present or not This method also accounts for any other unexpected fields

# File lib/google_contacts_api/contact.rb, line 216
def name_only(name)
  return name if name.blank?
  return name if name.is_a?(String)
  name['$t']
end
nested_field_name_only(level1, level2) click to toggle source
# File lib/google_contacts_api/contact.rb, line 208
def nested_field_name_only(level1, level2)
  name_only(self[level1][level2]) if self[level1]
end
nested_field_yomi_only(level1, level2) click to toggle source
# File lib/google_contacts_api/contact.rb, line 222
def nested_field_yomi_only(level1, level2)
  self[level1][level2]['yomi'] if self[level1]
end