ruby_hubspot_api 0.1.2.1 → 0.2.1.pre.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.github/workflows/ruby.yml +47 -0
- data/.gitignore +1 -0
- data/CHANGELOG.md +36 -1
- data/Gemfile.lock +25 -20
- data/README.md +316 -24
- data/lib/hubspot/api_client.rb +42 -8
- data/lib/hubspot/batch.rb +252 -0
- data/lib/hubspot/config.rb +7 -6
- data/lib/hubspot/paged_batch.rb +56 -0
- data/lib/hubspot/paged_collection.rb +3 -18
- data/lib/hubspot/property.rb +4 -0
- data/lib/hubspot/resource.rb +36 -7
- data/lib/hubspot/version.rb +1 -1
- data/lib/hubspot.rb +15 -0
- data/lib/ruby_hubspot_api.rb +3 -0
- data/lib/support/patches.rb +38 -0
- data/ruby_hubspot_api.gemspec +5 -3
- metadata +46 -14
- data/.ruby-version +0 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2ca83fa3cba8c574d585b31a359da74678d405d2
|
4
|
+
data.tar.gz: 151f119e552b17faff4d921cda1ceec62a3fc045
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e2e95c0a9ef1b69ff862c7843bbb100b23d57fe29cfea0d2042a7593dc3760307d48027fc0b54a6ae05bd39c4721db7603e04a7b16a5ec51b50a1becc436fdc1
|
7
|
+
data.tar.gz: 9dd953ca1946b3f9c3f1d0616f377a330f7e894f6a0f1a1aa6e98fde137015b6c39148dec58437c5cf027d89b9e096dbeb36b144a368ed8f1e61aa2a673305d7
|
@@ -0,0 +1,47 @@
|
|
1
|
+
# This workflow uses actions that are not certified by GitHub.
|
2
|
+
# They are provided by a third-party and are governed by
|
3
|
+
# separate terms of service, privacy policy, and support
|
4
|
+
# documentation.
|
5
|
+
# This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
|
6
|
+
# For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
|
7
|
+
|
8
|
+
name: Ruby
|
9
|
+
|
10
|
+
on:
|
11
|
+
push:
|
12
|
+
branches: [ "main" ]
|
13
|
+
pull_request:
|
14
|
+
branches: [ "main" ]
|
15
|
+
|
16
|
+
permissions:
|
17
|
+
contents: read
|
18
|
+
|
19
|
+
jobs:
|
20
|
+
test:
|
21
|
+
|
22
|
+
runs-on: ubuntu-latest
|
23
|
+
strategy:
|
24
|
+
matrix:
|
25
|
+
ruby-version: ['2.5', '2.6', '2.7', '3.0']
|
26
|
+
|
27
|
+
steps:
|
28
|
+
- uses: actions/checkout@v4
|
29
|
+
|
30
|
+
- name: Set up Ruby
|
31
|
+
uses: ruby/setup-ruby@v1
|
32
|
+
with:
|
33
|
+
ruby-version: ${{ matrix.ruby-version }}
|
34
|
+
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
|
35
|
+
|
36
|
+
- name: Run tests
|
37
|
+
run: HUBSPOT_LOG_LEVEL=FATAL bundle exec rspec
|
38
|
+
|
39
|
+
- name: Upload coverage to Codecov
|
40
|
+
run: bash <(curl -s https://codecov.io/bash)
|
41
|
+
env:
|
42
|
+
CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
|
43
|
+
|
44
|
+
- name: Upload coverage to Codacy
|
45
|
+
run: bash <(curl -Ls https://coverage.codacy.com/get.sh)
|
46
|
+
env:
|
47
|
+
CODACY_PROJECT_TOKEN: ${{ secrets.CODACY_PROJECT_TOKEN }}
|
data/.gitignore
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,29 @@
|
|
1
|
+
## v.0.2.0
|
1
2
|
|
2
|
-
|
3
|
+
- Get the development dependencies right!
|
4
|
+
- Bump the version again
|
5
|
+
- describe find_by method
|
6
|
+
- update lock
|
7
|
+
- batch :sparkle: upsert spec
|
8
|
+
- Borrowing Object#blank? method cos it actually really helps...
|
9
|
+
- batch implemntation
|
10
|
+
- logger.debug the post body and response body
|
11
|
+
- Adds a changes? Method on resource
|
12
|
+
- Adds instance method resource_name on resource
|
13
|
+
- Ensure keys are stringified
|
14
|
+
- Add all end points to the batch spec
|
15
|
+
- Adds create and archive methods to batches
|
16
|
+
- Tidy up resource code
|
17
|
+
- Cover the previously nocov'd code
|
18
|
+
- Add api client logging spec
|
19
|
+
- add configurable timeouts to requests
|
20
|
+
- Move rate limit handling to the client
|
21
|
+
- Simplify mocked responses in batch spec
|
22
|
+
- Adds PagedBatch as pager for batch/read request
|
23
|
+
- Update the Readme to add Batch operations
|
24
|
+
- #5 batch_updating
|
25
|
+
|
26
|
+
## v0.1.2
|
3
27
|
|
4
28
|
- initial setup
|
5
29
|
- Setup the configuration block
|
@@ -46,6 +70,17 @@
|
|
46
70
|
- adds the version numbers to the gemspec
|
47
71
|
- Fix dependencies
|
48
72
|
- bump version
|
73
|
+
- Fix the Readme
|
74
|
+
- Sure the search param is values where passing an array
|
75
|
+
- update changelog and Gemfile.lock
|
76
|
+
- bump version
|
77
|
+
|
78
|
+
## v0.1.1
|
79
|
+
|
80
|
+
- Fix the Readme
|
81
|
+
- Sure the search param is values where passing an array
|
82
|
+
- update changelog and Gemfile.lock
|
83
|
+
- bump version
|
49
84
|
|
50
85
|
## v0.1.0
|
51
86
|
|
data/Gemfile.lock
CHANGED
@@ -1,30 +1,24 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
ruby_hubspot_api (0.
|
5
|
-
bundler (>= 2.0)
|
6
|
-
dotenv (>= 2.0)
|
4
|
+
ruby_hubspot_api (0.2.1)
|
7
5
|
httparty (>= 0.1, < 1.0)
|
8
|
-
pry (>= 0.1)
|
9
|
-
pry-byebug (>= 3.0)
|
10
|
-
rspec (>= 3.0)
|
11
|
-
simplecov (>= 0.22, < 1.0)
|
12
|
-
vcr (>= 6.0)
|
13
|
-
webmock (>= 3.0)
|
14
6
|
|
15
7
|
GEM
|
16
8
|
remote: https://rubygems.org/
|
17
9
|
specs:
|
18
10
|
addressable (2.8.7)
|
19
11
|
public_suffix (>= 2.0.2, < 7.0)
|
20
|
-
bigdecimal (3.
|
12
|
+
bigdecimal (3.0.2)
|
21
13
|
byebug (11.1.3)
|
14
|
+
codecov (0.6.0)
|
15
|
+
simplecov (>= 0.15, < 0.22)
|
22
16
|
coderay (1.1.3)
|
23
17
|
crack (1.0.0)
|
24
18
|
bigdecimal
|
25
19
|
rexml
|
26
20
|
diff-lcs (1.5.1)
|
27
|
-
docile (1.
|
21
|
+
docile (1.3.5)
|
28
22
|
dotenv (2.8.1)
|
29
23
|
hashdiff (1.1.1)
|
30
24
|
httparty (0.21.0)
|
@@ -33,15 +27,15 @@ GEM
|
|
33
27
|
method_source (1.1.0)
|
34
28
|
mini_mime (1.1.2)
|
35
29
|
multi_xml (0.6.0)
|
36
|
-
pry (0.
|
30
|
+
pry (0.14.2)
|
37
31
|
coderay (~> 1.1)
|
38
32
|
method_source (~> 1.0)
|
39
|
-
pry-byebug (3.
|
33
|
+
pry-byebug (3.8.0)
|
40
34
|
byebug (~> 11.0)
|
41
|
-
pry (~> 0.
|
35
|
+
pry (~> 0.10)
|
42
36
|
public_suffix (4.0.7)
|
43
37
|
rake (13.2.1)
|
44
|
-
rexml (3.
|
38
|
+
rexml (3.2.5)
|
45
39
|
rspec (3.13.0)
|
46
40
|
rspec-core (~> 3.13.0)
|
47
41
|
rspec-expectations (~> 3.13.0)
|
@@ -55,24 +49,35 @@ GEM
|
|
55
49
|
diff-lcs (>= 1.2.0, < 2.0)
|
56
50
|
rspec-support (~> 3.13.0)
|
57
51
|
rspec-support (3.13.1)
|
58
|
-
simplecov (0.
|
52
|
+
simplecov (0.18.5)
|
59
53
|
docile (~> 1.1)
|
60
54
|
simplecov-html (~> 0.11)
|
61
|
-
simplecov_json_formatter (~> 0.1)
|
62
55
|
simplecov-html (0.13.1)
|
63
|
-
|
56
|
+
simplecov-lcov (0.8.0)
|
64
57
|
vcr (6.0.0)
|
65
|
-
webmock (3.
|
58
|
+
webmock (3.18.1)
|
66
59
|
addressable (>= 2.8.0)
|
67
60
|
crack (>= 0.3.2)
|
68
61
|
hashdiff (>= 0.4.0, < 2.0.0)
|
69
62
|
|
70
63
|
PLATFORMS
|
64
|
+
ruby
|
71
65
|
x86_64-darwin-18
|
66
|
+
x86_64-linux
|
72
67
|
|
73
68
|
DEPENDENCIES
|
69
|
+
bundler (>= 2.0, < 2.4.0)
|
70
|
+
codecov
|
71
|
+
dotenv (>= 2.0)
|
72
|
+
pry (>= 0.1)
|
73
|
+
pry-byebug (>= 3.0)
|
74
74
|
rake (>= 11.0, < 14.0)
|
75
|
+
rspec (>= 3.0)
|
75
76
|
ruby_hubspot_api!
|
77
|
+
simplecov
|
78
|
+
simplecov-lcov
|
79
|
+
vcr (>= 6.0)
|
80
|
+
webmock (>= 3.0)
|
76
81
|
|
77
82
|
BUNDLED WITH
|
78
|
-
2.
|
83
|
+
2.2.34
|
data/README.md
CHANGED
@@ -1,8 +1,10 @@
|
|
1
1
|
# Ruby HubSpot API Gem
|
2
2
|
|
3
|
+
[![codecov](https://codecov.io/gh/sensadrome/ruby_hubspot_api/branch/main/graph/badge.svg)](https://codecov.io/gh/sensadrome/ruby_hubspot_api) [![Codacy Badge](https://app.codacy.com/project/badge/Grade/504ca01245ee4928b6ed0b13801259e7)](https://app.codacy.com/gh/sensadrome/ruby_hubspot_api/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade)
|
4
|
+
|
3
5
|
This gem was largely inspired by [hubspot-api-ruby](https://github.com/captaincontrat/hubspot-api-ruby) which, in turn, was inspired by the [hubspot-ruby](https://github.com/HubspotCommunity/hubspot-ruby) community gem. I wanted to use version 3 of the api and simplify some parts of the interface
|
4
6
|
|
5
|
-
The Ruby HubSpot API gem is a starting point for building an ORM-like interface to HubSpot's API.
|
7
|
+
The Ruby HubSpot API gem is a starting point for building an ORM-like interface to HubSpot's API.
|
6
8
|
|
7
9
|
## Installation
|
8
10
|
|
@@ -30,23 +32,58 @@ To authenticate API requests, you need a HubSpot access token. First you will ne
|
|
30
32
|
|
31
33
|
You can configure the gem by adding this code to your initializer (for Rails) or to your startup configuration (in any other environment):
|
32
34
|
|
35
|
+
##### Minimum configuration
|
36
|
+
|
37
|
+
```ruby
|
38
|
+
Hubspot.configure do |config|
|
39
|
+
config.access_token = 'your_access_token'
|
40
|
+
end
|
41
|
+
```
|
42
|
+
|
43
|
+
##### Full possible configuration
|
44
|
+
|
33
45
|
```ruby
|
34
46
|
Hubspot.configure do |config|
|
35
47
|
config.access_token = 'your_access_token'
|
48
|
+
config.portal_id = 'your_portal_id'
|
49
|
+
config.client_secret = 'your_client_secret'
|
50
|
+
config.logger = Rails.logger
|
51
|
+
config.log_level = 'info' # debug,info,warn,error,fatal
|
52
|
+
config.timeout = 10 # seconds to timeout all api requests
|
53
|
+
config.open_timeout = 5 # open_timeout seconds
|
54
|
+
config.read_timeout = 5 # read_timeout seconds
|
55
|
+
config.write_timeout = 5 # swrite_timeout econds (ruby >= 2.6)
|
36
56
|
end
|
37
57
|
```
|
38
58
|
|
39
59
|
This configuration ensures that your API requests are authenticated using your HubSpot access token.
|
40
60
|
|
41
|
-
## Working with
|
61
|
+
## Working with Resources
|
42
62
|
|
43
|
-
This gem allows you to interact with
|
63
|
+
This gem allows you to interact with Hubspot resources such as contacts and companies. You can perform operations on individual resources (e.g., creating or updating records) as well as on collections (e.g., listing or searching).
|
44
64
|
|
45
|
-
|
65
|
+
__please note__
|
46
66
|
|
47
|
-
|
67
|
+
> In the Hubspot API contacts, companies etc are referred to as "Objects" (e.g. CRM > Objects > Contacts) so when we use the word "Object" (with a capital O) we will be referring to an object in Hubspot
|
48
68
|
|
49
|
-
|
69
|
+
> In this gem we use the term Resource so as not to accidentally overload Object! When we use the term "Resource" we should be referring to the ruby ORM base class and when we say "resource" we should be referring to an instance of this class (or a class that inherits it)
|
70
|
+
|
71
|
+
### Hubspot::Resource class
|
72
|
+
|
73
|
+
This is the base ORM class for all Hubspot CRM objects. You should not operate on this class but with the following classes each of which inherits from Hubspot::Resource
|
74
|
+
|
75
|
+
```ruby
|
76
|
+
Hubspot::Contact # crm > contacts
|
77
|
+
Hubspot::Company # crm > companies
|
78
|
+
Hubspot::User # hubspot users (also referred to as 'owners')
|
79
|
+
Hubspot::Owner # alias of Hubspot::User if you prefer to use it
|
80
|
+
```
|
81
|
+
|
82
|
+
however you can [add custom objects of your own](#user-content-custom-resources) based on your own custom defined Objects in Hubspot
|
83
|
+
|
84
|
+
### Creating and Saving an Object
|
85
|
+
|
86
|
+
Create and instance of the resource passing a hash of properties. Calling `save` on the instance will persist the object to the HubSpot API, as well as set the id property (which you can then store in your own database for example)
|
50
87
|
|
51
88
|
Example:
|
52
89
|
|
@@ -60,44 +97,96 @@ new_contact.save
|
|
60
97
|
puts "New contact ID: #{new_contact.id}"
|
61
98
|
```
|
62
99
|
|
63
|
-
|
100
|
+
### Retreiving an Object
|
101
|
+
|
102
|
+
If you know the id of the object you can fetch it from the api using the find method
|
103
|
+
|
104
|
+
```ruby
|
105
|
+
contact = Hubspot::Contact.find(1)
|
106
|
+
puts "Contact: #{contact.firstname} #{contact.lastname}"
|
107
|
+
```
|
108
|
+
|
109
|
+
You can also retrieve a single object by using the `find_by` method. Simply specify the property and the value you want to search on:
|
110
|
+
|
111
|
+
```ruby
|
112
|
+
# find by email
|
113
|
+
contact = Hubspot::Contact.find_by('email', 'john.doe@example.org')
|
114
|
+
puts "Contact: #{contact.firstname} #{contact.lastname}"
|
115
|
+
|
116
|
+
#find by internal id (custom field)
|
117
|
+
contact = Hubspot::Contact.find_by('member_id', 123)
|
118
|
+
puts "Contact: #{contact.firstname} #{contact.lastname}"
|
119
|
+
```
|
64
120
|
|
65
|
-
|
121
|
+
### Updating an Existing Object
|
122
|
+
|
123
|
+
To update an existing object, you can either modify the object and call `save`, or use the `update` method specifying the properties you want to update. You can test whether or not the object will need to upload changes to the api by using the changes? method
|
66
124
|
|
67
125
|
Example using `save`:
|
68
126
|
|
69
127
|
```ruby
|
70
128
|
contact = Hubspot::Contact.find(1)
|
129
|
+
contact.changes? # false
|
130
|
+
|
71
131
|
contact.lastname = 'DoeUpdated'
|
132
|
+
contact.changes? # true
|
133
|
+
|
134
|
+
# save the updates to Hubspot
|
72
135
|
contact.save # true
|
136
|
+
contact.changes? # false
|
73
137
|
```
|
74
138
|
|
75
139
|
Example using `update`:
|
76
140
|
|
77
141
|
```ruby
|
78
142
|
contact = Hubspot::Contact.find(1)
|
143
|
+
# save the updates to Hubspot
|
79
144
|
contact.update(lastname: 'DoeUpdated') # true
|
80
145
|
```
|
81
146
|
|
82
|
-
|
147
|
+
If you are able to construct an Object with data stored locally you can save the inital `find` api call, but you will need to construct the persisted object specifying the id and a properties hash (as if it came from the api!)
|
148
|
+
|
149
|
+
Example:
|
150
|
+
|
151
|
+
```ruby
|
152
|
+
local_contact = Contact.find(contact_id)
|
153
|
+
|
154
|
+
hubspot_properties = {
|
155
|
+
firstname: local_contact.first_name,
|
156
|
+
lastname: local_contact.last_name,
|
157
|
+
email: local_contact.email,
|
158
|
+
# ... more properties...
|
159
|
+
}
|
83
160
|
|
84
|
-
|
161
|
+
hubspot_contact = Hubspot::Contact.new(id: contact.hs_object_id, properties: hubspot_properties )
|
162
|
+
hubspot_contact.changes? # false
|
85
163
|
|
86
|
-
|
164
|
+
# update a custom field "last_contacted"
|
165
|
+
# (in the hubspot_contact instance this will be stored in the changes property)
|
166
|
+
hubspot_contact.last_contacted = Time.now.utc.iso8601
|
167
|
+
hubspot_contact.changes? # true
|
168
|
+
|
169
|
+
# persist the change to hubspot
|
170
|
+
hubspot_contact.save #true
|
171
|
+
```
|
172
|
+
|
173
|
+
### Listing Objects
|
174
|
+
|
175
|
+
You can list all objects (such as contacts) using the `list` method, which returns a `PagedCollection`. This collection handles paginated results and is Enumerable, so responds to methods like `each_page`, `each`, and `all`. You can also pass the `page_size` parameter to control the number of records returned per page.
|
87
176
|
|
88
177
|
Example:
|
89
178
|
|
90
179
|
```ruby
|
91
180
|
contacts = Hubspot::Contact.list(page_size: 10)
|
92
181
|
|
93
|
-
# Using each_page to iterate over pages
|
182
|
+
# Using each_page to iterate over pages, there will be up to 10 contacts per page
|
94
183
|
contacts.each_page do |page|
|
95
184
|
page.each do |contact|
|
96
185
|
puts "Contact: #{contact.firstname} #{contact.lastname}"
|
97
186
|
end
|
98
187
|
end
|
99
188
|
|
100
|
-
# Or iterate over all contacts
|
189
|
+
# Or iterate over all contacts and the pagination will be handled transparently (page_size still applies)
|
101
190
|
contacts.each do |contact|
|
102
191
|
puts "Contact: #{contact.firstname} #{contact.lastname}"
|
103
192
|
end
|
@@ -106,23 +195,42 @@ end
|
|
106
195
|
all_contacts = contacts.all
|
107
196
|
```
|
108
197
|
|
109
|
-
#### Retrieving the first n items
|
198
|
+
#### Retrieving the first n items:
|
110
199
|
|
111
|
-
You can
|
200
|
+
As mentioned the list method returns a PagedCollection. You can call `first` on the result to retrieve the first item or a specified number of items:
|
112
201
|
|
113
202
|
```ruby
|
114
|
-
|
203
|
+
contacts_collection = Hubspot::Contact.list
|
115
204
|
|
116
205
|
# Retrieve the first contact
|
117
|
-
first_contact =
|
206
|
+
first_contact = contacts_collection.first
|
118
207
|
|
119
208
|
# Retrieve the first 5 contacts
|
120
|
-
first_five_contacts =
|
209
|
+
first_five_contacts = contacts_collection.first(5)
|
121
210
|
```
|
122
211
|
|
123
212
|
This will automatically set the limits and handle paging for the most efficient API calls while honouring the maximum page count for hubspot resources
|
124
213
|
|
125
|
-
####
|
214
|
+
#### Specifying properties
|
215
|
+
|
216
|
+
By default Hubspot will only send back the [default hubspot properties](https://knowledge.hubspot.com/properties/hubspots-default-contact-properties)
|
217
|
+
|
218
|
+
You can pass an array of properties to be returned as follows:
|
219
|
+
|
220
|
+
Example:
|
221
|
+
|
222
|
+
```ruby
|
223
|
+
# Get the full list of contacts and only return specific properties
|
224
|
+
contacts = Hubspot::Contact.list(
|
225
|
+
properties: ['firstname', 'lastname', 'email', 'mobile', 'custom_property_1']
|
226
|
+
)
|
227
|
+
|
228
|
+
contacts.each do |contact|
|
229
|
+
puts "Name: #{contact.firstname} #{contact.lastname}, Email: #{contact.email}, Mobile: #{contact.mobile} CustomerRef: #{contact.custom_property_1}"
|
230
|
+
end
|
231
|
+
```
|
232
|
+
|
233
|
+
### Searching
|
126
234
|
|
127
235
|
You can search for objects by passing query parameters to the `search` method. HubSpot supports several operators such as `eq`, `gte`, `lt`, and `IN` for filtering.
|
128
236
|
|
@@ -132,15 +240,21 @@ Example:
|
|
132
240
|
# Search for contacts with email containing "hubspot.com"
|
133
241
|
contacts = Hubspot::Contact.search(query: { email_contains: 'hubspot.com' })
|
134
242
|
|
243
|
+
puts "Searching for Hubspot staff in the contacts CRM"
|
244
|
+
puts ""
|
245
|
+
|
135
246
|
contacts.each do |contact|
|
136
|
-
puts "Found: #{contact.email}"
|
247
|
+
puts " Found: #{contact.firstname} #{contact.lastname} (#{contact.email})"
|
137
248
|
end
|
138
249
|
|
139
250
|
# Search for companies with number of employees greater than or equal to 100
|
140
251
|
companies = Hubspot::Company.search(query: { number_of_employees_gte: 100 })
|
141
252
|
|
253
|
+
puts "Searching for medium to large companies"
|
254
|
+
puts ""
|
255
|
+
|
142
256
|
companies.each do |company|
|
143
|
-
puts "Found: #{company.name}
|
257
|
+
puts " Found: #{company.name} (#{company.number_of_employees} employees)"
|
144
258
|
end
|
145
259
|
|
146
260
|
# Search for contacts with email in a specific list (IN operator)
|
@@ -152,15 +266,18 @@ end
|
|
152
266
|
```
|
153
267
|
|
154
268
|
### Available Search Operators:
|
155
|
-
- **
|
269
|
+
- **contains**: contains <string>
|
156
270
|
- **neq**: Not equal to.
|
271
|
+
- **gt**: Greater than.
|
157
272
|
- **gte**: Greater than or equal to.
|
273
|
+
- **lt**: Less than.
|
158
274
|
- **lte**: Less than or equal to.
|
159
275
|
- **IN**: Matches any of the values in an array.
|
160
276
|
|
161
277
|
#### Specifying Properties in Search
|
162
278
|
|
163
|
-
When performing a search, you can also specify which properties to return.
|
279
|
+
When performing a search, you can also specify which properties to return.
|
280
|
+
*NB* If you specify any properties, you will only get those properties back, and the default HubSpot properties will not be included automatically.
|
164
281
|
|
165
282
|
Example:
|
166
283
|
|
@@ -172,10 +289,185 @@ contacts = Hubspot::Contact.search(
|
|
172
289
|
)
|
173
290
|
|
174
291
|
contacts.each do |contact|
|
175
|
-
puts "Name: #{contact.firstname} #{contact.lastname}, Email: #{contact.email}, Mobile: #{contact.mobile}"
|
292
|
+
puts "Name: #{contact.firstname} #{contact.lastname}, Email: #{contact.email}, Mobile: #{contact.mobile} CustomerRef: #{contact.custom_property_1}"
|
293
|
+
end
|
294
|
+
```
|
295
|
+
|
296
|
+
## Working with batches
|
297
|
+
|
298
|
+
### Hubspot::Batch
|
299
|
+
|
300
|
+
The `Hubspot::Batch` class allows you to perform batch operations on HubSpot resources, such as contacts or companies. This includes batch `create`, `read`, `update`, `upsert`, and `archive` operations. Below are examples of how to use these methods.
|
301
|
+
|
302
|
+
#### Batch Create
|
303
|
+
|
304
|
+
To create new resources in bulk, you can use the `create` method.
|
305
|
+
|
306
|
+
In this example, `batch.create` triggers the creation of new contacts. After creation, the batch response will include the new IDs assigned to each object by HubSpot which will be assigned to the resources in the batch
|
307
|
+
|
308
|
+
```ruby
|
309
|
+
contacts = [
|
310
|
+
Hubspot::Contact.new(email: 'new.john@example.com', firstname: 'John', lastname: 'Doe'),
|
311
|
+
Hubspot::Contact.new(email: 'new.jane@example.com', firstname: 'Jane', lastname: 'Doe')
|
312
|
+
]
|
313
|
+
|
314
|
+
batch = Hubspot::Batch.new(contacts)
|
315
|
+
batch.create
|
316
|
+
|
317
|
+
batch.resources.each do |contact|
|
318
|
+
hubspot_id = contact.id
|
319
|
+
# store hubspot_id against a contact....
|
176
320
|
end
|
177
321
|
```
|
178
322
|
|
323
|
+
|
324
|
+
#### Batch Read
|
325
|
+
|
326
|
+
To read a batch of Objects by their internal hubspot id or by another uniq property you can use the `read` method. You will need to pass the class of the resource, an array of ids and optionally an id_property.
|
327
|
+
|
328
|
+
For simplicity you can also use the `batch_read` method of the corresponding class (e.g. Hubspot::Contacts, Hubspot::Company etc) passing an array of ids and optionally an id_property (defaults to 'id'). This method will return a Hubspot::Batch and the results will be in "resources"
|
329
|
+
|
330
|
+
Example using `read` along with the Hubspot id of several companies...
|
331
|
+
|
332
|
+
```ruby
|
333
|
+
# Grab an array of hubspot company ids to read from the api...
|
334
|
+
company_ids = my_companies.collect(&:hubspot_id).compact
|
335
|
+
|
336
|
+
# this will grab all the results from the api handling paging automagically
|
337
|
+
batch = Hubspot::Batch.read(Hubspot::Company, company_ids)
|
338
|
+
companies = batch.resources
|
339
|
+
|
340
|
+
# Or using the domain field
|
341
|
+
# Grab an array of company domains
|
342
|
+
company_domains = my_companies.collect(&:domain_name).compact
|
343
|
+
|
344
|
+
# calls /crm/v3/objects/companies/batch/read
|
345
|
+
batch = Hubspot::Batch.read(Hubspot::Company, company_domains, id_property: 'domain')
|
346
|
+
companies = batch.resources
|
347
|
+
```
|
348
|
+
|
349
|
+
Example of reading contacts by email and the helper method `batch_read`
|
350
|
+
By using this method you can page through the results as needed or collect them
|
351
|
+
|
352
|
+
```ruby
|
353
|
+
email_addresses = my_selected_contacts.collect(&:email).compact
|
354
|
+
|
355
|
+
batch = Hubspot::Contact.batch_read(email_addresses, id_property: 'email')
|
356
|
+
|
357
|
+
batch.each_page do |contacts|
|
358
|
+
contacts.each do |contact|
|
359
|
+
# persist some data locally
|
360
|
+
update_local_contact_from_hubspot(contact)
|
361
|
+
end
|
362
|
+
# stop the api calls if a condition is met
|
363
|
+
# break if <condition>
|
364
|
+
end
|
365
|
+
```
|
366
|
+
|
367
|
+
Finally there is another helper method `batch_read_all` on any Hubspot::Resource class (Hubspot::Contact, Hubspot::Company, Hubspot::User etc) which will read all of the resources and return a HubSpot::Batch (with all of the resources).
|
368
|
+
|
369
|
+
You can then update the resources and call `update` on the batch.... see below
|
370
|
+
|
371
|
+
#### Batch Update
|
372
|
+
|
373
|
+
For updating existing resources in bulk, you can use the `update` method. If you want to locally create an object without calling the API you specify the id and pass any properties in the 'properties' hash (this is how the objects are returned from Hubspot)
|
374
|
+
|
375
|
+
```ruby
|
376
|
+
contacts = [
|
377
|
+
Hubspot::Contact.new(id: 1, properties: { firstname: 'John', lastname: 'Doe' }),
|
378
|
+
Hubspot::Contact.new(id: 2, properties: { firstname: 'Jane', lastname: 'Doe' })
|
379
|
+
]
|
380
|
+
|
381
|
+
# make a changes to each contact
|
382
|
+
contacts.each { |contact| contact.last_contacted = Time.now.utc.iso8601 }
|
383
|
+
|
384
|
+
batch = Hubspot::Batch.new(contacts)
|
385
|
+
batch.update
|
386
|
+
```
|
387
|
+
|
388
|
+
Example using a batch
|
389
|
+
```ruby
|
390
|
+
user_ids = my_selected_users.collect(&:hubspot_id).compact
|
391
|
+
batch = Hubspot::User.batch_read(user_ids)
|
392
|
+
|
393
|
+
batch.resources.each do |hubspot_user|
|
394
|
+
# some logic or method to set any new/changed properties on hubspot_user
|
395
|
+
hubspot_user.sales_total = fetch_sales_total(user.email)
|
396
|
+
end
|
397
|
+
|
398
|
+
# now we have a batch with changed resources we can update the batch
|
399
|
+
batch.update # true
|
400
|
+
```
|
401
|
+
|
402
|
+
#### Batch Upsert
|
403
|
+
|
404
|
+
The `upsert` method allows you to insert new records or update existing ones. You’ll need to specify an `id_property` (like `email`) to uniquely identify records
|
405
|
+
|
406
|
+
```ruby
|
407
|
+
contacts = [
|
408
|
+
Hubspot::Contact.new(email: 'new.john@example.com', firstname: 'John', lastname: 'Doe'),
|
409
|
+
Hubspot::Contact.new(email: 'new.jane@example.com', firstname: 'Jane', lastname: 'Doe')
|
410
|
+
]
|
411
|
+
|
412
|
+
batch = Hubspot::Batch.new(contacts, id_property: 'email')
|
413
|
+
batch.upsert
|
414
|
+
```
|
415
|
+
|
416
|
+
In this example, if a contact with the given email already exists in HubSpot, it will be updated. If it doesn't, a new contact will be created.
|
417
|
+
|
418
|
+
#### Batch Archive
|
419
|
+
|
420
|
+
To archive objects in bulk, you can use the `archive` method. This removes the objects from HubSpot.
|
421
|
+
|
422
|
+
```ruby
|
423
|
+
contacts = Hubspot::Contact.search(query: { email_contains: 'hubspot.com' }).all
|
424
|
+
|
425
|
+
batch = Hubspot::Batch.new(contacts)
|
426
|
+
batch.archive
|
427
|
+
```
|
428
|
+
|
429
|
+
The `archive` method sends a batch request to HubSpot to archive the objects. If any of the objects fail to be archived, you can check for partial success using the `partial_success?` method.
|
430
|
+
|
431
|
+
#### Error Handling and Success Checks
|
432
|
+
|
433
|
+
You can check whether the batch operation was entirely successful, partially successful, or if any failures occurred:
|
434
|
+
|
435
|
+
```ruby
|
436
|
+
if batch.all_successful?
|
437
|
+
puts "All resources were successfully processed."
|
438
|
+
elsif batch.partial_success?
|
439
|
+
puts "Some resources were successfully processed, but others failed."
|
440
|
+
else
|
441
|
+
puts "The batch operation failed."
|
442
|
+
end
|
443
|
+
```
|
444
|
+
|
445
|
+
## Custom Resources
|
446
|
+
|
447
|
+
If you have defined custom objects you can easily add them by creating a class that inherits from `Hubspot::Resource`
|
448
|
+
|
449
|
+
```ruby
|
450
|
+
# lib/hubspot/projects.rb
|
451
|
+
|
452
|
+
require 'ruby_hubspot_api' # if not required by bundler already...
|
453
|
+
|
454
|
+
module Hubspot
|
455
|
+
class Project < Resource
|
456
|
+
|
457
|
+
# resource_name (part of the url in the api) will default
|
458
|
+
# to a simple plural of the class name - in this case 'projects'
|
459
|
+
# if the url for your custom object is different you can override it
|
460
|
+
|
461
|
+
def resource_name
|
462
|
+
'company_projects'
|
463
|
+
end
|
464
|
+
end
|
465
|
+
end
|
466
|
+
|
467
|
+
projects = Hubspot::Projects.search(query: { status_in: ['upcoming', 'active', 'overrun'] }).all
|
468
|
+
|
469
|
+
```
|
470
|
+
|
179
471
|
## Contributing
|
180
472
|
|
181
473
|
There is much to do (including writing a TODO list, or at least adding issues in github!) but this should provide a solid start
|