ruby_hubspot_api 0.2.1 → 0.2.1.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA256:
3
- metadata.gz: f455ed36bd0ae0284959198213bea7924099b97fc0b43b4ac50b4ad21a73def2
4
- data.tar.gz: 9ba207fcf4fdf8c14889d130a0cdd3284ff75816873d994084d80b410e8306e1
2
+ SHA1:
3
+ metadata.gz: ae46636189d9ad859e0e342eed9b752ccbd64c06
4
+ data.tar.gz: 3cf0de6c387b00810af776e6b4ff89bcdcc00230
5
5
  SHA512:
6
- metadata.gz: 0d4274f0519d4fe99a09f06405689a3b45145a6890b4c5a1052e7e6e38bf91ae4ce9d96669d8bb97a5acd7e92110a0eeac4c73e7e0e6ea3b93fd1393f2f4c648
7
- data.tar.gz: 42829d5342d0dbd126b9200b609c662518dce48e55a82a6e3f6536ee4ed7bdf1c9af14007114e1f883ca036df53cc49522d239d803e5bdfceb525170a18adbac
6
+ metadata.gz: ebdaa4d4f2bb6f1f7b6c9fede064598daf78edcf2204322819d2a13e7dbd504ff1792a7afd75037a4eae24171cd9b52d962dc6e2eb7439fe5bb9a84ad6733a22
7
+ data.tar.gz: fa2dd031fa494b3bd8c68880d68aa19603035bbf32395a7e3650eefa8906507d6e0790020e032002612d59c516c5eb97b371b69f2f1ff563a4819006aa5d6180
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ruby_hubspot_api (0.2)
4
+ ruby_hubspot_api (0.2.1)
5
5
  httparty (>= 0.1, < 1.0)
6
6
 
7
7
  GEM
@@ -9,35 +9,33 @@ GEM
9
9
  specs:
10
10
  addressable (2.8.7)
11
11
  public_suffix (>= 2.0.2, < 7.0)
12
- bigdecimal (3.1.8)
12
+ bigdecimal (3.0.2)
13
13
  byebug (11.1.3)
14
- codecov (0.2.12)
15
- json
16
- simplecov
14
+ codecov (0.6.0)
15
+ simplecov (>= 0.15, < 0.22)
17
16
  coderay (1.1.3)
18
17
  crack (1.0.0)
19
18
  bigdecimal
20
19
  rexml
21
20
  diff-lcs (1.5.1)
22
- docile (1.4.1)
21
+ docile (1.3.5)
23
22
  dotenv (2.8.1)
24
23
  hashdiff (1.1.1)
25
24
  httparty (0.21.0)
26
25
  mini_mime (>= 1.0.0)
27
26
  multi_xml (>= 0.5.2)
28
- json (2.7.2)
29
27
  method_source (1.1.0)
30
28
  mini_mime (1.1.2)
31
29
  multi_xml (0.6.0)
32
- pry (0.13.1)
30
+ pry (0.14.2)
33
31
  coderay (~> 1.1)
34
32
  method_source (~> 1.0)
35
- pry-byebug (3.9.0)
33
+ pry-byebug (3.8.0)
36
34
  byebug (~> 11.0)
37
- pry (~> 0.13.0)
35
+ pry (~> 0.10)
38
36
  public_suffix (4.0.7)
39
37
  rake (13.2.1)
40
- rexml (3.3.7)
38
+ rexml (3.2.5)
41
39
  rspec (3.13.0)
42
40
  rspec-core (~> 3.13.0)
43
41
  rspec-expectations (~> 3.13.0)
@@ -51,15 +49,13 @@ GEM
51
49
  diff-lcs (>= 1.2.0, < 2.0)
52
50
  rspec-support (~> 3.13.0)
53
51
  rspec-support (3.13.1)
54
- simplecov (0.22.0)
52
+ simplecov (0.18.5)
55
53
  docile (~> 1.1)
56
54
  simplecov-html (~> 0.11)
57
- simplecov_json_formatter (~> 0.1)
58
55
  simplecov-html (0.13.1)
59
56
  simplecov-lcov (0.8.0)
60
- simplecov_json_formatter (0.1.4)
61
57
  vcr (6.0.0)
62
- webmock (3.23.1)
58
+ webmock (3.18.1)
63
59
  addressable (>= 2.8.0)
64
60
  crack (>= 0.3.2)
65
61
  hashdiff (>= 0.4.0, < 2.0.0)
@@ -84,4 +80,4 @@ DEPENDENCIES
84
80
  webmock (>= 3.0)
85
81
 
86
82
  BUNDLED WITH
87
- 2.3.27
83
+ 2.2.34
@@ -1,5 +1,7 @@
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.
3
5
  module Hubspot
4
6
  # All interations with the Hubspot API happen here...
5
7
  class ApiClient
@@ -15,6 +15,11 @@ 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
+
18
23
  private
19
24
 
20
25
  # Initialize the default logger
@@ -43,11 +48,6 @@ module Hubspot
43
48
  end
44
49
  # rubocop:enable Metrics/MethodLength
45
50
 
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,65 +6,20 @@ require_relative './paged_batch'
6
6
 
7
7
  module Hubspot
8
8
  # rubocop:disable Metrics/ClassLength
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
- #
9
+ # Hubspot::Resource class
26
10
  class Resource < ApiClient
27
11
  METADATA_FIELDS = %w[createdate hs_object_id lastmodifieddate].freeze
28
12
 
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
13
+ # Allow read/write access to properties and metadata
14
+ attr_accessor :id, :properties, :changes, :metadata
42
15
 
43
16
  class << self
44
17
  # 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.
52
18
  def find(id)
53
19
  response = get("/crm/v3/objects/#{resource_name}/#{id}")
54
20
  instantiate_from_response(response)
55
21
  end
56
22
 
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.
68
23
  def find_by(property, value, properties = nil)
69
24
  params = { idProperty: property }
70
25
  params[:properties] = properties if properties.is_a?(Array)
@@ -72,28 +27,12 @@ module Hubspot
72
27
  instantiate_from_response(response)
73
28
  end
74
29
 
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.
30
+ # Create a new resource
83
31
  def create(params)
84
32
  response = post("/crm/v3/objects/#{resource_name}", body: { properties: params }.to_json)
85
33
  instantiate_from_response(response)
86
34
  end
87
35
 
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
97
36
  def update(id, params)
98
37
  response = patch("/crm/v3/objects/#{resource_name}/#{id}", body: { properties: params }.to_json)
99
38
  raise Hubspot.error_from_response(response) unless response.success?
@@ -101,14 +40,6 @@ module Hubspot
101
40
  true
102
41
  end
103
42
 
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
112
43
  def archive(id)
113
44
  response = delete("/crm/v3/objects/#{resource_name}/#{id}")
114
45
  raise Hubspot.error_from_response(response) unless response.success?
@@ -116,14 +47,6 @@ module Hubspot
116
47
  true
117
48
  end
118
49
 
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.
127
50
  def list(params = {})
128
51
  PagedCollection.new(
129
52
  url: "/crm/v3/objects/#{resource_name}",
@@ -132,17 +55,6 @@ module Hubspot
132
55
  )
133
56
  end
134
57
 
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)
146
58
  def batch_read(object_ids = [], id_property: 'id')
147
59
  params = id_property == 'id' ? {} : { idProperty: id_property }
148
60
 
@@ -154,23 +66,11 @@ module Hubspot
154
66
  )
155
67
  end
156
68
 
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
167
69
  def batch_read_all(object_ids = [], id_property: 'id')
168
70
  Hubspot::Batch.read(self, object_ids, id_property: id_property)
169
71
  end
170
72
 
171
- # Retrieve the complete list of properties for this resource class
172
- #
173
- # Returns [Array<Hubspot::Property>] An array of hubspot properties
73
+ # Get the complete list of fields (properties) for the object
174
74
  def properties
175
75
  @properties ||= begin
176
76
  response = get("/crm/v3/properties/#{resource_name}")
@@ -178,34 +78,18 @@ module Hubspot
178
78
  end
179
79
  end
180
80
 
181
- # Retrieve the complete list of user defined properties for this resource class
182
- #
183
- # Returns [Array<Hubspot::Property>] An array of hubspot properties
184
81
  def custom_properties
185
82
  properties.reject { |property| property['hubspotDefined'] }
186
83
  end
187
84
 
188
- # Retrieve the complete list of updatable properties for this resource class
189
- #
190
- # Returns [Array<Hubspot::Property>] An array of updateable hubspot properties
191
85
  def updatable_properties
192
86
  properties.reject(&:read_only?)
193
87
  end
194
88
 
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
198
89
  def read_only_properties
199
- properties.select(&:read_only)
90
+ properties.select(&:read_only?)
200
91
  end
201
92
 
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
209
93
  def property(property_name)
210
94
  properties.detect { |prop| prop.name == property_name }
211
95
  end
@@ -222,45 +106,6 @@ module Hubspot
222
106
  }.freeze
223
107
 
224
108
  # 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.
264
109
  def search(query:, properties: [], page_size: 100)
265
110
  search_body = {}
266
111
 
@@ -340,23 +185,6 @@ module Hubspot
340
185
  end
341
186
 
342
187
  # 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)
360
188
  def initialize(data = {})
361
189
  data.transform_keys!(&:to_s)
362
190
  @id = extract_id(data)
@@ -368,23 +196,13 @@ module Hubspot
368
196
  initialize_new_object(data)
369
197
  end
370
198
  end
371
-
372
199
  # rubocop:enable Ling/MissingSuper
373
200
 
374
- # Determine the state of the object
375
- #
376
- # Returns Boolean
377
201
  def changes?
378
202
  !@changes.empty?
379
203
  end
380
204
 
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
205
+ # Instance methods for update (or save)
388
206
  def save
389
207
  if persisted?
390
208
  self.class.update(@id, @changes).tap do |result|
@@ -398,22 +216,11 @@ module Hubspot
398
216
  end
399
217
  end
400
218
 
401
- # If the resource exists in Hubspot
402
- #
403
- # Returns Boolean
404
219
  def persisted?
405
220
  @id ? true : false
406
221
  end
407
222
 
408
223
  # 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
417
224
  def update(params)
418
225
  raise 'Not able to update as not persisted' unless persisted?
419
226
 
@@ -424,12 +231,6 @@ module Hubspot
424
231
  save
425
232
  end
426
233
 
427
- # Archive the object in Hubspot
428
- #
429
- # Example:
430
- # company = Hubspot::Company.find(hubspot_company_id)
431
- # company.delete
432
- #
433
234
  def delete
434
235
  self.class.archive(id)
435
236
  end
@@ -440,11 +241,7 @@ module Hubspot
440
241
  end
441
242
 
442
243
  # rubocop:disable Metrics/MethodLength
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)
244
+ # Handle dynamic getter and setter methods with method_missing
448
245
  def method_missing(method, *args)
449
246
  method_name = method.to_s
450
247
 
@@ -470,10 +267,9 @@ module Hubspot
470
267
  # Fallback if the method or attribute is not found
471
268
  super
472
269
  end
473
-
474
270
  # rubocop:enable Metrics/MethodLength
475
271
 
476
- # Ensure respond_to_missing? handles existing keys in the properties anc changes hashes
272
+ # Ensure respond_to_missing? is properly overridden
477
273
  def respond_to_missing?(method_name, include_private = false)
478
274
  property_name = method_name.to_s.chomp('=')
479
275
  @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'
4
+ VERSION = '0.2.1.1'
5
5
  end
data/lib/hubspot.rb CHANGED
@@ -20,6 +20,7 @@ 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
23
24
  end
24
25
 
25
26
  def configured?
@@ -9,3 +9,30 @@ 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.5'
19
+ spec.required_ruby_version = '>= 2.4'
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
4
+ version: 0.2.1.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Simon Brook
@@ -246,14 +246,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
246
246
  requirements:
247
247
  - - ">="
248
248
  - !ruby/object:Gem::Version
249
- version: '2.5'
249
+ version: '2.4'
250
250
  required_rubygems_version: !ruby/object:Gem::Requirement
251
251
  requirements:
252
252
  - - ">="
253
253
  - !ruby/object:Gem::Version
254
254
  version: '0'
255
255
  requirements: []
256
- rubygems_version: 3.2.3
256
+ rubyforge_project:
257
+ rubygems_version: 2.6.14.4
257
258
  signing_key:
258
259
  specification_version: 4
259
260
  summary: ruby_hubspot_api is an ORM-like wrapper for the Hubspot API