hubspot-ruby 0.2.0 → 0.2.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 +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
|