natero 1.1.0 → 1.2.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 +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
|