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
@@ -0,0 +1,111 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NylasV2
4
+ Error = Class.new(::StandardError)
5
+
6
+ class ModelActionError < Error; end
7
+ class ModelNotFilterableError < ModelActionError; end
8
+ class ModelNotCreatableError < ModelActionError; end
9
+ class ModelNotShowableError < ModelActionError; end
10
+ class ModelNotAvailableAsRawError < ModelActionError; end
11
+ class ModelNotListableError < ModelActionError; end
12
+ class ModelNotFilterableError < ModelActionError; end
13
+ class ModelNotSearchableError < ModelActionError; end
14
+ class ModelNotUpdatableError < ModelActionError; end
15
+ class ModelNotDestroyableError < ModelActionError; end
16
+
17
+ class JsonParseError < Error; end
18
+
19
+ # Raised when attempting to set a field that is not on a model with mass assignment
20
+ class ModelMissingFieldError < ModelActionError
21
+ def initialize(field, model)
22
+ super("#{field} is not a valid attribute for #{model.class.name}")
23
+ end
24
+ end
25
+
26
+ # Indicates that a given method needs an access token to work.
27
+ class NoAuthToken < Error
28
+ def initialize(method_name)
29
+ super "No access token was provided and the #{method_name} method requires one"
30
+ end
31
+ end
32
+
33
+ UnexpectedAccountAction = Class.new(Error)
34
+ UnexpectedResponse = Class.new(Error)
35
+
36
+ # Base class to inflate the standard errors returned from the Nylas API
37
+ class APIError < Error
38
+ attr_accessor :type
39
+ attr_accessor :message
40
+ attr_accessor :server_error
41
+
42
+ def initialize(type, message, server_error = nil)
43
+ super(message)
44
+ self.type = type
45
+ self.message = message
46
+ self.server_error = server_error
47
+ end
48
+
49
+ def self.parse_error_response(response)
50
+ new(
51
+ response["type"],
52
+ response["message"],
53
+ response["server_error"]
54
+ )
55
+ end
56
+ end
57
+
58
+ # Error class representing a 429 error response, with details on the rate limit
59
+ class RateLimitError < APIError
60
+ attr_accessor :rate_limit
61
+ attr_accessor :rate_limit_reset
62
+
63
+ RATE_LIMIT_LIMIT_HEADER = "x_ratelimit_limit"
64
+ RATE_LIMIT_RESET_HEADER = "x_ratelimit_reset"
65
+
66
+ def initialize(type, message, server_error = nil, rate_limit = nil, rate_limit_reset = nil)
67
+ super(type, message, server_error)
68
+ self.rate_limit = rate_limit
69
+ self.rate_limit_reset = rate_limit_reset
70
+ end
71
+
72
+ def self.parse_error_response(response)
73
+ rate_limit, rate_limit_rest = extract_rate_limit_details(response)
74
+
75
+ new(
76
+ response["type"],
77
+ response["message"],
78
+ response["server_error"],
79
+ rate_limit,
80
+ rate_limit_rest
81
+ )
82
+ end
83
+
84
+ def self.extract_rate_limit_details(response)
85
+ return nil, nil unless response.respond_to?(:headers)
86
+
87
+ rate_limit = response.headers[RATE_LIMIT_LIMIT_HEADER.to_sym].to_i
88
+ rate_limit_rest = response.headers[RATE_LIMIT_RESET_HEADER.to_sym].to_i
89
+
90
+ [rate_limit, rate_limit_rest]
91
+ end
92
+
93
+ private_class_method :extract_rate_limit_details
94
+ end
95
+
96
+ AccessDenied = Class.new(APIError)
97
+ ResourceNotFound = Class.new(APIError)
98
+ MethodNotAllowed = Class.new(APIError)
99
+ InvalidRequest = Class.new(APIError)
100
+ UnauthorizedRequest = Class.new(APIError)
101
+ ResourceRemoved = Class.new(APIError)
102
+ TeapotError = Class.new(APIError)
103
+ RequestTimedOut = Class.new(APIError)
104
+ MessageRejected = Class.new(APIError)
105
+ SendingQuotaExceeded = Class.new(RateLimitError)
106
+ ServiceUnavailable = Class.new(APIError)
107
+ BadGateway = Class.new(APIError)
108
+ InternalError = Class.new(APIError)
109
+ EndpointNotYetImplemented = Class.new(APIError)
110
+ MailProviderError = Class.new(APIError)
111
+ end
@@ -0,0 +1,141 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NylasV2
4
+ # Structure to represent a the Event Schema.
5
+ # @see https://docs.nylas.com/reference#events
6
+ class Event
7
+ include Model
8
+ self.resources_path = "/events"
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, read_only: true
19
+ attribute :object, :string, read_only: true
20
+ attribute :account_id, :string, read_only: true
21
+ attribute :calendar_id, :string
22
+ attribute :master_event_id, :string
23
+ attribute :message_id, :string
24
+ attribute :ical_uid, :string
25
+ attribute :event_collection_id, :string
26
+
27
+ attribute :capacity, :integer
28
+ attribute :busy, :boolean
29
+ attribute :description, :string
30
+ attribute :location, :string
31
+ attribute :owner, :string
32
+ attribute :recurrence, :recurrence
33
+ has_n_of_attribute :participants, :participant
34
+ attribute :read_only, :boolean
35
+ attribute :status, :string
36
+ attribute :title, :string
37
+ attribute :when, :when
38
+ attribute :metadata, :hash
39
+ attribute :conferencing, :event_conferencing
40
+ has_n_of_attribute :notifications, :event_notification
41
+ has_n_of_attribute :round_robin_order, :string
42
+ attribute :original_start_time, :unix_timestamp
43
+ attribute :reminder_minutes, :string
44
+ attribute :reminder_method, :string
45
+ attribute :job_status_id, :string, read_only: true
46
+ attribute :visibility, :string
47
+
48
+ attr_accessor :notify_participants
49
+
50
+ def busy?
51
+ busy
52
+ end
53
+
54
+ def read_only?
55
+ read_only
56
+ end
57
+
58
+ def save
59
+ validate
60
+ format_reminder_minutes
61
+
62
+ super
63
+ end
64
+
65
+ def rsvp(status, notify_participants:)
66
+ rsvp = Rsvp.new(api: api, status: status, notify_participants: notify_participants,
67
+ event_id: id, account_id: account_id)
68
+ rsvp.save
69
+ end
70
+
71
+ # Generate an ICS file server-side, from an Event
72
+ # @param ical_uid [String] Unique identifier used events across calendaring systems
73
+ # @param method [String] Description of invitation and response methods for attendees
74
+ # @param prodid [String] Company-specific unique product identifier
75
+ # @return [String] String for writing directly into an ICS file
76
+ def generate_ics(ical_uid: nil, method: nil, prodid: nil)
77
+ raise ArgumentError, "Cannot generate an ICS file for an event without a Calendar ID or when set" unless
78
+ calendar_id && self.when
79
+
80
+ payload = build_ics_event_payload(ical_uid, method, prodid)
81
+ response = api.execute(
82
+ method: :post,
83
+ path: "#{resources_path}/to-ics",
84
+ payload: JSON.dump(payload)
85
+ )
86
+
87
+ response[:ics]
88
+ end
89
+
90
+ private
91
+
92
+ def validate
93
+ if conferencing
94
+ body = to_h
95
+ if body.dig(:conferencing, :details) && body.dig(:conferencing, :autocreate)
96
+ raise ArgumentError, "Cannot set both 'details' and 'autocreate' in conferencing object."
97
+ end
98
+ end
99
+ return unless capacity && capacity != -1 && participants && participants.length > capacity
100
+
101
+ raise ArgumentError, "The number of participants in the event exceeds the set capacity."
102
+ end
103
+
104
+ def build_ics_event_payload(ical_uid, method, prodid)
105
+ payload = {}
106
+ if id
107
+ payload[:event_id] = id
108
+ else
109
+ payload = to_h(enforce_read_only: true)
110
+ end
111
+ ics_options = build_ics_options_payload(ical_uid, method, prodid)
112
+ payload["ics_options"] = ics_options unless ics_options.empty?
113
+ payload
114
+ end
115
+
116
+ def build_ics_options_payload(ical_uid, method, prodid)
117
+ payload = {}
118
+ payload["ical_uid"] = ical_uid if ical_uid
119
+ payload["method"] = method if method
120
+ payload["prodid"] = prodid if prodid
121
+ payload
122
+ end
123
+
124
+ # Formats the reminder minute field to match the API format: "[%d]"
125
+ def format_reminder_minutes
126
+ return if reminder_minutes.nil? || reminder_minutes.empty? || reminder_minutes.match(/\[\d+\]/)
127
+
128
+ self.reminder_minutes = "[#{reminder_minutes}]"
129
+ end
130
+
131
+ def query_params
132
+ if notify_participants.nil?
133
+ {}
134
+ else
135
+ {
136
+ notify_participants: notify_participants
137
+ }
138
+ end
139
+ end
140
+ end
141
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NylasV2
4
+ # Syntactical sugar methods for some of the Event's filters
5
+ # @see https://docs.nylas.com/reference#get-events
6
+ class EventCollection < Collection
7
+ def expand_recurring
8
+ where(expand_recurring: true)
9
+ end
10
+
11
+ def show_cancelled
12
+ where(show_cancelled: true)
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,12 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NylasV2
4
+ # Structure to represent the Event Conferencing object
5
+ # @see https://developer.nylas.com/docs/connectivity/calendar/conference-sync-beta
6
+ class EventConferencing
7
+ include Model::Attributable
8
+ attribute :provider, :string
9
+ attribute :details, :event_conferencing_details
10
+ attribute :autocreate, :event_conferencing_autocreate
11
+ end
12
+ end
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NylasV2
4
+ # Structure to represent the autocreate object within the Event Conferencing object
5
+ # @see https://developer.nylas.com/docs/connectivity/calendar/conference-sync-beta
6
+ class EventConferencingAutocreate
7
+ include Model::Attributable
8
+ attribute :settings, :hash, default: {}
9
+ end
10
+ end
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NylasV2
4
+ # Structure to represent the details object within the Event Conferencing object
5
+ # @see https://developer.nylas.com/docs/connectivity/calendar/conference-sync-beta
6
+ class EventConferencingDetails
7
+ include Model::Attributable
8
+ attribute :meeting_code, :string
9
+ attribute :password, :string
10
+ attribute :pin, :string
11
+ attribute :url, :string
12
+ has_n_of_attribute :phone, :string
13
+ end
14
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NylasV2
4
+ # Structure to represent the Event Notification object
5
+ # @see https://developer.nylas.com/docs/connectivity/calendar/event-notifications
6
+ class EventNotification
7
+ include Model::Attributable
8
+
9
+ attribute :type, :string
10
+ attribute :minutes_before_event, :integer
11
+ attribute :url, :string
12
+ attribute :payload, :string
13
+ attribute :subject, :string
14
+ attribute :body, :string
15
+ attribute :message, :string
16
+ end
17
+ end
@@ -0,0 +1,75 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NylasV2
4
+ # Structure to represent a the File Schema.
5
+ # @see https://docs.nylas.com/reference#events
6
+ class File
7
+ include Model
8
+ self.resources_path = "/files"
9
+ self.creatable = true
10
+ self.listable = true
11
+ self.showable = true
12
+ self.filterable = true
13
+ self.destroyable = true
14
+ self.id_listable = true
15
+ self.countable = true
16
+
17
+ attribute :id, :string
18
+ attribute :account_id, :string
19
+ attribute :content_id, :string
20
+ has_n_of_attribute :message_ids, :string
21
+
22
+ attribute :object, :string
23
+
24
+ attribute :content_type, :string
25
+ attribute :filename, :string
26
+ attribute :size, :integer
27
+ attribute :content_disposition, :string
28
+
29
+ attr_accessor :file
30
+
31
+ # Downloads and caches a local copy of the file.
32
+ # @return [Tempfile] - Local copy of the file
33
+ def download
34
+ return file if file
35
+
36
+ self.file = retrieve_file
37
+ end
38
+
39
+ # Redownloads a file even if it's been cached. Closes and unlinks the tempfile to help memory usage.
40
+ def download!
41
+ return download if file.nil?
42
+
43
+ file.close
44
+ file.unlink
45
+ self.file = nil
46
+ download
47
+ end
48
+
49
+ def create
50
+ save
51
+ end
52
+
53
+ def save
54
+ raise ModelNotUpdatableError if persisted?
55
+
56
+ response = api.execute(path: "/files", method: :post, headers: { multipart: true },
57
+ payload: { file: file })
58
+ attributes.merge(response.first)
59
+ true
60
+ end
61
+
62
+ private
63
+
64
+ def retrieve_file
65
+ response = api.get(path: "#{resource_path}/download")
66
+ filename = response.headers.fetch(:content_disposition, "").gsub("attachment; filename=", "")
67
+ # The returned filename can be longer than 256 chars which isn't supported by rb_sysopen.
68
+ # 128 chars here is more than enough given that TempFile ensure the filename will be unique.
69
+ temp_file = Tempfile.new(filename[0..127], encoding: "ascii-8bit")
70
+ temp_file.write(response.body)
71
+ temp_file.seek(0)
72
+ temp_file
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,25 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NylasV2
4
+ # Methods to check and raise error if extra attributes are present
5
+ class FilterAttributes
6
+ def initialize(attributes:, allowed_attributes:)
7
+ @attributes = attributes
8
+ @allowed_attributes = allowed_attributes
9
+ end
10
+
11
+ def check
12
+ return if extra_attributes.empty?
13
+
14
+ raise ArgumentError, "Only #{allowed_attributes} are allowed to be sent"
15
+ end
16
+
17
+ private
18
+
19
+ attr_reader :attributes, :allowed_attributes
20
+
21
+ def extra_attributes
22
+ attributes - allowed_attributes
23
+ end
24
+ end
25
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NylasV2
4
+ # Structure to represent the Folder Schema
5
+ # @see https://docs.nylas.com/reference#folders
6
+ class Folder
7
+ include Model
8
+ self.resources_path = "/folders"
9
+ self.creatable = true
10
+ self.listable = true
11
+ self.showable = true
12
+ self.filterable = false
13
+ self.updatable = true
14
+ self.destroyable = true
15
+ self.id_listable = true
16
+ self.countable = true
17
+
18
+ attribute :id, :string, read_only: true
19
+ attribute :account_id, :string, read_only: true
20
+ attribute :object, :string, read_only: true
21
+
22
+ attribute :name, :string
23
+ attribute :display_name, :string
24
+ attribute :job_status_id, :string, read_only: true
25
+ end
26
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NylasV2
4
+ # Query free/busy information for a calendar during a certain time period
5
+ # @see https://docs.nylas.com/reference#calendars-free-busy
6
+ class FreeBusy
7
+ include Model::Attributable
8
+
9
+ attribute :email, :string
10
+ attribute :object, :string
11
+ has_n_of_attribute :time_slots, :time_slot
12
+ end
13
+ end
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module NylasV2
4
+ # Helper to get and build `FreeBusy` objects
5
+ class FreeBusyCollection
6
+ extend Forwardable
7
+ def_delegators :each, :map, :select, :reject, :to_a, :take
8
+ def_delegators :to_a, :first, :last, :[]
9
+
10
+ def initialize(emails:, start_time:, end_time:, api:)
11
+ @api = api
12
+ @emails = emails
13
+ @start_time = start_time
14
+ @end_time = end_time
15
+ end
16
+
17
+ def each
18
+ return enum_for(:each) unless block_given?
19
+
20
+ execute.each do |result|
21
+ yield(FreeBusy.new(**result))
22
+ end
23
+ end
24
+
25
+ private
26
+
27
+ attr_reader :api, :emails, :start_time, :end_time
28
+
29
+ PATH = "/calendars/free-busy"
30
+ private_constant :PATH
31
+
32
+ def execute
33
+ api.execute(
34
+ method: :post,
35
+ path: PATH,
36
+ payload: payload
37
+ )
38
+ end
39
+
40
+ def payload
41
+ JSON.dump(
42
+ emails: emails,
43
+ start_time: start_time,
44
+ end_time: end_time
45
+ )
46
+ end
47
+ end
48
+ end