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 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
+
@@ -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