hubspot-api-ruby 0.8.1 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +17 -9
- data/hubspot-api-ruby.gemspec +3 -4
- data/lib/hubspot/association.rb +79 -53
- data/lib/hubspot/company.rb +2 -2
- data/lib/hubspot/config.rb +10 -9
- data/lib/hubspot/connection.rb +20 -14
- data/lib/hubspot/contact.rb +5 -1
- data/lib/hubspot/contact_list.rb +0 -7
- data/lib/hubspot/custom_event.rb +25 -0
- data/lib/hubspot/deal.rb +34 -14
- data/lib/hubspot/exceptions.rb +2 -0
- data/lib/hubspot/meeting.rb +44 -0
- data/lib/hubspot/properties.rb +1 -1
- data/lib/hubspot-api-ruby.rb +2 -0
- data/spec/lib/hubspot/association_spec.rb +37 -32
- data/spec/lib/hubspot/blog_spec.rb +8 -14
- data/spec/lib/hubspot/company_properties_spec.rb +8 -11
- data/spec/lib/hubspot/company_spec.rb +5 -6
- data/spec/lib/hubspot/contact_list_spec.rb +76 -53
- data/spec/lib/hubspot/contact_properties_spec.rb +5 -34
- data/spec/lib/hubspot/contact_spec.rb +1 -3
- data/spec/lib/hubspot/custom_event_spec.rb +27 -0
- data/spec/lib/hubspot/deal_pipeline_spec.rb +4 -15
- data/spec/lib/hubspot/deal_properties_spec.rb +11 -58
- data/spec/lib/hubspot/deal_spec.rb +11 -53
- data/spec/lib/hubspot/engagement_spec.rb +20 -31
- data/spec/lib/hubspot/file_spec.rb +5 -30
- data/spec/lib/hubspot/form_spec.rb +36 -33
- data/spec/lib/hubspot/meeting_spec.rb +75 -0
- data/spec/spec_helper.rb +13 -4
- data/spec/support/vcr.rb +3 -6
- metadata +12 -24
- data/spec/lib/hubspot/topic_spec.rb +0 -23
- data/spec/support/tests_helper.rb +0 -17
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: adea84341de555a5a7b9d83e03f8aa1013484015ad17d151f4876e9f2bd02293
|
4
|
+
data.tar.gz: 16380d38efaea5c290d2d3b969e76b7501f81beab80a2bec1b8dee6209c5bc57
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 3ca148e0b2648da567d90d312cf979b1bcf8f840ed56393623d8c4cdb2aa0a7d1fe711721fd0828d5062837765280dc4f39719742cd124313bb9e15d31371e89
|
7
|
+
data.tar.gz: b3f6ac7fd1468a9caf227bd37f7cbe8316328ee88008e0305d891fa7c11478e9161425ababe9eb93416684284e39f2839f468e5667d6e9ce05e96c6c807b617c
|
data/README.md
CHANGED
@@ -1,11 +1,17 @@
|
|
1
1
|
# HubSpot REST API wrappers for ruby
|
2
2
|
|
3
|
-
**This is the master branch and contains unreleased and potentially breaking changes. If you are looking for the most recent stable release you want the [v0-stable branch](https://github.com/adimichele/hubspot-ruby/tree/v0-stable).**
|
4
|
-
|
5
3
|
Wraps the HubSpot REST API for convenient access from ruby applications.
|
6
4
|
|
7
5
|
Documentation for the HubSpot REST API can be found here: https://developers.hubspot.com/docs/endpoints
|
8
6
|
|
7
|
+
## Disclaimer
|
8
|
+
|
9
|
+
This gem is a fork of the unofficial [hubspot-ruby](https://github.com/HubspotCommunity/hubspot-ruby) gem which is unfortunately not maintained anymore.
|
10
|
+
|
11
|
+
The API has evolved quite a bit and while this is not a drop-in replacement you should feel familiar if you come from `hubspot-ruby`.
|
12
|
+
|
13
|
+
This project and the code therein was not created by and is not supported by HubSpot, Inc or any of its affiliates.
|
14
|
+
|
9
15
|
## Setup
|
10
16
|
|
11
17
|
gem install hubspot-api-ruby
|
@@ -141,15 +147,17 @@ By default, the VCR recording mode is set to `:none`, which allows recorded
|
|
141
147
|
requests to be re-played but raises for any new request. This prevents the test
|
142
148
|
suite from issuing unexpected HTTP requests.
|
143
149
|
|
144
|
-
|
145
|
-
environment variable:
|
150
|
+
Some requests require to be done on a live hubspot portal, you can set the `HUBSPOT_HAPI_KEY` environement variable, for example inside a `.env.test` file :
|
146
151
|
|
147
|
-
```
|
148
|
-
|
152
|
+
```
|
153
|
+
HUBSPOT_HAPI_KEY=xxxx
|
149
154
|
```
|
150
155
|
|
151
|
-
|
156
|
+
To add a new test or update a VCR recording, run the test with the `VCR_RECORD_MODE`
|
157
|
+
environment variable, for instance:
|
152
158
|
|
153
|
-
|
159
|
+
```sh
|
160
|
+
VCR_RECORD_MODE=new_episodes bundle exec rspec spec
|
161
|
+
```
|
154
162
|
|
155
|
-
|
163
|
+
[VCR]: https://github.com/vcr/vcr
|
data/hubspot-api-ruby.gemspec
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
Gem::Specification.new do |s|
|
2
2
|
s.name = "hubspot-api-ruby"
|
3
|
-
s.version = "0.
|
3
|
+
s.version = "0.9.0"
|
4
4
|
s.require_paths = ["lib"]
|
5
5
|
s.authors = ["Jonathan"]
|
6
6
|
s.email = ["jonathan@hoggo.com"]
|
@@ -10,10 +10,10 @@ Gem::Specification.new do |s|
|
|
10
10
|
s.files += Dir["lib/**/*.rb"]
|
11
11
|
s.files += Dir["lib/**/*.rake"]
|
12
12
|
s.files += Dir["spec/**/*.rb"]
|
13
|
-
s.homepage = "
|
13
|
+
s.homepage = "https://github.com/captaincontrat/hubspot-api-ruby"
|
14
14
|
s.summary = "hubspot-api-ruby is a wrapper for the HubSpot REST API"
|
15
15
|
s.metadata = {
|
16
|
-
"changelog_uri" => "https://github.com/
|
16
|
+
"changelog_uri" => "https://github.com/captaincontrat/hubspot-api-ruby/blob/master/History.md"
|
17
17
|
}
|
18
18
|
|
19
19
|
s.required_ruby_version = ">= 2.3"
|
@@ -23,7 +23,6 @@ Gem::Specification.new do |s|
|
|
23
23
|
s.add_runtime_dependency "httparty", ">= 0.10"
|
24
24
|
|
25
25
|
# Add development-only dependencies here
|
26
|
-
s.add_development_dependency("appraisal", "~> 2.2")
|
27
26
|
s.add_development_dependency("dotenv")
|
28
27
|
s.add_development_dependency("rake", "~> 11.0")
|
29
28
|
s.add_development_dependency("rspec", "~> 3.8")
|
data/lib/hubspot/association.rb
CHANGED
@@ -1,80 +1,106 @@
|
|
1
1
|
class Hubspot::Association
|
2
|
-
|
3
|
-
|
4
|
-
|
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
|
2
|
+
OBJECT_TARGET_TO_CLASS = {
|
3
|
+
"Contact" => Hubspot::Contact,
|
4
|
+
"Deal" => Hubspot::Deal,
|
5
|
+
"Company" => Hubspot::Company
|
13
6
|
}.freeze
|
14
7
|
|
15
|
-
|
16
|
-
|
17
|
-
|
8
|
+
ASSOCIATION_DEFINITIONS = {
|
9
|
+
"Company" => {
|
10
|
+
"Contact" => 2,
|
11
|
+
"Deal" => 6,
|
12
|
+
"Company" => 13
|
13
|
+
},
|
14
|
+
"Deal" => {
|
15
|
+
"Company" => 5,
|
16
|
+
"Contact" => 3
|
17
|
+
},
|
18
|
+
"Contact" => {
|
19
|
+
"Deal" => 4
|
20
|
+
}
|
21
|
+
}.freeze
|
18
22
|
|
19
23
|
class << self
|
20
|
-
def create(
|
21
|
-
batch_create([{
|
24
|
+
def create(object_type, object_id, to_object_type, to_object_id)
|
25
|
+
batch_create(object_type, to_object_type, [{from_id: object_id, to_id: to_object_id}])
|
22
26
|
end
|
23
27
|
|
24
28
|
# Make multiple associations in a single API call
|
25
|
-
# {https://developers.hubspot.com/docs/
|
29
|
+
# {https://developers.hubspot.com/docs/api/crm/associations}
|
26
30
|
# usage:
|
27
|
-
# Hubspot::Association.batch_create([{
|
28
|
-
def batch_create(associations)
|
29
|
-
|
30
|
-
|
31
|
+
# Hubspot::Association.batch_create("Company", "Contact", [{from_id: 1, to_id: 2}]])
|
32
|
+
def batch_create(from_object_type, to_object_type, associations)
|
33
|
+
definition_id = ASSOCIATION_DEFINITIONS.dig(from_object_type, to_object_type)
|
34
|
+
request = { inputs: associations.map { |assocation| build_create_association_body(assocation, definition_id) } }
|
35
|
+
response = Hubspot::Connection.post_json("/crm/v4/associations/#{from_object_type}/#{to_object_type}/batch/create", params: { no_parse: true }, body: request)
|
36
|
+
return false if response.parsed_response["errors"].present?
|
37
|
+
|
38
|
+
response.success?
|
31
39
|
end
|
32
40
|
|
33
|
-
def delete(
|
34
|
-
batch_delete([{from_id:
|
41
|
+
def delete(object_type, object_id, to_object_type, to_object_id)
|
42
|
+
batch_delete(object_type, to_object_type, [{from_id: object_id, to_id: to_object_id}])
|
35
43
|
end
|
36
44
|
|
37
45
|
# Remove multiple associations in a single API call
|
38
|
-
# {https://developers.hubspot.com/docs/
|
46
|
+
# {https://developers.hubspot.com/docs/api/crm/associations}
|
39
47
|
# usage:
|
40
|
-
# Hubspot::Association.batch_delete([{ from_id: 1, to_id: 2
|
41
|
-
def batch_delete(associations)
|
42
|
-
request =
|
43
|
-
Hubspot::Connection.
|
48
|
+
# Hubspot::Association.batch_delete("Company", "Contact", [{ from_id: 1, to_id: 2}])
|
49
|
+
def batch_delete(from_object_type, to_object_type, associations)
|
50
|
+
request = { inputs: build_delete_associations_body(associations) }
|
51
|
+
Hubspot::Connection.post_json("/crm/v4/associations/#{from_object_type}/#{to_object_type}/batch/archive", params: { no_parse: true }, body: request).success?
|
44
52
|
end
|
45
53
|
|
46
|
-
# Retrieve all associated resources given a source (
|
47
|
-
#
|
48
|
-
#
|
49
|
-
#
|
50
|
-
|
51
|
-
|
52
|
-
|
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?
|
54
|
+
# Retrieve all associated resources given a source (object_type and object_id) and a relation type (to_object_type)
|
55
|
+
# {https://developers.hubspot.com/docs/api/crm/associations}
|
56
|
+
# Warning: it will return at most 1000 objects and make up to 1001 queries
|
57
|
+
# Hubspot::Association.all("Company", 42, "Contact")
|
58
|
+
def all(object_type, object_id, to_object_type)
|
59
|
+
klass = OBJECT_TARGET_TO_CLASS[to_object_type]
|
60
|
+
raise(Hubspot::InvalidParams, 'Object type not supported') unless klass.present?
|
58
61
|
|
59
|
-
|
60
|
-
|
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
|
62
|
+
response = Hubspot::Connection.get_json("/crm/v4/objects/#{object_type}/#{object_id}/associations/#{to_object_type}", {})
|
63
|
+
response['results'].map { |result| klass.find(result["toObjectId"]) }
|
67
64
|
end
|
68
65
|
|
69
66
|
private
|
70
67
|
|
71
|
-
def
|
68
|
+
def build_create_association_body(association, definition_id)
|
72
69
|
{
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
70
|
+
from: {
|
71
|
+
id: association[:from_id]
|
72
|
+
},
|
73
|
+
to: {
|
74
|
+
id: association[:to_id]
|
75
|
+
},
|
76
|
+
types: [
|
77
|
+
{
|
78
|
+
associationCategory: "HUBSPOT_DEFINED",
|
79
|
+
associationTypeId: definition_id
|
80
|
+
}
|
81
|
+
]
|
77
82
|
}
|
78
83
|
end
|
84
|
+
|
85
|
+
def build_delete_associations_body(associations)
|
86
|
+
normalized_associations = associations.inject({}) do |memo, association|
|
87
|
+
memo[association[:from_id]] ||= []
|
88
|
+
memo[association[:from_id]] << association[:to_id]
|
89
|
+
memo
|
90
|
+
end
|
91
|
+
|
92
|
+
normalized_associations.map do |from_id, to_ids|
|
93
|
+
{
|
94
|
+
from: {
|
95
|
+
id: from_id
|
96
|
+
},
|
97
|
+
to: to_ids.map do |to_id|
|
98
|
+
{
|
99
|
+
id: to_id
|
100
|
+
}
|
101
|
+
end
|
102
|
+
}
|
103
|
+
end
|
104
|
+
end
|
79
105
|
end
|
80
106
|
end
|
data/lib/hubspot/company.rb
CHANGED
@@ -78,11 +78,11 @@ class Hubspot::Company < Hubspot::Resource
|
|
78
78
|
end
|
79
79
|
|
80
80
|
def add_contact(id, contact_id)
|
81
|
-
Hubspot::Association.create(id,
|
81
|
+
Hubspot::Association.create("Company", id, "Contact", contact_id)
|
82
82
|
end
|
83
83
|
|
84
84
|
def remove_contact(id, contact_id)
|
85
|
-
Hubspot::Association.delete(id,
|
85
|
+
Hubspot::Association.delete("Company", id, "Contact", contact_id)
|
86
86
|
end
|
87
87
|
|
88
88
|
def batch_update(companies, opts = {})
|
data/lib/hubspot/config.rb
CHANGED
@@ -5,7 +5,7 @@ module Hubspot
|
|
5
5
|
class Config
|
6
6
|
CONFIG_KEYS = [
|
7
7
|
:hapikey, :base_url, :portal_id, :logger, :access_token, :client_id,
|
8
|
-
:client_secret, :redirect_uri, :read_timeout, :open_timeout
|
8
|
+
:client_secret, :redirect_uri, :read_timeout, :open_timeout, :custom_event_prefix
|
9
9
|
]
|
10
10
|
DEFAULT_LOGGER = Logger.new(nil)
|
11
11
|
DEFAULT_BASE_URL = "https://api.hubapi.com".freeze
|
@@ -15,16 +15,17 @@ module Hubspot
|
|
15
15
|
|
16
16
|
def configure(config)
|
17
17
|
config.stringify_keys!
|
18
|
-
@hapikey = config[
|
19
|
-
@base_url = config[
|
20
|
-
@portal_id = config[
|
21
|
-
@logger = config[
|
22
|
-
@access_token = config[
|
23
|
-
@client_id = config[
|
24
|
-
@client_secret = config[
|
25
|
-
@redirect_uri = config[
|
18
|
+
@hapikey = config['hapikey']
|
19
|
+
@base_url = config['base_url'] || DEFAULT_BASE_URL
|
20
|
+
@portal_id = config['portal_id']
|
21
|
+
@logger = config['logger'] || DEFAULT_LOGGER
|
22
|
+
@access_token = config['access_token']
|
23
|
+
@client_id = config['client_id'] if config['client_id'].present?
|
24
|
+
@client_secret = config['client_secret'] if config['client_secret'].present?
|
25
|
+
@redirect_uri = config['redirect_uri'] if config['redirect_uri'].present?
|
26
26
|
@read_timeout = config['read_timeout'] || config['timeout']
|
27
27
|
@open_timeout = config['open_timeout'] || config['timeout']
|
28
|
+
@custom_event_prefix = config['custom_event_prefix']
|
28
29
|
|
29
30
|
unless authentication_uncertain?
|
30
31
|
raise Hubspot::ConfigurationError.new("You must provide either an access_token or an hapikey")
|
data/lib/hubspot/connection.rb
CHANGED
@@ -7,7 +7,7 @@ module Hubspot
|
|
7
7
|
url = generate_url(path, opts)
|
8
8
|
response = get(url, format: :json, read_timeout: read_timeout(opts), open_timeout: open_timeout(opts))
|
9
9
|
log_request_and_response url, response
|
10
|
-
handle_response(response)
|
10
|
+
handle_response(response).parsed_response
|
11
11
|
end
|
12
12
|
|
13
13
|
def post_json(path, opts)
|
@@ -24,9 +24,9 @@ module Hubspot
|
|
24
24
|
)
|
25
25
|
|
26
26
|
log_request_and_response url, response, opts[:body]
|
27
|
-
|
28
|
-
|
29
|
-
|
27
|
+
handle_response(response).yield_self do |r|
|
28
|
+
no_parse ? r : r.parsed_response
|
29
|
+
end
|
30
30
|
end
|
31
31
|
|
32
32
|
def put_json(path, options)
|
@@ -43,17 +43,16 @@ module Hubspot
|
|
43
43
|
)
|
44
44
|
|
45
45
|
log_request_and_response(url, response, options[:body])
|
46
|
-
|
47
|
-
|
48
|
-
|
46
|
+
handle_response(response).yield_self do |r|
|
47
|
+
no_parse ? r : r.parsed_response
|
48
|
+
end
|
49
49
|
end
|
50
50
|
|
51
51
|
def delete_json(path, opts)
|
52
52
|
url = generate_url(path, opts)
|
53
53
|
response = delete(url, format: :json, read_timeout: read_timeout(opts), open_timeout: open_timeout(opts))
|
54
54
|
log_request_and_response url, response, opts[:body]
|
55
|
-
|
56
|
-
response
|
55
|
+
handle_response(response)
|
57
56
|
end
|
58
57
|
|
59
58
|
protected
|
@@ -67,11 +66,10 @@ module Hubspot
|
|
67
66
|
end
|
68
67
|
|
69
68
|
def handle_response(response)
|
70
|
-
if response.success?
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
end
|
69
|
+
return response if response.success?
|
70
|
+
|
71
|
+
raise(Hubspot::NotFoundError.new(response)) if response.not_found?
|
72
|
+
raise(Hubspot::RequestError.new(response))
|
75
73
|
end
|
76
74
|
|
77
75
|
def log_request_and_response(uri, response, body=nil)
|
@@ -149,4 +147,12 @@ module Hubspot
|
|
149
147
|
get(url, body: opts[:body], headers: opts[:headers])
|
150
148
|
end
|
151
149
|
end
|
150
|
+
|
151
|
+
class CustomEventConnection < Connection
|
152
|
+
def self.trigger(path, opts)
|
153
|
+
url = generate_url(path, opts[:params], { hapikey: true })
|
154
|
+
headers = (opts[:headers] || {}).merge('content-type': 'application/json')
|
155
|
+
post(url, body: opts[:body].to_json, headers: headers)
|
156
|
+
end
|
157
|
+
end
|
152
158
|
end
|
data/lib/hubspot/contact.rb
CHANGED
@@ -12,7 +12,6 @@ class Hubspot::Contact < Hubspot::Resource
|
|
12
12
|
MERGE_PATH = '/contacts/v1/contact/merge-vids/:id/'
|
13
13
|
SEARCH_PATH = '/contacts/v1/search/query'
|
14
14
|
UPDATE_PATH = '/contacts/v1/contact/vid/:id/profile'
|
15
|
-
UPDATE_PATH = '/contacts/v1/contact/vid/:id/profile'
|
16
15
|
BATCH_UPDATE_PATH = '/contacts/v1/contact/batch'
|
17
16
|
|
18
17
|
class << self
|
@@ -28,6 +27,11 @@ class Hubspot::Contact < Hubspot::Resource
|
|
28
27
|
end
|
29
28
|
end
|
30
29
|
|
30
|
+
def find_by_vid(vid)
|
31
|
+
response = Hubspot::Connection.get_json(FIND_PATH, id: vid)
|
32
|
+
from_result(response)
|
33
|
+
end
|
34
|
+
|
31
35
|
def find_by_email(email)
|
32
36
|
response = Hubspot::Connection.get_json(FIND_BY_EMAIL_PATH, email: email)
|
33
37
|
from_result(response)
|
data/lib/hubspot/contact_list.rb
CHANGED
@@ -10,7 +10,6 @@ module Hubspot
|
|
10
10
|
RECENT_CONTACTS_PATH = LIST_PATH + '/contacts/recent'
|
11
11
|
ADD_CONTACT_PATH = LIST_PATH + '/add'
|
12
12
|
REMOVE_CONTACT_PATH = LIST_PATH + '/remove'
|
13
|
-
REFRESH_PATH = LIST_PATH + '/refresh'
|
14
13
|
|
15
14
|
class << self
|
16
15
|
# {http://developers.hubspot.com/docs/methods/lists/create_list}
|
@@ -92,12 +91,6 @@ module Hubspot
|
|
92
91
|
end
|
93
92
|
end
|
94
93
|
|
95
|
-
# {http://developers.hubspot.com/docs/methods/lists/refresh_list}
|
96
|
-
def refresh
|
97
|
-
response = Hubspot::Connection.post_json(REFRESH_PATH, params: { list_id: @id, no_parse: true }, body: {})
|
98
|
-
response.code == 204
|
99
|
-
end
|
100
|
-
|
101
94
|
# {http://developers.hubspot.com/docs/methods/lists/add_contact_to_list}
|
102
95
|
def add(contacts)
|
103
96
|
contact_ids = [contacts].flatten.uniq.compact.map(&:id)
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'hubspot/utils'
|
2
|
+
|
3
|
+
module Hubspot
|
4
|
+
#
|
5
|
+
# HubSpot Custom Behavioral Events HTTP API
|
6
|
+
#
|
7
|
+
# {https://developers.hubspot.com/docs/api/analytics/events}
|
8
|
+
#
|
9
|
+
class CustomEvent
|
10
|
+
POST_EVENT_PATH = '/events/v3/send'
|
11
|
+
|
12
|
+
class << self
|
13
|
+
def trigger(event_name, email, properties, options = {})
|
14
|
+
options[:params] ||= {}
|
15
|
+
options[:body] ||= {}
|
16
|
+
options[:body].merge!(
|
17
|
+
eventName: "#{Hubspot::Config.custom_event_prefix}_#{event_name}",
|
18
|
+
email: email,
|
19
|
+
properties: properties
|
20
|
+
)
|
21
|
+
Hubspot::CustomEventConnection.trigger(POST_EVENT_PATH, options).success?
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/hubspot/deal.rb
CHANGED
@@ -64,13 +64,23 @@ module Hubspot
|
|
64
64
|
# Usage
|
65
65
|
# Hubspot::Deal.associate!(45146940, [32], [52])
|
66
66
|
def associate!(deal_id, company_ids=[], vids=[])
|
67
|
-
associations = company_ids.map do |id|
|
68
|
-
{ from_id: deal_id, to_id: id
|
67
|
+
company_associations = associations = company_ids.map do |id|
|
68
|
+
{ from_id: deal_id, to_id: id }
|
69
69
|
end
|
70
|
-
|
71
|
-
|
70
|
+
|
71
|
+
contact_associations = vids.map do |id|
|
72
|
+
{ from_id: deal_id, to_id: id}
|
73
|
+
end
|
74
|
+
|
75
|
+
results = []
|
76
|
+
if company_associations.any?
|
77
|
+
results << HubSpot::Association.batch_create("Deal", "Company", company_associations)
|
72
78
|
end
|
73
|
-
|
79
|
+
if contact_associations.any?
|
80
|
+
results << HubSpot::Association.batch_create("Deal", "Contact", contact_associations)
|
81
|
+
end
|
82
|
+
|
83
|
+
results.all?
|
74
84
|
end
|
75
85
|
|
76
86
|
# Didssociate a deal with a contact or company
|
@@ -78,13 +88,23 @@ module Hubspot
|
|
78
88
|
# Usage
|
79
89
|
# Hubspot::Deal.dissociate!(45146940, [32], [52])
|
80
90
|
def dissociate!(deal_id, company_ids=[], vids=[])
|
81
|
-
|
82
|
-
{ from_id: deal_id, to_id: id
|
91
|
+
company_associations = company_ids.map do |id|
|
92
|
+
{ from_id: deal_id, to_id: id }
|
83
93
|
end
|
84
|
-
|
85
|
-
|
94
|
+
|
95
|
+
contact_associations = vids.map do |id|
|
96
|
+
{ from_id: deal_id, to_id: id }
|
97
|
+
end
|
98
|
+
|
99
|
+
results = []
|
100
|
+
if company_associations.any?
|
101
|
+
results << HubSpot::Association.batch_delete("Deal", "Company", company_associations)
|
86
102
|
end
|
87
|
-
|
103
|
+
if contact_associations.any?
|
104
|
+
results << HubSpot::Association.batch_delete("Deal", "Contact", contact_associations)
|
105
|
+
end
|
106
|
+
|
107
|
+
results.all?
|
88
108
|
end
|
89
109
|
|
90
110
|
def find(deal_id)
|
@@ -134,12 +154,12 @@ module Hubspot
|
|
134
154
|
# @param object [Hubspot::Contact || Hubspot::Company] a contact or company
|
135
155
|
# @return [Array] Array of Hubspot::Deal records
|
136
156
|
def find_by_association(object)
|
137
|
-
|
138
|
-
when Hubspot::Company then
|
139
|
-
when Hubspot::Contact then
|
157
|
+
to_object_type = case object
|
158
|
+
when Hubspot::Company then "Company"
|
159
|
+
when Hubspot::Contact then "Contact"
|
140
160
|
else raise(Hubspot::InvalidParams, 'Instance type not supported')
|
141
161
|
end
|
142
|
-
Hubspot::Association.all(object.id,
|
162
|
+
Hubspot::Association.all(to_object_type, object.id, "Deal")
|
143
163
|
end
|
144
164
|
end
|
145
165
|
|
data/lib/hubspot/exceptions.rb
CHANGED
@@ -0,0 +1,44 @@
|
|
1
|
+
require 'hubspot/utils'
|
2
|
+
|
3
|
+
module Hubspot
|
4
|
+
class Meeting
|
5
|
+
#
|
6
|
+
# HubSpot Meeting API
|
7
|
+
#
|
8
|
+
# {https://developers.hubspot.com/docs/api/crm/meetings}
|
9
|
+
#
|
10
|
+
CREATE_MEETING_PATH = '/crm/v3/objects/meetings'
|
11
|
+
MEETING_PATH = '/crm/v3/objects/meetings/:meeting_id'
|
12
|
+
ASSOCIATE_MEETING_PATH = '/crm/v3/objects/meetings/:meeting_id/associations/Contact/:contact_id/meeting_event_to_contact'
|
13
|
+
|
14
|
+
class << self
|
15
|
+
def create!(owner_id, meeting_title, meeting_body, start_date_time, end_date_time)
|
16
|
+
body = {
|
17
|
+
properties: {
|
18
|
+
hs_timestamp: DateTime.now.strftime('%Q'),
|
19
|
+
hubspot_owner_id: owner_id,
|
20
|
+
hs_meeting_title: meeting_title,
|
21
|
+
hs_meeting_body: meeting_body,
|
22
|
+
hs_meeting_start_time: start_date_time.is_a?(DateTime) ? start_date_time.strftime('%Q') : start_date_time,
|
23
|
+
hs_meeting_end_time: end_date_time.is_a?(DateTime) ? end_date_time.strftime('%Q') : end_date_time,
|
24
|
+
hs_meeting_outcome: 'SCHEDULED'
|
25
|
+
}
|
26
|
+
}
|
27
|
+
response = Hubspot::Connection.post_json(CREATE_MEETING_PATH, params: {}, body: body)
|
28
|
+
HashWithIndifferentAccess.new(response)
|
29
|
+
end
|
30
|
+
|
31
|
+
def destroy!(meeting_id)
|
32
|
+
Hubspot::Connection.delete_json(MEETING_PATH, {meeting_id: meeting_id})
|
33
|
+
end
|
34
|
+
|
35
|
+
def associate!(meeting_id, contact_id)
|
36
|
+
Hubspot::Connection.put_json(ASSOCIATE_MEETING_PATH,
|
37
|
+
params: {
|
38
|
+
meeting_id: meeting_id,
|
39
|
+
contact_id: contact_id
|
40
|
+
})
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/hubspot/properties.rb
CHANGED
@@ -97,7 +97,7 @@ module Hubspot
|
|
97
97
|
|
98
98
|
def valid_group_params(params)
|
99
99
|
return {} if params.blank?
|
100
|
-
result = params.slice(*PROPERTY_SPECS[:group_field_names])
|
100
|
+
result = params.with_indifferent_access.slice(*PROPERTY_SPECS[:group_field_names])
|
101
101
|
result['properties'] = valid_property_params(result['properties']) unless result['properties'].blank?
|
102
102
|
result
|
103
103
|
end
|
data/lib/hubspot-api-ruby.rb
CHANGED
@@ -14,6 +14,7 @@ require 'hubspot/contact'
|
|
14
14
|
require 'hubspot/contact_properties'
|
15
15
|
require 'hubspot/contact_list'
|
16
16
|
require 'hubspot/event'
|
17
|
+
require 'hubspot/custom_event'
|
17
18
|
require 'hubspot/form'
|
18
19
|
require 'hubspot/blog'
|
19
20
|
require 'hubspot/topic'
|
@@ -27,6 +28,7 @@ require 'hubspot/engagement'
|
|
27
28
|
require 'hubspot/subscription'
|
28
29
|
require 'hubspot/oauth'
|
29
30
|
require 'hubspot/file'
|
31
|
+
require 'hubspot/meeting'
|
30
32
|
|
31
33
|
module Hubspot
|
32
34
|
def self.configure(config={})
|