
Compartir:
Pranav es ingeniero de software sénior en Moneycontrol, donde construye aplicaciones web de última generación con React y Next.js. También escribe sobre rendimiento y optimización en LearnersBucket.
Alerta de tráfico a través de SMS con Vonage y Google Maps API
Tiempo de lectura: 11 minutos
Visión general
En este mundo ajetreado en el que las piezas de la vida se mueven sin cesar, los usuarios valoran recuperar la información de la forma más cómoda posible. Esto no siempre es fácil, sobre todo en países como la India, donde la cobertura de la red de Internet en zonas remotas es más débil.
Supongamos, por ejemplo, que estás a punto de salir de la oficina para volver a casa después de un día ajetreado y quieres comprobar si hay tráfico en tu ruta, pero tu conexión a Internet es lenta. ¿Qué pasaría si pudieras enviar un SMS con tus posiciones de salida y llegada y obtener al instante la información sobre el tráfico? Te salvaría la vida.
En este artículo, voy a mostrar cómo se puede crear una alerta de tráfico a través de SMS utilizando Vonage y Google Maps API en Node.js.
Requisitos previos
Antes de empezar, asegúrate de haber instalado lo siguiente:
Node.js. Node.js es un entorno de ejecución JavaScript multiplataforma de código abierto.
ngrok - Se requiere una Account gratuita. Esta herramienta permite a los desarrolladores exponer a Internet un servidor de desarrollo local.
CLI de Vonage - Una vez instalado Node.js, puedes usar
npm install -g @vonage/clipara instalarlo. Esta herramienta te permite crear y administrar tus aplicaciones de Vonage.
Vonage API Account
To complete this tutorial, you will need a Vonage API account. If you don’t have one already, you can sign up today and start building with free credit. Once you have an account, you can find your API Key and API Secret at the top of the Vonage API Dashboard.
Una vez que hayas creado una Account, podrás encontrar tu API Key y API Secret en la parte superior del Panel de API de Vonage.

Una vez que haya recibido la Clave API y Secreto de la APIpuede utilizarlos para la SMS API.
API de Google Maps
También necesitaremos API de dirección de Google. Cree una Account de Google e inicie sesión para acceder a créditos gratuitos para utilizar la API de Google y la Clave API.

Para obtener la clave API de Google Maps:
Ir a la Plataforma Google Maps > Página de credenciales.
En la página Credenciales, haga clic en Crear credenciales > Clave API. La Clave API muestra su recién creada clave API.
Haga clic en Cerrar. La nueva clave API aparece en la página Credenciales en Claves API.
Desglose de problemas
La implementación de esta aplicación puede dividirse en tres partes:
Recibir y leer el mensaje SMS.
Extrae las ubicaciones de origen y destino del texto del SMS y obtén los detalles del tráfico de la API de Google Maps.
Procesa los datos de tráfico y devuelve el SMS en un formato textual y legible por humanos.
Configurar
Como nuestra aplicación se desarrollará en Node.js, asegúrate de tener Nodejs instalado en el sistema.
Instale las dependencias ejecutando este comando en su terminal:
Crea un único archivo llamado App.js que ejecutará la aplicación en el puerto 3000 y manejará todo el procesamiento dentro de él.
Hemos utilizado el paquete dotenv paquete npm para obtener las variables de entorno. Usando esto, podemos almacenar secretos de forma segura.
const app = require('express')()
const bodyParser = require('body-parser')
if (process.env.NODE_ENV !== "production") {
require("dotenv").config();
}
app.use(bodyParser.json())
app.use(bodyParser.urlencoded({ extended: true }))
app.listen(process.env.PORT || 3000, "127.0.0.1", () => {
console.log("Server Running on Port ", process.env.PORT || 3000);
});
Para almacenar y acceder a las variables de entorno, cree un archivo .env en su directorio raíz y añada las propiedades.
PORT = 3000Se puede acceder a estas propiedades mediante process.env.PORT
Recibir SMS
El primer paso es recibir el SMS y leerlo. Vonage proporciona un SDK Node.js para usar clientes de SMS dentro de nuestra aplicación Node.
Puede seguir este tutorial sobre cómo puedes recibir el Mensaje en una aplicación Node.js
El siguiente paso es configurar la API de entrada y agregarla a la consola de Vonage. De esta manera, cada vez que se envíe un SMS a nuestro número, se llamará a la API de entrada y podremos leer ese SMS.
Hay un tutorial detallado sobre cómo configurar la API de entrada y leer los SMS.
La API de entrada es lo que exponemos a cualquier aplicación de terceros a la que envían los datos.
Cualquier GET o POST que reciba nuestra API /webhooks/inbound-sms reciba será pasada a la función handleInboundSms función
app.route("/webhooks/inbound-sms")
.get(handleInboundSms)
.post(handleInboundSms);
function handleInboundSms(request, response) {
// reads the SMS body
const params = Object.assign(request.query, request.body);
// process the SMS text
getTrafficDetailsAndSendSMS(params);
// notify that we have received SMS
response.status(204).send();
}Para que esta API de entrada funcione, tendremos que poner en marcha nuestra aplicación. Podemos hacerlo utilizando ngrok.
Para configurar la aplicación en vivo, primero configurar ngrok.
Y luego ejecuta la aplicación node localmente
Una vez que la aplicación local se está ejecutando, podemos asignarla y ponerla en marcha utilizando ngrok.
Resultado esperado:

Una vez que la aplicación esté activa, recibiremos una URL pública, por ejemplo https://58c8-103-179-3-99.in.ngrok.io
Agrega esta URL al panel de Vonage para que podamos escuchar la API entrante.

Ahora que ya podemos recibir el SMS, procesemos el texto y obtengamos la información de tráfico de Google.
Obtener la información de tráfico entre dos rutas utilizando la API de Google Maps
Para extraer la información de origen y destino de los SMS que recibimos a través de la API de entrada, es necesario que el texto del SMS tenga un formato determinado para que se pueda analizar mejor. He creado una plantilla sencilla que es más fácil de procesar.
Por ejemplo, para recibir información sobre el tráfico entre Bombay y Pune, creemos el siguiente SMS:
Traffic between Mumbai and PuneEn el ejemplo anterior Mumbai es el origen y Pune es el destino.
En la función getTrafficDetailsAndSendSMS(params); podemos tomar el cuerpo del SMS y extraer la fuente.
function getTrafficDetailsAndSendSMS(params) {
// get the source and destination by parsing the text
const { origin, destination } = parseText(params);
// get the traffic details and routes
const routes = getTrafficDetails({ origin, destination });
// send back the SMS
sendSMS(params.msisdn, routes);
} Analizar texto
Para encontrar las rutas, tendremos que extraer el origen y el destino de los SMS que hemos recibido.
El método parseText(params) extrae el origen y el destino del texto del SMS y lo devuelve.
function parseText({ text }) {
let sampleText = "Traffic between mumbai and pune";
if (text) {
sampleText = text;
}
sampleText = sampleText.trim();
const characters = sampleText.split(" ");
const origin = characters[2];
const destination = characters[4];
return { origin, destination };
} Obtenga información sobre el tráfico
Ahora esto source y destination se pueden pasar a la API de matriz de distancias de Google que obtiene los detalles del tráfico.
Para realizar una llamada a la API desde nuestra aplicación necesitaríamos axiosasí que vamos a añadir esa dependencia.
Para obtener la información de tráfico tenemos que pasar el parámetro departure_time en el parámetro de consulta. Estamos pasando now para obtener los detalles del tráfico actual.
Además, hemos establecido el mode como driving. Esto se puede hacer configurable y puede ser aceptado a través del SMS junto con las rutas para proporcionar una mejor experiencia de usuario.
async function getTrafficDetails({ origins, destinations }) {
try {
const YOUR_API_KEY = process.env.GOOGLE_MAP_API_KEY;
const mode = "driving";
const departure_time = "now";
var config = {
method: "get",
url: `https://maps.googleapis.com/maps/api/directions/json?origins=${origins}&destinations=${destinations}&mode=${mode}&departure_time=${departure_time}&language=en-US&key=${YOUR_API_KEY}`,
};
let response = await axios(config);
response = await response.data;
const routes = getRoutes(response);
return routes.join(" \n\n ");
} catch (e) {
console.error("There was some error while getting routes details", e);
}
}
A continuación se muestra un ejemplo de respuesta de la API de Google Maps.
const response = {
routes: [
{
bounds: {
northeast: { lat: 41.8781139, lng: -87.6297872 },
southwest: { lat: 34.0523525, lng: -118.2435717 },
},
copyrights: "Map data ©2022 Google, INEGI",
legs: [
{
distance: { text: "579 km", value: 932311 },
duration: { text: "8 hours 48 mins", value: 31653 },
duration_in_traffic: { text: "8 hours 55 mins", value: 932311 },
end_address: "Panvel",
end_location: { lat: 37.0842449, lng: -94.513284 },
start_address: "Mumbai",
start_location: { lat: 41.8781139, lng: -87.6297872 },
steps: [],
traffic_speed_entry: [],
via_waypoint: [],
},
{
distance: { text: "217 km", value: 349512 },
duration: { text: "3 hours 17 mins", value: 11799 },
duration_in_traffic: { text: "3 hours 40 mins", value: 932311 },
end_address: "Alephata",
end_location: { lat: 35.4675612, lng: -97.5164077 },
start_address: "Panvel",
start_location: { lat: 37.0842449, lng: -94.513284 },
steps: [],
traffic_speed_entry: [],
via_waypoint: [],
},
{
distance: { text: "1,328 km", value: 2137682 },
duration: { text: "19 hours 28 mins", value: 70097 },
duration_in_traffic: { text: "20 hours 22 mins", value: 932311 },
end_address: "Pune",
end_location: { lat: 34.0523525, lng: -118.2435717 },
start_address: "Alephata",
start_location: { lat: 35.4675612, lng: -97.5164077 },
steps: [],
traffic_speed_entry: [],
via_waypoint: [],
},
],
summary: "I-55 S and I-44",
warnings: [],
waypoint_order: [0, 1],
},
],
status: "OK",
};Compruebe la estructura de respuesta completa
Hemos procesado la respuesta que recibimos de la API de Google Direction y hemos formado una cadena legible a partir de ella que nos mostrará las diferentes rutas que podemos tomar y cuánto tiempo y distancia puede llevarnos llegar al destino.
Para formar la cadena, tomamos todos los caminos de las rutas dadas, su distancia y el tiempo para llegar al destino normalmente y con tráfico.
Convertiremos todas las rutas a una cadena legible por humanos y luego las devolveremos juntas.
Para procesar la respuesta, utilizaremos funciones auxiliares.
const getRoutes = ({ routes }) => {
// calculate the overall distance of all the routes
return routes.reduce((a, b, l) => {
const { legs } = b;
let via = "";
let normalTime = 0;
let timeInTraffic = 0;
// for each route, calculate the distance path wise, from one to another
const distance = legs.reduce((x, y, i) => {
const { distance, duration, duration_in_traffic, steps, start_address, end_address } = y;
normalTime += getTimeInMinutes(duration.text);
timeInTraffic += getTimeInMinutes(duration_in_traffic.text);
if (i !== legs.length - 1) {
via = via ? via + " -> " + end_address : end_address;
}
const string = `From ${start_address} to ${end_address} it takes ${duration.text} normally and ${duration_in_traffic.text} in traffic to cover a distance of ${distance.text}`;
x.push(string);
return x;
}, []);
// for the final string
const finalString = `Route${l + 1} via ${via} will take ${processTime(
normalTime
)} normally and ${processTime(
timeInTraffic
)} in traffic. Path via breakdown is: ${distance.join(" AND ")}`;
// push the string
a.push(finalString);
return a;
}, []);
};
// helper function extract to hours and minutes from text
// and return time in minutes
const getTimeInMinutes = (timeText) => {
timeText = timeText.split(" ");
let hrs = timeText[0];
let mins = timeText[2];
return parseInt(hrs) * 60 + parseInt(mins);
};
// helper function to get hours and mins from the time
const processTime = (time) => {
const hrs = Math.floor(time / 60);
const mins = time % 60;
return `${hrs} hours ${mins} mins`;
};
Este método nos devolverá el array de rutas con la distancia por camino en tiempo normal y en tráfico y podemos devolverlas en formato textual.
Devuelva el SMS con los detalles del tráfico
En la función getTrafficDetails() estamos procesando una respuesta de la API de tráfico y utilizando esta respuesta para generar un texto que contiene los detalles del tráfico. El texto de salida tiene este aspecto:
"Route1 via Panvel -> Alephata will take 31 hours 33 mins normally and 32 hours 57 mins in traffic. Path via breakdown is: From Mumbai to Panvel it takes 8 hours 48 mins normally and 8 hours 55 mins in traffic to cover a distance of 579 km AND From Panvel to Alephata it takes 3 hours 17 mins normally and 3 hours 40 mins in traffic to cover a distance of 217 km AND From Alephata to Pune it takes 19 hours 28 mins normally and 20 hours 22 mins in traffic to cover a distance of 1,328 km"
"Route2 via Eastern Express Highway -> Lonavala will take 11 hours 33 mins normally and 12 hours 57 mins in traffic. Path via breakdown is: From Mumbai to Eastern Express Highway it takes 7 hours 48 mins normally and 7 hours 55 mins in traffic to cover a distance of 579 km AND From Eastern Express Highway to Lonavala it takes 2 hours 17 mins normally and 2 hours 40 mins in traffic to cover a distance of 200 km AND From Lonavala to Pune it takes 1 hours 28 mins normally and 2 hours 22 mins in traffic to cover a distance of 1,28 km"
Este texto generado contiene el tiempo que se tarda en llegar al destino desde el lugar de origen en horas normales y en horas punta. Podemos devolver esta información al mismo número de teléfono del que recibimos la entrada.
Podemos usar el SMS API de Vonage para enviar la información. Cuando recibimos el SMS, también recibimos el número de móvil del remitente al que podemos devolver el SMS.
async function sendSMS(msisdn, routes) {
try {
const data = qs.stringify({
from: "Vonage APIs",
text: routes,
to: msisdn,
api_key: process.env.VONAGE_API_KEY,
api_secret: process.env.VONAGE_API_SECRET,
});
const config = {
method: "post",
url: "https://rest.nexmo.com/sms/json",
headers: {
"Content-Type": "application/x-www-form-urlencoded",
},
data: data,
};
let response = await axios(config);
response = await response.data;
} catch (e) {
console.error("There was some error while sending sms", e);
}
}Puede encontrar el código fuente de esta aplicación aquí
Conclusión
Ahora que hemos creado la alerta de tráfico instantánea a través de la notificación por SMS, puedes consultar este artículo para crear un sistema de alerta diferente con SMS, o a través de WhatsApp utilizando Mensajes API de Vonage.
La participación de la comunidad siempre es bienvenida. Únete a Vonage en GitHub para ver ejemplos de código y en Slack de la comunidad para preguntas o comentarios. Envía a los desarrolladores de Vonage un tweet y cuéntales algo interesante que hayas creado con las API de Vonage.
También puedes ponerte en contacto conmigo en mi blog learnersbucket.com donde escribo artículos sobre desarrollo web.
