localytics-ruby 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +15 -0
- data/lib/localytics-ruby.rb +1 -0
- data/lib/localytics.rb +80 -0
- data/lib/localytics/profile.rb +45 -0
- data/lib/localytics/push.rb +71 -0
- data/test/localytics_test.rb +73 -0
- data/test/test_helper.rb +103 -0
- metadata +95 -0
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
OWI0YTMzNDBiYjA1NTUyZDc2Y2ZkMWE3NjJiNGNjN2IxYzJjOGMyZA==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
Y2FkMWNjYWU1NGRlOGVmYjVhNDI1NGZiNDJkZDIzOTI1YmY3NWQ1Ng==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
Y2ZlMDU0ZmUxNTI3NzVhMmMyNzBhZGMwNWRiYWQzYjk2ZTgyYzEwNzE2ZDhj
|
10
|
+
MzM3YjZhODNhOTE4NWEzOWFjMDk1ZmQwNmVkYzI5OGIwNWEzNDhmY2FlMDA5
|
11
|
+
NDc4NWIyMWIzYWJkNjgxYTMwNzU4OWYxN2ViNTQ2MWY5MjhmZTE=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
ODYzODI2MGZjNDZiZTM3YjY5ZDY2NjJmMjlkNDMwMWQ5MDgwNGY5N2U4NzMw
|
14
|
+
ZTA0ZTY0MGY4OTBlMmY5NTU4ZGFiNWRkNDdjYTVmM2JkZWVjNTFmNjE0MWU3
|
15
|
+
ZTgzZmVlOGJjYWRkNjk2MDMxODA5NWJmODUwYTViMDZjZWRkNzk=
|
@@ -0,0 +1 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/localytics'
|
data/lib/localytics.rb
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'rest_client'
|
2
|
+
require 'json'
|
3
|
+
require 'base64'
|
4
|
+
require_relative 'localytics/profile'
|
5
|
+
require_relative 'localytics/push'
|
6
|
+
|
7
|
+
module Localytics
|
8
|
+
class Error < StandardError
|
9
|
+
include Enumerable
|
10
|
+
attr_accessor :errors
|
11
|
+
|
12
|
+
def initialize message, errors={}
|
13
|
+
super message
|
14
|
+
@errors = errors
|
15
|
+
end
|
16
|
+
|
17
|
+
# Yield [error_code, message] pairs
|
18
|
+
def each
|
19
|
+
@errors.each { |e| yield *e.first }
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
class << self
|
24
|
+
attr_accessor :api_key, :api_secret
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.request(api_base, method, url, api_key=nil, api_secret=nil, params={}, headers={})
|
28
|
+
method = method.to_sym
|
29
|
+
|
30
|
+
url = api_base + url
|
31
|
+
|
32
|
+
unless api_key ||= @api_key
|
33
|
+
raise Error.new('No API key provided')
|
34
|
+
end
|
35
|
+
|
36
|
+
unless api_secret ||= @api_secret
|
37
|
+
raise Error.new('No API secret provided')
|
38
|
+
end
|
39
|
+
|
40
|
+
payload = JSON.generate(params) if method == :post || method == :patch
|
41
|
+
params = nil unless method == :get
|
42
|
+
|
43
|
+
auth = 'Basic ' + Base64.strict_encode64("#{api_key}:#{api_secret}")
|
44
|
+
|
45
|
+
headers = {
|
46
|
+
:params => params,
|
47
|
+
:content_type => 'application/json',
|
48
|
+
:accept => 'application/json',
|
49
|
+
:authorization => auth
|
50
|
+
|
51
|
+
}.merge(headers)
|
52
|
+
|
53
|
+
options = {
|
54
|
+
:headers => headers,
|
55
|
+
:method => method,
|
56
|
+
:url => url,
|
57
|
+
:payload => payload
|
58
|
+
}
|
59
|
+
|
60
|
+
begin
|
61
|
+
response = execute_request(options)
|
62
|
+
return {} if response.code == 204 and method == :delete
|
63
|
+
JSON.parse(response.body, :symbolize_names => true)
|
64
|
+
rescue RestClient::Exception => e
|
65
|
+
handle_errors e
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def self.execute_request(options)
|
72
|
+
RestClient::Request.execute(options)
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.handle_errors exception
|
76
|
+
body = JSON.parse exception.http_body
|
77
|
+
raise Error.new(exception.to_s, body['errors'])
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Localytics
|
2
|
+
class Profile
|
3
|
+
class << self
|
4
|
+
attr_accessor :app_id
|
5
|
+
end
|
6
|
+
|
7
|
+
def self.create(customer_id, params={}, app_id=nil, api_key=nil, api_secret=nil)
|
8
|
+
Localytics.request api_base, :post, url(customer_id, app_id), api_key, api_secret, params
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.update(customer_id, params={}, app_id=nil, api_key=nil, api_secret=nil)
|
12
|
+
Localytics.request api_base, :patch, url(customer_id, app_id), api_key, api_secret, params
|
13
|
+
end
|
14
|
+
|
15
|
+
def self.show(customer_id, app_id=nil, api_key=nil, api_secret=nil)
|
16
|
+
Localytics.request api_base, :get, url(customer_id, app_id), api_key, api_secret
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.delete(customer_id, app_id=nil, api_key=nil, api_secret=nil)
|
20
|
+
Localytics.request api_base, :delete, url(customer_id, app_id), api_key, api_secret
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.profiles(customer_id, api_key=nil, api_secret=nil)
|
24
|
+
Localytics.request api_base, :get, "/customers/#{customer_id}", api_key, api_secret
|
25
|
+
end
|
26
|
+
|
27
|
+
def self.profiles_by_email(customer_email, api_key=nil, api_secret=nil)
|
28
|
+
Localytics.request api_base, :get, "/customers?email=#{customer_email}", api_key, api_secret
|
29
|
+
end
|
30
|
+
|
31
|
+
private
|
32
|
+
|
33
|
+
def self.api_base
|
34
|
+
'https://profile.localytics.com/v1'
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.url(id=nil, app_id=nil)
|
38
|
+
if app_id ||= self.app_id
|
39
|
+
return "/apps/#{app_id}/profiles/#{id}"
|
40
|
+
end
|
41
|
+
|
42
|
+
id ? "/profiles/#{id}" : ''
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require 'securerandom'
|
2
|
+
|
3
|
+
module Localytics
|
4
|
+
class Push
|
5
|
+
|
6
|
+
class << self
|
7
|
+
attr_accessor :app_id
|
8
|
+
end
|
9
|
+
|
10
|
+
# Generic method to send push notifications thru Localytics.
|
11
|
+
# Mandatory parameters:
|
12
|
+
# * :messages an array containing the push messages to send.
|
13
|
+
# * :target_type targeted resource. Available values are:
|
14
|
+
# :customer_id
|
15
|
+
# :broadcast
|
16
|
+
# :profile
|
17
|
+
# :audience_id
|
18
|
+
# Optional attributes are:
|
19
|
+
# * :api_key
|
20
|
+
# * :api_secret
|
21
|
+
# * :headers
|
22
|
+
#
|
23
|
+
# More information on how messages can be built can be found on
|
24
|
+
# http://docs.localytics.com/#Dev/getting-started-trans-push.html
|
25
|
+
def self.push(messages, target_type, app_id=nil, api_key=nil, api_secret=nil, headers={})
|
26
|
+
Localytics.request(
|
27
|
+
api_base(app_id),
|
28
|
+
:post,
|
29
|
+
'',
|
30
|
+
api_key,
|
31
|
+
api_secret,
|
32
|
+
{
|
33
|
+
messages: messages,
|
34
|
+
target_type: target_type,
|
35
|
+
campaign_key: nil,
|
36
|
+
request_id: SecureRandom.uuid
|
37
|
+
},
|
38
|
+
headers
|
39
|
+
)
|
40
|
+
end
|
41
|
+
|
42
|
+
# For :messages options please check the :push method
|
43
|
+
def self.push_to_customers(messages, app_id, api_key=nil, api_secret=nil)
|
44
|
+
push messages, 'customer_id', app_id, api_key, api_secret
|
45
|
+
end
|
46
|
+
|
47
|
+
# For :messages options please check the :push method
|
48
|
+
def self.push_to_all_customers(messages, app_id, api_key=nil, api_secret=nil)
|
49
|
+
push messages, 'broadcast', app_id, api_key, api_secret
|
50
|
+
end
|
51
|
+
|
52
|
+
# For :messages options please check the :push method
|
53
|
+
def self.push_to_profiles(messages, app_id, api_key=nil, api_secret=nil)
|
54
|
+
push messages, 'profile', app_id, api_key, api_secret
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.push_to_audiences(messages, app_id, api_key=nil, api_secret=nil)
|
58
|
+
push messages, 'audience_id', app_id, api_key, api_secret
|
59
|
+
end
|
60
|
+
|
61
|
+
private
|
62
|
+
|
63
|
+
def self.api_base app_id
|
64
|
+
unless app_id ||= self.app_id
|
65
|
+
raise Error.new('No APP id provided')
|
66
|
+
end
|
67
|
+
|
68
|
+
"https://messaging.localytics.com/v2/push/#{app_id}"
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
require File.expand_path('../lib/localytics', File.dirname(__FILE__))
|
2
|
+
require File.expand_path('test_helper', File.dirname(__FILE__))
|
3
|
+
|
4
|
+
require 'cutest'
|
5
|
+
require 'mocha/api'
|
6
|
+
include Mocha::API
|
7
|
+
|
8
|
+
prepare do
|
9
|
+
Localytics.api_key = '1234'
|
10
|
+
Localytics.api_secret = '1234'
|
11
|
+
end
|
12
|
+
|
13
|
+
setup do
|
14
|
+
Localytics.mock_rest_client = mock
|
15
|
+
end
|
16
|
+
|
17
|
+
test 'operation show' do |mock|
|
18
|
+
mock.expects(:get).once.with('https://profile.localytics.com/v1/profiles/123', {}).returns(test_response(test_profile))
|
19
|
+
profile = Localytics::Profile.show 123
|
20
|
+
assert_equal 'Tester', profile[:attributes]['$first_name'.to_sym]
|
21
|
+
end
|
22
|
+
|
23
|
+
test 'operation show in app' do |mock|
|
24
|
+
mock.expects(:get).once.with('https://profile.localytics.com/v1/apps/app_id/profiles/123', {}).returns(test_response(test_profile))
|
25
|
+
profile = Localytics::Profile.show 123, 'app_id'
|
26
|
+
assert_equal 'Tester', profile[:attributes]['$first_name'.to_sym]
|
27
|
+
end
|
28
|
+
|
29
|
+
test 'operation show in app global' do |mock|
|
30
|
+
mock.expects(:get).once.with('https://profile.localytics.com/v1/apps/app_id/profiles/123', {}).returns(test_response(test_profile))
|
31
|
+
Localytics::Profile.app_id = 'app_id'
|
32
|
+
profile = Localytics::Profile.show 123
|
33
|
+
assert_equal 'Tester', profile[:attributes]['$first_name'.to_sym]
|
34
|
+
Localytics::Profile.app_id = nil
|
35
|
+
end
|
36
|
+
|
37
|
+
test 'operation create' do |mock|
|
38
|
+
mock.expects(:post).once.with('https://profile.localytics.com/v1/profiles/1234', anything).returns(test_response(test_profile))
|
39
|
+
profile = Localytics::Profile.create 1234, profile_params
|
40
|
+
assert_equal 'Tester', profile[:attributes]['$first_name'.to_sym]
|
41
|
+
end
|
42
|
+
|
43
|
+
test 'operation update' do |mock|
|
44
|
+
mock.expects(:patch).once.with('https://profile.localytics.com/v1/profiles/1234', anything).returns(test_response(test_profile))
|
45
|
+
profile = Localytics::Profile.update 1234, profile_params
|
46
|
+
assert_equal 'Tester', profile[:attributes]['$first_name'.to_sym]
|
47
|
+
end
|
48
|
+
|
49
|
+
test 'operation delete' do |mock|
|
50
|
+
mock.expects(:delete).once.with('https://profile.localytics.com/v1/profiles/1234').returns(test_response({}, 204))
|
51
|
+
profile = Localytics::Profile.delete 1234
|
52
|
+
assert(profile.empty?)
|
53
|
+
end
|
54
|
+
|
55
|
+
test 'operation profiles' do |mock|
|
56
|
+
mock.expects(:get).once.with('https://profile.localytics.com/v1/customers/Isa', {}).returns(test_response(test_profiles))
|
57
|
+
profiles = Localytics::Profile.profiles 'Isa'
|
58
|
+
assert_equal 'Isa', profiles[:id]
|
59
|
+
assert_equal 'Isa', profiles[:profiles][0][:attributes][:name]
|
60
|
+
end
|
61
|
+
|
62
|
+
test 'operation profiles' do |mock|
|
63
|
+
mock.expects(:get).once.with('https://profile.localytics.com/v1/customers?email=isa@localytics.com', {}).returns(test_response(test_profiles))
|
64
|
+
profiles = Localytics::Profile.profiles_by_email 'isa@localytics.com'
|
65
|
+
assert_equal 'Isa', profiles[:id]
|
66
|
+
assert_equal 'Isa', profiles[:profiles][0][:attributes][:name]
|
67
|
+
end
|
68
|
+
|
69
|
+
test 'send push' do |mock|
|
70
|
+
mock.expects(:post).once.with('https://messaging.localytics.com/v2/push/app_id', anything).returns(test_response({}, 200))
|
71
|
+
Localytics::Push.push_to_customers [{alert: 'message', target: 1}], 'app_id'
|
72
|
+
end
|
73
|
+
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,103 @@
|
|
1
|
+
module Localytics
|
2
|
+
@mock_rest_client = nil
|
3
|
+
|
4
|
+
def self.mock_rest_client=(mock_client)
|
5
|
+
@mock_rest_client = mock_client
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.execute_request(options)
|
9
|
+
case options[:method]
|
10
|
+
when :get
|
11
|
+
@mock_rest_client.get options[:url], options[:headers][:params]
|
12
|
+
when :post
|
13
|
+
@mock_rest_client.post options[:url], options[:payload]
|
14
|
+
when :patch
|
15
|
+
@mock_rest_client.patch options[:url], options[:payload]
|
16
|
+
when :delete
|
17
|
+
@mock_rest_client.delete options[:url]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
Response = Struct.new :body, :code
|
23
|
+
|
24
|
+
def test_response body, code=200
|
25
|
+
Response.new JSON.generate(body), code
|
26
|
+
end
|
27
|
+
|
28
|
+
def test_profile(params={})
|
29
|
+
{
|
30
|
+
attributes: {
|
31
|
+
'$first_name' => 'Tester',
|
32
|
+
'$last_name' => 'Localytics',
|
33
|
+
'$email' => 'tester@localytics.com'
|
34
|
+
},
|
35
|
+
localytics: {
|
36
|
+
attributes: {
|
37
|
+
last_session_date: '2015-08-21',
|
38
|
+
device_timezone: '-03:00',
|
39
|
+
country: 'ar',
|
40
|
+
language: 'es',
|
41
|
+
user_type: 'known'
|
42
|
+
}
|
43
|
+
}
|
44
|
+
}.merge(params)
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_profiles(params={})
|
48
|
+
{
|
49
|
+
'id': 'Isa',
|
50
|
+
'profiles': [
|
51
|
+
{
|
52
|
+
'attributes': {
|
53
|
+
'name': 'Isa',
|
54
|
+
'cats': ['Ofelia', 'Mittens', 'Spot', 'Schrödinger'],
|
55
|
+
'age': 30,
|
56
|
+
'lucky numbers': [1, 48, -100, 13],
|
57
|
+
'birthday': '1983-01-01'
|
58
|
+
},
|
59
|
+
'localytics': {
|
60
|
+
'attributes': {
|
61
|
+
'country': 'us',
|
62
|
+
'city_name': 'Boston',
|
63
|
+
'last_session_date': '2015-01-15'
|
64
|
+
}
|
65
|
+
}
|
66
|
+
},
|
67
|
+
{
|
68
|
+
'app_id': 'my_app',
|
69
|
+
'attributes': {
|
70
|
+
'high score': 30,
|
71
|
+
'favorite teams': ['Red Sox', 'Yankees']
|
72
|
+
},
|
73
|
+
'localytics': {
|
74
|
+
'attributes': {
|
75
|
+
'app_version': '3.1',
|
76
|
+
'push_enabled': 1,
|
77
|
+
'custom_1': 'yes'
|
78
|
+
}
|
79
|
+
}
|
80
|
+
}
|
81
|
+
]
|
82
|
+
|
83
|
+
}.merge(params)
|
84
|
+
end
|
85
|
+
|
86
|
+
def profile_params
|
87
|
+
{
|
88
|
+
attributes: {
|
89
|
+
'$email' => 'test@localytics.com',
|
90
|
+
'$first_name' => 'Tester Sister',
|
91
|
+
'$last_name' => 'Localytics'
|
92
|
+
}
|
93
|
+
}
|
94
|
+
end
|
95
|
+
|
96
|
+
def bad_request
|
97
|
+
json = {
|
98
|
+
'errors' => [{
|
99
|
+
'4051' => 'Bad Request: The request could not be understood by the server due to malformed syntax.'
|
100
|
+
}]
|
101
|
+
}
|
102
|
+
RestClient::Exception.new(test_response(json, 404), 400)
|
103
|
+
end
|
metadata
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: localytics-ruby
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Tobuy development team
|
8
|
+
- Marcos Chicote
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2015-09-02 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: rest-client
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ~>
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '1.7'
|
21
|
+
type: :runtime
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ~>
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '1.7'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: cutest
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - ~>
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '1.2'
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - ~>
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '1.2'
|
42
|
+
- !ruby/object:Gem::Dependency
|
43
|
+
name: mocha
|
44
|
+
requirement: !ruby/object:Gem::Requirement
|
45
|
+
requirements:
|
46
|
+
- - ~>
|
47
|
+
- !ruby/object:Gem::Version
|
48
|
+
version: '1.1'
|
49
|
+
type: :development
|
50
|
+
prerelease: false
|
51
|
+
version_requirements: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ~>
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '1.1'
|
56
|
+
description: API to interact with Localytics\nhttps://localytics.com/
|
57
|
+
email:
|
58
|
+
- support@tob.uy
|
59
|
+
executables: []
|
60
|
+
extensions: []
|
61
|
+
extra_rdoc_files: []
|
62
|
+
files:
|
63
|
+
- lib/localytics-ruby.rb
|
64
|
+
- lib/localytics.rb
|
65
|
+
- lib/localytics/profile.rb
|
66
|
+
- lib/localytics/push.rb
|
67
|
+
- test/localytics_test.rb
|
68
|
+
- test/test_helper.rb
|
69
|
+
homepage: https://tob.uy/
|
70
|
+
licenses:
|
71
|
+
- MIT
|
72
|
+
metadata: {}
|
73
|
+
post_install_message:
|
74
|
+
rdoc_options: []
|
75
|
+
require_paths:
|
76
|
+
- lib
|
77
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
78
|
+
requirements:
|
79
|
+
- - ! '>='
|
80
|
+
- !ruby/object:Gem::Version
|
81
|
+
version: '0'
|
82
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
83
|
+
requirements:
|
84
|
+
- - ! '>='
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: '0'
|
87
|
+
requirements: []
|
88
|
+
rubyforge_project:
|
89
|
+
rubygems_version: 2.4.5
|
90
|
+
signing_key:
|
91
|
+
specification_version: 4
|
92
|
+
summary: Ruby wrapper for Localytics API
|
93
|
+
test_files:
|
94
|
+
- test/localytics_test.rb
|
95
|
+
- test/test_helper.rb
|