hubspot-ruby 0.2.1 → 0.3.0
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 +4 -4
- data/hubspot-ruby.gemspec +3 -3
- data/lib/hubspot-ruby.rb +1 -0
- data/lib/hubspot/connection.rb +3 -3
- data/lib/hubspot/contact.rb +9 -4
- data/lib/hubspot/contact_list.rb +3 -1
- data/lib/hubspot/deal.rb +12 -0
- data/lib/hubspot/deal_pipeline.rb +15 -0
- data/lib/hubspot/engagement.rb +44 -1
- data/lib/hubspot/properties.rb +8 -4
- data/lib/hubspot/subscription.rb +29 -0
- data/spec/lib/hubspot/company_properties_spec.rb +10 -2
- data/spec/lib/hubspot/company_spec.rb +3 -3
- data/spec/lib/hubspot/connection_spec.rb +11 -5
- data/spec/lib/hubspot/contact_list_spec.rb +14 -2
- data/spec/lib/hubspot/contact_properties_spec.rb +10 -2
- data/spec/lib/hubspot/contact_spec.rb +25 -0
- data/spec/lib/hubspot/deal_properties_spec.rb +10 -2
- data/spec/lib/hubspot/engagement_spec.rb +89 -45
- data/spec/live/deal_pipeline_spec.rb +35 -0
- metadata +9 -8
- data/Gemfile.lock +0 -99
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA1:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 1ab6604b85e4945f699f88491ad18191a9ceda03
|
|
4
|
+
data.tar.gz: 8b01545c2f8c6d5e51d610233abcd55b2d9027d0
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a5b5d2e3c28f811c44b14e232e308cc2af19cf4050f6963dfa00ce7c0b59022c73fde892adf9e7fe0a5a73cb6d067b512cefdae13510b06164dd0630e4430b63
|
|
7
|
+
data.tar.gz: 3381873ef4e85c46cbf4a17608c66c29414fa40fdf911fb7463a58be117f7a307b06905d3db269f5a56f8d98b68f70f4ed632a6816a7c8d6ffb6801af7770281
|
data/hubspot-ruby.gemspec
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
Gem::Specification.new do |s|
|
|
2
2
|
s.name = "hubspot-ruby"
|
|
3
|
-
s.version = "0.
|
|
3
|
+
s.version = "0.3.0"
|
|
4
4
|
s.require_paths = ["lib"]
|
|
5
5
|
s.authors = ["Andrew DiMichele"]
|
|
6
6
|
s.description = "hubspot-ruby is a wrapper for the HubSpot REST API"
|
|
7
|
-
s.files = [".rspec", "Gemfile", "
|
|
7
|
+
s.files = [".rspec", "Gemfile", "Guardfile", "LICENSE.txt", "README.md", "RELEASING.md", "Rakefile", "hubspot-ruby.gemspec"]
|
|
8
8
|
s.files += Dir["lib/**/*.rb"]
|
|
9
9
|
s.files += Dir["lib/**/*.rake"]
|
|
10
10
|
s.files += Dir["spec/**/*.rb"]
|
|
@@ -17,7 +17,7 @@ Gem::Specification.new do |s|
|
|
|
17
17
|
|
|
18
18
|
# Add development-only dependencies here
|
|
19
19
|
s.add_development_dependency("rake")
|
|
20
|
-
s.add_development_dependency("rspec")
|
|
20
|
+
s.add_development_dependency("rspec", "~> 2.0")
|
|
21
21
|
s.add_development_dependency("rr")
|
|
22
22
|
s.add_development_dependency("webmock", "< 1.10")
|
|
23
23
|
s.add_development_dependency("vcr")
|
data/lib/hubspot-ruby.rb
CHANGED
data/lib/hubspot/connection.rb
CHANGED
|
@@ -58,7 +58,7 @@ module Hubspot
|
|
|
58
58
|
|
|
59
59
|
params.each do |k,v|
|
|
60
60
|
if path.match(":#{k}")
|
|
61
|
-
path.gsub!(":#{k}",v.to_s)
|
|
61
|
+
path.gsub!(":#{k}", CGI.escape(v.to_s))
|
|
62
62
|
params.delete(k)
|
|
63
63
|
end
|
|
64
64
|
end
|
|
@@ -68,13 +68,13 @@ module Hubspot
|
|
|
68
68
|
v.is_a?(Array) ? v.map { |value| param_string(k,value) } : param_string(k,v)
|
|
69
69
|
end.join("&")
|
|
70
70
|
|
|
71
|
-
|
|
71
|
+
path += path.include?('?') ? '&' : "?" if query.present?
|
|
72
72
|
base_url + path + query
|
|
73
73
|
end
|
|
74
74
|
|
|
75
75
|
# convert into milliseconds since epoch
|
|
76
76
|
def converted_value(value)
|
|
77
|
-
value.is_a?(Time) ? (value.to_i * 1000) : value
|
|
77
|
+
value.is_a?(Time) ? (value.to_i * 1000) : CGI.escape(value.to_s)
|
|
78
78
|
end
|
|
79
79
|
|
|
80
80
|
def param_string(key,value)
|
data/lib/hubspot/contact.rb
CHANGED
|
@@ -17,14 +17,15 @@ module Hubspot
|
|
|
17
17
|
UPDATE_CONTACT_PATH = '/contacts/v1/contact/vid/:contact_id/profile'
|
|
18
18
|
DESTROY_CONTACT_PATH = '/contacts/v1/contact/vid/:contact_id'
|
|
19
19
|
CONTACTS_PATH = '/contacts/v1/lists/all/contacts/all'
|
|
20
|
-
|
|
20
|
+
RECENTLY_UPDATED_PATH = '/contacts/v1/lists/recently_updated/contacts/recent'
|
|
21
21
|
CREATE_OR_UPDATE_PATH = '/contacts/v1/contact/createOrUpdate/email/:contact_email'
|
|
22
22
|
QUERY_PATH = '/contacts/v1/search/query'
|
|
23
23
|
|
|
24
24
|
class << self
|
|
25
25
|
# {https://developers.hubspot.com/docs/methods/contacts/create_contact}
|
|
26
26
|
def create!(email, params={})
|
|
27
|
-
params_with_email = params.stringify_keys
|
|
27
|
+
params_with_email = params.stringify_keys
|
|
28
|
+
params_with_email = params.stringify_keys.merge('email' => email) if email
|
|
28
29
|
post_data = {properties: Hubspot::Utils.hash_to_properties(params_with_email)}
|
|
29
30
|
response = Hubspot::Connection.post_json(CREATE_CONTACT_PATH, params: {}, body: post_data )
|
|
30
31
|
new(response)
|
|
@@ -34,15 +35,17 @@ module Hubspot
|
|
|
34
35
|
# {https://developers.hubspot.com/docs/methods/contacts/get_recently_updated_contacts}
|
|
35
36
|
def all(opts={})
|
|
36
37
|
recent = opts.delete(:recent) { false }
|
|
38
|
+
paged = opts.delete(:paged) { false }
|
|
37
39
|
path, opts =
|
|
38
40
|
if recent
|
|
39
|
-
[
|
|
41
|
+
[RECENTLY_UPDATED_PATH, Hubspot::ContactProperties.add_default_parameters(opts)]
|
|
40
42
|
else
|
|
41
43
|
[CONTACTS_PATH, opts]
|
|
42
44
|
end
|
|
43
45
|
|
|
44
46
|
response = Hubspot::Connection.get_json(path, opts)
|
|
45
|
-
response['contacts'].map { |c| new(c) }
|
|
47
|
+
response['contacts'].map! { |c| new(c) }
|
|
48
|
+
paged ? response : response['contacts']
|
|
46
49
|
end
|
|
47
50
|
|
|
48
51
|
# TODO: create or update a contact
|
|
@@ -141,10 +144,12 @@ module Hubspot
|
|
|
141
144
|
end
|
|
142
145
|
|
|
143
146
|
attr_reader :properties, :vid, :is_new
|
|
147
|
+
attr_reader :is_contact
|
|
144
148
|
|
|
145
149
|
def initialize(response_hash)
|
|
146
150
|
props = response_hash['properties']
|
|
147
151
|
@properties = Hubspot::Utils.properties_to_hash(props) unless props.blank?
|
|
152
|
+
@is_contact = response_hash["is-contact"]
|
|
148
153
|
@vid = response_hash['vid']
|
|
149
154
|
end
|
|
150
155
|
|
data/lib/hubspot/contact_list.rb
CHANGED
|
@@ -78,13 +78,15 @@ module Hubspot
|
|
|
78
78
|
# NOTE: caching functionality can be dependant of the nature of the list, if dynamic or not ...
|
|
79
79
|
bypass_cache = opts.delete(:bypass_cache) { false }
|
|
80
80
|
recent = opts.delete(:recent) { false }
|
|
81
|
+
paged = opts.delete(:paged) { false }
|
|
81
82
|
|
|
82
83
|
if bypass_cache || @contacts.nil?
|
|
83
84
|
path = recent ? RECENT_CONTACTS_PATH : CONTACTS_PATH
|
|
84
85
|
opts[:list_id] = @id
|
|
85
86
|
|
|
86
87
|
response = Hubspot::Connection.get_json(path, Hubspot::ContactProperties.add_default_parameters(opts))
|
|
87
|
-
@contacts = response['contacts'].map { |c| Hubspot::Contact.new(c) }
|
|
88
|
+
@contacts = response['contacts'].map! { |c| Hubspot::Contact.new(c) }
|
|
89
|
+
paged ? response : @contacts
|
|
88
90
|
else
|
|
89
91
|
@contacts
|
|
90
92
|
end
|
data/lib/hubspot/deal.rb
CHANGED
|
@@ -12,6 +12,7 @@ module Hubspot
|
|
|
12
12
|
RECENT_UPDATED_PATH = "/deals/v1/deal/recent/modified"
|
|
13
13
|
UPDATE_DEAL_PATH = '/deals/v1/deal/:deal_id'
|
|
14
14
|
ASSOCIATE_DEAL_PATH = '/deals/v1/deal/:deal_id/associations/:OBJECTTYPE?id=:objectId'
|
|
15
|
+
ASSOCIATED_DEAL_PATH = "/deals/v1/deal/associated/:objectType/:objectId"
|
|
15
16
|
|
|
16
17
|
attr_reader :properties
|
|
17
18
|
attr_reader :portal_id
|
|
@@ -61,6 +62,17 @@ module Hubspot
|
|
|
61
62
|
response = Hubspot::Connection.get_json(RECENT_UPDATED_PATH, opts)
|
|
62
63
|
response['results'].map { |d| new(d) }
|
|
63
64
|
end
|
|
65
|
+
|
|
66
|
+
# Find all deals associated to a company
|
|
67
|
+
# {http://developers.hubspot.com/docs/methods/deals/get-associated-deals}
|
|
68
|
+
# @param company [Hubspot::Company] the company
|
|
69
|
+
# @return [Array] Array of Hubspot::Deal records
|
|
70
|
+
def find_by_company(company)
|
|
71
|
+
path = ASSOCIATED_DEAL_PATH
|
|
72
|
+
params = { objectType: :company, objectId: company.vid }
|
|
73
|
+
response = Hubspot::Connection.get_json(path, params)
|
|
74
|
+
response["results"].map { |deal_id| find(deal_id) }
|
|
75
|
+
end
|
|
64
76
|
|
|
65
77
|
end
|
|
66
78
|
|
|
@@ -34,6 +34,21 @@ module Hubspot
|
|
|
34
34
|
response = Hubspot::Connection.get_json(PIPELINES_PATH, {})
|
|
35
35
|
response.map { |p| new(p) }
|
|
36
36
|
end
|
|
37
|
+
|
|
38
|
+
# Creates a DealPipeline
|
|
39
|
+
# {https://developers.hubspot.com/docs/methods/deal-pipelines/create-deal-pipeline}
|
|
40
|
+
# @return [Hubspot::PipeLine] Company record
|
|
41
|
+
def create!(post_data={})
|
|
42
|
+
response = Hubspot::Connection.post_json(PIPELINES_PATH, params: {}, body: post_data)
|
|
43
|
+
new(response)
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
# Destroys deal_pipeline
|
|
48
|
+
# {http://developers.hubspot.com/docs/methods/companies/delete_company}
|
|
49
|
+
# @return [TrueClass] true
|
|
50
|
+
def destroy!
|
|
51
|
+
Hubspot::Connection.delete_json(PIPELINE_PATH, pipeline_id: @pipeline_id)
|
|
37
52
|
end
|
|
38
53
|
|
|
39
54
|
def [](stage)
|
data/lib/hubspot/engagement.rb
CHANGED
|
@@ -33,7 +33,7 @@ module Hubspot
|
|
|
33
33
|
def find(engagement_id)
|
|
34
34
|
begin
|
|
35
35
|
response = Hubspot::Connection.get_json(ENGAGEMENT_PATH, { engagement_id: engagement_id })
|
|
36
|
-
new(HashWithIndifferentAccess.new(response))
|
|
36
|
+
response ? new(HashWithIndifferentAccess.new(response)) : nil
|
|
37
37
|
rescue Hubspot::RequestError => ex
|
|
38
38
|
if ex.response.code == 404
|
|
39
39
|
return nil
|
|
@@ -130,4 +130,47 @@ module Hubspot
|
|
|
130
130
|
end
|
|
131
131
|
end
|
|
132
132
|
end
|
|
133
|
+
|
|
134
|
+
class EngagementCall < Engagement
|
|
135
|
+
def body
|
|
136
|
+
metadata['body']
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def contact_ids
|
|
140
|
+
associations['contactIds']
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
def company_ids
|
|
144
|
+
associations['companyIds']
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
def deal_ids
|
|
148
|
+
associations['dealIds']
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
class << self
|
|
152
|
+
def create!(contact_vid, body, duration, owner_id = nil, deal_id = nil, status = 'COMPLETED', time = nil)
|
|
153
|
+
data = {
|
|
154
|
+
engagement: {
|
|
155
|
+
type: 'CALL'
|
|
156
|
+
},
|
|
157
|
+
associations: {
|
|
158
|
+
contactIds: [contact_vid],
|
|
159
|
+
dealIds: [deal_id],
|
|
160
|
+
ownerIds: [owner_id]
|
|
161
|
+
},
|
|
162
|
+
metadata: {
|
|
163
|
+
body: body,
|
|
164
|
+
status: status,
|
|
165
|
+
durationMilliseconds: duration
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
data[:engagement][:timestamp] = (time.to_i) * 1000 if time
|
|
170
|
+
data[:engagement][:owner_id] = owner_id if owner_id
|
|
171
|
+
|
|
172
|
+
super(data)
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
end
|
|
133
176
|
end
|
data/lib/hubspot/properties.rb
CHANGED
|
@@ -3,18 +3,22 @@ module Hubspot
|
|
|
3
3
|
|
|
4
4
|
PROPERTY_SPECS = {
|
|
5
5
|
group_field_names: %w(name displayName displayOrder properties),
|
|
6
|
-
field_names: %w(name groupName description fieldType formField type displayOrder label options),
|
|
7
|
-
valid_field_types: %w(textarea select text date file number radio checkbox),
|
|
6
|
+
field_names: %w(name groupName description fieldType formField type displayOrder label options showCurrencySymbol),
|
|
7
|
+
valid_field_types: %w(textarea select text date file number radio checkbox booleancheckbox),
|
|
8
8
|
valid_types: %w(string number bool datetime enumeration),
|
|
9
9
|
options: %w(description value label hidden displayOrder)
|
|
10
10
|
}
|
|
11
|
+
DEFAULT_PROPERTY = 'email'
|
|
11
12
|
|
|
12
13
|
class << self
|
|
13
14
|
# TODO: properties can be set as configuration
|
|
14
15
|
# TODO: find the way how to set a list of Properties + merge same property key if present from opts
|
|
15
16
|
def add_default_parameters(opts={})
|
|
16
|
-
|
|
17
|
-
|
|
17
|
+
if opts.keys.map(&:to_s).include? 'property'
|
|
18
|
+
opts
|
|
19
|
+
else
|
|
20
|
+
opts.merge(property: DEFAULT_PROPERTY)
|
|
21
|
+
end
|
|
18
22
|
end
|
|
19
23
|
|
|
20
24
|
def all(path, opts={}, filter={})
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
module Hubspot
|
|
2
|
+
class Subscription
|
|
3
|
+
SUBSCRIPTIONS_PATH = '/email/public/v1/subscriptions'
|
|
4
|
+
TIMELINE_PATH = '/email/public/v1/subscriptions/timeline'
|
|
5
|
+
SUBSCRIPTION_PATH = '/email/public/v1/subscriptions/:email_address'
|
|
6
|
+
|
|
7
|
+
attr_reader :subscribed
|
|
8
|
+
attr_reader :marked_as_spam
|
|
9
|
+
attr_reader :bounced
|
|
10
|
+
attr_reader :status
|
|
11
|
+
attr_reader :subscription_statuses
|
|
12
|
+
|
|
13
|
+
def initialize(response_hash)
|
|
14
|
+
@subscribed = response_hash['subscribed']
|
|
15
|
+
@marked_as_spam = response_hash['markedAsSpam']
|
|
16
|
+
@bounced = response_hash['bounced']
|
|
17
|
+
@status = response_hash['status']
|
|
18
|
+
@subscription_statuses = response_hash['SubscriptionStatuses']
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
class << self
|
|
22
|
+
def status(email)
|
|
23
|
+
response = Hubspot::Connection.get_json(SUBSCRIPTION_PATH, {email_address: email})
|
|
24
|
+
new(response)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
describe Hubspot::CompanyProperties do
|
|
2
2
|
describe '.add_default_parameters' do
|
|
3
|
-
|
|
3
|
+
let(:opts) { {} }
|
|
4
|
+
subject { Hubspot::CompanyProperties.add_default_parameters(opts) }
|
|
4
5
|
context 'default parameters' do
|
|
5
|
-
|
|
6
|
+
context 'without property parameter' do
|
|
7
|
+
its([:property]) { should == 'email' }
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
context 'with property parameter' do
|
|
11
|
+
let(:opts) { {property: 'name' } }
|
|
12
|
+
its([:property]) { should == 'name'}
|
|
13
|
+
end
|
|
6
14
|
end
|
|
7
15
|
end
|
|
8
16
|
|
|
@@ -108,15 +108,15 @@ describe Hubspot::Contact do
|
|
|
108
108
|
cassette 'find_all_recent_companies'
|
|
109
109
|
|
|
110
110
|
it 'must get the companies list' do
|
|
111
|
-
companies = Hubspot::Company.all(
|
|
111
|
+
companies = Hubspot::Company.all(recently_updated: true)
|
|
112
112
|
expect(companies.size).to eql 20
|
|
113
113
|
|
|
114
114
|
first, last = companies.first, companies.last
|
|
115
115
|
expect(first).to be_a Hubspot::Company
|
|
116
|
-
expect(first.vid).to eql
|
|
116
|
+
expect(first.vid).to eql 318615742
|
|
117
117
|
|
|
118
118
|
expect(last).to be_a Hubspot::Company
|
|
119
|
-
expect(last.vid).to eql
|
|
119
|
+
expect(last.vid).to eql 359899290
|
|
120
120
|
end
|
|
121
121
|
end
|
|
122
122
|
end
|
|
@@ -76,30 +76,36 @@ describe Hubspot::Connection do
|
|
|
76
76
|
|
|
77
77
|
context "with an interpolated param" do
|
|
78
78
|
let(:params){ {email: "email@address.com"} }
|
|
79
|
-
it{ should == "https://api.hubapi.com/test/email
|
|
79
|
+
it{ should == "https://api.hubapi.com/test/email%40address.com/profile?hapikey=demo" }
|
|
80
80
|
end
|
|
81
81
|
|
|
82
82
|
context "with multiple interpolated params" do
|
|
83
83
|
let(:path){ "/test/:email/:id/profile" }
|
|
84
84
|
let(:params){{email: "email@address.com", id: 1234}}
|
|
85
|
-
it{ should == "https://api.hubapi.com/test/email
|
|
85
|
+
it{ should == "https://api.hubapi.com/test/email%40address.com/1234/profile?hapikey=demo" }
|
|
86
86
|
end
|
|
87
87
|
|
|
88
88
|
context "with query params" do
|
|
89
89
|
let(:params){{email: "email@address.com", id: 1234}}
|
|
90
|
-
it{ should == "https://api.hubapi.com/test/email
|
|
90
|
+
it{ should == "https://api.hubapi.com/test/email%40address.com/profile?id=1234&hapikey=demo" }
|
|
91
91
|
|
|
92
92
|
context "containing a time" do
|
|
93
93
|
let(:start_time) { Time.now }
|
|
94
94
|
let(:params){{email: "email@address.com", id: 1234, start: start_time}}
|
|
95
|
-
it{ should == "https://api.hubapi.com/test/email
|
|
95
|
+
it{ should == "https://api.hubapi.com/test/email%40address.com/profile?id=1234&start=#{start_time.to_i * 1000}&hapikey=demo" }
|
|
96
96
|
end
|
|
97
97
|
|
|
98
98
|
context "containing a range" do
|
|
99
99
|
let(:start_time) { Time.now }
|
|
100
100
|
let(:end_time) { Time.now + 1.year }
|
|
101
101
|
let(:params){{email: "email@address.com", id: 1234, created__range: start_time..end_time }}
|
|
102
|
-
it{ should == "https://api.hubapi.com/test/email
|
|
102
|
+
it{ should == "https://api.hubapi.com/test/email%40address.com/profile?id=1234&created__range=#{start_time.to_i * 1000}&created__range=#{end_time.to_i * 1000}&hapikey=demo" }
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
context "containing an array of strings" do
|
|
106
|
+
let(:path){ "/test/emails" }
|
|
107
|
+
let(:params){{batch_email: %w(email1@example.com email2@example.com)}}
|
|
108
|
+
it{ should == "https://api.hubapi.com/test/emails?email=email1%40example.com&email=email2%40example.com&hapikey=demo" }
|
|
103
109
|
end
|
|
104
110
|
end
|
|
105
111
|
|
|
@@ -32,12 +32,24 @@ describe Hubspot::ContactList do
|
|
|
32
32
|
|
|
33
33
|
let(:list) { Hubspot::ContactList.new(example_contact_list_hash) }
|
|
34
34
|
|
|
35
|
-
it 'returns by
|
|
35
|
+
it 'returns by default 20 contact lists' do
|
|
36
36
|
expect(list.contacts.count).to eql 20
|
|
37
37
|
contact = list.contacts.first
|
|
38
38
|
expect(contact).to be_a(Hubspot::Contact)
|
|
39
39
|
end
|
|
40
40
|
|
|
41
|
+
it 'returns by default 20 contact lists with paging data' do
|
|
42
|
+
contact_data = list.contacts({paged: true})
|
|
43
|
+
contacts = contact_data['contacts']
|
|
44
|
+
|
|
45
|
+
expect(contact_data).to have_key 'vid-offset'
|
|
46
|
+
expect(contact_data).to have_key 'has-more'
|
|
47
|
+
|
|
48
|
+
expect(contacts.count).to eql 20
|
|
49
|
+
contact = contacts.first
|
|
50
|
+
expect(contact).to be_a(Hubspot::Contact)
|
|
51
|
+
end
|
|
52
|
+
|
|
41
53
|
it 'add default properties to the contacts returned' do
|
|
42
54
|
contact = list.contacts.first
|
|
43
55
|
expect(contact.email).to_not be_empty
|
|
@@ -86,7 +98,7 @@ describe Hubspot::ContactList do
|
|
|
86
98
|
context 'all list types' do
|
|
87
99
|
cassette 'find_all_lists'
|
|
88
100
|
|
|
89
|
-
it 'returns by
|
|
101
|
+
it 'returns by default 20 contact lists' do
|
|
90
102
|
lists = Hubspot::ContactList.all
|
|
91
103
|
expect(lists.count).to eql 20
|
|
92
104
|
|
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
describe Hubspot::ContactProperties do
|
|
2
2
|
describe '.add_default_parameters' do
|
|
3
|
-
|
|
3
|
+
let(:opts) { {} }
|
|
4
|
+
subject { Hubspot::ContactProperties.add_default_parameters(opts) }
|
|
4
5
|
context 'default parameters' do
|
|
5
|
-
|
|
6
|
+
context 'without property parameter' do
|
|
7
|
+
its([:property]) { should == 'email' }
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
context 'with property parameter' do
|
|
11
|
+
let(:opts) { {property: 'firstname' } }
|
|
12
|
+
its([:property]) { should == 'firstname'}
|
|
13
|
+
end
|
|
6
14
|
end
|
|
7
15
|
end
|
|
8
16
|
|
|
@@ -261,6 +261,31 @@ describe Hubspot::Contact do
|
|
|
261
261
|
expect(last['lastname']).to eql 'Morgan'
|
|
262
262
|
end
|
|
263
263
|
|
|
264
|
+
it 'must get the contacts list with paging data' do
|
|
265
|
+
contact_data = Hubspot::Contact.all({paged: true})
|
|
266
|
+
contacts = contact_data['contacts']
|
|
267
|
+
|
|
268
|
+
expect(contacts.size).to eql 20 # default page size
|
|
269
|
+
|
|
270
|
+
first = contacts.first
|
|
271
|
+
last = contacts.last
|
|
272
|
+
|
|
273
|
+
expect(contact_data).to have_key 'vid-offset'
|
|
274
|
+
expect(contact_data).to have_key 'has-more'
|
|
275
|
+
|
|
276
|
+
expect(first).to be_a Hubspot::Contact
|
|
277
|
+
expect(first.vid).to eql 154835
|
|
278
|
+
expect(first['firstname']).to eql 'HubSpot'
|
|
279
|
+
expect(first['lastname']).to eql 'Test'
|
|
280
|
+
|
|
281
|
+
expect(last).to be_a Hubspot::Contact
|
|
282
|
+
expect(last.vid).to eql 196199
|
|
283
|
+
expect(last['firstname']).to eql 'Eleanor'
|
|
284
|
+
expect(last['lastname']).to eql 'Morgan'
|
|
285
|
+
expect(contact_data['has-more']).to eql true
|
|
286
|
+
expect(contact_data['vid-offset']).to eql 196199
|
|
287
|
+
end
|
|
288
|
+
|
|
264
289
|
it 'must filter only 2 contacts' do
|
|
265
290
|
contacts = Hubspot::Contact.all(count: 2)
|
|
266
291
|
expect(contacts.size).to eql 2
|
|
@@ -1,8 +1,16 @@
|
|
|
1
1
|
describe Hubspot::DealProperties do
|
|
2
2
|
describe '.add_default_parameters' do
|
|
3
|
-
|
|
3
|
+
let(:opts) { {} }
|
|
4
|
+
subject { Hubspot::DealProperties.add_default_parameters(opts) }
|
|
4
5
|
context 'default parameters' do
|
|
5
|
-
|
|
6
|
+
context 'without property parameter' do
|
|
7
|
+
its([:property]) { should == 'email' }
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
context 'with property parameter' do
|
|
11
|
+
let(:opts) { {property: 'dealname' } }
|
|
12
|
+
its([:property]) { should == 'dealname'}
|
|
13
|
+
end
|
|
6
14
|
end
|
|
7
15
|
end
|
|
8
16
|
|
|
@@ -19,69 +19,113 @@ describe Hubspot::Engagement do
|
|
|
19
19
|
its (:id) { should == 51484873 }
|
|
20
20
|
end
|
|
21
21
|
|
|
22
|
-
describe
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
22
|
+
describe 'EngagementNote' do
|
|
23
|
+
describe ".create!" do
|
|
24
|
+
cassette "engagement_create"
|
|
25
|
+
body = "Test note"
|
|
26
|
+
subject { Hubspot::EngagementNote.create!(nil, body) }
|
|
27
|
+
its(:id) { should_not be_nil }
|
|
28
|
+
its(:body) { should eql body }
|
|
29
|
+
end
|
|
29
30
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
31
|
+
describe ".find" do
|
|
32
|
+
cassette "engagement_find"
|
|
33
|
+
let(:engagement) {Hubspot::EngagementNote.new(example_engagement_hash)}
|
|
33
34
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
35
|
+
it 'must find by the engagement id' do
|
|
36
|
+
find_engagement = Hubspot::EngagementNote.find(engagement.id)
|
|
37
|
+
find_engagement.id.should eql engagement.id
|
|
38
|
+
find_engagement.body.should eql engagement.body
|
|
39
|
+
end
|
|
38
40
|
end
|
|
39
|
-
end
|
|
40
41
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
42
|
+
describe ".find_by_company" do
|
|
43
|
+
cassette "engagement_find_by_country"
|
|
44
|
+
let(:engagement) {Hubspot::EngagementNote.new(example_associated_engagement_hash)}
|
|
44
45
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
46
|
+
it 'must find by company id' do
|
|
47
|
+
find_engagements = Hubspot::EngagementNote.find_by_company(engagement.associations["companyIds"].first)
|
|
48
|
+
find_engagements.should_not be_nil
|
|
49
|
+
find_engagements.any?{|engagement| engagement.id == engagement.id and engagement.body == engagement.body}.should be_true
|
|
50
|
+
end
|
|
49
51
|
end
|
|
50
|
-
end
|
|
51
52
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
53
|
+
describe ".find_by_contact" do
|
|
54
|
+
cassette "engagement_find_by_contact"
|
|
55
|
+
let(:engagement) {Hubspot::EngagementNote.new(example_associated_engagement_hash)}
|
|
55
56
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
57
|
+
it 'must find by contact id' do
|
|
58
|
+
find_engagements = Hubspot::EngagementNote.find_by_contact(engagement.associations["contactIds"].first)
|
|
59
|
+
find_engagements.should_not be_nil
|
|
60
|
+
find_engagements.any?{|engagement| engagement.id == engagement.id and engagement.body == engagement.body}.should be_true
|
|
61
|
+
end
|
|
60
62
|
end
|
|
61
|
-
end
|
|
62
63
|
|
|
63
|
-
|
|
64
|
-
|
|
64
|
+
describe ".find_by_association" do
|
|
65
|
+
cassette "engagement_find_by_association"
|
|
66
|
+
|
|
67
|
+
it 'must raise for fake association type' do
|
|
68
|
+
expect {
|
|
69
|
+
Hubspot::EngagementNote.find_by_association(1, 'FAKE_TYPE')
|
|
70
|
+
}.to raise_error
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
describe '#destroy!' do
|
|
75
|
+
cassette 'engagement_destroy'
|
|
76
|
+
|
|
77
|
+
let(:engagement) {Hubspot::EngagementNote.create!(nil, 'test note') }
|
|
65
78
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
79
|
+
it 'should remove from hubspot' do
|
|
80
|
+
expect(Hubspot::Engagement.find(engagement.id)).to_not be_nil
|
|
81
|
+
|
|
82
|
+
expect(engagement.destroy!).to be_true
|
|
83
|
+
expect(engagement.destroyed?).to be_true
|
|
84
|
+
|
|
85
|
+
expect(Hubspot::Engagement.find(engagement.id)).to be_nil
|
|
86
|
+
end
|
|
70
87
|
end
|
|
71
88
|
end
|
|
72
89
|
|
|
73
|
-
describe '
|
|
74
|
-
|
|
90
|
+
describe 'EngagementCall' do
|
|
91
|
+
let(:example_engagement_hash) do
|
|
92
|
+
VCR.use_cassette("engagement_call_example") do
|
|
93
|
+
HTTParty.get("https://api.hubapi.com/engagements/v1/engagements/4709059?hapikey=demo").parsed_response
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
describe ".create!" do
|
|
98
|
+
cassette "engagement_call_create"
|
|
99
|
+
body = "Test call"
|
|
100
|
+
subject { Hubspot::EngagementCall.create!(nil, body, 0) }
|
|
101
|
+
its(:id) { should_not be_nil }
|
|
102
|
+
its(:body) { should eql body }
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
describe ".find" do
|
|
106
|
+
cassette "engagement_call_find"
|
|
107
|
+
let(:engagement) { Hubspot::EngagementNote.new(example_engagement_hash) }
|
|
108
|
+
|
|
109
|
+
it 'must find by the engagement id' do
|
|
110
|
+
find_engagement = Hubspot::EngagementNote.find(engagement.id)
|
|
111
|
+
find_engagement.id.should eql engagement.id
|
|
112
|
+
find_engagement.body.should eql engagement.body
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
describe '#destroy!' do
|
|
117
|
+
cassette 'engagement_call_destroy'
|
|
75
118
|
|
|
76
|
-
|
|
119
|
+
let(:engagement) { Hubspot::EngagementCall.create!(nil, 'test call', 0) }
|
|
77
120
|
|
|
78
|
-
|
|
79
|
-
|
|
121
|
+
it 'should remove from hubspot' do
|
|
122
|
+
expect(Hubspot::Engagement.find(engagement.id)).to_not be_nil
|
|
80
123
|
|
|
81
|
-
|
|
82
|
-
|
|
124
|
+
expect(engagement.destroy!).to be_true
|
|
125
|
+
expect(engagement.destroyed?).to be_true
|
|
83
126
|
|
|
84
|
-
|
|
127
|
+
expect(Hubspot::Engagement.find(engagement.id)).to be_nil
|
|
128
|
+
end
|
|
85
129
|
end
|
|
86
130
|
end
|
|
87
131
|
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
describe 'Deals pipeline API Live test', live: true do
|
|
2
|
+
|
|
3
|
+
before do
|
|
4
|
+
Hubspot.configure hapikey: 'demo'
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
let(:params) do
|
|
8
|
+
{
|
|
9
|
+
'label' => 'auto pipeline1',
|
|
10
|
+
'stages' => [
|
|
11
|
+
{
|
|
12
|
+
'label' => 'initial state',
|
|
13
|
+
'displayOrder' => 0,
|
|
14
|
+
'probability' => 0.5
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
'label' => 'next state',
|
|
18
|
+
'displayOrder' => 1,
|
|
19
|
+
'probability' => 0.9
|
|
20
|
+
}
|
|
21
|
+
]
|
|
22
|
+
}
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it 'should create, find, update and destroy' do
|
|
26
|
+
pipeline = Hubspot::DealPipeline.create!(params)
|
|
27
|
+
|
|
28
|
+
expect(pipeline.label).to eql 'auto pipeline1'
|
|
29
|
+
expect(pipeline.stages.size).to eql 2
|
|
30
|
+
expect(pipeline.stages.first['label']).to eql 'initial state'
|
|
31
|
+
expect(pipeline.stages[1]['label']).to eql 'next state'
|
|
32
|
+
|
|
33
|
+
pipeline.destroy!
|
|
34
|
+
end
|
|
35
|
+
end
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: hubspot-ruby
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Andrew DiMichele
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2017-10-24 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: activesupport
|
|
@@ -56,16 +56,16 @@ dependencies:
|
|
|
56
56
|
name: rspec
|
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
|
58
58
|
requirements:
|
|
59
|
-
- - "
|
|
59
|
+
- - "~>"
|
|
60
60
|
- !ruby/object:Gem::Version
|
|
61
|
-
version: '0'
|
|
61
|
+
version: '2.0'
|
|
62
62
|
type: :development
|
|
63
63
|
prerelease: false
|
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
|
65
65
|
requirements:
|
|
66
|
-
- - "
|
|
66
|
+
- - "~>"
|
|
67
67
|
- !ruby/object:Gem::Version
|
|
68
|
-
version: '0'
|
|
68
|
+
version: '2.0'
|
|
69
69
|
- !ruby/object:Gem::Dependency
|
|
70
70
|
name: rr
|
|
71
71
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -200,7 +200,6 @@ extra_rdoc_files: []
|
|
|
200
200
|
files:
|
|
201
201
|
- ".rspec"
|
|
202
202
|
- Gemfile
|
|
203
|
-
- Gemfile.lock
|
|
204
203
|
- Guardfile
|
|
205
204
|
- LICENSE.txt
|
|
206
205
|
- README.md
|
|
@@ -225,6 +224,7 @@ files:
|
|
|
225
224
|
- lib/hubspot/owner.rb
|
|
226
225
|
- lib/hubspot/properties.rb
|
|
227
226
|
- lib/hubspot/railtie.rb
|
|
227
|
+
- lib/hubspot/subscription.rb
|
|
228
228
|
- lib/hubspot/topic.rb
|
|
229
229
|
- lib/hubspot/utils.rb
|
|
230
230
|
- lib/tasks/properties.rake
|
|
@@ -250,6 +250,7 @@ files:
|
|
|
250
250
|
- spec/live/companies_properties_integration_spec.rb
|
|
251
251
|
- spec/live/contacts_integration_spec.rb
|
|
252
252
|
- spec/live/contacts_properties_integration_spec.rb
|
|
253
|
+
- spec/live/deal_pipeline_spec.rb
|
|
253
254
|
- spec/live/deal_properties_integration_spec.rb
|
|
254
255
|
- spec/live/deals_integration_spec.rb
|
|
255
256
|
- spec/spec_helper.rb
|
|
@@ -274,7 +275,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
274
275
|
version: '0'
|
|
275
276
|
requirements: []
|
|
276
277
|
rubyforge_project:
|
|
277
|
-
rubygems_version: 2.5.
|
|
278
|
+
rubygems_version: 2.4.5.2
|
|
278
279
|
signing_key:
|
|
279
280
|
specification_version: 4
|
|
280
281
|
summary: hubspot-ruby is a wrapper for the HubSpot REST API
|
data/Gemfile.lock
DELETED
|
@@ -1,99 +0,0 @@
|
|
|
1
|
-
PATH
|
|
2
|
-
remote: .
|
|
3
|
-
specs:
|
|
4
|
-
hubspot-ruby (0.2.0)
|
|
5
|
-
activesupport (>= 3.0.0)
|
|
6
|
-
httparty (>= 0.10.0)
|
|
7
|
-
|
|
8
|
-
GEM
|
|
9
|
-
remote: http://rubygems.org/
|
|
10
|
-
specs:
|
|
11
|
-
activesupport (3.2.12)
|
|
12
|
-
i18n (~> 0.6)
|
|
13
|
-
multi_json (~> 1.0)
|
|
14
|
-
addressable (2.3.6)
|
|
15
|
-
awesome_print (1.1.0)
|
|
16
|
-
celluloid (0.16.0)
|
|
17
|
-
timers (~> 4.0.0)
|
|
18
|
-
coderay (1.1.0)
|
|
19
|
-
crack (0.4.2)
|
|
20
|
-
safe_yaml (~> 1.0.0)
|
|
21
|
-
diff-lcs (1.2.1)
|
|
22
|
-
ffi (1.9.6)
|
|
23
|
-
formatador (0.2.5)
|
|
24
|
-
guard (2.6.1)
|
|
25
|
-
formatador (>= 0.2.4)
|
|
26
|
-
listen (~> 2.7)
|
|
27
|
-
lumberjack (~> 1.0)
|
|
28
|
-
pry (>= 0.9.12)
|
|
29
|
-
thor (>= 0.18.1)
|
|
30
|
-
guard-rspec (3.1.0)
|
|
31
|
-
guard (>= 1.8)
|
|
32
|
-
rspec (~> 2.13)
|
|
33
|
-
hitimes (1.2.2)
|
|
34
|
-
httparty (0.10.2)
|
|
35
|
-
multi_json (~> 1.0)
|
|
36
|
-
multi_xml (>= 0.5.2)
|
|
37
|
-
i18n (0.6.4)
|
|
38
|
-
json (1.8.3)
|
|
39
|
-
listen (2.7.11)
|
|
40
|
-
celluloid (>= 0.15.2)
|
|
41
|
-
rb-fsevent (>= 0.9.3)
|
|
42
|
-
rb-inotify (>= 0.9)
|
|
43
|
-
lumberjack (1.0.9)
|
|
44
|
-
method_source (0.8.2)
|
|
45
|
-
multi_json (1.6.1)
|
|
46
|
-
multi_xml (0.5.3)
|
|
47
|
-
pry (0.10.1)
|
|
48
|
-
coderay (~> 1.1.0)
|
|
49
|
-
method_source (~> 0.8.1)
|
|
50
|
-
slop (~> 3.4)
|
|
51
|
-
rake (10.4.2)
|
|
52
|
-
rb-fsevent (0.9.4)
|
|
53
|
-
rb-inotify (0.9.5)
|
|
54
|
-
ffi (>= 0.5.0)
|
|
55
|
-
rdoc (4.0.0)
|
|
56
|
-
json (~> 1.4)
|
|
57
|
-
rr (1.0.4)
|
|
58
|
-
rspec (2.13.0)
|
|
59
|
-
rspec-core (~> 2.13.0)
|
|
60
|
-
rspec-expectations (~> 2.13.0)
|
|
61
|
-
rspec-mocks (~> 2.13.0)
|
|
62
|
-
rspec-core (2.13.1)
|
|
63
|
-
rspec-expectations (2.13.0)
|
|
64
|
-
diff-lcs (>= 1.1.3, < 2.0)
|
|
65
|
-
rspec-mocks (2.13.0)
|
|
66
|
-
safe_yaml (1.0.4)
|
|
67
|
-
simplecov (0.7.1)
|
|
68
|
-
multi_json (~> 1.0)
|
|
69
|
-
simplecov-html (~> 0.7.1)
|
|
70
|
-
simplecov-html (0.7.1)
|
|
71
|
-
slop (3.6.0)
|
|
72
|
-
thor (0.19.1)
|
|
73
|
-
timecop (0.7.1)
|
|
74
|
-
timers (4.0.1)
|
|
75
|
-
hitimes
|
|
76
|
-
vcr (2.4.0)
|
|
77
|
-
webmock (1.9.3)
|
|
78
|
-
addressable (>= 2.2.7)
|
|
79
|
-
crack (>= 0.3.2)
|
|
80
|
-
|
|
81
|
-
PLATFORMS
|
|
82
|
-
ruby
|
|
83
|
-
|
|
84
|
-
DEPENDENCIES
|
|
85
|
-
awesome_print
|
|
86
|
-
bundler
|
|
87
|
-
guard-rspec
|
|
88
|
-
hubspot-ruby!
|
|
89
|
-
rake
|
|
90
|
-
rdoc
|
|
91
|
-
rr
|
|
92
|
-
rspec
|
|
93
|
-
simplecov
|
|
94
|
-
timecop
|
|
95
|
-
vcr
|
|
96
|
-
webmock (< 1.10)
|
|
97
|
-
|
|
98
|
-
BUNDLED WITH
|
|
99
|
-
1.13.2
|