Class: Nylas::HttpClient

Inherits:
Object
  • Object
show all
Includes:
Logging
Defined in:
lib/nylas/http_client.rb

Overview

Plain HTTP client that can be used to interact with the Nylas API sans any type casting.

Constant Summary collapse

HTTP_SUCCESS_CODES =

rubocop:disable Metrics/ClassLength

[200, 201, 302].freeze
HTTP_CODE_TO_EXCEPTIONS =
{
  400 => InvalidRequest,
  401 => UnauthorizedRequest,
  402 => MessageRejected,
  403 => AccessDenied,
  404 => ResourceNotFound,
  405 => MethodNotAllowed,
  410 => ResourceRemoved,
  418 => TeapotError,
  422 => MailProviderError,
  429 => SendingQuotaExceeded,
  500 => InternalError,
  501 => EndpointNotYetImplemented,
  502 => BadGateway,
  503 => ServiceUnavailable,
  504 => RequestTimedOut
}.freeze
ENDPOINT_TIMEOUTS =
{
  "/oauth/authorize" => 345,
  "/messages/search" => 350,
  "/threads/search" => 350,
  "/delta" => 3650,
  "/delta/longpoll" => 3650,
  "/delta/streaming" => 3650
}.freeze
SUPPORTED_API_VERSION =
"2.2"

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Logging

included, level, logger, logger=

Constructor Details

#initialize(app_id:, app_secret:, access_token: nil, api_server: "https://api.nylas.com") ⇒ Nylas::HttpClient

Parameters:

  • app_id (String)

    Your application id from the Nylas Dashboard

  • app_secret (String)

    Your application secret from the Nylas Dashboard

  • access_token (String) (defaults to: nil)

    (Optional) Your users access token.

  • api_server (String) (defaults to: "https://api.nylas.com")

    (Optional) Which Nylas API Server to connect to. Only change this if you're using a self-hosted Nylas instance.



51
52
53
54
55
56
57
58
59
60
# File 'lib/nylas/http_client.rb', line 51

def initialize(app_id:, app_secret:, access_token: nil, api_server: "https://api.nylas.com")
  unless api_server.include?("://")
    raise "When overriding the Nylas API server address, you must include https://"
  end

  @api_server = api_server
  @access_token = access_token
  @app_secret = app_secret
  @app_id = app_id
end

Instance Attribute Details

#access_tokenObject (readonly)

Returns the value of attribute access_token.



41
42
43
# File 'lib/nylas/http_client.rb', line 41

def access_token
  @access_token
end

#api_serverObject

Returns the value of attribute api_server.



39
40
41
# File 'lib/nylas/http_client.rb', line 39

def api_server
  @api_server
end

#app_idObject (readonly)

Returns the value of attribute app_id.



42
43
44
# File 'lib/nylas/http_client.rb', line 42

def app_id
  @app_id
end

#app_secretObject (readonly)

Returns the value of attribute app_secret.



43
44
45
# File 'lib/nylas/http_client.rb', line 43

def app_secret
  @app_secret
end

#default_headersObject



141
142
143
144
145
146
147
148
149
# File 'lib/nylas/http_client.rb', line 141

def default_headers
  @default_headers ||= {
    "X-Nylas-API-Wrapper" => "ruby",
    "X-Nylas-Client-Id" => @app_id,
    "Nylas-API-Version" => SUPPORTED_API_VERSION,
    "User-Agent" => "Nylas Ruby SDK #{Nylas::VERSION} - #{RUBY_VERSION}",
    "Content-type" => "application/json"
  }
end

Instance Method Details

#as(access_token) ⇒ Nylas::HttpClient[]

Returns Nylas::HttpClient[].

Returns:



63
64
65
66
# File 'lib/nylas/http_client.rb', line 63

def as(access_token)
  HttpClient.new(app_id: app_id, access_token: access_token,
                 app_secret: app_secret, api_server: api_server)
end

#build_request(method:, path: nil, headers: {}, query: {}, payload: nil, timeout: nil) ⇒ Object



110
111
112
113
114
115
# File 'lib/nylas/http_client.rb', line 110

def build_request(method:, path: nil, headers: {}, query: {}, payload: nil, timeout: nil)
  url ||= url_for_path(path)
  url = add_query_params_to_url(url, query)
  resulting_headers = default_headers.merge(headers)
  { method: method, url: url, payload: payload, headers: resulting_headers, timeout: timeout }
end

#delete(path: nil, payload: nil, headers: {}, query: {}) ⇒ Object

Syntactical sugar for making DELETE requests via the API.

See Also:



137
138
139
# File 'lib/nylas/http_client.rb', line 137

def delete(path: nil, payload: nil, headers: {}, query: {})
  execute(method: :delete, path: path, headers: headers, query: query, payload: payload)
end

#execute(method:, path: nil, headers: {}, query: {}, payload: nil) ⇒ Array Hash Stringn

Sends a request to the Nylas API and rai rubocop:disable Metrics/MethodLength

Parameters:

  • method (Symbol)

    HTTP method for the API call. Either :get, :post, :delete, or :patch

  • path (String) (defaults to: nil)

    (Optional, defaults to nil) - Relative path from the API Base. Preferred way to execute arbitrary or-not-yet-SDK-ified API commands.

  • headers (Hash) (defaults to: {})

    (Optional, defaults to {}) - Additional HTTP headers to include in the payload.

  • query (Hash) (defaults to: {})

    (Optional, defaults to {}) - Hash of names and values to include in the query section of the URI fragment

  • payload (String, Hash) (defaults to: nil)

    (Optional, defaults to nil) - Body to send with the request.

Returns:

  • (Array Hash Stringn)


78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/nylas/http_client.rb', line 78

def execute(method:, path: nil, headers: {}, query: {}, payload: nil)
  timeout = ENDPOINT_TIMEOUTS.fetch(path, 230)
  request = build_request(
    method: method,
    path: path,
    headers: headers,
    query: query,
    payload: payload,
    timeout: timeout
  )
  rest_client_execute(**request) do |response, _request, result|
    content_type = nil

    if response.headers && response.headers[:content_type]
      content_type = response.headers[:content_type].downcase
    end

    begin
      response = parse_response(response) if content_type == "application/json"
    rescue Nylas::JsonParseError
      handle_failed_response(result: result, response: response)
      raise
    end

    handle_failed_response(result: result, response: response)
    response
  end
end

#get(path: nil, headers: {}, query: {}) ⇒ Object

Syntactical sugar for making GET requests via the API.

See Also:



119
120
121
# File 'lib/nylas/http_client.rb', line 119

def get(path: nil, headers: {}, query: {})
  execute(method: :get, path: path, query: query, headers: headers)
end

#parse_response(response) ⇒ Object



151
152
153
154
155
156
157
158
# File 'lib/nylas/http_client.rb', line 151

def parse_response(response)
  return response if response.is_a?(Enumerable)

  json = StringIO.new(response)
  Yajl::Parser.new(symbolize_names: true).parse(json)
rescue Yajl::ParseError
  raise Nylas::JsonParseError
end

#post(path: nil, payload: nil, headers: {}, query: {}) ⇒ Object

Syntactical sugar for making POST requests via the API.

See Also:



125
126
127
# File 'lib/nylas/http_client.rb', line 125

def post(path: nil, payload: nil, headers: {}, query: {})
  execute(method: :post, path: path, headers: headers, query: query, payload: payload)
end

#put(path: nil, payload:, headers: {}, query: {}) ⇒ Object

Syntactical sugar for making PUT requests via the API.

See Also:



131
132
133
# File 'lib/nylas/http_client.rb', line 131

def put(path: nil, payload:, headers: {}, query: {})
  execute(method: :put, path: path, headers: headers, query: query, payload: payload)
end

#url_for_path(path) ⇒ Object



161
162
163
164
# File 'lib/nylas/http_client.rb', line 161

def url_for_path(path)
  protocol, domain = api_server.split("//")
  "#{protocol}//#{access_token}:@#{domain}#{path}"
end