Module: Smartcar

Extended by:
Utils
Defined in:
lib/smartcar.rb,
lib/smartcar/base.rb,
lib/smartcar/utils.rb,
lib/smartcar/vehicle.rb,
lib/smartcar/version.rb,
lib/smartcar/auth_client.rb

Overview

Main Smartcar umbrella module

Defined Under Namespace

Modules: Utils Classes: AuthClient, Base, ConfigNotFound, Vehicle

Constant Summary collapse

API_ORIGIN =

Host to connect to smartcar

'https://api.smartcar.com/'
MANAGEMENT_API_ORIGIN =
'https://management.smartcar.com'
PATHS =
{
  compatibility: '/compatibility',
  user: '/user',
  vehicles: '/vehicles',
  connections: '/management/connections'
}.freeze
CONNECT_ORIGIN =

Path for smartcar oauth

'https://connect.smartcar.com'
AUTH_ORIGIN =
'https://auth.smartcar.com'
UNITS =

Constant for units

[IMPERIAL, METRIC].freeze
DEFAULT_REQUEST_TIMEOUT =

Number of seconds to wait for responses

310
VERSION =

Gem current version number

'3.8.0'

Class Method Summary collapse

Methods included from Utils

build_aliases, build_error, build_meta, build_response, convert_path_to_attribute, determine_mode, get_config, handle_error, initialize, json_to_ostruct, process_batch_response, stringify_params

Class Method Details

.delete_connections(amt:, filter: {}, options: {}) ⇒ Object



200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
# File 'lib/smartcar.rb', line 200

def delete_connections(amt:, filter: {}, options: {})
  user_id = filter[:user_id]
  vehicle_id = filter[:vehicle_id]
  error_message = nil
  error_message = 'Filter can contain EITHER user_id OR vehicle_id, not both.' if user_id && vehicle_id
  error_message = 'Filter needs one of user_id OR vehicle_id.' unless user_id || vehicle_id

  raise Base::InvalidParameterValue.new, error_message if error_message

  query_params = {}
  query_params['user_id'] = user_id if user_id
  query_params['vehicle_id'] = vehicle_id if vehicle_id

  base_object = Base.new(
    url: ENV['SMARTCAR_MANAGEMENT_API_ORIGIN'] || MANAGEMENT_API_ORIGIN,
    auth_type: Base::BASIC,
    token: generate_basic_management_auth(amt, options),
    version: options[:version] || Smartcar.get_api_version,
    service: options[:service]
  )

  base_object.build_response(*base_object.delete(
    PATHS[:connections],
    query_params
  ))
end

.generate_basic_management_auth(amt, options = {}) ⇒ String

returns auth token for Basic vehicle management auth

Returns:

  • (String)

    Base64 encoding of default:amt



230
231
232
233
# File 'lib/smartcar.rb', line 230

def generate_basic_management_auth(amt, options = {})
  username = options[:username] || 'default'
  Base64.strict_encode64("#{username}:#{amt}")
end

.get_api_versionString

Module method Used to get api version to be used. This is the getter for the class instance variable @api_version

Returns:

  • (String)

    api version number without 'v' prefix



58
59
60
# File 'lib/smartcar.rb', line 58

def get_api_version
  instance_variable_get('@api_version')
end

.get_compatibility(vin:, scope:, country: 'US', options: {}) ⇒ OpenStruct

Module method Used to check compatiblity for VIN and scope

API Documentation - https://smartcar.com/docs/api#compatibility-api. Options Hash ISO 3166-1 alpha-2. Defaults to US. Launch Smartcar Connect in test mode(https://smartcar.com/docs/guides/testing/). Should be one of test, live or simulated. test mode with a real vin. For more information refer to docs.

Parameters:

  • vin (String)

    VIN of the vehicle to be checked

  • scope (Array of Strings)
    • array of scopes
  • country (String) (defaults to: 'US')

    An optional country code according to

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

    Other optional parameters including overrides (only valid for Smartcar API v1.0)

  • options[Boolean] (Hash)

    a customizable set of options

Options Hash (options:):

  • :client_id (String)

    Client ID that overrides ENV

  • :client_secret (String)

    Client Secret that overrides ENV

  • :version (String)

    API version to use, defaults to what is globally set

  • :flags (Hash)

    A hash of flag name string as key and a string or boolean value.

  • :mode (String)

    Determine what mode Smartcar Connect should be launched in.

  • :test_mode_compatibility_level (String)

    this is required argument while using

  • :service (Faraday::Connection)

    Optional connection object to be used for requests

Returns:

Raises:



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/smartcar.rb', line 84

def get_compatibility(vin:, scope:, country: 'US', options: {})
  raise Base::InvalidParameterValue.new, 'vin is a required field' if vin.nil?
  raise Base::InvalidParameterValue.new, 'scope is a required field' if scope.nil? || scope.empty?

  base_object = Base.new(
    {
      version: options[:version] || Smartcar.get_api_version,
      auth_type: Base::BASIC,
      service: options[:service]
    }
  )

  base_object.token = generate_basic_auth(options, base_object)

  base_object.build_response(*base_object.get(
    PATHS[:compatibility],
    build_compatibility_params(vin, scope, country, options)
  ))
end

.get_connections(amt:, filter: {}, paging: {}, options: {}) ⇒ OpenStruct

Module method Returns a paged list of all vehicle connections connected to the application.

API Documentation - https://smartcar.com/docs/api#get-connections

Parameters:

  • amt (String)
    • Application Management token
  • filters (Hash)
    • Optional filter parameters (check documentation)
  • paging (Hash) (defaults to: {})
    • Pass a cursor for paginated results
  • options (Hash) (defaults to: {})

    Other optional parameters including overrides

Options Hash (options:):

  • :service (Faraday::Connection)

    Optional connection object to be used for requests

  • :version (String)

    Optional API version to use, defaults to what is globally set

Returns:



183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
# File 'lib/smartcar.rb', line 183

def get_connections(amt:, filter: {}, paging: {}, options: {})
  paging[:limit] ||= 10
  base_object = Base.new(
    token: generate_basic_management_auth(amt, options),
    version: options[:version] || Smartcar.get_api_version,
    service: options[:service],
    auth_type: Base::BASIC,
    url: ENV['SMARTCAR_MANAGEMENT_API_ORIGIN'] || MANAGEMENT_API_ORIGIN
  )
  query_params = filter.merge(paging).compact

  base_object.build_response(*base_object.get(
    PATHS[:connections],
    query_params
  ))
end

.get_user(token:, version: Smartcar.get_api_version, options: {}) ⇒ OpenStruct

Module method Used to get user id

API Documentation - https://smartcar.com/docs/api#get-user

Parameters:

  • token (String)

    Access token

  • version (String) (defaults to: Smartcar.get_api_version)

    Optional API version to use, defaults to what is globally set

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

    Other optional parameters including overrides

Options Hash (options:):

  • :service (Faraday::Connection)

    Optional connection object to be used for requests

Returns:



114
115
116
117
118
119
120
121
122
123
# File 'lib/smartcar.rb', line 114

def get_user(token:, version: Smartcar.get_api_version, options: {})
  base_object = Base.new(
    {
      token: token,
      version: version,
      service: options[:service]
    }
  )
  base_object.build_response(*base_object.get(PATHS[:user]))
end

.get_vehicles(token:, paging: {}, version: Smartcar.get_api_version, options: {}) ⇒ OpenStruct

Module method Returns a paged list of all vehicles connected to the application for the current authorized user.

API Documentation - https://smartcar.com/docs/api#get-all-vehicles

Parameters:

  • token (String)
    • Access token
  • paging (Hash) (defaults to: {})
    • Optional filter parameters (check documentation)
  • version (String) (defaults to: Smartcar.get_api_version)

    Optional API version to use, defaults to what is globally set

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

    Other optional parameters including overrides

Options Hash (options:):

  • :service (Faraday::Connection)

    Optional connection object to be used for requests

Returns:



136
137
138
139
140
141
142
143
144
145
146
147
148
# File 'lib/smartcar.rb', line 136

def get_vehicles(token:, paging: {}, version: Smartcar.get_api_version, options: {})
  base_object = Base.new(
    {
      token: token,
      version: version,
      service: options[:service]
    }
  )
  base_object.build_response(*base_object.get(
    PATHS[:vehicles],
    paging
  ))
end

.hash_challenge(amt, challenge) ⇒ String

Module method to generate hash challenge for webhooks. It does HMAC_SHA256(amt, challenge)

Parameters:

  • amt (String)
    • Application Management Token
  • challenge (String)
    • Challenge string

Returns:

  • (String)

    String representing the hex digest



156
157
158
# File 'lib/smartcar.rb', line 156

def hash_challenge(amt, challenge)
  OpenSSL::HMAC.hexdigest(OpenSSL::Digest.new('sha256'), amt, challenge)
end

.set_api_version(version) ⇒ Object

Module method Used to set api version to be used. This method can be used at the top to set the version and any following request will use the version set here unless overridden separately.

Parameters:

  • version (String)

    version to be set without 'v' prefix.



50
51
52
# File 'lib/smartcar.rb', line 50

def set_api_version(version)
  instance_variable_set('@api_version', version)
end

.verify_payload(amt, signature, body) ⇒ true, false

Module method used to verify webhook payload with AMT and signature.

Parameters:

  • amt (String)
    • Application Management Token
  • signature (String)
    • sc-signature header value
  • body (Object)
    • webhook response body

Returns:

  • (true, false)
    • true if signature matches the hex digest of amt and body


167
168
169
# File 'lib/smartcar.rb', line 167

def verify_payload(amt, signature, body)
  hash_challenge(amt, body.to_json) == signature
end