calendly 0.5.2 → 0.6.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: 987260a701999245159a34a38b587e873a80272a3391b5909339c7b6cd01994a
4
- data.tar.gz: bb1b11aba44dcfca555b97887611cc989921a972263ea071e1ec144cac7d2bf6
3
+ metadata.gz: 5890f2e5488593ef1b1edcc4284abb1d50442fe66a782322aff7990d3a1d9424
4
+ data.tar.gz: de8d74e6d9b4b588cca90dc075b74d497ddb92f1cc4ca22db71e15f0da01d8ac
5
5
  SHA512:
6
- metadata.gz: 62d40c515e6833f34ef591b8b2a2a8089970951f6eae3fb68190388de58919a67c16851426f11c0c7c2b06bbc89f9de5248223ed2bd0d4b45fe45c11c0e232d7
7
- data.tar.gz: 58136d311993b7b3a1e352888eba6756c7235476078934f2b8e893f06a29af33e36cefd3bdb751d8540948953c1cfdd145c1e160779cad2d3c554eff3f1ccc31
6
+ metadata.gz: 91ed1a2beab52e4e92bc6b1c068323ad882cdef5bf7f74f538ef3919d1cae64139da374471e68200c644571b235a12e8c69ccb74086a1834113add6ebe93dd56
7
+ data.tar.gz: a3a596cfb67f401756b2f913598845003d3b17c861d292da9706f630ff0028c07e97b52e9b7b989b0853be16f09de9c33c4570c71c8c8bc28fd96fc26d4040d8
data/CHANGELOG.md CHANGED
@@ -1,5 +1,40 @@
1
1
  # CHANGELOG
2
2
 
3
+ ## 0.6.0
4
+
5
+ - supported to new features until April 2021. (#29)
6
+ - Client
7
+ - (Change) support organization options in `event_types` api.
8
+ - (Rename) `event_types` to `event_types_by_user`
9
+ - User model
10
+ - (Add field) current_organization
11
+ - (Add method) webhooks
12
+ - (Add method) webhooks!
13
+ - (Add method) create_webhook
14
+ - Event model
15
+ - (Remove field) invitees_counter_total
16
+ - (Remove field) invitees_counter_active
17
+ - (Remove field) invitees_counter_limit
18
+ - (Add field) invitees_counter
19
+ - (Add field) event_memberships
20
+ - (Add field) event_guests
21
+ - EventType model
22
+ - (Remove field) owner_uuid
23
+ - (Remove field) owner_uri
24
+ - (Remove field) owner_name
25
+ - (Add field) profile
26
+ - (Add field) secret
27
+ - (Add field) custom_questions
28
+ - (Add method) owner_user
29
+ - (Add method) owner_team
30
+ - Invitee model
31
+ - (Add field) first_name
32
+ - (Add field) last_name
33
+ - (Add field) cancellation
34
+ - (Add field) payment
35
+ - fixed debug log encoding error. (#30)
36
+ - improved inspect method to be more readable in CLI.
37
+
3
38
  ## 0.5.2
4
39
 
5
40
  - started to support a API
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
@@ -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,7 +103,34 @@ 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] 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.
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, opts = {})
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 opts, 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
136
  # @param [Hash] opts the optional request parameters.
@@ -116,7 +143,7 @@ module Calendly
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, opts = {})
120
147
  check_not_empty user_uri, 'user_uri'
121
148
 
122
149
  opts_keys = %i[count page_token sort]
@@ -566,7 +593,7 @@ module Calendly
566
593
  def request(method, path, params: nil, body: nil)
567
594
  debug_log "Request #{method.to_s.upcase} #{API_HOST}/#{path} params:#{params}, body:#{body}"
568
595
  res = access_token.request method, path, params: params, body: body
569
- debug_log "Response status:#{res.status}, body:#{res.body}"
596
+ debug_log "Response status:#{res.status}, body:#{res.body.dup&.force_encoding(Encoding::UTF_8)}"
570
597
  parse_as_json res
571
598
  rescue OAuth2::Error => e
572
599
  res = e.response.response
@@ -7,19 +7,24 @@ module Calendly
7
7
  class Configuration
8
8
  # @return [String]
9
9
  attr_accessor :client_id
10
+
10
11
  # @return [String]
11
12
  attr_accessor :client_secret
13
+
12
14
  # @return [String]
13
15
  attr_accessor :token
16
+
14
17
  # @return [String]
15
18
  attr_accessor :refresh_token
19
+
16
20
  # @return [Integer]
17
21
  attr_accessor :token_expires_at
22
+
18
23
  # @return [Logger]
19
24
  attr_accessor :logger
20
25
 
21
26
  def initialize
22
- @logger = Logger.new STDOUT
27
+ @logger = Logger.new $stdout
23
28
  @logger.level = :warn
24
29
  end
25
30
  end
@@ -3,37 +3,52 @@
3
3
  require 'calendly/client'
4
4
  require 'calendly/models/model_utils'
5
5
  require 'calendly/models/event_type'
6
+ require 'calendly/models/guest'
7
+ require 'calendly/models/invitees_counter'
8
+ require 'calendly/models/location'
6
9
 
7
10
  module Calendly
8
11
  # Calendly's event model.
9
- # A meeting that has been scheduled
12
+ # A meeting that has been scheduled.
10
13
  class Event
11
14
  include ModelUtils
12
15
  UUID_RE = %r{\A#{Client::API_HOST}/scheduled_events/(\w+)\z}.freeze
13
16
  TIME_FIELDS = %i[start_time end_time created_at updated_at].freeze
14
- ASSOCIATION = {event_type: EventType}.freeze
17
+ ASSOCIATION = {
18
+ event_type: EventType,
19
+ event_guests: Guest,
20
+ invitees_counter: InviteesCounter,
21
+ location: Location
22
+ }.freeze
15
23
 
16
24
  # @return [String]
17
25
  # unique id of the Event object.
18
26
  attr_accessor :uuid
27
+
19
28
  # @return [String]
20
29
  # Canonical resource reference.
21
30
  attr_accessor :uri
31
+
22
32
  # @return [String]
23
33
  # Name of the event.
24
34
  attr_accessor :name
35
+
25
36
  # @return [String]
26
37
  # Whether the event is active or canceled.
27
38
  attr_accessor :status
39
+
28
40
  # @return [Time]
29
41
  # Moment when event is (or was) scheduled to begin.
30
42
  attr_accessor :start_time
43
+
31
44
  # @return [Time]
32
45
  # Moment when event is (or was) scheduled to end.
33
46
  attr_accessor :end_time
47
+
34
48
  # @return [Time]
35
49
  # Moment when user record was first created.
36
50
  attr_accessor :created_at
51
+
37
52
  # @return [Time]
38
53
  # Moment when user record was last updated.
39
54
  attr_accessor :updated_at
@@ -46,15 +61,17 @@ module Calendly
46
61
  # location in this event.
47
62
  attr_accessor :location
48
63
 
49
- # @return [Integer]
50
- # number of total invitees in this event.
51
- attr_accessor :invitees_counter_total
52
- # @return [Integer]
53
- # number of active invitees in this event.
54
- attr_accessor :invitees_counter_active
55
- # @return [Integer]
56
- # max invitees in this event.
57
- attr_accessor :invitees_counter_limit
64
+ # @return [InviteesCounter]
65
+ # invitees counter.
66
+ attr_accessor :invitees_counter
67
+
68
+ # @return [Array<User>]
69
+ # Event membership list.
70
+ attr_accessor :event_memberships
71
+
72
+ # @return [Array<Guest>]
73
+ # Additional people added to an event by an invitee.
74
+ attr_accessor :event_guests
58
75
 
59
76
  #
60
77
  # Get Scheduled Event associated with self.
@@ -83,7 +100,7 @@ module Calendly
83
100
  # @raise [Calendly::ApiError] if the api returns error code.
84
101
  # @since 0.1.0
85
102
  def invitees(opts = {})
86
- return @cached_invitees if @cached_invitees
103
+ return @cached_invitees if defined?(@cached_invitees) && @cached_invitees
87
104
 
88
105
  request_proc = proc { |options| client.event_invitees uuid, options }
89
106
  @cached_invitees = auto_pagination request_proc, opts
@@ -99,16 +116,12 @@ module Calendly
99
116
 
100
117
  def after_set_attributes(attrs)
101
118
  super attrs
102
- loc_params = attrs[:location]
103
- @location = Location.new loc_params if loc_params&.is_a? Hash
104
-
105
- inv_cnt_attrs = attrs[:invitees_counter]
106
- return unless inv_cnt_attrs
107
- return unless inv_cnt_attrs.is_a? Hash
108
-
109
- @invitees_counter_total = inv_cnt_attrs[:total]
110
- @invitees_counter_active = inv_cnt_attrs[:active]
111
- @invitees_counter_limit = inv_cnt_attrs[:limit]
119
+ if event_memberships.is_a? Array # rubocop:disable Style/GuardClause
120
+ @event_memberships = event_memberships.map do |params|
121
+ uri = params[:user]
122
+ User.new({uri: uri}, @client)
123
+ end
124
+ end
112
125
  end
113
126
  end
114
127
  end
@@ -2,78 +2,109 @@
2
2
 
3
3
  require 'calendly/client'
4
4
  require 'calendly/models/model_utils'
5
+ require 'calendly/models/event_type_profile'
6
+ require 'calendly/models/event_type_custom_question'
5
7
 
6
8
  module Calendly
7
9
  # Calendly's event type model.
8
- # A configuration for a schedulable event
10
+ # A configuration for a schedulable event.
9
11
  class EventType
10
12
  include ModelUtils
11
13
  UUID_RE = %r{\A#{Client::API_HOST}/event_types/(\w+)\z}.freeze
12
14
  TIME_FIELDS = %i[created_at updated_at].freeze
15
+ ASSOCIATION = {profile: EventTypeProfile, custom_questions: EventTypeCustomQuestion}.freeze
13
16
 
14
17
  # @return [String]
15
18
  # unique id of the EventType object.
16
19
  attr_accessor :uuid
20
+
17
21
  # @return [String]
18
22
  # Canonical resource reference.
19
23
  attr_accessor :uri
24
+
20
25
  # @return [Boolean]
21
26
  # Is this event type currently active?
22
27
  attr_accessor :active
28
+
23
29
  # @return [String]
24
30
  # The web page styling color for this event type,
25
31
  # expressed as a hexadecimal RGB value (e.g. #fa12e4).
26
32
  attr_accessor :color
33
+
27
34
  # @return [String]
28
35
  # Longer text description with HTML formatting.
29
36
  attr_accessor :description_html
37
+
30
38
  # @return [String]
31
39
  # Longer text description in plain text.
32
40
  attr_accessor :description_plain
41
+
33
42
  # @return [Integer]
34
43
  # Length of event type in minutes.
35
44
  attr_accessor :duration
45
+
36
46
  # @return [String]
37
47
  # Optional internal note on an event type.
38
48
  attr_accessor :internal_note
49
+
39
50
  # @return [String]
40
51
  # Whether the event type is “solo” or with a “group”.
41
52
  attr_accessor :kind
53
+
42
54
  # @return [String]
43
55
  # Human-readable name. Note: some Event Types don't have a name.
44
56
  attr_accessor :name
57
+
45
58
  # @return [String]
46
59
  # Whether the event type is "round_robin" or "collective".
47
60
  # This value is null if the event type does not pool team members' availability.
48
61
  attr_accessor :pooling_type
62
+
49
63
  # @return [String]
50
64
  # The full URL of the web page for this event type.
51
65
  attr_accessor :scheduling_url
66
+
52
67
  # @return [String]
53
68
  # Unique human-readable slug used in page URL.
54
69
  attr_accessor :slug
70
+
55
71
  # @return [String]
56
72
  # Whether the event type is a “StandardEventType” or an "AdhocEventType”.
57
73
  attr_accessor :type
74
+
75
+ # @return [Boolean]
76
+ # Indicates if the event type is hidden on the owner's main scheduling page.
77
+ attr_accessor :secret
78
+
58
79
  # @return [Time]
59
80
  # Moment when event type was eventually created.
60
81
  attr_accessor :created_at
82
+
61
83
  # @return [Time]
62
84
  # Moment when event type was last updated.
63
85
  attr_accessor :updated_at
64
86
 
65
- # @return [String]
66
- # uuid of User or Team object.
67
- attr_accessor :owner_uuid
68
- # @return [String]
69
- # Reference to the profile owner.
70
- attr_accessor :owner_uri
71
- # @return [String]
72
- # Human-readable name.
73
- attr_accessor :owner_name
74
- # @return [String]
75
- # Whether the profile belongs to a “User” or a “Team”.
76
- attr_accessor :owner_type
87
+ # @return [EventTypeProfile]
88
+ # The profile of the User that's associated with the Event Type.
89
+ attr_accessor :profile
90
+
91
+ # @return [Array<EventTypeCustomQuestion>]
92
+ # A collection of custom questions.
93
+ attr_accessor :custom_questions
94
+
95
+ # The owner user if the profile belongs to a "user" (individual).
96
+ # @return [User]
97
+ # @since 0.6.0
98
+ def owner_user
99
+ profile&.owner_user
100
+ end
101
+
102
+ # The owner team if the profile belongs to a "team".
103
+ # @return [Team]
104
+ # @since 0.6.0
105
+ def owner_team
106
+ profile&.owner_team
107
+ end
77
108
 
78
109
  #
79
110
  # Get EventType associated with self.
@@ -107,14 +138,8 @@ module Calendly
107
138
 
108
139
  private
109
140
 
110
- def after_set_attributes(attrs)
111
- super attrs
112
- return unless attrs[:profile]
113
-
114
- @owner_uri = attrs[:profile][:owner]
115
- @owner_uuid = User.extract_uuid owner_uri
116
- @owner_name = attrs[:profile][:name]
117
- @owner_type = attrs[:profile][:type]
141
+ def inspect_attributes
142
+ super + %i[active kind scheduling_url]
118
143
  end
119
144
  end
120
145
  end