ruby_hubspot_api 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: a9081936b5a9201fa61faff7d03946af84e7a655bc8fb4b87216fe904ed8a147
4
+ data.tar.gz: 7e33a98b6224c769b90327ac2702dbe3752d8ae7d15b7032f1ad195021db7ae8
5
+ SHA512:
6
+ metadata.gz: 3bf538ac27be73eb2a4dbe97e65d6449aa304b40628779836f482014009361586e129a2b363697d1c3b06264b22cbd295233af961f8d18eeef94146c7c46e3d1
7
+ data.tar.gz: 82fb453482303e5fc8ff09404fc3b0e7f1aae13614e6fba98c700b781272c731b03f7f461213a8949bb2220d11c1637db68df1a71215523329352f6d39b2eadc
data/.env.sample ADDED
@@ -0,0 +1,40 @@
1
+ # Sample .env file
2
+ # If you want to run the tests and re-record the cassettes you will need
3
+ # a private app in hubspot with the correct scopes and you will need to
4
+ # grab the access token and the client secret and portal_id
5
+ # see https://developers.hubspot.com/docs/api/private-apps
6
+
7
+ export HUBSPOT_ACCESS_TOKEN=your_private_app_access_token
8
+ export HUBSPOT_CLIENT_SECRET=your_client_secret
9
+ export HUBSPOT_PORTAL_ID=portal_id
10
+
11
+ # VCR configuration
12
+ # record mode can be none, once, newepisodes or all (default none)
13
+ # see https://andrewmcodes.gitbook.io/vcr/record_modes
14
+ export VCR_RECORD_MODE=once
15
+ # to allow new request set to true
16
+ export VCR_ALLOW_REQUESTS=false
17
+
18
+ # Used in specs....
19
+ # The values of the following are the defaults if the env var is not set
20
+
21
+ # Company id used to test find and update (should be real)
22
+ export HUBSPOT_TEST_COMPANY_ID=1
23
+
24
+ # Company name to test create company
25
+ export HUBSPOT_TEST_COMPANY_NAME="Numenor Capital"
26
+
27
+ # Company id to test deleting (hint: make a dummy one first!)
28
+ export HUBSPOT_TEST_COMPANY_ID_DELETE=666
29
+
30
+ # Contact if to test find and update
31
+ export HUBSPOT_TEST_CONTACT_ID=1
32
+
33
+ # domain name to test the search by email contains
34
+ export HUBSPOT_SEARCH_TEST_DOMAIN=hubspot.com
35
+
36
+ # maximum number of records to fetch when testing lists
37
+ export HUBSPOT_SEARCH_LIMIT=5
38
+
39
+ # email address for search on email = <email>
40
+ export HUBSPOT_TEST_CONTACT_EMAIL=test@hubspot.com
data/.gitignore ADDED
@@ -0,0 +1,8 @@
1
+ /.bundle/
2
+ /coverage/
3
+ /tmp/
4
+
5
+ .env
6
+ # rspec failure tracking
7
+ .rspec_status
8
+ .pry_history
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
data/.rubocop.yml ADDED
@@ -0,0 +1,6 @@
1
+ # .rubocop.yml
2
+
3
+ # Ignore Metrics/BlockLength for the spec directory
4
+ Metrics/BlockLength:
5
+ Exclude:
6
+ - spec/**/*.rb
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ 2.5.3
data/CHANGELOG.md ADDED
@@ -0,0 +1,43 @@
1
+ ## v0.1.0
2
+
3
+ - initial setup
4
+ - Setup the configuration block
5
+ - Adds spec for config
6
+ - Set the auth headers when access_token configured
7
+ - Version spec
8
+ - don't test for client id
9
+ - Load api client and add exception handler
10
+ - Initial bases class Resource for api crud
11
+ - Contact class with spec
12
+ - Cassettes for contact spec
13
+ - company model and spec with cassettes
14
+ - Adds PagedCollection for paged results (list / search)
15
+ - Adds Hubspot configuration to tests
16
+ - Update required files
17
+ - Adds list method to return PagedCollection
18
+ - Add interface for search
19
+ - VCR configuration
20
+ - Contact/search cassette
21
+ - Sample ENV file for developers
22
+ - console with configuration if env vars set
23
+ - Readme file
24
+ - MIT license
25
+ - allow connections if vcr_record_mode is on
26
+ - Fix rubocop config
27
+ - Update Readme
28
+ - Log api requests and add interface to set logging
29
+ - Update exception handing logic and add more exception classes
30
+ - Test all parts of the config code
31
+ - Adds user model (aliased to Owner) and specs
32
+ - Add a configured? method to Hubspot module
33
+ - Adds a dummy Hubspot::Property class
34
+ - Update Paged request handling based on method
35
+ - Adds a find_by mechanism for resources
36
+ - Use the Hubspot::Property class to return properties for a given resource object
37
+ - Update the specs for 100% coverage
38
+ - Update the sample .env file
39
+ - Reorder and clarify Readme
40
+ - When we use limit(1) we should only return the object not an array
41
+ - Test that we only get the properties we ask for or the defaults
42
+ - Flatten the properties array into a comma separated list
43
+ - Improve the intialiser
data/Gemfile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
6
+
7
+ # Specify your gem's dependencies in ruby_hubspot_api.gemspec
8
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,78 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ ruby_hubspot_api (0.1.0)
5
+ bundler (~> 2.3, < 3.0)
6
+ dotenv (~> 2.8, < 3.0)
7
+ httparty (~> 0.21, < 1.0)
8
+ pry (~> 0.13, < 1.0)
9
+ pry-byebug (~> 3.9, < 4.0)
10
+ rspec (~> 3.13, < 4.0)
11
+ simplecov (~> 0.22, < 1.0)
12
+ vcr (~> 6.0, < 7.0)
13
+ webmock (~> 3.23, < 4.0)
14
+
15
+ GEM
16
+ remote: https://rubygems.org/
17
+ specs:
18
+ addressable (2.8.7)
19
+ public_suffix (>= 2.0.2, < 7.0)
20
+ bigdecimal (3.1.8)
21
+ byebug (11.1.3)
22
+ coderay (1.1.3)
23
+ crack (1.0.0)
24
+ bigdecimal
25
+ rexml
26
+ diff-lcs (1.5.1)
27
+ docile (1.4.1)
28
+ dotenv (2.8.1)
29
+ hashdiff (1.1.1)
30
+ httparty (0.21.0)
31
+ mini_mime (>= 1.0.0)
32
+ multi_xml (>= 0.5.2)
33
+ method_source (1.1.0)
34
+ mini_mime (1.1.2)
35
+ multi_xml (0.6.0)
36
+ pry (0.13.1)
37
+ coderay (~> 1.1)
38
+ method_source (~> 1.0)
39
+ pry-byebug (3.9.0)
40
+ byebug (~> 11.0)
41
+ pry (~> 0.13.0)
42
+ public_suffix (4.0.7)
43
+ rake (13.2.1)
44
+ rexml (3.3.7)
45
+ rspec (3.13.0)
46
+ rspec-core (~> 3.13.0)
47
+ rspec-expectations (~> 3.13.0)
48
+ rspec-mocks (~> 3.13.0)
49
+ rspec-core (3.13.1)
50
+ rspec-support (~> 3.13.0)
51
+ rspec-expectations (3.13.3)
52
+ diff-lcs (>= 1.2.0, < 2.0)
53
+ rspec-support (~> 3.13.0)
54
+ rspec-mocks (3.13.1)
55
+ diff-lcs (>= 1.2.0, < 2.0)
56
+ rspec-support (~> 3.13.0)
57
+ rspec-support (3.13.1)
58
+ simplecov (0.22.0)
59
+ docile (~> 1.1)
60
+ simplecov-html (~> 0.11)
61
+ simplecov_json_formatter (~> 0.1)
62
+ simplecov-html (0.13.1)
63
+ simplecov_json_formatter (0.1.4)
64
+ vcr (6.0.0)
65
+ webmock (3.23.1)
66
+ addressable (>= 2.8.0)
67
+ crack (>= 0.3.2)
68
+ hashdiff (>= 0.4.0, < 2.0.0)
69
+
70
+ PLATFORMS
71
+ x86_64-darwin-18
72
+
73
+ DEPENDENCIES
74
+ rake (>= 11.0, < 14.0)
75
+ ruby_hubspot_api!
76
+
77
+ BUNDLED WITH
78
+ 2.3.26
data/LICENSE.txt ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2024 Simon Brook
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,225 @@
1
+ # Ruby HubSpot API Gem
2
+
3
+ This gem was largely inspired by [hubspot-api-ruby](https://github.com/captaincontrat/hubspot-api-ruby) which, in turn, was inspired by the [hubspot-ruby](https://github.com/HubspotCommunity/hubspot-ruby) community gem. I wanted to use version 3 of the api and simplify some parts of the interface
4
+
5
+ The Ruby HubSpot API gem is a starting point for building an ORM-like interface to HubSpot's API.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'ruby_hubspot_api'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ ```bash
18
+ $ bundle install
19
+ ```
20
+
21
+ Or install it yourself as:
22
+
23
+ ```bash
24
+ $ gem install ruby_hubspot_api
25
+ ```
26
+
27
+ ## Configuration
28
+
29
+ To authenticate API requests, you need a HubSpot access token. First you will need to add a [private app in hubspot](https://developers.hubspot.com/docs/api/private-apps) When that is setup you can go to the "Auth" tab of your private app page and grab the access token from there
30
+
31
+ You can configure the gem by adding this code to your initializer (for Rails) or to your startup configuration (in any other environment):
32
+
33
+ ```ruby
34
+ Hubspot.configure do |config|
35
+ config.access_token = 'your_access_token'
36
+ end
37
+ ```
38
+
39
+ This configuration ensures that your API requests are authenticated using your HubSpot access token.
40
+
41
+ ## Working with Objects
42
+
43
+ This gem allows you to interact with HubSpot objects such as contacts and companies. You can perform operations on individual instances (e.g., creating or updating records) as well as on collections (e.g., listing or searching).
44
+
45
+ ### Instance Methods
46
+
47
+ #### Creating and Saving an Object
48
+
49
+ You can instantiate a new resource (such as a contact) by passing a hash of properties when creating the object. After setting the properties, calling `save` will persist the object to the HubSpot API.
50
+
51
+ Example:
52
+
53
+ ```ruby
54
+ new_contact = Hubspot::Contact.new(firstname: 'John', lastname: 'Doe', email: 'john.doe@example.com')
55
+
56
+ # Save the contact to HubSpot
57
+ new_contact.save
58
+
59
+ # After saving, the contact will be assigned an ID by the API
60
+ puts "New contact ID: #{new_contact.id}"
61
+ ```
62
+
63
+ #### Updating an Existing Object
64
+
65
+ To update an existing object, you can either modify the object and call `save`, or use the `update` method specifying the properties you want to update
66
+
67
+ Example using `save`:
68
+
69
+ ```ruby
70
+ contact = Hubspot::Contact.find(1)
71
+ contact.lastname = 'DoeUpdated'
72
+ contact.save # true
73
+ ```
74
+
75
+ Example using `update`:
76
+
77
+ ```ruby
78
+ contact = Hubspot::Contact.find(1)
79
+ contact.update(lastname: 'DoeUpdated') # true
80
+ ```
81
+
82
+ ### Class Methods
83
+
84
+ #### Listing Objects
85
+
86
+ You can list all objects (such as contacts) using the `list` method, which returns a `PagedCollection`. This collection handles paginated results and responds to methods like `each_page`, `each`, and `all`. You can also pass the `page_size` parameter to control the number of records returned per page.
87
+
88
+ Example:
89
+
90
+ ```ruby
91
+ contacts = Hubspot::Contact.list(page_size: 10)
92
+
93
+ # Using each_page to iterate over pages
94
+ contacts.each_page do |page|
95
+ page.each do |contact|
96
+ puts "Contact: #{contact.firstname} #{contact.lastname}"
97
+ end
98
+ end
99
+
100
+ # Or iterate over all contacts without worrying about pagination
101
+ contacts.each do |contact|
102
+ puts "Contact: #{contact.firstname} #{contact.lastname}"
103
+ end
104
+
105
+ # Get all contacts at once (use with caution for large datasets)
106
+ all_contacts = contacts.all
107
+ ```
108
+
109
+ #### Retrieving the first n items
110
+
111
+ You can use the `first` method to retrieve the first item or a specified number of items:
112
+
113
+ ```ruby
114
+ contacts = Hubspot::Contact.list(page_size: 10)
115
+
116
+ # Retrieve the first contact
117
+ first_contact = contacts.first
118
+
119
+ # Retrieve the first 5 contacts
120
+ first_five_contacts = contacts.first(5)
121
+ ```
122
+
123
+ This will automatically set the limits and handle paging for the most efficient API calls while honouring the maximum page count for hubspot resources
124
+
125
+ #### Searching
126
+
127
+ You can search for objects by passing query parameters to the `search` method. HubSpot supports several operators such as `eq`, `gte`, `lt`, and `IN` for filtering.
128
+
129
+ Example:
130
+
131
+ ```ruby
132
+ # Search for contacts with email containing "hubspot.com"
133
+ contacts = Hubspot::Contact.search(query: { email_contains: 'hubspot.com' })
134
+
135
+ contacts.each do |contact|
136
+ puts "Found: #{contact.email}"
137
+ end
138
+
139
+ # Search for companies with number of employees greater than or equal to 100
140
+ companies = Hubspot::Company.search(number_of_employees_gte: 100)
141
+
142
+ companies.each do |company|
143
+ puts "Found: #{company.name}, Employees: #{company.number_of_employees}"
144
+ end
145
+
146
+ # Search for contacts with email in a specific list (IN operator)
147
+ contacts = Hubspot::Contact.search(email_in: ['user1@example.com', 'user2@example.com'])
148
+
149
+ contacts.each do |contact|
150
+ puts "Found: #{contact.email}"
151
+ end
152
+ ```
153
+
154
+ ### Available Search Operators:
155
+ - **eq**: Equal to.
156
+ - **neq**: Not equal to.
157
+ - **gte**: Greater than or equal to.
158
+ - **lte**: Less than or equal to.
159
+ - **IN**: Matches any of the values in an array.
160
+
161
+ #### Specifying Properties in Search
162
+
163
+ When performing a search, you can also specify which properties to return. If you specify any properties, you will only get those properties back, and the default HubSpot properties will not be included automatically.
164
+
165
+ Example:
166
+
167
+ ```ruby
168
+ # Search for contacts with email containing "hubspot.com" and only return specific properties
169
+ contacts = Hubspot::Contact.search(
170
+ query: { email_contains: 'hubspot.com' },
171
+ properties: ['firstname', 'lastname', 'email', 'mobile', 'custom_property_1']
172
+ )
173
+
174
+ contacts.each do |contact|
175
+ puts "Name: #{contact.firstname} #{contact.lastname}, Email: #{contact.email}, Mobile: #{contact.mobile}"
176
+ end
177
+ ```
178
+
179
+ ## Contributing
180
+
181
+ There is much to do (including writing a TODO list, or at least adding issues in github!) but this should provide a solid start
182
+
183
+ If you're interested in contributing to the gem, follow the instructions below.
184
+
185
+ ### Developer Setup
186
+
187
+ A `.env.sample` file is provided with all the environment variables needed for development, including testing credentials. To set up your environment:
188
+
189
+ 1. Copy the `.env.sample` file to `.env`.
190
+ 2. Update the values with your own credentials (e.g., your `HUBSPOT_ACCESS_TOKEN`).
191
+
192
+ The `.env` file will be used to configure your access to the HubSpot API and ensure that environment variables are properly loaded during development.
193
+
194
+ ### Using VCR for Testing
195
+
196
+ We use VCR for recording and replaying HTTP requests during testing. You can control the VCR recording mode by setting the `VCR_RECORD_MODE` environment variable as a string. The following modes are supported:
197
+
198
+ - `none` (default): No new requests are recorded; only replay from existing cassettes.
199
+ - `all`: Records all requests, overwriting existing cassettes.
200
+ - `new_episodes`: Records new requests, but keeps existing cassettes unchanged.
201
+ - `once`: Records the first time tests are run, and replays on subsequent runs.
202
+
203
+ You can specify the `VCR_RECORD_MODE` either via the command line or in the `.env` file (see the `.env.sample` file for examples).
204
+
205
+ To change the record mode on the command line, use:
206
+
207
+ ```bash
208
+ $ export VCR_RECORD_MODE=all
209
+ ```
210
+
211
+ For more information on how VCR modes work, refer to the [VCR documentation](https://andrewmcodes.gitbook.io/vcr/record_modes).
212
+
213
+ ### Running Tests
214
+
215
+ To run the tests, simply execute:
216
+
217
+ ```bash
218
+ $ rspec
219
+ ```
220
+
221
+ Ensure you have your `.env` file configured with a valid `HUBSPOT_ACCESS_TOKEN` for API integration tests if you want to rerecord your interactions.
222
+
223
+ ## License
224
+
225
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
data/bin/console ADDED
@@ -0,0 +1,16 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ require 'bundler/setup'
5
+ require 'dotenv/load'
6
+ require 'pry'
7
+ require 'ruby_hubspot_api'
8
+ require 'openssl'
9
+
10
+ Hubspot.configure do |config|
11
+ config.access_token = ENV['HUBSPOT_ACCESS_TOKEN']
12
+ config.portal_id = ENV['HUBSPOT_PORTAL_ID']
13
+ config.client_secret = ENV['HUBSPOT_CLIENT_SECRET']
14
+ end
15
+
16
+ Pry.start
data/bin/setup ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,77 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hubspot
4
+ # All interations with the Hubspot API happen here...
5
+ class ApiClient
6
+ include HTTParty
7
+ base_uri 'https://api.hubapi.com'
8
+
9
+ headers 'Content-Type' => 'application/json'
10
+
11
+ def handle_response(response)
12
+ self.class.handle_response(response)
13
+ end
14
+
15
+ class << self
16
+ def get(url, options = {})
17
+ ensure_configuration!
18
+
19
+ if options[:query] && options[:query][:properties].is_a?(Array)
20
+ options[:query][:properties] = options[:query][:properties].join(',')
21
+ end
22
+
23
+ start_time = Time.now
24
+ response = super(url, options)
25
+
26
+ request = HTTParty::Request.new(Net::HTTP::Get, url, options)
27
+ log_request(:get, request.uri.to_s, response, start_time)
28
+ response
29
+ end
30
+
31
+ def post(url, options = {})
32
+ ensure_configuration!
33
+ start_time = Time.now
34
+ response = super(url, options)
35
+ log_request(:post, url, response, start_time)
36
+ response
37
+ end
38
+
39
+ def patch(url, options = {})
40
+ ensure_configuration!
41
+ start_time = Time.now
42
+ response = super(url, options)
43
+ log_request(:patch, url, response, start_time)
44
+ response
45
+ end
46
+
47
+ def delete(url, options = {})
48
+ ensure_configuration!
49
+ start_time = Time.now
50
+ response = super(url, options)
51
+ log_request(:delete, url, response, start_time)
52
+ response
53
+ end
54
+
55
+ def log_request(http_method, url, response, start_time)
56
+ d = Time.now - start_time
57
+ Hubspot.logger.info("#{http_method.to_s.upcase} #{url} took #{d.round(2)}s with status #{response.code}")
58
+ Hubspot.logger.debug("Response body: #{response.body}") if Hubspot.logger.debug?
59
+ end
60
+
61
+ def handle_response(response)
62
+ if response.success?
63
+ response.parsed_response
64
+ else
65
+ Hubspot.logger.error("API Error: #{response.code} - #{response.body}")
66
+ raise Hubspot.error_from_response(response)
67
+ end
68
+ end
69
+
70
+ private
71
+
72
+ def ensure_configuration!
73
+ raise NotConfiguredError, 'Hubspot API not configured' unless Hubspot.configured?
74
+ end
75
+ end
76
+ end
77
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hubspot
4
+ class Company < Resource
5
+ end
6
+ end
@@ -0,0 +1,59 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hubspot
4
+ # To hold Hubspot configuration
5
+ class Config
6
+ attr_accessor :access_token, :portal_id, :client_secret, :logger, :log_level
7
+
8
+ def initialize
9
+ @access_token = nil
10
+ @portal_id = nil
11
+ @client_secret = nil
12
+ @logger = initialize_logger
13
+ @log_level = determine_log_level
14
+ apply_log_level
15
+ end
16
+
17
+ private
18
+
19
+ # Initialize the default logger
20
+ def initialize_logger
21
+ Logger.new($stdout)
22
+ end
23
+
24
+ # Map string values from environment variables to Logger constants
25
+ # rubocop:disable Metrics/MethodLength
26
+ def determine_log_level
27
+ env_log_level = ENV['HUBSPOT_LOG_LEVEL'] || default_log_level
28
+ case env_log_level.to_s.upcase
29
+ when 'DEBUG'
30
+ Logger::DEBUG
31
+ when 'INFO'
32
+ Logger::INFO
33
+ when 'WARN'
34
+ Logger::WARN
35
+ when 'ERROR'
36
+ Logger::ERROR
37
+ when 'FATAL'
38
+ Logger::FATAL
39
+ else
40
+ Logger::INFO # Default to INFO if unrecognized
41
+ end
42
+ end
43
+ # rubocop:enable Metrics/MethodLength
44
+
45
+ # Apply the log level to the logger
46
+ def apply_log_level
47
+ @logger.level = @log_level
48
+ end
49
+
50
+ # Set the default log level based on environment
51
+ def default_log_level
52
+ if defined?(Rails) && Rails.env.test?
53
+ 'FATAL' # Default to FATAL in test environments
54
+ else
55
+ 'INFO' # Default to INFO in normal usage
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,6 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Hubspot
4
+ class Contact < Resource
5
+ end
6
+ end
@@ -0,0 +1,36 @@
1
+ # frozen_string_literal: true
2
+
3
+ # The main hubspot module
4
+ module Hubspot
5
+ # define the Hubspot specific error classes
6
+ class RequestError < StandardError
7
+ attr_accessor :response
8
+
9
+ def initialize(response, message = nil)
10
+ message = response.parsed_response['message'] if !message && response.respond_to?(:parsed_response)
11
+ message += "\n" if message
12
+ me = super("#{message}Response body: #{response.body}",)
13
+ me.response = response
14
+ end
15
+ end
16
+
17
+ class NotFoundError < RequestError; end
18
+ class OauthScopeError < RequestError; end
19
+ class RateLimitExceededError < RequestError; end
20
+ class NotConfiguredError < StandardError; end
21
+ class ArgumentError < StandardError; end
22
+
23
+ class << self
24
+ def error_from_response(response)
25
+ return NotFoundError.new(response) if response.not_found?
26
+ return RateLimitExceededError.new(response) if response.code == 429
27
+
28
+ case response.body
29
+ when /MISSING_SCOPES/, /You do not have permissions/i
30
+ OauthScopeError.new(response, 'Private app missing required scopes')
31
+ else
32
+ RequestError.new(response)
33
+ end
34
+ end
35
+ end
36
+ end