hubspot-ruby 0.2.0 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +11 -0
- data/hubspot-ruby.gemspec +2 -1
- data/lib/hubspot/connection.rb +1 -1
- data/lib/hubspot/contact.rb +36 -14
- data/lib/hubspot/deal.rb +12 -0
- data/lib/tasks/properties.rake +49 -0
- data/spec/lib/hubspot/contact_spec.rb +32 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9eded4f33457d91f6b5feb303f5bd7524223d8ab
|
4
|
+
data.tar.gz: 84a6116a408d19dd093ebd40d0fae9d535e5e078
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f3359f3aeef879c07870f8d6537f99c7d96117224e13ebbb6a1a87032aaa2ba212f5862dcbde1795cf2feefb01850d2b3879dc48e96672f55bab8e1c43be3e6a
|
7
|
+
data.tar.gz: 350179721426bffbd0260655aa98485b855591042dc8edffb4e4139b70390bad24512d67a27af1de0313741926b782b3133cd822f1df7164677f223a176d1929
|
data/README.md
CHANGED
@@ -37,6 +37,12 @@ Here's what you can do for now:
|
|
37
37
|
Hubspot::Contact.create!("email@address.com", {firstname: "First", lastname: "Last"})
|
38
38
|
```
|
39
39
|
|
40
|
+
#### In batches
|
41
|
+
|
42
|
+
```ruby
|
43
|
+
Hubspot::Contact.create_or_update!([{email: 'smith@example.com', firstname: 'First', lastname: 'Last'}])
|
44
|
+
```
|
45
|
+
|
40
46
|
### Find a contact
|
41
47
|
|
42
48
|
These methods will return a `Hubspot::Contact` object if successful, `nil` otherwise:
|
@@ -54,6 +60,11 @@ Given an instance of `Hubspot::Contact`, update its attributes with:
|
|
54
60
|
contact.update!({firstname: "First", lastname: "Last"})
|
55
61
|
```
|
56
62
|
|
63
|
+
#### In batches
|
64
|
+
|
65
|
+
```ruby
|
66
|
+
Hubspot::Contact.create_or_update!([{vid: '12345', firstname: 'First', lastname: 'Last'}])
|
67
|
+
```
|
57
68
|
## Contributing to hubspot-ruby
|
58
69
|
|
59
70
|
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
|
data/hubspot-ruby.gemspec
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "hubspot-ruby"
|
3
|
-
s.version = "0.2.
|
3
|
+
s.version = "0.2.1"
|
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
7
|
s.files = [".rspec", "Gemfile", "Gemfile.lock", "Guardfile", "LICENSE.txt", "README.md", "RELEASING.md", "Rakefile", "hubspot-ruby.gemspec"]
|
8
8
|
s.files += Dir["lib/**/*.rb"]
|
9
|
+
s.files += Dir["lib/**/*.rake"]
|
9
10
|
s.files += Dir["spec/**/*.rb"]
|
10
11
|
s.homepage = "http://github.com/adimichele/hubspot-ruby"
|
11
12
|
s.summary = "hubspot-ruby is a wrapper for the HubSpot REST API"
|
data/lib/hubspot/connection.rb
CHANGED
data/lib/hubspot/contact.rb
CHANGED
@@ -6,19 +6,20 @@ module Hubspot
|
|
6
6
|
#
|
7
7
|
# TODO: work on all endpoints that can specify contact properties, property mode etc... as params. cf pending specs
|
8
8
|
class Contact
|
9
|
-
CREATE_CONTACT_PATH
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
9
|
+
CREATE_CONTACT_PATH = '/contacts/v1/contact'
|
10
|
+
BATCH_CREATE_OR_UPDATE_PATH = '/contacts/v1/contact/batch/'
|
11
|
+
GET_CONTACT_BY_EMAIL_PATH = '/contacts/v1/contact/email/:contact_email/profile'
|
12
|
+
GET_CONTACTS_BY_EMAIL_PATH = '/contacts/v1/contact/emails/batch'
|
13
|
+
GET_CONTACT_BY_ID_PATH = '/contacts/v1/contact/vid/:contact_id/profile'
|
14
|
+
CONTACT_BATCH_PATH = '/contacts/v1/contact/vids/batch'
|
15
|
+
GET_CONTACT_BY_UTK_PATH = '/contacts/v1/contact/utk/:contact_utk/profile'
|
16
|
+
GET_CONTACTS_BY_UTK_PATH = '/contacts/v1/contact/utks/batch'
|
17
|
+
UPDATE_CONTACT_PATH = '/contacts/v1/contact/vid/:contact_id/profile'
|
18
|
+
DESTROY_CONTACT_PATH = '/contacts/v1/contact/vid/:contact_id'
|
19
|
+
CONTACTS_PATH = '/contacts/v1/lists/all/contacts/all'
|
20
|
+
RECENT_CONTACTS_PATH = '/contacts/v1/lists/recently_updated/contacts/recent'
|
21
|
+
CREATE_OR_UPDATE_PATH = '/contacts/v1/contact/createOrUpdate/email/:contact_email'
|
22
|
+
QUERY_PATH = '/contacts/v1/search/query'
|
22
23
|
|
23
24
|
class << self
|
24
25
|
# {https://developers.hubspot.com/docs/methods/contacts/create_contact}
|
@@ -47,7 +48,6 @@ module Hubspot
|
|
47
48
|
# TODO: create or update a contact
|
48
49
|
# PATH /contacts/v1/contact/createOrUpdate/email/:contact_email
|
49
50
|
# API endpoint: https://developers.hubspot.com/docs/methods/contacts/create_or_update
|
50
|
-
# + batch mode: https://developers.hubspot.com/docs/methods/contacts/batch_create_or_update
|
51
51
|
def createOrUpdate(email, params={})
|
52
52
|
post_data = {properties: Hubspot::Utils.hash_to_properties(params.stringify_keys)}
|
53
53
|
response = Hubspot::Connection.post_json(CREATE_OR_UPDATE_PATH, params: { contact_email: email }, body: post_data )
|
@@ -56,6 +56,28 @@ module Hubspot
|
|
56
56
|
contact
|
57
57
|
end
|
58
58
|
|
59
|
+
# NOTE: Performance is best when calls are limited to 100 or fewer contacts
|
60
|
+
# {https://developers.hubspot.com/docs/methods/contacts/batch_create_or_update}
|
61
|
+
def create_or_update!(contacts)
|
62
|
+
query = contacts.map do |ch|
|
63
|
+
contact_hash = ch.with_indifferent_access
|
64
|
+
contact_param = {
|
65
|
+
properties: Hubspot::Utils.hash_to_properties(contact_hash.except(:vid))
|
66
|
+
}
|
67
|
+
if contact_hash[:vid]
|
68
|
+
contact_param.merge!(vid: contact_hash[:vid])
|
69
|
+
elsif contact_hash[:email]
|
70
|
+
contact_param.merge!(email: contact_hash[:email])
|
71
|
+
else
|
72
|
+
raise Hubspot::InvalidParams, 'expecting vid or email for contact'
|
73
|
+
end
|
74
|
+
contact_param
|
75
|
+
end
|
76
|
+
Hubspot::Connection.post_json(BATCH_CREATE_OR_UPDATE_PATH,
|
77
|
+
params: {},
|
78
|
+
body: query)
|
79
|
+
end
|
80
|
+
|
59
81
|
# NOTE: problem with batch api endpoint
|
60
82
|
# {https://developers.hubspot.com/docs/methods/contacts/get_contact}
|
61
83
|
# {https://developers.hubspot.com/docs/methods/contacts/get_batch_by_vid}
|
data/lib/hubspot/deal.rb
CHANGED
@@ -11,6 +11,7 @@ module Hubspot
|
|
11
11
|
DEAL_PATH = "/deals/v1/deal/:deal_id"
|
12
12
|
RECENT_UPDATED_PATH = "/deals/v1/deal/recent/modified"
|
13
13
|
UPDATE_DEAL_PATH = '/deals/v1/deal/:deal_id'
|
14
|
+
ASSOCIATE_DEAL_PATH = '/deals/v1/deal/:deal_id/associations/:OBJECTTYPE?id=:objectId'
|
14
15
|
|
15
16
|
attr_reader :properties
|
16
17
|
attr_reader :portal_id
|
@@ -36,6 +37,17 @@ module Hubspot
|
|
36
37
|
new(response)
|
37
38
|
end
|
38
39
|
|
40
|
+
# Associate a deal with a contact or company
|
41
|
+
# {http://developers.hubspot.com/docs/methods/deals/associate_deal}
|
42
|
+
# Usage
|
43
|
+
# Hubspot::Deal.associate!(45146940, [], [52])
|
44
|
+
def associate!(deal_id, company_ids=[], vids=[])
|
45
|
+
objecttype = company_ids.any? ? 'COMPANY' : 'CONTACT'
|
46
|
+
object_ids = (company_ids.any? ? company_ids : vids).join('&id=')
|
47
|
+
Hubspot::Connection.put_json(ASSOCIATE_DEAL_PATH, params: { deal_id: deal_id, OBJECTTYPE: objecttype, objectId: object_ids}, body: {})
|
48
|
+
end
|
49
|
+
|
50
|
+
|
39
51
|
def find(deal_id)
|
40
52
|
response = Hubspot::Connection.get_json(DEAL_PATH, { deal_id: deal_id })
|
41
53
|
new(response)
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'hubspot-ruby'
|
2
|
+
|
3
|
+
namespace :hubspot do
|
4
|
+
desc 'Dump properties to file'
|
5
|
+
task :dump_properties, [:kind, :file, :hapikey, :include, :exclude] do |_, args|
|
6
|
+
hapikey = args[:hapikey] || ENV['HUBSPOT_API_KEY']
|
7
|
+
kind = args[:kind]
|
8
|
+
unless %w(contact deal).include?(kind)
|
9
|
+
raise ArgumentError, ':kind must be either "contact" or "deal"'
|
10
|
+
end
|
11
|
+
klass = kind == 'contact' ? Hubspot::ContactProperties : Hubspot::DealProperties
|
12
|
+
props = Hubspot::Utils::dump_properties(klass, hapikey, build_filter(args))
|
13
|
+
if args[:file].blank?
|
14
|
+
puts JSON.pretty_generate(props)
|
15
|
+
else
|
16
|
+
File.open(args[:file], 'w') do |f|
|
17
|
+
f.write(JSON.pretty_generate(props))
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
desc 'Restore properties from file'
|
23
|
+
task :restore_properties, [:kind, :file, :hapikey, :dry_run] do |_, args|
|
24
|
+
hapikey = args[:hapikey] || ENV['HUBSPOT_API_KEY']
|
25
|
+
if args[:file].blank?
|
26
|
+
raise ArgumentError, ':file is a required parameter'
|
27
|
+
end
|
28
|
+
kind = args[:kind]
|
29
|
+
unless %w(contact deal).include?(kind)
|
30
|
+
raise ArgumentError, ':kind must be either "contact" or "deal"'
|
31
|
+
end
|
32
|
+
klass = kind == 'contact' ? Hubspot::ContactProperties : Hubspot::DealProperties
|
33
|
+
file = File.read(args[:file])
|
34
|
+
props = JSON.parse(file)
|
35
|
+
Hubspot::Utils.restore_properties(klass, hapikey, props, args[:dry_run] != 'false')
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def build_filter(args)
|
41
|
+
{ include: val_to_array(args[:include]),
|
42
|
+
exclude: val_to_array(args[:exclude])
|
43
|
+
}
|
44
|
+
end
|
45
|
+
|
46
|
+
def val_to_array(val)
|
47
|
+
val.blank? ? val : val.split(/\W+/)
|
48
|
+
end
|
49
|
+
end
|
@@ -84,6 +84,38 @@ describe Hubspot::Contact do
|
|
84
84
|
end
|
85
85
|
end
|
86
86
|
|
87
|
+
describe '.create_or_update!' do
|
88
|
+
cassette 'create_or_update'
|
89
|
+
let(:existing_contact) do
|
90
|
+
Hubspot::Contact.create!("morpheus@example.com", firstname: 'Morpheus')
|
91
|
+
end
|
92
|
+
before do
|
93
|
+
Hubspot::Contact.create_or_update!(params)
|
94
|
+
end
|
95
|
+
|
96
|
+
let(:params) do
|
97
|
+
[
|
98
|
+
{
|
99
|
+
vid: existing_contact.vid,
|
100
|
+
email: existing_contact.email,
|
101
|
+
firstname: 'Neo'
|
102
|
+
},
|
103
|
+
{
|
104
|
+
email: 'smith@example.com',
|
105
|
+
firstname: 'Smith'
|
106
|
+
}
|
107
|
+
]
|
108
|
+
end
|
109
|
+
|
110
|
+
it 'creates and updates contacts' do
|
111
|
+
contact = Hubspot::Contact.find_by_id existing_contact.vid
|
112
|
+
expect(contact.properties['firstname']).to eql 'Neo'
|
113
|
+
latest_contact_email = Hubspot::Contact.all(recent: true).first.email
|
114
|
+
new_contact = Hubspot::Contact.find_by_email(latest_contact_email)
|
115
|
+
expect(new_contact.properties['firstname']).to eql 'Smith'
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
87
119
|
describe '.find_by_email' do
|
88
120
|
context 'given an uniq email' do
|
89
121
|
cassette 'contact_find_by_email'
|
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.2.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Andrew DiMichele
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2016-
|
11
|
+
date: 2016-11-07 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: activesupport
|
@@ -227,6 +227,7 @@ files:
|
|
227
227
|
- lib/hubspot/railtie.rb
|
228
228
|
- lib/hubspot/topic.rb
|
229
229
|
- lib/hubspot/utils.rb
|
230
|
+
- lib/tasks/properties.rake
|
230
231
|
- spec/lib/hubspot-ruby_spec.rb
|
231
232
|
- spec/lib/hubspot/blog_spec.rb
|
232
233
|
- spec/lib/hubspot/company_properties_spec.rb
|