nylas 5.2.0 → 5.3.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: c6b0265bb93198dcc5494a819c68a5261703a143a4fe320a4662cc6c65aa2e94
4
- data.tar.gz: ee107c7cacfb2b7e2b099fd675c20c02700def063e1ccdd6b46923448da9e25b
3
+ metadata.gz: 8ab5c418509c447497fbd6106eb6e01fb7c23af451bf8150584b9bcf4e1ce736
4
+ data.tar.gz: 6827492459317c848f6f89c748a1cf5f5858506b83a578f53dbb4169010779ad
5
5
  SHA512:
6
- metadata.gz: 4e7aca3de25b0e2847011c4b190960405a214e8905429ba2743f9d3bd068d41e60cb36ad7365d298f685eb47979c30df0397996212d784c26e20e54f32b874aa
7
- data.tar.gz: 8fc30003aa6609694e5f2a7aedf2c949e2f191c45a0edea6045669d918c3ff88cdfc837046ec409815f67c255b7a1184586532878988166cd39865c8517f00fe
6
+ metadata.gz: 593d58ed82147ee51b00f90ed0e619eb4a6680b07cc8bae04eeba0809026e2e24ecce2565292c026bd2d164fba8a6a76f67768bf362c35c8e50bc0efbbe61da1
7
+ data.tar.gz: 10ed94be5d4e2c785ef92d32495301857f6c193e85e5087e96e8c2826b379219833f6db07c669c38fb7be573f77376748a6b323c1af46952c10853bf50e04233
data/lib/nylas.rb CHANGED
@@ -75,6 +75,19 @@ require_relative "nylas/raw_message"
75
75
  require_relative "nylas/thread"
76
76
  require_relative "nylas/webhook"
77
77
 
78
+ # Neural specific types
79
+ require_relative "nylas/neural"
80
+ require_relative "nylas/neural_sentiment_analysis"
81
+ require_relative "nylas/neural_ocr"
82
+ require_relative "nylas/neural_categorizer"
83
+ require_relative "nylas/neural_clean_conversation"
84
+ require_relative "nylas/neural_contact_link"
85
+ require_relative "nylas/neural_contact_name"
86
+ require_relative "nylas/neural_signature_contact"
87
+ require_relative "nylas/neural_signature_extraction"
88
+ require_relative "nylas/neural_message_options"
89
+ require_relative "nylas/categorize"
90
+
78
91
  require_relative "nylas/native_authentication"
79
92
 
80
93
  require_relative "nylas/http_client"
@@ -110,4 +123,9 @@ module Nylas
110
123
  Types.registry[:contact_group] = Types::ModelType.new(model: ContactGroup)
111
124
  Types.registry[:when] = Types::ModelType.new(model: When)
112
125
  Types.registry[:time_slot] = Types::ModelType.new(model: TimeSlot)
126
+ Types.registry[:neural] = Types::ModelType.new(model: Neural)
127
+ Types.registry[:categorize] = Types::ModelType.new(model: Categorize)
128
+ Types.registry[:neural_signature_contact] = Types::ModelType.new(model: NeuralSignatureContact)
129
+ Types.registry[:neural_contact_link] = Types::ModelType.new(model: NeuralContactLink)
130
+ Types.registry[:neural_contact_name] = Types::ModelType.new(model: NeuralContactName)
113
131
  end
data/lib/nylas/api.rb CHANGED
@@ -126,6 +126,11 @@ module Nylas
126
126
  @room_resources ||= Collection.new(model: RoomResource, api: self)
127
127
  end
128
128
 
129
+ # @return[Neural] A {Neural} object that provides
130
+ def neural
131
+ @neural ||= Neural.new(api: self)
132
+ end
133
+
129
134
  # Revokes access to the Nylas API for the given access token
130
135
  # @return [Boolean]
131
136
  def revoke(access_token)
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nylas
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
data/lib/nylas/delta.rb CHANGED
@@ -15,6 +15,8 @@ module Nylas
15
15
  attribute :namespace_id, :string
16
16
  attribute :account_id, :string
17
17
 
18
+ attribute :headers, :message_headers
19
+
18
20
  attribute :date, :unix_timestamp
19
21
  attribute :metadata, :hash
20
22
  attribute :object_attributes, :hash
@@ -5,7 +5,7 @@ module Nylas
5
5
 
6
6
  # Plain HTTP client that can be used to interact with the Nylas API sans any type casting.
7
7
  class HttpClient # rubocop:disable Metrics/ClassLength
8
- HTTP_SUCCESS_CODES = [200, 302].freeze
8
+ HTTP_SUCCESS_CODES = [200, 201, 302].freeze
9
9
 
10
10
  HTTP_CODE_TO_EXCEPTIONS = {
11
11
  400 => InvalidRequest,
@@ -92,7 +92,12 @@ module Nylas
92
92
  content_type = response.headers[:content_type].downcase
93
93
  end
94
94
 
95
- response = parse_response(response) if content_type == "application/json"
95
+ begin
96
+ response = parse_response(response) if content_type == "application/json"
97
+ rescue Nylas::JsonParseError
98
+ handle_failed_response(result: result, response: response)
99
+ raise
100
+ end
96
101
 
97
102
  handle_failed_response(result: result, response: response)
98
103
  response
@@ -139,7 +144,7 @@ module Nylas
139
144
  "X-Nylas-Client-Id" => @app_id,
140
145
  "Nylas-API-Version" => SUPPORTED_API_VERSION,
141
146
  "User-Agent" => "Nylas Ruby SDK #{Nylas::VERSION} - #{RUBY_VERSION}",
142
- "Content-types" => "application/json"
147
+ "Content-type" => "application/json"
143
148
  }
144
149
  end
145
150
 
@@ -179,12 +184,12 @@ module Nylas
179
184
  return if HTTP_SUCCESS_CODES.include?(http_code)
180
185
 
181
186
  exception = HTTP_CODE_TO_EXCEPTIONS.fetch(http_code, APIError)
182
- parsed_response = parse_response(response)
187
+ raise exception.new(http_code, response) unless response.is_a?(Hash)
183
188
 
184
189
  raise exception.new(
185
- parsed_response[:type],
186
- parsed_response[:message],
187
- parsed_response.fetch(:server_error, nil)
190
+ response[:type],
191
+ response[:message],
192
+ response.fetch(:server_error, nil)
188
193
  )
189
194
  end
190
195
 
@@ -63,6 +63,21 @@ module Nylas
63
63
  end
64
64
  end
65
65
 
66
+ # Allows a class to inherit parent's attributes
67
+ def inherit_attributes
68
+ return if superclass.nil?
69
+
70
+ parent_attributes = superclass.attribute_definitions
71
+ parent_attributes.each do |parent_attribute|
72
+ name = parent_attribute[0]
73
+ attr = parent_attribute[1]
74
+ next if attribute_definitions.key?(name)
75
+
76
+ attribute_definitions[name] = attr
77
+ define_accessors(name)
78
+ end
79
+ end
80
+
66
81
  def attribute_definitions
67
82
  @attribute_definitions ||= Registry.new
68
83
  end
@@ -0,0 +1,87 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nylas
4
+ # Class containing methods for accessing Neural API features.
5
+ # @see https://developer.nylas.com/docs/intelligence/
6
+ class Neural
7
+ attr_accessor :api
8
+
9
+ def initialize(api:)
10
+ self.api = api
11
+ end
12
+
13
+ def sentiment_analysis_message(message_ids)
14
+ body = { message_id: message_ids }
15
+ response = request(NeuralSentimentAnalysis.resources_path, body)
16
+
17
+ collection = []
18
+ response.each do |sentiment|
19
+ collection.push(NeuralSentimentAnalysis.new(**sentiment.merge(api: api)))
20
+ end
21
+ collection
22
+ end
23
+
24
+ def sentiment_analysis_text(text)
25
+ body = { text: text }
26
+ NeuralSentimentAnalysis.new(**request(NeuralSentimentAnalysis.resources_path, body).merge(api: api))
27
+ end
28
+
29
+ def extract_signature(message_ids, options = nil)
30
+ body = { message_id: message_ids }
31
+ body = body.merge(options) unless options.nil?
32
+ response = request(NeuralSignatureExtraction.resources_path, body)
33
+
34
+ collection = []
35
+ response.each do |signature|
36
+ collection.push(NeuralSignatureExtraction.new(**signature.merge(api: api)))
37
+ end
38
+ collection
39
+ end
40
+
41
+ def ocr_request(file_id, pages = nil)
42
+ body = { file_id: file_id }
43
+ body[:pages] = pages unless pages.nil?
44
+
45
+ NeuralOcr.new(**request(NeuralOcr.resources_path, body).merge(api: api))
46
+ end
47
+
48
+ def categorize(message_ids)
49
+ body = { message_id: message_ids }
50
+ response = request(NeuralCategorizer.resources_path, body)
51
+
52
+ collection = []
53
+ response.each do |categorize|
54
+ collection.push(NeuralCategorizer.new(**categorize.merge(api: api)))
55
+ end
56
+ collection
57
+ end
58
+
59
+ def clean_conversation(message_ids, options = nil)
60
+ body = { message_id: message_ids }
61
+ body = body.merge(delete_from_hash(options.to_hash, :parse_contact)) unless options.nil?
62
+
63
+ response = request(NeuralCleanConversation.resources_path, body)
64
+ collection = []
65
+ response.each do |conversation|
66
+ collection.push(NeuralCleanConversation.new(**conversation.merge(api: api)))
67
+ end
68
+ collection
69
+ end
70
+
71
+ private
72
+
73
+ def request(path, body)
74
+ api.execute(
75
+ method: :put,
76
+ path: path,
77
+ payload: JSON.dump(body)
78
+ )
79
+ end
80
+
81
+ # For Ruby < 3.0 support, as it doesn't support Hash.except
82
+ def delete_from_hash(hash, to_delete)
83
+ hash.delete(to_delete)
84
+ hash
85
+ end
86
+ end
87
+ end
@@ -0,0 +1,29 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nylas
4
+ # Structure to represent a the Neural Categorizer object.
5
+ # @see https://developer.nylas.com/docs/intelligence/categorizer/#categorize-message-response
6
+ class NeuralCategorizer < Message
7
+ include Model
8
+ self.resources_path = "/neural/categorize"
9
+ allows_operations(listable: true)
10
+
11
+ attribute :categorizer, :categorize
12
+ # Overrides Message's label attribute as currently categorize returns
13
+ # list of strings for labels instead of label object types
14
+ has_n_of_attribute :labels, :string
15
+
16
+ inherit_attributes
17
+
18
+ def recategorize(category)
19
+ body = { message_id: id, category: category }
20
+ api.execute(
21
+ method: :post,
22
+ path: "#{resources_path}/feedback",
23
+ payload: JSON.dump(body)
24
+ )
25
+ list = api.neural.categorize([id])
26
+ list[0]
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nylas
4
+ # Structure to represent a the Neural Clean Conversations object.
5
+ # @see https://developer.nylas.com/docs/intelligence/clean-conversations/#clean-conversation-response
6
+ class NeuralCleanConversation < Message
7
+ include Model
8
+ self.resources_path = "/neural/conversation"
9
+ allows_operations(listable: true)
10
+ IMAGE_REGEX = /[(']cid:(.*?)[)']/.freeze
11
+
12
+ attribute :conversation, :string
13
+ attribute :model_version, :string
14
+
15
+ inherit_attributes
16
+
17
+ # Parses image file IDs found in the clean conversation object and returns
18
+ # an array of File objects returned from the File API
19
+ def extract_images
20
+ return if conversation.nil?
21
+
22
+ files = []
23
+ matches = conversation.scan(IMAGE_REGEX)
24
+ matches.each do |match|
25
+ # After applying the regex, if there are IDs found they would be
26
+ # in the form of => 'cid:xxxx' (including apostrophes), so we discard
27
+ # everything before and after the file ID (denoted as xxxx above)
28
+ files.push(api.files.find(match))
29
+ end
30
+ files
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nylas
4
+ # Structure to represent the "Link" object in the Neural API's Signature Extraction Contact object
5
+ # @see https://developer.nylas.com/docs/intelligence/signature-extraction/#parse-signature-response
6
+ class NeuralContactLink
7
+ include Model::Attributable
8
+ attribute :description, :string
9
+ attribute :url, :string
10
+ end
11
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nylas
4
+ # Structure to represent the "Name" object in the Neural API's Signature Extraction Contact object
5
+ # @see https://developer.nylas.com/docs/intelligence/signature-extraction/#parse-signature-response
6
+ class NeuralContactName
7
+ include Model::Attributable
8
+ attribute :first_name, :string
9
+ attribute :last_name, :string
10
+ end
11
+ end
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nylas
4
+ # Structure to represent a the Neural Optical Character Recognition object.
5
+ # @see https://developer.nylas.com/docs/intelligence/optical-charecter-recognition/#ocr-response
6
+ class NeuralMessageOptions
7
+ attr_accessor :ignore_links, :ignore_images, :ignore_tables, :remove_conclusion_phrases,
8
+ :images_as_markdown, :parse_contact
9
+
10
+ def initialize(ignore_links: nil,
11
+ ignore_images: nil,
12
+ ignore_tables: nil,
13
+ remove_conclusion_phrases: nil,
14
+ images_as_markdown: nil,
15
+ parse_contact: nil)
16
+ @ignore_links = ignore_links
17
+ @ignore_images = ignore_images
18
+ @ignore_tables = ignore_tables
19
+ @remove_conclusion_phrases = remove_conclusion_phrases
20
+ @images_as_markdown = images_as_markdown
21
+ @parse_contact = parse_contact
22
+ end
23
+
24
+ def to_hash
25
+ hash = {}
26
+ hash[:ignore_links] = @ignore_links unless @ignore_links.nil?
27
+ hash[:ignore_images] = @ignore_images unless @ignore_images.nil?
28
+ hash[:ignore_tables] = @ignore_tables unless @ignore_tables.nil?
29
+ hash[:remove_conclusion_phrases] = @remove_conclusion_phrases unless @remove_conclusion_phrases.nil?
30
+ hash[:images_as_markdown] = @images_as_markdown unless @images_as_markdown.nil?
31
+ hash[:parse_contact] = @parse_contact unless @parse_contact.nil?
32
+ hash
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nylas
4
+ # Structure to represent a the Neural Optical Character Recognition object.
5
+ # @see https://developer.nylas.com/docs/intelligence/optical-charecter-recognition/#ocr-response
6
+ class NeuralOcr < File
7
+ include Model
8
+ self.resources_path = "/neural/ocr"
9
+ allows_operations(listable: true)
10
+
11
+ has_n_of_attribute :ocr, :string
12
+ attribute :processed_pages, :integer
13
+
14
+ inherit_attributes
15
+ end
16
+ end
@@ -0,0 +1,17 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nylas
4
+ # Structure to represent a the Neural Sentiment Analysis object.
5
+ # @see https://developer.nylas.com/docs/intelligence/sentiment-analysis/#sentiment-analysis-response-message
6
+ class NeuralSentimentAnalysis
7
+ include Model
8
+ self.resources_path = "/neural/sentiment"
9
+ allows_operations(listable: true)
10
+
11
+ attribute :account_id, :string
12
+ attribute :sentiment, :string
13
+ attribute :sentiment_score, :float
14
+ attribute :processed_length, :integer
15
+ attribute :text, :string
16
+ end
17
+ end
@@ -0,0 +1,81 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nylas
4
+ # Structure to represent the Neural API's Signature Extraction Contact object
5
+ # @see https://developer.nylas.com/docs/intelligence/signature-extraction/#parse-signature-response
6
+ class NeuralSignatureContact
7
+ include Model::Attributable
8
+ has_n_of_attribute :job_titles, :string
9
+ has_n_of_attribute :links, :neural_contact_link
10
+ has_n_of_attribute :phone_numbers, :string
11
+ has_n_of_attribute :emails, :string
12
+ has_n_of_attribute :names, :neural_contact_name
13
+
14
+ attr_accessor :api
15
+
16
+ # Creates a Nylas contact object compatible with the contact endpoints.
17
+ # Please note if multiple names or multiple job titles were parsed only
18
+ # the first set are used.
19
+ def to_contact_object
20
+ contact = merge_multiple_hashes([convert_names, convert_emails, convert_phone_numbers, convert_links])
21
+ contact[:job_title] = job_titles[0] unless job_titles.nil?
22
+ Contact.new(**contact.merge(api: api))
23
+ end
24
+
25
+ private
26
+
27
+ def convert_names
28
+ return {} if names.empty?
29
+
30
+ contact = {}
31
+ contact[:given_name] = names[0].first_name if names[0].first_name
32
+ contact[:surname] = names[0].last_name if names[0].last_name
33
+ contact
34
+ end
35
+
36
+ def convert_emails
37
+ return {} if emails.empty?
38
+
39
+ contact = {}
40
+ contact[:emails] = []
41
+ emails.each do |e|
42
+ contact[:emails].push(type: "personal", email: e)
43
+ end
44
+ contact
45
+ end
46
+
47
+ def convert_phone_numbers
48
+ return {} if phone_numbers.empty?
49
+
50
+ contact = {}
51
+ contact[:phone_numbers] = []
52
+ phone_numbers.each do |number|
53
+ contact[:phone_numbers].push(type: "mobile", number: number)
54
+ end
55
+ contact
56
+ end
57
+
58
+ def convert_links
59
+ return {} if links.empty?
60
+
61
+ contact = {}
62
+ contact[:web_pages] = []
63
+ links.each do |link|
64
+ type = "homepage"
65
+ type = link.description unless link.description.empty?
66
+ contact[:web_pages].push(type: type, url: link.url)
67
+ end
68
+ contact
69
+ end
70
+
71
+ # For Ruby 2.5 support as it doesn't support multiple hashes to merge at once
72
+ def merge_multiple_hashes(hashes_to_merge)
73
+ hash = {}
74
+ hashes_to_merge.each do |new_hash|
75
+ hash = hash.merge(new_hash)
76
+ end
77
+
78
+ hash
79
+ end
80
+ end
81
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Nylas
4
+ # Structure to represent a the Signature Extraction Schema.
5
+ # @see https://developer.nylas.com/docs/intelligence/signature-extraction/#signature-feedback-response
6
+ class NeuralSignatureExtraction < Message
7
+ include Model
8
+ self.resources_path = "/neural/signature"
9
+
10
+ attribute :signature, :string
11
+ attribute :model_version, :string
12
+ attribute :contacts, :neural_signature_contact
13
+
14
+ inherit_attributes
15
+
16
+ transfer :api, to: %i[contacts]
17
+ end
18
+ end
@@ -26,7 +26,7 @@ module Nylas
26
26
  attribute :tracking, :message_tracking
27
27
 
28
28
  def send!
29
- Message.new(api.execute(method: :post, path: "/send", payload: to_json).merge(api: api))
29
+ Message.new(**api.execute(method: :post, path: "/send", payload: to_json).merge(api: api))
30
30
  end
31
31
  end
32
32
  end
data/lib/nylas/thread.rb CHANGED
@@ -23,6 +23,7 @@ module Nylas
23
23
  has_n_of_attribute :labels, :label
24
24
  has_n_of_attribute :folders, :folder
25
25
  has_n_of_attribute :message_ids, :string
26
+ has_n_of_attribute :messages, :message
26
27
  has_n_of_attribute :participants, :participant
27
28
  attribute :snippet, :string
28
29
  attribute :starred, :boolean
data/lib/nylas/types.rb CHANGED
@@ -144,5 +144,16 @@ module Nylas
144
144
  end
145
145
  end
146
146
  Types.registry[:boolean] = BooleanType.new
147
+
148
+ # Type for attributes represented as floats.
149
+ class FloatType < ValueType
150
+ # @param value [Object] Strictly casts the passed in value to a boolean (must be true, not "" or 1)
151
+ def cast(value)
152
+ return nil if value.nil?
153
+
154
+ value.to_f
155
+ end
156
+ end
157
+ Types.registry[:float] = FloatType.new
147
158
  end
148
159
  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.2.0"
4
+ VERSION = "5.3.0"
5
5
  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.2.0
4
+ version: 5.3.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-07-15 00:00:00.000000000 Z
11
+ date: 2021-08-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -270,6 +270,7 @@ files:
270
270
  - lib/nylas/account.rb
271
271
  - lib/nylas/api.rb
272
272
  - lib/nylas/calendar.rb
273
+ - lib/nylas/categorize.rb
273
274
  - lib/nylas/collection.rb
274
275
  - lib/nylas/constraints.rb
275
276
  - lib/nylas/contact.rb
@@ -302,6 +303,16 @@ files:
302
303
  - lib/nylas/model/list_attribute_definition.rb
303
304
  - lib/nylas/model/transferable.rb
304
305
  - lib/nylas/native_authentication.rb
306
+ - lib/nylas/neural.rb
307
+ - lib/nylas/neural_categorizer.rb
308
+ - lib/nylas/neural_clean_conversation.rb
309
+ - lib/nylas/neural_contact_link.rb
310
+ - lib/nylas/neural_contact_name.rb
311
+ - lib/nylas/neural_message_options.rb
312
+ - lib/nylas/neural_ocr.rb
313
+ - lib/nylas/neural_sentiment_analysis.rb
314
+ - lib/nylas/neural_signature_contact.rb
315
+ - lib/nylas/neural_signature_extraction.rb
305
316
  - lib/nylas/new_message.rb
306
317
  - lib/nylas/nylas_date.rb
307
318
  - lib/nylas/participant.rb