nylas_v2 5.14.2

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.
Files changed (91) hide show
  1. checksums.yaml +7 -0
  2. data/lib/nylas_v2/account.rb +56 -0
  3. data/lib/nylas_v2/api.rb +244 -0
  4. data/lib/nylas_v2/application_details.rb +13 -0
  5. data/lib/nylas_v2/calendar.rb +46 -0
  6. data/lib/nylas_v2/calendar_collection.rb +144 -0
  7. data/lib/nylas_v2/categorize.rb +14 -0
  8. data/lib/nylas_v2/collection.rb +175 -0
  9. data/lib/nylas_v2/component.rb +35 -0
  10. data/lib/nylas_v2/component_collection.rb +10 -0
  11. data/lib/nylas_v2/constraints.rb +56 -0
  12. data/lib/nylas_v2/contact.rb +53 -0
  13. data/lib/nylas_v2/contact_group.rb +23 -0
  14. data/lib/nylas_v2/current_account.rb +23 -0
  15. data/lib/nylas_v2/delta.rb +56 -0
  16. data/lib/nylas_v2/deltas.rb +19 -0
  17. data/lib/nylas_v2/deltas_collection.rb +40 -0
  18. data/lib/nylas_v2/draft.rb +100 -0
  19. data/lib/nylas_v2/email_address.rb +12 -0
  20. data/lib/nylas_v2/errors.rb +111 -0
  21. data/lib/nylas_v2/event.rb +141 -0
  22. data/lib/nylas_v2/event_collection.rb +15 -0
  23. data/lib/nylas_v2/event_conferencing.rb +12 -0
  24. data/lib/nylas_v2/event_conferencing_autocreate.rb +10 -0
  25. data/lib/nylas_v2/event_conferencing_details.rb +14 -0
  26. data/lib/nylas_v2/event_notification.rb +17 -0
  27. data/lib/nylas_v2/file.rb +75 -0
  28. data/lib/nylas_v2/filter_attributes.rb +25 -0
  29. data/lib/nylas_v2/folder.rb +26 -0
  30. data/lib/nylas_v2/free_busy.rb +13 -0
  31. data/lib/nylas_v2/free_busy_collection.rb +48 -0
  32. data/lib/nylas_v2/http_client.rb +279 -0
  33. data/lib/nylas_v2/im_address.rb +11 -0
  34. data/lib/nylas_v2/job_status.rb +27 -0
  35. data/lib/nylas_v2/job_status_collection.rb +21 -0
  36. data/lib/nylas_v2/label.rb +27 -0
  37. data/lib/nylas_v2/logging.rb +41 -0
  38. data/lib/nylas_v2/message.rb +98 -0
  39. data/lib/nylas_v2/message_headers.rb +27 -0
  40. data/lib/nylas_v2/message_tracking.rb +13 -0
  41. data/lib/nylas_v2/model/attributable.rb +89 -0
  42. data/lib/nylas_v2/model/attribute_definition.rb +24 -0
  43. data/lib/nylas_v2/model/attributes.rb +97 -0
  44. data/lib/nylas_v2/model/list_attribute_definition.rb +39 -0
  45. data/lib/nylas_v2/model/transferable.rb +53 -0
  46. data/lib/nylas_v2/model.rb +217 -0
  47. data/lib/nylas_v2/native_authentication.rb +39 -0
  48. data/lib/nylas_v2/neural.rb +87 -0
  49. data/lib/nylas_v2/neural_categorizer.rb +29 -0
  50. data/lib/nylas_v2/neural_clean_conversation.rb +33 -0
  51. data/lib/nylas_v2/neural_contact_link.rb +11 -0
  52. data/lib/nylas_v2/neural_contact_name.rb +11 -0
  53. data/lib/nylas_v2/neural_message_options.rb +35 -0
  54. data/lib/nylas_v2/neural_ocr.rb +16 -0
  55. data/lib/nylas_v2/neural_sentiment_analysis.rb +17 -0
  56. data/lib/nylas_v2/neural_signature_contact.rb +81 -0
  57. data/lib/nylas_v2/neural_signature_extraction.rb +18 -0
  58. data/lib/nylas_v2/new_message.rb +39 -0
  59. data/lib/nylas_v2/nylas_date.rb +25 -0
  60. data/lib/nylas_v2/open_hours.rb +15 -0
  61. data/lib/nylas_v2/outbox.rb +116 -0
  62. data/lib/nylas_v2/outbox_job_status.rb +19 -0
  63. data/lib/nylas_v2/outbox_message.rb +17 -0
  64. data/lib/nylas_v2/participant.rb +13 -0
  65. data/lib/nylas_v2/phone_number.rb +11 -0
  66. data/lib/nylas_v2/physical_address.rb +17 -0
  67. data/lib/nylas_v2/raw_message.rb +25 -0
  68. data/lib/nylas_v2/recurrence.rb +11 -0
  69. data/lib/nylas_v2/registry.rb +42 -0
  70. data/lib/nylas_v2/room_resource.rb +19 -0
  71. data/lib/nylas_v2/rsvp.rb +24 -0
  72. data/lib/nylas_v2/scheduler.rb +51 -0
  73. data/lib/nylas_v2/scheduler_booking_confirmation.rb +24 -0
  74. data/lib/nylas_v2/scheduler_booking_request.rb +17 -0
  75. data/lib/nylas_v2/scheduler_collection.rb +104 -0
  76. data/lib/nylas_v2/scheduler_config.rb +20 -0
  77. data/lib/nylas_v2/scheduler_time_slot.rb +14 -0
  78. data/lib/nylas_v2/search_collection.rb +10 -0
  79. data/lib/nylas_v2/send_grid_verified_status.rb +12 -0
  80. data/lib/nylas_v2/thread.rb +66 -0
  81. data/lib/nylas_v2/time_slot.rb +16 -0
  82. data/lib/nylas_v2/time_slot_capacity.rb +13 -0
  83. data/lib/nylas_v2/timespan.rb +20 -0
  84. data/lib/nylas_v2/token_info.rb +20 -0
  85. data/lib/nylas_v2/types.rb +168 -0
  86. data/lib/nylas_v2/version.rb +5 -0
  87. data/lib/nylas_v2/web_page.rb +11 -0
  88. data/lib/nylas_v2/webhook.rb +98 -0
  89. data/lib/nylas_v2/when.rb +75 -0
  90. data/lib/nylas_v2.rb +162 -0
  91. metadata +415 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 52c4f0f502315cce5b206a8f51117e827bf490b79fbab115c353eea8db6012a8
4
+ data.tar.gz: ad67ce144b9fbded6bdeff86c88baacb4c132b67cc5614f571d67c836c6f10a6
5
+ SHA512:
6
+ metadata.gz: dceebf6c7ea48e88b6cc9bc6dcf7f6f7442c9c0d29eb42fcd4b939065a84883e064f69ea8cd1e1693bcc7ca6991258da5dba82f341c0cb6a8f83855304e32230
7
+ data.tar.gz: 530315f2275117a919ccf410d0c9083ed24ed589ab31981181156deae5daf5af2d76b6a43ed8f486c91488eca21ed49c1fc6e2891c2d13a4c39af33d401484c8
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NylasV2
4
+ # Representation of the accounts for Account management purposes.
5
+ # @see https://docs.nylas.com/reference#account-management
6
+ class Account
7
+ include Model
8
+ self.listable = true
9
+ self.showable = true
10
+ self.updatable = true
11
+ self.destroyable = true
12
+ self.filterable = true
13
+ self.auth_method = HttpClient::AuthMethod::BASIC
14
+
15
+ attribute :id, :string, read_only: true
16
+ attribute :account_id, :string, read_only: true
17
+ attribute :billing_state, :string, read_only: true
18
+ attribute :sync_state, :string, read_only: true
19
+ attribute :provider, :string, read_only: true
20
+ attribute :authentication_type, :string, read_only: true
21
+
22
+ attribute :email, :string, read_only: true
23
+ attribute :trial, :boolean, read_only: true
24
+ attribute :metadata, :hash
25
+
26
+ def upgrade
27
+ response = execute(method: :post, path: "#{resource_path}/upgrade")
28
+ response[:success]
29
+ end
30
+
31
+ def downgrade
32
+ response = execute(method: :post, path: "#{resource_path}/downgrade")
33
+ response[:success]
34
+ end
35
+
36
+ def revoke_all(keep_access_token: nil)
37
+ payload = JSON.dump(keep_access_token: keep_access_token) if keep_access_token
38
+
39
+ response = execute(method: :post, path: "#{resource_path}/revoke-all", payload: payload)
40
+ response[:success]
41
+ end
42
+
43
+ # Return information about an account's access token
44
+ # @param access_token [String] The access token to inquire about
45
+ # @return [TokenInfo] The access token information
46
+ def token_info(access_token)
47
+ payload = JSON.dump(access_token: access_token)
48
+ response = execute(method: :post, path: "#{resource_path}/token-info", payload: payload)
49
+ TokenInfo.new(**response)
50
+ end
51
+
52
+ def self.resources_path(api:)
53
+ "/a/#{api.app_id}/accounts"
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,244 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NylasV2
4
+ # Methods to retrieve data from the Nylas API as Ruby objects
5
+ class API
6
+ attr_accessor :client
7
+
8
+ extend Forwardable
9
+ def_delegators :client, :execute, :get, :post, :put, :delete, :app_id, :api_server
10
+
11
+ include Logging
12
+
13
+ # @param client [HttpClient] Http Client to use for retrieving data
14
+ # @param app_id [String] Your application id from the Nylas Dashboard
15
+ # @param app_secret [String] Your application secret from the Nylas Dashboard
16
+ # @param access_token [String] (Optional) Your users access token.
17
+ # @param api_server [String] (Optional) Which Nylas API Server to connect to. Only change this if
18
+ # you're using a self-hosted Nylas instance.
19
+ # @return [NylasV2::API]
20
+ def initialize(client: nil, app_id: nil, app_secret: nil, access_token: nil,
21
+ api_server: "https://api.nylas.com")
22
+ self.client = client || HttpClient.new(app_id: app_id, app_secret: app_secret,
23
+ access_token: access_token, api_server: api_server)
24
+ end
25
+
26
+ # @return [String] A Nylas access token for that particular user.
27
+ def authenticate(name:, email_address:, provider:, settings:, reauth_account_id: nil, scopes: nil)
28
+ NativeAuthentication.new(api: self).authenticate(
29
+ name: name,
30
+ email_address: email_address,
31
+ provider: provider,
32
+ settings: settings,
33
+ reauth_account_id: reauth_account_id,
34
+ scopes: scopes
35
+ )
36
+ end
37
+
38
+ def authentication_url(redirect_uri:, scopes:, response_type: "code", login_hint: nil, state: nil,
39
+ provider: nil, redirect_on_error: nil, disable_provider_selection: nil)
40
+ params = { client_id: app_id, redirect_uri: redirect_uri, response_type: response_type,
41
+ login_hint: login_hint }
42
+
43
+ params[:state] = state if state
44
+ params[:scopes] = scopes.join(",") if scopes
45
+ params[:provider] = provider if provider
46
+ params[:redirect_on_error] = redirect_on_error if redirect_on_error
47
+ params[:disable_provider_selection] = disable_provider_selection if disable_provider_selection
48
+
49
+ "#{api_server}/oauth/authorize?#{URI.encode_www_form(params)}"
50
+ end
51
+
52
+ # Exchanges an authorization code for an access token
53
+ # @param code [String] The authorization code to exchange
54
+ # @param return_full_response [Boolean] If true, returns the full response body instead of just the token
55
+ # @return [String | Hash] Returns just the access token as a string, or the full response as a hash
56
+ def exchange_code_for_token(code, return_full_response: false)
57
+ data = {
58
+ "client_id" => app_id,
59
+ "client_secret" => client.app_secret,
60
+ "grant_type" => "authorization_code",
61
+ "code" => code
62
+ }
63
+
64
+ response = execute(method: :post, path: "/oauth/token", payload: data)
65
+ return_full_response ? response : response[:access_token]
66
+ end
67
+
68
+ # @return [Collection<Contact>] A queryable collection of Contacts
69
+ def contacts
70
+ @contacts ||= Collection.new(model: Contact, api: self)
71
+ end
72
+
73
+ # @return [Collection<ContactGroup>] A queryable collection of Contact Groups
74
+ def contact_groups
75
+ @contact_groups ||= Collection.new(model: ContactGroup, api: self)
76
+ end
77
+
78
+ # @return [CurrentAccount] The account details for whomevers access token is set
79
+ def current_account
80
+ prevent_calling_if_missing_access_token(:current_account)
81
+ CurrentAccount.from_hash(execute(method: :get, path: "/account"), api: self)
82
+ end
83
+
84
+ # @return [Collection<Account>] A queryable collection of {Account}s
85
+ def accounts
86
+ @accounts ||= Collection.new(model: Account, api: as(client.app_secret))
87
+ end
88
+
89
+ # @return [CalendarCollection<Calendar>] A queryable collection of {Calendar}s
90
+ def calendars
91
+ @calendars ||= CalendarCollection.new(model: Calendar, api: self)
92
+ end
93
+
94
+ # @return [DeltasCollection<Delta>] A queryable collection of Deltas, which are themselves a collection.
95
+ def deltas
96
+ @deltas ||= DeltasCollection.new(api: self)
97
+ end
98
+
99
+ # @return[Collection<Draft>] A queryable collection of {Draft} objects
100
+ def drafts
101
+ @drafts ||= Collection.new(model: Draft, api: self)
102
+ end
103
+
104
+ # @return [EventCollection<Event>] A queryable collection of {Event}s
105
+ def events
106
+ @events ||= EventCollection.new(model: Event, api: self)
107
+ end
108
+
109
+ # @return [Collection<Folder>] A queryable collection of {Folder}s
110
+ def folders
111
+ @folders ||= Collection.new(model: Folder, api: self)
112
+ end
113
+
114
+ # @return [Collection<File>] A queryable collection of {File}s
115
+ def files
116
+ @files ||= Collection.new(model: File, api: self)
117
+ end
118
+
119
+ # @return [Collection<Label>] A queryable collection of {Label} objects
120
+ def labels
121
+ @labels ||= Collection.new(model: Label, api: self)
122
+ end
123
+
124
+ # @return[Collection<Message>] A queryable collection of {Message} objects
125
+ def messages
126
+ @messages ||= Collection.new(model: Message, api: self)
127
+ end
128
+
129
+ # @return[Collection<RoomResource>] A queryable collection of {RoomResource} objects
130
+ def room_resources
131
+ @room_resources ||= Collection.new(model: RoomResource, api: self)
132
+ end
133
+
134
+ # @return[Collection<JobStatus>] A queryable collection of {JobStatus} objects
135
+ def job_statuses
136
+ @job_statuses ||= JobStatusCollection.new(model: JobStatus, api: self)
137
+ end
138
+
139
+ # @return[OutboxCollection] A collection of Outbox operations
140
+ def outbox
141
+ @outbox ||= Outbox.new(api: self)
142
+ end
143
+
144
+ # @return[SchedulerCollection<Scheduler>] A queryable collection of {Scheduler} objects
145
+ def scheduler
146
+ # Make a deep copy of the API as the scheduler API uses a different base URL
147
+ scheduler_api = Marshal.load(Marshal.dump(self))
148
+ scheduler_api.client.api_server = "https://api.schedule.nylas.com"
149
+ @scheduler ||= SchedulerCollection.new(model: Scheduler, api: scheduler_api)
150
+ end
151
+
152
+ # @return[Neural] A collection of Neural operations
153
+ def neural
154
+ @neural ||= Neural.new(api: self)
155
+ end
156
+
157
+ # @return [Collection<Component>] A queryable collection of {Component}s
158
+ def components
159
+ @components ||= ComponentCollection.new(model: Component, api: as(client.app_secret))
160
+ end
161
+
162
+ # Revokes access to the Nylas API for the given access token
163
+ # @return [Boolean]
164
+ def revoke(access_token)
165
+ response = client.as(access_token).post(path: "/oauth/revoke")
166
+ response.code == 200 && response.empty?
167
+ end
168
+
169
+ # Returns the application details
170
+ # @return [ApplicationDetail] The application details
171
+ def application_details
172
+ response = client.as(client.app_secret).execute(
173
+ method: :get,
174
+ path: "/a/#{app_id}",
175
+ auth_method: HttpClient::AuthMethod::BASIC
176
+ )
177
+ ApplicationDetail.new(**response)
178
+ end
179
+
180
+ # Updates the application details
181
+ # @param application_details [ApplicationDetail] The updated application details
182
+ # @return [ApplicationDetails] The updated application details, returned from the server
183
+ def update_application_details(application_details)
184
+ response = client.as(client.app_secret).execute(
185
+ method: :put,
186
+ path: "/a/#{app_id}",
187
+ payload: JSON.dump(application_details.to_h),
188
+ auth_method: HttpClient::AuthMethod::BASIC
189
+ )
190
+ ApplicationDetail.new(**response)
191
+ end
192
+
193
+ # Returns list of IP addresses
194
+ # @return [Hash]
195
+ # hash has keys of :updated_at (unix timestamp) and :ip_addresses (array of strings)
196
+ def ip_addresses
197
+ path = "/a/#{app_id}/ip_addresses"
198
+ client.as(client.app_secret).get(path: path, auth_method: HttpClient::AuthMethod::BASIC)
199
+ end
200
+
201
+ # @param message [Hash, String, #send!]
202
+ # @return [Message] The resulting message
203
+ def send!(message)
204
+ return message.send! if message.respond_to?(:send!)
205
+ return NewMessage.new(**message.merge(api: self)).send! if message.respond_to?(:key?)
206
+ return RawMessage.new(message, api: self).send! if message.is_a? String
207
+ end
208
+
209
+ # Allows you to get an API that acts as a different user but otherwise has the same settings
210
+ # @param access_token [String] Oauth Access token or app secret used to authenticate with the API
211
+ # @return [API]
212
+ def as(access_token)
213
+ API.new(client: client.as(access_token))
214
+ end
215
+
216
+ # @return [Collection<Thread>] A queryable collection of Threads
217
+ def threads
218
+ @threads ||= Collection.new(model: Thread, api: self)
219
+ end
220
+
221
+ # @return [Collection<Webhook>] A queryable collection of {Webhook}s
222
+ def webhooks
223
+ @webhooks ||= Collection.new(model: Webhook, api: as(client.app_secret))
224
+ end
225
+
226
+ # TODO: Move this into calendar collection
227
+ def free_busy(emails:, start_time:, end_time:)
228
+ FreeBusyCollection.new(
229
+ api: self,
230
+ emails: emails,
231
+ start_time: start_time.to_i,
232
+ end_time: end_time.to_i
233
+ )
234
+ end
235
+
236
+ private
237
+
238
+ def prevent_calling_if_missing_access_token(method_name)
239
+ return if client.access_token && !client.access_token.empty?
240
+
241
+ raise NoAuthToken, method_name
242
+ end
243
+ end
244
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NylasV2
4
+ # Structure to represent a Nylas Application Detail object.
5
+ # @see https://developer.nylas.com/docs/api/#get/a/client_id
6
+ class ApplicationDetail
7
+ include Model::Attributable
8
+
9
+ attribute :application_name, :string
10
+ attribute :icon_url, :string
11
+ has_n_of_attribute :redirect_uris, :string
12
+ end
13
+ end
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NylasV2
4
+ # Ruby bindings for the Nylas Calendar API
5
+ # @see https://docs.nylas.com/reference#calendars
6
+ class Calendar
7
+ include Model
8
+ self.resources_path = "/calendars"
9
+ self.creatable = true
10
+ self.listable = true
11
+ self.showable = true
12
+ self.filterable = true
13
+ self.updatable = true
14
+ self.destroyable = true
15
+ self.id_listable = true
16
+ self.countable = true
17
+
18
+ attribute :id, :string
19
+ attribute :account_id, :string
20
+
21
+ attribute :object, :string
22
+
23
+ attribute :name, :string
24
+ attribute :description, :string
25
+ attribute :is_primary, :boolean
26
+ attribute :location, :string
27
+ attribute :timezone, :string
28
+
29
+ attribute :read_only, :boolean
30
+ attribute :metadata, :hash
31
+ attribute :job_status_id, :string, read_only: true
32
+ attribute :hex_color, :string, read_only: true
33
+
34
+ def read_only?
35
+ read_only == true
36
+ end
37
+
38
+ def primary?
39
+ is_primary
40
+ end
41
+
42
+ def events
43
+ api.events.where(calendar_id: id)
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,144 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NylasV2
4
+ # Additional methods for some of Calendar's other functionality
5
+ # @see https://developer.nylas.com/docs/connectivity/calendar
6
+ class CalendarCollection < Collection
7
+ # Check multiple calendars to find available time slots for a single meeting
8
+ # @param duration_minutes [Integer] The total number of minutes the event should last
9
+ # @param interval_minutes [Integer] How many minutes it should check for availability
10
+ # @param start_time [Integer] The timestamp for the beginning of the event
11
+ # @param end_time [Integer] The timestamp for the end of the event
12
+ # @param emails [Array<String>] Emails on the same domain to check
13
+ # @param buffer [Integer] The amount of buffer time in minutes that you want around existing meetings
14
+ # @param round_robin [String] Finds available meeting times in a round-robin style
15
+ # @param event_collection_id [String] Unique identifier for a collection of events that are created
16
+ # @param free_busy [Array<NylasV2::FreeBusy>] A list of free-busy data for users not in your organization
17
+ # @param open_hours [Array<NylasV2::OpenHours>] Additional times email accounts are available
18
+ # @param calendars [Array] Check account and calendar IDs for free/busy status
19
+ # @return [Hash] The availability information; a list of time slots where all participants are available
20
+ def availability(duration_minutes:,
21
+ interval_minutes:,
22
+ start_time:,
23
+ end_time:,
24
+ emails: [],
25
+ buffer: nil,
26
+ round_robin: nil,
27
+ event_collection_id: nil,
28
+ free_busy: [],
29
+ open_hours: [],
30
+ calendars: [])
31
+ validate_calendars_or_emails(calendars, emails)
32
+ validate_open_hours(emails, free_busy, open_hours) unless open_hours.empty?
33
+
34
+ payload = {
35
+ duration_minutes: duration_minutes,
36
+ interval_minutes: interval_minutes,
37
+ start_time: start_time,
38
+ end_time: end_time,
39
+ emails: emails,
40
+ free_busy: free_busy.map(&:to_h),
41
+ open_hours: open_hours.map(&:to_h),
42
+ calendars: calendars
43
+ }
44
+ payload[:buffer] = buffer if buffer
45
+ payload[:round_robin] = round_robin if round_robin
46
+ payload[:event_collection_id] = event_collection_id if event_collection_id
47
+
48
+ execute_availability("/calendars/availability", **payload)
49
+ end
50
+
51
+ # Check multiple calendars to find availability for multiple meetings with several participants
52
+ # @param duration_minutes [Integer] The total number of minutes the event should last
53
+ # @param interval_minutes [Integer] How many minutes it should check for availability
54
+ # @param start_time [Integer] The timestamp for the beginning of the event
55
+ # @param end_time [Integer] The timestamp for the end of the event
56
+ # @param emails [Array<Array<String>>] Emails on the same domain to check
57
+ # @param buffer [Integer] The amount of buffer time in minutes that you want around existing meetings
58
+ # @param free_busy [Array<NylasV2::FreeBusy>] A list of free-busy data for users not in your organization
59
+ # @param open_hours [Array<NylasV2::OpenHours>] Additional times email accounts are available
60
+ # @param calendars [Array] Check account and calendar IDs for free/busy status
61
+ # @return [Hash] The availability information; a list of all possible groupings that share time slots
62
+ def consecutive_availability(duration_minutes:,
63
+ interval_minutes:,
64
+ start_time:,
65
+ end_time:,
66
+ emails: [],
67
+ buffer: nil,
68
+ free_busy: [],
69
+ open_hours: [],
70
+ calendars: [])
71
+ validate_calendars_or_emails(emails, calendars)
72
+ validate_open_hours(emails, free_busy, open_hours) unless open_hours.empty?
73
+
74
+ payload = {
75
+ duration_minutes: duration_minutes,
76
+ interval_minutes: interval_minutes,
77
+ start_time: start_time,
78
+ end_time: end_time,
79
+ emails: emails,
80
+ free_busy: free_busy.map(&:to_h),
81
+ open_hours: open_hours.map(&:to_h),
82
+ calendars: calendars
83
+ }
84
+ payload[:buffer] = buffer if buffer
85
+
86
+ execute_availability("/calendars/availability/consecutive", **payload)
87
+ end
88
+
89
+ private
90
+
91
+ def execute_availability(path, **payload)
92
+ api.execute(
93
+ method: :post,
94
+ path: path,
95
+ payload: JSON.dump(payload)
96
+ )
97
+ end
98
+
99
+ def validate_calendars_or_emails(calendars, emails)
100
+ return unless calendars.empty? && emails.empty?
101
+
102
+ raise ArgumentError, "You must provide at least one of 'emails' or 'calendars'"
103
+ end
104
+
105
+ def validate_open_hours(emails, free_busy, open_hours)
106
+ raise TypeError, "open_hours' must be an array." unless open_hours.is_a?(Array)
107
+
108
+ open_hours_emails = map_open_hours_emails(open_hours)
109
+ free_busy_emails = map_free_busy_emails(free_busy)
110
+ emails = merge_arrays(emails) if emails[0].is_a?(Array)
111
+
112
+ open_hours_emails.each do |email|
113
+ next if emails.include?(email) || free_busy_emails.include?(email)
114
+
115
+ raise ArgumentError, "Open Hours cannot contain an email not present in the main email list or
116
+ the free busy email list."
117
+ end
118
+ end
119
+
120
+ def map_open_hours_emails(open_hours)
121
+ open_hours_emails = []
122
+ open_hours.map do |oh|
123
+ open_hours_emails += oh.emails
124
+ end
125
+ open_hours_emails
126
+ end
127
+
128
+ def map_free_busy_emails(free_busy)
129
+ free_busy_emails = []
130
+ free_busy.map do |fb|
131
+ free_busy_emails.append(fb.email)
132
+ end
133
+ free_busy_emails
134
+ end
135
+
136
+ def merge_arrays(array)
137
+ list = []
138
+ array.each do |x|
139
+ list += x
140
+ end
141
+ list
142
+ end
143
+ end
144
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NylasV2
4
+ # Structure to represent the Neural Categorize object.
5
+ # @see https://developer.nylas.com/docs/intelligence/categorizer/#categorize-message-response
6
+ class Categorize
7
+ include Model::Attributable
8
+
9
+ attribute :category, :string
10
+ attribute :categorized_at, :unix_timestamp
11
+ attribute :model_version, :string
12
+ has_n_of_attribute :subcategories, :string
13
+ end
14
+ end