knockapi 0.4.3 → 0.4.5
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 +4 -4
- data/.github/workflows/ruby.yml +52 -0
- data/.rubocop.yml +8 -0
- data/Gemfile +5 -1
- data/Gemfile.lock +16 -1
- data/bin/console +5 -4
- data/knockapi.gemspec +15 -15
- data/lib/knock/base.rb +3 -2
- data/lib/knock/bulk_operations.rb +4 -2
- data/lib/knock/client.rb +32 -28
- data/lib/knock/errors.rb +7 -4
- data/lib/knock/messages.rb +10 -4
- data/lib/knock/objects.rb +23 -11
- data/lib/knock/preferences.rb +5 -3
- data/lib/knock/tenants.rb +73 -0
- data/lib/knock/users.rb +23 -16
- data/lib/knock/version.rb +1 -1
- data/lib/knock/workflows.rb +4 -2
- data/lib/knock.rb +18 -16
- data/spec/tenants_spec.rb +66 -0
- metadata +9 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 81cfa3f6f13dddad567058c6c1bf837d41fbf4227247e6d5f7cd4bcedf94cb2b
|
4
|
+
data.tar.gz: 18ed9ffaed543083c5edcb5c2a0274919b10fca298938e324f96d2514c2dfa81
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8e2e848f8d590fff5367f1a805c671fc9ad0643fc6b14e1300d362d99007de94922fe56a74dc1a9bf73e4d4aa79002239b9f7171d25aef68cea6ef3c261304e8
|
7
|
+
data.tar.gz: c4c4ee1372ed47fea5d4fa4c7fddeb1daf4d101959214101b671c1ea8408c7144f98f0e263c0c785639cc8978b2639d438a38b1a97974eab1333fde9fa2d7fc4
|
@@ -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
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,12 +1,13 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
knockapi (0.4.
|
4
|
+
knockapi (0.4.5)
|
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
data/knockapi.gemspec
CHANGED
@@ -1,30 +1,30 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
lib = File.expand_path(
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
4
4
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
-
require
|
5
|
+
require 'knock/version'
|
6
6
|
|
7
7
|
Gem::Specification.new do |spec|
|
8
|
-
spec.name =
|
8
|
+
spec.name = 'knockapi'
|
9
9
|
spec.version = Knock::VERSION
|
10
|
-
spec.authors = [
|
11
|
-
spec.email = [
|
12
|
-
spec.description =
|
13
|
-
spec.summary =
|
14
|
-
spec.homepage =
|
15
|
-
spec.license =
|
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
|
-
|
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 = [
|
23
|
+
spec.require_paths = ['lib']
|
24
24
|
|
25
|
-
spec.add_development_dependency
|
26
|
-
spec.add_development_dependency
|
27
|
-
spec.add_development_dependency
|
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 =
|
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
|
-
|
8
|
-
attr_reader :key
|
9
|
+
attr_accessor :key
|
9
10
|
end
|
10
11
|
end
|
11
12
|
end
|
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,9 +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
|
-
if response.body
|
22
|
-
JSON.parse(response.body)
|
23
|
-
end
|
23
|
+
JSON.parse(response.body) if response.body && (response.body != '')
|
24
24
|
end
|
25
25
|
|
26
26
|
def get_request(path:, auth: false, params: {}, access_token: nil)
|
@@ -29,19 +29,19 @@ module Knock
|
|
29
29
|
|
30
30
|
request = Net::HTTP::Get.new(
|
31
31
|
uri.to_s,
|
32
|
-
|
32
|
+
'Content-Type' => 'application/json'
|
33
33
|
)
|
34
34
|
|
35
|
-
request[
|
36
|
-
request[
|
35
|
+
request['Authorization'] = "Bearer #{access_token || Knock.key!}" if auth
|
36
|
+
request['User-Agent'] = user_agent
|
37
37
|
request
|
38
38
|
end
|
39
39
|
|
40
|
-
def post_request(path:, auth: false,
|
41
|
-
request = Net::HTTP::Post.new(path,
|
40
|
+
def post_request(path:, auth: false, _idempotency_key: nil, body: nil)
|
41
|
+
request = Net::HTTP::Post.new(path, 'Content-Type' => 'application/json')
|
42
42
|
request.body = body.to_json if body
|
43
|
-
request[
|
44
|
-
request[
|
43
|
+
request['Authorization'] = "Bearer #{Knock.key!}" if auth
|
44
|
+
request['User-Agent'] = user_agent
|
45
45
|
request
|
46
46
|
end
|
47
47
|
|
@@ -51,19 +51,19 @@ module Knock
|
|
51
51
|
|
52
52
|
request = Net::HTTP::Delete.new(
|
53
53
|
uri.to_s,
|
54
|
-
|
54
|
+
'Content-Type' => 'application/json'
|
55
55
|
)
|
56
56
|
|
57
|
-
request[
|
58
|
-
request[
|
57
|
+
request['Authorization'] = "Bearer #{Knock.key!}" if auth
|
58
|
+
request['User-Agent'] = user_agent
|
59
59
|
request
|
60
60
|
end
|
61
61
|
|
62
|
-
def put_request(path:, auth: false,
|
63
|
-
request = Net::HTTP::Put.new(path,
|
62
|
+
def put_request(path:, auth: false, _idempotency_key: nil, body: nil)
|
63
|
+
request = Net::HTTP::Put.new(path, 'Content-Type' => 'application/json')
|
64
64
|
request.body = body.to_json if body
|
65
|
-
request[
|
66
|
-
request[
|
65
|
+
request['Authorization'] = "Bearer #{Knock.key!}" if auth
|
66
|
+
request['User-Agent'] = user_agent
|
67
67
|
request
|
68
68
|
end
|
69
69
|
|
@@ -71,6 +71,8 @@ module Knock
|
|
71
71
|
"Knock Ruby - v#{Knock::VERSION}"
|
72
72
|
end
|
73
73
|
|
74
|
+
# rubocop:disable Metrics/AbcSize
|
75
|
+
|
74
76
|
def handle_error_response(response:)
|
75
77
|
http_status = response.code.to_i
|
76
78
|
json = JSON.parse(response.body)
|
@@ -78,41 +80,43 @@ module Knock
|
|
78
80
|
case http_status
|
79
81
|
when 400
|
80
82
|
raise InvalidRequestError.new(
|
81
|
-
message: json[
|
83
|
+
message: json['message'],
|
82
84
|
http_status: http_status,
|
83
|
-
request_id: response[
|
85
|
+
request_id: response['x-request-id']
|
84
86
|
)
|
85
87
|
when 401
|
86
88
|
raise AuthenticationError.new(
|
87
|
-
message: json[
|
89
|
+
message: json['message'],
|
88
90
|
http_status: http_status,
|
89
|
-
request_id: response[
|
91
|
+
request_id: response['x-request-id']
|
90
92
|
)
|
91
93
|
when 404
|
92
94
|
raise APIError.new(
|
93
|
-
message: json[
|
95
|
+
message: json['message'],
|
94
96
|
http_status: http_status,
|
95
|
-
request_id: response[
|
97
|
+
request_id: response['x-request-id']
|
96
98
|
)
|
97
99
|
when 422
|
98
|
-
message = json[
|
99
|
-
errors = extract_error(json[
|
100
|
+
message = json['message']
|
101
|
+
errors = extract_error(json['errors']) if json['errors']
|
100
102
|
message += " (#{errors})" if errors
|
101
103
|
|
102
104
|
raise InvalidRequestError.new(
|
103
105
|
message: message,
|
104
106
|
http_status: http_status,
|
105
|
-
request_id: response[
|
107
|
+
request_id: response['x-request-id']
|
106
108
|
)
|
107
109
|
end
|
108
110
|
end
|
109
111
|
|
112
|
+
# rubocop:enable Metrics/AbcSize
|
113
|
+
|
110
114
|
private
|
111
115
|
|
112
116
|
def extract_error(errors)
|
113
117
|
errors.map do |error|
|
114
|
-
"#{error[
|
115
|
-
end.join(
|
118
|
+
"#{error['field']}: #{error['message']} (#{error['type']})"
|
119
|
+
end.join('; ')
|
116
120
|
end
|
117
121
|
end
|
118
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? ?
|
16
|
-
id_string = @request_id.nil? ?
|
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}"
|
data/lib/knock/messages.rb
CHANGED
@@ -1,5 +1,8 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require 'net/http'
|
5
|
+
require 'uri'
|
3
6
|
|
4
7
|
module Knock
|
5
8
|
# Methods for interacting with messages in Knock
|
@@ -14,9 +17,11 @@ module Knock
|
|
14
17
|
#
|
15
18
|
# @return [Hash] Paginated list of Message records
|
16
19
|
def list(options: {})
|
20
|
+
options[:trigger_data] = JSON.generate(options[:trigger_data]) if options[:trigger_data]
|
21
|
+
|
17
22
|
request = get_request(
|
18
23
|
auth: true,
|
19
|
-
path:
|
24
|
+
path: '/v1/messages',
|
20
25
|
params: options
|
21
26
|
)
|
22
27
|
|
@@ -58,6 +63,8 @@ module Knock
|
|
58
63
|
#
|
59
64
|
# @return [Hash] Paginated Message's activities
|
60
65
|
def get_activities(id:, options: {})
|
66
|
+
options[:trigger_data] = JSON.generate(options[:trigger_data]) if options[:trigger_data]
|
67
|
+
|
61
68
|
request = get_request(
|
62
69
|
auth: true,
|
63
70
|
path: "/v1/messages/#{id}/activities",
|
@@ -85,4 +92,3 @@ module Knock
|
|
85
92
|
end
|
86
93
|
end
|
87
94
|
end
|
88
|
-
|
data/lib/knock/objects.rb
CHANGED
@@ -1,14 +1,18 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require 'net/http'
|
5
|
+
require 'uri'
|
3
6
|
|
4
7
|
module Knock
|
5
|
-
#
|
8
|
+
# Methods for interacting with objects in Knock
|
9
|
+
# rubocop:disable Metrics/ModuleLength
|
6
10
|
module Objects
|
7
11
|
class << self
|
8
12
|
include Base
|
9
13
|
include Client
|
10
14
|
|
11
|
-
DEFAULT_PREFERENCE_SET_ID =
|
15
|
+
DEFAULT_PREFERENCE_SET_ID = 'default'
|
12
16
|
|
13
17
|
# Retrieves an Object in a collection
|
14
18
|
#
|
@@ -52,7 +56,7 @@ module Knock
|
|
52
56
|
request = post_request(
|
53
57
|
auth: true,
|
54
58
|
path: "/v1/objects/#{collection}/bulk/set",
|
55
|
-
body: {objects: objects}
|
59
|
+
body: { objects: objects }
|
56
60
|
)
|
57
61
|
|
58
62
|
execute_request(request: request)
|
@@ -83,7 +87,7 @@ module Knock
|
|
83
87
|
request = post_request(
|
84
88
|
auth: true,
|
85
89
|
path: "/v1/objects/#{collection}/bulk/delete",
|
86
|
-
body: {object_ids: object_ids}
|
90
|
+
body: { object_ids: object_ids }
|
87
91
|
)
|
88
92
|
|
89
93
|
execute_request(request: request)
|
@@ -117,7 +121,7 @@ module Knock
|
|
117
121
|
request = put_request(
|
118
122
|
auth: true,
|
119
123
|
path: "/v1/objects/#{collection}/#{id}/channel_data/#{channel_id}",
|
120
|
-
body: {data: channel_data}
|
124
|
+
body: { data: channel_data }
|
121
125
|
)
|
122
126
|
|
123
127
|
execute_request(request: request)
|
@@ -147,6 +151,8 @@ module Knock
|
|
147
151
|
#
|
148
152
|
# @return [Hash] Paginated messages response
|
149
153
|
def get_messages(collection:, id:, options: {})
|
154
|
+
options[:trigger_data] = JSON.generate(options[:trigger_data]) if options[:trigger_data]
|
155
|
+
|
150
156
|
request = get_request(
|
151
157
|
auth: true,
|
152
158
|
path: "/v1/objects/#{collection}/#{id}/messages",
|
@@ -206,6 +212,7 @@ module Knock
|
|
206
212
|
# @param [Hash] categories The categories hash to set
|
207
213
|
#
|
208
214
|
# @return [Hash] The preference set
|
215
|
+
|
209
216
|
def set_preferences(
|
210
217
|
collection:,
|
211
218
|
id:,
|
@@ -238,13 +245,17 @@ module Knock
|
|
238
245
|
# @param [Bool] setting Whether the channel type is enabled or not
|
239
246
|
#
|
240
247
|
# @return [Hash] The preference set
|
241
|
-
def set_channel_type_preferences(collection:,
|
248
|
+
def set_channel_type_preferences(collection:,
|
249
|
+
id:,
|
250
|
+
channel_type:,
|
251
|
+
setting:,
|
252
|
+
preference_set: DEFAULT_PREFERENCE_SET_ID)
|
242
253
|
endpoint = "/v1/objects/#{collection}/#{id}/preferences/#{preference_set}/channel_types/#{channel_type}"
|
243
254
|
|
244
255
|
request = put_request(
|
245
256
|
auth: true,
|
246
257
|
path: endpoint,
|
247
|
-
body: {subscribed: setting}
|
258
|
+
body: { subscribed: setting }
|
248
259
|
)
|
249
260
|
|
250
261
|
execute_request(request: request)
|
@@ -261,7 +272,7 @@ module Knock
|
|
261
272
|
#
|
262
273
|
# @return [Hash] The preference set
|
263
274
|
def set_workflow_preferences(collection:, id:, workflow:, setting:, preference_set: DEFAULT_PREFERENCE_SET_ID)
|
264
|
-
params = setting.is_a?(Hash) ? setting : {subscribed: setting}
|
275
|
+
params = setting.is_a?(Hash) ? setting : { subscribed: setting }
|
265
276
|
endpoint = "/v1/objects/#{collection}/#{id}/preferences/#{preference_set}/workflows/#{workflow}"
|
266
277
|
|
267
278
|
request = put_request(
|
@@ -284,7 +295,7 @@ module Knock
|
|
284
295
|
#
|
285
296
|
# @return [Hash] The preference set
|
286
297
|
def set_category_preferences(collection:, id:, category:, setting:, preference_set: DEFAULT_PREFERENCE_SET_ID)
|
287
|
-
params = setting.is_a?(Hash) ? setting : {subscribed: setting}
|
298
|
+
params = setting.is_a?(Hash) ? setting : { subscribed: setting }
|
288
299
|
endpoint = "/v1/objects/#{collection}/#{id}/preferences/#{preference_set}/categories/#{category}"
|
289
300
|
|
290
301
|
request = put_request(
|
@@ -297,4 +308,5 @@ module Knock
|
|
297
308
|
end
|
298
309
|
end
|
299
310
|
end
|
311
|
+
# rubocop:enable Metrics/ModuleLength
|
300
312
|
end
|
data/lib/knock/preferences.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
|
-
|
2
|
-
|
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
|
-
#
|
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,18 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'json'
|
4
|
+
require 'net/http'
|
5
|
+
require 'uri'
|
3
6
|
|
4
7
|
module Knock
|
5
8
|
# Provides convienience methods for working with users
|
9
|
+
# rubocop:disable Metrics/ModuleLength
|
6
10
|
module Users
|
7
11
|
class << self
|
8
12
|
include Base
|
9
13
|
include Client
|
10
14
|
|
11
|
-
DEFAULT_PREFERENCE_SET_ID =
|
15
|
+
DEFAULT_PREFERENCE_SET_ID = 'default'
|
12
16
|
|
13
17
|
# Identifies the user
|
14
18
|
#
|
@@ -34,8 +38,8 @@ module Knock
|
|
34
38
|
def bulk_identify(users: [])
|
35
39
|
request = post_request(
|
36
40
|
auth: true,
|
37
|
-
path:
|
38
|
-
body: {users: users}
|
41
|
+
path: '/v1/users/bulk/identify',
|
42
|
+
body: { users: users }
|
39
43
|
)
|
40
44
|
|
41
45
|
execute_request(request: request)
|
@@ -77,8 +81,8 @@ module Knock
|
|
77
81
|
def bulk_delete(user_ids: [])
|
78
82
|
request = post_request(
|
79
83
|
auth: true,
|
80
|
-
path:
|
81
|
-
body: {user_ids: user_ids}
|
84
|
+
path: '/v1/users/bulk/delete',
|
85
|
+
body: { user_ids: user_ids }
|
82
86
|
)
|
83
87
|
|
84
88
|
execute_request(request: request)
|
@@ -92,6 +96,8 @@ module Knock
|
|
92
96
|
#
|
93
97
|
# @return [Hash] the feed response
|
94
98
|
def get_feed(id:, channel_id:, options: {})
|
99
|
+
options[:trigger_data] = JSON.generate(options[:trigger_data]) if options[:trigger_data]
|
100
|
+
|
95
101
|
request = get_request(
|
96
102
|
auth: true,
|
97
103
|
path: "/v1/users/#{id}/feeds/#{channel_id}",
|
@@ -111,7 +117,7 @@ module Knock
|
|
111
117
|
request = post_request(
|
112
118
|
auth: true,
|
113
119
|
path: "/v1/users/#{id}/merge",
|
114
|
-
body: {from_user_id: from_user_id}
|
120
|
+
body: { from_user_id: from_user_id }
|
115
121
|
)
|
116
122
|
|
117
123
|
execute_request(request: request)
|
@@ -198,12 +204,10 @@ module Knock
|
|
198
204
|
preferences: {},
|
199
205
|
preference_set: DEFAULT_PREFERENCE_SET_ID
|
200
206
|
)
|
201
|
-
endpoint =
|
207
|
+
endpoint = '/v1/users/bulk/preferences'
|
202
208
|
|
203
209
|
# Put the preference set id if it doesn't already exist
|
204
|
-
unless preferences.has_key(
|
205
|
-
preferences["id"] = preference_set
|
206
|
-
end
|
210
|
+
preferences['id'] = preference_set unless preferences.has_key('id')
|
207
211
|
|
208
212
|
request = put_request(
|
209
213
|
auth: true,
|
@@ -231,7 +235,7 @@ module Knock
|
|
231
235
|
request = put_request(
|
232
236
|
auth: true,
|
233
237
|
path: endpoint,
|
234
|
-
body: {subscribed: setting}
|
238
|
+
body: { subscribed: setting }
|
235
239
|
)
|
236
240
|
|
237
241
|
execute_request(request: request)
|
@@ -247,7 +251,7 @@ module Knock
|
|
247
251
|
#
|
248
252
|
# @return [Hash] The preference set
|
249
253
|
def set_workflow_preferences(user_id:, workflow:, setting:, preference_set: DEFAULT_PREFERENCE_SET_ID)
|
250
|
-
params = setting.is_a?(Hash) ? setting : {subscribed: setting}
|
254
|
+
params = setting.is_a?(Hash) ? setting : { subscribed: setting }
|
251
255
|
endpoint = "/v1/users/#{user_id}/preferences/#{preference_set}/workflows/#{workflow}"
|
252
256
|
|
253
257
|
request = put_request(
|
@@ -269,7 +273,7 @@ module Knock
|
|
269
273
|
#
|
270
274
|
# @return [Hash] The preference set
|
271
275
|
def set_category_preferences(user_id:, category:, setting:, preference_set: DEFAULT_PREFERENCE_SET_ID)
|
272
|
-
params = setting.is_a?(Hash) ? setting : {subscribed: setting}
|
276
|
+
params = setting.is_a?(Hash) ? setting : { subscribed: setting }
|
273
277
|
endpoint = "/v1/users/#{user_id}/preferences/#{preference_set}/categories/#{category}"
|
274
278
|
|
275
279
|
request = put_request(
|
@@ -311,7 +315,7 @@ module Knock
|
|
311
315
|
request = put_request(
|
312
316
|
auth: true,
|
313
317
|
path: "/v1/users/#{id}/channel_data/#{channel_id}",
|
314
|
-
body: {data: channel_data}
|
318
|
+
body: { data: channel_data }
|
315
319
|
)
|
316
320
|
|
317
321
|
execute_request(request: request)
|
@@ -344,6 +348,8 @@ module Knock
|
|
344
348
|
#
|
345
349
|
# @return [Hash] Paginated messages response
|
346
350
|
def get_messages(id:, options: {})
|
351
|
+
options[:trigger_data] = JSON.generate(options[:trigger_data]) if options[:trigger_data]
|
352
|
+
|
347
353
|
request = get_request(
|
348
354
|
auth: true,
|
349
355
|
path: "/v1/users/#{id}/messages",
|
@@ -354,4 +360,5 @@ module Knock
|
|
354
360
|
end
|
355
361
|
end
|
356
362
|
end
|
363
|
+
# rubocop:enable Metrics/ModuleLength
|
357
364
|
end
|
data/lib/knock/version.rb
CHANGED
data/lib/knock/workflows.rb
CHANGED
data/lib/knock.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
3
|
+
require 'knock/version'
|
4
|
+
require 'json'
|
5
5
|
|
6
|
+
# Setup for Knock client
|
6
7
|
module Knock
|
7
|
-
API_HOSTNAME = ENV[
|
8
|
+
API_HOSTNAME = ENV['KNOCK_API_HOSTNAME'] || 'api.knock.app'
|
8
9
|
|
9
10
|
def self.key=(value)
|
10
11
|
Base.key = value
|
@@ -15,26 +16,27 @@ module Knock
|
|
15
16
|
end
|
16
17
|
|
17
18
|
def self.key!
|
18
|
-
key || raise(
|
19
|
+
key || raise('Knock.key not set')
|
19
20
|
end
|
20
21
|
|
21
|
-
autoload :Base,
|
22
|
-
autoload :Client,
|
22
|
+
autoload :Base, 'knock/base'
|
23
|
+
autoload :Client, 'knock/client'
|
23
24
|
|
24
25
|
# Resources
|
25
|
-
autoload :Preferences,
|
26
|
-
autoload :Users,
|
27
|
-
autoload :Workflows,
|
28
|
-
autoload :BulkOperations,
|
29
|
-
autoload :Objects,
|
30
|
-
autoload :
|
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'
|
31
33
|
|
32
34
|
# Errors
|
33
|
-
autoload :APIError,
|
34
|
-
autoload :AuthenticationError,
|
35
|
-
autoload :InvalidRequestError,
|
35
|
+
autoload :APIError, 'knock/errors'
|
36
|
+
autoload :AuthenticationError, 'knock/errors'
|
37
|
+
autoload :InvalidRequestError, 'knock/errors'
|
36
38
|
|
37
|
-
key = ENV[
|
39
|
+
key = ENV['KNOCK_API_KEY']
|
38
40
|
Knock.key = key unless key.nil?
|
39
41
|
|
40
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.
|
4
|
+
version: 0.4.5
|
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-
|
11
|
+
date: 2022-12-22 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
|
@@ -79,9 +81,11 @@ files:
|
|
79
81
|
- lib/knock/messages.rb
|
80
82
|
- lib/knock/objects.rb
|
81
83
|
- lib/knock/preferences.rb
|
84
|
+
- lib/knock/tenants.rb
|
82
85
|
- lib/knock/users.rb
|
83
86
|
- lib/knock/version.rb
|
84
87
|
- lib/knock/workflows.rb
|
88
|
+
- spec/tenants_spec.rb
|
85
89
|
homepage: https://github.com/knocklabs/knock-ruby
|
86
90
|
licenses:
|
87
91
|
- MIT
|
@@ -102,8 +106,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
102
106
|
- !ruby/object:Gem::Version
|
103
107
|
version: '0'
|
104
108
|
requirements: []
|
105
|
-
rubygems_version: 3.3.
|
109
|
+
rubygems_version: 3.3.26
|
106
110
|
signing_key:
|
107
111
|
specification_version: 4
|
108
112
|
summary: API client for Knock
|
109
|
-
test_files:
|
113
|
+
test_files:
|
114
|
+
- spec/tenants_spec.rb
|