Rust crate for Smartcar API
Smartcar API lets you read vehicle data and send commands to vehicles (lock, unlock) using HTTP requests.
To make requests to a vehicle from a web or mobile application, the end user must connect their vehicle using Smartcar Connect. This flow follows the OAuth spec and will return a code
which can be used to obtain an access token from Smartcar.
The Smartcar Rust SDK provides methods to:
code
obtained from Connect to obtain an
access and refresh tokenBefore integrating with Smartcar's SDK, you'll need to register an application in the Smartcar Developer portal. If you do not have access to the dashboard, please request access.
Add this to your Cargo.toml
:
[dependencies]
smartcar = "0.1.3"
AuthClient
struct with your client_id
, client_secret
, and redirect_uri
.<AuthClient>.get_auth_url
with required scope
or with one of our frontend SDKs.scope
's permissions.redirect_uri
.
<AuthClient>.exchange_code
with this code to obtain an access struct.
This struct contains an access token (lasting 2 hours) and a refresh token (lasting 60 days).
get_vehicles
.vehicle
struct using an d
from the previous response,
and the access_token
.<AuthClient>.exchange_refresh_token
on your saved refresh_token
to retrieve a new token
when your accessToken
expires.The following code is in /examples. To run the code, replace the fake Smartcar credentials in
get_auth_client
with your own and run this command:
cargo run --example=getting-started
```rust use axum::extract::Query; use axum::http::StatusCode; use axum::response::{IntoResponse, Redirect}; use axum::Json; use axum::{routing::get, Router}; use serde::Deserialize; use serde_json::json;
use smartcar; use smartcar::response::{Meta, VehicleAttributes}; use smartcar::vehicle::Vehicle; use smartcar::{Permission, ScopeBuilder};
async fn main() { let app = Router::new() .route("/login", get(login)) .route("/callback", get(callback));
// run on localhost:3000
axum::Server::bind(&"0.0.0.0:3000".parse().unwrap())
.serve(app.into_make_service())
.await
.unwrap();
}
/// Helper for creating an Auth Client instance with your credentials fn getauthclient() -> smartcar::authclient::AuthClient { smartcar::authclient::AuthClient::new( "REPLACE-WITH-YOUR-SMARTCAR-CLIENT-ID", "REPLACE-WITH-YOUR-SMARTCAR-CLIENT-SECRET", "REPLACE-WITH-YOUR-SMARTCAR-REDIRECT-URI.COM", true, ) }
/// Redirect to Smartcar Connect async fn login() -> Redirect { let scope = ScopeBuilder::new().addpermission(Permission::ReadVehicleInfo); let link = getauthclient().getauth_url(&scope, None);
println!("URL your user will go to:\n\n{}", link);
Redirect::to(&link)
}
/// The potential query codes after user goes through Smartcar Connect
struct Callback {
code: Option
// Handle Smartcar callback with auth code
async fn callback(q: Query
let code = &q.code.to_owned().unwrap();
let res = get_attributes(code.as_str()).await;
match res {
Err(_) => {
return (
StatusCode::EXPECTATION_FAILED,
Json(json!("attributes request failed")),
)
}
Ok((attributes, meta)) => {
println!("Information about the request itself:\n\n{:#?}", meta);
println!("Vehicle's id, make, model, year:\n\n{:#?}", attributes);
(
StatusCode::OK,
Json(json!(attributes)), // please help me make this better... lol
)
}
}
}
async fn getattributes( authcode: &str, ) -> Result<(VehicleAttributes, Meta), smartcar::error::Error> { let client = getauthclient();
// Exchange auth code for an access struct (that has tokens)
let (access, _) = client.exchange_code(auth_code).await?;
// Get the user's vehicles
let (vehicle_ids, _) = smartcar::get_vehicles(&access, None, None).await?;
// For the sake of this example, just use the first vehicle
let vehicle = Vehicle::new(&vehicle_ids.vehicles[0], &access.access_token);
// Get the vehicle's attributes (make/model/year)
let (attributes, meta) = vehicle.attributes().await?;
Ok((attributes, meta))
} ```