calendly 0.1.1 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fa6443944ba1a41d6f868879ddd4aac837f09ce9285eb210d7b61acd5c644615
4
- data.tar.gz: efccf9e1c02314b14447e2d99ee9b67cb599f7eff3f9cd37d2b1396dd96d5bbd
3
+ metadata.gz: 5fb02343424c86dc7fbc58c8b0874382d824ae2e2dca791e1346138ccb4a0608
4
+ data.tar.gz: 4ed30818c3094ed630718fced80fb7eb78569299a363e6e7bfbd788807c279cd
5
5
  SHA512:
6
- metadata.gz: be6f91ef55bc88c7a7b925d80de73028f3390b6077765ad91648a486992845db1137778ddbe048cc08e861f025a2fcb653699289f0698a6fd6706144e00638e2
7
- data.tar.gz: 490abe0dc221919393b84d23c1eab5dfc776779df1b8f1c52206fd3251e36e09a8d8e8d6324cfad622540ea91d0a433283ca2cbff6f38fbd07ff49801a4851de
6
+ metadata.gz: b76d91932bf624dd4bb997da1197670843cbf84ec3d8de7b848ffacc8345434cf08b08886558c8d93bbf146d746f9e6d1b8e65c495d73633e72d3e517b6da6ba
7
+ data.tar.gz: f35b3781d1fc979fa3d8207a120bf9ca07bf85a9b6aa69faa7713d64deb26d8b332525cf768653e65dba6c17558a26db95ed74ca7accda8eeb2d316a134ff1bb
@@ -23,12 +23,11 @@ Metrics/BlockNesting:
23
23
  Max: 2
24
24
 
25
25
  Layout/LineLength:
26
- AllowURI: true
27
- Enabled: false
26
+ Max: 120
28
27
 
29
28
  Metrics/MethodLength:
30
29
  CountComments: false
31
- Max: 15
30
+ Max: 20
32
31
 
33
32
  Metrics/ParameterLists:
34
33
  Max: 4
@@ -39,10 +38,10 @@ Metrics/AbcSize:
39
38
 
40
39
  Style/CollectionMethods:
41
40
  PreferredMethods:
42
- map: 'collect'
43
- reduce: 'inject'
44
- find: 'detect'
45
- find_all: 'select'
41
+ map: "collect"
42
+ reduce: "inject"
43
+ find: "detect"
44
+ find_all: "select"
46
45
 
47
46
  Style/Documentation:
48
47
  Enabled: false
@@ -60,10 +59,13 @@ Style/ExpandPathArguments:
60
59
  Enabled: false
61
60
 
62
61
  Style/HashSyntax:
63
- EnforcedStyle: hash_rockets
62
+ EnforcedStyle: ruby19
64
63
 
65
64
  Style/Lambda:
66
65
  Enabled: false
67
66
 
68
67
  Style/RaiseArgs:
69
- EnforcedStyle: compact
68
+ EnforcedStyle: compact
69
+
70
+ Style/AsciiComments:
71
+ Enabled: false
@@ -1,27 +1,53 @@
1
- # 0.1.1
1
+ # CHANGELOG
2
+
3
+ ## 0.4.0
4
+
5
+ - fix changed Location fields such as `kind` to `type`. (refs #18)
6
+
7
+ ## 0.3.0
8
+
9
+ - remove zeitwerk dependency. (refs #16)
10
+
11
+ ## 0.2.0
12
+
13
+ - save fetched data in cache. (refs #14)
14
+
15
+ ## 0.1.3
16
+
17
+ - support webhook APIs (refs #9)
18
+ - `GET /webhook_subscriptions`
19
+ - `GET /webhook_subscriptions/{webhook_uuid}`
20
+ - `POST /webhook_subscriptions`
21
+ - `DELETE /webhook_subscriptions/{webhook_uuid}`
22
+
23
+ ## 0.1.2
24
+
25
+ - fix rubocop warnings.
26
+
27
+ ## 0.1.1
2
28
 
3
29
  - add tests to make coverage 100%.
4
30
 
5
- # 0.1.0
31
+ ## 0.1.0
6
32
 
7
33
  - define methods to access associated resources with each model.
8
34
  - rename methods:
9
35
  - `Calendly::Client#events` to `Calendly::Client#scheduled_events`
10
36
 
11
- # 0.0.7.alpha
37
+ ## 0.0.7.alpha
12
38
 
13
39
  - support APIs
14
40
  - `POST /organizations/{uuid}/invitations`
15
41
  - `DELETE /organizations/{org_uuid}/invitations/{invitation_uuid}`
16
42
  - `DELETE /organization_memberships/{uuid}`
17
43
 
18
- # 0.0.6.alpha
44
+ ## 0.0.6.alpha
19
45
 
20
46
  - support APIs
21
47
  - `GET /organizations/{uuid}/invitations`
22
48
  - `GET /organizations/{organization_uuid}/invitations/{invitation_uuid}`
23
49
 
24
- # 0.0.5.alpha
50
+ ## 0.0.5.alpha
25
51
 
26
52
  - support APIs
27
53
  - `GET /organization_memberships`
@@ -30,24 +56,24 @@
30
56
  - Invitee#event to Invitee#event_uri
31
57
  - Event#event_type to Event#event_type_uri
32
58
 
33
- # 0.0.4.alpha
59
+ ## 0.0.4.alpha
34
60
 
35
61
  - support APIs
36
62
  - `GET /scheduled_events/{event_uuid}/invitees`
37
63
  - `GET /scheduled_events/{event_uuid}/invitees/{invitee_uuid}`
38
64
 
39
- # 0.0.3.alpha
65
+ ## 0.0.3.alpha
40
66
 
41
67
  - support APIs
42
68
  - `GET /scheduled_events`
43
69
  - `GET /scheduled_events/{uuid}`
44
70
 
45
- # 0.0.2.alpha
71
+ ## 0.0.2.alpha
46
72
 
47
73
  - support APIs
48
74
  - `GET /event_types`
49
75
 
50
- # 0.0.1.alpha
76
+ ## 0.0.1.alpha
51
77
 
52
78
  - Initial release
53
79
  - support APIs
data/README.md CHANGED
@@ -5,37 +5,7 @@
5
5
  [![Gem Version](https://badge.fury.io/rb/calendly.svg)](http://badge.fury.io/rb/calendly)
6
6
  [![license](https://img.shields.io/github/license/koshilife/calendly-api-ruby-client)](https://github.com/koshilife/calendly-api-ruby-client/blob/master/LICENSE.txt)
7
7
 
8
- ## About
9
-
10
- These client libraries are created for [Calendly v2 APIs](https://calendly.stoplight.io/docs/gh/calendly/api-docs).
11
-
12
- As of August 2020, Calendly v2 API is currently undergoing an upgrade.
13
- This library is trying to follow and support for the upgrade.
14
-
15
- As of now the supported statuses each Calendly API are as below.
16
-
17
- ## Supported statuses each Calendly API
18
-
19
- - User
20
- - [x] Get basic information about a user
21
- - EventType
22
- - [ ] Get Event Type (This endpoint hasn't been released yet.)
23
- - [x] User Event Types
24
- - Organization
25
- - [x] Get Organization Invitation
26
- - [x] Get Organization Invitations
27
- - [x] Get Organization Membership
28
- - [x] Get a list of Organization Memberships
29
- - [x] Invite a person to Organization
30
- - [x] Remove a User from an Organization
31
- - [x] Revoke Organization Invitation
32
- - ScheduledEvent
33
- - [x] Get Event
34
- - [x] Get Invitee of an Event
35
- - [x] Get List of Event Invitees
36
- - [x] Get List of User Events
37
- - Webhook V2
38
- - These endpoints havn't been released yet.
8
+ These client libraries are created for [Calendly v2 APIs](https://calendly.stoplight.io/).
39
9
 
40
10
  ## Installation
41
11
 
@@ -55,6 +25,8 @@ Or install it yourself as:
55
25
 
56
26
  ## Usage
57
27
 
28
+ ### Basic
29
+
58
30
  The APIs client needs access token.
59
31
  This client setup step is below.
60
32
 
@@ -116,7 +88,50 @@ invitation.status
116
88
 
117
89
  # cancel the invitation
118
90
  invitation.delete
91
+ ```
92
+
93
+ ### Webhook
94
+
95
+ The webhook usage is below.
96
+
97
+ ```ruby
98
+ events = ['invitee.created', 'invitee.canceled']
99
+ own_member = client.me.organization_membership
100
+ org = own_member.organization
101
+
102
+ # create user scope webhook
103
+ url = 'https://example.com/received_event'
104
+ user_webhook = own_member.create_user_scope_webhook(url, events)
105
+ # => #<Calendly::WebhookSubscription uuid:USER_WEBHOOK_001>
106
+
107
+ # list of user scope webhooks
108
+ own_member.user_scope_webhooks
109
+ # => [#<Calendly::WebhookSubscription uuid:USER_WEBHOOK_001>]
110
+
111
+ # delete the webhook
112
+ user_webhook.delete
113
+ # => true
119
114
 
115
+
116
+ # create organization scope webhook
117
+ url = 'https://example.com/received_event'
118
+ org_webhook = org.create_webhook(url, events)
119
+ # => #<Calendly::WebhookSubscription uuid:ORG_WEBHOOK_001>
120
+
121
+ # list of organization scope webhooks
122
+ org.webhooks
123
+ # => [#<Calendly::WebhookSubscription uuid:ORG_WEBHOOK_001>]
124
+
125
+ # delete the webhook
126
+ org_webhook.delete
127
+ # => true
128
+ ```
129
+
130
+ ### Logging
131
+
132
+ This library supports a configurable logger.
133
+
134
+ ```ruby
120
135
  # if the log level set :debug, you can get the request/response information.
121
136
  Calendly.configuration.logger.level = :debug
122
137
  invitation = my_org.create_invitation('foobar@example.com')
@@ -124,6 +139,8 @@ invitation = my_org.create_invitation('foobar@example.com')
124
139
  # D, [2020-08-10T10:48:16] DEBUG -- : Response status:201, body:{"resource":{"created_at":"2020-08-10T10:48:16.051159Z","email":"foobar@example.com","last_sent_at":"2020-08-10T10:48:16.096518Z","organization":"https://api.calendly.com/organizations/ORG001","status":"pending","updated_at":"2020-08-10T10:48:16.051159Z","uri":"https://api.calendly.com/organizations/ORG001/invitations/INV001"}}
125
140
  ```
126
141
 
142
+ More in-depth method documentation can be found at [RubyDoc.info](https://www.rubydoc.info/gems/calendly/).
143
+
127
144
  ## Contributing
128
145
 
129
146
  Bug reports and pull requests are welcome on [GitHub](https://github.com/koshilife/calendly-api-ruby-client). This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
data/Rakefile CHANGED
@@ -1,10 +1,12 @@
1
- require "bundler/gem_tasks"
2
- require "rake/testtask"
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rake/testtask'
3
5
 
4
6
  Rake::TestTask.new(:test) do |t|
5
- t.libs << "test"
6
- t.libs << "lib"
7
- t.test_files = FileList["test/**/*_test.rb"]
7
+ t.libs << 'test'
8
+ t.libs << 'lib'
9
+ t.test_files = FileList['test/**/*_test.rb']
8
10
  end
9
11
 
10
- task :default => :test
12
+ task default: :test
@@ -29,7 +29,6 @@ Gem::Specification.new do |spec|
29
29
  spec.require_paths = ['lib']
30
30
 
31
31
  spec.add_runtime_dependency 'oauth2', '>= 1.4.4'
32
- spec.add_runtime_dependency 'zeitwerk', '>= 2.3.0'
33
32
 
34
33
  spec.add_development_dependency 'bundler'
35
34
  spec.add_development_dependency 'codecov'
@@ -1,9 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'zeitwerk'
4
- loader = Zeitwerk::Loader.for_gem
5
- loader.collapse('**/models')
6
- loader.setup
3
+ Dir[
4
+ File.join(
5
+ File.dirname(__FILE__),
6
+ 'calendly',
7
+ '**',
8
+ '*'
9
+ )
10
+ ].sort.each do |f|
11
+ next if File.directory? f
12
+
13
+ require f
14
+ end
7
15
 
8
16
  # module for Calendly apis client
9
17
  module Calendly
@@ -1,8 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'calendly/error'
4
+
3
5
  module Calendly
4
6
  # Calendly apis client error object.
5
- class ApiError < Calendly::Error
7
+ class ApiError < Error
6
8
  # @return [Faraday::Response]
7
9
  attr_reader :response
8
10
  # @return [Integer]
@@ -25,9 +27,9 @@ module Calendly
25
27
  "\#<#{self.class}:#{object_id} title:#{title}, status:#{status}>"
26
28
  end
27
29
 
28
- private
30
+ private
29
31
 
30
- def set_attributes_from_response
32
+ def set_attributes_from_response # rubocop:disable Metrics/CyclomaticComplexity
31
33
  return unless response
32
34
  return unless response.respond_to? :body
33
35
 
@@ -4,14 +4,15 @@ require 'oauth2'
4
4
 
5
5
  module Calendly
6
6
  # Calendly apis client.
7
- class Client
7
+ class Client # rubocop:disable Metrics/ClassLength
8
+ include Loggable
8
9
  API_HOST = 'https://api.calendly.com'
9
10
  AUTH_API_HOST = 'https://auth.calendly.com'
10
11
 
11
12
  # @param [String] token a Calendly's access token.
13
+ # @raise [Calendly::Error] if the token is empty.
12
14
  def initialize(token = nil)
13
15
  @config = Calendly.configuration
14
- @logger = @config.logger
15
16
  @token = token || Calendly.configuration.token
16
17
 
17
18
  check_not_empty @token, 'token'
@@ -58,11 +59,21 @@ module Calendly
58
59
  # @raise [Calendly::ApiError] if the api returns error code.
59
60
  # @since 0.0.1
60
61
  def current_user
61
- user
62
+ return @cached_current_user if @cached_current_user
63
+
64
+ @cached_current_user = user
62
65
  end
63
66
 
64
67
  alias me current_user
65
68
 
69
+ # @since 0.2.0
70
+ def current_user!
71
+ @cached_current_user = nil
72
+ current_user
73
+ end
74
+
75
+ alias me! current_user!
76
+
66
77
  #
67
78
  # Get basic information about a user
68
79
  #
@@ -95,7 +106,7 @@ module Calendly
95
106
  check_not_empty user_uri, 'user_uri'
96
107
 
97
108
  opts_keys = %i[count page_token sort]
98
- params = { user: user_uri }
109
+ params = {user: user_uri}
99
110
  params = merge_options opts, opts_keys, params
100
111
  body = request :get, 'event_types', params: params
101
112
 
@@ -124,12 +135,12 @@ module Calendly
124
135
  # @param [String] user_uri the specified user (user's uri).
125
136
  # @param [Hash] opts the optional request parameters.
126
137
  # @option opts [Integer] :count Number of rows to return.
127
- # @option opts [String] :invitee_email Return events scheduled with the specified invitee email
138
+ # @option opts [String] :invitee_email Return events scheduled with the specified invitee email.
128
139
  # @option opts [String] :max_start_time Upper bound (inclusive) for an event's start time to filter by.
129
140
  # @option opts [String] :min_start_time Lower bound (inclusive) for an event's start time to filter by.
130
141
  # @option opts [String] :page_token Pass this to get the next portion of collection.
131
142
  # @option opts [String] :sort Order results by the specified field and directin. Accepts comma-separated list of {field}:{direction} values.
132
- # @option opts [String] :status Whether the scheduled event is active or canceled
143
+ # @option opts [String] :status Whether the scheduled event is active or canceled.
133
144
  # @return [Array<Array<Calendly::Event>, Hash>]
134
145
  # - [Array<Calendly::Event>] events
135
146
  # - [Hash] next_params the parameters to get next data. if thre is no next it returns nil.
@@ -140,7 +151,7 @@ module Calendly
140
151
  check_not_empty user_uri, 'user_uri'
141
152
 
142
153
  opts_keys = %i[count invitee_email max_start_time min_start_time page_token sort status]
143
- params = { user: user_uri }
154
+ params = {user: user_uri}
144
155
  params = merge_options opts, opts_keys, params
145
156
  body = request :get, 'scheduled_events', params: params
146
157
 
@@ -227,7 +238,7 @@ module Calendly
227
238
  check_not_empty org_uri, 'org_uri'
228
239
 
229
240
  opts_keys = %i[count email page_token]
230
- params = { organization: org_uri }
241
+ params = {organization: org_uri}
231
242
  params = merge_options opts, opts_keys, params
232
243
  body = request :get, 'organization_memberships', params: params
233
244
 
@@ -254,7 +265,7 @@ module Calendly
254
265
  check_not_empty user_uri, 'user_uri'
255
266
 
256
267
  opts_keys = %i[count email page_token]
257
- params = { user: user_uri }
268
+ params = {user: user_uri}
258
269
  params = merge_options opts, opts_keys, params
259
270
  body = request :get, 'organization_memberships', params: params
260
271
 
@@ -339,7 +350,7 @@ module Calendly
339
350
  body = request(
340
351
  :post,
341
352
  "organizations/#{uuid}/invitations",
342
- body: { email: email }
353
+ body: {email: email}
343
354
  )
344
355
  OrganizationInvitation.new body[:resource], self
345
356
  end
@@ -361,14 +372,120 @@ module Calendly
361
372
  true
362
373
  end
363
374
 
364
- private
375
+ #
376
+ # Get a webhook subscription for an organization or user with a specified UUID.
377
+ #
378
+ # @param [String] uuid the specified webhook (webhook's uuid).
379
+ # @return [Calendly::WebhookSubscription]
380
+ # @raise [Calendly::Error] if the uuid arg is empty.
381
+ # @raise [Calendly::ApiError] if the api returns error code.
382
+ # @since 0.1.3
383
+ def webhook(uuid)
384
+ check_not_empty uuid, 'uuid'
385
+ body = request :get, "webhook_subscriptions/#{uuid}"
386
+ WebhookSubscription.new body[:resource], self
387
+ end
365
388
 
366
- def debug_log(msg)
367
- return unless @logger
389
+ #
390
+ # Get List of organization scope Webhooks.
391
+ #
392
+ # @param [String] org_uri the specified organization (organization's uri).
393
+ # @param [Hash] opts the optional request parameters.
394
+ # @option opts [Integer] :count Number of rows to return.
395
+ # @option opts [String] :page_token Pass this to get the next portion of collection.
396
+ # @option opts [String] :sort Order results by the specified field and directin. Accepts comma-separated list of {field}:{direction} values.
397
+ # @return [Array<Array<Calendly::WebhookSubscription>, Hash>]
398
+ # - [Array<Calendly::WebhookSubscription>] webhooks
399
+ # - [Hash] next_params the parameters to get next data. if thre is no next it returns nil.
400
+ # @raise [Calendly::Error] if the org_uri arg is empty.
401
+ # @raise [Calendly::ApiError] if the api returns error code.
402
+ # @since 0.1.3
403
+ def webhooks(org_uri, opts = {})
404
+ check_not_empty org_uri, 'org_uri'
368
405
 
369
- @logger.debug msg
406
+ opts_keys = %i[count page_token sort]
407
+ params = {organization: org_uri, scope: 'organization'}
408
+ params = merge_options opts, opts_keys, params
409
+ body = request :get, 'webhook_subscriptions', params: params
410
+ items = body[:collection] || []
411
+ evs = items.map { |item| WebhookSubscription.new item, self }
412
+ [evs, next_page_params(body)]
370
413
  end
371
414
 
415
+ #
416
+ # Get List of user scope Webhooks.
417
+ #
418
+ # @param [String] org_uri the specified organization (organization's uri).
419
+ # @param [String] user_uri the specified user (user's uri).
420
+ # @param [Hash] opts the optional request parameters.
421
+ # @option opts [Integer] :count Number of rows to return.
422
+ # @option opts [String] :page_token Pass this to get the next portion of collection.
423
+ # @option opts [String] :sort Order results by the specified field and directin. Accepts comma-separated list of {field}:{direction} values.
424
+ # @return [Array<Array<Calendly::WebhookSubscription>, Hash>]
425
+ # - [Array<Calendly::WebhookSubscription>] webhooks
426
+ # - [Hash] next_params the parameters to get next data. if thre is no next it returns nil.
427
+ # @raise [Calendly::Error] if the org_uri arg is empty.
428
+ # @raise [Calendly::Error] if the user_uri arg is empty.
429
+ # @raise [Calendly::ApiError] if the api returns error code.
430
+ # @since 0.1.3
431
+ def user_scope_webhooks(org_uri, user_uri, opts = {})
432
+ check_not_empty org_uri, 'org_uri'
433
+ check_not_empty user_uri, 'user_uri'
434
+
435
+ opts_keys = %i[count page_token sort]
436
+ params = {organization: org_uri, user: user_uri, scope: 'user'}
437
+ params = merge_options opts, opts_keys, params
438
+ body = request :get, 'webhook_subscriptions', params: params
439
+ items = body[:collection] || []
440
+ evs = items.map { |item| WebhookSubscription.new item, self }
441
+ [evs, next_page_params(body)]
442
+ end
443
+
444
+ #
445
+ # Create a webhook subscription for an organization or user.
446
+ #
447
+ # @param [String] url Canonical reference (unique identifier) for the resource.
448
+ # @param [Array<String>] events List of user events to subscribe to. options: invitee.created or invitee.canceled
449
+ # @param [String] org_uri The unique reference to the organization that the webhook will be tied to.
450
+ # @param [String] user_uri The unique reference to the user that the webhook will be tied to.
451
+ # @return [Calendly::WebhookSubscription]
452
+ # @raise [Calendly::Error] if the url arg is empty.
453
+ # @raise [Calendly::Error] if the events arg is empty.
454
+ # @raise [Calendly::Error] if the org_uri arg is empty.
455
+ # @raise [Calendly::ApiError] if the api returns error code.
456
+ # @since 0.1.3
457
+ def create_webhook(url, events, org_uri, user_uri = nil)
458
+ check_not_empty url, 'url'
459
+ check_not_empty events, 'events'
460
+ check_not_empty org_uri, 'org_uri'
461
+
462
+ params = {url: url, events: events, organization: org_uri}
463
+ if user_uri
464
+ params[:scope] = 'user'
465
+ params[:user] = user_uri
466
+ else
467
+ params[:scope] = 'organization'
468
+ end
469
+ body = request(:post, 'webhook_subscriptions', body: params)
470
+ WebhookSubscription.new body[:resource], self
471
+ end
472
+
473
+ #
474
+ # Delete a webhook subscription for an organization or user with a specified UUID.
475
+ #
476
+ # @param [String] uuid the specified webhook (webhook's uuid).
477
+ # @return [true]
478
+ # @raise [Calendly::Error] if the uuid arg is empty.
479
+ # @raise [Calendly::ApiError] if the api returns error code.
480
+ # @since 0.1.3
481
+ def delete_webhook(uuid)
482
+ check_not_empty uuid, 'uuid'
483
+ request :delete, "webhook_subscriptions/#{uuid}"
484
+ true
485
+ end
486
+
487
+ private
488
+
372
489
  def request(method, path, params: nil, body: nil)
373
490
  debug_log "Request #{method.to_s.upcase} #{API_HOST}/#{path} params:#{params}, body:#{body}"
374
491
  res = access_token.request(method, path, params: params, body: body)
@@ -388,12 +505,13 @@ module Calendly
388
505
  end
389
506
 
390
507
  def check_not_empty(value, name)
391
- raise Calendly::Error, "#{name} is required." if blank? value
508
+ raise Error.new("#{name} is required.") if blank? value
392
509
  end
393
510
 
394
511
  def blank?(value)
395
512
  return true if value.nil?
396
513
  return true if value.to_s.empty?
514
+ return true if value.is_a?(Array) && value.empty?
397
515
 
398
516
  false
399
517
  end