ruby_hubspot_api 0.2.1.pre.1 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 2ca83fa3cba8c574d585b31a359da74678d405d2
4
- data.tar.gz: 151f119e552b17faff4d921cda1ceec62a3fc045
2
+ SHA256:
3
+ metadata.gz: f455ed36bd0ae0284959198213bea7924099b97fc0b43b4ac50b4ad21a73def2
4
+ data.tar.gz: 9ba207fcf4fdf8c14889d130a0cdd3284ff75816873d994084d80b410e8306e1
5
5
  SHA512:
6
- metadata.gz: e2e95c0a9ef1b69ff862c7843bbb100b23d57fe29cfea0d2042a7593dc3760307d48027fc0b54a6ae05bd39c4721db7603e04a7b16a5ec51b50a1becc436fdc1
7
- data.tar.gz: 9dd953ca1946b3f9c3f1d0616f377a330f7e894f6a0f1a1aa6e98fde137015b6c39148dec58437c5cf027d89b9e096dbeb36b144a368ed8f1e61aa2a673305d7
6
+ metadata.gz: 0d4274f0519d4fe99a09f06405689a3b45145a6890b4c5a1052e7e6e38bf91ae4ce9d96669d8bb97a5acd7e92110a0eeac4c73e7e0e6ea3b93fd1393f2f4c648
7
+ data.tar.gz: 42829d5342d0dbd126b9200b609c662518dce48e55a82a6e3f6536ee4ed7bdf1c9af14007114e1f883ca036df53cc49522d239d803e5bdfceb525170a18adbac
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ruby_hubspot_api (0.2.1)
4
+ ruby_hubspot_api (0.2)
5
5
  httparty (>= 0.1, < 1.0)
6
6
 
7
7
  GEM
@@ -9,33 +9,35 @@ GEM
9
9
  specs:
10
10
  addressable (2.8.7)
11
11
  public_suffix (>= 2.0.2, < 7.0)
12
- bigdecimal (3.0.2)
12
+ bigdecimal (3.1.8)
13
13
  byebug (11.1.3)
14
- codecov (0.6.0)
15
- simplecov (>= 0.15, < 0.22)
14
+ codecov (0.2.12)
15
+ json
16
+ simplecov
16
17
  coderay (1.1.3)
17
18
  crack (1.0.0)
18
19
  bigdecimal
19
20
  rexml
20
21
  diff-lcs (1.5.1)
21
- docile (1.3.5)
22
+ docile (1.4.1)
22
23
  dotenv (2.8.1)
23
24
  hashdiff (1.1.1)
24
25
  httparty (0.21.0)
25
26
  mini_mime (>= 1.0.0)
26
27
  multi_xml (>= 0.5.2)
28
+ json (2.7.2)
27
29
  method_source (1.1.0)
28
30
  mini_mime (1.1.2)
29
31
  multi_xml (0.6.0)
30
- pry (0.14.2)
32
+ pry (0.13.1)
31
33
  coderay (~> 1.1)
32
34
  method_source (~> 1.0)
33
- pry-byebug (3.8.0)
35
+ pry-byebug (3.9.0)
34
36
  byebug (~> 11.0)
35
- pry (~> 0.10)
37
+ pry (~> 0.13.0)
36
38
  public_suffix (4.0.7)
37
39
  rake (13.2.1)
38
- rexml (3.2.5)
40
+ rexml (3.3.7)
39
41
  rspec (3.13.0)
40
42
  rspec-core (~> 3.13.0)
41
43
  rspec-expectations (~> 3.13.0)
@@ -49,13 +51,15 @@ GEM
49
51
  diff-lcs (>= 1.2.0, < 2.0)
50
52
  rspec-support (~> 3.13.0)
51
53
  rspec-support (3.13.1)
52
- simplecov (0.18.5)
54
+ simplecov (0.22.0)
53
55
  docile (~> 1.1)
54
56
  simplecov-html (~> 0.11)
57
+ simplecov_json_formatter (~> 0.1)
55
58
  simplecov-html (0.13.1)
56
59
  simplecov-lcov (0.8.0)
60
+ simplecov_json_formatter (0.1.4)
57
61
  vcr (6.0.0)
58
- webmock (3.18.1)
62
+ webmock (3.23.1)
59
63
  addressable (>= 2.8.0)
60
64
  crack (>= 0.3.2)
61
65
  hashdiff (>= 0.4.0, < 2.0.0)
@@ -80,4 +84,4 @@ DEPENDENCIES
80
84
  webmock (>= 3.0)
81
85
 
82
86
  BUNDLED WITH
83
- 2.2.34
87
+ 2.3.27
@@ -1,7 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # HubSpot API Client
4
- # Handles all HTTP interactions with the HubSpot API. It manages GET, POST, PATCH, and DELETE requests.
5
3
  module Hubspot
6
4
  # All interations with the Hubspot API happen here...
7
5
  class ApiClient
@@ -15,11 +15,6 @@ module Hubspot
15
15
  apply_log_level
16
16
  end
17
17
 
18
- # Apply the log level to the logger
19
- def apply_log_level
20
- @logger.level = @log_level
21
- end
22
-
23
18
  private
24
19
 
25
20
  # Initialize the default logger
@@ -48,6 +43,11 @@ module Hubspot
48
43
  end
49
44
  # rubocop:enable Metrics/MethodLength
50
45
 
46
+ # Apply the log level to the logger
47
+ def apply_log_level
48
+ @logger.level = @log_level
49
+ end
50
+
51
51
  # Set the default log level based on environment
52
52
  def default_log_level
53
53
  if defined?(Rails) && Rails.env.test?
@@ -6,20 +6,65 @@ require_relative './paged_batch'
6
6
 
7
7
  module Hubspot
8
8
  # rubocop:disable Metrics/ClassLength
9
- # Hubspot::Resource class
9
+
10
+ # HubSpot Resource Base Class
11
+ # This class provides common functionality for interacting with HubSpot API resources such as Contacts, Companies, etc
12
+ #
13
+ # It supports common operations like finding, creating, updating, and deleting resources, as well as batch operations.
14
+ #
15
+ # This class is meant to be inherited by specific resources like `Hubspot::Contact`.
16
+ #
17
+ # You can access the properties of a resource instance by calling the property name as method
18
+ #
19
+ # Example Usage:
20
+ # Hubspot::Contact.find(1)
21
+ # contact.name # 'Luke'
22
+ #
23
+ # company = Hubspot::Company.create(name: "Acme Corp")
24
+ # company.id.nil? # false
25
+ #
10
26
  class Resource < ApiClient
11
27
  METADATA_FIELDS = %w[createdate hs_object_id lastmodifieddate].freeze
12
28
 
13
- # Allow read/write access to properties and metadata
14
- attr_accessor :id, :properties, :changes, :metadata
29
+ # Allow read/write access to id, properties, changes and metadata
30
+
31
+ # the id of the object in hubspot
32
+ attr_accessor :id
33
+
34
+ # the properties as if read from the api
35
+ attr_accessor :properties
36
+
37
+ # track any changes made to properties before saving etc
38
+ attr_accessor :changes
39
+
40
+ # any other data sent from the api about the resource
41
+ attr_accessor :metadata
15
42
 
16
43
  class << self
17
44
  # Find a resource by ID and return an instance of the class
45
+ #
46
+ # id - [Integer] The ID (or hs_object_id) of the resource to fetch.
47
+ #
48
+ # Example:
49
+ # contact = Hubspot::Contact.find(1)
50
+ #
51
+ # Returns An instance of the resource.
18
52
  def find(id)
19
53
  response = get("/crm/v3/objects/#{resource_name}/#{id}")
20
54
  instantiate_from_response(response)
21
55
  end
22
56
 
57
+ # Finds a resource by a given property and value.
58
+ #
59
+ # property - The property to search by (e.g., "email").
60
+ # value - The value of the property to match.
61
+ # properties - Optional list of properties to return.
62
+ #
63
+ # Example:
64
+ # properties = %w[firstname lastname email last_contacted]
65
+ # contact = Hubspot::Contact.find_by("email", "john@example.com", properties)
66
+ #
67
+ # Returns An instance of the resource.
23
68
  def find_by(property, value, properties = nil)
24
69
  params = { idProperty: property }
25
70
  params[:properties] = properties if properties.is_a?(Array)
@@ -27,12 +72,28 @@ module Hubspot
27
72
  instantiate_from_response(response)
28
73
  end
29
74
 
30
- # Create a new resource
75
+ # Creates a new resource with the given parameters.
76
+ #
77
+ # params - The properties to create the resource with.
78
+ #
79
+ # Example:
80
+ # contact = Hubspot::Contact.create(name: "John Doe", email: "john@example.com")
81
+ #
82
+ # Returns [Resource] The newly created resource.
31
83
  def create(params)
32
84
  response = post("/crm/v3/objects/#{resource_name}", body: { properties: params }.to_json)
33
85
  instantiate_from_response(response)
34
86
  end
35
87
 
88
+ # Updates an existing resource by ID.
89
+ #
90
+ # id - The ID of the resource to update.
91
+ # params - The properties to update.
92
+ #
93
+ # Example:
94
+ # contact.update(1, name: "Jane Doe")
95
+ #
96
+ # Returns True if the update was successful, false if not
36
97
  def update(id, params)
37
98
  response = patch("/crm/v3/objects/#{resource_name}/#{id}", body: { properties: params }.to_json)
38
99
  raise Hubspot.error_from_response(response) unless response.success?
@@ -40,6 +101,14 @@ module Hubspot
40
101
  true
41
102
  end
42
103
 
104
+ # Deletes a resource by ID.
105
+ #
106
+ # id - The ID of the resource to delete.
107
+ #
108
+ # Example:
109
+ # Hubspot::Contact.archive(1)
110
+ #
111
+ # Returns True if the deletion was successful, false if not
43
112
  def archive(id)
44
113
  response = delete("/crm/v3/objects/#{resource_name}/#{id}")
45
114
  raise Hubspot.error_from_response(response) unless response.success?
@@ -47,6 +116,14 @@ module Hubspot
47
116
  true
48
117
  end
49
118
 
119
+ # Lists all resources with optional filters and pagination.
120
+ #
121
+ # params - Optional parameters to filter or paginate the results.
122
+ #
123
+ # Example:
124
+ # contacts = Hubspot::Contact.list(limit: 100)
125
+ #
126
+ # Returns [PagedCollection] A collection of resources.
50
127
  def list(params = {})
51
128
  PagedCollection.new(
52
129
  url: "/crm/v3/objects/#{resource_name}",
@@ -55,6 +132,17 @@ module Hubspot
55
132
  )
56
133
  end
57
134
 
135
+ # Performs a batch read operation to retrieve multiple resources by their IDs.
136
+ #
137
+ # object_ids - A list of resource IDs to fetch.
138
+ #
139
+ # id_property - The property to use for identifying resources (default: 'id').
140
+ #
141
+ #
142
+ # Example:
143
+ # Hubspot::Contact.batch_read([1, 2, 3])
144
+ #
145
+ # Returns [PagedBatch] A paged batch of resources (call .each_page to cycle through pages from the API)
58
146
  def batch_read(object_ids = [], id_property: 'id')
59
147
  params = id_property == 'id' ? {} : { idProperty: id_property }
60
148
 
@@ -66,11 +154,23 @@ module Hubspot
66
154
  )
67
155
  end
68
156
 
157
+ # Performs a batch read operation to retrieve multiple resources by their IDs
158
+ # until there are none left
159
+ #
160
+ # object_ids - A list of resource IDs to fetch. [Array<Integer>]
161
+ # id_property - The property to use for identifying resources (default: 'id').
162
+ #
163
+ # Example:
164
+ # Hubspot::Contact.batch_read([1, 2, 3])
165
+ #
166
+ # Returns [Hubspot::Batch] A batch of resources that can be operated on further
69
167
  def batch_read_all(object_ids = [], id_property: 'id')
70
168
  Hubspot::Batch.read(self, object_ids, id_property: id_property)
71
169
  end
72
170
 
73
- # Get the complete list of fields (properties) for the object
171
+ # Retrieve the complete list of properties for this resource class
172
+ #
173
+ # Returns [Array<Hubspot::Property>] An array of hubspot properties
74
174
  def properties
75
175
  @properties ||= begin
76
176
  response = get("/crm/v3/properties/#{resource_name}")
@@ -78,18 +178,34 @@ module Hubspot
78
178
  end
79
179
  end
80
180
 
181
+ # Retrieve the complete list of user defined properties for this resource class
182
+ #
183
+ # Returns [Array<Hubspot::Property>] An array of hubspot properties
81
184
  def custom_properties
82
185
  properties.reject { |property| property['hubspotDefined'] }
83
186
  end
84
187
 
188
+ # Retrieve the complete list of updatable properties for this resource class
189
+ #
190
+ # Returns [Array<Hubspot::Property>] An array of updateable hubspot properties
85
191
  def updatable_properties
86
192
  properties.reject(&:read_only?)
87
193
  end
88
194
 
195
+ # Retrieve the complete list of read-only properties for this resource class
196
+ #
197
+ # Returns [Array<Hubspot::Property>] An array of read-only hubspot properties
89
198
  def read_only_properties
90
- properties.select(&:read_only?)
199
+ properties.select(&:read_only)
91
200
  end
92
201
 
202
+ # Retrieve information about a specific property
203
+ #
204
+ # Example:
205
+ # property = Hubspot::Contact.property('industry_sector')
206
+ # values_for_select = property.options.each_with_object({}) { |prop, ps| ps[prop['value']] = prop['label'] }
207
+ #
208
+ # Returns [Array<Hubspot::Property>] An array of hubspot properties
93
209
  def property(property_name)
94
210
  properties.detect { |prop| prop.name == property_name }
95
211
  end
@@ -106,6 +222,45 @@ module Hubspot
106
222
  }.freeze
107
223
 
108
224
  # rubocop:disable Metrics/MethodLength
225
+
226
+ # Search for resources using a flexible query format and optional properties.
227
+ #
228
+ # This method allows searching for resources by passing a query in the form of a string (for full-text search)
229
+ # or a hash with special suffixes on the keys to define different comparison operators.
230
+ # You can also specify which properties to return and the number of results per page.
231
+ #
232
+ # Available suffixes for query keys (when using a hash):
233
+ # - `_contains`: Matches values that contain the given string.
234
+ # - `_gt`: Greater than comparison.
235
+ # - `_lt`: Less than comparison.
236
+ # - `_gte`: Greater than or equal to comparison.
237
+ # - `_lte`: Less than or equal to comparison.
238
+ # - `_neq`: Not equal to comparison.
239
+ # - `_in`: Matches any of the values in the given array.
240
+ #
241
+ # If no suffix is provided, the default comparison is equality (`EQ`).
242
+ #
243
+ # query - [String, Hash] The query for searching. This can be either:
244
+ # - A String: for full-text search.
245
+ # - A Hash: where each key represents a property and may have suffixes for the comparison
246
+ # (e.g., `{ email_contains: 'example.org', age_gt: 30 }`).
247
+ # properties - An optional array of property names to return in the search results. [Array<String>]
248
+ # If not specified or empty, HubSpot will return the default set of properties.
249
+ # page_size - The number of results to return per page (default is 10 for contacts and 100 for everything else).
250
+ #
251
+ # Example Usage:
252
+ # # Full-text search for 'example.org':
253
+ # contacts = Hubspot::Contact.search(query: "example.org",
254
+ # properties: ["email", "firstname", "lastname"], page_size: 50)
255
+ #
256
+ # # Search for contacts whose email contains 'example.org' and are older than 30:
257
+ # contacts = Hubspot::Contact.search(
258
+ # query: { email_contains: 'example.org', age_gt: 30 },
259
+ # properties: ["email", "firstname", "lastname"],
260
+ # page_size: 50
261
+ # )
262
+ #
263
+ # Returns [PagedCollection] A paged collection of results that can be iterated over.
109
264
  def search(query:, properties: [], page_size: 100)
110
265
  search_body = {}
111
266
 
@@ -185,6 +340,23 @@ module Hubspot
185
340
  end
186
341
 
187
342
  # rubocop:disable Ling/MissingSuper
343
+
344
+ # Public: Initialize a resouce
345
+ #
346
+ # data - [2D Hash, nested Hash] data to initialise the resourse This can be either:
347
+ # - A Simple 2D Hash, key value pairs of property => value (for the create option)
348
+ # - A structured hash consisting of { id: <hs_object_id>, properties: {}, ... }
349
+ # This is the same structure as per the API, and can be rebuilt if you store the id
350
+ # of the object against your own data
351
+ #
352
+ # Example:
353
+ # contact = Hubspot::Contact.new(firstname: 'Luke', lastname: 'Skywalker', email: 'luke@jedi.org')
354
+ # contact.persisted? # false
355
+ # contact.save # creates the record in Hubspot
356
+ # contact.persisted? # true
357
+ # puts "Contact saved with hubspot id #{contact.id}"
358
+ #
359
+ # existing_contact = Hubspot::Contact.new(id: hubspot_id, properties: contact.to_hubspot_properties)
188
360
  def initialize(data = {})
189
361
  data.transform_keys!(&:to_s)
190
362
  @id = extract_id(data)
@@ -196,13 +368,23 @@ module Hubspot
196
368
  initialize_new_object(data)
197
369
  end
198
370
  end
371
+
199
372
  # rubocop:enable Ling/MissingSuper
200
373
 
374
+ # Determine the state of the object
375
+ #
376
+ # Returns Boolean
201
377
  def changes?
202
378
  !@changes.empty?
203
379
  end
204
380
 
205
- # Instance methods for update (or save)
381
+ # Create or Update the resource.
382
+ # If the resource was already persisted (e.g. it was retrieved from the API)
383
+ # it will be updated using values from @changes
384
+ #
385
+ # If the resource is new (no id) it will be created
386
+ #
387
+ # Returns Boolean
206
388
  def save
207
389
  if persisted?
208
390
  self.class.update(@id, @changes).tap do |result|
@@ -216,11 +398,22 @@ module Hubspot
216
398
  end
217
399
  end
218
400
 
401
+ # If the resource exists in Hubspot
402
+ #
403
+ # Returns Boolean
219
404
  def persisted?
220
405
  @id ? true : false
221
406
  end
222
407
 
223
408
  # Update the resource
409
+ #
410
+ # params - hash of properties to update in key value pairs
411
+ #
412
+ # Example:
413
+ # contact = Hubspot::Contact.find(hubspot_contact_id)
414
+ # contact.update(status: 'gold customer', last_contacted_at: Time.now.utc.iso8601)
415
+ #
416
+ # Returns Boolean
224
417
  def update(params)
225
418
  raise 'Not able to update as not persisted' unless persisted?
226
419
 
@@ -231,6 +424,12 @@ module Hubspot
231
424
  save
232
425
  end
233
426
 
427
+ # Archive the object in Hubspot
428
+ #
429
+ # Example:
430
+ # company = Hubspot::Company.find(hubspot_company_id)
431
+ # company.delete
432
+ #
234
433
  def delete
235
434
  self.class.archive(id)
236
435
  end
@@ -241,7 +440,11 @@ module Hubspot
241
440
  end
242
441
 
243
442
  # rubocop:disable Metrics/MethodLength
244
- # Handle dynamic getter and setter methods with method_missing
443
+
444
+ # getter: Check the properties and changes hashes to see if the method
445
+ # being called is a key, and return the corresponding value
446
+ # setter: If the method ends in "=" persist the value in the changes hash
447
+ # (when it is different from the corresponding value in properties if set)
245
448
  def method_missing(method, *args)
246
449
  method_name = method.to_s
247
450
 
@@ -267,9 +470,10 @@ module Hubspot
267
470
  # Fallback if the method or attribute is not found
268
471
  super
269
472
  end
473
+
270
474
  # rubocop:enable Metrics/MethodLength
271
475
 
272
- # Ensure respond_to_missing? is properly overridden
476
+ # Ensure respond_to_missing? handles existing keys in the properties anc changes hashes
273
477
  def respond_to_missing?(method_name, include_private = false)
274
478
  property_name = method_name.to_s.chomp('=')
275
479
  @properties.key?(property_name) || @changes.key?(property_name) || super
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Hubspot
4
- VERSION = '0.2.1-1'
4
+ VERSION = '0.2.1'
5
5
  end
data/lib/hubspot.rb CHANGED
@@ -20,7 +20,6 @@ module Hubspot
20
20
  yield(config) if block_given?
21
21
  set_client_headers if config.access_token
22
22
  set_request_timeouts
23
- config.apply_log_level
24
23
  end
25
24
 
26
25
  def configured?
@@ -9,30 +9,3 @@ class Object
9
9
  end
10
10
  end
11
11
  end
12
-
13
- # At some point this will seem like a bad idea ;)
14
-
15
- # :nocov:
16
- if RUBY_VERSION < '2.5.0'
17
- class Hash
18
- # Non-mutating version (returns a new hash with transformed keys)
19
- def transform_keys
20
- return enum_for(:transform_keys) unless block_given?
21
- result = {}
22
- each_key do |key|
23
- result[yield(key)] = self[key]
24
- end
25
- result
26
- end
27
-
28
- # Mutating version (modifies the hash in place)
29
- def transform_keys!
30
- return enum_for(:transform_keys!) unless block_given?
31
- keys.each do |key|
32
- self[yield(key)] = delete(key)
33
- end
34
- self
35
- end
36
- end
37
- end
38
- # :nocov:end
@@ -16,7 +16,7 @@ Gem::Specification.new do |spec|
16
16
  spec.homepage = 'https://github.com/sensadrome/ruby_hubspot_api'
17
17
  spec.license = 'MIT'
18
18
 
19
- spec.required_ruby_version = '>= 2.4'
19
+ spec.required_ruby_version = '>= 2.5'
20
20
 
21
21
  # Prevent pushing this gem to RubyGems.org.
22
22
  # To allow pushes either set the 'allowed_push_host'
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby_hubspot_api
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1.pre.1
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Simon Brook
@@ -246,15 +246,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
246
246
  requirements:
247
247
  - - ">="
248
248
  - !ruby/object:Gem::Version
249
- version: '2.4'
249
+ version: '2.5'
250
250
  required_rubygems_version: !ruby/object:Gem::Requirement
251
251
  requirements:
252
- - - ">"
252
+ - - ">="
253
253
  - !ruby/object:Gem::Version
254
- version: 1.3.1
254
+ version: '0'
255
255
  requirements: []
256
- rubyforge_project:
257
- rubygems_version: 2.6.14.4
256
+ rubygems_version: 3.2.3
258
257
  signing_key:
259
258
  specification_version: 4
260
259
  summary: ruby_hubspot_api is an ORM-like wrapper for the Hubspot API