Skip to main content

Embedded Inspections

Controla todo el flujo de la inspección realizando una integración de punta a punta.

Intro

Esta guía te proporcionará los pasos a seguir para implementar Autoinspector de una manera en la que tendrás el control de la mayor parte del flujo de una inspección.

Obtener x-api-key

Permisos

Para obtener la x-api-key se necesita que un rol apto. Comunícate con el administrador propietario de tu empresa en caso de que no lo tengas.

Toda interacción con Autoinspector API requiere de un código secreto de autenticación. Para encontrar el tuyo, puedes seguir los siguientes pasos:

1. Dirígite al dashboard de Autoinspector
2. Haz click en el ícono de tu perfil y luego haz click en Configuración
3. Dirígite a la sección de developers
4. Encuentra tu API token en esta página

Crear template

Para poder crear inspecciones necesitas hacer referencia a un template: manifiesto que define el flujo de una inspección. Para eso debes crear un 'template' personalizado. Como ejemplo utilizaremos una inspección de tipo car y allí se definirán las especificaciones necesarias para el flujo de inspección. Luego este template se utilizará para crear inspecciones.

Para crear un template, debes seguir los siguientes pasos:

1. Dirígite al dashboard de Autoinspector
2. Haz click en el ícono de tu perfil y luego en la opción de Configuración
3. Dirígite a la sección de inspecciones
4. Dirígite al botón de administrar templates y haz click sobre él
4. Haz click sobre el botón de crear inspección y luego selecciona la opción "auto"
5. Una vez dentro del editor de templates, agrega las imágenes y campos que necesites
6. Finalmente copia el identificador del template que se encuentra en la esquina superior izquierda

Creando la aplicación / Servidor

La aplicación que se comunicará con Autoinspector tiene que ser de tipo backend, es decir, no puede correr dentro del browser de algún cliente debido a que estarías exponiendo credenciales sensibles como x-api-key.

npm init -y

Luego debes instalar algunas dependencias para poder crear el servicio:

npm i express autoinspector dotenv

Por último, debes crear un archivo con el nombre .env en donde guardarás las credenciales:

.env
AUTOINSPECTOR_API_KEY=YOUR_X_API_KEY

Con las credenciales ya guardadas en un archivo, necesitarás cargarlas en la aplicación para poder utilizarlas:

/src/main.js
const dotenv = require('dotenv')

dotenv.config({
path: '.env',
})

Ya estás en condiciones de empezar a usar Autoinspector SDK, instalada anteriormente como dependencia. Para eso, debes crear una instancia pasando las credenciales:

/src/main.js
const Autoinspector = require('autoinspector')

const autoinspector = new Autoinspector({
apikey: process.env.AUTOINSPECTOR_API_KEY,
})

Finalmente, debes preparar la aplicación para que al momento de levantarla se encuentre lista y empieces a recibir peticiones.

src/main.js
const express = require('express')

const app = express()

app.listen(3000, () => {
console.log('HTTP server listening on port 3000')
})

Creación de una inspección

El punto de partida de una inspección es su creación. Puedes crear diferentes tipos de inspección, y dependiendo de los mismos, determinados productos pueden ser asignados a dicha inspección. En esta guía crearemos y completaremos una inspección de tipo car. Sin embargo, la implementación es exactamente igual con el resto de los tipos de inspección.

Para crear una inspección, debes agregar una ruta en tu servidor:

src/main.js
app.post('/inspection/car', (req, res) => {
autoinspector.inspections.car
.create({
locale: 'es_AR',
inputs: [
//Aquí rellena con los campos que agregaste en el template y que se necesitan para la creación
],
consumer: {
firstName: req.body.consumer.firstName,
lastName: req.body.consumer.lastName,
email: req.body.consumer.email,
identification: req.body.identification,
},
producer: {
internalId: '123',
},
car: {
plate: req.body.car.plate,
},
templateId: 'YOUR_CUSTOM_TEMPLATE_ID', //Aqui reemplaza YOUR_CUSTOM_TEMPLATE_ID por el id del template que creaste anteriormente
initialStatus: 'started',
delivery: {
disabled: true, //Deshabilito el delivery de inspección debido a que la propagación del link la quiero realizar de manera personalizada
},
})
.then(inspection => {
res.status(201).json(inspection)
})
.catch(err => {
console.error(err)
res.status(500).json({ message: 'Something went wrong' })
})
})
SANITIZACIÓN DE DATOS

Asegúrate siempre de agregar un middleware para sanitizar y validar que la información que recibes en una 'request' sea válida. Aquí no tendremos en cuenta esa parte por ser un ejemplo.

Procesamiento de imágenes

El proceso de validación de los productos que se encuentran en una inspección, es a través de imágenes. Para requerir a Autoinspector la subida de cierta imagen, debes crear un token. Este token es la representación de la solicitud de subida de una imagen, la cual tiene una expiración de 10 minutos y es de único uso. Puedes crear image tokens cuantas veces quieras, siempre y cuando se cumpla con las especificaciones del template. Para ello, debes agregar una nueva ruta a tu servidor que se encargara de ello:

src/main.js
app.post("/image/:productId", (req, res) => {

const token = await autoinspector.images.generateToken({
side:req.body.side,
productId:req.params.productId
})

res.status(201).json({token})
});

Crear webhook

Autoinspector notifica vía webhooks cuando ocurre algún evento en el flujo de una inspección. Para indicar a Autoinspector hacia donde tiene que enviar dichos eventos, debes crear un webhook con un endpoint accessible.

Para recibir dichos eventos, debes agregar una nueva ruta en tu servidor:

src/main.js
app.post('/webhook', (req, res) => {
switch (req.body.event) {
case 'image_processed':
// When a image was processed, you will receive this event
break

case 'inspection_completed':
// When a inspection was finished and all photos attached to it was processed, you will receive this event
break

default:
// another events like inspection_started, inspection_blocked
break
}

res.status(200).json({ message: 'webhook received.' })
})

Una vez que ya tienes la ruta que recibirá los eventos de Autoinspector, puedes crear un webhook dentro del Dashboard.

Para crear un webhook, debes seguir los siguientes pasos:

1. Dirígite al Dashboard de Autoinspector
2. Haz click en el ícono de tu perfil y luego haz click en Configuración
3. Dirígite a la sección de developers
4. Haz click en el botón de añadir un endpoint
5. Rellena el formulario con la información necesaria
6. Una vez completado el formulario, haz click sobre Crear Endpoint
Webhook Tip

El endpoint de tu servidor tiene que ser accessible desde internet. Es por ello que si deseas testear los eventos que Autoinspector envía en tu host, puedes usar una herramienta llamada ngrok para crear un túnel desde internet a tu host.

Cierre de inspección

El punto final en el ciclo de inspección es su finalización, a partir de la cual podrás obtener un veredicto: approved o disapproved. Desde el momento en que una inspección se finaliza, se vuelve inmutable y el resultado se envía vía webhooks.

Para finalizar una inspección, debes crear una ruta en tu servidor que se encargue de eso:

src/main.js
app.post('/inspection/finish/:inspectionId', (req, res) => {
autoinspector.inspections
.finish({
inspectionId: req.params.inspectionId,
})
.then(res => {
res.status(200).json({ message: 'inspection completed successfully' })
})
.catch(err => {
res.status(500).json({ message: 'Something went wrong' })
})
})

Correr la aplicación

Una vez que ya tienes el servidor conectado a Autoinspector, puedes levantarlo corriendo el siguiente comando:

Antes de levantar el servidor, necesitas agregar lo siguiente en el package.json:

package.json
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start":"node ./src/main.js"
}

Finalmente, ya puedes correr el siguiente comando:

npm run start

Creando la aplicacion / Cliente

Una vez que ya tienes una aplicación segura con la que puedes comunicarte con Autoinspector, es MOMENTO de crear una aplicaciÓn con una interfaz gráfica que te permita comunicarte con tu servidor.

Inicio del proyecto

Como primer paso, te ayudaremos a iniciar el proyecto:

npx create-react-app my-app
cd my-app

Formulario para solicitar una inspección

Una vez que ya tenemos el proyecto, vamos a crear un formulario para la solicitud de inspección.

/src/CreateInspectionForm.jsx
import React, { useState } from 'react'

export const CreateInspectionForm = ({ onInspectionCreated }) => {
const [inspection, setInspection] = useState({})

const onSubmit = e => {
e.preventDefault()
fetch({
method: 'POST',
url: 'http://localhost:3000/inspection/car',
body: JSON.stringify(inspection),
})
.then(res => res.json())
.then(inspectionDetails => {
onInspectionCreated(inspectionDetails)
})
.catch(err => {
console.error(err)
})
}

return (
<div>
<h1>Create Inspection | Car</h1>
<form onSubmit={onSubmit}>
<label>Nombre</label>
<input
onChange={e =>
setInspection({
...inspection,
firstName: e.target.value,
})
}
name='firstName'
type='text'
/>
<label>Apellido</label>
<input
onChange={e =>
setInspection({
...inspection,
lastName: e.target.value,
})
}
name='lastName'
type='text'
/>
<label>Identificacion</label>
<input
onChange={e =>
setInspection({
...inspection,
identification: e.target.value,
})
}
name='identification'
type='text'
/>
<label>Email</label>
<input
onChange={e =>
setInspection({
...inspection,
email: e.target.value,
})
}
name='email'
type='email'
/>
<label>Patente</label>
<input
onChange={e =>
setInspection({
...inspection,
plate: e.target.value,
})
}
name='plate'
type='plate'
/>
<button type='submit'>Crear Inspeccion</button>
</form>
</div>
)
}

Formulario para subir imágenes

Luego vamos a crear otro componente para poder subir imágenes de un producto y empezar a procesarlas:

/src/DoInspectionForm.jsx
export const DoInspectionForm = ({
productId,
inspectionId,
onInspectionCompleted,
}) => {

const UploadButton = ({ side }) => {
const [loading, setLoading] = useState(false);
const [success, setSuccess] = useState(false);

const onUploadImage = (e) => {
setLoading(true);

fetch({
method: "POST",
url: "http://localhost:3000/image/" + productId,
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({ side }),
})
.then((res) => res.json())
.then((token) => {
const formData = new FormData();
formData.append("image", e.target.files[0]);

fetch({
method: "POST",
body: formData,
url: "https://api.autoinspector.ai/v1/inspection/image/" + productId,
headers: {
"x-image-token": token,
},
})
.then((res) => res.json())
.then(() => setSuccess(true))
.finally(() => setLoading(false));
});
};

return (
<div>
<label>Imagen {side}</label>
{loading ? (
"Subiendo imagen..."
) : (
<input name={"image-" + side} onChange={onUploadImage} type="file" />
)}
{success && "Imagen subida con éxito!"}
</div>
);
};

const [loading, setLoading] = useState(false);

const onSubmit = (e) => {
setLoading(true);
e.preventDefault();
fetch({
method: "POST",
url: http://localhost:3000/inspection/finish/" + inspectionId,
})
.then((res) => res.json())
.then(() => onInspectionCompleted())
.catch((err) => {
console.error(err);
})
.finally(() => setLoading(false));
};

return (
<form onSubmit={onSubmit}>
<div>
<label>Imagen trasera del vehículo</label>
<UploadButton side="back" />
</div>
<div>
<label>Imagen delantera del vehículo</label>
<UploadButton side="front" />
</div>
{loading ? (
"Finalizando inspección..."
) : (
<button type="submit">Finalizar inspección</button>
)}
</form>
);
};


Correr aplicación

Finalmente vamos a actualizar nuestra página principal para agregar los nuevos componentes que ya creamos:

/src/App.js
import './index.css'
import { useState } from 'react'
import CreateInspectionForm from './CreateInspectionForm'
import DoInspectionForm from './DoInspectionForm'

export default function App() {
const [inspection, setInspection] = useState()
const [wasCompleted, setWasCompleted] = useState(false)

return (
<div>
{!inspection && (
<CreateInspectionForm
onInspectionCreated={inspection => setInspection(inspection)}
/>
)}

{inspection && !wasCompleted && (
<DoInspectionForm
productId={inspection.productId}
inspectionId={inspection.inspectionId}
onInspectionCompleted={() => setWasCompleted(true)}
/>
)}

{wasCompleted && inspection && (
<div>
<p>Inspección {inspection.inspectionId} completada correctamente!</p>
<button
onClick={() => {
setWasCompleted(false)
setInspection(undefined)
}}
>
Crear otra inspección
</button>
</div>
)}
</div>
)
}

Una vez que la página principal fue actualizada, puedes correr el siguiente comando:

npm run start

Si abres el navegador y te diriges a localhost:3000, vas a poder observar la app terminada.