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.
- checksums.yaml +7 -0
- data/lib/nylas_v2/account.rb +56 -0
- data/lib/nylas_v2/api.rb +244 -0
- data/lib/nylas_v2/application_details.rb +13 -0
- data/lib/nylas_v2/calendar.rb +46 -0
- data/lib/nylas_v2/calendar_collection.rb +144 -0
- data/lib/nylas_v2/categorize.rb +14 -0
- data/lib/nylas_v2/collection.rb +175 -0
- data/lib/nylas_v2/component.rb +35 -0
- data/lib/nylas_v2/component_collection.rb +10 -0
- data/lib/nylas_v2/constraints.rb +56 -0
- data/lib/nylas_v2/contact.rb +53 -0
- data/lib/nylas_v2/contact_group.rb +23 -0
- data/lib/nylas_v2/current_account.rb +23 -0
- data/lib/nylas_v2/delta.rb +56 -0
- data/lib/nylas_v2/deltas.rb +19 -0
- data/lib/nylas_v2/deltas_collection.rb +40 -0
- data/lib/nylas_v2/draft.rb +100 -0
- data/lib/nylas_v2/email_address.rb +12 -0
- data/lib/nylas_v2/errors.rb +111 -0
- data/lib/nylas_v2/event.rb +141 -0
- data/lib/nylas_v2/event_collection.rb +15 -0
- data/lib/nylas_v2/event_conferencing.rb +12 -0
- data/lib/nylas_v2/event_conferencing_autocreate.rb +10 -0
- data/lib/nylas_v2/event_conferencing_details.rb +14 -0
- data/lib/nylas_v2/event_notification.rb +17 -0
- data/lib/nylas_v2/file.rb +75 -0
- data/lib/nylas_v2/filter_attributes.rb +25 -0
- data/lib/nylas_v2/folder.rb +26 -0
- data/lib/nylas_v2/free_busy.rb +13 -0
- data/lib/nylas_v2/free_busy_collection.rb +48 -0
- data/lib/nylas_v2/http_client.rb +279 -0
- data/lib/nylas_v2/im_address.rb +11 -0
- data/lib/nylas_v2/job_status.rb +27 -0
- data/lib/nylas_v2/job_status_collection.rb +21 -0
- data/lib/nylas_v2/label.rb +27 -0
- data/lib/nylas_v2/logging.rb +41 -0
- data/lib/nylas_v2/message.rb +98 -0
- data/lib/nylas_v2/message_headers.rb +27 -0
- data/lib/nylas_v2/message_tracking.rb +13 -0
- data/lib/nylas_v2/model/attributable.rb +89 -0
- data/lib/nylas_v2/model/attribute_definition.rb +24 -0
- data/lib/nylas_v2/model/attributes.rb +97 -0
- data/lib/nylas_v2/model/list_attribute_definition.rb +39 -0
- data/lib/nylas_v2/model/transferable.rb +53 -0
- data/lib/nylas_v2/model.rb +217 -0
- data/lib/nylas_v2/native_authentication.rb +39 -0
- data/lib/nylas_v2/neural.rb +87 -0
- data/lib/nylas_v2/neural_categorizer.rb +29 -0
- data/lib/nylas_v2/neural_clean_conversation.rb +33 -0
- data/lib/nylas_v2/neural_contact_link.rb +11 -0
- data/lib/nylas_v2/neural_contact_name.rb +11 -0
- data/lib/nylas_v2/neural_message_options.rb +35 -0
- data/lib/nylas_v2/neural_ocr.rb +16 -0
- data/lib/nylas_v2/neural_sentiment_analysis.rb +17 -0
- data/lib/nylas_v2/neural_signature_contact.rb +81 -0
- data/lib/nylas_v2/neural_signature_extraction.rb +18 -0
- data/lib/nylas_v2/new_message.rb +39 -0
- data/lib/nylas_v2/nylas_date.rb +25 -0
- data/lib/nylas_v2/open_hours.rb +15 -0
- data/lib/nylas_v2/outbox.rb +116 -0
- data/lib/nylas_v2/outbox_job_status.rb +19 -0
- data/lib/nylas_v2/outbox_message.rb +17 -0
- data/lib/nylas_v2/participant.rb +13 -0
- data/lib/nylas_v2/phone_number.rb +11 -0
- data/lib/nylas_v2/physical_address.rb +17 -0
- data/lib/nylas_v2/raw_message.rb +25 -0
- data/lib/nylas_v2/recurrence.rb +11 -0
- data/lib/nylas_v2/registry.rb +42 -0
- data/lib/nylas_v2/room_resource.rb +19 -0
- data/lib/nylas_v2/rsvp.rb +24 -0
- data/lib/nylas_v2/scheduler.rb +51 -0
- data/lib/nylas_v2/scheduler_booking_confirmation.rb +24 -0
- data/lib/nylas_v2/scheduler_booking_request.rb +17 -0
- data/lib/nylas_v2/scheduler_collection.rb +104 -0
- data/lib/nylas_v2/scheduler_config.rb +20 -0
- data/lib/nylas_v2/scheduler_time_slot.rb +14 -0
- data/lib/nylas_v2/search_collection.rb +10 -0
- data/lib/nylas_v2/send_grid_verified_status.rb +12 -0
- data/lib/nylas_v2/thread.rb +66 -0
- data/lib/nylas_v2/time_slot.rb +16 -0
- data/lib/nylas_v2/time_slot_capacity.rb +13 -0
- data/lib/nylas_v2/timespan.rb +20 -0
- data/lib/nylas_v2/token_info.rb +20 -0
- data/lib/nylas_v2/types.rb +168 -0
- data/lib/nylas_v2/version.rb +5 -0
- data/lib/nylas_v2/web_page.rb +11 -0
- data/lib/nylas_v2/webhook.rb +98 -0
- data/lib/nylas_v2/when.rb +75 -0
- data/lib/nylas_v2.rb +162 -0
- metadata +415 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module NylasV2
|
|
4
|
+
module Model
|
|
5
|
+
# Stores the actual model data to allow for type casting and clean/dirty checking
|
|
6
|
+
class Attributes
|
|
7
|
+
attr_accessor :data, :attribute_definitions
|
|
8
|
+
|
|
9
|
+
def initialize(attribute_definitions)
|
|
10
|
+
@attribute_definitions = attribute_definitions
|
|
11
|
+
@data = Registry.new(default_attributes)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def [](key)
|
|
15
|
+
data[key]
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def []=(key, value)
|
|
19
|
+
data[key] = cast(key, value)
|
|
20
|
+
rescue NylasV2::Registry::MissingKeyError
|
|
21
|
+
# Don't crash when a new attribute is added
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Merges data into the registry while casting input types correctly
|
|
25
|
+
def merge(new_data)
|
|
26
|
+
new_data.each do |attribute_name, value|
|
|
27
|
+
self[attribute_name] = value
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Convert the object to hash
|
|
32
|
+
# @param keys [Array<String>] The keys included
|
|
33
|
+
# @param enforce_read_only [Boolean] Whether to enforce read_only property (serializing for API)
|
|
34
|
+
# @return [Hash] The hash representation of the object
|
|
35
|
+
def to_h(keys: attribute_definitions.keys, enforce_read_only: false)
|
|
36
|
+
casted_data = {}
|
|
37
|
+
keys.each do |key|
|
|
38
|
+
value = attribute_to_hash(key, enforce_read_only)
|
|
39
|
+
# If the value is an empty hash but we specify that it is valid (via default value), serialize it
|
|
40
|
+
casted_data[key] = value unless value.nil? || (value.respond_to?(:empty?) && value.empty? &&
|
|
41
|
+
!(attribute_definitions[key].default == value && value.is_a?(Hash)))
|
|
42
|
+
end
|
|
43
|
+
casted_data
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
# Serialize the object
|
|
47
|
+
# @param keys [Array<String>] The keys included
|
|
48
|
+
# @param enforce_read_only [Boolean] Whether to enforce read_only property (serializing for API)
|
|
49
|
+
# @return [String] The serialized object as a JSON string
|
|
50
|
+
def serialize(keys: attribute_definitions.keys, enforce_read_only: false)
|
|
51
|
+
JSON.dump(to_h(keys: keys, enforce_read_only: enforce_read_only))
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
# Serialize the object to an API-compatible JSON string
|
|
55
|
+
# @param keys [Array<String>] The keys included
|
|
56
|
+
# @return [String] The serialized object as a JSON string
|
|
57
|
+
def serialize_for_api(keys: attribute_definitions.keys)
|
|
58
|
+
serialize(keys: keys, enforce_read_only: true)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def serialize_all_for_api(keys: attribute_definitions.keys)
|
|
62
|
+
api_keys = keys.delete_if { |key| attribute_definitions[key].read_only == true }
|
|
63
|
+
|
|
64
|
+
JSON.dump(
|
|
65
|
+
api_keys.each_with_object({}) do |key, casted_data|
|
|
66
|
+
casted_data[key] = attribute_definitions[key].serialize(self[key])
|
|
67
|
+
end
|
|
68
|
+
)
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
private
|
|
72
|
+
|
|
73
|
+
def cast(key, value)
|
|
74
|
+
attribute_definitions[key].cast(value)
|
|
75
|
+
rescue TypeError => e
|
|
76
|
+
raise TypeError, "#{key} #{e.message}"
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def default_attributes
|
|
80
|
+
attribute_definitions.keys.zip([]).to_h
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Convert the attribute value as a hash
|
|
84
|
+
# @param key [String] The attribute's key
|
|
85
|
+
# @param enforce_read_only [Boolean] Whether to enforce read_only property (serializing for API)
|
|
86
|
+
# @return [nil | Hash] The appropriately serialized value
|
|
87
|
+
def attribute_to_hash(key, enforce_read_only)
|
|
88
|
+
attribute_definition = attribute_definitions[key]
|
|
89
|
+
if enforce_read_only
|
|
90
|
+
attribute_definition.read_only == true ? nil : attribute_definition.serialize_for_api(self[key])
|
|
91
|
+
else
|
|
92
|
+
attribute_definition.serialize(self[key])
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
96
|
+
end
|
|
97
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module NylasV2
|
|
4
|
+
module Model
|
|
5
|
+
# Allows models to have an attribute which is a lists of another type of thing
|
|
6
|
+
class ListAttributeDefinition
|
|
7
|
+
attr_accessor :type_name, :read_only, :default
|
|
8
|
+
|
|
9
|
+
def initialize(type_name:, read_only:, default:)
|
|
10
|
+
self.type_name = type_name
|
|
11
|
+
self.read_only = read_only
|
|
12
|
+
self.default = default
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def cast(list)
|
|
16
|
+
return default if list.nil? || list.empty?
|
|
17
|
+
|
|
18
|
+
list.map { |item| type.cast(item) }
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def serialize(list, enforce_read_only: false)
|
|
22
|
+
list = default if list.nil? || list.empty?
|
|
23
|
+
if enforce_read_only
|
|
24
|
+
list.map { |item| type.serialize_for_api(item) }
|
|
25
|
+
else
|
|
26
|
+
list.map { |item| type.serialize(item) }
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def serialize_for_api(list)
|
|
31
|
+
serialize(list, enforce_read_only: true)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def type
|
|
35
|
+
Types.registry[type_name]
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module NylasV2
|
|
4
|
+
module Model
|
|
5
|
+
# Allows definition of attributes, which should transfer to other dependent attributes
|
|
6
|
+
module Transferable
|
|
7
|
+
def self.included(model)
|
|
8
|
+
model.extend(ClassMethods)
|
|
9
|
+
model.init_attribute_recipients
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def initialize(**initial_data)
|
|
13
|
+
assign(**initial_data)
|
|
14
|
+
transfer_attributes
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
private
|
|
18
|
+
|
|
19
|
+
def transfer_attributes
|
|
20
|
+
self.class.attribute_recipients.each_pair do |name, recipient_names|
|
|
21
|
+
value = send(:"#{name}")
|
|
22
|
+
next if value.nil?
|
|
23
|
+
|
|
24
|
+
recipient_names.each do |recipient_name|
|
|
25
|
+
recipient = send(:"#{recipient_name}")
|
|
26
|
+
transfer_to_recipient(name, value, recipient) unless recipient.nil?
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def transfer_to_recipient(name, value, recipient)
|
|
32
|
+
if recipient.respond_to?(:each)
|
|
33
|
+
recipient.each { |item| item.send(:"#{name}=", value) }
|
|
34
|
+
else
|
|
35
|
+
recipient.send(:"#{name}=", value)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# Methods to call when tweaking Transferable classes
|
|
40
|
+
module ClassMethods
|
|
41
|
+
attr_accessor :attribute_recipients
|
|
42
|
+
|
|
43
|
+
def init_attribute_recipients
|
|
44
|
+
self.attribute_recipients ||= {}
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def transfer(*attributes, **opts)
|
|
48
|
+
attributes.each { |name| self.attribute_recipients[name] = opts[:to] }
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require_relative "model/attribute_definition"
|
|
4
|
+
require_relative "model/list_attribute_definition"
|
|
5
|
+
require_relative "model/attributable"
|
|
6
|
+
require_relative "model/attributes"
|
|
7
|
+
require_relative "model/transferable"
|
|
8
|
+
module NylasV2
|
|
9
|
+
# Include this to define a class to represent an object returned from the API
|
|
10
|
+
module Model
|
|
11
|
+
attr_accessor :api
|
|
12
|
+
|
|
13
|
+
def model_class
|
|
14
|
+
self.class
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def self.included(model)
|
|
18
|
+
model.include(Attributable)
|
|
19
|
+
model.include(Transferable)
|
|
20
|
+
model.extend(ClassMethods)
|
|
21
|
+
model.extend(Forwardable)
|
|
22
|
+
model.def_delegators :model_class, :creatable?, :filterable?, :listable?, :searchable?, :showable?,
|
|
23
|
+
:updatable?, :destroyable?, :id_listable?, :countable?
|
|
24
|
+
model.init_operations
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def save
|
|
28
|
+
result = if persisted?
|
|
29
|
+
raise ModelNotUpdatableError, self unless updatable?
|
|
30
|
+
|
|
31
|
+
update_call(attributes.serialize_for_api)
|
|
32
|
+
else
|
|
33
|
+
create
|
|
34
|
+
end
|
|
35
|
+
attributes.merge(result)
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def persisted?
|
|
39
|
+
!id.nil?
|
|
40
|
+
end
|
|
41
|
+
|
|
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
|
+
end
|
|
45
|
+
|
|
46
|
+
def create
|
|
47
|
+
raise ModelNotCreatableError, self unless creatable?
|
|
48
|
+
|
|
49
|
+
execute(
|
|
50
|
+
method: :post,
|
|
51
|
+
payload: attributes.serialize_for_api,
|
|
52
|
+
path: resources_path,
|
|
53
|
+
query: query_params
|
|
54
|
+
)
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def update(**data)
|
|
58
|
+
raise ModelNotUpdatableError, model_class unless updatable?
|
|
59
|
+
|
|
60
|
+
attributes.merge(**data)
|
|
61
|
+
payload = attributes.serialize_for_api(keys: data.keys)
|
|
62
|
+
update_call(payload)
|
|
63
|
+
|
|
64
|
+
true
|
|
65
|
+
rescue Registry::MissingKeyError => e
|
|
66
|
+
raise ModelMissingFieldError.new(e.key, self)
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def save_all_attributes
|
|
70
|
+
result = if persisted?
|
|
71
|
+
raise ModelNotUpdatableError, self unless updatable?
|
|
72
|
+
|
|
73
|
+
execute(
|
|
74
|
+
method: :put,
|
|
75
|
+
payload: attributes.serialize_all_for_api,
|
|
76
|
+
path: resource_path
|
|
77
|
+
)
|
|
78
|
+
else
|
|
79
|
+
create
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
attributes.merge(result)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def update_all_attributes(**data)
|
|
86
|
+
raise ModelNotUpdatableError, model_class unless updatable?
|
|
87
|
+
|
|
88
|
+
attributes.merge(**data)
|
|
89
|
+
payload = attributes.serialize_all_for_api(keys: data.keys)
|
|
90
|
+
update_call(payload)
|
|
91
|
+
|
|
92
|
+
true
|
|
93
|
+
rescue Registry::MissingKeyError => e
|
|
94
|
+
raise ModelMissingFieldError.new(e.key, self)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
def reload
|
|
98
|
+
assign(**execute(method: :get, path: resource_path))
|
|
99
|
+
true
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def resource_path
|
|
103
|
+
"#{resources_path}/#{id}"
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def resources_path
|
|
107
|
+
self.class.resources_path(api: api)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def auth_method
|
|
111
|
+
self.class.auth_method(api: api)
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
def destroy
|
|
115
|
+
raise ModelNotDestroyableError, self unless destroyable?
|
|
116
|
+
|
|
117
|
+
execute(method: :delete, path: resource_path, query: query_params)
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
# @return [String] JSON String of the model.
|
|
121
|
+
def to_json(_opts = {})
|
|
122
|
+
JSON.dump(to_h)
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
private
|
|
126
|
+
|
|
127
|
+
def update_call(payload)
|
|
128
|
+
result = execute(
|
|
129
|
+
method: :put,
|
|
130
|
+
payload: payload,
|
|
131
|
+
path: resource_path,
|
|
132
|
+
query: query_params
|
|
133
|
+
)
|
|
134
|
+
attributes.merge(result) if result
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def query_params
|
|
138
|
+
{}
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# Allows you to narrow in exactly what kind of model you're working with
|
|
142
|
+
module ClassMethods
|
|
143
|
+
attr_accessor :raw_mime_type, :creatable, :showable, :filterable, :searchable, :listable, :updatable,
|
|
144
|
+
:destroyable, :id_listable, :countable
|
|
145
|
+
attr_writer :resources_path, :auth_method
|
|
146
|
+
|
|
147
|
+
def init_operations
|
|
148
|
+
self.creatable = false
|
|
149
|
+
self.showable = false
|
|
150
|
+
self.listable = false
|
|
151
|
+
self.filterable = false
|
|
152
|
+
self.searchable = false
|
|
153
|
+
self.updatable = false
|
|
154
|
+
self.destroyable = false
|
|
155
|
+
self.id_listable = false
|
|
156
|
+
self.countable = false
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def creatable?
|
|
160
|
+
creatable
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def showable?
|
|
164
|
+
showable
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def listable?
|
|
168
|
+
listable
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def filterable?
|
|
172
|
+
filterable
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
def searchable?
|
|
176
|
+
searchable
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def updatable?
|
|
180
|
+
updatable
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def destroyable?
|
|
184
|
+
destroyable
|
|
185
|
+
end
|
|
186
|
+
|
|
187
|
+
def id_listable?
|
|
188
|
+
id_listable
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def countable?
|
|
192
|
+
countable
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
def resources_path(*)
|
|
196
|
+
@resources_path
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
def auth_method(*)
|
|
200
|
+
@auth_method || HttpClient::AuthMethod::BEARER
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
def exposable_as_raw?
|
|
204
|
+
!raw_mime_type.nil?
|
|
205
|
+
end
|
|
206
|
+
|
|
207
|
+
def from_json(json, api:)
|
|
208
|
+
from_hash(JSON.parse(json, symbolize_names: true), api: api)
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
def from_hash(data, api:)
|
|
212
|
+
instance = new(**data.merge(api: api))
|
|
213
|
+
instance
|
|
214
|
+
end
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
end
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module NylasV2
|
|
4
|
+
# Authenticate your application using the native interface
|
|
5
|
+
# @see https://docs.nylas.com/reference#native-authentication-1
|
|
6
|
+
class NativeAuthentication
|
|
7
|
+
attr_accessor :api
|
|
8
|
+
|
|
9
|
+
def initialize(api:)
|
|
10
|
+
self.api = api
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def authenticate(name:, email_address:, provider:, settings:, reauth_account_id: nil,
|
|
14
|
+
scopes: nil)
|
|
15
|
+
scopes ||= %w[email calendar contacts]
|
|
16
|
+
scopes = scopes.join(",") unless scopes.is_a?(String)
|
|
17
|
+
code = retrieve_code(name: name, email_address: email_address, provider: provider,
|
|
18
|
+
settings: settings, reauth_account_id: reauth_account_id, scopes: scopes)
|
|
19
|
+
|
|
20
|
+
exchange_code_for_access_token(code)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
private
|
|
24
|
+
|
|
25
|
+
def retrieve_code(name:, email_address:, provider:, settings:, reauth_account_id:, scopes:)
|
|
26
|
+
payload = { client_id: api.client.app_id, name: name, email_address: email_address,
|
|
27
|
+
provider: provider, settings: settings, scopes: scopes }
|
|
28
|
+
payload[:reauth_account_id] = reauth_account_id
|
|
29
|
+
response = api.execute(method: :post, path: "/connect/authorize", payload: JSON.dump(payload))
|
|
30
|
+
response[:code]
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def exchange_code_for_access_token(code)
|
|
34
|
+
payload = { client_id: api.client.app_id, client_secret: api.client.app_secret, code: code }
|
|
35
|
+
response = api.execute(method: :post, path: "/connect/token", payload: JSON.dump(payload))
|
|
36
|
+
response[:access_token]
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module NylasV2
|
|
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 NylasV2
|
|
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
|
+
self.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 NylasV2
|
|
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
|
+
self.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 NylasV2
|
|
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 NylasV2
|
|
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 NylasV2
|
|
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 NylasV2
|
|
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
|
+
self.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 NylasV2
|
|
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
|
+
self.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
|