nylas 5.6.1 → 5.9.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 54c46b764fd777bee7eb27539bd6dc54ad253b76a242db3cfa9c969e128c05e4
4
- data.tar.gz: 2c0876d20db34b5796ec2d6c21c487de8d661cd6041a899604b6dcf594ffa8f1
3
+ metadata.gz: b390b7c22a3dfcc7a4eed1db3966295d71a5f8928efd4b81bedbabd0c7bac0dc
4
+ data.tar.gz: d27e92177ddf12626917c2b20334bc74bcc703f04d5d68721375429aa4ce06fe
5
5
  SHA512:
6
- metadata.gz: f70e5d14160b41bb0b50fddc2a17141fd16405fc9f0460a0fbdeaf7ac9ff356332a0400167322c63e7c0a1d0673a1b234a57e1427d9682c8bf88e59e0ca2a5c6
7
- data.tar.gz: f4494a94a6bf17fc43be9af8961ce9ceb0ce9b97e76b06e598bf4214934d81561378f3519c3715a536d2b8703194bfe6ba047496e1ab425b3bdb99b18e46bc90
6
+ metadata.gz: c0d5c385aa98002eceed26178f6d63e60950344fd48cd229c2c32fd4b3998c837db894ca2fd883da8886f4dd91ee8fef01b07885f7e3941ef5b17d8bb4c2afe6
7
+ data.tar.gz: 86d6663b12da809962c28d6284ee5a22c90951ac9055bbadce90a347a55061ac1c67ff1feeb7e22b711d2311f24df2d0928e858be3ca03074e9e109022199b62
data/lib/nylas/account.rb CHANGED
@@ -8,12 +8,15 @@ module Nylas
8
8
  self.listable = true
9
9
  self.showable = true
10
10
  self.updatable = true
11
+ self.destroyable = true
12
+ self.auth_method = HttpClient::AuthMethod::BASIC
11
13
 
12
14
  attribute :id, :string, read_only: true
13
15
  attribute :account_id, :string, read_only: true
14
16
  attribute :billing_state, :string, read_only: true
15
17
  attribute :sync_state, :string, read_only: true
16
18
  attribute :provider, :string, read_only: true
19
+ attribute :authentication_type, :string, read_only: true
17
20
 
18
21
  attribute :email, :string, read_only: true
19
22
  attribute :trial, :boolean, read_only: true
@@ -36,6 +39,15 @@ module Nylas
36
39
  response[:success]
37
40
  end
38
41
 
42
+ # Return information about an account's access token
43
+ # @param access_token [String] The access token to inquire about
44
+ # @return [TokenInfo] The access token information
45
+ def token_info(access_token)
46
+ payload = JSON.dump(access_token: access_token)
47
+ response = execute(method: :post, path: "#{resource_path}/token-info", payload: payload)
48
+ TokenInfo.new(**response)
49
+ end
50
+
39
51
  def self.resources_path(api:)
40
52
  "/a/#{api.app_id}/accounts"
41
53
  end
data/lib/nylas/api.rb CHANGED
@@ -130,6 +130,16 @@ module Nylas
130
130
  @room_resources ||= Collection.new(model: RoomResource, api: self)
131
131
  end
132
132
 
133
+ # @return[Collection<JobStatus>] A queryable collection of {JobStatus} objects
134
+ def job_statuses
135
+ @job_statuses ||= JobStatusCollection.new(model: JobStatus, api: self)
136
+ end
137
+
138
+ # @return[OutboxCollection] A collection of Outbox operations
139
+ def outbox
140
+ @outbox ||= Outbox.new(api: self)
141
+ end
142
+
133
143
  # @return[SchedulerCollection<Scheduler>] A queryable collection of {Scheduler} objects
134
144
  def scheduler
135
145
  # Make a deep copy of the API as the scheduler API uses a different base URL
@@ -138,7 +148,7 @@ module Nylas
138
148
  @scheduler ||= SchedulerCollection.new(model: Scheduler, api: scheduler_api)
139
149
  end
140
150
 
141
- # @return[Neural] A {Neural} object that provides
151
+ # @return[Neural] A collection of Neural operations
142
152
  def neural
143
153
  @neural ||= Neural.new(api: self)
144
154
  end
@@ -155,12 +165,36 @@ module Nylas
155
165
  response.code == 200 && response.empty?
156
166
  end
157
167
 
168
+ # Returns the application details
169
+ # @return [ApplicationDetail] The application details
170
+ def application_details
171
+ response = client.as(client.app_secret).execute(
172
+ method: :get,
173
+ path: "/a/#{app_id}",
174
+ auth_method: HttpClient::AuthMethod::BASIC
175
+ )
176
+ ApplicationDetail.new(**response)
177
+ end
178
+
179
+ # Updates the application details
180
+ # @param application_details [ApplicationDetail] The updated application details
181
+ # @return [ApplicationDetails] The updated application details, returned from the server
182
+ def update_application_details(application_details)
183
+ response = client.as(client.app_secret).execute(
184
+ method: :put,
185
+ path: "/a/#{app_id}",
186
+ payload: JSON.dump(application_details.to_h),
187
+ auth_method: HttpClient::AuthMethod::BASIC
188
+ )
189
+ ApplicationDetail.new(**response)
190
+ end
191
+
158
192
  # Returns list of IP addresses
159
193
  # @return [Hash]
160
194
  # hash has keys of :updated_at (unix timestamp) and :ip_addresses (array of strings)
161
195
  def ip_addresses
162
196
  path = "/a/#{app_id}/ip_addresses"
163
- client.as(client.app_secret).get(path: path)
197
+ client.as(client.app_secret).get(path: path, auth_method: HttpClient::AuthMethod::BASIC)
164
198
  end
165
199
 
166
200
  # @param message [Hash, String, #send!]
@@ -172,7 +206,7 @@ module Nylas
172
206
  end
173
207
 
174
208
  # Allows you to get an API that acts as a different user but otherwise has the same settings
175
- # @param [String] Oauth Access token or app secret used to authenticate with the API
209
+ # @param access_token [String] Oauth Access token or app secret used to authenticate with the API
176
210
  # @return [API]
177
211
  def as(access_token)
178
212
  API.new(client: client.as(access_token))
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nylas
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
@@ -22,6 +22,7 @@ module Nylas
22
22
 
23
23
  attribute :read_only, :boolean
24
24
  attribute :metadata, :hash
25
+ attribute :job_status_id, :string, read_only: true
25
26
 
26
27
  def read_only?
27
28
  read_only == true
@@ -5,47 +5,53 @@ module Nylas
5
5
  # @see https://developer.nylas.com/docs/connectivity/calendar
6
6
  class CalendarCollection < Collection
7
7
  def availability(duration_minutes:,
8
- interval:,
8
+ interval_minutes:,
9
9
  start_time:,
10
10
  end_time:,
11
- emails:,
11
+ emails: [],
12
12
  buffer: nil,
13
13
  round_robin: nil,
14
14
  free_busy: [],
15
- open_hours: [])
15
+ open_hours: [],
16
+ calendars: [])
17
+ validate_calendars_or_emails(calendars, emails)
16
18
  validate_open_hours(emails, free_busy, open_hours) unless open_hours.empty?
17
19
 
18
20
  execute_availability("/calendars/availability",
19
21
  duration_minutes: duration_minutes,
20
- interval: interval,
22
+ interval_minutes: interval_minutes,
21
23
  start_time: start_time,
22
24
  end_time: end_time,
23
25
  emails: emails,
24
26
  buffer: buffer,
25
27
  round_robin: round_robin,
26
28
  free_busy: free_busy,
27
- open_hours: open_hours)
29
+ open_hours: open_hours,
30
+ calendars: calendars)
28
31
  end
29
32
 
30
33
  def consecutive_availability(duration_minutes:,
31
- interval:,
34
+ interval_minutes:,
32
35
  start_time:,
33
36
  end_time:,
34
- emails:,
37
+ emails: [],
35
38
  buffer: nil,
36
39
  free_busy: [],
37
- open_hours: [])
40
+ open_hours: [],
41
+ calendars: [])
42
+ validate_calendars_or_emails(emails, calendars)
38
43
  validate_open_hours(emails, free_busy, open_hours) unless open_hours.empty?
39
44
 
40
45
  execute_availability("/calendars/availability/consecutive",
41
46
  duration_minutes: duration_minutes,
42
- interval: interval,
47
+ interval_minutes: interval_minutes,
43
48
  start_time: start_time,
44
49
  end_time: end_time,
45
50
  emails: emails,
46
51
  buffer: buffer,
47
52
  free_busy: free_busy,
48
- open_hours: open_hours)
53
+ open_hours: open_hours,
54
+ calendars: calendars)
49
55
  end
50
56
 
51
57
  private
@@ -58,6 +64,12 @@ module Nylas
58
64
  )
59
65
  end
60
66
 
67
+ def validate_calendars_or_emails(calendars, emails)
68
+ return unless calendars.empty? && emails.empty?
69
+
70
+ raise ArgumentError, "You must provide at least one of 'emails' or 'calendars'"
71
+ end
72
+
61
73
  def validate_open_hours(emails, free_busy, open_hours)
62
74
  raise TypeError, "open_hours' must be an array." unless open_hours.is_a?(Array)
63
75
 
@@ -139,7 +139,7 @@ module Nylas
139
139
  # @return [Hash] Specification for request to be passed to {API#execute}
140
140
  def to_be_executed
141
141
  { method: :get, path: resources_path, query: constraints.to_query,
142
- headers: constraints.to_headers }
142
+ headers: constraints.to_headers, auth_method: model.auth_method }
143
143
  end
144
144
 
145
145
  # Retrieves the data from the API for the particular constraints
@@ -6,6 +6,7 @@ module Nylas
6
6
  include Model
7
7
  allows_operations(creatable: true, listable: true, filterable: true, showable: true, updatable: true,
8
8
  destroyable: true)
9
+ self.auth_method = HttpClient::AuthMethod::BASIC
9
10
 
10
11
  attribute :id, :string, read_only: true
11
12
  attribute :account_id, :string
data/lib/nylas/contact.rb CHANGED
@@ -30,6 +30,7 @@ module Nylas
30
30
  attribute :office_location, :string
31
31
  attribute :notes, :string
32
32
  attribute :source, :string
33
+ attribute :job_status_id, :string, read_only: true
33
34
 
34
35
  has_n_of_attribute :groups, :contact_group
35
36
  has_n_of_attribute :emails, :email_address
data/lib/nylas/draft.rb CHANGED
@@ -36,6 +36,7 @@ module Nylas
36
36
  has_n_of_attribute :labels, :label
37
37
 
38
38
  attribute :tracking, :message_tracking
39
+ attribute :job_status_id, :string, read_only: true
39
40
 
40
41
  transfer :api, to: %i[events files folder labels]
41
42
 
data/lib/nylas/event.rb CHANGED
@@ -31,6 +31,7 @@ module Nylas
31
31
  attribute :conferencing, :event_conferencing
32
32
  has_n_of_attribute :notifications, :event_notification
33
33
  attribute :original_start_time, :unix_timestamp
34
+ attribute :job_status_id, :string, read_only: true
34
35
 
35
36
  attr_accessor :notify_participants
36
37
 
@@ -59,8 +60,47 @@ module Nylas
59
60
  rsvp.save
60
61
  end
61
62
 
63
+ # Generate an ICS file server-side, from an Event
64
+ # @param ical_uid [String] Unique identifier used events across calendaring systems
65
+ # @param method [String] Description of invitation and response methods for attendees
66
+ # @param prodid [String] Company-specific unique product identifier
67
+ # @return [String] String for writing directly into an ICS file
68
+ def generate_ics(ical_uid: nil, method: nil, prodid: nil)
69
+ raise ArgumentError, "Cannot generate an ICS file for an event without a Calendar ID or when set" unless
70
+ calendar_id && self.when
71
+
72
+ payload = build_ics_event_payload(ical_uid, method, prodid)
73
+ response = api.execute(
74
+ method: :post,
75
+ path: "#{resources_path}/to-ics",
76
+ payload: JSON.dump(payload)
77
+ )
78
+
79
+ response[:ics]
80
+ end
81
+
62
82
  private
63
83
 
84
+ def build_ics_event_payload(ical_uid, method, prodid)
85
+ payload = {}
86
+ if id
87
+ payload[:event_id] = id
88
+ else
89
+ payload = to_h(enforce_read_only: true)
90
+ end
91
+ ics_options = build_ics_options_payload(ical_uid, method, prodid)
92
+ payload["ics_options"] = ics_options unless ics_options.empty?
93
+ payload
94
+ end
95
+
96
+ def build_ics_options_payload(ical_uid, method, prodid)
97
+ payload = {}
98
+ payload["ical_uid"] = ical_uid if ical_uid
99
+ payload["method"] = method if method
100
+ payload["prodid"] = prodid if prodid
101
+ payload
102
+ end
103
+
64
104
  def query_params
65
105
  if notify_participants.nil?
66
106
  {}
data/lib/nylas/folder.rb CHANGED
@@ -13,12 +13,12 @@ module Nylas
13
13
  self.updatable = true
14
14
  self.destroyable = true
15
15
 
16
- attribute :id, :string
17
- attribute :account_id, :string
18
-
19
- attribute :object, :string
16
+ attribute :id, :string, read_only: true
17
+ attribute :account_id, :string, read_only: true
18
+ attribute :object, :string, read_only: true
20
19
 
21
20
  attribute :name, :string
22
21
  attribute :display_name, :string
22
+ attribute :job_status_id, :string, read_only: true
23
23
  end
24
24
  end
@@ -2,10 +2,16 @@
2
2
 
3
3
  module Nylas
4
4
  require "yajl"
5
+ require "base64"
5
6
 
6
7
  # Plain HTTP client that can be used to interact with the Nylas API sans any type casting.
7
8
  class HttpClient # rubocop:disable Metrics/ClassLength
8
- HTTP_SUCCESS_CODES = [200, 201, 302].freeze
9
+ module AuthMethod
10
+ BEARER = 1
11
+ BASIC = 2
12
+ end
13
+
14
+ HTTP_SUCCESS_CODES = [200, 201, 202, 302].freeze
9
15
 
10
16
  HTTP_CODE_TO_EXCEPTIONS = {
11
17
  400 => InvalidRequest,
@@ -33,7 +39,8 @@ module Nylas
33
39
  "/delta/longpoll" => 3650,
34
40
  "/delta/streaming" => 3650
35
41
  }.freeze
36
- SUPPORTED_API_VERSION = "2.2"
42
+
43
+ SUPPORTED_API_VERSION = "2.5"
37
44
 
38
45
  include Logging
39
46
  attr_accessor :api_server
@@ -73,9 +80,10 @@ module Nylas
73
80
  # @param query [Hash] (Optional, defaults to {}) - Hash of names and values to include in the query
74
81
  # section of the URI fragment
75
82
  # @param payload [String,Hash] (Optional, defaults to nil) - Body to send with the request.
83
+ # @param auth_method [AuthMethod] (Optional, defaults to BEARER) - The authentication method.
76
84
  # @return [Array Hash Stringn]
77
85
  # rubocop:disable Metrics/MethodLength
78
- def execute(method:, path: nil, headers: {}, query: {}, payload: nil)
86
+ def execute(method:, path: nil, headers: {}, query: {}, payload: nil, auth_method: nil)
79
87
  timeout = ENDPOINT_TIMEOUTS.fetch(path, 230)
80
88
  request = build_request(
81
89
  method: method,
@@ -83,7 +91,8 @@ module Nylas
83
91
  headers: headers,
84
92
  query: query,
85
93
  payload: payload,
86
- timeout: timeout
94
+ timeout: timeout,
95
+ auth_method: auth_method || AuthMethod::BEARER
87
96
  )
88
97
  rest_client_execute(**request) do |response, _request, result|
89
98
  content_type = nil
@@ -107,35 +116,64 @@ module Nylas
107
116
  inform_on :execute, level: :debug,
108
117
  also_log: { result: true, values: %i[method url path headers query payload] }
109
118
 
110
- def build_request(method:, path: nil, headers: {}, query: {}, payload: nil, timeout: nil)
119
+ def build_request(
120
+ method:,
121
+ path: nil,
122
+ headers: {},
123
+ query: {},
124
+ payload: nil,
125
+ timeout: nil,
126
+ auth_method: nil
127
+ )
111
128
  url ||= url_for_path(path)
112
129
  url = add_query_params_to_url(url, query)
113
- resulting_headers = default_headers.merge(headers)
130
+ resulting_headers = default_headers.merge(headers).merge(auth_header(auth_method))
114
131
  { method: method, url: url, payload: payload, headers: resulting_headers, timeout: timeout }
115
132
  end
116
133
 
117
134
  # Syntactical sugar for making GET requests via the API.
118
135
  # @see #execute
119
- def get(path: nil, headers: {}, query: {})
120
- execute(method: :get, path: path, query: query, headers: headers)
136
+ def get(path: nil, headers: {}, query: {}, auth_method: nil)
137
+ execute(method: :get, path: path, query: query, headers: headers, auth_method: auth_method)
121
138
  end
122
139
 
123
140
  # Syntactical sugar for making POST requests via the API.
124
141
  # @see #execute
125
- def post(path: nil, payload: nil, headers: {}, query: {})
126
- execute(method: :post, path: path, headers: headers, query: query, payload: payload)
142
+ def post(path: nil, payload: nil, headers: {}, query: {}, auth_method: nil)
143
+ execute(
144
+ method: :post,
145
+ path: path,
146
+ headers: headers,
147
+ query: query,
148
+ payload: payload,
149
+ auth_method: auth_method
150
+ )
127
151
  end
128
152
 
129
153
  # Syntactical sugar for making PUT requests via the API.
130
154
  # @see #execute
131
- def put(path: nil, payload:, headers: {}, query: {})
132
- execute(method: :put, path: path, headers: headers, query: query, payload: payload)
155
+ def put(path: nil, payload:, headers: {}, query: {}, auth_method: nil)
156
+ execute(
157
+ method: :put,
158
+ path: path,
159
+ headers: headers,
160
+ query: query,
161
+ payload: payload,
162
+ auth_method: auth_method
163
+ )
133
164
  end
134
165
 
135
166
  # Syntactical sugar for making DELETE requests via the API.
136
167
  # @see #execute
137
- def delete(path: nil, payload: nil, headers: {}, query: {})
138
- execute(method: :delete, path: path, headers: headers, query: query, payload: payload)
168
+ def delete(path: nil, payload: nil, headers: {}, query: {}, auth_method: nil)
169
+ execute(
170
+ method: :delete,
171
+ path: path,
172
+ headers: headers,
173
+ query: query,
174
+ payload: payload,
175
+ auth_method: auth_method
176
+ )
139
177
  end
140
178
 
141
179
  def default_headers
@@ -216,5 +254,18 @@ module Nylas
216
254
 
217
255
  query
218
256
  end
257
+
258
+ def auth_header(auth_method)
259
+ authorization_string = case auth_method
260
+ when AuthMethod::BEARER
261
+ "Bearer #{access_token}"
262
+ when AuthMethod::BASIC
263
+ "Basic #{Base64.encode64("#{access_token}:")}"
264
+ else
265
+ "Bearer #{access_token}"
266
+ end
267
+
268
+ { "Authorization" => authorization_string }
269
+ end
219
270
  end
220
271
  end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nylas
4
+ # Ruby representation of a Nylas Job Status object
5
+ # @see https://developer.nylas.com/docs/api/#tag--Job-Status
6
+ class JobStatus
7
+ include Model
8
+ self.resources_path = "/job-statuses"
9
+ allows_operations(listable: true)
10
+
11
+ attribute :id, :string, read_only: true
12
+ attribute :account_id, :string, read_only: true
13
+ attribute :job_status_id, :string, read_only: true
14
+ attribute :action, :string, read_only: true
15
+ attribute :object, :string, read_only: true
16
+ attribute :status, :string, read_only: true
17
+ attribute :created_at, :unix_timestamp, read_only: true
18
+ attribute :reason, :string, read_only: true
19
+
20
+ # Returns the status of a job as a boolean
21
+ # @return [Boolean] If the job was successful
22
+ def successful?
23
+ status == "successful"
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nylas
4
+ # Additional methods for some of Calendar's other functionality
5
+ # @see https://developer.nylas.com/docs/connectivity/calendar
6
+ class JobStatusCollection < Collection
7
+ def find_model(id)
8
+ response = api.execute(
9
+ **to_be_executed.merge(
10
+ path: "#{resources_path}/#{id}",
11
+ query: view_query
12
+ )
13
+ )
14
+
15
+ object_type = response[:object]
16
+ return OutboxJobStatus.from_hash(response, api: api) if object_type == "message"
17
+
18
+ model.from_hash(response, api: api)
19
+ end
20
+ end
21
+ end
data/lib/nylas/label.rb CHANGED
@@ -20,5 +20,6 @@ module Nylas
20
20
 
21
21
  attribute :name, :string
22
22
  attribute :display_name, :string
23
+ attribute :job_status_id, :string, read_only: true
23
24
  end
24
25
  end
data/lib/nylas/message.rb CHANGED
@@ -37,6 +37,7 @@ module Nylas
37
37
  attribute :folder, :folder
38
38
  attribute :folder_id, :string
39
39
  attribute :metadata, :hash
40
+ attribute :job_status_id, :string, read_only: true
40
41
 
41
42
  has_n_of_attribute :labels, :label, read_only: true
42
43
  has_n_of_attribute :label_ids, :string
data/lib/nylas/model.rb CHANGED
@@ -39,8 +39,8 @@ module Nylas
39
39
  !id.nil?
40
40
  end
41
41
 
42
- def execute(method:, payload: nil, path:, query: {})
43
- api.execute(method: method, payload: payload, path: path, query: query)
42
+ def execute(method:, payload: nil, path:, query: {}, auth_method: self.auth_method)
43
+ api.execute(method: method, payload: payload, path: path, query: query, auth_method: auth_method)
44
44
  end
45
45
 
46
46
  def create
@@ -107,6 +107,10 @@ module Nylas
107
107
  self.class.resources_path(api: api)
108
108
  end
109
109
 
110
+ def auth_method
111
+ self.class.auth_method(api: api)
112
+ end
113
+
110
114
  def destroy
111
115
  raise ModelNotDestroyableError, self unless destroyable?
112
116
 
@@ -138,7 +142,7 @@ module Nylas
138
142
  module ClassMethods
139
143
  attr_accessor :raw_mime_type, :creatable, :showable, :filterable, :searchable, :listable, :updatable,
140
144
  :destroyable
141
- attr_writer :resources_path
145
+ attr_writer :resources_path, :auth_method
142
146
 
143
147
  def allows_operations(creatable: false, showable: false, listable: false, filterable: false,
144
148
  searchable: false, updatable: false, destroyable: false)
@@ -184,6 +188,10 @@ module Nylas
184
188
  @resources_path
185
189
  end
186
190
 
191
+ def auth_method(*)
192
+ @auth_method || HttpClient::AuthMethod::BEARER
193
+ end
194
+
187
195
  def exposable_as_raw?
188
196
  !raw_mime_type.nil?
189
197
  end
@@ -0,0 +1,116 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nylas
4
+ # Methods for Outbox functionality
5
+ # @see https://developer.nylas.com/docs/api/#tag--Outbox
6
+ class Outbox
7
+ attr_accessor :api
8
+
9
+ def initialize(api:)
10
+ self.api = api
11
+ end
12
+
13
+ def outbox_path
14
+ @outbox_path ||= "/v2/outbox"
15
+ end
16
+
17
+ # rubocop:disable Layout/LineLength
18
+ # Send a message via Outbox
19
+ # @param draft [Draft, OutboxMessage] The message to send
20
+ # @param send_at [Numeric] The date and time to send the message. If not set, Outbox will send this message immediately.
21
+ # @param retry_limit_datetime [Numeric] The date and time to stop retry attempts for a message. If not set, it defaults to 24 hours after send_at.
22
+ # @return [OutboxJobStatus] The outbox job status status and message data
23
+ # rubocop:enable Layout/LineLength
24
+ def send(draft, send_at: nil, retry_limit_datetime: nil)
25
+ message = draft.to_h(enforce_read_only: true)
26
+ message.merge!(validate_set_date_time(send_at, retry_limit_datetime))
27
+ outbox_response = api.execute(
28
+ method: :post,
29
+ path: outbox_path,
30
+ payload: JSON.dump(message)
31
+ )
32
+
33
+ OutboxJobStatus.new(**outbox_response)
34
+ end
35
+
36
+ # rubocop:disable Layout/LineLength
37
+ # Update a scheduled Outbox message
38
+ # @param job_status_id [String] The ID of the outbox job status
39
+ # @param message [Draft, OutboxMessage] The message object with updated values
40
+ # @param send_at [Numeric] The date and time to send the message. If not set, Outbox will send this message immediately.
41
+ # @param retry_limit_datetime [Numeric] The date and time to stop retry attempts for a message. If not set, it defaults to 24 hours after send_at.
42
+ # @return [OutboxJobStatus] The updated outbox job status status and message data
43
+ # rubocop:enable Layout/LineLength
44
+ def update(job_status_id, message: nil, send_at: nil, retry_limit_datetime: nil)
45
+ payload = {}
46
+ payload.merge!(message.to_h(enforce_read_only: true)) if message
47
+ payload.merge!(validate_set_date_time(send_at, retry_limit_datetime))
48
+ outbox_response = api.execute(
49
+ method: :patch,
50
+ path: "#{outbox_path}/#{job_status_id}",
51
+ payload: JSON.dump(payload)
52
+ )
53
+
54
+ OutboxJobStatus.new(**outbox_response)
55
+ end
56
+
57
+ # Delete a scheduled Outbox message
58
+ # @param job_status_id [String] The ID of the outbox job status to delete
59
+ # @return [void]
60
+ def delete(job_status_id)
61
+ api.execute(
62
+ method: :delete,
63
+ path: "#{outbox_path}/#{job_status_id}"
64
+ )
65
+ end
66
+
67
+ # SendGrid - Check Authentication and Verification Status
68
+ # @return [SendGridVerifiedStatus] The SendGrid Authentication and Verification Status
69
+ def send_grid_verification_status
70
+ response = api.execute(
71
+ method: :get,
72
+ path: "#{outbox_path}/onboard/verified_status"
73
+ )
74
+
75
+ raise "Verification status not present in response" if response.key?("results")
76
+
77
+ SendGridVerifiedStatus.new(**response[:results])
78
+ end
79
+
80
+ # SendGrid - Delete SendGrid Subuser and UAS Grant
81
+ # @param email [String] Email address for SendGrid subuser to delete
82
+ # @return [void]
83
+ def delete_send_grid_sub_user(email)
84
+ api.execute(
85
+ method: :delete,
86
+ path: "#{outbox_path}/onboard/subuser",
87
+ payload: JSON.dump({ email: email })
88
+ )
89
+ end
90
+
91
+ private
92
+
93
+ def validate_set_date_time(send_at, retry_limit_datetime)
94
+ hash = {}
95
+ hash[:send_at] = validate_send_at(send_at) if send_at
96
+ if retry_limit_datetime
97
+ hash[:retry_limit_datetime] = validate_retry_limit_datetime(send_at, retry_limit_datetime)
98
+ end
99
+
100
+ hash
101
+ end
102
+
103
+ def validate_send_at(send_at)
104
+ return send_at unless send_at != 0 && (send_at < Time.now.to_i)
105
+
106
+ raise ArgumentError, "Cannot set message to be sent at a time before the current time."
107
+ end
108
+
109
+ def validate_retry_limit_datetime(send_at, retry_limit_datetime)
110
+ valid_send_at = send_at && send_at != 0 ? send_at : Time.now.to_i
111
+ return retry_limit_datetime unless retry_limit_datetime != 0 && (retry_limit_datetime < valid_send_at)
112
+
113
+ raise ArgumentError, "Cannot set message to stop retrying before time to send at."
114
+ end
115
+ end
116
+ end
@@ -0,0 +1,19 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nylas
4
+ # Ruby representation of a Nylas Outbox Job Status object
5
+ # @see https://developer.nylas.com/docs/api/#post/v2/outbox
6
+ class OutboxJobStatus < JobStatus
7
+ include Model
8
+
9
+ attribute :send_at, :unix_timestamp
10
+ attribute :original_send_at, :unix_timestamp
11
+ attribute :message_id, :string
12
+ attribute :thread_id, :string
13
+ attribute :original_data, :outbox_message
14
+
15
+ transfer :api, to: %i[original_data]
16
+
17
+ inherit_attributes
18
+ end
19
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nylas
4
+ # Ruby representation of a Nylas Outbox Message object
5
+ # @see https://developer.nylas.com/docs/api/#post/v2/outbox
6
+ class OutboxMessage < Draft
7
+ include Model
8
+
9
+ attribute :send_at, :unix_timestamp
10
+ attribute :retry_limit_datetime, :unix_timestamp
11
+ attribute :original_send_at, :unix_timestamp, read_only: true
12
+
13
+ transfer :api, to: %i[events files folder labels]
14
+
15
+ inherit_attributes
16
+ end
17
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nylas
4
+ # Ruby representation of a Nylas Send Grid verified status object
5
+ # @see https://docs.nylas.com/reference#drafts
6
+ class SendGridVerifiedStatus
7
+ include Model::Attributable
8
+
9
+ attribute :domain_verified, :boolean
10
+ attribute :sender_verified, :boolean
11
+ end
12
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nylas
4
+ # Structure to represent information about a Nylas access token.
5
+ # @see https://developer.nylas.com/docs/api/#post/a/client_id/accounts/id/token-info
6
+ class TokenInfo
7
+ include Model::Attributable
8
+
9
+ attribute :scopes, :string
10
+ attribute :state, :string
11
+ attribute :created_at, :unix_timestamp
12
+ attribute :updated_at, :unix_timestamp
13
+
14
+ # Returns the state of the token as a boolean
15
+ # @return [Boolean] If the token is active
16
+ def valid?
17
+ state == "valid"
18
+ end
19
+ end
20
+ end
data/lib/nylas/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Nylas
4
- VERSION = "5.6.1"
4
+ VERSION = "5.9.0"
5
5
  end
data/lib/nylas/webhook.rb CHANGED
@@ -1,21 +1,95 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ module WebhookState
4
+ # Module representing the possible 'state' values in a Webhook
5
+ # @see https://developer.nylas.com/docs/api#post/a/client_id/webhooks
6
+
7
+ ACTIVE = "active"
8
+ INACTIVE = "inactive"
9
+ end
10
+
11
+ module WebhookTrigger
12
+ # Module representing the possible 'trigger' values in a Webhook
13
+ # @see https://developer.nylas.com/docs/api#post/a/client_id/webhooks
14
+
15
+ ACCOUNT_CONNECTED = "account.connected"
16
+ ACCOUNT_RUNNING = "account.running"
17
+ ACCOUNT_STOPPED = "account.stopped"
18
+ ACCOUNT_INVALID = "account.invalid"
19
+ ACCOUNT_SYNC_ERROR = "account.sync_error"
20
+ MESSAGE_CREATED = "message.created"
21
+ MESSAGE_OPENED = "message.opened"
22
+ MESSAGE_LINK_CLICKED = "message.link_created"
23
+ MESSAGE_UPDATED = "message.updated"
24
+ MESSAGE_BOUNCED = "message.bounced"
25
+ THREAD_REPLIED = "thread.replied"
26
+ CONTACT_CREATED = "contact.created"
27
+ CONTACT_UPDATED = "contact.updated"
28
+ CONTACT_DELETED = "contact.deleted"
29
+ CALENDAR_CREATED = "calendar.created"
30
+ CALENDAR_UPDATED = "calendar.updated"
31
+ CALENDAR_DELETED = "calendar.deleted"
32
+ EVENT_CREATED = "event.created"
33
+ EVENT_UPDATED = "event.updated"
34
+ EVENT_DELETED = "event.deleted"
35
+ JOB_SUCCESSFUL = "job.successful"
36
+ JOB_FAILED = "job.failed"
37
+ end
38
+
3
39
  module Nylas
4
40
  # Represents a webhook attached to your application.
5
41
  # @see https://docs.nylas.com/reference#webhooks
6
42
  class Webhook
7
43
  include Model
8
- allows_operations(listable: true, showable: true)
9
- attribute :id, :string
10
- attribute :application_id, :string
44
+ allows_operations(creatable: true, listable: true, showable: true, updatable: true,
45
+ destroyable: true)
46
+ self.auth_method = HttpClient::AuthMethod::BASIC
47
+ attribute :id, :string, read_only: true
48
+ attribute :application_id, :string, read_only: true
11
49
 
12
50
  attribute :callback_url, :string
13
51
  attribute :state, :string
14
- attribute :version, :string
52
+ attribute :version, :string, read_only: true
15
53
  has_n_of_attribute :triggers, :string
16
54
 
55
+ STATE = [:inactive].freeze
56
+
57
+ def save
58
+ result = if persisted?
59
+ update_call(update_payload)
60
+ else
61
+ create
62
+ end
63
+
64
+ attributes.merge(result)
65
+ end
66
+
67
+ def save_all_attributes
68
+ save
69
+ end
70
+
71
+ def update(**data)
72
+ raise ArgumentError, "Only 'state' is allowed to be updated" if data.length > 1 || !data.key?(:state)
73
+
74
+ attributes.merge(**data)
75
+ payload = JSON.dump(data)
76
+ update_call(payload)
77
+
78
+ true
79
+ end
80
+
81
+ def update_all_attributes(**data)
82
+ update(**data)
83
+ end
84
+
17
85
  def self.resources_path(api:)
18
86
  "/a/#{api.app_id}/webhooks"
19
87
  end
88
+
89
+ private
90
+
91
+ def update_payload
92
+ JSON.dump({ state: state })
93
+ end
20
94
  end
21
95
  end
data/lib/nylas.rb CHANGED
@@ -29,6 +29,8 @@ require_relative "nylas/registry"
29
29
  require_relative "nylas/types"
30
30
  require_relative "nylas/constraints"
31
31
 
32
+ require_relative "nylas/http_client"
33
+ require_relative "nylas/api"
32
34
  require_relative "nylas/collection"
33
35
  require_relative "nylas/model"
34
36
 
@@ -67,6 +69,8 @@ require_relative "nylas/free_busy_collection"
67
69
  require_relative "nylas/calendar_collection"
68
70
  require_relative "nylas/component_collection"
69
71
  require_relative "nylas/scheduler_collection"
72
+ require_relative "nylas/job_status_collection"
73
+ require_relative "nylas/outbox"
70
74
 
71
75
  # Models supported by the API
72
76
  require_relative "nylas/account"
@@ -84,6 +88,12 @@ require_relative "nylas/raw_message"
84
88
  require_relative "nylas/thread"
85
89
  require_relative "nylas/webhook"
86
90
  require_relative "nylas/scheduler"
91
+ require_relative "nylas/job_status"
92
+ require_relative "nylas/token_info"
93
+ require_relative "nylas/application_details"
94
+ require_relative "nylas/outbox_message"
95
+ require_relative "nylas/outbox_job_status"
96
+ require_relative "nylas/send_grid_verified_status"
87
97
 
88
98
  # Neural specific types
89
99
  require_relative "nylas/neural"
@@ -104,9 +114,6 @@ require_relative "nylas/scheduler_booking_confirmation"
104
114
 
105
115
  require_relative "nylas/native_authentication"
106
116
 
107
- require_relative "nylas/http_client"
108
- require_relative "nylas/api"
109
-
110
117
  require_relative "nylas/filter_attributes"
111
118
  # an SDK for interacting with the Nylas API
112
119
  # @see https://docs.nylas.com/reference
@@ -148,4 +155,6 @@ module Nylas
148
155
  Types.registry[:neural_contact_name] = Types::ModelType.new(model: NeuralContactName)
149
156
  Types.registry[:scheduler_config] = Types::ModelType.new(model: SchedulerConfig)
150
157
  Types.registry[:scheduler_time_slot] = Types::ModelType.new(model: SchedulerTimeSlot)
158
+ Types.registry[:job_status] = Types::ModelType.new(model: JobStatus)
159
+ Types.registry[:outbox_message] = Types::ModelType.new(model: OutboxMessage)
151
160
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: nylas
3
3
  version: !ruby/object:Gem::Version
4
- version: 5.6.1
4
+ version: 5.9.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Nylas, Inc.
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-12-13 00:00:00.000000000 Z
11
+ date: 2022-04-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -58,28 +58,28 @@ dependencies:
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 0.52.0
61
+ version: 1.24.1
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 0.52.0
68
+ version: 1.24.1
69
69
  - !ruby/object:Gem::Dependency
70
70
  name: rubocop-rspec
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: 1.20.1
75
+ version: 2.7.0
76
76
  type: :development
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: 1.20.1
82
+ version: 2.7.0
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: overcommit
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -269,6 +269,7 @@ files:
269
269
  - lib/nylas.rb
270
270
  - lib/nylas/account.rb
271
271
  - lib/nylas/api.rb
272
+ - lib/nylas/application_details.rb
272
273
  - lib/nylas/calendar.rb
273
274
  - lib/nylas/calendar_collection.rb
274
275
  - lib/nylas/categorize.rb
@@ -298,6 +299,8 @@ files:
298
299
  - lib/nylas/free_busy_collection.rb
299
300
  - lib/nylas/http_client.rb
300
301
  - lib/nylas/im_address.rb
302
+ - lib/nylas/job_status.rb
303
+ - lib/nylas/job_status_collection.rb
301
304
  - lib/nylas/label.rb
302
305
  - lib/nylas/logging.rb
303
306
  - lib/nylas/message.rb
@@ -323,6 +326,9 @@ files:
323
326
  - lib/nylas/new_message.rb
324
327
  - lib/nylas/nylas_date.rb
325
328
  - lib/nylas/open_hours.rb
329
+ - lib/nylas/outbox.rb
330
+ - lib/nylas/outbox_job_status.rb
331
+ - lib/nylas/outbox_message.rb
326
332
  - lib/nylas/participant.rb
327
333
  - lib/nylas/phone_number.rb
328
334
  - lib/nylas/physical_address.rb
@@ -338,9 +344,11 @@ files:
338
344
  - lib/nylas/scheduler_config.rb
339
345
  - lib/nylas/scheduler_time_slot.rb
340
346
  - lib/nylas/search_collection.rb
347
+ - lib/nylas/send_grid_verified_status.rb
341
348
  - lib/nylas/thread.rb
342
349
  - lib/nylas/time_slot.rb
343
350
  - lib/nylas/timespan.rb
351
+ - lib/nylas/token_info.rb
344
352
  - lib/nylas/types.rb
345
353
  - lib/nylas/version.rb
346
354
  - lib/nylas/web_page.rb
@@ -371,7 +379,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
371
379
  - !ruby/object:Gem::Version
372
380
  version: '0'
373
381
  requirements: []
374
- rubygems_version: 3.2.17
382
+ rubygems_version: 3.3.3
375
383
  signing_key:
376
384
  specification_version: 4
377
385
  summary: Gem for interacting with the Nylas API