hubspot-api-ruby 0.15.0 → 0.17.0

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
2
  SHA256:
3
- metadata.gz: 5b5da1c5b3161e39ad26020948f72dc349ec275140714ed29b470e9081c0e22d
4
- data.tar.gz: e0fbef872458028ef540fe2fac43816980f2a4ad6862ee3acdaf68f6c12fc907
3
+ metadata.gz: 1c10bc271fecc20b749272010f29ca4d5e667872c39ed5ecd68a2cfd564b8311
4
+ data.tar.gz: c4b4459027deb4700a09876fd9d4e46a450753f26c83e982383f15121379571f
5
5
  SHA512:
6
- metadata.gz: 2ddeb851b64faacbed0a42a1019d28c7a04b0899454db482188a7c53f6f9c397ad929fdf445d1143b9cfd85742d595b085e7e58c37b2de988307bc74e15665da
7
- data.tar.gz: f2bfebd54dfecd85121f49399d271a1bd3a917b58db832639f983ca98897610e064525a43e645dda305f16d57b4316bae633b65a57289c2211a724c9ac934e8f
6
+ metadata.gz: a7d72b4aef781a7ba1857859d1572e7df94ba10635ebd13687012e9b2895bc1d0b7e16e19b6ce48cbc5fd736137eab144d7bed289a5c70607a576421404a779e
7
+ data.tar.gz: 160173f51c195de7214027940d471ee999fdf7df351a05f36654ba669aa50091c1e3d16cd7e0da1d6fe355398bedeec60777a92615cbd9bd63ce84b07924172f
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = "hubspot-api-ruby"
3
- s.version = "0.15.0"
3
+ s.version = "0.17.0"
4
4
  s.require_paths = ["lib"]
5
5
  s.authors = ["Jonathan"]
6
6
  s.email = ["jonathan@hoggo.com"]
@@ -15,7 +15,7 @@ Gem::Specification.new do |s|
15
15
  "changelog_uri" => "https://github.com/captaincontrat/hubspot-api-ruby/blob/master/History.md"
16
16
  }
17
17
 
18
- s.required_ruby_version = ">= 2.7"
18
+ s.required_ruby_version = ">= 3.1"
19
19
 
20
20
  # Add runtime dependencies here
21
21
  s.add_runtime_dependency "activesupport", ">= 4.2.2"
@@ -17,6 +17,18 @@ class Hubspot::Association
17
17
  },
18
18
  "Contact" => {
19
19
  "Deal" => 4
20
+ },
21
+ "Ticket" => {
22
+ "Contact" => 16,
23
+ "Deal" => 28,
24
+ "Company" => 339,
25
+ "Task" => 229
26
+ },
27
+ "Task" => {
28
+ "Contact" => 204,
29
+ "Deal" => 216,
30
+ "Company" => 192,
31
+ "Ticket" => 230
20
32
  }
21
33
  }.freeze
22
34
 
@@ -10,30 +10,33 @@ module Hubspot
10
10
  handle_response(response).parsed_response
11
11
  end
12
12
 
13
- def post_json(path, opts)
14
- no_parse = opts[:params].delete(:no_parse) { false }
13
+ def post_json(path, options)
14
+ modification_query(:post, path, options)
15
+ end
15
16
 
16
- url = generate_url(path, opts[:params])
17
- response = post(
18
- url,
19
- body: opts[:body].to_json,
20
- headers: { 'Content-Type' => 'application/json' },
21
- format: :json,
22
- read_timeout: read_timeout(opts),
23
- open_timeout: open_timeout(opts)
24
- )
17
+ def put_json(path, options)
18
+ modification_query(:put, path, options)
19
+ end
20
+
21
+ def patch_json(path, options)
22
+ modification_query(:patch, path, options)
23
+ end
25
24
 
25
+ def delete_json(path, opts)
26
+ url = generate_url(path, opts)
27
+ response = delete(url, format: :json, read_timeout: read_timeout(opts), open_timeout: open_timeout(opts))
26
28
  log_request_and_response url, response, opts[:body]
27
- handle_response(response).yield_self do |r|
28
- no_parse ? r : r.parsed_response
29
- end
29
+ handle_response(response)
30
30
  end
31
31
 
32
- def put_json(path, options)
32
+ protected
33
+
34
+ def modification_query(verb, path, options)
33
35
  no_parse = options[:params].delete(:no_parse) { false }
34
36
  url = generate_url(path, options[:params])
35
37
 
36
- response = put(
38
+ response = send(
39
+ verb,
37
40
  url,
38
41
  body: options[:body].to_json,
39
42
  headers: { "Content-Type" => "application/json" },
@@ -48,15 +51,6 @@ module Hubspot
48
51
  end
49
52
  end
50
53
 
51
- def delete_json(path, opts)
52
- url = generate_url(path, opts)
53
- response = delete(url, format: :json, read_timeout: read_timeout(opts), open_timeout: open_timeout(opts))
54
- log_request_and_response url, response, opts[:body]
55
- handle_response(response)
56
- end
57
-
58
- protected
59
-
60
54
  def read_timeout(opts = {})
61
55
  opts.delete(:read_timeout) || Hubspot::Config.read_timeout
62
56
  end
@@ -26,8 +26,11 @@ module Hubspot
26
26
  }
27
27
  end
28
28
 
29
- def find(id)
30
- response = Hubspot::Connection.get_json(MEETING_PATH, { meeting_id: id, properties: BASE_PROPERTIES.join(',') })
29
+ def find(id, opts = {})
30
+ input_properties = opts[:properties].presence || []
31
+ properties = BASE_PROPERTIES | input_properties.compact
32
+
33
+ response = Hubspot::Connection.get_json(MEETING_PATH, { meeting_id: id, properties: properties.join(',') })
31
34
  new(response)
32
35
  end
33
36
 
@@ -36,6 +39,7 @@ module Hubspot
36
39
  limit: opts[:limit].presence || 100,
37
40
  after: opts[:after].presence
38
41
  }.compact
42
+ properties = opts[:properties].presence || []
39
43
 
40
44
  default_filters = [{ propertyName: 'associations.contact', 'operator': 'EQ', value: contact_id }]
41
45
  default_sorts = [{ propertyName: "hs_lastmodifieddate", direction: "DESCENDING" }]
@@ -44,7 +48,7 @@ module Hubspot
44
48
  params: {},
45
49
  body: {
46
50
  **params,
47
- properties: BASE_PROPERTIES,
51
+ properties: BASE_PROPERTIES | properties.compact,
48
52
  filters: (opts[:filters].presence || []) + default_filters,
49
53
  sorts: opts[:sorts].presence || default_sorts
50
54
  }
@@ -0,0 +1,46 @@
1
+ require 'hubspot/utils'
2
+
3
+ module Hubspot
4
+ #
5
+ # HubSpot Tasks API
6
+ #
7
+ # {https://developers.hubspot.com/beta-docs/guides/api/crm/engagements/tasks}
8
+ #
9
+ class Task
10
+ TASKS_PATH = '/crm/v3/objects/tasks'
11
+ TASK_PATH = '/crm/v3/objects/tasks/:task_id'
12
+ DEFAULT_TASK_FIELDS = 'hs_timestamp,hs_task_body,hubspot_owner_id,hs_task_subject,hs_task_status,hs_task_priority,'\
13
+ 'hs_task_type,hs_task_reminders'
14
+
15
+ attr_reader :properties, :id
16
+
17
+ def initialize(response_hash)
18
+ @id = response_hash['id']
19
+ @properties = response_hash['properties'].deep_symbolize_keys
20
+ end
21
+
22
+ class << self
23
+ def create!(params = {}, ticket_id: nil)
24
+ associations_hash = { 'associations' => [] }
25
+ if ticket_id.present?
26
+ associations_hash['associations'] << {
27
+ "to": { "id": ticket_id },
28
+ "types": [{ "associationCategory": 'HUBSPOT_DEFINED',
29
+ "associationTypeId": Hubspot::Association::ASSOCIATION_DEFINITIONS['Task']['Ticket'] }]
30
+ }
31
+ end
32
+ properties = { hs_task_status: 'NOT_STARTED', hs_task_type: 'TODO' }.merge(params)
33
+ post_data = associations_hash.merge({ properties: properties })
34
+
35
+ response = Hubspot::Connection.post_json(TASKS_PATH, params: {}, body: post_data)
36
+ new(response)
37
+ end
38
+
39
+ def find(task_id, properties = DEFAULT_TASK_FIELDS)
40
+ response = Hubspot::Connection.get_json(TASK_PATH, { task_id: task_id,
41
+ properties: properties })
42
+ new(response)
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,62 @@
1
+ require 'hubspot/utils'
2
+
3
+ module Hubspot
4
+ #
5
+ # HubSpot Tickets API
6
+ #
7
+ # {https://developers.hubspot.com/beta-docs/guides/api/crm/objects/tickets}
8
+ #
9
+ class Ticket
10
+ TICKETS_PATH = '/crm/v3/objects/tickets'
11
+ TICKET_PATH = '/crm/v3/objects/tickets/:ticket_id'
12
+
13
+ attr_reader :properties, :id
14
+
15
+ def initialize(response_hash)
16
+ @id = response_hash['id']
17
+ @properties = response_hash['properties'].deep_symbolize_keys
18
+ end
19
+
20
+ class << self
21
+ def create!(params = {}, contact_id: nil, company_id: nil, deal_id: nil)
22
+ associations_hash = { 'associations' => [] }
23
+ if contact_id.present?
24
+ associations_hash['associations'] << {
25
+ "to": { "id": contact_id },
26
+ "types": [{ "associationCategory": 'HUBSPOT_DEFINED',
27
+ "associationTypeId": Hubspot::Association::ASSOCIATION_DEFINITIONS['Ticket']['Contact'] }]
28
+ }
29
+ end
30
+ if company_id.present?
31
+ associations_hash['associations'] << {
32
+ "to": { "id": company_id },
33
+ "types": [{ "associationCategory": 'HUBSPOT_DEFINED',
34
+ "associationTypeId": Hubspot::Association::ASSOCIATION_DEFINITIONS['Ticket']['Company'] }]
35
+ }
36
+ end
37
+ if deal_id.present?
38
+ associations_hash['associations'] << {
39
+ "to": { "id": deal_id },
40
+ "types": [{ "associationCategory": 'HUBSPOT_DEFINED',
41
+ "associationTypeId": Hubspot::Association::ASSOCIATION_DEFINITIONS['Ticket']['Deal'] }]
42
+ }
43
+ end
44
+ post_data = associations_hash.merge({ properties: params })
45
+
46
+ response = Hubspot::Connection.post_json(TICKETS_PATH, params: {}, body: post_data)
47
+ new(response)
48
+ end
49
+
50
+ def update!(id, properties = {})
51
+ request = { properties: properties }
52
+ response = Hubspot::Connection.patch_json(TICKET_PATH, params: { ticket_id: id }, body: request)
53
+ new(response)
54
+ end
55
+
56
+ def find(ticket_id)
57
+ response = Hubspot::Connection.get_json(TICKET_PATH, { ticket_id: ticket_id })
58
+ new(response)
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,10 @@
1
+ module Hubspot
2
+ class TicketProperties < Properties
3
+ CREATE_PROPERTY_PATH = '/crm/v3/properties/ticket'
4
+ class << self
5
+ def create!(params = {})
6
+ superclass.create!(CREATE_PROPERTY_PATH, params)
7
+ end
8
+ end
9
+ end
10
+ end
@@ -29,6 +29,9 @@ require 'hubspot/subscription'
29
29
  require 'hubspot/oauth'
30
30
  require 'hubspot/file'
31
31
  require 'hubspot/meeting'
32
+ require 'hubspot/ticket'
33
+ require 'hubspot/ticket_properties'
34
+ require 'hubspot/task'
32
35
 
33
36
  module Hubspot
34
37
  def self.configure(config={})
@@ -5,6 +5,6 @@ FactoryBot.define do
5
5
 
6
6
  firstname { Faker::Name.first_name }
7
7
  lastname { Faker::Name.last_name }
8
- email { Faker::Internet.safe_email(name: "#{Time.new.to_i.to_s[-5..-1]}#{(0..3).map { (65 + rand(26)).chr }.join}") }
8
+ email { Faker::Internet.email(name: "#{Time.new.to_i.to_s[-5..-1]}#{(0..3).map { (65 + rand(26)).chr }.join}") }
9
9
  end
10
10
  end
@@ -84,6 +84,56 @@ describe Hubspot::Connection do
84
84
  end
85
85
  end
86
86
 
87
+ describe ".patch_json" do
88
+ it "issues a PATCH request and returns the parsed body" do
89
+ path = "/some/path"
90
+ update_options = { params: {}, body: {} }
91
+
92
+ stub_request(:patch, "https://api.hubapi.com/some/path").to_return(status: 200, body: JSON.generate(vid: 123))
93
+
94
+ response = Hubspot::Connection.patch_json(path, update_options)
95
+
96
+ assert_requested(
97
+ :patch,
98
+ "https://api.hubapi.com/some/path",
99
+ {
100
+ body: "{}",
101
+ headers: { "Content-Type" => "application/json" },
102
+ }
103
+ )
104
+ expect(response).to eq({ "vid" => 123 })
105
+ end
106
+
107
+ it "logs information about the request and response" do
108
+ path = "/some/path"
109
+ update_options = { params: {}, body: {} }
110
+
111
+ logger = stub_logger
112
+
113
+ stub_request(:patch, "https://api.hubapi.com/some/path").to_return(status: 200,
114
+ body: JSON.generate("response body"))
115
+
116
+ Hubspot::Connection.patch_json(path, update_options)
117
+
118
+ expect(logger).to have_received(:info).with(<<~MSG)
119
+ Hubspot: https://api.hubapi.com/some/path.
120
+ Body: {}.
121
+ Response: 200 "response body"
122
+ MSG
123
+ end
124
+
125
+ it "raises when the request fails" do
126
+ path = "/some/path"
127
+ update_options = { params: {}, body: {} }
128
+
129
+ stub_request(:patch, "https://api.hubapi.com/some/path").to_return(status: 401)
130
+
131
+ expect {
132
+ Hubspot::Connection.patch_json(path, update_options)
133
+ }.to raise_error(Hubspot::RequestError)
134
+ end
135
+ end
136
+
87
137
  context 'private methods' do
88
138
  describe ".generate_url" do
89
139
  let(:path) { "/test/:email/profile" }
@@ -42,7 +42,7 @@ RSpec.describe Hubspot::Contact do
42
42
  context 'without properties' do
43
43
  cassette
44
44
 
45
- let(:email) { Faker::Internet.safe_email(name: "#{(0..3).map { (65 + rand(26)).chr }.join}#{Time.new.to_i.to_s[-5..-1]}") }
45
+ let(:email) { Faker::Internet.email(name: "#{(0..3).map { (65 + rand(26)).chr }.join}#{Time.new.to_i.to_s[-5..-1]}") }
46
46
  subject { described_class.create email }
47
47
 
48
48
  it 'creates a new contact' do
@@ -54,7 +54,7 @@ RSpec.describe Hubspot::Contact do
54
54
  context 'with properties' do
55
55
  cassette
56
56
 
57
- let(:email) { Faker::Internet.safe_email(name: "#{(0..3).map { (65 + rand(26)).chr }.join}#{Time.new.to_i.to_s[-5..-1]}") }
57
+ let(:email) { Faker::Internet.email(name: "#{(0..3).map { (65 + rand(26)).chr }.join}#{Time.new.to_i.to_s[-5..-1]}") }
58
58
  let(:firstname) { "Allison" }
59
59
  let(:properties) { { firstname: firstname } }
60
60
 
@@ -94,8 +94,10 @@ RSpec.describe Hubspot::Meeting do
94
94
  end
95
95
  end
96
96
 
97
- context 'when custom filters' do
98
- let(:opts) { { filters: [{ propertyName: 'hs_meeting_title', 'operator': 'EQ', value: 'Hello World' }] } }
97
+ context 'when custom filters and props' do
98
+ let(:filters) { [{ propertyName: 'hs_meeting_title', 'operator': 'EQ', value: 'Hello World' }] }
99
+ let(:properties) { [:hs_timestamp] }
100
+ let(:opts) { { filters: filters, properties: properties } }
99
101
 
100
102
  it 'retrieves meetings' do
101
103
  VCR.use_cassette 'meeting_find_by_contact_custom_filters' do
@@ -110,6 +112,7 @@ RSpec.describe Hubspot::Meeting do
110
112
  expect(first_meeting.properties[:hs_meeting_body]).not_to be nil
111
113
  expect(first_meeting.properties[:hs_meeting_start_time]).not_to be nil
112
114
  expect(first_meeting.properties[:hs_meeting_end_time]).not_to be nil
115
+ expect(first_meeting.properties[:hs_timestamp]).not_to be nil
113
116
  end
114
117
  end
115
118
  end
@@ -131,6 +134,7 @@ RSpec.describe Hubspot::Meeting do
131
134
  expect(first_meeting.properties[:hs_meeting_body]).not_to be nil
132
135
  expect(first_meeting.properties[:hs_meeting_start_time]).not_to be nil
133
136
  expect(first_meeting.properties[:hs_meeting_end_time]).not_to be nil
137
+ expect(first_meeting.properties[:hs_timestamp]).to be nil
134
138
  end
135
139
  end
136
140
  end
@@ -0,0 +1,44 @@
1
+ RSpec.describe Hubspot::Task do
2
+ describe 'create!' do
3
+ subject(:new_task) do
4
+ params = {
5
+ hs_task_body: 'i am a task',
6
+ hs_task_subject: 'title of task',
7
+ hs_timestamp: DateTime.now.strftime('%Q')
8
+ }
9
+ described_class.create!(params, ticket_id: 16_174_569_112)
10
+ end
11
+
12
+ it 'creates a new task with valid properties' do
13
+ VCR.use_cassette 'task' do
14
+ expect(new_task.id).not_to be_nil
15
+ expect(new_task.properties[:hs_task_status]).to eq('NOT_STARTED')
16
+ expect(new_task.properties[:hs_task_subject]).to eq('title of task')
17
+ expect(new_task.properties[:hs_body_preview]).to eq('i am a task')
18
+ end
19
+ end
20
+ end
21
+
22
+ describe 'find' do
23
+ let(:task_id) { 64_075_014_222 }
24
+
25
+ subject(:existing_task) { described_class.find(task_id, 'hs_task_subject,hs_task_status') }
26
+
27
+ it 'gets existing task' do
28
+ VCR.use_cassette 'task_find' do
29
+ expect(existing_task.id).not_to be_nil
30
+ expect(existing_task.properties[:hs_task_subject]).to eq('title of task')
31
+ end
32
+ end
33
+
34
+ context 'when task does not exist' do
35
+ let(:task_id) { 996_174_569_112 }
36
+
37
+ it 'returns nil' do
38
+ VCR.use_cassette 'task_find' do
39
+ expect { existing_task }.to raise_error Hubspot::NotFoundError
40
+ end
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,41 @@
1
+ describe Hubspot::TicketProperties do
2
+ describe '.create' do
3
+ context 'with all valid parameters' do
4
+ let(:params) do
5
+ {
6
+ 'name' => 'my_new_property',
7
+ 'label' => 'This is my new property',
8
+ 'description' => 'How much money do you have?',
9
+ 'groupName' => 'ticketinformation',
10
+ 'type' => 'string',
11
+ 'fieldType' => 'text',
12
+ 'hidden' => false,
13
+ 'deleted' => false,
14
+ 'displayOrder' => 0,
15
+ 'formField' => true,
16
+ 'readOnlyValue' => false,
17
+ 'readOnlyDefinition' => false,
18
+ 'mutableDefinitionNotDeletable' => false,
19
+ 'calculated' => false,
20
+ 'externalOptions' => false,
21
+ 'displayMode' => 'current_value'
22
+ }
23
+ end
24
+
25
+ it 'should return the valid parameters' do
26
+ VCR.use_cassette 'ticket_create_property' do
27
+ response = Hubspot::TicketProperties.create!(params)
28
+ expect(Hubspot::TicketProperties.same?(params, response.compact.except('options'))).to be true
29
+ end
30
+ end
31
+ end
32
+
33
+ context 'with invalid parameters' do
34
+ it 'should return nil' do
35
+ VCR.use_cassette 'ticket_fail_to_create_property' do
36
+ expect(Hubspot::TicketProperties.create!({})).to be(nil)
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,63 @@
1
+ RSpec.describe Hubspot::Ticket do
2
+ describe 'create!' do
3
+ subject(:new_ticket) do
4
+ params = {
5
+ hs_pipeline: '0',
6
+ hs_pipeline_stage: '1',
7
+ hs_ticket_priority: 'MEDIUM',
8
+ subject: 'test ticket'
9
+ }
10
+ described_class.create!(params, contact_id: 75_761_595_194, company_id: 25_571_271_600, deal_id: 28_806_796_888)
11
+ end
12
+
13
+ it 'creates a new ticket with valid properties' do
14
+ VCR.use_cassette 'ticket' do
15
+ expect(new_ticket.id).not_to be_nil
16
+ expect(new_ticket.properties[:subject]).to eq('test ticket')
17
+ end
18
+ end
19
+ end
20
+
21
+ describe 'find' do
22
+ let(:ticket_id) { 16_174_569_112 }
23
+
24
+ subject(:existing_ticket) { described_class.find(ticket_id) }
25
+
26
+ it 'gets existing ticket' do
27
+ VCR.use_cassette 'ticket_find' do
28
+ expect(existing_ticket.id).not_to be_nil
29
+ expect(existing_ticket.properties[:subject]).to eq('test ticket')
30
+ end
31
+ end
32
+
33
+ context 'when ticket does not exist' do
34
+ let(:ticket_id) { 996_174_569_112 }
35
+
36
+ it 'returns nil' do
37
+ VCR.use_cassette 'ticket_find' do
38
+ expect { existing_ticket }.to raise_error Hubspot::NotFoundError
39
+ end
40
+ end
41
+ end
42
+ end
43
+
44
+ describe 'update!' do
45
+ let(:ticket_id) { 16_174_569_112 }
46
+ let(:properties) do
47
+ {
48
+ hs_ticket_priority: 'HIGH',
49
+ subject: 'New name'
50
+ }
51
+ end
52
+
53
+ subject(:update_ticket) { described_class.update!(ticket_id, properties) }
54
+
55
+ it 'updates existing ticket, returns the updated entity' do
56
+ VCR.use_cassette 'ticket_update' do
57
+ ticket = update_ticket
58
+ ticket.properties[:subject] = 'New name'
59
+ ticket.properties[:subject] = 'HIGH'
60
+ end
61
+ end
62
+ end
63
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hubspot-api-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.15.0
4
+ version: 0.17.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jonathan
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-11-14 00:00:00.000000000 Z
11
+ date: 2024-11-08 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -292,6 +292,9 @@ files:
292
292
  - lib/hubspot/railtie.rb
293
293
  - lib/hubspot/resource.rb
294
294
  - lib/hubspot/subscription.rb
295
+ - lib/hubspot/task.rb
296
+ - lib/hubspot/ticket.rb
297
+ - lib/hubspot/ticket_properties.rb
295
298
  - lib/hubspot/topic.rb
296
299
  - lib/hubspot/utils.rb
297
300
  - spec/factories/companies.rb
@@ -319,6 +322,9 @@ files:
319
322
  - spec/lib/hubspot/owner_spec.rb
320
323
  - spec/lib/hubspot/properties_spec.rb
321
324
  - spec/lib/hubspot/resource_spec.rb
325
+ - spec/lib/hubspot/task_spec.rb
326
+ - spec/lib/hubspot/ticket_properties_spec.rb
327
+ - spec/lib/hubspot/ticket_spec.rb
322
328
  - spec/lib/hubspot/utils_spec.rb
323
329
  - spec/shared_examples/saveable_resource.rb
324
330
  - spec/shared_examples/updateable_resource.rb
@@ -331,7 +337,7 @@ licenses:
331
337
  - MIT
332
338
  metadata:
333
339
  changelog_uri: https://github.com/captaincontrat/hubspot-api-ruby/blob/master/History.md
334
- post_install_message:
340
+ post_install_message:
335
341
  rdoc_options: []
336
342
  require_paths:
337
343
  - lib
@@ -339,15 +345,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
339
345
  requirements:
340
346
  - - ">="
341
347
  - !ruby/object:Gem::Version
342
- version: '2.7'
348
+ version: '3.1'
343
349
  required_rubygems_version: !ruby/object:Gem::Requirement
344
350
  requirements:
345
351
  - - ">="
346
352
  - !ruby/object:Gem::Version
347
353
  version: '0'
348
354
  requirements: []
349
- rubygems_version: 3.1.2
350
- signing_key:
355
+ rubygems_version: 3.5.3
356
+ signing_key:
351
357
  specification_version: 4
352
358
  summary: hubspot-api-ruby is a wrapper for the HubSpot REST API
353
359
  test_files: []