hubspot-api-ruby 0.8.0 → 0.8.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +2 -142
- data/hubspot-api-ruby.gemspec +3 -3
- data/lib/hubspot-api-ruby.rb +1 -0
- data/lib/hubspot/association.rb +80 -0
- data/lib/hubspot/company.rb +2 -13
- data/lib/hubspot/deal.rb +33 -32
- data/lib/hubspot/resource.rb +4 -4
- data/spec/lib/hubspot/association_spec.rb +160 -0
- data/spec/lib/hubspot/company_spec.rb +16 -33
- data/spec/lib/hubspot/deal_spec.rb +45 -4
- data/spec/lib/hubspot/resource_spec.rb +41 -1
- metadata +4 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 5039b18c952923db03dbe7f0ae2f1ae676008179860804e34182298e6acbbcfb
|
4
|
+
data.tar.gz: 13a047c2ff4858e64cd00c173513bf0643d79ba9dc9b815d6017c148af6bf2fb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 17ac11777f8b4c3bb6e95f29a43ffb3ae6b1cba2ab1a27f37c423390fd6603bad8a9b140ebcaaca3df2a74995407dbcafadeceeb853a950fdb0fb8d5a0f289a3
|
7
|
+
data.tar.gz: ae7cfcbbdf2a34c7cec6505f34144436f055f7902cb1d8497845d33fff0fc25f90376c6bd221c2c4fb9c59b8cf4dc44efdb75479a6a2322bcd6970bb3b76ff43
|
data/README.md
CHANGED
@@ -109,149 +109,9 @@ At this time, OAuth tokens are configured globally rather than on a per-connecti
|
|
109
109
|
|
110
110
|
Classes have been created that map to Hubspot resource types and attempt to abstract away as much of the API specific details as possible. These classes generally follow the [ActiveRecord](https://en.wikipedia.org/wiki/Active_record_pattern) pattern and general Ruby conventions. Anyone familiar with [Ruby On Rails](https://rubyonrails.org/) should find this API closely maps with familiar concepts.
|
111
111
|
|
112
|
+
### Example
|
112
113
|
|
113
|
-
|
114
|
-
|
115
|
-
```ruby
|
116
|
-
irb(main):001:0> company = Hubspot::Company.new(name: "My Company LLC.")
|
117
|
-
=> #<Hubspot::Company:0x000055b9219cc068 @changes={"name"=>"My Company LLC."}, @properties={}, @id=nil, @persisted=false, @deleted=false>
|
118
|
-
|
119
|
-
irb(main):002:0> company.persisted?
|
120
|
-
=> false
|
121
|
-
|
122
|
-
irb(main):003:0> company.save
|
123
|
-
=> true
|
124
|
-
|
125
|
-
irb(main):004:0> company.persisted?
|
126
|
-
=> true
|
127
|
-
```
|
128
|
-
|
129
|
-
```ruby
|
130
|
-
irb(main):001:0> company = Hubspot::Company.create(name: "Second Financial LLC.")
|
131
|
-
=> #<Hubspot::Company:0x0000557ea7119fb0 @changes={}, @properties={"hs_lastmodifieddate"=>{"value"=>"1552234087467", "timestamp"=>1552234087467, "source"=>"CALCULATED", "sourceId"=>nil, "versions"=>[{"name"=>"hs_lastmodifieddate", "value"=>"1552234087467", "timestamp"=>1552234087467, "source"=>"CALCULATED", "sourceVid"=>[], "requestId"=>"fd45773b-30d0-4d9d-b3b8-a85e01534e46"}]}, "name"=>{"value"=>"Second Financial LLC.", "timestamp"=>1552234087467, "source"=>"API", "sourceId"=>nil, "versions"=>[{"name"=>"name", "value"=>"Second Financial LLC.", "timestamp"=>1552234087467, "source"=>"API", "sourceVid"=>[], "requestId"=>"fd45773b-30d0-4d9d-b3b8-a85e01534e46"}]}, "createdate"=>{"value"=>"1552234087467", "timestamp"=>1552234087467, "source"=>"API", "sourceId"=>nil, "versions"=>[{"name"=>"createdate", "value"=>"1552234087467", "timestamp"=>1552234087467, "source"=>"API", "sourceVid"=>[], "requestId"=>"fd45773b-30d0-4d9d-b3b8-a85e01534e46"}, {"name"=>"createdate", "value"=>"1552234087467", "timestamp"=>1552234087467, "sourceId"=>"API", "source"=>"API", "sourceVid"=>[], "requestId"=>"fd45773b-30d0-4d9d-b3b8-a85e01534e46"}]}}, @id=1726317857, @persisted=true, @deleted=false, @metadata={"portalId"=>62515, "companyId"=>1726317857, "isDeleted"=>false, "additionalDomains"=>[], "stateChanges"=>[], "mergeAudits"=>[]}>
|
132
|
-
|
133
|
-
irb(main):002:0> company.persisted?
|
134
|
-
=> true
|
135
|
-
```
|
136
|
-
|
137
|
-
|
138
|
-
### Find an existing resource
|
139
|
-
|
140
|
-
**Note:** Hubspot uses a combination of different names for the "ID" property of a resource based on what type of resource it is (eg. vid for Contact). This library attempts to abstract that away and generalizes an `id` property for all resources
|
141
|
-
|
142
|
-
```ruby
|
143
|
-
irb(main):001:0> company = Hubspot::Company.find(1726317857)
|
144
|
-
=> #<Hubspot::Company:0x0000562e4988c9a8 @changes={}, @properties={"hs_lastmodifieddate"=>{"value"=>"1552234087467", "timestamp"=>1552234087467, "source"=>"CALCULATED", "sourceId"=>nil, "versions"=>[{"name"=>"hs_lastmodifieddate", "value"=>"1552234087467", "timestamp"=>1552234087467, "source"=>"CALCULATED", "sourceVid"=>[], "requestId"=>"fd45773b-30d0-4d9d-b3b8-a85e01534e46"}]}, "name"=>{"value"=>"Second Financial LLC.", "timestamp"=>1552234087467, "source"=>"API", "sourceId"=>nil, "versions"=>[{"name"=>"name", "value"=>"Second Financial LLC.", "timestamp"=>1552234087467, "source"=>"API", "sourceVid"=>[], "requestId"=>"fd45773b-30d0-4d9d-b3b8-a85e01534e46"}]}, "createdate"=>{"value"=>"1552234087467", "timestamp"=>1552234087467, "source"=>"API", "sourceId"=>nil, "versions"=>[{"name"=>"createdate", "value"=>"1552234087467", "timestamp"=>1552234087467, "source"=>"API", "sourceVid"=>[], "requestId"=>"fd45773b-30d0-4d9d-b3b8-a85e01534e46"}]}}, @id=1726317857, @persisted=true, @deleted=false, @metadata={"portalId"=>62515, "companyId"=>1726317857, "isDeleted"=>false, "additionalDomains"=>[], "stateChanges"=>[], "mergeAudits"=>[]}>
|
145
|
-
|
146
|
-
irb(main):002:0> company = Hubspot::Company.find(1)
|
147
|
-
Traceback (most recent call last):
|
148
|
-
6: from ./hubspot-api-ruby/bin/console:20:in `<main>'
|
149
|
-
5: from (irb):2
|
150
|
-
4: from ./hubspot-api-ruby/lib/hubspot/resource.rb:17:in `find'
|
151
|
-
3: from ./hubspot-api-ruby/lib/hubspot/resource.rb:81:in `reload'
|
152
|
-
2: from ./hubspot-api-ruby/lib/hubspot/connection.rb:10:in `get_json'
|
153
|
-
1: from ./hubspot-api-ruby/lib/hubspot/connection.rb:52:in `handle_response'
|
154
|
-
Hubspot::RequestError (Response body: {"status":"error","message":"resource not found","correlationId":"7c8ba50e-16a4-4a52-a304-ff249175a8f1","requestId":"b4898274bf8992924082b4a460b90cbe"})
|
155
|
-
```
|
156
|
-
|
157
|
-
|
158
|
-
### Updating resource properties
|
159
|
-
|
160
|
-
```ruby
|
161
|
-
irb(main):001:0> company = Hubspot::Company.find(1726317857)
|
162
|
-
=> #<Hubspot::Company:0x0000563b9f3ee230 @changes={}, @properties={"hs_lastmodifieddate"=>{"value"=>"1552234087467", "timestamp"=>1552234087467, "source"=>"CALCULATED", "sourceId"=>nil, "versions"=>[{"name"=>"hs_lastmodifieddate", "value"=>"1552234087467", "timestamp"=>1552234087467, "source"=>"CALCULATED", "sourceVid"=>[], "requestId"=>"fd45773b-30d0-4d9d-b3b8-a85e01534e46"}]}, "name"=>{"value"=>"Second Financial LLC.", "timestamp"=>1552234087467, "source"=>"API", "sourceId"=>nil, "versions"=>[{"name"=>"name", "value"=>"Second Financial LLC.", "timestamp"=>1552234087467, "source"=>"API", "sourceVid"=>[], "requestId"=>"fd45773b-30d0-4d9d-b3b8-a85e01534e46"}]}, "createdate"=>{"value"=>"1552234087467", "timestamp"=>1552234087467, "source"=>"API", "sourceId"=>nil, "versions"=>[{"name"=>"createdate", "value"=>"1552234087467", "timestamp"=>1552234087467, "source"=>"API", "sourceVid"=>[], "requestId"=>"fd45773b-30d0-4d9d-b3b8-a85e01534e46"}]}}, @id=1726317857, @persisted=true, @deleted=false, @metadata={"portalId"=>62515, "companyId"=>1726317857, "isDeleted"=>false, "additionalDomains"=>[], "stateChanges"=>[], "mergeAudits"=>[]}>
|
163
|
-
|
164
|
-
irb(main):002:0> company.name
|
165
|
-
=> "Second Financial LLC."
|
166
|
-
|
167
|
-
irb(main):003:0> company.name = "Third Financial LLC."
|
168
|
-
=> "Third Financial LLC."
|
169
|
-
|
170
|
-
irb(main):004:0> company.changed?
|
171
|
-
=> true
|
172
|
-
|
173
|
-
irb(main):005:0> company.changes
|
174
|
-
=> {:name=>"Third Financial LLC."}
|
175
|
-
|
176
|
-
irb(main):006:0> company.save
|
177
|
-
=> true
|
178
|
-
|
179
|
-
irb(main):007:0> company.changed?
|
180
|
-
=> false
|
181
|
-
|
182
|
-
irb(main):008:0> company.changes
|
183
|
-
=> {}
|
184
|
-
```
|
185
|
-
|
186
|
-
**Note:** Unlike ActiveRecord in Rails, in some cases not all properties of a resource are known. If these properties are not returned by the API then they will not have a getter method defined for them until they've been set first. This may change in the future to improve the user experience and different methods are being tested.
|
187
|
-
|
188
|
-
```ruby
|
189
|
-
irb(main):001:0> company = Hubspot::Company.new
|
190
|
-
=> #<Hubspot::Company:0x0000561d0a8bdff8 @changes={}, @properties={}, @id=nil, @persisted=false, @deleted=false>
|
191
|
-
|
192
|
-
irb(main):002:0> company.name
|
193
|
-
Traceback (most recent call last):
|
194
|
-
3: from ./hubspot-api-ruby/bin/console:20:in `<main>'
|
195
|
-
2: from (irb):2
|
196
|
-
1: from ./hubspot-api-ruby/lib/hubspot/resource.rb:215:in `method_missing'
|
197
|
-
NoMethodError (undefined method `name' for #<Hubspot::Company:0x0000561d0a8bdff8>)
|
198
|
-
|
199
|
-
irb(main):003:0> company.name = "Foobar"
|
200
|
-
=> "Foobar"
|
201
|
-
|
202
|
-
irb(main):004:0> company.name
|
203
|
-
=> "Foobar"
|
204
|
-
```
|
205
|
-
|
206
|
-
### Collections
|
207
|
-
|
208
|
-
To make working with API endpoints that return multiple resources easier, the returned instances will be wrapped in a collection instance. Just like in Rails, the collection instance provides helper methods for limiting the number of returned resources, paging through the results, and handles passing the options each time a new API call is made. The collection exposes all Ruby Array methods so you can use things like `size()`, `first()`, `last()`, and `map()`.
|
209
|
-
|
210
|
-
```ruby
|
211
|
-
irb(main):001:0> contacts = Hubspot::Contact.all
|
212
|
-
=> #<Hubspot::PagedCollection:0x000055ba3c2b55d8 @limit_param="limit", @limit=25, @offset_param="offset", @offset=nil, @options={}, @fetch_proc=#<Proc:0x000055ba3c2b5538@./hubspot-api-ruby/lib/hubspot/contact.rb:18>, @resources=[...snip...], @next_offset=9242374, @has_more=true>
|
213
|
-
|
214
|
-
irb(main):002:0> contacts.more?
|
215
|
-
=> true
|
216
|
-
|
217
|
-
irb(main):003:0> contacts.next_offset
|
218
|
-
=> 9242374
|
219
|
-
|
220
|
-
irb(main):004:0> contacts.size
|
221
|
-
=> 25
|
222
|
-
|
223
|
-
irb(main):005:0> contacts.first
|
224
|
-
=> #<Hubspot::Contact:0x000055ba3c29bac0 @changes={}, @properties={"firstname"=>{"value"=>"My Street X 1551971239 => My Street X 1551971267 => My Street X 1551971279"}, "lastmodifieddate"=>{"value"=>"1551971286841"}, "company"=>{"value"=>"MadKudu"}, "lastname"=>{"value"=>"Test0830181615"}}, @id=9153674, @persisted=true, @deleted=false, @metadata={"addedAt"=>1535664601481, "vid"=>9153674, "canonical-vid"=>9153674, "merged-vids"=>[], "portal-id"=>62515, "is-contact"=>true, "profile-token"=>"AO_T-mPNHk6O7jh8u8D2IlrhZn7GO91w-weZrC93_UaJvdB0U4o6Uc_PkPJ3DOpf15sUplrxMzG9weiTTpPI05Nr04zxnaNYBVcWHOlMbVlJ2Avq1KGoCBVbIoQucOy_YmCBIfOXRtcc", "profile-url"=>"https://app.hubspot.com/contacts/62515/contact/9153674", "form-submissions"=>[], "identity-profiles"=>[{"vid"=>9153674, "saved-at-timestamp"=>1535664601272, "deleted-changed-timestamp"=>0, "identities"=>[{"type"=>"EMAIL", "value"=>"test.0830181615@test.com", "timestamp"=>1535664601151, "is-primary"=>true}, {"type"=>"LEAD_GUID", "value"=>"01a107c4-3872-44e0-ab2e-47061507ffa1", "timestamp"=>1535664601259}]}], "merge-audits"=>[]}>
|
225
|
-
|
226
|
-
irb(main):006:0> contacts.next_page
|
227
|
-
=> #<Hubspot::PagedCollection:0x000055ba3c2b55d8 @limit_param="limit", @limit=25, @offset_param="offset", @offset=9242374, @options={}, @fetch_proc=#<Proc:0x000055ba3c2b5538@./hubspot-api-ruby/lib/hubspot/contact.rb:18>, @resources=[...snip...], @next_offset=9324874, @has_more=true>
|
228
|
-
```
|
229
|
-
|
230
|
-
For Hubspot resources that support batch updates for updating multiple resources, the collection provides an `update_all()` method:
|
231
|
-
|
232
|
-
```ruby
|
233
|
-
irb(main):001:0> companies = Hubspot::Company.all(limit: 5)
|
234
|
-
=> #<Hubspot::PagedCollection:0x000055d5314fe0c8 @limit_param="limit", @limit=5, @offset_param="offset", @offset=nil, @options={}, @fetch_proc=#<Proc:0x000055d5314fe028@./hubspot-api-ruby/lib/hubspot/company.rb:21>, @resources=[...snip...], @next_offset=116011506, @has_more=true>
|
235
|
-
|
236
|
-
irb(main):002:0> companies.size
|
237
|
-
=> 5
|
238
|
-
|
239
|
-
irb(main):003:0> companies.update_all(lifecyclestage: "opportunity")
|
240
|
-
=> true
|
241
|
-
|
242
|
-
irb(main):004:0> companies.refresh
|
243
|
-
=> #<Hubspot::PagedCollection:0x000055d5314fe0c8 @limit_param="limit", @limit=5, @offset_param="offset", @offset=nil, @options={}, @fetch_proc=#<Proc:0x000055d5314fe028@./hubspot-api-ruby/lib/hubspot/company.rb:21>, @resources=[...snip...], @next_offset=116011506, @has_more=true>
|
244
|
-
```
|
245
|
-
|
246
|
-
### Deleting a resource
|
247
|
-
|
248
|
-
```ruby
|
249
|
-
irb(main):001:0> contact = Hubspot::Contact.find(9324874)
|
250
|
-
=> #<Hubspot::Contact:0x000055a87c87aee0 ...snip... >
|
251
|
-
|
252
|
-
irb(main):002:0> contact.delete
|
253
|
-
=> true
|
254
|
-
```
|
114
|
+
https://github.com/lounna-sas/hubspot-api-ruby/wiki
|
255
115
|
|
256
116
|
## Resource types
|
257
117
|
|
data/hubspot-api-ruby.gemspec
CHANGED
@@ -1,9 +1,9 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "hubspot-api-ruby"
|
3
|
-
s.version = "0.8.
|
3
|
+
s.version = "0.8.1"
|
4
4
|
s.require_paths = ["lib"]
|
5
|
-
s.authors = ["Jonathan"
|
6
|
-
s.email = ["jonathan@hoggo.com"
|
5
|
+
s.authors = ["Jonathan"]
|
6
|
+
s.email = ["jonathan@hoggo.com"]
|
7
7
|
s.description = "hubspot-api-ruby is a wrapper for the HubSpot REST API"
|
8
8
|
s.licenses = ["MIT"]
|
9
9
|
s.files = [".rspec", "Gemfile", "Guardfile", "LICENSE.txt", "README.md", "RELEASING.md", "Rakefile", "hubspot-api-ruby.gemspec"]
|
data/lib/hubspot-api-ruby.rb
CHANGED
@@ -0,0 +1,80 @@
|
|
1
|
+
class Hubspot::Association
|
2
|
+
COMPANY_TO_CONTACT = 2
|
3
|
+
DEAL_TO_CONTACT = 3
|
4
|
+
CONTACT_TO_DEAL = 4
|
5
|
+
DEAL_TO_COMPANY = 5
|
6
|
+
COMPANY_TO_DEAL = 6
|
7
|
+
DEFINITION_TARGET_TO_CLASS = {
|
8
|
+
2 => Hubspot::Contact,
|
9
|
+
3 => Hubspot::Contact,
|
10
|
+
4 => Hubspot::Deal,
|
11
|
+
5 => Hubspot::Company,
|
12
|
+
6 => Hubspot::Deal
|
13
|
+
}.freeze
|
14
|
+
|
15
|
+
BATCH_CREATE_PATH = '/crm-associations/v1/associations/create-batch'
|
16
|
+
BATCH_DELETE_PATH = '/crm-associations/v1/associations/delete-batch'
|
17
|
+
ASSOCIATIONS_PATH = '/crm-associations/v1/associations/:resource_id/HUBSPOT_DEFINED/:definition_id'
|
18
|
+
|
19
|
+
class << self
|
20
|
+
def create(from_id, to_id, definition_id)
|
21
|
+
batch_create([{ from_id: from_id, to_id: to_id, definition_id: definition_id }])
|
22
|
+
end
|
23
|
+
|
24
|
+
# Make multiple associations in a single API call
|
25
|
+
# {https://developers.hubspot.com/docs/methods/crm-associations/batch-associate-objects}
|
26
|
+
# usage:
|
27
|
+
# Hubspot::Association.batch_create([{ from_id: 1, to_id: 2, definition_id: Hubspot::Association::COMPANY_TO_CONTACT }])
|
28
|
+
def batch_create(associations)
|
29
|
+
request = associations.map { |assocation| build_association_body(assocation) }
|
30
|
+
Hubspot::Connection.put_json(BATCH_CREATE_PATH, params: { no_parse: true }, body: request).success?
|
31
|
+
end
|
32
|
+
|
33
|
+
def delete(from_id, to_id, definition_id)
|
34
|
+
batch_delete([{from_id: from_id, to_id: to_id, definition_id: definition_id}])
|
35
|
+
end
|
36
|
+
|
37
|
+
# Remove multiple associations in a single API call
|
38
|
+
# {https://developers.hubspot.com/docs/methods/crm-associations/batch-delete-associations}
|
39
|
+
# usage:
|
40
|
+
# Hubspot::Association.batch_delete([{ from_id: 1, to_id: 2, definition_id: Hubspot::Association::COMPANY_TO_CONTACT }])
|
41
|
+
def batch_delete(associations)
|
42
|
+
request = associations.map { |assocation| build_association_body(assocation) }
|
43
|
+
Hubspot::Connection.put_json(BATCH_DELETE_PATH, params: { no_parse: true }, body: request).success?
|
44
|
+
end
|
45
|
+
|
46
|
+
# Retrieve all associated resources given a source (resource_id) and a kind (definition_id)
|
47
|
+
# Example: if resource_id is a deal, using DEAL_TO_CONTACT will find every contact associated with the deal
|
48
|
+
# {https://developers.hubspot.com/docs/methods/crm-associations/get-associations}
|
49
|
+
# Warning: it will make N+M queries, where
|
50
|
+
# N is the number of PagedCollection requests necessary to get all ids,
|
51
|
+
# and M is the number of results, each resulting in a find
|
52
|
+
# usage:
|
53
|
+
# Hubspot::Association.all(42, Hubspot::Association::DEAL_TO_CONTACT)
|
54
|
+
def all(resource_id, definition_id)
|
55
|
+
opts = { resource_id: resource_id, definition_id: definition_id }
|
56
|
+
klass = DEFINITION_TARGET_TO_CLASS[definition_id]
|
57
|
+
raise(Hubspot::InvalidParams, 'Definition not supported') unless klass.present?
|
58
|
+
|
59
|
+
collection = Hubspot::PagedCollection.new(opts) do |options, offset, limit|
|
60
|
+
params = options.merge(offset: offset, limit: limit)
|
61
|
+
response = Hubspot::Connection.get_json(ASSOCIATIONS_PATH, params)
|
62
|
+
|
63
|
+
resources = response['results'].map { |result| klass.find(result) }
|
64
|
+
[resources, response['offset'], response['has-more']]
|
65
|
+
end
|
66
|
+
collection.resources
|
67
|
+
end
|
68
|
+
|
69
|
+
private
|
70
|
+
|
71
|
+
def build_association_body(assocation)
|
72
|
+
{
|
73
|
+
fromObjectId: assocation[:from_id],
|
74
|
+
toObjectId: assocation[:to_id],
|
75
|
+
category: 'HUBSPOT_DEFINED',
|
76
|
+
definitionId: assocation[:definition_id]
|
77
|
+
}
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
data/lib/hubspot/company.rb
CHANGED
@@ -2,7 +2,6 @@ class Hubspot::Company < Hubspot::Resource
|
|
2
2
|
self.id_field = "companyId"
|
3
3
|
self.property_name_field = "name"
|
4
4
|
|
5
|
-
ADD_CONTACT_PATH = '/companies/v2/companies/:id/contacts/:contact_id'
|
6
5
|
ALL_PATH = '/companies/v2/companies/paged'
|
7
6
|
BATCH_UPDATE_PATH = '/companies/v1/batch-async/update'
|
8
7
|
CONTACTS_PATH = '/companies/v2/companies/:id/contacts'
|
@@ -12,7 +11,6 @@ class Hubspot::Company < Hubspot::Resource
|
|
12
11
|
FIND_PATH = '/companies/v2/companies/:id'
|
13
12
|
RECENTLY_CREATED_PATH = '/companies/v2/companies/recent/created'
|
14
13
|
RECENTLY_MODIFIED_PATH = '/companies/v2/companies/recent/modified'
|
15
|
-
REMOVE_CONTACT_PATH = '/companies/v2/companies/:id/contacts/:contact_id'
|
16
14
|
SEARCH_DOMAIN_PATH = '/companies/v2/domains/:domain/companies'
|
17
15
|
UPDATE_PATH = '/companies/v2/companies/:id'
|
18
16
|
|
@@ -80,20 +78,11 @@ class Hubspot::Company < Hubspot::Resource
|
|
80
78
|
end
|
81
79
|
|
82
80
|
def add_contact(id, contact_id)
|
83
|
-
Hubspot::
|
84
|
-
ADD_CONTACT_PATH,
|
85
|
-
params: { id: id, contact_id: contact_id }
|
86
|
-
)
|
87
|
-
true
|
81
|
+
Hubspot::Association.create(id, contact_id, Hubspot::Association::COMPANY_TO_CONTACT)
|
88
82
|
end
|
89
83
|
|
90
84
|
def remove_contact(id, contact_id)
|
91
|
-
Hubspot::
|
92
|
-
REMOVE_CONTACT_PATH,
|
93
|
-
{ id: id, contact_id: contact_id }
|
94
|
-
)
|
95
|
-
|
96
|
-
true
|
85
|
+
Hubspot::Association.delete(id, contact_id, Hubspot::Association::COMPANY_TO_CONTACT)
|
97
86
|
end
|
98
87
|
|
99
88
|
def batch_update(companies, opts = {})
|
data/lib/hubspot/deal.rb
CHANGED
@@ -12,8 +12,6 @@ module Hubspot
|
|
12
12
|
DEAL_PATH = "/deals/v1/deal/:deal_id"
|
13
13
|
RECENT_UPDATED_PATH = "/deals/v1/deal/recent/modified"
|
14
14
|
UPDATE_DEAL_PATH = '/deals/v1/deal/:deal_id'
|
15
|
-
ASSOCIATE_DEAL_PATH = '/deals/v1/deal/:deal_id/associations/:OBJECTTYPE?id=:objectId'
|
16
|
-
ASSOCIATED_DEAL_PATH = "/deals/v1/deal/associated/:objectType/:objectId"
|
17
15
|
|
18
16
|
attr_reader :properties
|
19
17
|
attr_reader :portal_id
|
@@ -61,25 +59,33 @@ module Hubspot
|
|
61
59
|
response.success?
|
62
60
|
end
|
63
61
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
62
|
+
# Associate a deal with a contact or company
|
63
|
+
# {http://developers.hubspot.com/docs/methods/deals/associate_deal}
|
64
|
+
# Usage
|
65
|
+
# Hubspot::Deal.associate!(45146940, [32], [52])
|
66
|
+
def associate!(deal_id, company_ids=[], vids=[])
|
67
|
+
associations = company_ids.map do |id|
|
68
|
+
{ from_id: deal_id, to_id: id, definition_id: Hubspot::Association::DEAL_TO_COMPANY }
|
69
|
+
end
|
70
|
+
associations += vids.map do |id|
|
71
|
+
{ from_id: deal_id, to_id: id, definition_id: Hubspot::Association::DEAL_TO_CONTACT }
|
72
|
+
end
|
73
|
+
Hubspot::Association.batch_create(associations)
|
74
|
+
end
|
75
|
+
|
76
|
+
# Didssociate a deal with a contact or company
|
77
|
+
# {https://developers.hubspot.com/docs/methods/deals/delete_association}
|
78
|
+
# Usage
|
79
|
+
# Hubspot::Deal.dissociate!(45146940, [32], [52])
|
80
|
+
def dissociate!(deal_id, company_ids=[], vids=[])
|
81
|
+
associations = company_ids.map do |id|
|
82
|
+
{ from_id: deal_id, to_id: id, definition_id: Hubspot::Association::DEAL_TO_COMPANY }
|
83
|
+
end
|
84
|
+
associations += vids.map do |id|
|
85
|
+
{ from_id: deal_id, to_id: id, definition_id: Hubspot::Association::DEAL_TO_CONTACT }
|
86
|
+
end
|
87
|
+
Hubspot::Association.batch_delete(associations)
|
88
|
+
end
|
83
89
|
|
84
90
|
def find(deal_id)
|
85
91
|
response = Hubspot::Connection.get_json(DEAL_PATH, { deal_id: deal_id })
|
@@ -125,20 +131,15 @@ module Hubspot
|
|
125
131
|
end
|
126
132
|
|
127
133
|
# Find all deals associated to a contact or company
|
128
|
-
# {http://developers.hubspot.com/docs/methods/deals/get-associated-deals}
|
129
134
|
# @param object [Hubspot::Contact || Hubspot::Company] a contact or company
|
130
135
|
# @return [Array] Array of Hubspot::Deal records
|
131
136
|
def find_by_association(object)
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
params = { objectType: objectType, objectId: object.id }
|
140
|
-
response = Hubspot::Connection.get_json(path, params)
|
141
|
-
response["results"].map { |deal_id| find(deal_id) }
|
137
|
+
definition = case object
|
138
|
+
when Hubspot::Company then Hubspot::Association::COMPANY_TO_DEAL
|
139
|
+
when Hubspot::Contact then Hubspot::Association::CONTACT_TO_DEAL
|
140
|
+
else raise(Hubspot::InvalidParams, 'Instance type not supported')
|
141
|
+
end
|
142
|
+
Hubspot::Association.all(object.id, definition)
|
142
143
|
end
|
143
144
|
end
|
144
145
|
|
data/lib/hubspot/resource.rb
CHANGED
@@ -98,7 +98,7 @@ module Hubspot
|
|
98
98
|
end
|
99
99
|
|
100
100
|
def [](name)
|
101
|
-
@changes[name] || @properties
|
101
|
+
@changes[name] || @properties.dig(name, 'value')
|
102
102
|
end
|
103
103
|
|
104
104
|
def reload
|
@@ -238,7 +238,7 @@ module Hubspot
|
|
238
238
|
singleton_class.instance_eval do
|
239
239
|
keys.each do |k|
|
240
240
|
# Define a getter
|
241
|
-
define_method(k) { @changes[k.to_sym] || @properties.dig(k,
|
241
|
+
define_method(k) { @changes[k.to_sym] || @properties.dig(k, 'value') }
|
242
242
|
|
243
243
|
# Define a setter
|
244
244
|
define_method("#{k}=") do |v|
|
@@ -257,7 +257,7 @@ module Hubspot
|
|
257
257
|
# Call the new setter
|
258
258
|
return send(method_name, arguments[0])
|
259
259
|
elsif @properties.key?(method_name)
|
260
|
-
return @properties[method_name]
|
260
|
+
return @properties[method_name]['value']
|
261
261
|
else
|
262
262
|
super
|
263
263
|
end
|
@@ -267,4 +267,4 @@ module Hubspot
|
|
267
267
|
(@properties && @properties.key?(method_name)) || super
|
268
268
|
end
|
269
269
|
end
|
270
|
-
end
|
270
|
+
end
|
@@ -0,0 +1,160 @@
|
|
1
|
+
RSpec.describe Hubspot::Association do
|
2
|
+
before { Hubspot.configure(hapikey: 'demo') }
|
3
|
+
|
4
|
+
let(:portal_id) { 62515 }
|
5
|
+
let(:company) { create :company }
|
6
|
+
let(:contact) { create :contact }
|
7
|
+
|
8
|
+
describe '.create' do
|
9
|
+
context 'with a valid ID' do
|
10
|
+
cassette
|
11
|
+
subject { described_class.create(company.id, contact.id, described_class::COMPANY_TO_CONTACT) }
|
12
|
+
|
13
|
+
it 'associates the resources' do
|
14
|
+
expect(subject).to be true
|
15
|
+
expect(company.contact_ids.resources).to eq [contact.id]
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'with an invalid ID' do
|
20
|
+
cassette
|
21
|
+
subject { described_class.create(company.id, 1234, described_class::COMPANY_TO_CONTACT) }
|
22
|
+
|
23
|
+
it 'raises an error' do
|
24
|
+
expect { subject }.to raise_error(Hubspot::RequestError, /One or more associations are invalid/)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '.batch_create' do
|
30
|
+
let(:deal) { Hubspot::Deal.create!(portal_id, [], [], {}) }
|
31
|
+
|
32
|
+
subject { described_class.batch_create(associations) }
|
33
|
+
|
34
|
+
context 'with a valid request' do
|
35
|
+
cassette
|
36
|
+
let(:associations) do
|
37
|
+
[
|
38
|
+
{ from_id: deal.deal_id, to_id: contact.id, definition_id: described_class::DEAL_TO_CONTACT },
|
39
|
+
{ from_id: deal.deal_id, to_id: company.id, definition_id: described_class::DEAL_TO_COMPANY }
|
40
|
+
]
|
41
|
+
end
|
42
|
+
|
43
|
+
it 'associates the resources' do
|
44
|
+
expect(subject).to be true
|
45
|
+
find_deal = Hubspot::Deal.find(deal.deal_id)
|
46
|
+
expect(find_deal.vids).to eq [contact.id]
|
47
|
+
expect(find_deal.company_ids).to eq [company.id]
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context 'with an invalid ID' do
|
52
|
+
cassette
|
53
|
+
let(:associations) do
|
54
|
+
[
|
55
|
+
{ from_id: deal.deal_id, to_id: 1234, definition_id: described_class::DEAL_TO_CONTACT },
|
56
|
+
{ from_id: deal.deal_id, to_id: company.id, definition_id: described_class::DEAL_TO_COMPANY }
|
57
|
+
]
|
58
|
+
end
|
59
|
+
|
60
|
+
it 'raises an error' do
|
61
|
+
expect { subject }.to raise_error(Hubspot::RequestError, /One or more associations are invalid/)
|
62
|
+
find_deal = Hubspot::Deal.find(deal.deal_id)
|
63
|
+
expect(find_deal.vids).to eq []
|
64
|
+
expect(find_deal.company_ids).to eq []
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
describe '.delete' do
|
70
|
+
subject { described_class.delete(company.id, contact_id_to_dissociate, described_class::COMPANY_TO_CONTACT) }
|
71
|
+
before { described_class.create(company.id, contact.id, described_class::COMPANY_TO_CONTACT) }
|
72
|
+
|
73
|
+
context 'with a valid ID' do
|
74
|
+
cassette
|
75
|
+
let(:contact_id_to_dissociate) { contact.id }
|
76
|
+
|
77
|
+
it 'dissociates the resources' do
|
78
|
+
expect(subject).to be true
|
79
|
+
expect(company.contact_ids.resources).to eq []
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
context 'with an invalid ID' do
|
84
|
+
cassette
|
85
|
+
let(:contact_id_to_dissociate) { 1234 }
|
86
|
+
|
87
|
+
it 'does not raise an error' do
|
88
|
+
expect(subject).to be true
|
89
|
+
expect(company.contact_ids.resources).to eq [contact.id]
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
describe '.batch_delete' do
|
95
|
+
let(:deal) { Hubspot::Deal.create!(portal_id, [company.id], [contact.id], {}) }
|
96
|
+
|
97
|
+
subject { described_class.batch_delete(associations) }
|
98
|
+
|
99
|
+
context 'with a valid request' do
|
100
|
+
cassette
|
101
|
+
let(:associations) do
|
102
|
+
[
|
103
|
+
{ from_id: deal.deal_id, to_id: contact.id, definition_id: described_class::DEAL_TO_CONTACT },
|
104
|
+
{ from_id: deal.deal_id, to_id: company.id, definition_id: described_class::DEAL_TO_COMPANY }
|
105
|
+
]
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'dissociates the resources' do
|
109
|
+
expect(subject).to be true
|
110
|
+
find_deal = Hubspot::Deal.find(deal.deal_id)
|
111
|
+
expect(find_deal.vids).to eq []
|
112
|
+
expect(find_deal.company_ids).to eq []
|
113
|
+
end
|
114
|
+
end
|
115
|
+
|
116
|
+
context 'with an invalid ID' do
|
117
|
+
cassette
|
118
|
+
let(:associations) do
|
119
|
+
[
|
120
|
+
{ from_id: deal.deal_id, to_id: 1234, definition_id: described_class::DEAL_TO_CONTACT },
|
121
|
+
{ from_id: deal.deal_id, to_id: company.id, definition_id: described_class::DEAL_TO_COMPANY }
|
122
|
+
]
|
123
|
+
end
|
124
|
+
|
125
|
+
it 'does not raise an error, removes the valid associations' do
|
126
|
+
expect(subject).to be true
|
127
|
+
find_deal = Hubspot::Deal.find(deal.deal_id)
|
128
|
+
expect(find_deal.vids).to eq [contact.id]
|
129
|
+
expect(find_deal.company_ids).to eq []
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
describe '.all' do
|
135
|
+
subject { described_class.all(resource_id, definition_id) }
|
136
|
+
|
137
|
+
context 'with valid params' do
|
138
|
+
cassette
|
139
|
+
|
140
|
+
let(:resource_id) { deal.deal_id }
|
141
|
+
let(:definition_id) { described_class::DEAL_TO_CONTACT }
|
142
|
+
let(:deal) { Hubspot::Deal.create!(portal_id, [], contact_ids, {}) }
|
143
|
+
let(:contact_ids) { [contact.id, second_contact.id] }
|
144
|
+
let(:second_contact) { create :contact }
|
145
|
+
|
146
|
+
it 'finds the resources' do
|
147
|
+
expect(subject.map(&:id)).to contain_exactly(*contact_ids)
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
context 'with unsupported definition' do
|
152
|
+
let(:resource_id) { 1234 }
|
153
|
+
let(:definition_id) { -1 }
|
154
|
+
|
155
|
+
it 'raises an error' do
|
156
|
+
expect { subject }.to raise_error(Hubspot::InvalidParams, 'Definition not supported')
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
@@ -1,16 +1,5 @@
|
|
1
1
|
RSpec.describe Hubspot::Company do
|
2
|
-
|
3
|
-
# VCR.use_cassette("company_example") do
|
4
|
-
# HTTParty.get("https://api.hubapi.com/companies/v2/companies/21827084?hapikey=demo").parsed_response
|
5
|
-
# end
|
6
|
-
# end
|
7
|
-
# let(:company_with_contacts_hash) do
|
8
|
-
# VCR.use_cassette("company_with_contacts") do
|
9
|
-
# HTTParty.get("https://api.hubapi.com/companies/v2/companies/115200636?hapikey=demo").parsed_response
|
10
|
-
# end
|
11
|
-
# end
|
12
|
-
|
13
|
-
before{ Hubspot.configure(hapikey: "demo") }
|
2
|
+
before { Hubspot.configure(hapikey: 'demo') }
|
14
3
|
|
15
4
|
it_behaves_like "a saveable resource", :company do
|
16
5
|
def set_property(company)
|
@@ -279,13 +268,11 @@ RSpec.describe Hubspot::Company do
|
|
279
268
|
subject { described_class.add_contact company.id, contact.id }
|
280
269
|
|
281
270
|
it 'returns success' do
|
282
|
-
expect(subject).to
|
271
|
+
expect(subject).to be true
|
283
272
|
end
|
284
273
|
|
285
274
|
it 'adds the contact to the company' do
|
286
|
-
expect {
|
287
|
-
subject
|
288
|
-
}.to change { company.contact_ids }.by([contact.id])
|
275
|
+
expect { subject }.to change { company.contact_ids }.by([contact.id])
|
289
276
|
end
|
290
277
|
end
|
291
278
|
|
@@ -294,12 +281,10 @@ RSpec.describe Hubspot::Company do
|
|
294
281
|
|
295
282
|
let(:company) { create :company }
|
296
283
|
|
297
|
-
subject { described_class.add_contact company.id,
|
284
|
+
subject { described_class.add_contact company.id, 1234 }
|
298
285
|
|
299
286
|
it 'raises an error' do
|
300
|
-
expect {
|
301
|
-
subject
|
302
|
-
}.to raise_error(Hubspot::RequestError, /Contact with the vid/)
|
287
|
+
expect { subject }.to raise_error(Hubspot::RequestError, /CONTACT=1234 is not valid/)
|
303
288
|
end
|
304
289
|
end
|
305
290
|
|
@@ -309,32 +294,30 @@ RSpec.describe Hubspot::Company do
|
|
309
294
|
subject { described_class.add_contact 1, 1 }
|
310
295
|
|
311
296
|
it 'raises an error' do
|
312
|
-
expect {
|
313
|
-
subject
|
314
|
-
}.to raise_error(Hubspot::RequestError, /company with the ID/)
|
297
|
+
expect { subject }.to raise_error(Hubspot::RequestError, /COMPANY=1 is not valid/)
|
315
298
|
end
|
316
299
|
end
|
317
300
|
end
|
318
301
|
|
319
302
|
describe '.remove_contact' do
|
320
303
|
context 'with a valid company ID and contact ID' do
|
321
|
-
cassette
|
304
|
+
cassette
|
322
305
|
|
323
|
-
let
|
324
|
-
let
|
306
|
+
let(:company) { create :company }
|
307
|
+
let(:contact) { create :contact }
|
325
308
|
|
309
|
+
before { described_class.add_contact(company.id, contact.id) }
|
326
310
|
subject { described_class.remove_contact company.id, contact.id }
|
327
311
|
|
328
312
|
it 'returns success' do
|
329
|
-
expect(subject).to
|
313
|
+
expect(subject).to be true
|
330
314
|
end
|
331
315
|
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
# it 'removes the contact from the company'
|
316
|
+
it 'removes the contact from the company' do
|
317
|
+
expect(company.contact_ids.resources).to eq [contact.id]
|
318
|
+
subject
|
319
|
+
expect(company.contact_ids.resources).to eq []
|
320
|
+
end
|
338
321
|
end
|
339
322
|
end
|
340
323
|
end
|
@@ -11,7 +11,7 @@ describe Hubspot::Deal do
|
|
11
11
|
end
|
12
12
|
end
|
13
13
|
|
14
|
-
before{ Hubspot.configure(hapikey:
|
14
|
+
before { Hubspot.configure(hapikey: 'demo') }
|
15
15
|
|
16
16
|
describe "#initialize" do
|
17
17
|
subject{ Hubspot::Deal.new(example_deal_hash) }
|
@@ -107,6 +107,35 @@ describe Hubspot::Deal do
|
|
107
107
|
end
|
108
108
|
end
|
109
109
|
end
|
110
|
+
|
111
|
+
|
112
|
+
describe '.associate' do
|
113
|
+
cassette
|
114
|
+
let(:deal) { Hubspot::Deal.create!(portal_id, [], [], {}) }
|
115
|
+
let(:company) { create :company }
|
116
|
+
let(:contact) { create :contact }
|
117
|
+
let(:contact_id) { contact.id }
|
118
|
+
|
119
|
+
subject { Hubspot::Deal.associate!(deal.deal_id, [company.id], [contact_id]) }
|
120
|
+
|
121
|
+
it 'associates the deal to the contact and the company' do
|
122
|
+
subject
|
123
|
+
find_deal = Hubspot::Deal.find(deal.deal_id)
|
124
|
+
find_deal.company_ids.should eql [company.id]
|
125
|
+
find_deal.vids.should eql [contact.id]
|
126
|
+
end
|
127
|
+
|
128
|
+
context 'when an id is invalid' do
|
129
|
+
let(:contact_id) { 1234 }
|
130
|
+
|
131
|
+
it 'raises an error and do not changes associations' do
|
132
|
+
expect { subject }.to raise_error(Hubspot::RequestError)
|
133
|
+
find_deal = Hubspot::Deal.find(deal.deal_id)
|
134
|
+
find_deal.company_ids.should eql []
|
135
|
+
find_deal.vids.should eql []
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
110
139
|
|
111
140
|
describe ".find" do
|
112
141
|
cassette "deal_find"
|
@@ -119,9 +148,9 @@ describe Hubspot::Deal do
|
|
119
148
|
end
|
120
149
|
|
121
150
|
describe '.find_by_company' do
|
122
|
-
cassette
|
123
|
-
let(:company) {
|
124
|
-
let(:
|
151
|
+
cassette
|
152
|
+
let(:company) { create :company }
|
153
|
+
let!(:deal) { Hubspot::Deal.create!(portal_id, [company.id], [], { amount: amount }) }
|
125
154
|
|
126
155
|
it 'returns company deals' do
|
127
156
|
deals = Hubspot::Deal.find_by_company(company)
|
@@ -130,6 +159,18 @@ describe Hubspot::Deal do
|
|
130
159
|
end
|
131
160
|
end
|
132
161
|
|
162
|
+
describe '.find_by_contact' do
|
163
|
+
cassette
|
164
|
+
let(:contact) { create :contact }
|
165
|
+
let!(:deal) { Hubspot::Deal.create!(portal_id, [], [contact.id], { amount: amount }) }
|
166
|
+
|
167
|
+
it 'returns contact deals' do
|
168
|
+
deals = Hubspot::Deal.find_by_contact(contact)
|
169
|
+
deals.first.deal_id.should eql deal.deal_id
|
170
|
+
deals.first.properties['amount'].should eql amount
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
133
174
|
describe '.recent' do
|
134
175
|
cassette 'find_all_recent_updated_deals'
|
135
176
|
|
@@ -51,4 +51,44 @@ RSpec.describe Hubspot::Resource do
|
|
51
51
|
end
|
52
52
|
end
|
53
53
|
end
|
54
|
-
|
54
|
+
|
55
|
+
describe '#[]' do
|
56
|
+
context 'using new' do
|
57
|
+
let(:resource) { described_class.new(properties) }
|
58
|
+
let(:properties) { { id: 1, firstname: 'John', lastname: 'Wayne' } }
|
59
|
+
|
60
|
+
it { expect(resource[:firstname]).to eq 'John' }
|
61
|
+
it { expect(resource['lastname']).to eq 'Wayne' }
|
62
|
+
it { expect(resource[:middlename]).to be nil }
|
63
|
+
end
|
64
|
+
|
65
|
+
context 'using from_result' do
|
66
|
+
let(:resource) { described_class.from_result({ properties: properties }) }
|
67
|
+
let(:properties) { { id: { 'value' => 1 }, firstname: { 'value' => 'John' }, lastname: { 'value' => 'Wayne' } } }
|
68
|
+
|
69
|
+
it { expect(resource[:firstname]).to eq 'John' }
|
70
|
+
it { expect(resource['lastname']).to eq 'Wayne' }
|
71
|
+
it { expect(resource[:middlename]).to be nil }
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
describe '#adding_accessors' do
|
76
|
+
describe 'getters' do
|
77
|
+
context 'using new' do
|
78
|
+
let(:resource) { described_class.new(properties) }
|
79
|
+
let(:properties) { { id: 1, firstname: 'John', lastname: 'Wayne' } }
|
80
|
+
|
81
|
+
it { expect(resource.firstname).to eq 'John' }
|
82
|
+
it { expect(resource.lastname).to eq 'Wayne' }
|
83
|
+
end
|
84
|
+
|
85
|
+
context 'using from_result' do
|
86
|
+
let(:resource) { described_class.from_result({ properties: properties }) }
|
87
|
+
let(:properties) { { id: { 'value' => 1 }, firstname: { 'value' => 'John' }, lastname: { 'value' => 'Wayne' } } }
|
88
|
+
|
89
|
+
it { expect(resource.firstname).to eq 'John' }
|
90
|
+
it { expect(resource.lastname).to eq 'Wayne' }
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
metadata
CHANGED
@@ -1,15 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hubspot-api-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.8.
|
4
|
+
version: 0.8.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Jonathan
|
8
|
-
- Juliette
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date: 2019-12-
|
11
|
+
date: 2019-12-31 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: activesupport
|
@@ -266,7 +265,6 @@ dependencies:
|
|
266
265
|
description: hubspot-api-ruby is a wrapper for the HubSpot REST API
|
267
266
|
email:
|
268
267
|
- jonathan@hoggo.com
|
269
|
-
- juliette@hoggo.com
|
270
268
|
executables: []
|
271
269
|
extensions: []
|
272
270
|
extra_rdoc_files: []
|
@@ -280,6 +278,7 @@ files:
|
|
280
278
|
- Rakefile
|
281
279
|
- hubspot-api-ruby.gemspec
|
282
280
|
- lib/hubspot-api-ruby.rb
|
281
|
+
- lib/hubspot/association.rb
|
283
282
|
- lib/hubspot/blog.rb
|
284
283
|
- lib/hubspot/collection.rb
|
285
284
|
- lib/hubspot/company.rb
|
@@ -311,6 +310,7 @@ files:
|
|
311
310
|
- spec/factories/companies.rb
|
312
311
|
- spec/factories/contacts.rb
|
313
312
|
- spec/lib/hubspot-ruby_spec.rb
|
313
|
+
- spec/lib/hubspot/association_spec.rb
|
314
314
|
- spec/lib/hubspot/blog_spec.rb
|
315
315
|
- spec/lib/hubspot/company_properties_spec.rb
|
316
316
|
- spec/lib/hubspot/company_spec.rb
|