inbox 1.1.0 → 1.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +136 -78
- data/lib/api_account.rb +1 -0
- data/lib/inbox.rb +26 -33
- data/lib/message.rb +4 -0
- data/lib/nylas.rb +26 -33
- data/lib/restful_model_collection.rb +2 -0
- data/lib/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 618ad62529f730da5f0097aaba2b3af2e0756368
|
4
|
+
data.tar.gz: 70a5b740506e3160c231d7a52cb2250262864efa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b26bac41d70e09821cd640ddcd50d47814d227ebf56905bdd7a2055689b892a9ee995d797699f2fb5b8ff550aa25c755e11033832cea5cf377c00da2a1e311df
|
7
|
+
data.tar.gz: cb8248ff8c10f93f811ab8b98df7b2c2bd4bd805a4d1551b8cf64ffb57b9626df6f1e7b2ecc9801054c647f68d411bd88a32e6be6c4c838567fdb09d91b58267
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# Nylas REST API Ruby bindings
|
1
|
+
# Nylas REST API Ruby bindings ![Travis build status](https://travis-ci.org/nylas/nylas-ruby.svg?branch=master)
|
2
2
|
|
3
3
|
## Installation
|
4
4
|
|
@@ -10,14 +10,23 @@ And then execute:
|
|
10
10
|
|
11
11
|
bundle
|
12
12
|
|
13
|
-
You don't need to use this repo unless you're planning to modify the gem. If you just want to use the
|
13
|
+
You don't need to use this repo unless you're planning to modify the gem. If you just want to use the Nylas SDK with Ruby bindings, you should run:
|
14
14
|
|
15
15
|
gem install nylas
|
16
16
|
|
17
|
+
### MacOS 10.11 (El Capitan) note
|
18
|
+
|
19
|
+
Apple stopped bundling openssl with MacOS 10.11. However, one of the dependencies of this gem (EventMachine) requires it. If you're on El Capitan and are unable to install the gem, try running the following commands in a terminal:
|
20
|
+
|
21
|
+
```
|
22
|
+
sudo brew install openssl
|
23
|
+
sudo brew link openssl --force
|
24
|
+
gem install nylas
|
25
|
+
```
|
17
26
|
|
18
27
|
##Requirements
|
19
28
|
|
20
|
-
- Ruby 1.
|
29
|
+
- Ruby 1.9.3 or above.
|
21
30
|
|
22
31
|
- rest-client, json, yajl-ruby, em-http-request
|
23
32
|
|
@@ -37,13 +46,17 @@ ruby index.rb
|
|
37
46
|
|
38
47
|
A small example Rails app is included in the `examples/rails` directory. You can run the sample app to see how an authentication flow might be implemented.
|
39
48
|
|
49
|
+
**Note:** To use the sample app you will need to
|
50
|
+
|
51
|
+
1. Replace the Nylas App ID and Secret in `config/environments/development.rb`
|
52
|
+
2. Add the Callback URL `http://localhost:3000/login_callback` to your app in the [developer console](https://developer.nylas.com/console)
|
53
|
+
|
40
54
|
```
|
41
55
|
cd examples/rails
|
56
|
+
bundle install
|
42
57
|
RESTCLIENT_LOG=stdout rails s
|
43
58
|
```
|
44
59
|
|
45
|
-
**Note:** *You will need to replace the Nylas App ID and Secret in `config/environments/development.rb` to use the sample app.*
|
46
|
-
|
47
60
|
## Usage
|
48
61
|
|
49
62
|
### App ID and Secret
|
@@ -101,11 +114,13 @@ If you're using the open-source version of the Nylas Sync Engine or have fewer t
|
|
101
114
|
|
102
115
|
### Account Status
|
103
116
|
|
104
|
-
|
117
|
+
```ruby
|
105
118
|
# Query the status of every account linked to the app
|
106
119
|
nylas = Nylas::API.new(config.nylas_app_id, config.nylas_app_secret, nylas_token)
|
107
120
|
accounts = nylas.accounts
|
108
|
-
accounts.each { |a| [a.account_id, a.sync_state] }
|
121
|
+
accounts.each { |a| [a.account_id, a.sync_state] }
|
122
|
+
# Available fields are: account_id, sync_state, trial, trial_expires and billing_state.
|
123
|
+
# See lib/account.rb for more details.
|
109
124
|
```
|
110
125
|
|
111
126
|
### Fetching Accounts
|
@@ -113,12 +128,11 @@ If you're using the open-source version of the Nylas Sync Engine or have fewer t
|
|
113
128
|
```ruby
|
114
129
|
nylas = Nylas::API.new(config.nylas_app_id, config.nylas_app_secret, nylas_token)
|
115
130
|
|
116
|
-
|
117
|
-
puts nylas.account.
|
118
|
-
puts nylas.account.
|
131
|
+
puts nylas.account.email_address #=> 'alice@example.com'
|
132
|
+
puts nylas.account.provider #=> 'gmail'
|
133
|
+
puts nylas.account.sync_state #=> 'running'
|
119
134
|
```
|
120
135
|
|
121
|
-
|
122
136
|
### Fetching Threads
|
123
137
|
|
124
138
|
```ruby
|
@@ -155,7 +169,6 @@ count = nylas.threads.where(:any_email => 'ben@inboxapp.com').count
|
|
155
169
|
threads = nylas.threads.where(:any_email => 'ben@nylas.com').all
|
156
170
|
```
|
157
171
|
|
158
|
-
|
159
172
|
### Working with Threads
|
160
173
|
|
161
174
|
```ruby
|
@@ -192,8 +205,12 @@ thread.save!
|
|
192
205
|
thread.messages.each do |message|
|
193
206
|
puts message.subject
|
194
207
|
end
|
195
|
-
```
|
196
208
|
|
209
|
+
# List all messages sent by Ben where Helena was cc'ed:
|
210
|
+
thread.messages.where(:from => 'ben@nylas.com').each.select { |t|
|
211
|
+
t.cc.any? {|p| p['email'] == 'helena@nylas.com' }
|
212
|
+
}
|
213
|
+
```
|
197
214
|
|
198
215
|
### Working with Files
|
199
216
|
|
@@ -204,7 +221,7 @@ nylas.files.each do |file|
|
|
204
221
|
end
|
205
222
|
|
206
223
|
# Create a new file
|
207
|
-
file = nylas.files.build(:file => File.new(
|
224
|
+
file = nylas.files.build(:file => File.new('./public/favicon.ico', 'rb'))
|
208
225
|
file.save!
|
209
226
|
|
210
227
|
# Download a file's contents
|
@@ -216,7 +233,6 @@ content = file.download
|
|
216
233
|
The new folders and labels API replaces the now deprecated Tags API. It allows you to apply Gmail labels to whole threads or individual messages and, for providers other than Gmail, to move threads and messages between folders.
|
217
234
|
|
218
235
|
```ruby
|
219
|
-
|
220
236
|
# List labels
|
221
237
|
nylas.labels.each do |label|
|
222
238
|
puts label.display_name, label.id
|
@@ -239,20 +255,60 @@ fld.save!
|
|
239
255
|
fld = nylas.folders.first
|
240
256
|
fld.display_name = 'Renamed folder'
|
241
257
|
fld.save!
|
242
|
-
|
243
258
|
```
|
244
259
|
|
245
260
|
### Working with Messages, Contacts, etc.
|
246
261
|
|
262
|
+
#### Filtering
|
263
|
+
|
247
264
|
Each of the primary collections (contacts, messages, etc.) behave the same way as `threads`. For example, finding messages with a filter is similar to finding threads:
|
248
265
|
|
249
266
|
```ruby
|
250
|
-
|
267
|
+
# Let's get all the attachments Ben sent me.
|
268
|
+
messages = nylas.messages.where(:to => 'ben@nylas.com')
|
269
|
+
|
270
|
+
messages.each do |msg|
|
271
|
+
puts msg.subject
|
272
|
+
|
273
|
+
if msg.files? # => returns true if the message has attachments.
|
274
|
+
# Download them all.
|
275
|
+
msg.files.each |file| do
|
276
|
+
puts file.download
|
277
|
+
end
|
278
|
+
end
|
279
|
+
end
|
280
|
+
```
|
281
|
+
|
282
|
+
The `#where` method accepts a hash of filters, as documented in the [Filters Documentation](https://nylas.com/docs/platform#filters).
|
283
|
+
|
284
|
+
#### Enumerator methods
|
285
|
+
|
286
|
+
Every object API object has an `each` method which returns an `Enumerator` if you don't pass it a block.
|
287
|
+
This allows you to do leverage all that Ruby's `Enumerable` has to offer.
|
288
|
+
For example, this is the previous example rewritten to use an `Enumerator`:
|
289
|
+
|
290
|
+
```ruby
|
291
|
+
messages_with_files = messages.each.select(&:files?)
|
292
|
+
to_download = messages_with_files.flat_map(&:files)
|
293
|
+
to_download.map { |file| puts file.download }
|
251
294
|
```
|
252
295
|
|
253
|
-
|
296
|
+
#### Accessing an object's raw JSON
|
254
297
|
|
255
|
-
|
298
|
+
Sometimes you really need to access the JSON object the API returned. You can use the `#raw_json` property for this:
|
299
|
+
|
300
|
+
```ruby
|
301
|
+
puts contact.raw_json #=>
|
302
|
+
# {
|
303
|
+
# "name": "Ben Bitdiddle",
|
304
|
+
# "email": "ben.bitdiddle@mit.edu",
|
305
|
+
# "id": "8pjz8oj4hkfwgtb46furlh77",
|
306
|
+
# "account_id": "aqau8ta87ndh6cwv0o3ajfoo2",
|
307
|
+
# "object": "contact"
|
308
|
+
# }
|
309
|
+
```
|
310
|
+
|
311
|
+
#### Getting a message's Message-Id, References and In-Reply-To headers
|
256
312
|
|
257
313
|
If you've building your own threading solution, you'll probably need access to a handful of headers like
|
258
314
|
`Message-Id`, `In-Reply-To` and `References`. Here's how to access them:
|
@@ -265,7 +321,7 @@ puts expanded_message.references
|
|
265
321
|
puts expanded_message.in_reply_to
|
266
322
|
```
|
267
323
|
|
268
|
-
|
324
|
+
#### Getting the raw contents of a message
|
269
325
|
|
270
326
|
It's possible to access the unprocessed contents of a message using the raw method:
|
271
327
|
|
@@ -273,15 +329,14 @@ It's possible to access the unprocessed contents of a message using the raw meth
|
|
273
329
|
raw_contents = message.raw
|
274
330
|
```
|
275
331
|
|
276
|
-
|
277
332
|
### Creating and Sending Drafts
|
278
333
|
|
279
334
|
```ruby
|
280
335
|
# Create a new draft
|
281
336
|
draft = nylas.drafts.build(
|
282
337
|
:to => [{:name => 'Ben Gotow', :email => 'ben@nylas.com'}],
|
283
|
-
:subject =>
|
284
|
-
:body =>
|
338
|
+
:subject => 'Sent by Ruby',
|
339
|
+
:body => 'Hi there!<strong>This is HTML</strong>'
|
285
340
|
)
|
286
341
|
|
287
342
|
# Modify attributes as necessary
|
@@ -299,18 +354,18 @@ draft.send!
|
|
299
354
|
# Sometimes sending isn't possible --- handle the exception and
|
300
355
|
# print the error message returned by the SMTP server:
|
301
356
|
begin
|
302
|
-
|
357
|
+
draft.send!
|
303
358
|
rescue Nylas::APIError => e
|
304
|
-
|
305
|
-
|
306
|
-
|
307
|
-
|
359
|
+
puts "Failed with error: #{e.message}"
|
360
|
+
if not e.server_error.nil?
|
361
|
+
puts "The SMTP server replied: #{e.server_error}"
|
362
|
+
end
|
308
363
|
end
|
309
364
|
```
|
310
365
|
|
311
366
|
### Creating an event
|
312
367
|
|
313
|
-
|
368
|
+
```ruby
|
314
369
|
# Every event is attached to a calendar -- get the id of the first calendar
|
315
370
|
calendar_id = nylas.calendars.first.id
|
316
371
|
new_event = nylas.events.build(:calendar_id => calendar_id, :title => 'Coffee?')
|
@@ -318,7 +373,7 @@ new_event = nylas.events.build(:calendar_id => calendar_id, :title => 'Coffee?')
|
|
318
373
|
# Modify attributes as necessary
|
319
374
|
new_event.location = "L'excelsior"
|
320
375
|
|
321
|
-
# Dates are expressed by the
|
376
|
+
# Dates are expressed by the Nylas API as UTC timestamps
|
322
377
|
new_event.when = {:start_time => 1407542195, :end_time => 1407543195}
|
323
378
|
|
324
379
|
# Persist the event --- it's automatically synced back to the Google or Exchange calendar
|
@@ -334,9 +389,10 @@ emailed_invite.rsvp!(status='yes', comment='I will come')
|
|
334
389
|
|
335
390
|
## Using the Delta sync API
|
336
391
|
|
337
|
-
The delta sync API allows fetching all the changes that
|
392
|
+
The delta sync API allows fetching all the changes that occurred after a specific time.
|
393
|
+
[Read this](https://nylas.com/docs/platform/#deltas) for more details about the API.
|
338
394
|
|
339
|
-
|
395
|
+
```ruby
|
340
396
|
# Get an API cursor. Cursors are API objects identifying an individual change.
|
341
397
|
# The latest cursor is the id of the latest change which was applied
|
342
398
|
# to an API object (e.g: a message got read, an event got created, etc.)
|
@@ -344,19 +400,19 @@ cursor = nylas.latest_cursor
|
|
344
400
|
|
345
401
|
last_cursor = nil
|
346
402
|
nylas.deltas(cursor) do |event, object|
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
|
352
|
-
end
|
353
|
-
elsif event == "delete"
|
354
|
-
# In the case of a deletion, the API only returns the ID of the object.
|
355
|
-
# In this case, the Ruby SDK returns a dummy object with only the id field
|
356
|
-
# set.
|
357
|
-
puts "Deleting from collection #{object.class.name}, id: #{object}"
|
403
|
+
if event == "create" or event == "modify"
|
404
|
+
if object.is_a?(Nylas::Contact)
|
405
|
+
puts "#{object.name} - #{object.email}"
|
406
|
+
elsif object.is_a?(Nylas::Event)
|
407
|
+
puts "Event!"
|
358
408
|
end
|
359
|
-
|
409
|
+
elsif event == "delete"
|
410
|
+
# In the case of a deletion, the API only returns the ID of the object.
|
411
|
+
# In this case, the Ruby SDK returns a dummy object with only the id field
|
412
|
+
# set.
|
413
|
+
puts "Deleting from collection #{object.class.name}, id: #{object}"
|
414
|
+
end
|
415
|
+
last_cursor = object.cursor
|
360
416
|
end
|
361
417
|
|
362
418
|
# Don't forget to save the last cursor so that we can pick up changes
|
@@ -368,57 +424,58 @@ save_to_db(last_cursor)
|
|
368
424
|
|
369
425
|
The streaming API will receive deltas in real time, without needing to repeatedly poll. It uses EventMachine for async IO.
|
370
426
|
|
371
|
-
|
427
|
+
```ruby
|
372
428
|
cursor = nylas.latest_cursor
|
373
429
|
|
374
430
|
last_cursor = nil
|
375
431
|
nylas.delta_stream(cursor) do |event, object|
|
376
|
-
|
377
|
-
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
end
|
382
|
-
elsif event == "delete"
|
383
|
-
# In the case of a deletion, the API only returns the ID of the object.
|
384
|
-
# In this case, the Ruby SDK returns a dummy object with only the id field
|
385
|
-
# set.
|
386
|
-
puts "Deleting from collection #{object.class.name}, id: #{object}"
|
432
|
+
if event == "create" or event == "modify"
|
433
|
+
if object.is_a?(Nylas::Contact)
|
434
|
+
puts "#{object.name} - #{object.email}"
|
435
|
+
elsif object.is_a?(Nylas::Event)
|
436
|
+
puts "Event!"
|
387
437
|
end
|
388
|
-
|
438
|
+
elsif event == "delete"
|
439
|
+
# In the case of a deletion, the API only returns the ID of the object.
|
440
|
+
# In this case, the Ruby SDK returns a dummy object with only the id field
|
441
|
+
# set.
|
442
|
+
puts "Deleting from collection #{object.class.name}, id: #{object}"
|
443
|
+
end
|
444
|
+
last_cursor = object.cursor
|
389
445
|
|
390
|
-
|
446
|
+
# This will loop indefintely
|
391
447
|
end
|
392
|
-
|
393
448
|
```
|
394
449
|
|
395
|
-
|
396
450
|
### Exclude changes from a specific type --- get only messages
|
397
|
-
|
451
|
+
|
452
|
+
```ruby
|
398
453
|
nylas.deltas(cursor, exclude=[Nylas::Contact,
|
399
454
|
Nylas::Event,
|
400
455
|
Nylas::File,
|
401
456
|
Nylas::Tag,
|
402
457
|
Nylas::Thread]) do |event, object|
|
403
|
-
if
|
404
|
-
|
405
|
-
|
458
|
+
if ['create', 'modify'].include? event
|
459
|
+
puts object.subject
|
460
|
+
end
|
406
461
|
end
|
407
462
|
```
|
408
463
|
|
409
464
|
### Expand Messages from the Delta stream
|
410
465
|
|
411
466
|
It's possible to ask the Deltas and delta stream API to return [expanded messages](https://nylas.com/docs/platform#expanded_message_view) directly:
|
412
|
-
|
467
|
+
|
468
|
+
```ruby
|
413
469
|
nylas.deltas(cursor, exclude=[Nylas::Contact,
|
414
470
|
Nylas::Event,
|
415
471
|
Nylas::File,
|
416
472
|
Nylas::Tag,
|
417
473
|
Nylas::Thread], expanded_view=true) do |event, object|
|
418
|
-
if
|
419
|
-
|
474
|
+
if ['create', 'modify'].include? event
|
475
|
+
if obj.is_a?(Nylas::Message)
|
420
476
|
puts obj.subject
|
421
477
|
puts obj.message_id
|
478
|
+
end
|
422
479
|
end
|
423
480
|
end
|
424
481
|
```
|
@@ -428,20 +485,18 @@ The Nylas API uses conventional HTTP response codes to indicate success or failu
|
|
428
485
|
|
429
486
|
Code | Error Type | Description
|
430
487
|
--- | --- | ---
|
431
|
-
400 | InvalidRequest | Your request has invalid parameters.
|
432
|
-
403 | AccessDenied | You don't have authorization to access the requested resource or perform the requested action. You may need to re-authenticate the user.
|
433
|
-
404 | ResourceNotFound | The requested resource doesn't exist.
|
434
|
-
500 | APIError | There was an internal error with the Nylas server.
|
488
|
+
400 | `InvalidRequest` | Your request has invalid parameters.
|
489
|
+
403 | `AccessDenied` | You don't have authorization to access the requested resource or perform the requested action. You may need to re-authenticate the user.
|
490
|
+
404 | `ResourceNotFound` | The requested resource doesn't exist.
|
491
|
+
500 | `APIError` | There was an internal error with the Nylas server.
|
435
492
|
|
436
493
|
A few additional exceptions are raised by the `draft.send!` method if your draft couldn't be sent.
|
437
494
|
|
438
495
|
Code | Error Type | Description
|
439
496
|
--- | --- | ---
|
440
|
-
402 | MessageRejected| The message was syntactically valid, but rejected for delivery by the mail server.
|
441
|
-
429 | SendingQuotaExceeded | The user has exceeded their daily sending quota.
|
442
|
-
503 | ServiceUnavailable | There was a temporary error establishing a connection to the user's mail server.
|
443
|
-
|
444
|
-
|
497
|
+
402 | `MessageRejected` | The message was syntactically valid, but rejected for delivery by the mail server.
|
498
|
+
429 | `SendingQuotaExceeded` | The user has exceeded their daily sending quota.
|
499
|
+
503 | `ServiceUnavailable` | There was a temporary error establishing a connection to the user's mail server.
|
445
500
|
|
446
501
|
## Open-Source Sync Engine
|
447
502
|
|
@@ -491,5 +546,8 @@ If it's your first time updating the ruby gems, you may be prompted for the user
|
|
491
546
|
Because it's critical that we don't break the SDK for our customers, we require releasers to run some tests before releasing a new version of the gem. The test programs are located in the test/ directory. To set up them up, you'll need to copy `tests/credentials.rb.templates` as `test/credentials.rb` and edit the `APP_ID` and `APP_SECRET` with a working Nylas API app id and secret. You also need to set up a `/callback` URL in the Nylas admin panel.
|
492
547
|
|
493
548
|
You can run the programs like this:
|
494
|
-
|
495
|
-
|
549
|
+
|
550
|
+
```shell
|
551
|
+
cd tests && ruby -I../lib auth.rb
|
552
|
+
cd tests && ruby -I../lib system.rb
|
553
|
+
```
|
data/lib/api_account.rb
CHANGED
data/lib/inbox.rb
CHANGED
@@ -21,15 +21,14 @@ require 'restful_model'
|
|
21
21
|
require 'restful_model_collection'
|
22
22
|
require 'version'
|
23
23
|
|
24
|
-
|
25
24
|
module Inbox
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
class APIError <
|
25
|
+
Error = Class.new(::StandardError)
|
26
|
+
AccessDenied = Class.new(Error)
|
27
|
+
ResourceNotFound = Class.new(Error)
|
28
|
+
NoAuthToken = Class.new(Error)
|
29
|
+
UnexpectedAccountAction = Class.new(Error)
|
30
|
+
UnexpectedResponse = Class.new(Error)
|
31
|
+
class APIError < Error
|
33
32
|
attr_accessor :error_type
|
34
33
|
attr_accessor :server_error
|
35
34
|
|
@@ -39,10 +38,10 @@ module Inbox
|
|
39
38
|
self.server_error = server_error
|
40
39
|
end
|
41
40
|
end
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
41
|
+
InvalidRequest = Class.new(APIError)
|
42
|
+
MessageRejected = Class.new(APIError)
|
43
|
+
SendingQuotaExceeded = Class.new(APIError)
|
44
|
+
ServiceUnavailable = Class.new(APIError)
|
46
45
|
|
47
46
|
def self.interpret_http_status(result)
|
48
47
|
# Handle HTTP errors and RestClient errors
|
@@ -50,29 +49,22 @@ module Inbox
|
|
50
49
|
raise AccessDenied.new if result.code.to_i == 403
|
51
50
|
end
|
52
51
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
exc = ResourceNotFound
|
62
|
-
elsif http_code == 429
|
63
|
-
exc = SendingQuotaExceeded
|
64
|
-
elsif http_code == 503
|
65
|
-
exc = ServiceUnavailable
|
66
|
-
else
|
67
|
-
exc = APIError
|
68
|
-
end
|
52
|
+
HTTP_CODE_TO_EXCEPTIONS = {
|
53
|
+
400 => InvalidRequest,
|
54
|
+
402 => MessageRejected,
|
55
|
+
403 => AccessDenied,
|
56
|
+
404 => ResourceNotFound,
|
57
|
+
429 => SendingQuotaExceeded,
|
58
|
+
503 => ServiceUnavailable
|
59
|
+
}.freeze
|
69
60
|
|
70
|
-
|
61
|
+
def self.http_code_to_exception(http_code)
|
62
|
+
HTTP_CODE_TO_EXCEPTIONS.fetch(http_code, APIError)
|
71
63
|
end
|
72
64
|
|
73
65
|
def self.interpret_response(result, result_content, options = {})
|
74
66
|
# Handle HTTP errors
|
75
|
-
|
67
|
+
self.interpret_http_status(result)
|
76
68
|
|
77
69
|
# Handle content expectation errors
|
78
70
|
raise UnexpectedResponse.new if options[:expected_class] && result_content.empty?
|
@@ -283,7 +275,8 @@ module Inbox
|
|
283
275
|
end
|
284
276
|
|
285
277
|
def deltas(cursor, exclude_types=[], expanded_view=false)
|
286
|
-
|
278
|
+
return enum_for(:deltas, cursor, exclude_types, expanded_view) unless block_given?
|
279
|
+
|
287
280
|
exclude_string = ""
|
288
281
|
|
289
282
|
if exclude_types.any?
|
@@ -292,7 +285,7 @@ module Inbox
|
|
292
285
|
|
293
286
|
# loop and yield deltas until we've come to the end.
|
294
287
|
loop do
|
295
|
-
path = self.url_for_path("/delta?cursor=#{cursor}#{exclude_string}")
|
288
|
+
path = self.url_for_path("/delta?exclude_folders=false&cursor=#{cursor}#{exclude_string}")
|
296
289
|
if expanded_view
|
297
290
|
path += '&view=expanded'
|
298
291
|
end
|
@@ -345,7 +338,7 @@ module Inbox
|
|
345
338
|
end
|
346
339
|
|
347
340
|
# loop and yield deltas indefinitely.
|
348
|
-
path = self.url_for_path("/delta/streaming?cursor=#{cursor}#{exclude_string}")
|
341
|
+
path = self.url_for_path("/delta/streaming?exclude_folders=false&cursor=#{cursor}#{exclude_string}")
|
349
342
|
if expanded_view
|
350
343
|
path += '&view=expanded'
|
351
344
|
end
|
data/lib/message.rb
CHANGED
@@ -71,6 +71,10 @@ module Inbox
|
|
71
71
|
@files ||= RestfulModelCollection.new(File, @_api, {:message_id=>@id})
|
72
72
|
end
|
73
73
|
|
74
|
+
def files?
|
75
|
+
!@raw_json['files'].empty?
|
76
|
+
end
|
77
|
+
|
74
78
|
def raw
|
75
79
|
model = nil
|
76
80
|
collection = RestfulModelCollection.new(Message, @_api, {:message_id=>@id})
|
data/lib/nylas.rb
CHANGED
@@ -21,15 +21,14 @@ require 'restful_model'
|
|
21
21
|
require 'restful_model_collection'
|
22
22
|
require 'version'
|
23
23
|
|
24
|
-
|
25
24
|
module Inbox
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
class APIError <
|
25
|
+
Error = Class.new(::StandardError)
|
26
|
+
AccessDenied = Class.new(Error)
|
27
|
+
ResourceNotFound = Class.new(Error)
|
28
|
+
NoAuthToken = Class.new(Error)
|
29
|
+
UnexpectedAccountAction = Class.new(Error)
|
30
|
+
UnexpectedResponse = Class.new(Error)
|
31
|
+
class APIError < Error
|
33
32
|
attr_accessor :error_type
|
34
33
|
attr_accessor :server_error
|
35
34
|
|
@@ -39,10 +38,10 @@ module Inbox
|
|
39
38
|
self.server_error = server_error
|
40
39
|
end
|
41
40
|
end
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
41
|
+
InvalidRequest = Class.new(APIError)
|
42
|
+
MessageRejected = Class.new(APIError)
|
43
|
+
SendingQuotaExceeded = Class.new(APIError)
|
44
|
+
ServiceUnavailable = Class.new(APIError)
|
46
45
|
|
47
46
|
def self.interpret_http_status(result)
|
48
47
|
# Handle HTTP errors and RestClient errors
|
@@ -50,29 +49,22 @@ module Inbox
|
|
50
49
|
raise AccessDenied.new if result.code.to_i == 403
|
51
50
|
end
|
52
51
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
exc = ResourceNotFound
|
62
|
-
elsif http_code == 429
|
63
|
-
exc = SendingQuotaExceeded
|
64
|
-
elsif http_code == 503
|
65
|
-
exc = ServiceUnavailable
|
66
|
-
else
|
67
|
-
exc = APIError
|
68
|
-
end
|
52
|
+
HTTP_CODE_TO_EXCEPTIONS = {
|
53
|
+
400 => InvalidRequest,
|
54
|
+
402 => MessageRejected,
|
55
|
+
403 => AccessDenied,
|
56
|
+
404 => ResourceNotFound,
|
57
|
+
429 => SendingQuotaExceeded,
|
58
|
+
503 => ServiceUnavailable
|
59
|
+
}.freeze
|
69
60
|
|
70
|
-
|
61
|
+
def self.http_code_to_exception(http_code)
|
62
|
+
HTTP_CODE_TO_EXCEPTIONS.fetch(http_code, APIError)
|
71
63
|
end
|
72
64
|
|
73
65
|
def self.interpret_response(result, result_content, options = {})
|
74
66
|
# Handle HTTP errors
|
75
|
-
|
67
|
+
self.interpret_http_status(result)
|
76
68
|
|
77
69
|
# Handle content expectation errors
|
78
70
|
raise UnexpectedResponse.new if options[:expected_class] && result_content.empty?
|
@@ -283,7 +275,8 @@ module Inbox
|
|
283
275
|
end
|
284
276
|
|
285
277
|
def deltas(cursor, exclude_types=[], expanded_view=false)
|
286
|
-
|
278
|
+
return enum_for(:deltas, cursor, exclude_types, expanded_view) unless block_given?
|
279
|
+
|
287
280
|
exclude_string = ""
|
288
281
|
|
289
282
|
if exclude_types.any?
|
@@ -292,7 +285,7 @@ module Inbox
|
|
292
285
|
|
293
286
|
# loop and yield deltas until we've come to the end.
|
294
287
|
loop do
|
295
|
-
path = self.url_for_path("/delta?cursor=#{cursor}#{exclude_string}")
|
288
|
+
path = self.url_for_path("/delta?exclude_folders=false&cursor=#{cursor}#{exclude_string}")
|
296
289
|
if expanded_view
|
297
290
|
path += '&view=expanded'
|
298
291
|
end
|
@@ -345,7 +338,7 @@ module Inbox
|
|
345
338
|
end
|
346
339
|
|
347
340
|
# loop and yield deltas indefinitely.
|
348
|
-
path = self.url_for_path("/delta/streaming?cursor=#{cursor}#{exclude_string}")
|
341
|
+
path = self.url_for_path("/delta/streaming?exclude_folders=false&cursor=#{cursor}#{exclude_string}")
|
349
342
|
if expanded_view
|
350
343
|
path += '&view=expanded'
|
351
344
|
end
|
data/lib/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: inbox
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1
|
4
|
+
version: 1.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ben Gotow
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2015-
|
13
|
+
date: 2015-11-20 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rest-client
|