Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Ruby SDK Messages, Threads, Drafts, and Send support #432

Merged
merged 8 commits into from
Nov 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,5 @@ jobs:
with:
ruby-version: 3.0
bundler-cache: true # runs 'bundle install' and caches installed gems automatically
- name: Run rubocop
- name: Generate docs
run: bundle exec rubocop --config .rubocop.yml
5 changes: 5 additions & 0 deletions lib/nylas.rb
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,13 @@
require_relative "nylas/resources/calendars"
require_relative "nylas/resources/connectors"
require_relative "nylas/resources/credentials"
require_relative "nylas/resources/drafts"
require_relative "nylas/resources/events"
require_relative "nylas/resources/grants"
require_relative "nylas/resources/messages"
require_relative "nylas/resources/smart_compose"
require_relative "nylas/resources/threads"
require_relative "nylas/resources/redirect_uris"
require_relative "nylas/resources/webhooks"

require_relative "nylas/utils/file_utils"
22 changes: 18 additions & 4 deletions lib/nylas/client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@ def applications
Applications.new(self)
end

# The auth resources for your Nylas application.
#
# @return [Nylas::Auth] Auth resources for your Nylas application.
def auth
Auth.new(self)
end

# The calendar resources for your Nylas application.
#
# @return [Nylas::Calendars] Calendar resources for your Nylas application.
Expand All @@ -47,6 +54,13 @@ def connectors
Connectors.new(self)
end

# The draft resources for your Nylas application.
#
# @return [Nylas::Drafts] Draft resources for your Nylas application.
def drafts
Drafts.new(self)
end

# The event resources for your Nylas application.
#
# @return [Nylas::Events] Event resources for your Nylas application
Expand All @@ -61,11 +75,11 @@ def messages
Messages.new(self)
end

# The auth resources for your Nylas application.
# The thread resources for your Nylas application.
#
# @return [Nylas::Auth] Auth resources for your Nylas application.
def auth
Auth.new(self)
# @return [Nylas::Threads] Thread resources for your Nylas application.
def threads
Threads.new(self)
end

# The webhook resources for your Nylas application.
Expand Down
2 changes: 2 additions & 0 deletions lib/nylas/handler/api_operations.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
# frozen_string_literal: true

require_relative "http_client"

module Nylas
# Allows resources to perform API operations on the Nylas API endpoints without exposing the HTTP
# client to the end user.
Expand Down
18 changes: 11 additions & 7 deletions lib/nylas/handler/http_client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -77,17 +77,21 @@ def build_request(
url = path
url = add_query_params_to_url(url, query)
resulting_headers = default_headers.merge(headers).merge(auth_header(api_key))
serialized_payload = payload&.to_json
if !payload.nil? && !payload["multipart"]
payload = payload&.to_json
resulting_headers["Content-type"] = "application/json"
elsif !payload.nil? && payload["multipart"]
payload.delete("multipart")
end

{ method: method, url: url, payload: serialized_payload, headers: resulting_headers, timeout: timeout }
{ method: method, url: url, payload: payload, headers: resulting_headers, timeout: timeout }
end

# Sets the default headers for API requests.
def default_headers
@default_headers ||= {
"X-Nylas-API-Wrapper" => "ruby",
"User-Agent" => "Nylas Ruby SDK #{Nylas::VERSION} - #{RUBY_VERSION}",
"Content-type" => "application/json"
"User-Agent" => "Nylas Ruby SDK #{Nylas::VERSION} - #{RUBY_VERSION}"
}
end

Expand Down Expand Up @@ -141,11 +145,11 @@ def error_hash_to_exception(response, status_code, path)
NylasOAuthError.new(response[:error], response[:error_description], response[:error_uri],
response[:error_code], status_code)
else
throw_error(response)
throw_error(response, status_code)
end
end

def throw_error(response)
def throw_error(response, status_code)
error_obj = response[:error]
provider_error = error_obj.fetch(:provider_error, nil)

Expand All @@ -157,7 +161,7 @@ def throw_error(response)
#
# @return [String] Processed URL, including query params.
def add_query_params_to_url(url, query)
unless query.empty?
unless query.nil? || query.empty?
uri = URI.parse(url)
query = custom_params(query)
params = URI.decode_www_form(uri.query || "") + query.to_a
Expand Down
91 changes: 91 additions & 0 deletions lib/nylas/resources/drafts.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,91 @@
# frozen_string_literal: true

require_relative "resource"
require_relative "../handler/api_operations"
require_relative "../utils/file_utils"

module Nylas
# Nylas Drafts API
class Drafts < Resource
include ApiOperations::Get
include ApiOperations::Post
include ApiOperations::Put
include ApiOperations::Delete

# Return all drafts.
#
# @param identifier [String] Grant ID or email account to query.
# @param query_params [Hash, nil] Query params to pass to the request.
# @return [Array(Array(Hash), String)] The list of drafts and API Request ID.
def list(identifier:, query_params: nil)
get(
path: "#{api_uri}/v3/grants/#{identifier}/drafts",
query_params: query_params
)
end

# Return an draft.
#
# @param identifier [String] Grant ID or email account to query.
# @param draft_id [String] The id of the draft to return.
# @return [Array(Hash, String)] The draft and API request ID.
def find(identifier:, draft_id:)
get(
path: "#{api_uri}/v3/grants/#{identifier}/drafts/#{draft_id}"
)
end

# Create an draft.
#
# @param identifier [String] Grant ID or email account in which to create the draft.
# @param request_body [Hash] The values to create the message with.
# If you're attaching files, you must pass an array of [File] objects, or
# you can use {FileUtils::attach_file_request_builder} to build each object attach.
# @return [Array(Hash, String)] The created draft and API Request ID.
def create(identifier:, request_body:)
form_body, opened_files = FileUtils.build_form_request(request_body)
response = post(
path: "#{api_uri}/v3/grants/#{identifier}/drafts",
request_body: form_body
)

opened_files.each(&:close)

response
end

# Update an draft.
#
# @param identifier [String] Grant ID or email account in which to update the draft.
# @param draft_id [String] The id of the draft to update.
# @param request_body [Hash] The values to create the message with.
# If you're attaching files, you must pass an array of [File] objects, or
# you can use {FileUtils::attach_file_request_builder} to build each object attach.
# @return [Array(Hash, String)] The updated draft and API Request ID.
def update(identifier:, draft_id:, request_body:)
form_body, opened_files = FileUtils.build_form_request(request_body)

response = put(
path: "#{api_uri}/v3/grants/#{identifier}/drafts/#{draft_id}",
request_body: form_body
)

opened_files.each(&:close)

response
end

# Delete an draft.
#
# @param identifier [String] Grant ID or email account from which to delete an object.
# @param draft_id [String] The id of the draft to delete.
# @return [Array(TrueClass, String)] True and the API Request ID for the delete operation.
def destroy(identifier:, draft_id:)
_, request_id = delete(
path: "#{api_uri}/v3/grants/#{identifier}/drafts/#{draft_id}"
)

[true, request_id]
end
end
end
67 changes: 64 additions & 3 deletions lib/nylas/resources/messages.rb
Original file line number Diff line number Diff line change
@@ -1,15 +1,27 @@
# frozen_string_literal: true

require_relative "resource"
require_relative "smart_compose"
require_relative "../handler/api_operations"
require_relative "../utils/file_utils"

module Nylas
# Nylas Messages API
class Messages < Resource
include ApiOperations::Get
include ApiOperations::Post
include ApiOperations::Put
include ApiOperations::Delete

attr_reader :smart_compose

# Initializes the messages resource.
# @param sdk_instance [Nylas::API] The API instance to which the resource is bound.
def initialize(sdk_instance)
super(sdk_instance)
@smart_compose = SmartCompose.new(sdk_instance)
end

# Return all messages.
#
# @param identifier [String] Grant ID or email account to query.
Expand All @@ -26,7 +38,6 @@ def list(identifier:, query_params: nil)
#
# @param identifier [String] Grant ID or email account to query.
# @param message_id [String] The id of the message to return.
# Use "primary" to refer to the primary message associated with grant.
# @return [Array(Hash, String)] The message and API request ID.
def find(identifier:, message_id:)
get(
Expand All @@ -38,7 +49,6 @@ def find(identifier:, message_id:)
#
# @param identifier [String] Grant ID or email account in which to update an object.
# @param message_id [String] The id of the message to update.
# Use "primary" to refer to the primary message associated with grant.
# @param request_body [Hash] The values to update the message with
# @return [Array(Hash, String)] The updated message and API Request ID.
def update(identifier:, message_id:, request_body:)
Expand All @@ -52,7 +62,6 @@ def update(identifier:, message_id:, request_body:)
#
# @param identifier [String] Grant ID or email account from which to delete an object.
# @param message_id [String] The id of the message to delete.
# Use "primary" to refer to the primary message associated with grant.
# @return [Array(TrueClass, String)] True and the API Request ID for the delete operation.
def destroy(identifier:, message_id:)
_, request_id = delete(
Expand All @@ -61,5 +70,57 @@ def destroy(identifier:, message_id:)

[true, request_id]
end

# Send a message.
#
# @param identifier [String] Grant ID or email account from which to delete an object.
# @param request_body [Hash] The values to create the message with.
# If you're attaching files, you must pass an array of [File] objects, or
# you can use {FileUtils::attach_file_request_builder} to build each object attach.
# @return [Array(Hash, String)] The sent message and the API Request ID.
def send(identifier:, request_body:)
form_body, opened_files = FileUtils.build_form_request(request_body)

response = post(
path: "#{api_uri}/v3/grants/#{identifier}/messages/send",
request_body: form_body
)

opened_files.each(&:close)

response
end

# Retrieve your scheduled messages.
#
# @param identifier [String] Grant ID or email account from which to find the scheduled message from.
# @param schedule_id [String] The id of the scheduled message to stop.
# @return [Array(Hash, String)] The list of scheduled messages and the API Request ID.
def list_scheduled_messages(identifier:, schedule_id:)
get(
path: "#{api_uri}/v3/grants/#{identifier}/messages/schedules/#{schedule_id}"
)
end

# Retrieve your scheduled messages.
#
# @param identifier [String] Grant ID or email account from which to list the scheduled messages from.
# @return [Array(Hash, String)] The scheduled message and the API Request ID.
def find_scheduled_messages(identifier:)
get(
path: "#{api_uri}/v3/grants/#{identifier}/messages/schedules"
)
end

# Stop a scheduled message.
#
# @param identifier [String] Grant ID or email account from which to list the scheduled messages from.
# @param schedule_id [String] The id of the scheduled message to stop..
# @return [Array(Hash, String)] The scheduled message and the API Request ID.
def stop_scheduled_messages(identifier:, schedule_id:)
delete(
path: "#{api_uri}/v3/grants/#{identifier}/messages/schedules/#{schedule_id}"
)
end
end
end
36 changes: 36 additions & 0 deletions lib/nylas/resources/smart_compose.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# frozen_string_literal: true

require_relative "resource"
require_relative "../handler/api_operations"

module Nylas
# Nylas Smart Compose API
class SmartCompose < Resource
include ApiOperations::Post

# Compose a message.
#
# @param identifier [String] Grant ID or email account to generate a message suggestion for.
# @param request_body [Hash] The prompt that smart compose will use to generate a message suggestion.
# @return [Array(Hash, String)] The generated message and API Request ID.
def compose_message(identifier:, request_body:)
post(
path: "#{api_uri}/v3/grants/#{identifier}/messages/smart-compose",
request_body: request_body
)
end

# Compose a message reply.
#
# @param identifier [String] Grant ID or email account to generate a message suggestion for.
# @param message_id [String] The id of the message to reply to.
# @param request_body [Hash] The prompt that smart compose will use to generate a message reply suggestion.
# @return [Array(Hash, String)] The generated message reply and API Request ID.
def compose_message_reply(identifier:, message_id:, request_body:)
post(
path: "#{api_uri}/v3/grants/#{identifier}/messages/#{message_id}/smart-compose",
request_body: request_body
)
end
end
end