calendly 0.5.0 → 0.8.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: ed9a6a6603eff87ea16541bd352c82516ca1fb69b1e517d7e08b2a433c9a2764
4
- data.tar.gz: 502ddb8c46807e459f0b3ee4179e853912ea1eab1091a0526decda51f4b1ee6a
3
+ metadata.gz: 5e6b1e9a3e025d825c0fea46f89e00bff03a5ff64e075fae3794022aad9d6271
4
+ data.tar.gz: efb1c10ff8a3e73f4799193a6225c31bfa74d200969699c305cb7aa815c09890
5
5
  SHA512:
6
- metadata.gz: 9c2dd02c24e48b0db78ff0e687c6934700d30392e382d8dd8f0559aeb2a4caa00e76351b80575b086ecb95e2d6d33ae339e70e623b1831463ff71ae956d46b4e
7
- data.tar.gz: 256e9711d23191ec8dc5cfbc5893f31deb98975d85fcdaccf74d2c86cca1537922848f64443474614345a3b283e24d205c3d0408c396dffd1e7e75c89812e91a
6
+ metadata.gz: 6543fec0b13503100c112334d7fe2a32b9bfd69b263064334c52a7ac622ec6f16c0345b222b8d5e94e12912fbbbd841ea26328a5ccd36bdc27b8eb2103a1da0d
7
+ data.tar.gz: c86ce5d7a1e7ccf1f60dd3a210aea4435e19910592ca75c7e7da5c357fbd7ab8aaec9e05f3a132c3b89bd9f481c560ec090151e719d21fe72a997b9e6855ef3c
data/CHANGELOG.md CHANGED
@@ -1,5 +1,98 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 0.8.0
4
+
5
+ - used keyword arguments for optional parameters, to be friendly for programmer.
6
+ - changed methods are followings:
7
+ - Client
8
+ - event_types
9
+ - event_types_by_user
10
+ - scheduled_events
11
+ - scheduled_events_by_user
12
+ - event_invitees
13
+ - memberships
14
+ - memberships_by_user
15
+ - invitations
16
+ - webhooks
17
+ - user_scope_webhooks
18
+ - create_schedule_link
19
+ - Event
20
+ - invitees
21
+ - invitees!
22
+ - EventType
23
+ - create_schedule_link
24
+ - Organization
25
+ - memberships
26
+ - memberships!
27
+ - invitations
28
+ - invitations!
29
+ - event_types
30
+ - event_types!
31
+ - scheduled_events
32
+ - scheduled_events!
33
+ - webhooks
34
+ - webhooks!
35
+ - OrganizationMembership
36
+ - user_scope_webhooks
37
+ - user_scope_webhooks!
38
+ - User
39
+ - event_types
40
+ - scheduled_events
41
+ - webhooks
42
+ - webhooks!
43
+
44
+ ## 0.7.0
45
+
46
+ - supported a signing key parameter when creating webhooks. (#33)
47
+ - changed `user_uri` argument to keyword argument on Client#create_webhook.
48
+
49
+ ## 0.6.0
50
+
51
+ - supported new features until April 2021. (#29)
52
+ - Client
53
+ - (Change) support organization options in `event_types` api.
54
+ - (Rename) `event_types` to `event_types_by_user`
55
+ - User model
56
+ - (Add field) current_organization
57
+ - (Add method) webhooks
58
+ - (Add method) webhooks!
59
+ - (Add method) create_webhook
60
+ - Organization model
61
+ - (Add method) event_types
62
+ - (Add method) event_types!
63
+ - Event model
64
+ - (Remove field) invitees_counter_total
65
+ - (Remove field) invitees_counter_active
66
+ - (Remove field) invitees_counter_limit
67
+ - (Add field) invitees_counter
68
+ - (Add field) event_memberships
69
+ - (Add field) event_guests
70
+ - EventType model
71
+ - (Remove field) owner_uuid
72
+ - (Remove field) owner_uri
73
+ - (Remove field) owner_name
74
+ - (Add field) profile
75
+ - (Add field) secret
76
+ - (Add field) custom_questions
77
+ - (Add method) owner_user
78
+ - (Add method) owner_team
79
+ - Invitee model
80
+ - (Add field) first_name
81
+ - (Add field) last_name
82
+ - (Add field) cancellation
83
+ - (Add field) payment
84
+ - fixed debug log encoding error. (#30)
85
+ - improved inspect method to be more readable in CLI.
86
+
87
+ ## 0.5.2
88
+
89
+ - started to support a API
90
+ - `POST /scheduling_links`
91
+
92
+ ## 0.5.1
93
+
94
+ - added method EventType#fetch
95
+
3
96
  ## 0.5.0
4
97
 
5
98
  - changed Calendly::Client#scheduled_events behavior (refs #21)
data/README.md CHANGED
@@ -50,21 +50,28 @@ client = Calendly::Client.new '<ACCESS_TOKEN>'
50
50
  This client basic usage is below.
51
51
 
52
52
  ```ruby
53
+ #
53
54
  # get a current user's information.
55
+ #
54
56
  me = client.me
55
- # => <Calendly::User uuid:U001>
57
+ # => #<Calendly::User uuid="U001", name="Foo Bar", slug="foobar", email="foobar@example.com", ..>
58
+
56
59
  me.scheduling_url
57
- # => "https://calendly.com/your_name"
60
+ # => "https://calendly.com/foobar"
58
61
 
59
- # get all Event Types
62
+ #
63
+ # get all event types
64
+ #
60
65
  event_types = me.event_types
61
- # => [#<Calendly::EventType uuid:ET001>, #<Calendly::EventType uuid:ET002>, #<Calendly::EventType uuid:ET003>]
66
+ # => [#<Calendly::EventType uuid="ET001", name="15 Minute Meeting", type="StandardEventType", slug="15min", active=true, kind="solo", scheduling_url="https://calendly.com/foobar/15min", ..>, #<Calendly::EventType uuid="ET002", name="30 Minute Meeting", type="StandardEventType", slug="30min", active=true, kind="solo", scheduling_url="https://calendly.com/foobar/30min", ..>]
62
67
  event_types.first.scheduling_url
63
- # => "https://calendly.com/your_name/30min"
68
+ # => "https://calendly.com/foobar/15min"
64
69
 
70
+ #
65
71
  # get scheduled events
72
+ #
66
73
  events = me.scheduled_events
67
- # => => [#<Calendly::Event uuid:EV001>, #<Calendly::Event uuid:EV002>, #<Calendly::Event uuid:EV003>]
74
+ # => => [#<Calendly::Event uuid="EV001", name="FooBar Meeting", status="active", ..>, #<Calendly::Event uuid="EV002", name="Team Meeting", status="active", ..>]
68
75
  ev = events.first
69
76
  ev.name
70
77
  # => "FooBar Meeting"
@@ -73,21 +80,23 @@ ev.start_time
73
80
  ev.end_time
74
81
  # => 2020-07-22 02:00:00 UTC
75
82
 
76
- # get organization information
77
- own_member = me.organization_membership
78
- # => #<Calendly::OrganizationMembership uuid:MEM001>
79
- my_org = own_member.organization
80
- all_members = my_org.memberships
81
- # => [#<Calendly::OrganizationMembership uuid:MEM001>, #<Calendly::OrganizationMembership uuid:MEM002>]
83
+ #
84
+ # get a current organization's information
85
+ #
86
+ org = me.current_organization
87
+ # => #<Calendly::Organization uuid="ORG001", ..>
88
+ all_members = org.memberships
89
+ # => [#<Calendly::OrganizationMembership uuid="MEM001", role="owner", ..>, #<Calendly::OrganizationMembership uuid="MEM002", role="user", ..>]
82
90
 
91
+ #
83
92
  # create new invitation and send invitation email
84
- invitation = my_org.create_invitation('foobar@example.com')
85
- # => #<Calendly::OrganizationInvitation uuid:INV001>
86
- invitation.status
87
- # => "pending"
93
+ #
94
+ invitation = org.create_invitation('foobar@example.com')
95
+ # => #<Calendly::OrganizationInvitation uuid="INV001", status="pending", email="foobar@example.com", ..>
88
96
 
89
97
  # cancel the invitation
90
98
  invitation.delete
99
+ # => true
91
100
  ```
92
101
 
93
102
  ### Webhook
@@ -96,31 +105,33 @@ The webhook usage is below.
96
105
 
97
106
  ```ruby
98
107
  events = ['invitee.created', 'invitee.canceled']
99
- own_member = client.me.organization_membership
100
- org = own_member.organization
101
-
102
- # create user scope webhook
103
108
  url = 'https://example.com/received_event'
104
- user_webhook = own_member.create_user_scope_webhook(url, events)
105
- # => #<Calendly::WebhookSubscription uuid:USER_WEBHOOK_001>
109
+
110
+ #
111
+ # create a user scope webhook
112
+ #
113
+ me = client.me
114
+ user_webhook = me.create_webhook(url, events)
115
+ # => #<Calendly::WebhookSubscription uuid="USER_WEBHOOK_001", state="active", scope="user", events=["invitee.created", "invitee.canceled"], callback_url="https://example.com/received_event", ..>
106
116
 
107
117
  # list of user scope webhooks
108
- own_member.user_scope_webhooks
109
- # => [#<Calendly::WebhookSubscription uuid:USER_WEBHOOK_001>]
118
+ me.webhooks
119
+ # => [#<Calendly::WebhookSubscription uuid="USER_WEBHOOK_001", state="active", scope="user", events=["invitee.created", "invitee.canceled"], callback_url="https://example.com/received_event", ..>]
110
120
 
111
121
  # delete the webhook
112
122
  user_webhook.delete
113
123
  # => true
114
124
 
115
-
116
- # create organization scope webhook
117
- url = 'https://example.com/received_event'
125
+ #
126
+ # create an organization scope webhook
127
+ #
128
+ org = client.me.current_organization
118
129
  org_webhook = org.create_webhook(url, events)
119
- # => #<Calendly::WebhookSubscription uuid:ORG_WEBHOOK_001>
130
+ # => #<Calendly::WebhookSubscription uuid="ORG_WEBHOOK_001", state="active", scope="organization", events=["invitee.created", "invitee.canceled"], callback_url="https://example.com/received_event", ..>
120
131
 
121
132
  # list of organization scope webhooks
122
133
  org.webhooks
123
- # => [#<Calendly::WebhookSubscription uuid:ORG_WEBHOOK_001>]
134
+ # => [#<Calendly::WebhookSubscription uuid="ORG_WEBHOOK_001", state="active", scope="organization", events=["invitee.created", "invitee.canceled"], callback_url="https://example.com/received_event", ..>]
124
135
 
125
136
  # delete the webhook
126
137
  org_webhook.delete
@@ -134,7 +145,7 @@ This library supports a configurable logger.
134
145
  ```ruby
135
146
  # if the log level set :debug, you can get the request/response information.
136
147
  Calendly.configuration.logger.level = :debug
137
- invitation = my_org.create_invitation('foobar@example.com')
148
+ invitation = org.create_invitation('foobar@example.com')
138
149
  # D, [2020-08-10T10:48:15] DEBUG -- : Request POST https://api.calendly.com/organizations/ORG001/invitations params:, body:{:email=>"foobar@example.com"}
139
150
  # 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"}}
140
151
  ```
@@ -7,10 +7,13 @@ module Calendly
7
7
  class ApiError < Error
8
8
  # @return [Faraday::Response]
9
9
  attr_reader :response
10
+
10
11
  # @return [Integer]
11
12
  attr_reader :status
13
+
12
14
  # @return [String]
13
15
  attr_reader :title
16
+
14
17
  # @return [OAuth2::Error, JSON::ParserError]
15
18
  attr_reader :cause_exception
16
19
 
@@ -25,7 +25,7 @@ module Calendly
25
25
  # @return [OAuth2::AccessToken]
26
26
  # @since 0.0.1
27
27
  def access_token
28
- return @access_token if defined? @access_token
28
+ return @access_token if defined?(@access_token) && @access_token
29
29
 
30
30
  client = OAuth2::Client.new(@config.client_id,
31
31
  @config.client_secret, client_options)
@@ -59,7 +59,7 @@ module Calendly
59
59
  # @raise [Calendly::ApiError] if the api returns error code.
60
60
  # @since 0.0.1
61
61
  def current_user
62
- return @cached_current_user if @cached_current_user
62
+ return @cached_current_user if defined?(@cached_current_user) && @cached_current_user
63
63
 
64
64
  @cached_current_user = user
65
65
  end
@@ -103,25 +103,52 @@ module Calendly
103
103
  end
104
104
 
105
105
  #
106
- # Returns all Event Types associated with a specified User.
106
+ # Returns all Event Types associated with a specified organization.
107
+ #
108
+ # @param [String] org_uri the specified organization (organization's uri).
109
+ # @param [Hash] options the optional request parameters. Optional.
110
+ # @option options [Integer] :count Number of rows to return.
111
+ # @option options [String] :page_token Pass this to get the next portion of collection.
112
+ # @option options [String] :sort Order results by the specified field and direction. Accepts comma-separated list of {field}:{direction} values.
113
+ # @return [Array<Array<Calendly::EventType>, Hash>]
114
+ # - [Array<Calendly::EventType>] event_types
115
+ # - [Hash] next_params the parameters to get next data. if thre is no next it returns nil.
116
+ # @raise [Calendly::Error] if the org_uri arg is empty.
117
+ # @raise [Calendly::ApiError] if the api returns error code.
118
+ # @since 0.6.0
119
+ def event_types(org_uri, options: nil)
120
+ check_not_empty org_uri, 'org_uri'
121
+
122
+ opts_keys = %i[count page_token sort]
123
+ params = {organization: org_uri}
124
+ params = merge_options options, opts_keys, params
125
+ body = request :get, 'event_types', params: params
126
+
127
+ items = body[:collection] || []
128
+ ev_types = items.map { |item| EventType.new item, self }
129
+ [ev_types, next_page_params(body)]
130
+ end
131
+
132
+ #
133
+ # Returns all Event Types associated with a specified user.
107
134
  #
108
135
  # @param [String] user_uri the specified user (user's uri).
109
- # @param [Hash] opts the optional request parameters.
110
- # @option opts [Integer] :count Number of rows to return.
111
- # @option opts [String] :page_token Pass this to get the next portion of collection.
112
- # @option opts [String] :sort Order results by the specified field and direction. Accepts comma-separated list of {field}:{direction} values.
136
+ # @param [Hash] options the optional request parameters. Optional.
137
+ # @option options [Integer] :count Number of rows to return.
138
+ # @option options [String] :page_token Pass this to get the next portion of collection.
139
+ # @option options [String] :sort Order results by the specified field and direction. Accepts comma-separated list of {field}:{direction} values.
113
140
  # @return [Array<Array<Calendly::EventType>, Hash>]
114
141
  # - [Array<Calendly::EventType>] event_types
115
142
  # - [Hash] next_params the parameters to get next data. if thre is no next it returns nil.
116
143
  # @raise [Calendly::Error] if the user_uri arg is empty.
117
144
  # @raise [Calendly::ApiError] if the api returns error code.
118
145
  # @since 0.0.2
119
- def event_types(user_uri, opts = {})
146
+ def event_types_by_user(user_uri, options: nil)
120
147
  check_not_empty user_uri, 'user_uri'
121
148
 
122
149
  opts_keys = %i[count page_token sort]
123
150
  params = {user: user_uri}
124
- params = merge_options opts, opts_keys, params
151
+ params = merge_options options, opts_keys, params
125
152
  body = request :get, 'event_types', params: params
126
153
 
127
154
  items = body[:collection] || []
@@ -147,26 +174,26 @@ module Calendly
147
174
  # Get List of scheduled events belonging to a specific organization.
148
175
  #
149
176
  # @param [String] org_uri the specified organization (organization's uri).
150
- # @param [Hash] opts the optional request parameters.
151
- # @option opts [Integer] :count Number of rows to return.
152
- # @option opts [String] :invitee_email Return events scheduled with the specified invitee email.
153
- # @option opts [String] :max_start_time Upper bound (inclusive) for an event's start time to filter by.
154
- # @option opts [String] :min_start_time Lower bound (inclusive) for an event's start time to filter by.
155
- # @option opts [String] :page_token Pass this to get the next portion of collection.
156
- # @option opts [String] :sort Order results by the specified field and directin. Accepts comma-separated list of {field}:{direction} values.
157
- # @option opts [String] :status Whether the scheduled event is active or canceled.
177
+ # @param [Hash] options the optional request parameters. Optional.
178
+ # @option options [Integer] :count Number of rows to return.
179
+ # @option options [String] :invitee_email Return events scheduled with the specified invitee email.
180
+ # @option options [String] :max_start_time Upper bound (inclusive) for an event's start time to filter by.
181
+ # @option options [String] :min_start_time Lower bound (inclusive) for an event's start time to filter by.
182
+ # @option options [String] :page_token Pass this to get the next portion of collection.
183
+ # @option options [String] :sort Order results by the specified field and directin. Accepts comma-separated list of {field}:{direction} values.
184
+ # @option options [String] :status Whether the scheduled event is active or canceled.
158
185
  # @return [Array<Array<Calendly::Event>, Hash>]
159
186
  # - [Array<Calendly::Event>] events
160
187
  # - [Hash] next_params the parameters to get next data. if thre is no next it returns nil.
161
188
  # @raise [Calendly::Error] if the org_uri arg is empty.
162
189
  # @raise [Calendly::ApiError] if the api returns error code.
163
190
  # @since 0.5.0
164
- def scheduled_events(org_uri, opts = {})
191
+ def scheduled_events(org_uri, options: nil)
165
192
  check_not_empty org_uri, 'org_uri'
166
193
 
167
194
  opts_keys = %i[count invitee_email max_start_time min_start_time page_token sort status]
168
195
  params = {organization: org_uri}
169
- params = merge_options opts, opts_keys, params
196
+ params = merge_options options, opts_keys, params
170
197
  body = request :get, 'scheduled_events', params: params
171
198
 
172
199
  items = body[:collection] || []
@@ -178,27 +205,27 @@ module Calendly
178
205
  # Get List of scheduled events belonging to a specific user.
179
206
  #
180
207
  # @param [String] user_uri the specified user (user's uri).
181
- # @param [Hash] opts the optional request parameters.
182
- # @option opts [String] :organization the specified organization (organization's uri).
183
- # @option opts [Integer] :count Number of rows to return.
184
- # @option opts [String] :invitee_email Return events scheduled with the specified invitee email.
185
- # @option opts [String] :max_start_time Upper bound (inclusive) for an event's start time to filter by.
186
- # @option opts [String] :min_start_time Lower bound (inclusive) for an event's start time to filter by.
187
- # @option opts [String] :page_token Pass this to get the next portion of collection.
188
- # @option opts [String] :sort Order results by the specified field and directin. Accepts comma-separated list of {field}:{direction} values.
189
- # @option opts [String] :status Whether the scheduled event is active or canceled.
208
+ # @param [Hash] options the optional request parameters. Optional.
209
+ # @option options [String] :organization the specified organization (organization's uri).
210
+ # @option options [Integer] :count Number of rows to return.
211
+ # @option options [String] :invitee_email Return events scheduled with the specified invitee email.
212
+ # @option options [String] :max_start_time Upper bound (inclusive) for an event's start time to filter by.
213
+ # @option options [String] :min_start_time Lower bound (inclusive) for an event's start time to filter by.
214
+ # @option options [String] :page_token Pass this to get the next portion of collection.
215
+ # @option options [String] :sort Order results by the specified field and directin. Accepts comma-separated list of {field}:{direction} values.
216
+ # @option options [String] :status Whether the scheduled event is active or canceled.
190
217
  # @return [Array<Array<Calendly::Event>, Hash>]
191
218
  # - [Array<Calendly::Event>] events
192
219
  # - [Hash] next_params the parameters to get next data. if thre is no next it returns nil.
193
220
  # @raise [Calendly::Error] if the user_uri arg is empty.
194
221
  # @raise [Calendly::ApiError] if the api returns error code.
195
222
  # @since 0.0.3
196
- def scheduled_events_by_user(user_uri, opts = {})
223
+ def scheduled_events_by_user(user_uri, options: nil)
197
224
  check_not_empty user_uri, 'user_uri'
198
225
 
199
226
  opts_keys = %i[organization count invitee_email max_start_time min_start_time page_token sort status]
200
227
  params = {user: user_uri}
201
- params = merge_options opts, opts_keys, params
228
+ params = merge_options options, opts_keys, params
202
229
  body = request :get, 'scheduled_events', params: params
203
230
 
204
231
  items = body[:collection] || []
@@ -228,23 +255,23 @@ module Calendly
228
255
  # Get List of Event Invitees.
229
256
  #
230
257
  # @param [String] uuid the specified event (event's uuid).
231
- # @param [Hash] opts the optional request parameters.
232
- # @option opts [Integer] :count Number of rows to return.
233
- # @option opts [String] :email Filter by email.
234
- # @option opts [String] :page_token Pass this to get the next portion of collection.
235
- # @option opts [String] :sort Order results by the specified field and directin. Accepts comma-separated list of {field}:{direction} values.
236
- # @option opts [String] :status Whether the scheduled event is active or canceled.
258
+ # @param [Hash] options the optional request parameters. Optional.
259
+ # @option options [Integer] :count Number of rows to return.
260
+ # @option options [String] :email Filter by email.
261
+ # @option options [String] :page_token Pass this to get the next portion of collection.
262
+ # @option options [String] :sort Order results by the specified field and directin. Accepts comma-separated list of {field}:{direction} values.
263
+ # @option options [String] :status Whether the scheduled event is active or canceled.
237
264
  # @return [Array<Array<Calendly::Invitee>, Hash>]
238
265
  # - [Array<Calendly::Invitee>] invitees
239
266
  # - [Hash] next_params the parameters to get next data. if thre is no next it returns nil.
240
267
  # @raise [Calendly::Error] if the uuid arg is empty.
241
268
  # @raise [Calendly::ApiError] if the api returns error code.
242
269
  # @since 0.0.4
243
- def event_invitees(uuid, opts = {})
270
+ def event_invitees(uuid, options: nil)
244
271
  check_not_empty uuid, 'uuid'
245
272
 
246
273
  opts_keys = %i[count email page_token sort status]
247
- params = merge_options opts, opts_keys
274
+ params = merge_options options, opts_keys
248
275
  body = request :get, "scheduled_events/#{uuid}/invitees", params: params
249
276
 
250
277
  items = body[:collection] || []
@@ -270,22 +297,22 @@ module Calendly
270
297
  # Get List of memberships belonging to specific an organization.
271
298
  #
272
299
  # @param [String] org_uri the specified organization (organization's uri).
273
- # @param [Hash] opts the optional request parameters.
274
- # @option opts [Integer] :count Number of rows to return.
275
- # @option opts [String] :email Filter by email.
276
- # @option opts [String] :page_token Pass this to get the next portion of collection.
300
+ # @param [Hash] options the optional request parameters. Optional.
301
+ # @option options [Integer] :count Number of rows to return.
302
+ # @option options [String] :email Filter by email.
303
+ # @option options [String] :page_token Pass this to get the next portion of collection.
277
304
  # @return [Array<Array<Calendly::OrganizationMembership>, Hash>]
278
305
  # - [Array<Calendly::OrganizationMembership>] memberships
279
306
  # - [Hash] next_params the parameters to get next data. if thre is no next it returns nil.
280
307
  # @raise [Calendly::Error] if the org_uri arg is empty.
281
308
  # @raise [Calendly::ApiError] if the api returns error code.
282
309
  # @since 0.0.5
283
- def memberships(org_uri, opts = {})
310
+ def memberships(org_uri, options: nil)
284
311
  check_not_empty org_uri, 'org_uri'
285
312
 
286
313
  opts_keys = %i[count email page_token]
287
314
  params = {organization: org_uri}
288
- params = merge_options opts, opts_keys, params
315
+ params = merge_options options, opts_keys, params
289
316
  body = request :get, 'organization_memberships', params: params
290
317
 
291
318
  items = body[:collection] || []
@@ -297,22 +324,22 @@ module Calendly
297
324
  # Get List of memberships belonging to specific a user.
298
325
  #
299
326
  # @param [String] user_uri the specified user (user's uri).
300
- # @param [Hash] opts the optional request parameters.
301
- # @option opts [Integer] :count Number of rows to return.
302
- # @option opts [String] :email Filter by email.
303
- # @option opts [String] :page_token Pass this to get the next portion of collection.
327
+ # @param [Hash] options the optional request parameters. Optional.
328
+ # @option options [Integer] :count Number of rows to return.
329
+ # @option options [String] :email Filter by email.
330
+ # @option options [String] :page_token Pass this to get the next portion of collection.
304
331
  # @return [Array<Array<Calendly::OrganizationMembership>, Hash>]
305
332
  # - [Array<Calendly::OrganizationMembership>] memberships
306
333
  # - [Hash] next_params the parameters to get next data. if thre is no next it returns nil.
307
334
  # @raise [Calendly::Error] if the user_uri arg is empty.
308
335
  # @raise [Calendly::ApiError] if the api returns error code.
309
336
  # @since 0.0.5
310
- def memberships_by_user(user_uri, opts = {})
337
+ def memberships_by_user(user_uri, options: nil)
311
338
  check_not_empty user_uri, 'user_uri'
312
339
 
313
340
  opts_keys = %i[count email page_token]
314
341
  params = {user: user_uri}
315
- params = merge_options opts, opts_keys, params
342
+ params = merge_options options, opts_keys, params
316
343
  body = request :get, 'organization_memberships', params: params
317
344
 
318
345
  items = body[:collection] || []
@@ -356,23 +383,23 @@ module Calendly
356
383
  # Get Organization Invitations.
357
384
  #
358
385
  # @param [String] uuid the specified organization (organization's uuid).
359
- # @param [Hash] opts the optional request parameters.
360
- # @option opts [Integer] :count Number of rows to return.
361
- # @option opts [String] :email Filter by email.
362
- # @option opts [String] :page_token Pass this to get the next portion of collection.
363
- # @option opts [String] :sort Order results by the specified field and directin. Accepts comma-separated list of {field}:{direction} values.
364
- # @option opts [String] :status Filter by status.
386
+ # @param [Hash] options the optional request parameters. Optional.
387
+ # @option options [Integer] :count Number of rows to return.
388
+ # @option options [String] :email Filter by email.
389
+ # @option options [String] :page_token Pass this to get the next portion of collection.
390
+ # @option options [String] :sort Order results by the specified field and directin. Accepts comma-separated list of {field}:{direction} values.
391
+ # @option options [String] :status Filter by status.
365
392
  # @return [<Array<Array<Calendly::OrganizationInvitation>, Hash>]
366
393
  # - [Array<Calendly::OrganizationInvitation>] organizations
367
394
  # - [Hash] next_params the parameters to get next data. if thre is no next it returns nil.
368
395
  # @raise [Calendly::Error] if the uuid arg is empty.
369
396
  # @raise [Calendly::ApiError] if the api returns error code.
370
397
  # @since 0.0.6
371
- def invitations(uuid, opts = {})
398
+ def invitations(uuid, options: nil)
372
399
  check_not_empty uuid, 'uuid'
373
400
 
374
401
  opts_keys = %i[count email page_token sort status]
375
- params = merge_options opts, opts_keys
402
+ params = merge_options options, opts_keys
376
403
 
377
404
  body = request :get, "organizations/#{uuid}/invitations", params: params
378
405
  items = body[:collection] || []
@@ -436,22 +463,22 @@ module Calendly
436
463
  # Get List of organization scope Webhooks.
437
464
  #
438
465
  # @param [String] org_uri the specified organization (organization's uri).
439
- # @param [Hash] opts the optional request parameters.
440
- # @option opts [Integer] :count Number of rows to return.
441
- # @option opts [String] :page_token Pass this to get the next portion of collection.
442
- # @option opts [String] :sort Order results by the specified field and directin. Accepts comma-separated list of {field}:{direction} values.
466
+ # @param [Hash] options the optional request parameters. Optional.
467
+ # @option options [Integer] :count Number of rows to return.
468
+ # @option options [String] :page_token Pass this to get the next portion of collection.
469
+ # @option options [String] :sort Order results by the specified field and directin. Accepts comma-separated list of {field}:{direction} values.
443
470
  # @return [Array<Array<Calendly::WebhookSubscription>, Hash>]
444
471
  # - [Array<Calendly::WebhookSubscription>] webhooks
445
472
  # - [Hash] next_params the parameters to get next data. if thre is no next it returns nil.
446
473
  # @raise [Calendly::Error] if the org_uri arg is empty.
447
474
  # @raise [Calendly::ApiError] if the api returns error code.
448
475
  # @since 0.1.3
449
- def webhooks(org_uri, opts = {})
476
+ def webhooks(org_uri, options: nil)
450
477
  check_not_empty org_uri, 'org_uri'
451
478
 
452
479
  opts_keys = %i[count page_token sort]
453
480
  params = {organization: org_uri, scope: 'organization'}
454
- params = merge_options opts, opts_keys, params
481
+ params = merge_options options, opts_keys, params
455
482
  body = request :get, 'webhook_subscriptions', params: params
456
483
  items = body[:collection] || []
457
484
  evs = items.map { |item| WebhookSubscription.new item, self }
@@ -463,10 +490,10 @@ module Calendly
463
490
  #
464
491
  # @param [String] org_uri the specified organization (organization's uri).
465
492
  # @param [String] user_uri the specified user (user's uri).
466
- # @param [Hash] opts the optional request parameters.
467
- # @option opts [Integer] :count Number of rows to return.
468
- # @option opts [String] :page_token Pass this to get the next portion of collection.
469
- # @option opts [String] :sort Order results by the specified field and directin. Accepts comma-separated list of {field}:{direction} values.
493
+ # @param [Hash] options the optional request parameters. Optional.
494
+ # @option options [Integer] :count Number of rows to return.
495
+ # @option options [String] :page_token Pass this to get the next portion of collection.
496
+ # @option options [String] :sort Order results by the specified field and directin. Accepts comma-separated list of {field}:{direction} values.
470
497
  # @return [Array<Array<Calendly::WebhookSubscription>, Hash>]
471
498
  # - [Array<Calendly::WebhookSubscription>] webhooks
472
499
  # - [Hash] next_params the parameters to get next data. if thre is no next it returns nil.
@@ -474,13 +501,13 @@ module Calendly
474
501
  # @raise [Calendly::Error] if the user_uri arg is empty.
475
502
  # @raise [Calendly::ApiError] if the api returns error code.
476
503
  # @since 0.1.3
477
- def user_scope_webhooks(org_uri, user_uri, opts = {})
504
+ def user_scope_webhooks(org_uri, user_uri, options: nil)
478
505
  check_not_empty org_uri, 'org_uri'
479
506
  check_not_empty user_uri, 'user_uri'
480
507
 
481
508
  opts_keys = %i[count page_token sort]
482
509
  params = {organization: org_uri, user: user_uri, scope: 'user'}
483
- params = merge_options opts, opts_keys, params
510
+ params = merge_options options, opts_keys, params
484
511
  body = request :get, 'webhook_subscriptions', params: params
485
512
  items = body[:collection] || []
486
513
  evs = items.map { |item| WebhookSubscription.new item, self }
@@ -493,26 +520,29 @@ module Calendly
493
520
  # @param [String] url Canonical reference (unique identifier) for the resource.
494
521
  # @param [Array<String>] events List of user events to subscribe to. options: invitee.created or invitee.canceled
495
522
  # @param [String] org_uri The unique reference to the organization that the webhook will be tied to.
496
- # @param [String] user_uri The unique reference to the user that the webhook will be tied to.
523
+ # @param [String] user_uri The unique reference to the user that the webhook will be tied to. Optional.
524
+ # @param [String] signing_key secret key shared between your application and Calendly. Optional.
497
525
  # @return [Calendly::WebhookSubscription]
498
526
  # @raise [Calendly::Error] if the url arg is empty.
499
527
  # @raise [Calendly::Error] if the events arg is empty.
500
528
  # @raise [Calendly::Error] if the org_uri arg is empty.
501
529
  # @raise [Calendly::ApiError] if the api returns error code.
502
530
  # @since 0.1.3
503
- def create_webhook(url, events, org_uri, user_uri = nil)
531
+ def create_webhook(url, events, org_uri, user_uri: nil, signing_key: nil) # rubocop:disable Metrics/ParameterLists
504
532
  check_not_empty url, 'url'
505
533
  check_not_empty events, 'events'
506
534
  check_not_empty org_uri, 'org_uri'
507
535
 
508
536
  params = {url: url, events: events, organization: org_uri}
537
+ params[:signing_key] = signing_key if signing_key
538
+
509
539
  if user_uri
510
540
  params[:scope] = 'user'
511
541
  params[:user] = user_uri
512
542
  else
513
543
  params[:scope] = 'organization'
514
544
  end
515
- body = request(:post, 'webhook_subscriptions', body: params)
545
+ body = request :post, 'webhook_subscriptions', body: params
516
546
  WebhookSubscription.new body[:resource], self
517
547
  end
518
548
 
@@ -530,12 +560,43 @@ module Calendly
530
560
  true
531
561
  end
532
562
 
563
+ #
564
+ # Create a scheduling link.
565
+ #
566
+ # @param [String] uri A link to the resource that owns this scheduling Link.
567
+ # @param [String] max_event_count The max number of events that can be scheduled using this scheduling link.
568
+ # @param [String] owner_type Resource type.
569
+ # @return [Hash]
570
+ # e.g.
571
+ # {
572
+ # booking_url: "https://calendly.com/s/FOO-BAR-SLUG",
573
+ # owner: "https://api.calendly.com/event_types/GBGBDCAADAEDCRZ2",
574
+ # owner_type: "EventType"
575
+ # }
576
+ # @raise [Calendly::Error] if the uri arg is empty.
577
+ # @raise [Calendly::Error] if the max_event_count arg is empty.
578
+ # @raise [Calendly::Error] if the owner_type arg is empty.
579
+ # @raise [Calendly::ApiError] if the api returns error code.
580
+ # @since 0.5.2
581
+ def create_schedule_link(uri, max_event_count: 1, owner_type: 'EventType')
582
+ check_not_empty uri, 'uri'
583
+ check_not_empty max_event_count, 'max_event_count'
584
+ check_not_empty owner_type, 'owner_type'
585
+ params = {
586
+ max_event_count: max_event_count,
587
+ owner: uri,
588
+ owner_type: owner_type
589
+ }
590
+ body = request :post, 'scheduling_links', body: params
591
+ body[:resource]
592
+ end
593
+
533
594
  private
534
595
 
535
596
  def request(method, path, params: nil, body: nil)
536
597
  debug_log "Request #{method.to_s.upcase} #{API_HOST}/#{path} params:#{params}, body:#{body}"
537
- res = access_token.request(method, path, params: params, body: body)
538
- debug_log "Response status:#{res.status}, body:#{res.body}"
598
+ res = access_token.request method, path, params: params, body: body
599
+ debug_log "Response status:#{res.status}, body:#{res.body.dup&.force_encoding(Encoding::UTF_8)}"
539
600
  parse_as_json res
540
601
  rescue OAuth2::Error => e
541
602
  res = e.response.response