calendly 0.1.1 → 0.4.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: 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