cirro-ruby-client 1.6.2 → 2.0.0

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: f0d061a9b240178ba1982a8afab295b214d060ab159fbdcedca4029a1a0b702a
4
- data.tar.gz: 8a97b77f43397c611c186394a2882592fff533579507a3a80d6c21277585b59d
3
+ metadata.gz: c6f840761d7276eb20c0fe1b6fd52eb8d4bb7752905b390e13fb41878749ad9d
4
+ data.tar.gz: 39a164fcca5006eb8216bda852c9d39fcf470af6d2ac1f8e6e1c3c076dfdf9ea
5
5
  SHA512:
6
- metadata.gz: 2ff6817b1b04bcd964c1b442d883d0f7d6d602f811c949303b7c9dd5a01ca894ea754daf6fbc4d2a2942255f1b9ef7879eebf10261221dbde4e59087f235b2eb
7
- data.tar.gz: c568caf210771fb06aca9ae1e67c883dfb9cfb35549104a3bb942c15e9105b5435e74a2976578a19cdbb3f587fd32aea5569ef6840127b181754573de1941a6c
6
+ metadata.gz: 388fc09b1a3a4172c1db748a388821a4ff8187df8e716d0daaa747dd37683b4c3dbf7dd3d8b6203c482f3790ed22f7f736ebee289ac9edbbffb2b07f55808560
7
+ data.tar.gz: dc18388fda39c84bc201d0ee77ea0dd772e266c48f27975e8fe53597bb2f1e74916ad17cb257e4bbe4defa72377207d93b053f04f6c7ab7f8963eb6f08fdac99
data/.gitignore CHANGED
@@ -6,6 +6,11 @@
6
6
  /pkg/
7
7
  /spec/reports/
8
8
  /tmp/
9
+ .idea/
9
10
 
10
11
  # rspec failure tracking
11
12
  .rspec_status
13
+
14
+ # vim artifacts
15
+ **.swp
16
+ **.swo
data/.rubocop.yml CHANGED
@@ -10,18 +10,26 @@ AllCops:
10
10
  - 'vendor/**/*'
11
11
  - 'spec/fixtures/**/*'
12
12
 
13
- Metrics/MethodLength:
14
- Max: 25
13
+ Metrics/AbcSize:
14
+ Enabled: false
15
+
16
+ Metrics/ClassLength:
17
+ Enabled: false
18
+
19
+ Metrics/CyclomaticComplexity:
20
+ Enabled: false
15
21
 
16
22
  Layout/LineLength:
17
23
  Max: 160
18
24
 
19
- # Details:
20
- # http://c2.com/cgi/wiki?AbcMetric
21
- Metrics/AbcSize:
22
- # The ABC size is a calculated magnitude, so this number can be a Fixnum or
23
- # a Float.
24
- Max: 20
25
+ Metrics/ModuleLength:
26
+ Enabled: false
27
+
28
+ Metrics/MethodLength:
29
+ Enabled: false
30
+
31
+ Metrics/PerceivedComplexity:
32
+ Enabled: false
25
33
 
26
34
  Style/StringLiterals:
27
35
  EnforcedStyle: single_quotes
@@ -35,9 +43,6 @@ Style/NumericLiterals:
35
43
  Style/SignalException:
36
44
  EnforcedStyle: only_raise
37
45
 
38
- Metrics/ClassLength:
39
- Max: 120
40
-
41
46
  # TODO: enable this when Ruby 3.0 is out.
42
47
  Style/FrozenStringLiteralComment:
43
48
  Enabled: false
@@ -107,6 +112,9 @@ Style/HashTransformValues:
107
112
  RSpec/FilePath:
108
113
  Enabled: true
109
114
  IgnoreMethods: true
115
+ Exclude:
116
+ - "spec/cirro_io_v2/**/*_spec.rb"
117
+
110
118
 
111
119
  Style/Documentation:
112
120
  Enabled: false
@@ -114,5 +122,14 @@ Style/Documentation:
114
122
  RSpec/ExampleLength:
115
123
  Enabled: false
116
124
 
125
+ RSpec/EmptyExampleGroup:
126
+ Enabled: false
127
+
117
128
  RSpec/MultipleExpectations:
118
129
  Enabled: false
130
+
131
+ Style/SymbolArray:
132
+ EnforcedStyle: brackets
133
+
134
+ Style/WordArray:
135
+ EnforcedStyle: brackets
data/Gemfile.lock CHANGED
@@ -1,7 +1,8 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- cirro-ruby-client (1.6.2)
4
+ cirro-ruby-client (2.0.0)
5
+ activesupport
5
6
  faraday (< 1.2.0)
6
7
  faraday_middleware
7
8
  json_api_client (>= 1.10.0)
@@ -10,13 +11,14 @@ PATH
10
11
  GEM
11
12
  remote: https://rubygems.org/
12
13
  specs:
13
- activemodel (7.0.2.3)
14
- activesupport (= 7.0.2.3)
15
- activesupport (7.0.2.3)
14
+ activemodel (6.1.5)
15
+ activesupport (= 6.1.5)
16
+ activesupport (6.1.5)
16
17
  concurrent-ruby (~> 1.0, >= 1.0.2)
17
18
  i18n (>= 1.6, < 2)
18
19
  minitest (>= 5.1)
19
20
  tzinfo (~> 2.0)
21
+ zeitwerk (~> 2.3)
20
22
  addressable (2.8.0)
21
23
  public_suffix (>= 2.0.2, < 5.0)
22
24
  ast (2.4.1)
@@ -41,7 +43,7 @@ GEM
41
43
  faraday (>= 0.15.2, < 2.0)
42
44
  faraday_middleware (>= 0.9.0, < 2.0)
43
45
  rack (>= 0.2)
44
- jwt (2.3.0)
46
+ jwt (2.2.3)
45
47
  method_source (1.0.0)
46
48
  minitest (5.15.0)
47
49
  multipart-post (2.1.1)
@@ -92,6 +94,7 @@ GEM
92
94
  addressable (>= 2.3.6)
93
95
  crack (>= 0.3.2)
94
96
  hashdiff (>= 0.4.0, < 2.0.0)
97
+ zeitwerk (2.5.4)
95
98
 
96
99
  PLATFORMS
97
100
  ruby
@@ -107,4 +110,4 @@ DEPENDENCIES
107
110
  webmock
108
111
 
109
112
  BUNDLED WITH
110
- 2.1.4
113
+ 2.2.25
data/README.md CHANGED
@@ -70,3 +70,341 @@ CirroIO::Client::Payout.create(
70
70
  billing_date: DateTime.now
71
71
  )
72
72
  ```
73
+
74
+ # CirroIOV2::Client
75
+
76
+ ## Configuration
77
+
78
+ ```ruby
79
+ # with key path
80
+ client = CirroIOV2::Client.new(private_key_path: "./storage/cirro_key.pem", client_id: "WULnc6Y0rlaTBCSiHAb0kGWKFuIxPWBXJysyZeG3Rtw", site: "https://api.staging.cirro.io")
81
+
82
+ # with key string
83
+ client = CirroIOV2::Client.new(private_key: Rails.application.credentials.cirro_private_key, client_id: "WULnc6Y0rlaTBCSiHAb0kGWKFuIxPWBXJysyZeG3Rtw", site: "https://api.staging.cirro.io")
84
+ ```
85
+
86
+ # Usage
87
+
88
+ ## User
89
+ ### Get user info
90
+
91
+ ```ruby
92
+ user = client.User.find(1)
93
+ # => User object
94
+
95
+ user.first_name
96
+ # => 'Grazyna'
97
+
98
+ user.worker
99
+ # => { billable: false, document: {...} }
100
+ ```
101
+
102
+ ### Get notification preferences for a user
103
+
104
+ ```ruby
105
+ preference = client.User.get_notification_preference(1)
106
+ # => NotificationPreference object
107
+
108
+ preference.id
109
+ # => '1'
110
+
111
+ preference.locale
112
+ # => 'de'
113
+
114
+ preference.channels
115
+ # => Array of NotificationChannelPreference objects
116
+ ```
117
+
118
+ ### Update notification preferences for a user
119
+
120
+ ```ruby
121
+ client.User.update_notification_preference({
122
+ locale: 'de',
123
+ channels: [
124
+ { id: '1', preferences: { email: 'immediately' } },
125
+ { id: '2', preferences: { email: 'digest_daily' } }
126
+ ]
127
+ })
128
+ ```
129
+
130
+ ## Gig
131
+ ### Create a gig
132
+
133
+ ```ruby
134
+ client.Gig.create(
135
+ title: "Favourite programming language?",
136
+ description: "Description of gig ...",
137
+ url: "http://heathcote.co/zina.gibson",
138
+ start_at: 1652285764,
139
+ end_at: 1653412329,
140
+ total_seats: 2,
141
+ invitation_mode: "auto",
142
+ filter_query: {
143
+ status: "active",
144
+ segment: "my_favorite_testers"
145
+ },
146
+ tasks: [
147
+ { title: "Ah, Wilderness!", base_price: 300 }
148
+ ],
149
+ notification_payload: {
150
+ project_title: "Corporate Tax",
151
+ task_title: "Add dataset",
152
+ task_type: "Review"
153
+ },
154
+ epam_options: {
155
+ extra_mile: true
156
+ }
157
+ )
158
+ # => Gig object
159
+ ```
160
+
161
+ ## GigInvitation
162
+ ### Get list of gig invitations
163
+
164
+ By default the response is paginated with 10 per page. The `has_more` attribute indicates whether there're more records to be fetched or not.
165
+ You can move from page to page using `after` or `before`.
166
+
167
+ ```ruby
168
+ # return all with max limit
169
+ client.GigInvitation.list(limit: 100)
170
+
171
+ # return paginated after gig invitation ID 100
172
+ client.GigInvitation.list(limit: 100, after: 100)
173
+
174
+ # return paginated before gig invitation ID 100
175
+ client.GigInvitation.list(limit: 100, before: 100)
176
+
177
+ # filter by user with ID 1 and gig with ID 1
178
+ client.GigInvitation.list(user_id: 1, gig_id: 1)
179
+
180
+ # filter by status
181
+ client.GigInvitation.list(status: ['pending', 'accepted'])
182
+ client.GigInvitation.list(status: 'accepted')
183
+
184
+ list = client.GigInvitation.list(limit: 100)
185
+ # => ListObject
186
+
187
+ list.has_more?
188
+ # => true
189
+
190
+ list.data
191
+ # => Array of GigInvitation objects
192
+ ```
193
+
194
+ ### Accept a gig invitation
195
+
196
+ ```ruby
197
+ client.GigInvitation.accept(1)
198
+ ```
199
+
200
+ ## Notification Locale
201
+ ### Create a notification locale
202
+
203
+ ```ruby
204
+ locale = client.NotificationLocale.create(locale: 'de')
205
+ # => NotificationLocale object
206
+
207
+ locale.locale
208
+ # => 'de'
209
+
210
+ locale.configurations
211
+ # => Array of NotificationConfiguration objects
212
+ ```
213
+
214
+ ### List all notification locales
215
+
216
+ ```ruby
217
+ list = client.NotificationLocale.list
218
+ # => ListObject
219
+
220
+ list.has_more?
221
+ # => true
222
+
223
+ list.data
224
+ # => Array of NotificationLocale objects
225
+
226
+ client.NotificationLocale.list(default: true) # filter by default
227
+ ```
228
+
229
+ ## Notification Configuration
230
+ ### List all notification configurations
231
+
232
+ ```ruby
233
+ list = client.NotificationConfiguration.list
234
+ # => ListObject
235
+
236
+ list.has_more?
237
+ # => true
238
+
239
+ list.data
240
+ # => Array of NotificationConfiguration objects
241
+
242
+ client.NotificationConfiguration.list(locale: 'de') # filter by locale
243
+
244
+ client.NotificationConfiguration.list(limit: 100, after: 100) # pagination
245
+ ```
246
+
247
+ ## Notification Layout
248
+ ### Create a notification layout
249
+
250
+ ```ruby
251
+ client.NotificationLayout.create(
252
+ name: 'custom_layout',
253
+ templates: [
254
+ { notification_configuration_id: '1', body: '<p>hello {{recipient}}</p>' },
255
+ { notification_configuration_id: '2', body: '<p>hallo {{recipient}}</p>' }
256
+ ]
257
+ )
258
+ ```
259
+
260
+ ### Update a notification layout
261
+
262
+ ```ruby
263
+ client.NotificationLayout.update('1', name: 'custom_layout')
264
+ ```
265
+
266
+ ### Create a new template
267
+
268
+ ```ruby
269
+ client.NotificationLayout.create_template(
270
+ '1',
271
+ { notification_configuration_id: '1', body: '<p>hello {{recipient}}</p>' }
272
+ )
273
+ # => NotificationLayoutTemplate object
274
+ ```
275
+
276
+ ## Notification Layout Template
277
+ ### Update a notification layout template
278
+
279
+ ```ruby
280
+ client.NotificationLayoutTemplate.update(
281
+ '1',
282
+ { notification_configuration_id: '1', body: '<p>hello {{recipient}}</p>' }
283
+ )
284
+ ```
285
+ ### Delete a notification layout template
286
+
287
+ ```ruby
288
+ client.NotificationLayoutTemplate.delete('1')
289
+ ```
290
+
291
+ ## Notification Channel
292
+ ### List all notification channels
293
+
294
+ ```ruby
295
+ list = client.NotificationChannel
296
+ # => ListObject
297
+
298
+ list.has_more?
299
+ # => true
300
+
301
+ list.data
302
+ # => Array of NotificationChannel objects
303
+
304
+ # filter by layout_id
305
+ client.NotificationChannel.list(notification_layout_id: 1)
306
+
307
+ # pagination
308
+ client.NotificationChannel.list(limit: 10, after: 10)
309
+ ```
310
+
311
+ ### Create a notification channel
312
+
313
+ ```ruby
314
+ client.NotificationChannel.create(
315
+ name: 'new_bug_comment',
316
+ notification_layout_id: 1,
317
+ preferences: {
318
+ email: 'immediately'
319
+ },
320
+ templates: [
321
+ {
322
+ "notification_configuration_id": "1",
323
+ "subject": "New Bug Comment",
324
+ "body": "Hello {{recipient_first_name}}, you got {{pluralize count, 'new comment', 'new comments'}}"
325
+ },
326
+ {
327
+ "notification_configuration_id": "2",
328
+ "subject": "Neuer Kommentar",
329
+ "body": "Hallo {{recipient_first_name}}, Du hast {{pluralize count, 'neuen Kommentar', 'neue Kommentare'}}"
330
+ }
331
+ ]
332
+ )
333
+ ```
334
+
335
+ ## Notification (Channel) Template
336
+ ### List all
337
+
338
+ ```ruby
339
+ list = client.NotificationTemplate
340
+ # => ListObject
341
+
342
+ list.has_more?
343
+ # => true
344
+
345
+ list.data
346
+ # => Array of NotificationTemplate objects
347
+
348
+ # filter by channel id
349
+ client.NotificationTemplate.list(notification_channel_id: 1)
350
+
351
+ # filter by configuration id
352
+ client.NotificationTemplate.list(notification_configuration_id: 1)
353
+
354
+ # pagination
355
+ client.NotificationTemplate.list(limit: 10, after: 10)
356
+ ```
357
+
358
+ ### Update a notification template
359
+
360
+ ```ruby
361
+ client.NotificationTemplate.update(
362
+ '1',
363
+ "subject": "New Bug Comment",
364
+ "body": "Hello {{recipient_first_name}}, you got {{pluralize count, 'new comment', 'new comments'}}"
365
+ )
366
+ ```
367
+
368
+ ### Delete a notification template
369
+
370
+ ```ruby
371
+ client.NotificationTemplate.delete('1')
372
+ ```
373
+ ## Notifcation Channel Preference
374
+ ### List all
375
+
376
+ ```ruby
377
+ list = client.NotificationChannelPreference.list
378
+ # => ListObject
379
+
380
+ list.has_more?
381
+ # => true
382
+
383
+ list.data
384
+ # => Array of NotificationChannelPreference objects
385
+
386
+ # filter by channel id
387
+ client.NotificationChannelPreference.list(notification_channel_id: 1)
388
+
389
+ # filter by user id
390
+ client.NotificationChannelPreference.list(user_id: 1)
391
+
392
+ # pagination
393
+ client.NotificationChannelPreference.list(limit: 10, after: 10)
394
+ ```
395
+
396
+ ## Notifcation Broadcast
397
+ ### Create a notifcation broadcast
398
+
399
+ ```ruby
400
+ client.NotificationBroadcast.create(
401
+ payload: {
402
+ foo: 'bar',
403
+ key: 'value'
404
+ },
405
+ recipients: {
406
+ user_ids: [1, 2, 3]
407
+ },
408
+ notification_channel_id: 1
409
+ )
410
+ ```
data/bin/console CHANGED
@@ -2,6 +2,7 @@
2
2
 
3
3
  require 'bundler/setup'
4
4
  require 'cirro_io/client'
5
+ require 'cirro_io_v2/client'
5
6
 
6
7
  # You can add fixtures and/or initialization code here to make experimenting
7
8
  # with your gem easier. You can also use a different console, if you like.
@@ -25,6 +25,7 @@ Gem::Specification.new do |spec|
25
25
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
26
26
  spec.require_paths = ['lib']
27
27
 
28
+ spec.add_runtime_dependency 'activesupport'
28
29
  spec.add_runtime_dependency 'jwt'
29
30
  spec.add_runtime_dependency 'faraday', '< 1.2.0'
30
31
  spec.add_runtime_dependency 'faraday_middleware'
@@ -8,7 +8,6 @@ module CirroIO
8
8
  has_many :gig_results
9
9
  has_many :gig_time_activities
10
10
 
11
- # rubocop:disable Metrics/AbcSize
12
11
  def bulk_create_with(worker_filter, gig_tasks)
13
12
  payload = { data: { attributes: attributes, relationships: {} } }
14
13
  payload[:data][:relationships][:gig_tasks] = gig_tasks.map(&:attributes)
@@ -35,7 +34,6 @@ module CirroIO
35
34
 
36
35
  self.class.parser.parse(self.class, response).first
37
36
  end
38
- # rubocop:enable Metrics/AbcSize
39
37
  end
40
38
  end
41
39
  end
@@ -1,7 +1,7 @@
1
1
  # rubocop:disable Style/MutableConstant
2
2
  module CirroIO
3
3
  module Client
4
- VERSION = '1.6.2'
4
+ VERSION = '2.0.0'
5
5
  end
6
6
  end
7
7
  # rubocop:enable Style/MutableConstant
@@ -0,0 +1,106 @@
1
+ require 'cirro_io/client/version'
2
+ require 'cirro_io_v2/errors/http_error'
3
+ require 'cirro_io_v2/errors/response_not_json_error'
4
+
5
+ require 'cirro_io_v2/request_clients/base'
6
+ require 'cirro_io_v2/request_clients/jwt'
7
+
8
+ require 'cirro_io_v2/resources/base'
9
+ require 'cirro_io_v2/resources/gig'
10
+ require 'cirro_io_v2/resources/gig_ivitation'
11
+ require 'cirro_io_v2/resources/user'
12
+
13
+ require 'cirro_io_v2/responses/base'
14
+ require 'cirro_io_v2/responses/responses'
15
+
16
+ require 'cirro_io_v2/resources/notification_broadcast'
17
+ require 'cirro_io_v2/resources/notification_topic_preference'
18
+ require 'cirro_io_v2/resources/notification_topic'
19
+ require 'cirro_io_v2/resources/notification_configuration'
20
+ require 'cirro_io_v2/resources/notification_layout_template'
21
+ require 'cirro_io_v2/resources/notification_layout'
22
+ require 'cirro_io_v2/resources/notification_locale'
23
+ require 'cirro_io_v2/resources/notification_template'
24
+
25
+ module CirroIOV2
26
+ class Client
27
+ attr_accessor :request_client
28
+ attr_reader :options
29
+
30
+ DEFAULT_OPTIONS = {
31
+ site: 'https://api.cirro.io',
32
+ api_version: 'v2',
33
+ auth_type: :jwt,
34
+ }.freeze
35
+
36
+ DEFINED_OPTIONS = (DEFAULT_OPTIONS.keys + [:private_key, :private_key_path, :client_id]).freeze
37
+
38
+ def initialize(options = {})
39
+ @options = DEFAULT_OPTIONS.merge(options)
40
+
41
+ unknown_options = @options.keys.reject { |o| DEFINED_OPTIONS.include?(o) }
42
+ raise ArgumentError, "Unknown option(s) given: #{unknown_options}" unless unknown_options.empty?
43
+
44
+ # TODO: for now we only have jwt
45
+ case @options[:auth_type]
46
+ when :jwt
47
+ private_key = OpenSSL::PKey::RSA.new(@options[:private_key]) if @options[:private_key]
48
+ private_key = OpenSSL::PKey::RSA.new(File.read(@options[:private_key_path])) if @options[:private_key_path]
49
+ @request_client = RequestClients::Jwt.new(base_url: "#{@options[:site]}/#{@options[:api_version]}",
50
+ client_id: @options[:client_id],
51
+ private_key: private_key)
52
+ else
53
+ raise ArgumentError, 'Options: ":auth_type" must be ":jwt"'
54
+ end
55
+ end
56
+
57
+ # resources
58
+ # rubocop:disable Naming/MethodName
59
+
60
+ def User
61
+ Resources::User.new(self)
62
+ end
63
+
64
+ def GigInvitation
65
+ Resources::GigInvitation.new(self)
66
+ end
67
+
68
+ def Gig
69
+ Resources::Gig.new(self)
70
+ end
71
+
72
+ def NotificationBroadcast
73
+ Resources::NotificationBroadcast.new(self)
74
+ end
75
+
76
+ def NotificationChannelPreference
77
+ Resources::NotificationChannelPreference.new(self)
78
+ end
79
+
80
+ def NotificationChannel
81
+ Resources::NotificationChannel.new(self)
82
+ end
83
+
84
+ def NotificationConfiguration
85
+ Resources::NotificationConfiguration.new(self)
86
+ end
87
+
88
+ def NotificationLayoutTemplate
89
+ Resources::NotificationLayoutTemplate.new(self)
90
+ end
91
+
92
+ def NotificationLayout
93
+ Resources::NotificationLayout.new(self)
94
+ end
95
+
96
+ def NotificationLocale
97
+ Resources::NotificationLocale.new(self)
98
+ end
99
+
100
+ def NotificationTemplate
101
+ Resources::NotificationTemplate.new(self)
102
+ end
103
+
104
+ # rubocop:enable Naming/MethodName
105
+ end
106
+ end
@@ -0,0 +1,17 @@
1
+ require 'forwardable'
2
+
3
+ module CirroIOV2
4
+ module Errors
5
+ class HTTPError < StandardError
6
+ extend Forwardable
7
+
8
+ def_instance_delegators :@response, :code
9
+ attr_reader :response, :message
10
+
11
+ def initialize(response)
12
+ @response = response
13
+ @message = response.try(:message).presence || response.try(:body)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ require 'forwardable'
2
+
3
+ module CirroIOV2
4
+ module Errors
5
+ class ResponseNotJsonError < StandardError
6
+ extend Forwardable
7
+
8
+ def_instance_delegators :@faraday_error, :message, :full_message, :response
9
+
10
+ attr_reader :faraday_error
11
+
12
+ def initialize(faraday_error)
13
+ @faraday_error = faraday_error
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,21 @@
1
+ module CirroIOV2
2
+ module RequestClients
3
+ class Base
4
+ # Interface of all request clients. It returns the response if the request was successful (HTTP::2xx) and
5
+ # raises a CirroIOV2::HTTPError together with the response if the request was not successful
6
+
7
+ def request(*args, **named_args)
8
+ response = make_request(*args, **named_args)
9
+ raise Errors::HTTPError, response unless response.success?
10
+
11
+ response
12
+ rescue Faraday::ParsingError => e
13
+ raise Errors::ResponseNotJsonError, e
14
+ end
15
+
16
+ def make_request(*args)
17
+ raise NotImplementedError
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,41 @@
1
+ require 'jwt'
2
+ require 'openssl'
3
+
4
+ module CirroIOV2
5
+ module RequestClients
6
+ class Jwt < Base
7
+ attr_reader :base_url, :private_key, :client_id, :connection
8
+
9
+ def initialize(base_url:, private_key:, client_id:)
10
+ @base_url = base_url
11
+ @private_key = private_key
12
+ @client_id = client_id
13
+
14
+ @connection = Faraday.new(url: base_url) do |conn|
15
+ conn.request :json
16
+ conn.response :json
17
+ conn.adapter Faraday.default_adapter # testIO App is on older version of faraday and needs this line
18
+ end
19
+ end
20
+
21
+ def make_request(http_method, url, body: nil, params: nil, _headers: {})
22
+ @connection.send(http_method, url) do |request|
23
+ request.params = params if params
24
+ request.body = body.to_json if body
25
+ request.headers['Authorization'] = bearer_token
26
+ end
27
+ end
28
+
29
+ def bearer_token
30
+ payload = {
31
+ exp: Time.now.to_i + (10 * 60),
32
+ sub: client_id,
33
+ }
34
+
35
+ token = JWT.encode(payload, private_key, 'RS256')
36
+
37
+ "Bearer #{token}"
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,21 @@
1
+ require 'active_support/core_ext/string/inflections'
2
+
3
+ module CirroIOV2
4
+ module Resources
5
+ class Base
6
+ attr_reader :client
7
+
8
+ def initialize(client)
9
+ @client = client
10
+ end
11
+
12
+ def resource_root
13
+ self.class.name.demodulize.underscore.pluralize
14
+ end
15
+
16
+ def params_allowed?(params, allowed)
17
+ raise 'ParamNotAllowed' if (params.keys - allowed).any?
18
+ end
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,10 @@
1
+ module CirroIOV2
2
+ module Resources
3
+ class Gig < Base
4
+ def create(params)
5
+ response = client.request_client.request(:post, resource_root, body: params)
6
+ Responses::GigResponse.new(response.body)
7
+ end
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,18 @@
1
+ module CirroIOV2
2
+ module Resources
3
+ class GigInvitation < Base
4
+ ALLOWED_PARAMS = [:user_id, :gig_id, :limit, :before, :after, :status].freeze
5
+
6
+ def list(params = nil)
7
+ params_allowed?(params, ALLOWED_PARAMS) if params
8
+ response = client.request_client.request(:get, resource_root, params: params)
9
+ Responses::GigInvitationListResponse.new(response.body)
10
+ end
11
+
12
+ def accept(id)
13
+ response = client.request_client.request(:post, "#{resource_root}/#{id}/accept")
14
+ Responses::GigInvitationResponse.new(response.body)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,13 @@
1
+ module CirroIOV2
2
+ module Resources
3
+ class NotificationBroadcast < Base
4
+ ALLOWED_PARAMS = [:payload, :recipients, :notification_channel_id].freeze
5
+
6
+ def create(params)
7
+ params_allowed?(params, ALLOWED_PARAMS)
8
+ response = client.request_client.request(:post, resource_root, body: params)
9
+ Responses::NotificationBroadcastResponse.new(response.body)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ module CirroIOV2
2
+ module Resources
3
+ class NotificationConfiguration < Base
4
+ ALLOWED_PARAMS = [:locale, :limit, :before, :after].freeze
5
+
6
+ def list(params = nil)
7
+ params_allowed?(params, ALLOWED_PARAMS) if params
8
+ response = client.request_client.request(:get, resource_root, params: params)
9
+ Responses::NotificationConfigurationListResponse.new(response.body)
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,27 @@
1
+ module CirroIOV2
2
+ module Resources
3
+ class NotificationLayout < Base
4
+ CREATE_ALLOWED_PARAMS = [:name, :templates].freeze
5
+ UPDATE_ALLOWED_PARAMS = [:name].freeze
6
+ CREATE_TEMPLATE_ALLOWED_PARAMS = [:notification_configuration_id, :body].freeze
7
+
8
+ def create(params)
9
+ params_allowed?(params, CREATE_ALLOWED_PARAMS)
10
+ response = client.request_client.request(:post, resource_root, body: params)
11
+ Responses::NotificationLayoutResponse.new(response.body)
12
+ end
13
+
14
+ def update(id, params)
15
+ params_allowed?(params, UPDATE_ALLOWED_PARAMS)
16
+ response = client.request_client.request(:post, "#{resource_root}/#{id}", body: params)
17
+ Responses::NotificationLayoutResponse.new(response.body)
18
+ end
19
+
20
+ def create_template(id, params)
21
+ params_allowed?(params, CREATE_TEMPLATE_ALLOWED_PARAMS)
22
+ response = client.request_client.request(:post, "#{resource_root}/#{id}/notification_layout_templates", body: params)
23
+ Responses::NotificationLayoutTemplateResponse.new(response.body)
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,18 @@
1
+ module CirroIOV2
2
+ module Resources
3
+ class NotificationLayoutTemplate < Base
4
+ UPDATE_ALLOWED_PARAMS = [:notification_configuration_id, :body].freeze
5
+
6
+ def update(id, params)
7
+ params_allowed?(params, UPDATE_ALLOWED_PARAMS)
8
+ response = client.request_client.request(:post, "#{resource_root}/#{id}", body: params)
9
+ Responses::NotificationLayoutTemplateResponse.new(response.body)
10
+ end
11
+
12
+ def delete(id)
13
+ response = client.request_client.request(:delete, "#{resource_root}/#{id}")
14
+ Responses::NotificationLayoutTemplateDeleteResponse.new(response.body)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ module CirroIOV2
2
+ module Resources
3
+ class NotificationLocale < Base
4
+ ALLOWED_PARAMS = [:locale].freeze
5
+
6
+ def create(params)
7
+ params_allowed?(params, ALLOWED_PARAMS)
8
+ response = client.request_client.request(:post, resource_root, body: params)
9
+ Responses::NotificationLocaleResponse.new(response.body)
10
+ end
11
+
12
+ def list
13
+ response = client.request_client.request(:get, resource_root)
14
+ Responses::NotificationLocaleListResponse.new(response.body)
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,25 @@
1
+ module CirroIOV2
2
+ module Resources
3
+ class NotificationTemplate < Base
4
+ LIST_ALLOWED_PARAMS = [:notification_configuration_id, :notification_channel_id, :limit, :before, :after].freeze
5
+ UPDATE_ALLOWED_PARAMS = [:subject, :body].freeze
6
+
7
+ def list(params = nil)
8
+ params_allowed?(params, LIST_ALLOWED_PARAMS) if params
9
+ response = client.request_client.request(:get, resource_root, params: params)
10
+ Responses::NotificationTemplateListResponse.new(response.body)
11
+ end
12
+
13
+ def update(id, params)
14
+ params_allowed?(params, UPDATE_ALLOWED_PARAMS)
15
+ response = client.request_client.request(:post, "#{resource_root}/#{id}", body: params)
16
+ Responses::NotificationTemplateResponse.new(response.body)
17
+ end
18
+
19
+ def delete(id)
20
+ response = client.request_client.request(:delete, "#{resource_root}/#{id}")
21
+ Responses::NotificationTemplateDeleteResponse.new(response.body)
22
+ end
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,17 @@
1
+ module CirroIOV2
2
+ module Resources
3
+ class NotificationTopic < Base
4
+ ALLOWED_PARAMS = [:name, :notification_layout_id, :preferences, :templates].freeze
5
+
6
+ def resource_root
7
+ 'notification_channels'
8
+ end
9
+
10
+ def create(params)
11
+ params_allowed?(params, ALLOWED_PARAMS)
12
+ response = client.request_client.request(:post, resource_root, body: params)
13
+ Responses::NotificationChannelResponse.new(response.body)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,17 @@
1
+ module CirroIOV2
2
+ module Resources
3
+ class NotificationTopicPreference < Base
4
+ ALLOWED_PARAMS = [:user_id, :notification_channel_id, :limit, :before, :after].freeze
5
+
6
+ def resource_root
7
+ 'notification_channel_preferences'
8
+ end
9
+
10
+ def list(params = nil)
11
+ params_allowed?(params, ALLOWED_PARAMS) if params
12
+ response = client.request_client.request(:get, resource_root, params: params)
13
+ Responses::NotificationChannelPreferenceListResponse.new(response.body)
14
+ end
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,15 @@
1
+ module CirroIOV2
2
+ module Resources
3
+ class User < Base
4
+ def find(id)
5
+ response = client.request_client.request(:get, "#{resource_root}/#{id}")
6
+ CirroIOV2::Responses::UserResponse.new(response.body)
7
+ end
8
+
9
+ def notification_preferences(id, params)
10
+ response = client.request_client.request(:post, "#{resource_root}/#{id}/notification_preferences", body: params)
11
+ CirroIOV2::Responses::UserNotificationPreferenceResponse.new(response.body)
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,32 @@
1
+ module CirroIOV2
2
+ module Responses
3
+ module Base
4
+ def initialize(body)
5
+ body = body.deep_symbolize_keys
6
+ if body[:object] == 'list'
7
+ list_item_class = self.class.name.gsub('List', '').constantize
8
+ values_hash = body.slice(*members.excluding(:data)).merge(
9
+ data: body[:data].map { |list_item| list_item_class.new(list_item) },
10
+ )
11
+ super(*members.map { |attr| values_hash[attr] })
12
+ elsif list_attribute(body)
13
+ values_hash = body.slice(*members.excluding(list_attribute(body))).merge(
14
+ list_attribute(body) => create_sub_resource(list_attribute(body), body[list_attribute(body)]),
15
+ )
16
+ super(*body.slice(*members).keys.map { |attr| values_hash[attr] })
17
+ else
18
+ super(*body.slice(*members).values)
19
+ end
20
+ end
21
+
22
+ def list_attribute(data)
23
+ data.keys.find { |key| data[key].is_a?(Hash) && data[key][:object] == 'list' }
24
+ end
25
+
26
+ def create_sub_resource(resource_name, body)
27
+ sub_resource_class = "CirroIOV2::Responses::#{self.class::NESTED_RESPONSES[resource_name]}".constantize
28
+ sub_resource_class.new(body)
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,101 @@
1
+ module CirroIOV2
2
+ module Responses
3
+ LIST_RESPONSES = [
4
+ :GigTaskListResponse,
5
+ :GigInvitationListResponse,
6
+ :NotificationChannelPreferenceListResponse,
7
+ :NotificationLocaleListResponse,
8
+ :NotificationConfigurationListResponse,
9
+ :NotificationLayoutTemplateListResponse,
10
+ :NotificationChannelListResponse,
11
+ :NotificationTemplateListResponse,
12
+ ].freeze
13
+
14
+ UserResponse = Struct.new(:id, :object, :first_name, :last_name, :time_zone, :screen_name, :country_code, :epam, :worker) do
15
+ include Base
16
+ end
17
+
18
+ UserNotificationPreferenceResponse = Struct.new(:id, :object, :locale, :channels) do
19
+ self::NESTED_RESPONSES = { channels: :NotificationChannelListResponse }.freeze
20
+ include Base
21
+ end
22
+
23
+ GigResponse = Struct.new(:id,
24
+ :object,
25
+ :title,
26
+ :description,
27
+ :url,
28
+ :start_at,
29
+ :end_at,
30
+ :total_seats,
31
+ :invitation_mode,
32
+ :filter_query,
33
+ :tasks,
34
+ :notification_payload,
35
+ :epam_options) do
36
+ self::NESTED_RESPONSES = { tasks: :GigTaskListResponse }.freeze
37
+ include Base
38
+ end
39
+
40
+ GigTaskResponse = Struct.new(:id, :object, :title, :base_price) do
41
+ include Base
42
+ end
43
+
44
+ GigInvitationResponse = Struct.new(:id, :object, :status, :gig_id, :user_id) do
45
+ include Base
46
+ end
47
+
48
+ NotificationChannelPreferenceResponse = Struct.new(:id, :object, :preferences, :notification_channel_id, :user_id) do
49
+ self::NESTED_RESPONSES = { preferences: :NotificationChannelPreferenceListResponse }.freeze
50
+ include Base
51
+ end
52
+
53
+ NotificationLocaleResponse = Struct.new(:id, :object, :locale, :default, :configurations) do
54
+ self::NESTED_RESPONSES = { configurations: :NotificationConfigurationListResponse }.freeze
55
+ include Base
56
+ end
57
+
58
+ NotificationConfigurationResponse = Struct.new(:id, :object, :deliver_by, :format, :kind, :locale) do
59
+ include Base
60
+ end
61
+
62
+ NotificationLayoutResponse = Struct.new(:id, :object, :name, :templates) do
63
+ self::NESTED_RESPONSES = { templates: :NotificationLayoutTemplateListResponse }.freeze
64
+ include Base
65
+ end
66
+
67
+ NotificationLayoutTemplateResponse = Struct.new(:id, :notification_configuration_id, :notification_layout_id, :body) do
68
+ include Base
69
+ end
70
+
71
+ NotificationLayoutTemplateDeleteResponse = Struct.new(:id, :object, :deleted) do
72
+ include Base
73
+ end
74
+
75
+ NotificationChannelResponse = Struct.new(:id, :object, :name, :notification_layout_id, :preferences, :templates) do
76
+ self::NESTED_RESPONSES = { templates: :NotificationTemplateListResponse }.freeze
77
+ include Base
78
+ end
79
+
80
+ NotificationTemplateResponse = Struct.new(:id, :object, :notification_configuration_id, :notification_channel_id, :subject, :body) do
81
+ include Base
82
+ end
83
+
84
+ NotificationTemplateDeleteResponse = Struct.new(:id, :object, :deleted) do
85
+ include Base
86
+ end
87
+
88
+ NotificationBroadcastResponse = Struct.new(:id, :object, :payload, :recipients, :notification_channel_id) do
89
+ include Base
90
+ end
91
+
92
+ # cover the list responses
93
+ def self.const_missing(name)
94
+ return const_get(name) if const_defined? name
95
+ return unless LIST_RESPONSES.include? name
96
+
97
+ klass = Class.new(Struct.new(:object, :url, :has_more, :data)) { include Base }
98
+ const_set(name, klass)
99
+ end
100
+ end
101
+ end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: cirro-ruby-client
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.2
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Cirro Dev Team
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2022-03-30 00:00:00.000000000 Z
11
+ date: 2022-08-17 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: activesupport
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: jwt
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -107,6 +121,25 @@ files:
107
121
  - lib/cirro_io/client/response_debugging_middleware.rb
108
122
  - lib/cirro_io/client/version.rb
109
123
  - lib/cirro_io/client/worker_filter.rb
124
+ - lib/cirro_io_v2/client.rb
125
+ - lib/cirro_io_v2/errors/http_error.rb
126
+ - lib/cirro_io_v2/errors/response_not_json_error.rb
127
+ - lib/cirro_io_v2/request_clients/base.rb
128
+ - lib/cirro_io_v2/request_clients/jwt.rb
129
+ - lib/cirro_io_v2/resources/base.rb
130
+ - lib/cirro_io_v2/resources/gig.rb
131
+ - lib/cirro_io_v2/resources/gig_ivitation.rb
132
+ - lib/cirro_io_v2/resources/notification_broadcast.rb
133
+ - lib/cirro_io_v2/resources/notification_configuration.rb
134
+ - lib/cirro_io_v2/resources/notification_layout.rb
135
+ - lib/cirro_io_v2/resources/notification_layout_template.rb
136
+ - lib/cirro_io_v2/resources/notification_locale.rb
137
+ - lib/cirro_io_v2/resources/notification_template.rb
138
+ - lib/cirro_io_v2/resources/notification_topic.rb
139
+ - lib/cirro_io_v2/resources/notification_topic_preference.rb
140
+ - lib/cirro_io_v2/resources/user.rb
141
+ - lib/cirro_io_v2/responses/base.rb
142
+ - lib/cirro_io_v2/responses/responses.rb
110
143
  homepage: https://cirro.io/api-docs/v1#cirro-api-documentation
111
144
  licenses:
112
145
  - MIT
@@ -129,7 +162,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
129
162
  - !ruby/object:Gem::Version
130
163
  version: '0'
131
164
  requirements: []
132
- rubygems_version: 3.1.3
165
+ rubygems_version: 3.0.3.1
133
166
  signing_key:
134
167
  specification_version: 4
135
168
  summary: Ruby client library for Cirro API