knockapi 0.4.12 → 0.5.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
2
  SHA256:
3
- metadata.gz: '068773528aedcda44f03ce1f2378bf78aef474f64fdaf036c92a2aea5c6e0c72'
4
- data.tar.gz: 4bcb6204c07762d04460822b7bfb9a60ffc326c939ead527b7477b461a40c8e3
3
+ metadata.gz: a134ca1b8dfef66365a05c99f1eb70146f647d1df31978da691b81b09016d37e
4
+ data.tar.gz: ce602039743e58d61f5a926aec90996a95e6635343b148df247c914b33597cd4
5
5
  SHA512:
6
- metadata.gz: d2bd60b5658cbce9198b83276dec3e7539ba9e7ce434df0736d6abfe1f5365086cb31bf4803fbc881d27bfd123ac13643001fe07bc8b857b5324930a9be47f5a
7
- data.tar.gz: 6ea8d6f2669a13f68e14636463ee054a8fab1ecc81dc6260c2831d8c774598ff46743f68f409ed4e0bcc125aad2ac8c955e480ba49e616ea31e663fef4317a02
6
+ metadata.gz: 78a5c9740fd5fe6328ffaa1b8582dbf93221fc2775bdfc3471935c86de5bbb2fe1b9d80f2e7280c3a8bdb6bdc99cc59180a9e46ab77b6041673aae06ab3d43d7
7
+ data.tar.gz: 4dd3a4622d8d2cddd6b1b6b895740071603ffc613971e817bd58baa650602cc2c835664935d06500a768d83c00e8961b4eadbbf1e65b8cc91462b9c13d0fc7ee
@@ -9,42 +9,37 @@ name: Ruby
9
9
 
10
10
  on:
11
11
  push:
12
- branches: [ "main" ]
12
+ branches: ["main"]
13
13
  pull_request:
14
- branches: [ "main" ]
14
+ branches: ["main"]
15
15
 
16
16
  permissions:
17
17
  contents: read
18
18
 
19
19
  jobs:
20
20
  test:
21
-
22
21
  runs-on: ubuntu-latest
23
22
  strategy:
24
23
  matrix:
25
- ruby-version: ['2.6', '2.7', '3.0']
24
+ ruby-version: ["2.7", "3.0", "3.1", "3.2"]
26
25
 
27
26
  steps:
28
- - uses: actions/checkout@v3
29
- - name: Set up Ruby
30
- # To automatically get bug fixes and new Ruby versions for ruby/setup-ruby,
31
- # change this to (see https://github.com/ruby/setup-ruby#versioning):
32
- # uses: ruby/setup-ruby@v1
33
- uses: ruby/setup-ruby@2b019609e2b0f1ea1a2bc8ca11cb82ab46ada124
34
- with:
35
- ruby-version: ${{ matrix.ruby-version }}
36
- bundler-cache: true # runs 'bundle install' and caches installed gems automatically
37
- - name: Run tests
38
- run: bundle exec rspec spec
27
+ - uses: actions/checkout@v3
28
+ - name: Set up Ruby
29
+ uses: ruby/setup-ruby@v1
30
+ with:
31
+ ruby-version: ${{ matrix.ruby-version }}
32
+ bundler-cache: true # runs 'bundle install' and caches installed gems automatically
33
+ - name: Run tests
34
+ run: bundle exec rspec spec
39
35
 
40
36
  lint:
41
-
42
37
  runs-on: ubuntu-latest
43
38
  steps:
44
39
  - name: Checkout code
45
40
  uses: actions/checkout@v3
46
41
  - name: Install Ruby and gems
47
- uses: ruby/setup-ruby@8f312efe1262fb463d906e9bf040319394c18d3e # v1.92
42
+ uses: ruby/setup-ruby@v1
48
43
  with:
49
44
  bundler-cache: true
50
45
  # Add or replace any other lints here
data/.ruby-version CHANGED
@@ -1 +1 @@
1
- 3.0.2
1
+ 3.2.5
data/.tool-versions CHANGED
@@ -1 +1 @@
1
- ruby 3.2.2
1
+ ruby 3.2.5
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- knockapi (0.4.12)
4
+ knockapi (0.5.1)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
data/README.md CHANGED
@@ -26,7 +26,10 @@ Or, you may set the key yourself in an initializer:
26
26
 
27
27
  ```ruby
28
28
  # /config/initializers/knock.rb
29
- Knock.key = 'sk_12345'
29
+ Knock.configure do |config|
30
+ config.key = '[your api key]'
31
+ config.timeout = 120
32
+ end
30
33
  ```
31
34
 
32
35
  ## Usage
@@ -34,10 +37,6 @@ Knock.key = 'sk_12345'
34
37
  ### Identifying users
35
38
 
36
39
  ```ruby
37
- require "knock"
38
-
39
- Knock.key = "sk_12345"
40
-
41
40
  Knock::Users.identify(
42
41
  id: "jhammond",
43
42
  data: {
@@ -50,10 +49,6 @@ Knock::Users.identify(
50
49
  ### Sending notifies (triggering workflows)
51
50
 
52
51
  ```ruby
53
- require "knock"
54
-
55
- Knock.key = "sk_12345"
56
-
57
52
  # The key of the workflow (from Knock dashboard)
58
53
  Knock::Workflows.trigger(
59
54
  key: "dinosaurs-loose",
@@ -74,29 +69,18 @@ Knock::Workflows.trigger(
74
69
  ### Retrieving users
75
70
 
76
71
  ```ruby
77
- require "knock"
78
-
79
- Knock.key = "sk_12345"
80
-
81
72
  Knock::Users.get(id: "jhammond")
82
73
  ```
83
74
 
84
75
  ### Deleting users
85
76
 
86
77
  ```ruby
87
- require "knock"
88
-
89
- Knock.key = "sk_12345"
90
-
91
78
  Knock::Users.delete(id: "jhammond")
92
79
  ```
93
80
 
94
81
  ### Preferences
95
82
 
96
83
  ```ruby
97
- require "knock"
98
- Knock.key = "sk_12345"
99
-
100
84
  # Set an entire preference set
101
85
  Knock::Users.set_preferences(
102
86
  user_id: "jhammond",
@@ -115,9 +99,6 @@ Knock::Users.get_preferences(user_id: "jhammond")
115
99
  ### Getting and setting channel data
116
100
 
117
101
  ```ruby
118
- require "knock"
119
- Knock.key = "sk_12345"
120
-
121
102
  # Set channel data for an APNS
122
103
  Knock::Users.set_channel_data(
123
104
  id: "jhammond",
@@ -134,9 +115,6 @@ Knock::Users.get_channel_data(user_id: "jhammond", channel_id: KNOCK_APNS_CHANNE
134
115
  ### Cancelling workflows
135
116
 
136
117
  ```ruby
137
- require "knock"
138
- Knock.key = "sk_12345"
139
-
140
118
  Knock::Workflows.cancel(
141
119
  key: "dinosaurs-loose",
142
120
  cancellation_key: trigger_alert.id,
@@ -7,7 +7,6 @@ module Knock
7
7
  # Provides convienience methods for working with bulk operations
8
8
  module BulkOperations
9
9
  class << self
10
- include Base
11
10
  include Client
12
11
 
13
12
  # Retrieves the given bulk operation
data/lib/knock/client.rb CHANGED
@@ -2,20 +2,27 @@
2
2
 
3
3
  module Knock
4
4
  # A Net::HTTP based API client for interacting with the Knock API
5
+ # rubocop:disable Metrics/ModuleLength
5
6
  module Client
6
7
  include Kernel
7
8
 
8
9
  def client
9
- return @client if defined?(@client)
10
-
11
- @client = Net::HTTP.new(Knock::API_HOSTNAME, 443)
12
- @client.use_ssl = true
13
-
14
- @client
10
+ Net::HTTP.new(Knock.config.api_hostname, 443).tap do |http_client|
11
+ http_client.use_ssl = true
12
+ http_client.open_timeout = Knock.config.timeout
13
+ http_client.read_timeout = Knock.config.timeout
14
+ http_client.write_timeout = Knock.config.timeout if RUBY_VERSION >= '2.6.0'
15
+ end
15
16
  end
16
17
 
17
18
  def execute_request(request:)
18
- response = client.request(request)
19
+ begin
20
+ response = client.request(request)
21
+ rescue Net::OpenTimeout, Net::ReadTimeout, Net::WriteTimeout
22
+ raise TimeoutError.new(
23
+ message: 'API Timeout Error'
24
+ )
25
+ end
19
26
 
20
27
  http_status = response.code.to_i
21
28
  handle_error_response(response: response) if http_status >= 400
@@ -32,7 +39,7 @@ module Knock
32
39
  'Content-Type' => 'application/json'
33
40
  )
34
41
 
35
- request['Authorization'] = "Bearer #{access_token || Knock.key!}" if auth
42
+ request['Authorization'] = "Bearer #{access_token || Knock.config.key!}" if auth
36
43
  request['User-Agent'] = user_agent
37
44
  request
38
45
  end
@@ -40,7 +47,7 @@ module Knock
40
47
  def post_request(path:, auth: false, idempotency_key: nil, body: nil)
41
48
  request = Net::HTTP::Post.new(path, 'Content-Type' => 'application/json')
42
49
  request.body = body.to_json if body
43
- request['Authorization'] = "Bearer #{Knock.key!}" if auth
50
+ request['Authorization'] = "Bearer #{Knock.config.key!}" if auth
44
51
  request['User-Agent'] = user_agent
45
52
  request['Idempotency-Key'] = idempotency_key if idempotency_key
46
53
  request
@@ -56,7 +63,7 @@ module Knock
56
63
  )
57
64
 
58
65
  request.body = body.to_json if body
59
- request['Authorization'] = "Bearer #{Knock.key!}" if auth
66
+ request['Authorization'] = "Bearer #{Knock.config.key!}" if auth
60
67
  request['User-Agent'] = user_agent
61
68
  request
62
69
  end
@@ -64,7 +71,7 @@ module Knock
64
71
  def put_request(path:, auth: false, idempotency_key: nil, body: nil)
65
72
  request = Net::HTTP::Put.new(path, 'Content-Type' => 'application/json')
66
73
  request.body = body.to_json if body
67
- request['Authorization'] = "Bearer #{Knock.key!}" if auth
74
+ request['Authorization'] = "Bearer #{Knock.config.key!}" if auth
68
75
  request['User-Agent'] = user_agent
69
76
  request['Idempotency-Key'] = idempotency_key if idempotency_key
70
77
  request
@@ -75,6 +82,8 @@ module Knock
75
82
  end
76
83
 
77
84
  # rubocop:disable Metrics/AbcSize
85
+ # rubocop:disable Metrics/CyclomaticComplexity
86
+ # rubocop:disable Metrics/MethodLength
78
87
 
79
88
  def handle_error_response(response:)
80
89
  http_status = response.code.to_i
@@ -109,10 +118,18 @@ module Knock
109
118
  http_status: http_status,
110
119
  request_id: response['x-request-id']
111
120
  )
121
+ when 429
122
+ raise APIError.new(
123
+ message: json['message'],
124
+ http_status: http_status,
125
+ request_id: response['x-request-id']
126
+ )
112
127
  end
113
128
  end
114
129
 
115
130
  # rubocop:enable Metrics/AbcSize
131
+ # rubocop:enable Metrics/CyclomaticComplexity
132
+ # rubocop:enable Metrics/MethodLength
116
133
 
117
134
  private
118
135
 
@@ -122,4 +139,5 @@ module Knock
122
139
  end.join('; ')
123
140
  end
124
141
  end
142
+ # rubocop:enable Metrics/ModuleLength
125
143
  end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ # typed: true
4
+
5
+ module Knock
6
+ # Configuration class sets config initializer
7
+ class Configuration
8
+ attr_accessor :api_hostname, :timeout, :key
9
+
10
+ def initialize
11
+ @timeout = 60
12
+ end
13
+
14
+ def key!
15
+ key or raise '`Knock.config.key` not set'
16
+ end
17
+ end
18
+ end
data/lib/knock/errors.rb CHANGED
@@ -42,4 +42,7 @@ module Knock
42
42
  # InvalidRequestError is raised when a request is initiated with invalid
43
43
  # parameters.
44
44
  class InvalidRequestError < KnockError; end
45
+
46
+ # TimeoutError is raised when the HTTP request to the API times out
47
+ class TimeoutError < KnockError; end
45
48
  end
@@ -8,7 +8,6 @@ module Knock
8
8
  # Methods for interacting with messages in Knock
9
9
  module Messages
10
10
  class << self
11
- include Base
12
11
  include Client
13
12
 
14
13
  # Retrieves a paginated list of messages for the provided environment
data/lib/knock/objects.rb CHANGED
@@ -9,7 +9,6 @@ module Knock
9
9
  # rubocop:disable Metrics/ModuleLength
10
10
  module Objects
11
11
  class << self
12
- include Base
13
12
  include Client
14
13
 
15
14
  DEFAULT_PREFERENCE_SET_ID = 'default'
@@ -7,7 +7,6 @@ module Knock
7
7
  # Provides convienience methods for working with preferences (deprecated)
8
8
  module Preferences
9
9
  class << self
10
- include Base
11
10
  include Client
12
11
 
13
12
  # Returns all preference sets for the user
data/lib/knock/tenants.rb CHANGED
@@ -7,7 +7,6 @@ module Knock
7
7
  # Methods for interacting with tenants in Knock
8
8
  module Tenants
9
9
  class << self
10
- include Base
11
10
  include Client
12
11
 
13
12
  # Retrieves all Tenants in environment
data/lib/knock/users.rb CHANGED
@@ -9,7 +9,6 @@ module Knock
9
9
  # rubocop:disable Metrics/ModuleLength
10
10
  module Users
11
11
  class << self
12
- include Base
13
12
  include Client
14
13
 
15
14
  DEFAULT_PREFERENCE_SET_ID = 'default'
data/lib/knock/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Knock
4
- VERSION = '0.4.12'
4
+ VERSION = '0.5.1'
5
5
  end
@@ -7,7 +7,6 @@ module Knock
7
7
  # Methods for interacting with workflows in Knock
8
8
  module Workflows
9
9
  class << self
10
- include Base
11
10
  include Client
12
11
 
13
12
  # Triggers the workflow with the given key
data/lib/knock.rb CHANGED
@@ -2,25 +2,39 @@
2
2
 
3
3
  require 'knock/version'
4
4
  require 'json'
5
+ require 'knock/configuration'
5
6
 
6
7
  # Setup for Knock client
7
8
  module Knock
8
- API_HOSTNAME = ENV['KNOCK_API_HOSTNAME'] || 'api.knock.app'
9
+ def self.default_config
10
+ Configuration.new.tap do |config|
11
+ config.api_hostname = ENV['KNOCK_API_HOSTNAME'] || 'api.knock.app'
12
+ config.key = ENV['KNOCK_API_KEY']
13
+ end
14
+ end
9
15
 
10
- def self.key=(value)
11
- Base.key = value
16
+ def self.config
17
+ @config ||= default_config
12
18
  end
13
19
 
14
- def self.key
15
- Base.key
20
+ def self.configure
21
+ yield(config)
16
22
  end
17
23
 
18
- def self.key!
19
- key || raise('Knock.key not set')
24
+ def self.key=(value)
25
+ warn '`Knock.key=` is deprecated. Use `Knock.configure` instead.'
26
+
27
+ config.key = value
28
+ end
29
+
30
+ def self.key
31
+ warn '`Knock.key` is deprecated. Use `Knock.configure` instead.'
32
+ config.key
20
33
  end
21
34
 
22
35
  autoload :Base, 'knock/base'
23
36
  autoload :Client, 'knock/client'
37
+ autoload :Configuration, 'knock/configuration'
24
38
 
25
39
  # Resources
26
40
  autoload :Preferences, 'knock/preferences'
@@ -35,9 +49,7 @@ module Knock
35
49
  autoload :APIError, 'knock/errors'
36
50
  autoload :AuthenticationError, 'knock/errors'
37
51
  autoload :InvalidRequestError, 'knock/errors'
38
-
39
- key = ENV['KNOCK_API_KEY']
40
- Knock.key = key unless key.nil?
52
+ autoload :TimeoutError, 'knock/errors'
41
53
 
42
54
  # Triggers the workflow with the given key
43
55
  #
@@ -0,0 +1,63 @@
1
+ # frozen_string_literal: true
2
+
3
+ # typed: false
4
+ require_relative '../lib/knock'
5
+
6
+ describe Knock do
7
+ describe '.configure' do
8
+ context 'with key and no timeout' do
9
+ before do
10
+ Knock.configure do |config|
11
+ config.key = 'example_api_key'
12
+ end
13
+ end
14
+
15
+ it 'sets the key and default timeout configuration' do
16
+ expect(Knock.config.key).to eq('example_api_key')
17
+ expect(Knock.config.timeout).to eq(60)
18
+ end
19
+ end
20
+
21
+ context 'with key and timeout' do
22
+ before do
23
+ Knock.configure do |config|
24
+ config.key = 'example_api_key'
25
+ config.timeout = 120
26
+ end
27
+ end
28
+
29
+ it 'sets the key and timeout configuration' do
30
+ expect(Knock.config.key).to eq('example_api_key')
31
+ expect(Knock.config.timeout).to eq(120)
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+ describe Knock::Configuration do
38
+ describe '.key!' do
39
+ context 'with key set' do
40
+ before do
41
+ Knock.config.key = 'example_api_key'
42
+ end
43
+
44
+ it 'returns the key' do
45
+ expect(Knock.config.key!).to eq('example_api_key')
46
+ end
47
+ end
48
+
49
+ context 'with key not set' do
50
+ before do
51
+ Knock.config.key = nil
52
+ end
53
+
54
+ it 'throws an error' do
55
+ expect do
56
+ Knock.config.key!
57
+ end.to raise_error(
58
+ '`Knock.config.key` not set'
59
+ )
60
+ end
61
+ end
62
+ end
63
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: knockapi
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.4.12
4
+ version: 0.5.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Knock Labs, Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-04-11 00:00:00.000000000 Z
11
+ date: 2024-07-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -76,9 +76,9 @@ files:
76
76
  - bin/publish
77
77
  - knockapi.gemspec
78
78
  - lib/knock.rb
79
- - lib/knock/base.rb
80
79
  - lib/knock/bulk_operations.rb
81
80
  - lib/knock/client.rb
81
+ - lib/knock/configuration.rb
82
82
  - lib/knock/errors.rb
83
83
  - lib/knock/messages.rb
84
84
  - lib/knock/objects.rb
@@ -87,6 +87,7 @@ files:
87
87
  - lib/knock/users.rb
88
88
  - lib/knock/version.rb
89
89
  - lib/knock/workflows.rb
90
+ - spec/configuration_spec.rb
90
91
  - spec/tenants_spec.rb
91
92
  homepage: https://github.com/knocklabs/knock-ruby
92
93
  licenses:
@@ -108,9 +109,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
108
109
  - !ruby/object:Gem::Version
109
110
  version: '0'
110
111
  requirements: []
111
- rubygems_version: 3.5.3
112
+ rubygems_version: 3.5.11
112
113
  signing_key:
113
114
  specification_version: 4
114
115
  summary: API client for Knock
115
116
  test_files:
117
+ - spec/configuration_spec.rb
116
118
  - spec/tenants_spec.rb
data/lib/knock/base.rb DELETED
@@ -1,12 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module Knock
4
- ## The Base class handles setting and reading the Knock API Key for authentication
5
- module Base
6
- attr_accessor :key
7
-
8
- class << self
9
- attr_accessor :key
10
- end
11
- end
12
- end