natero 1.1.0 → 1.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +40 -0
- data/.ruby-version +1 -0
- data/README.md +75 -30
- data/config/model_properties.yml +100 -0
- data/lib/natero.rb +9 -2
- data/lib/natero/account.rb +21 -96
- data/lib/natero/base.rb +73 -0
- data/lib/natero/event.rb +16 -74
- data/lib/natero/metric.rb +21 -0
- data/lib/natero/request_helper.rb +31 -0
- data/lib/natero/user.rb +25 -0
- data/lib/natero/version.rb +2 -2
- data/natero.gemspec +16 -12
- metadata +116 -12
- data/Gemfile.lock +0 -41
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: ac2cc931c0961781b909cb322c1e8c19fd6f98951293cef9706aa0477425c0e7
|
4
|
+
data.tar.gz: 89e3d128534522fda00d4cff9b336b94018be1e67f13f39e670b42fd37c7678c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f4adfcd34ecceed163b07dadf43cf6b12668d27b0b49eaad6bd46679d417322b49a174e4a0dbb7c11e094e544a8bd5d199b2b0a8760ac0d55090f1b07b6dbcfd
|
7
|
+
data.tar.gz: dd6c995dcec524684e958bbb8937469278217053ae964396fa2bfc9ef8871e0cda2d6bce45fdc0057b9429dcac88954d0e2f47747afed84938537af472b36386
|
data/.gitignore
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
/.config
|
4
|
+
/coverage/
|
5
|
+
/InstalledFiles
|
6
|
+
/pkg/
|
7
|
+
/spec/reports/
|
8
|
+
/spec/examples.txt
|
9
|
+
/test/tmp/
|
10
|
+
/test/version_tmp/
|
11
|
+
/tmp/
|
12
|
+
Gemfile.lock
|
13
|
+
|
14
|
+
## Ignore RubyMine
|
15
|
+
.idea/
|
16
|
+
*.iml
|
17
|
+
|
18
|
+
## Specific to RubyMotion:
|
19
|
+
.dat*
|
20
|
+
.repl_history
|
21
|
+
build/
|
22
|
+
|
23
|
+
## Documentation cache and generated files:
|
24
|
+
/.yardoc/
|
25
|
+
/_yardoc/
|
26
|
+
/doc/
|
27
|
+
/rdoc/
|
28
|
+
|
29
|
+
## Environment normalization:
|
30
|
+
/.bundle/
|
31
|
+
/vendor/bundle
|
32
|
+
/lib/bundler/man/
|
33
|
+
|
34
|
+
# for a library or gem, you might want to ignore these files since the code is
|
35
|
+
# intended to run in multiple environments; otherwise, check them in:
|
36
|
+
# .ruby-version
|
37
|
+
# .ruby-gemset
|
38
|
+
|
39
|
+
# unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
|
40
|
+
.rvmrc
|
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.6.2
|
data/README.md
CHANGED
@@ -1,41 +1,86 @@
|
|
1
|
-
|
1
|
+
[api-docs]: https://apidocs.natero.com/
|
2
|
+
[free-sw]: https://www.fsf.org/licensing/essays/free-sw.html
|
3
|
+
[issues]: https://github.com/bonusly/natero/issues
|
4
|
+
[fork]: http://help.github.com/fork-a-repo/
|
5
|
+
[branch]: http://learn.github.com/p/branching.html
|
6
|
+
[pr]: http://help.github.com/send-pull-requests/
|
2
7
|
|
3
|
-
|
4
|
-
|
5
|
-
TODO: Delete this and the text above, and describe your gem
|
8
|
+
# Natero Gem
|
9
|
+
A Ruby interface for the [Natero Public API][api-docs].
|
6
10
|
|
7
11
|
## Installation
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
```ruby
|
12
|
-
gem 'natero'
|
12
|
+
```Bash
|
13
|
+
gem install natero
|
13
14
|
```
|
14
15
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
16
|
+
## Examples
|
17
|
+
Significant functionality is covered with this gem, but some basic functionality is covered below.
|
18
|
+
If you're interested in learning more, it's probably easiest to explore the specs in `/spec/natero`.
|
19
|
+
|
20
|
+
Set up your keys:
|
21
|
+
```Ruby
|
22
|
+
Natero.configure do |c|
|
23
|
+
c.account_api_key = 'ACCOUNT_API_KEY'
|
24
|
+
c.event_api_key = 'EVENT_API_KEY'
|
25
|
+
c.event_auth_key = 'EVENT_AUTH_KEY'
|
26
|
+
end
|
27
|
+
```
|
24
28
|
|
25
|
-
|
29
|
+
Retrieve all accounts:
|
30
|
+
```Ruby
|
31
|
+
Natero::Account.retrieve_all
|
32
|
+
```
|
26
33
|
|
27
|
-
|
34
|
+
Retrieve a specific account:
|
35
|
+
```Ruby
|
36
|
+
Natero::Account.retrieve('ACCOUNT_ID')
|
37
|
+
```
|
28
38
|
|
29
|
-
|
39
|
+
Modify an account:
|
40
|
+
```Ruby
|
41
|
+
account = Natero::Account.retrieve('ACCOUNT_ID')
|
42
|
+
account.name = 'TEST'
|
43
|
+
|
44
|
+
Natero::Account.modify('ACCOUNT_ID', account)
|
45
|
+
```
|
30
46
|
|
31
|
-
|
47
|
+
Create an event:
|
48
|
+
```Ruby
|
49
|
+
event = { id: 'test', name: 'Testing the API.'}
|
50
|
+
details = 'These details should be associated with the event in Natero'
|
51
|
+
|
52
|
+
Natero::Event.create(event, details)
|
53
|
+
```
|
32
54
|
|
33
55
|
## Contributing
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
56
|
+
In the spirit of [free software][free-sw], **everyone** is encouraged to help
|
57
|
+
improve this project. Here are some ways *you* can contribute:
|
58
|
+
|
59
|
+
* Report bugs.
|
60
|
+
* Suggest new features.
|
61
|
+
* Write or edit documentation.
|
62
|
+
* Write specifications.
|
63
|
+
* Write code (**no patch is too small**: fix typos, add comments, clean up inconsistent whitespace).
|
64
|
+
* Refactor code.
|
65
|
+
* Fix [issues][].
|
66
|
+
|
67
|
+
#### Submitting an issue:
|
68
|
+
We use the [GitHub issue tracker][issues] to track bugs and features. Before
|
69
|
+
submitting a bug report or feature request, check to make sure it hasn't
|
70
|
+
already been submitted. When submitting a bug report, please include a stack
|
71
|
+
trace and any details that may be necessary to reproduce
|
72
|
+
the bug, including your gem version, Ruby version, and operating system.
|
73
|
+
Ideally, a bug report should include a pull request with failing specs.
|
74
|
+
|
75
|
+
#### Submitting a Pull Request
|
76
|
+
1. [Fork the repository.][fork]
|
77
|
+
2. [Create a topic branch.][branch]
|
78
|
+
3. Add specs for your unimplemented feature or bug fix.
|
79
|
+
4. Run `bundle exec rake spec`. If your specs pass, return to step 3.
|
80
|
+
5. Implement your feature or bug fix.
|
81
|
+
6. Run `bundle exec rake spec`. If your specs fail, return to step 5.
|
82
|
+
7. Add documentation for your feature or bug fix.
|
83
|
+
8. Commit and push your changes.
|
84
|
+
9. [Submit a pull request.][pr]
|
85
|
+
|
86
|
+
_(Shamelessly based on the [Twitter Gem](https://github.com/sferik/twitter))_
|
@@ -0,0 +1,100 @@
|
|
1
|
+
---
|
2
|
+
Natero::Base:
|
3
|
+
source: ~
|
4
|
+
properties:
|
5
|
+
|
6
|
+
Natero::Account:
|
7
|
+
source: http://apidocs.natero.com/apidoc.html#Accounts
|
8
|
+
properties:
|
9
|
+
- account_id
|
10
|
+
- name
|
11
|
+
- join_date
|
12
|
+
- renewal_date
|
13
|
+
- billing_account_id
|
14
|
+
- support_account_id
|
15
|
+
- crm_account_id
|
16
|
+
- billing_street
|
17
|
+
- billing_city
|
18
|
+
- billing_postal_code
|
19
|
+
- billing_state
|
20
|
+
- billing_country
|
21
|
+
- phone
|
22
|
+
- employees
|
23
|
+
- industry
|
24
|
+
- tier
|
25
|
+
- csm_score
|
26
|
+
- current_nps_score
|
27
|
+
- sales_rep_name
|
28
|
+
- sales_rep_email
|
29
|
+
- source
|
30
|
+
- stage
|
31
|
+
- is_deleted
|
32
|
+
- is_churned
|
33
|
+
- inactive_time
|
34
|
+
- inactive_reason
|
35
|
+
- parent_account_id
|
36
|
+
- hierarchy_label
|
37
|
+
- is_leaf
|
38
|
+
- latest_status_title
|
39
|
+
- latest_status_details
|
40
|
+
- latest_status_date
|
41
|
+
- assigned_csms
|
42
|
+
- custom_label_dimensions
|
43
|
+
- custom_value_dimensions
|
44
|
+
- custom_event_dimensions
|
45
|
+
- stage_history
|
46
|
+
- nps_history
|
47
|
+
|
48
|
+
Natero::Event:
|
49
|
+
source: http://apidocs.natero.com/restapi.html
|
50
|
+
properties:
|
51
|
+
- account_id
|
52
|
+
- action
|
53
|
+
- active_duration
|
54
|
+
- created_at
|
55
|
+
- details
|
56
|
+
- feature
|
57
|
+
- module
|
58
|
+
- product
|
59
|
+
- session_id
|
60
|
+
- time_spent
|
61
|
+
- total
|
62
|
+
- user_id
|
63
|
+
|
64
|
+
Natero::Metric:
|
65
|
+
source: http://apidocs.natero.com/apidoc.html#Custom%20Metrics
|
66
|
+
properties:
|
67
|
+
- account_id
|
68
|
+
- name
|
69
|
+
- metrics
|
70
|
+
- direction
|
71
|
+
- page
|
72
|
+
|
73
|
+
Natero::User:
|
74
|
+
source: http://apidocs.natero.com/apidoc.html#Accounts%20Product%20Users
|
75
|
+
properties:
|
76
|
+
- user_id
|
77
|
+
- account_id
|
78
|
+
- first_name
|
79
|
+
- last_name
|
80
|
+
- contact_user_id
|
81
|
+
- phone
|
82
|
+
- mobile_phone
|
83
|
+
- email
|
84
|
+
- salutation
|
85
|
+
- title
|
86
|
+
- role
|
87
|
+
- department
|
88
|
+
- source
|
89
|
+
- mailing_street
|
90
|
+
- mailing_city
|
91
|
+
- mailing_state
|
92
|
+
- mailing_postal_code
|
93
|
+
- mailing_country
|
94
|
+
- lead_source
|
95
|
+
- product_join_date
|
96
|
+
- is_active
|
97
|
+
- custom_label_dimensions
|
98
|
+
- custom_value_dimensions
|
99
|
+
- custom_event_dimensions
|
100
|
+
...
|
data/lib/natero.rb
CHANGED
@@ -1,6 +1,5 @@
|
|
1
1
|
require 'httparty'
|
2
2
|
require 'json'
|
3
|
-
require 'pry'
|
4
3
|
|
5
4
|
module Natero
|
6
5
|
class Configuration
|
@@ -41,9 +40,17 @@ module Natero
|
|
41
40
|
def self.to_records_json(objects)
|
42
41
|
"{\"records\": #{Array(objects).map(&:serialize)}}".to_s.delete('\\').gsub('"{', '{').gsub('}"', '}')
|
43
42
|
end
|
43
|
+
|
44
|
+
def self.gem_root
|
45
|
+
File.expand_path('../..', __FILE__)
|
46
|
+
end
|
44
47
|
end
|
45
48
|
|
46
49
|
require_relative 'natero/serializable'
|
50
|
+
require_relative 'natero/request_helper'
|
51
|
+
require_relative 'natero/base'
|
52
|
+
require_relative 'natero/user'
|
47
53
|
require_relative 'natero/account'
|
48
54
|
require_relative 'natero/event'
|
49
|
-
require_relative 'natero/response'
|
55
|
+
require_relative 'natero/response'
|
56
|
+
require_relative 'natero/metric'
|
data/lib/natero/account.rb
CHANGED
@@ -1,144 +1,69 @@
|
|
1
|
-
class Natero::Account
|
2
|
-
include HTTParty
|
3
|
-
include Serializable
|
4
|
-
|
5
|
-
BASE_URI = 'https://api.natero.com'
|
6
|
-
VERSION_URI = '/api/v2'
|
7
|
-
|
8
|
-
attr_reader :account_id, :name, :join_date, :renewal_date,
|
9
|
-
:billing_account_id, :support_account_id, :crm_account_id,
|
10
|
-
:billing_street, :billing_city, :billing_postal_code,
|
11
|
-
:billing_state, :billing_country, :phone, :employees,
|
12
|
-
:industry, :tier, :csm_score, :sales_rep_name, :sales_rep_email,
|
13
|
-
:source, :stage, :is_deleted, :is_churned, :inactive_time, :inactive_reason,
|
14
|
-
:assigned_csms, :custom_label_dimensions, :custom_value_dimensions,
|
15
|
-
:custom_event_dimensions, :stage_history, :nps_history, :raw_response
|
16
|
-
|
17
|
-
# http://apidocs.natero.com/apidoc.html#Accounts_Retrieve%20all%20accounts
|
1
|
+
class Natero::Account < Natero::Base
|
18
2
|
def self.retrieve_all
|
19
|
-
|
3
|
+
get
|
20
4
|
end
|
21
5
|
|
22
|
-
# http://apidocs.natero.com/apidoc.html#Accounts_Retrieve%20an%20account
|
23
6
|
def self.retrieve(id)
|
24
|
-
|
7
|
+
get([id])
|
25
8
|
end
|
26
9
|
|
27
|
-
# http://apidocs.natero.com/apidoc.html#Accounts_Bulk%20insert%2Fmodify%20accounts
|
28
10
|
def self.bulk_insert_modify(accounts)
|
29
|
-
|
30
|
-
Natero::Response.new(post(endpoint, { :body => body, :headers => { 'Content-Type' => 'application/json' } }))
|
11
|
+
post([], json_data(Natero.to_records_json(accounts)))
|
31
12
|
end
|
32
13
|
|
33
|
-
# http://apidocs.natero.com/apidoc.html#Accounts_Modify%20an%20account
|
34
14
|
def self.modify(id, account)
|
35
|
-
|
36
|
-
Natero::Response.new(put(endpoint(id), { :body => body, :headers => { 'Content-Type' => 'application/json'} }))
|
15
|
+
put([id], json_data(account.to_json))
|
37
16
|
end
|
38
17
|
|
39
|
-
# http://apidocs.natero.com/apidoc.html#Accounts_Retrieve%20custom%20metrics
|
40
18
|
def self.retrieve_custom_metrics(id)
|
41
|
-
|
19
|
+
get([id, 'metrics'])
|
42
20
|
end
|
43
21
|
|
44
|
-
# http://apidocs.natero.com/apidoc.html#Accounts_Retrieve%20invoice%20statements
|
45
22
|
def self.retrieve_invoice_statements(id)
|
46
|
-
|
23
|
+
get([id, 'statements'])
|
47
24
|
end
|
48
25
|
|
49
|
-
# http://apidocs.natero.com/apidoc.html#Accounts_Retrieve%20subscription%20history
|
50
26
|
def self.retrieve_subscription_history(id)
|
51
|
-
|
27
|
+
get([id, 'subscriptions'])
|
52
28
|
end
|
53
29
|
|
54
|
-
# http://apidocs.natero.com/apidoc.html#Accounts_Retrieve%20support%20tickets
|
55
30
|
def self.retrieve_support_tickets(id)
|
56
|
-
|
31
|
+
get([id, 'support_tickets'])
|
57
32
|
end
|
58
33
|
|
59
|
-
# http://apidocs.natero.com/apidoc.html#Accounts_Retrieve%20product%20users
|
60
34
|
def self.retrieve_product_users(id)
|
61
|
-
|
35
|
+
get([id, 'users'])
|
62
36
|
end
|
63
37
|
|
64
|
-
# http://apidocs.natero.com/apidoc.html#Accounts_Retrieve%20contacts
|
65
38
|
def self.retrieve_contacts(id)
|
66
|
-
|
39
|
+
get([id, 'contacts'])
|
67
40
|
end
|
68
41
|
|
69
|
-
# http://apidocs.natero.com/apidoc.html#Accounts_Deactivate%20an%20account
|
70
42
|
def self.deactivate_account(id)
|
71
|
-
|
43
|
+
delete([id])
|
72
44
|
end
|
73
45
|
|
74
|
-
# http://apidocs.natero.com/apidoc.html#Accounts_Delete%20stage%20history
|
75
46
|
def self.delete_stage_history(id, name, timestamp)
|
76
|
-
|
47
|
+
delete([id, 'stage_history', name, timestamp])
|
77
48
|
end
|
78
49
|
|
79
|
-
# http://apidocs.natero.com/apidoc.html#Accounts_Delete%20dimension%20values
|
80
50
|
def self.delete_dimension_values(id, key)
|
81
|
-
|
51
|
+
delete([id, 'dimension_values', key])
|
82
52
|
end
|
83
53
|
|
84
|
-
# http://apidocs.natero.com/apidoc.html#Accounts_Delete%20dimension%20labels
|
85
54
|
def self.delete_dimension_labels(id, key)
|
86
|
-
|
55
|
+
delete([id, 'dimension_labels', key])
|
87
56
|
end
|
88
57
|
|
89
|
-
# http://apidocs.natero.com/apidoc.html#Accounts_Delete%20assigned%20csm%20reps
|
90
58
|
def self.delete_assigned_csm_reps(id, email)
|
91
|
-
|
59
|
+
delete([id, 'assigned_csms', email])
|
92
60
|
end
|
93
61
|
|
94
|
-
# http://apidocs.natero.com/apidoc.html#Accounts_Delete%20NPS%20history
|
95
62
|
def self.delete_nps_history(id, timestamp)
|
96
|
-
|
97
|
-
end
|
98
|
-
|
99
|
-
def self.
|
100
|
-
|
101
|
-
Natero.full_endpoint_uri(BASE_URI, VERSION_URI, params)
|
102
|
-
end
|
103
|
-
|
104
|
-
def initialize(params, raw_response = nil)
|
105
|
-
@account_id = params['account_id']
|
106
|
-
@name = params['name']
|
107
|
-
@join_date = params['join_date']
|
108
|
-
@renewal_date = params['renewal_date']
|
109
|
-
@billing_account_id = params['billing_account_id']
|
110
|
-
@support_account_id = params['support_account_id']
|
111
|
-
@crm_account_id = params['crm_account_id']
|
112
|
-
@billing_street = params['billing_street']
|
113
|
-
@billing_city = params['billing_city']
|
114
|
-
@billing_postal_code = params['billing_postal_code']
|
115
|
-
@billing_state = params['billing_state']
|
116
|
-
@billing_country = params['billing_country']
|
117
|
-
@phone = params['phone']
|
118
|
-
@employees = params['employees']
|
119
|
-
@industry = params['industry']
|
120
|
-
@tier = params['tier']
|
121
|
-
@csm_score = params['csm_score']
|
122
|
-
@sales_rep_name = params['sales_rep_name']
|
123
|
-
@sale_rep_email = params['sale_rep_email']
|
124
|
-
@source = params['source']
|
125
|
-
@stage = params['stage']
|
126
|
-
@is_deleted = params['is_deleted']
|
127
|
-
@is_churned = params['is_churned']
|
128
|
-
@inactive_time = params['inactive_time']
|
129
|
-
@inactive_reason = params['inactive_reason']
|
130
|
-
@assigned_csms = params['assigned_csms']
|
131
|
-
# Key/value #
|
132
|
-
@custom_label_dimensions = params['custom_label_dimensions']
|
133
|
-
@custom_value_dimensions = params['custom_value_dimensions']
|
134
|
-
@custom_event_dimensions = params['custom_event_dimensions']
|
135
|
-
#############
|
136
|
-
@stage_history = params['stage_history']
|
137
|
-
@nps_history = params['nps_history']
|
138
|
-
@raw_response = raw_response
|
139
|
-
end
|
140
|
-
|
141
|
-
def to_json
|
142
|
-
serialize
|
63
|
+
delete([id, 'nps_history', timestamp])
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.endpoint_path
|
67
|
+
['accounts']
|
143
68
|
end
|
144
69
|
end
|
data/lib/natero/base.rb
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'active_support'
|
2
|
+
require 'active_support/core_ext'
|
3
|
+
|
4
|
+
class Natero::Base
|
5
|
+
include Serializable
|
6
|
+
|
7
|
+
BASE_URI = 'https://api.natero.com'
|
8
|
+
VERSION_URI = '/api/v2'
|
9
|
+
|
10
|
+
REQUIRED_PARAMS = []
|
11
|
+
|
12
|
+
attr_reader :raw_response
|
13
|
+
|
14
|
+
class << self
|
15
|
+
delegate :get, :post, :put, :delete, to: :request_helper, allow_nil: true
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.endpoint(*params)
|
19
|
+
params = [endpoint_path, params, Natero.api_key_uri].flatten.compact.map(&:to_s)
|
20
|
+
Natero.full_endpoint_uri(BASE_URI, VERSION_URI, params)
|
21
|
+
end
|
22
|
+
|
23
|
+
def self.endpoint_path
|
24
|
+
raise NotImplementedError.new( 'This method needs to be overridden in a child class. Proper implementation '\
|
25
|
+
'should return an array where each index contains a different part of the path. For example: '\
|
26
|
+
'[\'test\', \'best\'] becomes \'/test/best/\'.' )
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.json_data(body)
|
30
|
+
{ body: body, headers: json_headers }
|
31
|
+
end
|
32
|
+
|
33
|
+
def self.json_headers
|
34
|
+
{ 'Content-Type': 'application/json' }
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.request_helper
|
38
|
+
Natero::RequestHelper.new(self)
|
39
|
+
end
|
40
|
+
|
41
|
+
def initialize(params, raw_response = nil)
|
42
|
+
missing_params = REQUIRED_PARAMS - params.keys
|
43
|
+
raise ArgumentError.new("Missing required params #{missing_params.join(', ')}") unless missing_params.empty?
|
44
|
+
|
45
|
+
load_model_properties
|
46
|
+
clean_params(params)
|
47
|
+
populate_properties(params)
|
48
|
+
|
49
|
+
@raw_response = raw_response
|
50
|
+
end
|
51
|
+
|
52
|
+
def to_json
|
53
|
+
serialize
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def load_model_properties
|
59
|
+
model_config[:properties].each { |prop| self.class.class_eval { attr_accessor prop.to_sym } }
|
60
|
+
end
|
61
|
+
|
62
|
+
def clean_params(params)
|
63
|
+
params.each { |_, value| value.gsub!(/"/, '') if value.respond_to?(:gsub!) }
|
64
|
+
end
|
65
|
+
|
66
|
+
def populate_properties(params)
|
67
|
+
params.each { |key, value| instance_variable_set("@#{key}", value) }
|
68
|
+
end
|
69
|
+
|
70
|
+
def model_config
|
71
|
+
YAML::load(File.read("#{Natero.gem_root}/config/model_properties.yml"))[self.class.name.to_s].with_indifferent_access
|
72
|
+
end
|
73
|
+
end
|
data/lib/natero/event.rb
CHANGED
@@ -1,106 +1,48 @@
|
|
1
|
-
class Natero::Event
|
2
|
-
include HTTParty
|
3
|
-
include Serializable
|
4
|
-
|
1
|
+
class Natero::Event < Natero::Base
|
5
2
|
BASE_URI = 'https://events.natero.com'
|
6
3
|
VERSION_URI = '/v1'
|
7
4
|
|
8
|
-
attr_reader :account_id, :user_id, :created_at, :session_id, :raw_response
|
9
|
-
|
10
|
-
##############################################
|
11
|
-
### Documentation for all endpoints ###
|
12
|
-
### http://apidocs.natero.com/restapi.html ###
|
13
|
-
##############################################
|
14
|
-
|
15
5
|
REQUIRED_PARAMS = %w{
|
16
6
|
account_id
|
17
7
|
user_id
|
18
8
|
created_at
|
19
9
|
session_id
|
20
10
|
}
|
21
|
-
|
22
|
-
private_class_method def self.post_event(body)
|
23
|
-
Natero::Response.new(post(endpoint, { :body => body.to_json, :headers => { 'Content-Type' => 'application/json' } }))
|
24
|
-
end
|
25
11
|
|
26
12
|
def self.identify_user(event, details)
|
27
|
-
|
28
|
-
|
29
|
-
body = event.to_h
|
30
|
-
body.merge!({ 'action' => action })
|
31
|
-
body.merge!({ 'details' => details })
|
32
|
-
|
33
|
-
post_event(body)
|
13
|
+
create(event, 'identifyUser', { details: details })
|
34
14
|
end
|
35
15
|
|
36
16
|
def self.identify_account(event, details)
|
37
|
-
|
38
|
-
|
39
|
-
body = event.to_h
|
40
|
-
body.merge!({ 'action' => action })
|
41
|
-
body.merge!({ 'details' => details })
|
42
|
-
|
43
|
-
post_event(body)
|
17
|
+
create(event, 'identifyAccount', { details: details })
|
44
18
|
end
|
45
19
|
|
46
20
|
def self.session_sync(event, active_duration)
|
47
|
-
|
48
|
-
|
49
|
-
body = event.to_h
|
50
|
-
body.merge!({ 'action' => action })
|
51
|
-
body.merge!({ 'active_duration' => active_duration })
|
52
|
-
|
53
|
-
post_event(body)
|
21
|
+
create(event, 'sessionSync', { active_duration: active_duration })
|
54
22
|
end
|
55
23
|
|
56
24
|
def self.module_end(event, module_name, time_spent)
|
57
|
-
|
58
|
-
|
59
|
-
body = event.to_h
|
60
|
-
body.merge!({ 'action' => action })
|
61
|
-
body.merge!({ 'module' => module_name })
|
62
|
-
body.merge!({ 'time_spent' => time_spent })
|
63
|
-
|
64
|
-
post_event(body)
|
25
|
+
create(event, 'moduleEnd', { module: module_name, time_spent: time_spent })
|
65
26
|
end
|
66
27
|
|
67
28
|
def self.feature(event, feature, module_name, total)
|
68
|
-
|
29
|
+
create(event, 'feature', { feature: feature, module: module_name, total: total })
|
30
|
+
end
|
69
31
|
|
32
|
+
def self.create(event, action, optional_fields={})
|
70
33
|
body = event.to_h
|
71
|
-
body.merge!({
|
72
|
-
body.merge!(
|
73
|
-
body.merge!({ 'module' => module_name })
|
74
|
-
body.merge!({ 'total' => total })
|
75
|
-
|
76
|
-
post_event(body)
|
77
|
-
end
|
34
|
+
body.merge!({ action: action })
|
35
|
+
body.merge!(optional_fields)
|
78
36
|
|
79
|
-
|
80
|
-
Natero.full_endpoint_uri(
|
81
|
-
BASE_URI,
|
82
|
-
VERSION_URI,
|
83
|
-
Natero.configuration.event_auth_key,
|
84
|
-
Natero.configuration.event_api_key
|
85
|
-
)
|
37
|
+
post([], json_data(body))
|
86
38
|
end
|
87
39
|
|
88
|
-
def
|
89
|
-
|
90
|
-
|
91
|
-
unless missing.empty?
|
92
|
-
raise ArgumentError.new("Missing required params #{missing.join(', ')}")
|
93
|
-
end
|
94
|
-
|
95
|
-
# Base properties - required
|
96
|
-
@account_id = params['account_id']
|
97
|
-
@user_id = params['user_id']
|
98
|
-
@created_at = params['created_at']
|
99
|
-
@session_id = params['session_id']
|
100
|
-
@raw_response = raw_response
|
40
|
+
def self.endpoint_path
|
41
|
+
[Natero.configuration.event_auth_key, Natero.configuration.event_api_key]
|
101
42
|
end
|
102
43
|
|
103
|
-
def
|
104
|
-
|
44
|
+
def self.endpoint(*params)
|
45
|
+
params = [endpoint_path, params].flatten.compact.map(&:to_s)
|
46
|
+
Natero.full_endpoint_uri(BASE_URI, VERSION_URI, params)
|
105
47
|
end
|
106
48
|
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
class Natero::Metric < Natero::Base
|
2
|
+
def self.retrieve(name)
|
3
|
+
get([name])
|
4
|
+
end
|
5
|
+
|
6
|
+
def self.bulk_insert_modify(metrics)
|
7
|
+
post([], json_data(Natero.to_records_json(metrics)))
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.modify(name, metric)
|
11
|
+
put([name], json_data(metric.to_json))
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.delete(name)
|
15
|
+
request_helper.delete([name])
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.endpoint_path
|
19
|
+
['metrics']
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'httparty'
|
2
|
+
|
3
|
+
class Natero::RequestHelper
|
4
|
+
def get(path_params=[], data={})
|
5
|
+
request(:get, path_params, data)
|
6
|
+
end
|
7
|
+
|
8
|
+
def post(path_params=[], data={})
|
9
|
+
request(:post, path_params, data)
|
10
|
+
end
|
11
|
+
|
12
|
+
def put(path_params=[], data={})
|
13
|
+
request(:put, path_params, data)
|
14
|
+
end
|
15
|
+
|
16
|
+
def delete(path_params=[], data={})
|
17
|
+
request(:delete, path_params, data)
|
18
|
+
end
|
19
|
+
|
20
|
+
def request(method, path_params=[], data={})
|
21
|
+
parse_response(HTTParty.send(method, @model.endpoint(path_params), data))
|
22
|
+
end
|
23
|
+
|
24
|
+
def parse_response(raw_response)
|
25
|
+
Natero::Response.new(raw_response)
|
26
|
+
end
|
27
|
+
|
28
|
+
def initialize(model)
|
29
|
+
@model = model
|
30
|
+
end
|
31
|
+
end
|
data/lib/natero/user.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
class Natero::User < Natero::Base
|
2
|
+
def self.retrieve_all
|
3
|
+
get
|
4
|
+
end
|
5
|
+
|
6
|
+
def self.retrieve(id, account_id=nil)
|
7
|
+
get([id, account_id])
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.bulk_insert_modify(accounts)
|
11
|
+
post([], json_data(Natero.to_records_json(accounts)))
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.modify(id, account)
|
15
|
+
put([id], json_data(account.to_json))
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.deactivate(id, account_id=nil)
|
19
|
+
delete([id, account_id])
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.endpoint_path
|
23
|
+
['account_users']
|
24
|
+
end
|
25
|
+
end
|
data/lib/natero/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
1
|
module Natero
|
2
|
-
VERSION =
|
3
|
-
end
|
2
|
+
VERSION = '1.2.1'
|
3
|
+
end
|
data/natero.gemspec
CHANGED
@@ -2,27 +2,31 @@
|
|
2
2
|
lib = File.expand_path('../lib', __FILE__)
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
4
|
require 'natero/version'
|
5
|
-
require 'pry'
|
6
5
|
|
7
6
|
Gem::Specification.new do |spec|
|
8
7
|
spec.name = 'natero'
|
9
8
|
spec.version = Natero::VERSION
|
10
|
-
spec.authors = 'Andrew Brown'
|
11
|
-
spec.email = '
|
9
|
+
spec.authors = ['Andrew Brown', 'Robert Ingrum']
|
10
|
+
spec.email = 'dev@bonus.ly'
|
12
11
|
spec.summary = 'Wrapper for Natero API'
|
13
|
-
spec.description =
|
14
|
-
Natero is customer success software used to reduce churn and increase B2B SaaS adoption.
|
15
|
-
}
|
12
|
+
spec.description = 'Natero is customer success software used to reduce churn and increase B2B SaaS adoption.'
|
16
13
|
spec.homepage = 'http://bonus.ly'
|
17
14
|
spec.license = 'MIT'
|
18
15
|
|
19
16
|
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
20
17
|
spec.bindir = 'exe'
|
21
18
|
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
22
|
-
spec.require_paths = 'lib'
|
19
|
+
spec.require_paths = ['lib']
|
23
20
|
|
24
|
-
spec.add_dependency
|
25
|
-
spec.add_development_dependency 'bundler',
|
26
|
-
spec.add_development_dependency 'rake',
|
27
|
-
spec.add_development_dependency 'rspec'
|
28
|
-
|
21
|
+
spec.add_dependency 'httparty', '~> 0.13'
|
22
|
+
spec.add_development_dependency 'bundler', '> 1.11'
|
23
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
24
|
+
spec.add_development_dependency 'rspec'
|
25
|
+
spec.add_development_dependency 'rspec-rails'
|
26
|
+
spec.add_development_dependency 'rails-html-sanitizer', '~> 1.0.4'
|
27
|
+
spec.add_development_dependency 'loofah', '>= 2.2.3'
|
28
|
+
spec.add_development_dependency 'nokogiri', '>= 1.10.4'
|
29
|
+
spec.add_development_dependency 'spring'
|
30
|
+
spec.add_development_dependency 'spring-commands-rspec'
|
31
|
+
spec.add_development_dependency 'spring-commands-cucumber'
|
32
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,15 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: natero
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1
|
4
|
+
version: 1.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew Brown
|
8
|
+
- Robert Ingrum
|
8
9
|
autorequire:
|
9
10
|
bindir: exe
|
10
11
|
cert_chain: []
|
11
|
-
date:
|
12
|
+
date: 2019-08-27 00:00:00.000000000 Z
|
12
13
|
dependencies:
|
13
14
|
- !ruby/object:Gem::Dependency
|
14
15
|
name: httparty
|
@@ -28,14 +29,14 @@ dependencies:
|
|
28
29
|
name: bundler
|
29
30
|
requirement: !ruby/object:Gem::Requirement
|
30
31
|
requirements:
|
31
|
-
- - "
|
32
|
+
- - ">"
|
32
33
|
- !ruby/object:Gem::Version
|
33
34
|
version: '1.11'
|
34
35
|
type: :development
|
35
36
|
prerelease: false
|
36
37
|
version_requirements: !ruby/object:Gem::Requirement
|
37
38
|
requirements:
|
38
|
-
- - "
|
39
|
+
- - ">"
|
39
40
|
- !ruby/object:Gem::Version
|
40
41
|
version: '1.11'
|
41
42
|
- !ruby/object:Gem::Dependency
|
@@ -54,39 +55,143 @@ dependencies:
|
|
54
55
|
version: '10.0'
|
55
56
|
- !ruby/object:Gem::Dependency
|
56
57
|
name: rspec
|
58
|
+
requirement: !ruby/object:Gem::Requirement
|
59
|
+
requirements:
|
60
|
+
- - ">="
|
61
|
+
- !ruby/object:Gem::Version
|
62
|
+
version: '0'
|
63
|
+
type: :development
|
64
|
+
prerelease: false
|
65
|
+
version_requirements: !ruby/object:Gem::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
- !ruby/object:Gem::Dependency
|
71
|
+
name: rspec-rails
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
requirements:
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: '0'
|
77
|
+
type: :development
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - ">="
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '0'
|
84
|
+
- !ruby/object:Gem::Dependency
|
85
|
+
name: rails-html-sanitizer
|
57
86
|
requirement: !ruby/object:Gem::Requirement
|
58
87
|
requirements:
|
59
88
|
- - "~>"
|
60
89
|
- !ruby/object:Gem::Version
|
61
|
-
version:
|
90
|
+
version: 1.0.4
|
62
91
|
type: :development
|
63
92
|
prerelease: false
|
64
93
|
version_requirements: !ruby/object:Gem::Requirement
|
65
94
|
requirements:
|
66
95
|
- - "~>"
|
67
96
|
- !ruby/object:Gem::Version
|
68
|
-
version:
|
69
|
-
|
70
|
-
|
71
|
-
|
97
|
+
version: 1.0.4
|
98
|
+
- !ruby/object:Gem::Dependency
|
99
|
+
name: loofah
|
100
|
+
requirement: !ruby/object:Gem::Requirement
|
101
|
+
requirements:
|
102
|
+
- - ">="
|
103
|
+
- !ruby/object:Gem::Version
|
104
|
+
version: 2.2.3
|
105
|
+
type: :development
|
106
|
+
prerelease: false
|
107
|
+
version_requirements: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - ">="
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: 2.2.3
|
112
|
+
- !ruby/object:Gem::Dependency
|
113
|
+
name: nokogiri
|
114
|
+
requirement: !ruby/object:Gem::Requirement
|
115
|
+
requirements:
|
116
|
+
- - ">="
|
117
|
+
- !ruby/object:Gem::Version
|
118
|
+
version: 1.10.4
|
119
|
+
type: :development
|
120
|
+
prerelease: false
|
121
|
+
version_requirements: !ruby/object:Gem::Requirement
|
122
|
+
requirements:
|
123
|
+
- - ">="
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: 1.10.4
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
name: spring
|
128
|
+
requirement: !ruby/object:Gem::Requirement
|
129
|
+
requirements:
|
130
|
+
- - ">="
|
131
|
+
- !ruby/object:Gem::Version
|
132
|
+
version: '0'
|
133
|
+
type: :development
|
134
|
+
prerelease: false
|
135
|
+
version_requirements: !ruby/object:Gem::Requirement
|
136
|
+
requirements:
|
137
|
+
- - ">="
|
138
|
+
- !ruby/object:Gem::Version
|
139
|
+
version: '0'
|
140
|
+
- !ruby/object:Gem::Dependency
|
141
|
+
name: spring-commands-rspec
|
142
|
+
requirement: !ruby/object:Gem::Requirement
|
143
|
+
requirements:
|
144
|
+
- - ">="
|
145
|
+
- !ruby/object:Gem::Version
|
146
|
+
version: '0'
|
147
|
+
type: :development
|
148
|
+
prerelease: false
|
149
|
+
version_requirements: !ruby/object:Gem::Requirement
|
150
|
+
requirements:
|
151
|
+
- - ">="
|
152
|
+
- !ruby/object:Gem::Version
|
153
|
+
version: '0'
|
154
|
+
- !ruby/object:Gem::Dependency
|
155
|
+
name: spring-commands-cucumber
|
156
|
+
requirement: !ruby/object:Gem::Requirement
|
157
|
+
requirements:
|
158
|
+
- - ">="
|
159
|
+
- !ruby/object:Gem::Version
|
160
|
+
version: '0'
|
161
|
+
type: :development
|
162
|
+
prerelease: false
|
163
|
+
version_requirements: !ruby/object:Gem::Requirement
|
164
|
+
requirements:
|
165
|
+
- - ">="
|
166
|
+
- !ruby/object:Gem::Version
|
167
|
+
version: '0'
|
168
|
+
description: Natero is customer success software used to reduce churn and increase
|
169
|
+
B2B SaaS adoption.
|
170
|
+
email: dev@bonus.ly
|
72
171
|
executables: []
|
73
172
|
extensions: []
|
74
173
|
extra_rdoc_files: []
|
75
174
|
files:
|
175
|
+
- ".gitignore"
|
76
176
|
- ".rspec"
|
177
|
+
- ".ruby-version"
|
77
178
|
- CODE_OF_CONDUCT.md
|
78
179
|
- Gemfile
|
79
|
-
- Gemfile.lock
|
80
180
|
- LICENSE.txt
|
81
181
|
- README.md
|
82
182
|
- Rakefile
|
83
183
|
- bin/console
|
84
184
|
- bin/setup
|
185
|
+
- config/model_properties.yml
|
85
186
|
- lib/natero.rb
|
86
187
|
- lib/natero/account.rb
|
188
|
+
- lib/natero/base.rb
|
87
189
|
- lib/natero/event.rb
|
190
|
+
- lib/natero/metric.rb
|
191
|
+
- lib/natero/request_helper.rb
|
88
192
|
- lib/natero/response.rb
|
89
193
|
- lib/natero/serializable.rb
|
194
|
+
- lib/natero/user.rb
|
90
195
|
- lib/natero/version.rb
|
91
196
|
- natero.gemspec
|
92
197
|
homepage: http://bonus.ly
|
@@ -108,8 +213,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
108
213
|
- !ruby/object:Gem::Version
|
109
214
|
version: '0'
|
110
215
|
requirements: []
|
111
|
-
|
112
|
-
rubygems_version: 2.5.1
|
216
|
+
rubygems_version: 3.0.3
|
113
217
|
signing_key:
|
114
218
|
specification_version: 4
|
115
219
|
summary: Wrapper for Natero API
|
data/Gemfile.lock
DELETED
@@ -1,41 +0,0 @@
|
|
1
|
-
PATH
|
2
|
-
remote: .
|
3
|
-
specs:
|
4
|
-
natero (1.0.0)
|
5
|
-
httparty (~> 0.13)
|
6
|
-
|
7
|
-
GEM
|
8
|
-
remote: https://rubygems.org/
|
9
|
-
specs:
|
10
|
-
diff-lcs (1.2.5)
|
11
|
-
httparty (0.13.7)
|
12
|
-
json (~> 1.8)
|
13
|
-
multi_xml (>= 0.5.2)
|
14
|
-
json (1.8.3)
|
15
|
-
multi_xml (0.5.5)
|
16
|
-
rake (10.5.0)
|
17
|
-
rspec (3.4.0)
|
18
|
-
rspec-core (~> 3.4.0)
|
19
|
-
rspec-expectations (~> 3.4.0)
|
20
|
-
rspec-mocks (~> 3.4.0)
|
21
|
-
rspec-core (3.4.4)
|
22
|
-
rspec-support (~> 3.4.0)
|
23
|
-
rspec-expectations (3.4.0)
|
24
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
25
|
-
rspec-support (~> 3.4.0)
|
26
|
-
rspec-mocks (3.4.1)
|
27
|
-
diff-lcs (>= 1.2.0, < 2.0)
|
28
|
-
rspec-support (~> 3.4.0)
|
29
|
-
rspec-support (3.4.1)
|
30
|
-
|
31
|
-
PLATFORMS
|
32
|
-
ruby
|
33
|
-
|
34
|
-
DEPENDENCIES
|
35
|
-
bundler (~> 1.11)
|
36
|
-
natero!
|
37
|
-
rake (~> 10.0)
|
38
|
-
rspec (~> 3.0)
|
39
|
-
|
40
|
-
BUNDLED WITH
|
41
|
-
1.11.2
|