knockapi 0.4.1 → 0.4.4

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: e5539a9d4052b39167c0aa22d71eb9848ab0c6ad0c2812bf72e09cc446256868
4
- data.tar.gz: 7b08912b135c05a15d528527788a3f7aa8d7b67b7c14e0e5bcbac8f80fb5fe4e
3
+ metadata.gz: 9d0a730346c7c39ec862f160ac31fd80844b3f0907129a02ad320bf724e74888
4
+ data.tar.gz: bab747c80c86891e7e5d8135748deec4cd8c6bee1b20fbddf19546aefebe5646
5
5
  SHA512:
6
- metadata.gz: 2e2976916846b11c9a8ccb6cdacba9f12fecb0e113f8114cb1eed77a248b53156cdf025ffd823148567675489d988f655d80fec43cdb8a2174f6d6cce5a0db02
7
- data.tar.gz: 83b75fd115a9ce6905629cc20bbdf1550eb726e2e39ece0e4d4215a1203ee1b6af46877d1dd50cda0de1c1230a5f948a9e6e974cdd600ca62794a154ba9f1ab6
6
+ metadata.gz: a7e879b66a557daac3950155ec7429cbfe72b7f6d7f2491eb440f92cf1b1f620753a2dab325751bdb704933df7be8c598b9b47c67b191c7659dbd9470c888f2c
7
+ data.tar.gz: 689dba9548ddba6fe5e2e90fb339eb2dee6c23f9c8d51ce878d4d163da70453482a1fae0806c7fa56638e3dec9aa0cf38f3c5669c657b11768d7e1087a57dd47
@@ -0,0 +1,52 @@
1
+ # This workflow uses actions that are not certified by GitHub.
2
+ # They are provided by a third-party and are governed by
3
+ # separate terms of service, privacy policy, and support
4
+ # documentation.
5
+ # This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake
6
+ # For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby
7
+
8
+ name: Ruby
9
+
10
+ on:
11
+ push:
12
+ branches: [ "main" ]
13
+ pull_request:
14
+ branches: [ "main" ]
15
+
16
+ permissions:
17
+ contents: read
18
+
19
+ jobs:
20
+ test:
21
+
22
+ runs-on: ubuntu-latest
23
+ strategy:
24
+ matrix:
25
+ ruby-version: ['2.6', '2.7', '3.0']
26
+
27
+ 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
39
+
40
+ lint:
41
+
42
+ runs-on: ubuntu-latest
43
+ steps:
44
+ - name: Checkout code
45
+ uses: actions/checkout@v3
46
+ - name: Install Ruby and gems
47
+ uses: ruby/setup-ruby@8f312efe1262fb463d906e9bf040319394c18d3e # v1.92
48
+ with:
49
+ bundler-cache: true
50
+ # Add or replace any other lints here
51
+ - name: Lint Ruby files
52
+ run: bundle exec rubocop
data/.rubocop.yml ADDED
@@ -0,0 +1,8 @@
1
+ AllCops:
2
+ TargetRubyVersion: 2.5
3
+ Metrics/LineLength:
4
+ Max: 120
5
+ Metrics/MethodLength:
6
+ Max: 35
7
+ Metrics/ParameterLists:
8
+ Max: 6
data/Gemfile CHANGED
@@ -1,5 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- source "https://rubygems.org"
3
+ source 'https://rubygems.org'
4
4
 
5
5
  gemspec
6
+
7
+ group :test do
8
+ gem 'rspec', '~> 3.11'
9
+ end
data/Gemfile.lock CHANGED
@@ -1,12 +1,13 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- knockapi (0.4.1)
4
+ knockapi (0.4.4)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
9
  ast (2.4.2)
10
+ diff-lcs (1.5.0)
10
11
  parallel (1.20.1)
11
12
  parser (3.0.2.0)
12
13
  ast (~> 2.4.1)
@@ -14,6 +15,19 @@ GEM
14
15
  rake (13.0.6)
15
16
  regexp_parser (2.1.1)
16
17
  rexml (3.2.5)
18
+ rspec (3.11.0)
19
+ rspec-core (~> 3.11.0)
20
+ rspec-expectations (~> 3.11.0)
21
+ rspec-mocks (~> 3.11.0)
22
+ rspec-core (3.11.0)
23
+ rspec-support (~> 3.11.0)
24
+ rspec-expectations (3.11.0)
25
+ diff-lcs (>= 1.2.0, < 2.0)
26
+ rspec-support (~> 3.11.0)
27
+ rspec-mocks (3.11.1)
28
+ diff-lcs (>= 1.2.0, < 2.0)
29
+ rspec-support (~> 3.11.0)
30
+ rspec-support (3.11.0)
17
31
  rubocop (1.18.4)
18
32
  parallel (~> 1.10)
19
33
  parser (>= 3.0.0.0)
@@ -42,6 +56,7 @@ DEPENDENCIES
42
56
  bundler (>= 2.0.1)
43
57
  knockapi!
44
58
  rake
59
+ rspec (~> 3.11)
45
60
  standard
46
61
 
47
62
  BUNDLED WITH
data/bin/console CHANGED
@@ -1,7 +1,8 @@
1
1
  #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
2
3
 
3
- require "bundler/setup"
4
- require "knock"
4
+ require 'bundler/setup'
5
+ require 'knock'
5
6
 
6
- require "irb"
7
- IRB.start(__FILE__)
7
+ require 'irb'
8
+ IRB.start(__FILE__)
data/knockapi.gemspec CHANGED
@@ -1,30 +1,30 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- lib = File.expand_path("lib", __dir__)
3
+ lib = File.expand_path('lib', __dir__)
4
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
5
- require "knock/version"
5
+ require 'knock/version'
6
6
 
7
7
  Gem::Specification.new do |spec|
8
- spec.name = "knockapi"
8
+ spec.name = 'knockapi'
9
9
  spec.version = Knock::VERSION
10
- spec.authors = ["Knock Labs, Inc."]
11
- spec.email = ["support@knock.app"]
12
- spec.description = "API client for Knock"
13
- spec.summary = "API client for Knock"
14
- spec.homepage = "https://github.com/knocklabs/knock-ruby"
15
- spec.license = "MIT"
10
+ spec.authors = ['Knock Labs, Inc.']
11
+ spec.email = ['support@knock.app']
12
+ spec.description = 'API client for Knock'
13
+ spec.summary = 'API client for Knock'
14
+ spec.homepage = 'https://github.com/knocklabs/knock-ruby'
15
+ spec.license = 'MIT'
16
16
  spec.metadata = {
17
- "documentation_uri" => "https://docs.knock.app"
17
+ 'documentation_uri' => 'https://docs.knock.app'
18
18
  }
19
19
 
20
20
  spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
21
21
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
22
22
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
23
- spec.require_paths = ["lib"]
23
+ spec.require_paths = ['lib']
24
24
 
25
- spec.add_development_dependency "bundler", ">= 2.0.1"
26
- spec.add_development_dependency "rake"
27
- spec.add_development_dependency "standard"
25
+ spec.add_development_dependency 'bundler', '>= 2.0.1'
26
+ spec.add_development_dependency 'rake'
27
+ spec.add_development_dependency 'standard'
28
28
 
29
- spec.required_ruby_version = ">= 2.5"
29
+ spec.required_ruby_version = '>= 2.5'
30
30
  end
data/lib/knock/base.rb CHANGED
@@ -1,11 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Knock
2
4
  ## The Base class handles setting and reading the Knock API Key for authentication
3
5
  module Base
4
6
  attr_accessor :key
5
7
 
6
8
  class << self
7
- attr_writer :key
8
- attr_reader :key
9
+ attr_accessor :key
9
10
  end
10
11
  end
11
12
  end
@@ -1,5 +1,7 @@
1
- require "net/http"
2
- require "uri"
1
+ # frozen_string_literal: true
2
+
3
+ require 'net/http'
4
+ require 'uri'
3
5
 
4
6
  module Knock
5
7
  # Provides convienience methods for working with bulk operations
data/lib/knock/client.rb CHANGED
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Knock
2
4
  # A Net::HTTP based API client for interacting with the Knock API
3
5
  module Client
@@ -18,7 +20,7 @@ module Knock
18
20
  http_status = response.code.to_i
19
21
  handle_error_response(response: response) if http_status >= 400
20
22
 
21
- JSON.parse(response.body)
23
+ JSON.parse(response.body) if response.body && (response.body != '')
22
24
  end
23
25
 
24
26
  def get_request(path:, auth: false, params: {}, access_token: nil)
@@ -27,19 +29,19 @@ module Knock
27
29
 
28
30
  request = Net::HTTP::Get.new(
29
31
  uri.to_s,
30
- "Content-Type" => "application/json"
32
+ 'Content-Type' => 'application/json'
31
33
  )
32
34
 
33
- request["Authorization"] = "Bearer #{access_token || Knock.key!}" if auth
34
- request["User-Agent"] = user_agent
35
+ request['Authorization'] = "Bearer #{access_token || Knock.key!}" if auth
36
+ request['User-Agent'] = user_agent
35
37
  request
36
38
  end
37
39
 
38
- def post_request(path:, auth: false, idempotency_key: nil, body: nil)
39
- request = Net::HTTP::Post.new(path, "Content-Type" => "application/json")
40
+ def post_request(path:, auth: false, _idempotency_key: nil, body: nil)
41
+ request = Net::HTTP::Post.new(path, 'Content-Type' => 'application/json')
40
42
  request.body = body.to_json if body
41
- request["Authorization"] = "Bearer #{Knock.key!}" if auth
42
- request["User-Agent"] = user_agent
43
+ request['Authorization'] = "Bearer #{Knock.key!}" if auth
44
+ request['User-Agent'] = user_agent
43
45
  request
44
46
  end
45
47
 
@@ -49,19 +51,19 @@ module Knock
49
51
 
50
52
  request = Net::HTTP::Delete.new(
51
53
  uri.to_s,
52
- "Content-Type" => "application/json"
54
+ 'Content-Type' => 'application/json'
53
55
  )
54
56
 
55
- request["Authorization"] = "Bearer #{Knock.key!}" if auth
56
- request["User-Agent"] = user_agent
57
+ request['Authorization'] = "Bearer #{Knock.key!}" if auth
58
+ request['User-Agent'] = user_agent
57
59
  request
58
60
  end
59
61
 
60
- def put_request(path:, auth: false, idempotency_key: nil, body: nil)
61
- request = Net::HTTP::Put.new(path, "Content-Type" => "application/json")
62
+ def put_request(path:, auth: false, _idempotency_key: nil, body: nil)
63
+ request = Net::HTTP::Put.new(path, 'Content-Type' => 'application/json')
62
64
  request.body = body.to_json if body
63
- request["Authorization"] = "Bearer #{Knock.key!}" if auth
64
- request["User-Agent"] = user_agent
65
+ request['Authorization'] = "Bearer #{Knock.key!}" if auth
66
+ request['User-Agent'] = user_agent
65
67
  request
66
68
  end
67
69
 
@@ -69,6 +71,8 @@ module Knock
69
71
  "Knock Ruby - v#{Knock::VERSION}"
70
72
  end
71
73
 
74
+ # rubocop:disable Metrics/AbcSize
75
+
72
76
  def handle_error_response(response:)
73
77
  http_status = response.code.to_i
74
78
  json = JSON.parse(response.body)
@@ -76,41 +80,43 @@ module Knock
76
80
  case http_status
77
81
  when 400
78
82
  raise InvalidRequestError.new(
79
- message: json["message"],
83
+ message: json['message'],
80
84
  http_status: http_status,
81
- request_id: response["x-request-id"]
85
+ request_id: response['x-request-id']
82
86
  )
83
87
  when 401
84
88
  raise AuthenticationError.new(
85
- message: json["message"],
89
+ message: json['message'],
86
90
  http_status: http_status,
87
- request_id: response["x-request-id"]
91
+ request_id: response['x-request-id']
88
92
  )
89
93
  when 404
90
94
  raise APIError.new(
91
- message: json["message"],
95
+ message: json['message'],
92
96
  http_status: http_status,
93
- request_id: response["x-request-id"]
97
+ request_id: response['x-request-id']
94
98
  )
95
99
  when 422
96
- message = json["message"]
97
- errors = extract_error(json["errors"]) if json["errors"]
100
+ message = json['message']
101
+ errors = extract_error(json['errors']) if json['errors']
98
102
  message += " (#{errors})" if errors
99
103
 
100
104
  raise InvalidRequestError.new(
101
105
  message: message,
102
106
  http_status: http_status,
103
- request_id: response["x-request-id"]
107
+ request_id: response['x-request-id']
104
108
  )
105
109
  end
106
110
  end
107
111
 
112
+ # rubocop:enable Metrics/AbcSize
113
+
108
114
  private
109
115
 
110
116
  def extract_error(errors)
111
117
  errors.map do |error|
112
- "#{error["field"]}: #{error["message"]} (#{error["type"]})"
113
- end.join("; ")
118
+ "#{error['field']}: #{error['message']} (#{error['type']})"
119
+ end.join('; ')
114
120
  end
115
121
  end
116
122
  end
data/lib/knock/errors.rb CHANGED
@@ -1,9 +1,12 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Knock
4
+ # Knock specific errors
2
5
  class KnockError < StandardError
3
- attr_reader :http_status
4
- attr_reader :request_id
6
+ attr_reader :http_status, :request_id
5
7
 
6
8
  def initialize(message: nil, error: nil, error_description: nil, http_status: nil, request_id: nil)
9
+ super
7
10
  @message = message
8
11
  @error = error
9
12
  @error_description = error_description
@@ -12,8 +15,8 @@ module Knock
12
15
  end
13
16
 
14
17
  def to_s
15
- status_string = @http_status.nil? ? "" : "Status #{@http_status}, "
16
- id_string = @request_id.nil? ? "" : " - request ID: #{@request_id}"
18
+ status_string = @http_status.nil? ? '' : "Status #{@http_status}, "
19
+ id_string = @request_id.nil? ? '' : " - request ID: #{@request_id}"
17
20
 
18
21
  if @error && @error_description
19
22
  error_string = "error: #{@error}, error_description: #{@error_description}"
@@ -0,0 +1,89 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'net/http'
4
+ require 'uri'
5
+
6
+ module Knock
7
+ # Methods for interacting with messages in Knock
8
+ module Messages
9
+ class << self
10
+ include Base
11
+ include Client
12
+
13
+ # Retrieves a paginated list of messages for the provided environment
14
+ #
15
+ # @param [Hash] options Options to pass to the messages endpoint query
16
+ #
17
+ # @return [Hash] Paginated list of Message records
18
+ def list(options: {})
19
+ request = get_request(
20
+ auth: true,
21
+ path: '/v1/messages',
22
+ params: options
23
+ )
24
+
25
+ execute_request(request: request)
26
+ end
27
+
28
+ # Retrieves a Message
29
+ #
30
+ # @param [String] id The message id
31
+ #
32
+ # @return [Hash] The Message
33
+ def get(id:)
34
+ request = get_request(
35
+ auth: true,
36
+ path: "/v1/messages/#{id}"
37
+ )
38
+
39
+ execute_request(request: request)
40
+ end
41
+
42
+ # Get a Message's content
43
+ #
44
+ # @param [String] id The message id
45
+ #
46
+ # @return [Hash] The Message content
47
+ def get_content(id:)
48
+ request = get_request(
49
+ auth: true,
50
+ path: "/v1/messages/#{id}/content"
51
+ )
52
+
53
+ execute_request(request: request)
54
+ end
55
+
56
+ # Get a Message's activities
57
+ #
58
+ # @param [String] id The message id
59
+ # @param [Hash] options Options to pass to the paginated activities endpoint query
60
+ #
61
+ # @return [Hash] Paginated Message's activities
62
+ def get_activities(id:, options: {})
63
+ request = get_request(
64
+ auth: true,
65
+ path: "/v1/messages/#{id}/activities",
66
+ params: options
67
+ )
68
+
69
+ execute_request(request: request)
70
+ end
71
+
72
+ # Get a Message's events
73
+ #
74
+ # @param [String] id The message id
75
+ # @param [Hash] options Options to pass to the paginated events endpoint query
76
+ #
77
+ # @return [Hash] Paginated Message's events
78
+ def get_events(id:, options: {})
79
+ request = get_request(
80
+ auth: true,
81
+ path: "/v1/messages/#{id}/events",
82
+ params: options
83
+ )
84
+
85
+ execute_request(request: request)
86
+ end
87
+ end
88
+ end
89
+ end
data/lib/knock/objects.rb CHANGED
@@ -1,13 +1,18 @@
1
- require "net/http"
2
- require "uri"
1
+ # frozen_string_literal: true
2
+
3
+ require 'net/http'
4
+ require 'uri'
3
5
 
4
6
  module Knock
5
- # Provides convienience methods for working with bulk operations
7
+ # Methods for interacting with objects in Knock
8
+ # rubocop:disable Metrics/ModuleLength
6
9
  module Objects
7
10
  class << self
8
11
  include Base
9
12
  include Client
10
13
 
14
+ DEFAULT_PREFERENCE_SET_ID = 'default'
15
+
11
16
  # Retrieves an Object in a collection
12
17
  #
13
18
  # @param [String] collection The collection the object is in
@@ -50,7 +55,7 @@ module Knock
50
55
  request = post_request(
51
56
  auth: true,
52
57
  path: "/v1/objects/#{collection}/bulk/set",
53
- body: {objects: objects}
58
+ body: { objects: objects }
54
59
  )
55
60
 
56
61
  execute_request(request: request)
@@ -81,7 +86,7 @@ module Knock
81
86
  request = post_request(
82
87
  auth: true,
83
88
  path: "/v1/objects/#{collection}/bulk/delete",
84
- body: {object_ids: object_ids}
89
+ body: { object_ids: object_ids }
85
90
  )
86
91
 
87
92
  execute_request(request: request)
@@ -111,15 +116,194 @@ module Knock
111
116
  # @param [Hash] channel_data channel data
112
117
  #
113
118
  # @return [Hash] channel data
114
- def set_channel_data(id:, channel_id:, channel_data:)
119
+ def set_channel_data(collection:, id:, channel_id:, channel_data:)
115
120
  request = put_request(
116
121
  auth: true,
117
122
  path: "/v1/objects/#{collection}/#{id}/channel_data/#{channel_id}",
118
- body: {data: channel_data}
123
+ body: { data: channel_data }
124
+ )
125
+
126
+ execute_request(request: request)
127
+ end
128
+
129
+ # Unsets object channel data for the given channel id
130
+ #
131
+ # @param [String] collection The collection the object is in
132
+ # @param [String] id The object id
133
+ # @param [String] channel_id target channel ID
134
+ #
135
+ # @return [Hash] channel data
136
+ def unset_channel_data(collection:, id:, channel_id:)
137
+ request = delete_request(
138
+ auth: true,
139
+ path: "/v1/objects/#{collection}/#{id}/channel_data/#{channel_id}"
140
+ )
141
+
142
+ execute_request(request: request)
143
+ end
144
+
145
+ # Get object's messages
146
+ #
147
+ # @param [String] collection The collection the object is in
148
+ # @param [String] id The object id
149
+ # @param [Hash] options Options to pass to the messages endpoint query
150
+ #
151
+ # @return [Hash] Paginated messages response
152
+ def get_messages(collection:, id:, options: {})
153
+ request = get_request(
154
+ auth: true,
155
+ path: "/v1/objects/#{collection}/#{id}/messages",
156
+ params: options
157
+ )
158
+
159
+ execute_request(request: request)
160
+ end
161
+
162
+ ##
163
+ # Preferences
164
+ ##
165
+
166
+ # Returns all preference sets for the object
167
+ #
168
+ # @param [String] collection The collection the object is in
169
+ # @param [String] id The object id
170
+ #
171
+ # @return [Array] The preference sets
172
+ def get_all_preferences(collection:, id:)
173
+ endpoint = "/v1/objects/#{collection}/#{id}/preferences"
174
+
175
+ request = get_request(
176
+ auth: true,
177
+ path: endpoint
178
+ )
179
+
180
+ execute_request(request: request)
181
+ end
182
+
183
+ # Gets a single preference set, defaults to the 'default' set
184
+ # for the object given.
185
+ #
186
+ # @param [String] collection The collection the object is in
187
+ # @param [String] id The object id
188
+ # @param [String] preference_set The preference set ID (defaults to `default`)
189
+ #
190
+ # @return [Hash] The preference set (if it exists)
191
+ def get_preferences(collection:, id:, preference_set: DEFAULT_PREFERENCE_SET_ID)
192
+ endpoint = "/v1/objects/#{collection}/#{id}/preferences/#{preference_set}"
193
+
194
+ request = get_request(
195
+ auth: true,
196
+ path: endpoint
197
+ )
198
+
199
+ execute_request(request: request)
200
+ end
201
+
202
+ # Sets multiple preferences at once for the preference set.
203
+ #
204
+ # @param [String] collection The collection the object is in
205
+ # @param [String] id The object id
206
+ # @param [String] preference_set The preference set ID (defaults to `default`)
207
+ # @param [Hash] channel_types The channel_types hash to set
208
+ # @param [Hash] workflows The workflows hash to set
209
+ # @param [Hash] categories The categories hash to set
210
+ #
211
+ # @return [Hash] The preference set
212
+
213
+ def set_preferences(
214
+ collection:,
215
+ id:,
216
+ channel_types: nil,
217
+ workflows: nil,
218
+ categories: nil,
219
+ preference_set: DEFAULT_PREFERENCE_SET_ID
220
+ )
221
+ endpoint = "/v1/objects/#{collection}/#{id}/preferences/#{preference_set}"
222
+
223
+ request = put_request(
224
+ auth: true,
225
+ path: endpoint,
226
+ body: {
227
+ channel_types: channel_types,
228
+ workflows: workflows,
229
+ categories: categories
230
+ }
231
+ )
232
+
233
+ execute_request(request: request)
234
+ end
235
+
236
+ # Sets preferences for the given channel type
237
+ #
238
+ # @param [String] collection The collection the object is in
239
+ # @param [String] id The object id
240
+ # @param [String] preference_set The preference set ID (defaults to `default`)
241
+ # @param [String] channel_type The channel type to set
242
+ # @param [Bool] setting Whether the channel type is enabled or not
243
+ #
244
+ # @return [Hash] The preference set
245
+ def set_channel_type_preferences(collection:,
246
+ id:,
247
+ channel_type:,
248
+ setting:,
249
+ preference_set: DEFAULT_PREFERENCE_SET_ID)
250
+ endpoint = "/v1/objects/#{collection}/#{id}/preferences/#{preference_set}/channel_types/#{channel_type}"
251
+
252
+ request = put_request(
253
+ auth: true,
254
+ path: endpoint,
255
+ body: { subscribed: setting }
256
+ )
257
+
258
+ execute_request(request: request)
259
+ end
260
+
261
+ # Sets preferences for the given workflow
262
+ #
263
+ # @param [String] collection The collection the object is in
264
+ # @param [String] id The object id
265
+ # @param [String] preference_set The preference set ID (defaults to `default`)
266
+ # @param [String] workflow The workflow to set preferences for
267
+ # @param [Bool | Hash] setting Either a boolean to indicate if the type is enabled
268
+ # or a hash containing channel types and settings
269
+ #
270
+ # @return [Hash] The preference set
271
+ def set_workflow_preferences(collection:, id:, workflow:, setting:, preference_set: DEFAULT_PREFERENCE_SET_ID)
272
+ params = setting.is_a?(Hash) ? setting : { subscribed: setting }
273
+ endpoint = "/v1/objects/#{collection}/#{id}/preferences/#{preference_set}/workflows/#{workflow}"
274
+
275
+ request = put_request(
276
+ auth: true,
277
+ path: endpoint,
278
+ body: params
279
+ )
280
+
281
+ execute_request(request: request)
282
+ end
283
+
284
+ # Sets preferences for the given category
285
+ #
286
+ # @param [String] collection The collection the object is in
287
+ # @param [String] id The object id
288
+ # @param [String] preference_set The preference set ID (defaults to `default`)
289
+ # @param [String] category The category to set preferences for
290
+ # @param [Bool | Hash] setting Either a boolean to indicate if the type is enabled
291
+ # or a hash containing channel types and settings
292
+ #
293
+ # @return [Hash] The preference set
294
+ def set_category_preferences(collection:, id:, category:, setting:, preference_set: DEFAULT_PREFERENCE_SET_ID)
295
+ params = setting.is_a?(Hash) ? setting : { subscribed: setting }
296
+ endpoint = "/v1/objects/#{collection}/#{id}/preferences/#{preference_set}/categories/#{category}"
297
+
298
+ request = put_request(
299
+ auth: true,
300
+ path: endpoint,
301
+ body: params
119
302
  )
120
303
 
121
304
  execute_request(request: request)
122
305
  end
123
306
  end
124
307
  end
308
+ # rubocop:enable Metrics/ModuleLength
125
309
  end
@@ -1,5 +1,7 @@
1
- require "net/http"
2
- require "uri"
1
+ # frozen_string_literal: true
2
+
3
+ require 'net/http'
4
+ require 'uri'
3
5
 
4
6
  module Knock
5
7
  # Provides convienience methods for working with preferences (deprecated)
@@ -36,7 +38,7 @@ module Knock
36
38
  # @param [String] preference_set The preference set ID (defaults to `default`)
37
39
  # @param [Hash] preferences The preferences hash to set
38
40
  #
39
- #  @return [Hash] The preference set
41
+ # @return [Hash] The preference set
40
42
  # @deprecated Please use {#Knock::Users.set_preferences} instead
41
43
  def update(
42
44
  user_id:,
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'net/http'
4
+ require 'uri'
5
+
6
+ module Knock
7
+ # Methods for interacting with tenants in Knock
8
+ module Tenants
9
+ class << self
10
+ include Base
11
+ include Client
12
+
13
+ # Retrieves all Tenants in environment
14
+ #
15
+ # @param [Hash] options Options to pass to the tenants endpoint query
16
+ #
17
+ # @return [Hash] Paginated list of Tenant records
18
+ def list(options: {})
19
+ request = get_request(
20
+ auth: true,
21
+ path: '/v1/tenants',
22
+ params: options
23
+ )
24
+
25
+ execute_request(request: request)
26
+ end
27
+
28
+ # Retrieves a Tenant
29
+ #
30
+ # @param [String] id The Tenant id
31
+ #
32
+ # @return [Hash] The Tenant
33
+ def get(id:)
34
+ request = get_request(
35
+ auth: true,
36
+ path: "/v1/tenants/#{id}"
37
+ )
38
+
39
+ execute_request(request: request)
40
+ end
41
+
42
+ # Upserts a Tenant
43
+ #
44
+ # @param [String] id The Tenant id
45
+ # @param [Hash] tenant_data The data to set on the Tenant
46
+ #
47
+ # @return [Hash] The Tenant
48
+ def set(id:, tenant_data: {})
49
+ request = put_request(
50
+ auth: true,
51
+ path: "/v1/tenants/#{id}",
52
+ body: tenant_data
53
+ )
54
+
55
+ execute_request(request: request)
56
+ end
57
+
58
+ # Deletes a Tenant
59
+ #
60
+ # @param [String] id The Tenant id
61
+ #
62
+ # @return [nil] Nothing
63
+ def delete(id:)
64
+ request = delete_request(
65
+ auth: true,
66
+ path: "/v1/tenants/#{id}"
67
+ )
68
+
69
+ execute_request(request: request)
70
+ end
71
+ end
72
+ end
73
+ end
data/lib/knock/users.rb CHANGED
@@ -1,14 +1,17 @@
1
- require "net/http"
2
- require "uri"
1
+ # frozen_string_literal: true
2
+
3
+ require 'net/http'
4
+ require 'uri'
3
5
 
4
6
  module Knock
5
7
  # Provides convienience methods for working with users
8
+ # rubocop:disable Metrics/ModuleLength
6
9
  module Users
7
10
  class << self
8
11
  include Base
9
12
  include Client
10
13
 
11
- DEFAULT_PREFERENCE_SET_ID = "default"
14
+ DEFAULT_PREFERENCE_SET_ID = 'default'
12
15
 
13
16
  # Identifies the user
14
17
  #
@@ -34,8 +37,8 @@ module Knock
34
37
  def bulk_identify(users: [])
35
38
  request = post_request(
36
39
  auth: true,
37
- path: "/v1/users/bulk/identify",
38
- body: {users: users}
40
+ path: '/v1/users/bulk/identify',
41
+ body: { users: users }
39
42
  )
40
43
 
41
44
  execute_request(request: request)
@@ -77,8 +80,8 @@ module Knock
77
80
  def bulk_delete(user_ids: [])
78
81
  request = post_request(
79
82
  auth: true,
80
- path: "/v1/users/bulk/delete",
81
- body: {user_ids: user_ids}
83
+ path: '/v1/users/bulk/delete',
84
+ body: { user_ids: user_ids }
82
85
  )
83
86
 
84
87
  execute_request(request: request)
@@ -198,12 +201,10 @@ module Knock
198
201
  preferences: {},
199
202
  preference_set: DEFAULT_PREFERENCE_SET_ID
200
203
  )
201
- endpoint = "/v1/users/bulk/preferences"
204
+ endpoint = '/v1/users/bulk/preferences'
202
205
 
203
206
  # Put the preference set id if it doesn't already exist
204
- unless preferences.has_key("id")
205
- preferences["id"] = preference_set
206
- end
207
+ preferences['id'] = preference_set unless preferences.has_key('id')
207
208
 
208
209
  request = put_request(
209
210
  auth: true,
@@ -231,7 +232,7 @@ module Knock
231
232
  request = put_request(
232
233
  auth: true,
233
234
  path: endpoint,
234
- body: {subscribed: setting}
235
+ body: { subscribed: setting }
235
236
  )
236
237
 
237
238
  execute_request(request: request)
@@ -247,7 +248,7 @@ module Knock
247
248
  #
248
249
  # @return [Hash] The preference set
249
250
  def set_workflow_preferences(user_id:, workflow:, setting:, preference_set: DEFAULT_PREFERENCE_SET_ID)
250
- params = setting.is_a?(Hash) ? setting : {subscribed: setting}
251
+ params = setting.is_a?(Hash) ? setting : { subscribed: setting }
251
252
  endpoint = "/v1/users/#{user_id}/preferences/#{preference_set}/workflows/#{workflow}"
252
253
 
253
254
  request = put_request(
@@ -269,7 +270,7 @@ module Knock
269
270
  #
270
271
  # @return [Hash] The preference set
271
272
  def set_category_preferences(user_id:, category:, setting:, preference_set: DEFAULT_PREFERENCE_SET_ID)
272
- params = setting.is_a?(Hash) ? setting : {subscribed: setting}
273
+ params = setting.is_a?(Hash) ? setting : { subscribed: setting }
273
274
  endpoint = "/v1/users/#{user_id}/preferences/#{preference_set}/categories/#{category}"
274
275
 
275
276
  request = put_request(
@@ -311,11 +312,48 @@ module Knock
311
312
  request = put_request(
312
313
  auth: true,
313
314
  path: "/v1/users/#{id}/channel_data/#{channel_id}",
314
- body: {data: channel_data}
315
+ body: { data: channel_data }
316
+ )
317
+
318
+ execute_request(request: request)
319
+ end
320
+
321
+ # Unsets user's channel data for the given channel id
322
+ #
323
+ # @param [String] id the user ID
324
+ # @param [String] channel_id target channel ID
325
+ # @param [Hash] channel_data channel data
326
+ #
327
+ # @return [Hash] channel data
328
+ def unset_channel_data(id:, channel_id:)
329
+ request = delete_request(
330
+ auth: true,
331
+ path: "/v1/users/#{id}/channel_data/#{channel_id}"
332
+ )
333
+
334
+ execute_request(request: request)
335
+ end
336
+
337
+ ##
338
+ # Messages
339
+ ##
340
+
341
+ # Get user's messages
342
+ #
343
+ # @param [String] id the user ID
344
+ # @param [Hash] options Options to pass to the messages endpoint query
345
+ #
346
+ # @return [Hash] Paginated messages response
347
+ def get_messages(id:, options: {})
348
+ request = get_request(
349
+ auth: true,
350
+ path: "/v1/users/#{id}/messages",
351
+ params: options
315
352
  )
316
353
 
317
354
  execute_request(request: request)
318
355
  end
319
356
  end
320
357
  end
358
+ # rubocop:enable Metrics/ModuleLength
321
359
  end
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.1"
4
+ VERSION = '0.4.4'
5
5
  end
@@ -1,5 +1,7 @@
1
- require "net/http"
2
- require "uri"
1
+ # frozen_string_literal: true
2
+
3
+ require 'net/http'
4
+ require 'uri'
3
5
 
4
6
  module Knock
5
7
  # Methods for interacting with workflows in Knock
@@ -11,7 +13,7 @@ module Knock
11
13
  # Triggers the workflow with the given key
12
14
  #
13
15
  # @param [String] key The workflow key
14
- # @param [String, Hash] actor The actor identifier
16
+ # @param [String, Hash] actor The actor identifier (optional)
15
17
  # @param [Array<String, Hash>] recipients The recipient identifiers
16
18
  # @param [Hash] data The data to pass to the workflow
17
19
  # @param [String] cancellation_key An optional key to identify this workflow
data/lib/knock.rb CHANGED
@@ -1,10 +1,11 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "knock/version"
4
- require "json"
3
+ require 'knock/version'
4
+ require 'json'
5
5
 
6
+ # Setup for Knock client
6
7
  module Knock
7
- API_HOSTNAME = ENV["KNOCK_API_HOSTNAME"] || "api.knock.app"
8
+ API_HOSTNAME = ENV['KNOCK_API_HOSTNAME'] || 'api.knock.app'
8
9
 
9
10
  def self.key=(value)
10
11
  Base.key = value
@@ -15,25 +16,27 @@ module Knock
15
16
  end
16
17
 
17
18
  def self.key!
18
- key || raise("Knock.key not set")
19
+ key || raise('Knock.key not set')
19
20
  end
20
21
 
21
- autoload :Base, "knock/base"
22
- autoload :Client, "knock/client"
22
+ autoload :Base, 'knock/base'
23
+ autoload :Client, 'knock/client'
23
24
 
24
25
  # Resources
25
- autoload :Preferences, "knock/preferences"
26
- autoload :Users, "knock/users"
27
- autoload :Workflows, "knock/workflows"
28
- autoload :BulkOperations, "knock/bulk_operations"
29
- autoload :Objects, "knock/objects"
26
+ autoload :Preferences, 'knock/preferences'
27
+ autoload :Users, 'knock/users'
28
+ autoload :Workflows, 'knock/workflows'
29
+ autoload :BulkOperations, 'knock/bulk_operations'
30
+ autoload :Objects, 'knock/objects'
31
+ autoload :Tenants, 'knock/tenants'
32
+ autoload :Messages, 'knock/messages'
30
33
 
31
34
  # Errors
32
- autoload :APIError, "knock/errors"
33
- autoload :AuthenticationError, "knock/errors"
34
- autoload :InvalidRequestError, "knock/errors"
35
+ autoload :APIError, 'knock/errors'
36
+ autoload :AuthenticationError, 'knock/errors'
37
+ autoload :InvalidRequestError, 'knock/errors'
35
38
 
36
- key = ENV["KNOCK_API_KEY"]
39
+ key = ENV['KNOCK_API_KEY']
37
40
  Knock.key = key unless key.nil?
38
41
 
39
42
  # Triggers the workflow with the given key
@@ -0,0 +1,66 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative '../lib/knock'
4
+ # rubocop:disable Metrics/BlockLength
5
+ describe 'tenant tests' do
6
+ before do
7
+ allow_any_instance_of(Knock::Client)
8
+ .to receive(:execute_request)
9
+ .with({ request: 'request' })
10
+ .and_return('ok')
11
+ end
12
+ describe '#list' do
13
+ before do
14
+ allow_any_instance_of(Knock::Client)
15
+ .to receive(:get_request)
16
+ .with({ auth: true,
17
+ path: '/v1/tenants',
18
+ params: {} })
19
+ .and_return('request')
20
+ end
21
+ it 'sends the correct parameters to the tenants API' do
22
+ Knock::Tenants.list(options: {})
23
+ end
24
+ end
25
+
26
+ describe '#get' do
27
+ before do
28
+ allow_any_instance_of(Knock::Client)
29
+ .to receive(:get_request)
30
+ .with({ auth: true,
31
+ path: '/v1/tenants/tenant_id' })
32
+ .and_return('request')
33
+ end
34
+ it 'sends the correct parameters to the tenants API' do
35
+ Knock::Tenants.get(id: 'tenant_id')
36
+ end
37
+ end
38
+
39
+ describe '#delete' do
40
+ before do
41
+ allow_any_instance_of(Knock::Client)
42
+ .to receive(:delete_request)
43
+ .with({ auth: true,
44
+ path: '/v1/tenants/tenant_id' })
45
+ .and_return('request')
46
+ end
47
+ it 'sends the correct parameters to the tenants API' do
48
+ Knock::Tenants.delete(id: 'tenant_id')
49
+ end
50
+ end
51
+
52
+ describe '#set' do
53
+ before do
54
+ body = { name: 'My tenant', settings: { branding: { primary_color: '#FFFFFF' } } }
55
+ allow_any_instance_of(Knock::Client).to receive(:put_request)
56
+ .with({ auth: true,
57
+ body: body, path: '/v1/tenants/tenant_id' })
58
+ .and_return('request')
59
+ end
60
+ it 'sends the correct parameters to the tenants API' do
61
+ tenant_data = { name: 'My tenant', settings: { branding: { primary_color: '#FFFFFF' } } }
62
+ Knock::Tenants.set(id: 'tenant_id', tenant_data: tenant_data)
63
+ end
64
+ end
65
+ end
66
+ # rubocop:enable Metrics/BlockLength
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.1
4
+ version: 0.4.4
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: 2022-01-21 00:00:00.000000000 Z
11
+ date: 2022-07-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -62,7 +62,9 @@ extensions: []
62
62
  extra_rdoc_files: []
63
63
  files:
64
64
  - ".github/workflows/publish.yml"
65
+ - ".github/workflows/ruby.yml"
65
66
  - ".gitignore"
67
+ - ".rubocop.yml"
66
68
  - ".ruby-version"
67
69
  - Gemfile
68
70
  - Gemfile.lock
@@ -76,11 +78,14 @@ files:
76
78
  - lib/knock/bulk_operations.rb
77
79
  - lib/knock/client.rb
78
80
  - lib/knock/errors.rb
81
+ - lib/knock/messages.rb
79
82
  - lib/knock/objects.rb
80
83
  - lib/knock/preferences.rb
84
+ - lib/knock/tenants.rb
81
85
  - lib/knock/users.rb
82
86
  - lib/knock/version.rb
83
87
  - lib/knock/workflows.rb
88
+ - spec/tenants_spec.rb
84
89
  homepage: https://github.com/knocklabs/knock-ruby
85
90
  licenses:
86
91
  - MIT
@@ -101,8 +106,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
101
106
  - !ruby/object:Gem::Version
102
107
  version: '0'
103
108
  requirements: []
104
- rubygems_version: 3.3.3
109
+ rubygems_version: 3.3.7
105
110
  signing_key:
106
111
  specification_version: 4
107
112
  summary: API client for Knock
108
- test_files: []
113
+ test_files:
114
+ - spec/tenants_spec.rb