Class: Rhoconnect::Android

Inherits:
Object
  • Object
show all
Defined in:
lib/rhoconnect/ping/android.rb

Defined Under Namespace

Classes: AndroidPingError, InvalidAuthToken

Constant Summary collapse

C2DM_AUTHTOKEN_KEY =
'app:application:c2dm_auth_token'

Class Method Summary collapse

Class Method Details

.c2d_message(params) ⇒ Object



64
65
66
67
68
69
70
71
72
73
74
75
# File 'lib/rhoconnect/ping/android.rb', line 64

def self.c2d_message(params)
  params.reject! {|k,v| v.nil? || v.length == 0}
  data = {}
  data['registration_id'] = params['device_pin']
  data['collapse_key'] = (rand * 100000000).to_i.to_s
  data['data.do_sync'] = params['sources'] ? params['sources'].join(',') : ''
  data['data.alert'] = params['message'] if params['message']
  data['data.vibrate'] = params['vibrate'] if params['vibrate']
  data['data.sound'] = params['sound'] if params['sound']
  data['data.phone_id'] = params['phone_id'] if params['phone_id']
  data
end

.get_c2dm_tokenObject



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/rhoconnect/ping/android.rb', line 77

def self.get_c2dm_token
  if Store.exists? C2DM_AUTHTOKEN_KEY
    return Store.get_value(C2DM_AUTHTOKEN_KEY)
  end
  
  settings = get_config(Rhoconnect.base_directory)[Rhoconnect.environment]
  data = {}
  data['accountType'] = 'HOSTED_OR_GOOGLE'
  data['Email'] = settings[:c2dm_username]
  data['Passwd'] = settings[:c2dm_passwd]
  data['service'] = 'ac2dm'
  
  urldata = ''
  data.each do |key,value|
    urldata += '&' + key.to_s + '=' + value.to_s
  end
  urldata[0,1] = ''
  
  RestClient.post(
    'https://www.google.com/accounts/ClientLogin', urldata, 
    :content_type => "application/x-www-form-urlencoded"
  ) do |response, request, result, &block|
    # return exceptions based on response code & body
    case response.code
    when 200
      authdata = /.*Auth=(.*)\n.*/.match(response.body)
      Store.put_value(C2DM_AUTHTOKEN_KEY, authdata[1])
      return authdata[1]
    else
      error_code = "Can not obtain auth token from C2DM service. Make sure that your C2DM credentials are valid."
      if response.body =~ /^Error=(.*)$/
        error_code += ': ' + response.body.to_s
      end
      raise InvalidAuthToken.new(error_code)
    end
  end
  nil
end

.ping(params) ⇒ Object



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/rhoconnect/ping/android.rb', line 10

def self.ping(params)
  already_retried = false
  begin
    settings = get_config(Rhoconnect.base_directory)[Rhoconnect.environment]
    authtoken = settings[:authtoken]
    
    # obtain C2DM auth token
    if not authtoken
      authtoken = get_c2dm_token
      if not already_retried
        authtoken = "BadToken"
      end
    end
          
    send_ping_to_device(authtoken, params)
  rescue InvalidAuthToken => error
    if not already_retried
      Store.flash_data(C2DM_AUTHTOKEN_KEY)
      already_retried = true
      retry
    end
    log error
    log error.backtrace.join("\n")
    raise error
  rescue Exception => error
    log error
    log error.backtrace.join("\n")
    raise error
  end
end

.send_ping_to_device(authtoken, params) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
# File 'lib/rhoconnect/ping/android.rb', line 41

def self.send_ping_to_device(authtoken,params)
  RestClient.post(
    'https://android.apis.google.com/c2dm/send', c2d_message(params), 
    :authorization => "GoogleLogin auth=#{authtoken}"
  ) do |response, request, result, &block|
    # return exceptions based on response code & body
    case response.code
    when 200
      if response.body =~ /^Error=(.*)$/
        raise AndroidPingError.new("Android ping error: #{$1 || ''}")
      else
        # store new token in redis for future calls
        if response.headers[:update_client_auth]
          Store.put_value(C2DM_AUTHTOKEN_KEY, response.headers[:update_client_auth])
        end
        response.return!(request, result, &block)
      end
    when 401, 403
      raise InvalidAuthToken.new("Invalid or expired auth token. Obtain new authtoken from C2DM service.")
    end
  end
end