hubspot-ruby 0.1.8 → 0.2.0

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.
Files changed (108) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +2 -22
  3. data/Gemfile.lock +14 -11
  4. data/LICENSE.txt +0 -2
  5. data/README.md +8 -6
  6. data/RELEASING.md +4 -5
  7. data/Rakefile +2 -17
  8. data/hubspot-ruby.gemspec +20 -157
  9. data/lib/hubspot-ruby.rb +10 -0
  10. data/lib/hubspot/blog.rb +1 -2
  11. data/lib/hubspot/company.rb +149 -0
  12. data/lib/hubspot/company_properties.rb +59 -0
  13. data/lib/hubspot/config.rb +10 -4
  14. data/lib/hubspot/connection.rb +12 -4
  15. data/lib/hubspot/contact.rb +52 -31
  16. data/lib/hubspot/contact_list.rb +16 -16
  17. data/lib/hubspot/contact_properties.rb +53 -6
  18. data/lib/hubspot/deal.rb +2 -2
  19. data/lib/hubspot/deal_pipeline.rb +43 -0
  20. data/lib/hubspot/deal_properties.rb +59 -0
  21. data/lib/hubspot/engagement.rb +133 -0
  22. data/lib/hubspot/exceptions.rb +1 -1
  23. data/lib/hubspot/form.rb +20 -20
  24. data/lib/hubspot/owner.rb +49 -0
  25. data/lib/hubspot/properties.rb +119 -0
  26. data/lib/hubspot/railtie.rb +10 -0
  27. data/lib/hubspot/topic.rb +2 -2
  28. data/lib/hubspot/utils.rb +106 -3
  29. data/spec/lib/hubspot/blog_spec.rb +2 -0
  30. data/spec/lib/hubspot/company_properties_spec.rb +239 -0
  31. data/spec/lib/hubspot/company_spec.rb +190 -0
  32. data/spec/lib/hubspot/config_spec.rb +1 -1
  33. data/spec/lib/hubspot/connection_spec.rb +33 -27
  34. data/spec/lib/hubspot/contact_list_spec.rb +61 -61
  35. data/spec/lib/hubspot/contact_properties_spec.rb +234 -3
  36. data/spec/lib/hubspot/contact_spec.rb +140 -71
  37. data/spec/lib/hubspot/deal_properties_spec.rb +254 -0
  38. data/spec/lib/hubspot/engagement_spec.rb +87 -0
  39. data/spec/lib/hubspot/form_spec.rb +72 -60
  40. data/spec/lib/hubspot/owner_spec.rb +56 -0
  41. data/spec/lib/hubspot/properties_spec.rb +45 -0
  42. data/spec/lib/hubspot/topic_spec.rb +0 -1
  43. data/spec/lib/hubspot/utils_spec.rb +113 -15
  44. data/spec/lib/tasks/properties_spec.rb +90 -0
  45. data/spec/live/companies_integration_spec.rb +23 -0
  46. data/spec/live/companies_properties_integration_spec.rb +120 -0
  47. data/spec/live/contacts_integration_spec.rb +1 -1
  48. data/spec/live/contacts_properties_integration_spec.rb +120 -0
  49. data/spec/live/deal_properties_integration_spec.rb +123 -0
  50. data/spec/live/deals_integration_spec.rb +1 -1
  51. data/spec/support/cassette_helper.rb +1 -1
  52. data/spec/support/tests_helper.rb +3 -3
  53. metadata +39 -78
  54. data/.document +0 -5
  55. data/lib/hubspot/version.rb +0 -9
  56. data/spec/fixtures/vcr_cassettes/add_contacts_to_lists.yml +0 -281
  57. data/spec/fixtures/vcr_cassettes/blog_list.yml +0 -180
  58. data/spec/fixtures/vcr_cassettes/blog_posts.yml +0 -107
  59. data/spec/fixtures/vcr_cassettes/blog_posts_list.yml +0 -6463
  60. data/spec/fixtures/vcr_cassettes/contact_create.yml +0 -64
  61. data/spec/fixtures/vcr_cassettes/contact_create_existing_email.yml +0 -62
  62. data/spec/fixtures/vcr_cassettes/contact_create_invalid_email.yml +0 -63
  63. data/spec/fixtures/vcr_cassettes/contact_create_with_params.yml +0 -64
  64. data/spec/fixtures/vcr_cassettes/contact_destroy.yml +0 -131
  65. data/spec/fixtures/vcr_cassettes/contact_example.yml +0 -32
  66. data/spec/fixtures/vcr_cassettes/contact_find_by_email.yml +0 -59
  67. data/spec/fixtures/vcr_cassettes/contact_find_by_email_batch_mode.yml +0 -509
  68. data/spec/fixtures/vcr_cassettes/contact_find_by_id.yml +0 -59
  69. data/spec/fixtures/vcr_cassettes/contact_find_by_id_batch_mode.yml +0 -33
  70. data/spec/fixtures/vcr_cassettes/contact_find_by_utk.yml +0 -83
  71. data/spec/fixtures/vcr_cassettes/contact_find_by_utk_batch_mode.yml +0 -33
  72. data/spec/fixtures/vcr_cassettes/contact_list_batch_find.yml +0 -65
  73. data/spec/fixtures/vcr_cassettes/contact_list_destroy.yml +0 -63
  74. data/spec/fixtures/vcr_cassettes/contact_list_example.yml +0 -33
  75. data/spec/fixtures/vcr_cassettes/contact_list_find.yml +0 -96
  76. data/spec/fixtures/vcr_cassettes/contact_list_refresh.yml +0 -33
  77. data/spec/fixtures/vcr_cassettes/contact_list_update.yml +0 -36
  78. data/spec/fixtures/vcr_cassettes/contact_update.yml +0 -66
  79. data/spec/fixtures/vcr_cassettes/contacts_among_list.yml +0 -189
  80. data/spec/fixtures/vcr_cassettes/create_form.yml +0 -39
  81. data/spec/fixtures/vcr_cassettes/create_list.yml +0 -36
  82. data/spec/fixtures/vcr_cassettes/create_list_with_filters.yml +0 -36
  83. data/spec/fixtures/vcr_cassettes/deal_create.yml +0 -61
  84. data/spec/fixtures/vcr_cassettes/deal_example.yml +0 -166
  85. data/spec/fixtures/vcr_cassettes/deal_find.yml +0 -115
  86. data/spec/fixtures/vcr_cassettes/destroy_deal.yml +0 -221
  87. data/spec/fixtures/vcr_cassettes/fail_to_create_form.yml +0 -35
  88. data/spec/fixtures/vcr_cassettes/fail_to_create_list.yml +0 -35
  89. data/spec/fixtures/vcr_cassettes/field_among_form.yml +0 -34
  90. data/spec/fixtures/vcr_cassettes/fields_among_form.yml +0 -35
  91. data/spec/fixtures/vcr_cassettes/find_all_contacts.yml +0 -297
  92. data/spec/fixtures/vcr_cassettes/find_all_dynamic_lists.yml +0 -104
  93. data/spec/fixtures/vcr_cassettes/find_all_forms.yml +0 -15378
  94. data/spec/fixtures/vcr_cassettes/find_all_lists.yml +0 -138
  95. data/spec/fixtures/vcr_cassettes/find_all_recent_contacts.yml +0 -33
  96. data/spec/fixtures/vcr_cassettes/find_all_recent_updated_deals.yml +0 -130
  97. data/spec/fixtures/vcr_cassettes/find_all_stastic_lists.yml +0 -21876
  98. data/spec/fixtures/vcr_cassettes/form_destroy.yml +0 -64
  99. data/spec/fixtures/vcr_cassettes/form_example.yml +0 -39
  100. data/spec/fixtures/vcr_cassettes/form_find.yml +0 -69
  101. data/spec/fixtures/vcr_cassettes/form_post.yml +0 -31
  102. data/spec/fixtures/vcr_cassettes/form_submit_data.yml +0 -130
  103. data/spec/fixtures/vcr_cassettes/form_update.yml +0 -77
  104. data/spec/fixtures/vcr_cassettes/one_month_blog_posts_filter_state.yml +0 -19127
  105. data/spec/fixtures/vcr_cassettes/one_month_blog_posts_list.yml +0 -34963
  106. data/spec/fixtures/vcr_cassettes/remove_contacts_from_lists.yml +0 -315
  107. data/spec/fixtures/vcr_cassettes/topic_list.yml +0 -48
  108. data/spec/fixtures/vcr_cassettes/topics_list.yml +0 -86
@@ -0,0 +1,59 @@
1
+ module Hubspot
2
+ class CompanyProperties < Properties
3
+
4
+ ALL_PROPERTIES_PATH = '/companies/v2/properties'
5
+ ALL_GROUPS_PATH = '/companies/v2/groups'
6
+ CREATE_PROPERTY_PATH = '/companies/v2/properties/'
7
+ UPDATE_PROPERTY_PATH = '/companies/v2/properties/named/:property_name'
8
+ DELETE_PROPERTY_PATH = '/companies/v2/properties/named/:property_name'
9
+ CREATE_GROUP_PATH = '/companies/v2/groups/'
10
+ UPDATE_GROUP_PATH = '/companies/v2/groups/named/:group_name'
11
+ DELETE_GROUP_PATH = '/companies/v2/groups/named/:group_name'
12
+
13
+ class << self
14
+ def add_default_parameters(opts={})
15
+ superclass.add_default_parameters(opts)
16
+ end
17
+
18
+ def all(opts={}, filter={})
19
+ superclass.all(ALL_PROPERTIES_PATH, opts, filter)
20
+ end
21
+
22
+ def groups(opts={}, filter={})
23
+ superclass.groups(ALL_GROUPS_PATH, opts, filter)
24
+ end
25
+
26
+ def create!(params={})
27
+ superclass.create!(CREATE_PROPERTY_PATH, params)
28
+ end
29
+
30
+ def update!(property_name, params={})
31
+ superclass.update!(UPDATE_PROPERTY_PATH, property_name, params)
32
+ end
33
+
34
+ def delete!(property_name)
35
+ superclass.delete!(DELETE_PROPERTY_PATH, property_name)
36
+ end
37
+
38
+ def create_group!(params={})
39
+ superclass.create_group!(CREATE_GROUP_PATH, params)
40
+ end
41
+
42
+ def update_group!(group_name, params={})
43
+ superclass.update_group!(UPDATE_GROUP_PATH, group_name, params)
44
+ end
45
+
46
+ def delete_group!(group_name)
47
+ superclass.delete_group!(DELETE_GROUP_PATH, group_name)
48
+ end
49
+
50
+ def same?(src, dst)
51
+ superclass.same?(src, dst)
52
+ end
53
+
54
+ def valid_params(params)
55
+ superclass.valid_params(params)
56
+ end
57
+ end
58
+ end
59
+ end
@@ -1,15 +1,20 @@
1
+ require 'logger'
2
+
1
3
  module Hubspot
2
4
  class Config
5
+
6
+ CONFIG_KEYS = [:hapikey, :base_url, :portal_id, :logger]
7
+ DEFAULT_LOGGER = Logger.new('/dev/null')
8
+
3
9
  class << self
4
- attr_reader :hapikey
5
- attr_reader :base_url
6
- attr_reader :portal_id
10
+ attr_accessor *CONFIG_KEYS
7
11
 
8
12
  def configure(config)
9
13
  config.stringify_keys!
10
14
  @hapikey = config["hapikey"]
11
15
  @base_url = config["base_url"] || "https://api.hubapi.com"
12
16
  @portal_id = config["portal_id"]
17
+ @logger = config['logger'] || DEFAULT_LOGGER
13
18
  self
14
19
  end
15
20
 
@@ -17,6 +22,7 @@ module Hubspot
17
22
  @hapikey = nil
18
23
  @base_url = "https://api.hubapi.com"
19
24
  @portal_id = nil
25
+ @logger = DEFAULT_LOGGER
20
26
  end
21
27
 
22
28
  def ensure!(*params)
@@ -28,4 +34,4 @@ module Hubspot
28
34
 
29
35
  reset!
30
36
  end
31
- end
37
+ end
@@ -6,6 +6,7 @@ module Hubspot
6
6
  def get_json(path, opts)
7
7
  url = generate_url(path, opts)
8
8
  response = get(url, format: :json)
9
+ log_request_and_response url, response
9
10
  raise(Hubspot::RequestError.new(response)) unless response.success?
10
11
  response.parsed_response
11
12
  end
@@ -15,6 +16,7 @@ module Hubspot
15
16
 
16
17
  url = generate_url(path, opts[:params])
17
18
  response = post(url, body: opts[:body].to_json, headers: { 'Content-Type' => 'application/json' }, format: :json)
19
+ log_request_and_response url, response, opts[:body]
18
20
  raise(Hubspot::RequestError.new(response)) unless response.success?
19
21
 
20
22
  no_parse ? response : response.parsed_response
@@ -23,6 +25,7 @@ module Hubspot
23
25
  def put_json(path, opts)
24
26
  url = generate_url(path, opts[:params])
25
27
  response = put(url, body: opts[:body].to_json, headers: { 'Content-Type' => 'application/json' }, format: :json)
28
+ log_request_and_response url, response, opts[:body]
26
29
  raise(Hubspot::RequestError.new(response)) unless response.success?
27
30
  response.parsed_response
28
31
  end
@@ -30,12 +33,17 @@ module Hubspot
30
33
  def delete_json(path, opts)
31
34
  url = generate_url(path, opts)
32
35
  response = delete(url, format: :json)
36
+ log_request_and_response url, response, opts[:body]
33
37
  raise(Hubspot::RequestError.new(response)) unless response.success?
34
38
  response
35
39
  end
36
40
 
37
41
  protected
38
42
 
43
+ def log_request_and_response(uri, response, body=nil)
44
+ Hubspot::Config.logger.info "Hubspot: #{uri}.\nBody: #{body}.\nResponse: #{response.code} #{response.body}"
45
+ end
46
+
39
47
  def generate_url(path, params={}, options={})
40
48
  Hubspot::Config.ensure! :hapikey
41
49
  path = path.clone
@@ -85,11 +93,11 @@ module Hubspot
85
93
  end
86
94
 
87
95
  class FormsConnection < Connection
88
- follow_redirects false
96
+ follow_redirects true
89
97
 
90
98
  def self.submit(path, opts)
91
- url = generate_url(path, opts[:params], { base_url: 'https://forms.hubspot.com' })
92
- post(url, body: opts[:body].to_json, headers: { 'Content-Type' => 'application/x-www-form-urlencoded' })
99
+ url = generate_url(path, opts[:params], { base_url: 'https://forms.hubspot.com', hapikey: false })
100
+ post(url, body: opts[:body], headers: { 'Content-Type' => 'application/x-www-form-urlencoded' })
93
101
  end
94
102
  end
95
- end
103
+ end
@@ -6,22 +6,24 @@ 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 = "/contacts/v1/contact"
10
- GET_CONTACT_BY_EMAIL_PATH = "/contacts/v1/contact/email/:contact_email/profile"
11
- GET_CONTACTS_BY_EMAIL_PATH = "/contacts/v1/contact/emails/batch"
12
- GET_CONTACT_BY_ID_PATH = "/contacts/v1/contact/vid/:contact_id/profile"
9
+ CREATE_CONTACT_PATH = '/contacts/v1/contact'
10
+ GET_CONTACT_BY_EMAIL_PATH = '/contacts/v1/contact/email/:contact_email/profile'
11
+ GET_CONTACTS_BY_EMAIL_PATH = '/contacts/v1/contact/emails/batch'
12
+ GET_CONTACT_BY_ID_PATH = '/contacts/v1/contact/vid/:contact_id/profile'
13
13
  CONTACT_BATCH_PATH = '/contacts/v1/contact/vids/batch'
14
- GET_CONTACT_BY_UTK_PATH = "/contacts/v1/contact/utk/:contact_utk/profile"
14
+ GET_CONTACT_BY_UTK_PATH = '/contacts/v1/contact/utk/:contact_utk/profile'
15
15
  GET_CONTACTS_BY_UTK_PATH = '/contacts/v1/contact/utks/batch'
16
- UPDATE_CONTACT_PATH = "/contacts/v1/contact/vid/:contact_id/profile"
17
- DESTROY_CONTACT_PATH = "/contacts/v1/contact/vid/:contact_id"
18
- CONTACTS_PATH = "/contacts/v1/lists/all/contacts/all"
16
+ UPDATE_CONTACT_PATH = '/contacts/v1/contact/vid/:contact_id/profile'
17
+ DESTROY_CONTACT_PATH = '/contacts/v1/contact/vid/:contact_id'
18
+ CONTACTS_PATH = '/contacts/v1/lists/all/contacts/all'
19
19
  RECENT_CONTACTS_PATH = '/contacts/v1/lists/recently_updated/contacts/recent'
20
+ CREATE_OR_UPDATE_PATH = '/contacts/v1/contact/createOrUpdate/email/:contact_email'
21
+ QUERY_PATH = '/contacts/v1/search/query'
20
22
 
21
23
  class << self
22
24
  # {https://developers.hubspot.com/docs/methods/contacts/create_contact}
23
25
  def create!(email, params={})
24
- params_with_email = params.stringify_keys.merge("email" => email)
26
+ params_with_email = params.stringify_keys.merge('email' => email)
25
27
  post_data = {properties: Hubspot::Utils.hash_to_properties(params_with_email)}
26
28
  response = Hubspot::Connection.post_json(CREATE_CONTACT_PATH, params: {}, body: post_data )
27
29
  new(response)
@@ -30,11 +32,11 @@ module Hubspot
30
32
  # {https://developers.hubspot.com/docs/methods/contacts/get_contacts}
31
33
  # {https://developers.hubspot.com/docs/methods/contacts/get_recently_updated_contacts}
32
34
  def all(opts={})
33
- recent = opts.delete(:recent) { false }
34
- path, opts =
35
- if recent
36
- [RECENT_CONTACTS_PATH, Hubspot::ContactProperties.add_default_parameters(opts)]
37
- else
35
+ recent = opts.delete(:recent) { false }
36
+ path, opts =
37
+ if recent
38
+ [RECENT_CONTACTS_PATH, Hubspot::ContactProperties.add_default_parameters(opts)]
39
+ else
38
40
  [CONTACTS_PATH, opts]
39
41
  end
40
42
 
@@ -46,6 +48,13 @@ module Hubspot
46
48
  # PATH /contacts/v1/contact/createOrUpdate/email/:contact_email
47
49
  # API endpoint: https://developers.hubspot.com/docs/methods/contacts/create_or_update
48
50
  # + batch mode: https://developers.hubspot.com/docs/methods/contacts/batch_create_or_update
51
+ def createOrUpdate(email, params={})
52
+ post_data = {properties: Hubspot::Utils.hash_to_properties(params.stringify_keys)}
53
+ response = Hubspot::Connection.post_json(CREATE_OR_UPDATE_PATH, params: { contact_email: email }, body: post_data )
54
+ contact = find_by_id(response['vid'])
55
+ contact.is_new = response['isNew']
56
+ contact
57
+ end
49
58
 
50
59
  # NOTE: problem with batch api endpoint
51
60
  # {https://developers.hubspot.com/docs/methods/contacts/get_contact}
@@ -71,18 +80,22 @@ module Hubspot
71
80
  else raise Hubspot::InvalidParams, 'expecting String or Array of Strings parameter'
72
81
  end
73
82
 
74
- response = Hubspot::Connection.get_json(path, params)
75
- if batch_mode
76
- #TODO: transform response
77
- response
78
- else
79
- new(response)
83
+ begin
84
+ response = Hubspot::Connection.get_json(path, params)
85
+ if batch_mode
86
+ response.map{|_, contact| new(contact)}
87
+ else
88
+ new(response)
89
+ end
90
+ rescue => e
91
+ raise e unless e.message =~ /not exist/ # 404 / handle the error and kindly return nil
92
+ nil
80
93
  end
81
94
  end
82
95
 
83
96
  # NOTE: problem with batch api endpoint
84
97
  # {https://developers.hubspot.com/docs/methods/contacts/get_contact_by_utk}
85
- # {https://developers.hubspot.com/docs/methods/contacts/get_batch_by_utk}
98
+ # {https://developers.hubspot.com/docs/methods/contacts/get_batch_by_utk}
86
99
  def find_by_utk(utks)
87
100
  batch_mode, path, params = case utks
88
101
  when String then [false, GET_CONTACT_BY_UTK_PATH, { contact_utk: utks }]
@@ -96,17 +109,21 @@ module Hubspot
96
109
  end
97
110
 
98
111
  # {https://developers.hubspot.com/docs/methods/contacts/search_contacts}
99
- def search(query, count=100)
100
- raise NotImplementedError
112
+ def search(query, options = {})
113
+ count = options.fetch(:count, 100)
114
+ offset = options.fetch(:offset, 0)
115
+
116
+ response = Hubspot::Connection.get_json(QUERY_PATH, { q: query, count: count, offset: offset })
117
+ response.merge("contacts" => response["contacts"].map { |contact_hash| new(contact_hash) })
101
118
  end
102
119
  end
103
120
 
104
- attr_reader :properties
105
- attr_reader :vid
121
+ attr_reader :properties, :vid, :is_new
106
122
 
107
123
  def initialize(response_hash)
108
- @properties = Hubspot::Utils.properties_to_hash(response_hash["properties"])
109
- @vid = response_hash["vid"]
124
+ props = response_hash['properties']
125
+ @properties = Hubspot::Utils.properties_to_hash(props) unless props.blank?
126
+ @vid = response_hash['vid']
110
127
  end
111
128
 
112
129
  def [](property)
@@ -114,11 +131,15 @@ module Hubspot
114
131
  end
115
132
 
116
133
  def email
117
- @properties["email"]
134
+ @properties['email']
118
135
  end
119
136
 
120
137
  def utk
121
- @properties["usertoken"]
138
+ @properties['usertoken']
139
+ end
140
+
141
+ def is_new=(val)
142
+ @is_new = val
122
143
  end
123
144
 
124
145
  # Updates the properties of a contact
@@ -127,7 +148,7 @@ module Hubspot
127
148
  # @return [Hubspot::Contact] self
128
149
  def update!(params)
129
150
  query = {"properties" => Hubspot::Utils.hash_to_properties(params.stringify_keys!)}
130
- response = Hubspot::Connection.post_json(UPDATE_CONTACT_PATH, params: { contact_id: vid }, body: query)
151
+ Hubspot::Connection.post_json(UPDATE_CONTACT_PATH, params: { contact_id: vid }, body: query)
131
152
  @properties.merge!(params)
132
153
  self
133
154
  end
@@ -136,7 +157,7 @@ module Hubspot
136
157
  # {https://developers.hubspot.com/docs/methods/contacts/delete_contact}
137
158
  # @return [TrueClass] true
138
159
  def destroy!
139
- response = Hubspot::Connection.delete_json(DESTROY_CONTACT_PATH, { contact_id: vid })
160
+ Hubspot::Connection.delete_json(DESTROY_CONTACT_PATH, { contact_id: vid })
140
161
  @destroyed = true
141
162
  end
142
163
 
@@ -15,10 +15,10 @@ module Hubspot
15
15
  class << self
16
16
  # {http://developers.hubspot.com/docs/methods/lists/create_list}
17
17
  def create!(opts={})
18
- dynamic = opts.delete(:dynamic) { false }
19
- portal_id = opts.delete(:portal_id) { Hubspot::Config.portal_id }
20
-
21
- response = Hubspot::Connection.post_json(LISTS_PATH, params: {}, body: opts.merge({ dynamic: dynamic, portal_id: portal_id}) )
18
+ dynamic = opts.delete(:dynamic) { false }
19
+ portal_id = opts.delete(:portal_id) { Hubspot::Config.portal_id }
20
+
21
+ response = Hubspot::Connection.post_json(LISTS_PATH, params: {}, body: opts.merge({ dynamic: dynamic, portal_id: portal_id}) )
22
22
  new(response)
23
23
  end
24
24
 
@@ -26,11 +26,11 @@ module Hubspot
26
26
  # {http://developers.hubspot.com/docs/methods/lists/get_static_lists}
27
27
  # {http://developers.hubspot.com/docs/methods/lists/get_dynamic_lists}
28
28
  def all(opts={})
29
- static = opts.delete(:static) { false }
30
- dynamic = opts.delete(:dynamic) { false }
29
+ static = opts.delete(:static) { false }
30
+ dynamic = opts.delete(:dynamic) { false }
31
31
 
32
32
  # NOTE: As opposed of what the documentation says, getting the static or dynamic lists returns all the lists, not only 20 lists
33
- path = LISTS_PATH + (static ? '/static' : dynamic ? '/dynamic' : '')
33
+ path = LISTS_PATH + (static ? '/static' : dynamic ? '/dynamic' : '')
34
34
  response = Hubspot::Connection.get_json(path, opts)
35
35
  response['lists'].map { |l| new(l) }
36
36
  end
@@ -38,12 +38,12 @@ module Hubspot
38
38
  # {http://developers.hubspot.com/docs/methods/lists/get_list}
39
39
  # {http://developers.hubspot.com/docs/methods/lists/get_batch_lists}
40
40
  def find(ids)
41
- batch_mode, path, params = case ids
41
+ batch_mode, path, params = case ids
42
42
  when Integer then [false, LIST_PATH, { list_id: ids }]
43
- when String then [false, LIST_PATH, { list_id: ids.to_i }]
43
+ when String then [false, LIST_PATH, { list_id: ids.to_i }]
44
44
  when Array then [true, LIST_BATCH_PATH, { batch_list_id: ids.map(&:to_i) }]
45
45
  else raise Hubspot::InvalidParams, 'expecting Integer or Array of Integers parameter'
46
- end
46
+ end
47
47
 
48
48
  response = Hubspot::Connection.get_json(path, params)
49
49
  batch_mode ? response['lists'].map { |l| new(l) } : new(response)
@@ -77,17 +77,17 @@ module Hubspot
77
77
  def contacts(opts={})
78
78
  # NOTE: caching functionality can be dependant of the nature of the list, if dynamic or not ...
79
79
  bypass_cache = opts.delete(:bypass_cache) { false }
80
- recent = opts.delete(:recent) { false }
80
+ recent = opts.delete(:recent) { false }
81
81
 
82
82
  if bypass_cache || @contacts.nil?
83
83
  path = recent ? RECENT_CONTACTS_PATH : CONTACTS_PATH
84
84
  opts[:list_id] = @id
85
-
85
+
86
86
  response = Hubspot::Connection.get_json(path, Hubspot::ContactProperties.add_default_parameters(opts))
87
87
  @contacts = response['contacts'].map { |c| Hubspot::Contact.new(c) }
88
88
  else
89
89
  @contacts
90
- end
90
+ end
91
91
  end
92
92
 
93
93
  # {http://developers.hubspot.com/docs/methods/lists/refresh_list}
@@ -97,12 +97,12 @@ module Hubspot
97
97
  end
98
98
 
99
99
  # {http://developers.hubspot.com/docs/methods/lists/add_contact_to_list}
100
- def add(contacts)
100
+ def add(contacts)
101
101
  contact_ids = [contacts].flatten.uniq.compact.map(&:vid)
102
102
  response = Hubspot::Connection.post_json(ADD_CONTACT_PATH, params: { list_id: @id }, body: { vids: contact_ids })
103
103
  response['updated'].sort == contact_ids.sort
104
104
  end
105
-
105
+
106
106
  # {http://developers.hubspot.com/docs/methods/lists/remove_contact_from_list}
107
107
  def remove(contacts)
108
108
  contact_ids = [contacts].flatten.uniq.compact.map(&:vid)
@@ -124,4 +124,4 @@ module Hubspot
124
124
  @properties = hash
125
125
  end
126
126
  end
127
- end
127
+ end
@@ -1,11 +1,58 @@
1
1
  module Hubspot
2
- class ContactProperties
3
- class << self
4
- # TODO: properties can be set as configuration
5
- # TODO: find the way how to set a list of Properties + merge same property key if present from opts
2
+ class ContactProperties < Properties
3
+
4
+ ALL_PROPERTIES_PATH = '/contacts/v2/properties'
5
+ ALL_GROUPS_PATH = '/contacts/v2/groups'
6
+ CREATE_PROPERTY_PATH = '/contacts/v2/properties/'
7
+ UPDATE_PROPERTY_PATH = '/contacts/v2/properties/named/:property_name'
8
+ DELETE_PROPERTY_PATH = '/contacts/v2/properties/named/:property_name'
9
+ CREATE_GROUP_PATH = '/contacts/v2/groups/'
10
+ UPDATE_GROUP_PATH = '/contacts/v2/groups/named/:group_name'
11
+ DELETE_GROUP_PATH = '/contacts/v2/groups/named/:group_name'
12
+
13
+ class << self
6
14
  def add_default_parameters(opts={})
7
- properties = 'email'
8
- opts.merge(property: properties)
15
+ superclass.add_default_parameters(opts)
16
+ end
17
+
18
+ def all(opts={}, filter={})
19
+ superclass.all(ALL_PROPERTIES_PATH, opts, filter)
20
+ end
21
+
22
+ def groups(opts={}, filter={})
23
+ superclass.groups(ALL_GROUPS_PATH, opts, filter)
24
+ end
25
+
26
+ def create!(params={})
27
+ superclass.create!(CREATE_PROPERTY_PATH, params)
28
+ end
29
+
30
+ def update!(property_name, params={})
31
+ superclass.update!(UPDATE_PROPERTY_PATH, property_name, params)
32
+ end
33
+
34
+ def delete!(property_name)
35
+ superclass.delete!(DELETE_PROPERTY_PATH, property_name)
36
+ end
37
+
38
+ def create_group!(params={})
39
+ superclass.create_group!(CREATE_GROUP_PATH, params)
40
+ end
41
+
42
+ def update_group!(group_name, params={})
43
+ superclass.update_group!(UPDATE_GROUP_PATH, group_name, params)
44
+ end
45
+
46
+ def delete_group!(group_name)
47
+ superclass.delete_group!(DELETE_GROUP_PATH, group_name)
48
+ end
49
+
50
+ def same?(src, dst)
51
+ superclass.same?(src, dst)
52
+ end
53
+
54
+ def valid_params(params)
55
+ superclass.valid_params(params)
9
56
  end
10
57
  end
11
58
  end