https://d226lax1qjow5r.cloudfront.net/blog/blogposts/create-an-emergency-broadcast-system-with-vonage-node-and-mongodb/emergency-broadcast-system.png

Crear un sistema de radiodifusión de emergencia con Vonage, Node y MongoDB

Publicado el February 1, 2022

Tiempo de lectura: 6 minutos

Es difícil hacer algo bien durante una emergencia, ¡sobre todo si cunde el pánico! Si te encuentras en una emergencia, algo tan sencillo como avisar a la persona adecuada de que necesitas ayuda puede resultar imposible. Hoy, vamos a resolver esto mediante la construcción de una aplicación web que le permite hacer clic en un solo botón para notificar a su familia que usted está en medio de una emergencia a través de texto y enviar su ubicación. Crearemos este sitio web utilizando Node.js, Express, MongoDB y la API Messages API de Vonage. Node es un popular servidor web, y Express es un framework que los desarrolladores utilizan a menudo con él. MongoDB es una base de datos NoSQL, y la API Messages API de Vonage te permite enviar mensajes rápidamente (como mensajes SMS) mediante programación.

Tu aplicación web tendrá este aspecto.

Emergency broadcast web app demo

Puedes añadir contactos, verlos y, cuando pulsas el botón Alerta, envía un mensaje SMS a todos tus contactos para informarles de tu ubicación y de que te encuentras en una emergencia.

Mientras nos sigues, puedes encontrar todo el código de este proyecto en este repositorio de GitHub.

¿Listo para empezar? Creemos una aplicación de difusión de emergencias.

Requisitos previos

Para seguir este tutorial, necesitas Node (puedes descargarlo aquí). También necesitas una Account de Vonage, que puedes registrarte aquí. También necesitarás una cuenta cuenta MongoDB.

Después de registrarte en tu Account de MongoDB, necesitas configurar una base de datos MongoDB Atlas, que puedes aprender a en la documentación de MongoDB.

Una vez que hayas creado tu Account de Vonage, deberás realizar algunas configuraciones iniciales.

Instala la CLI de Vonage globalmente con este comando:

npm install @vonage/cli -g

Luego, configura la CLI con tu clave y secreto de API de Vonage. Puedes encontrar esta información en el panel del desarrollador.

vonage config:set --apiKey=VONAGE_API_KEY --apiSecret=VONAGE_API_SECRET

Cree un nuevo directorio para su proyecto y CD en él:

mkdir my_project
cd my_project

Ahora, utiliza la CLI para crear una aplicación de Vonage con este comando:

vonage apps:create

Desplázate hasta Mensajes, pulsa la barra espaciadora y pulsa intro. Ahora necesitas un número para poder recibir llamadas. Puedes alquilar uno utilizando el siguiente comando (sustituyendo el código del país por tu código). Por ejemplo, si estás en Gran Bretaña, sustituye US por GB:

vonage numbers:search US
vonage numbers:buy [NUMBER] [COUNTRYCODE]

Ahora vincula el número a tu aplicación:

vonage apps:link --number=VONAGE_NUMBER APP_ID

Construcción del sistema de radiodifusión

Para empezar, necesitas instalar las librerías JavaScript que utilizarás para este proyecto de la siguiente manera:

npm install express body-parser dotenv firebase mongodb mongoose @vonage/server-sdk

A continuación, crea un archivo .env en tu proyecto y añade las siguientes variables:

API_KEY=your_vonage_api_key
API_SECRET=your_vonage_secret
APPLICATION_ID=your_vonage_application_id
PRIVATE_KEY=your_vonage_private_key
FROM_NUMBER=your_vonage_number
PORT=5000
MONGO_URL=your_mongodb_url

Asegúrate de reemplazar todo lo que aparece después del signo igual para cada variable con la información de tus cuentas de Vonage y MongoDB.

Ahora, crea un archivo llamado app.js e importa estas bibliotecas:

require('dotenv/config')
require('mongodb')
const express = require('express')
const Vonage = require('@vonage/server-sdk')
const bodyParser = require('body-parser')
const mongoose = require('mongoose')

Empecemos por crear una aplicación "Hello, World!" aplicación Express. He aquí cómo:

const app = express()

app.get('/', function(req, res) {
    res.send('Hello World!')
})

app.listen(process.env.PORT)

Ahora, ejecuta tu código así:

node app.js

Cuando ejecute este código y vaya a su servidor local (http://127.0.0.1:5000), debería decir Hello, World!

Ahora, añade este código debajoconst app = express():

app.use(bodyParser.json())
app.use(bodyParser.urlencoded({
    extended: true
}))
app.use(express.static('public'))

Este código le ayuda a aceptar peticiones POST usando Express y le dice a Express que sirva ficheros estáticos desde un directorio llamado public.

Es hora de añadir código para conectarte a tu base de datos MongoDB. Añade este código a tu aplicación y actualiza tu archivo .env para incluir una variable de entorno llamada MONGO_URL que contiene el enlace a tu base de datos MongoDB.

mongoose.connect(process.env.MONGO_URL, {
    useNewUrlParser: true,
    useUnifiedTopology: true
})
const contactsSchema = new mongoose.Schema({
    name: String,
    number: Number
})
const Contacts = mongoose.model('Contacts', contactsSchema)

El código anterior utiliza Mongoose para conectarse a tu base de datos MongoDB, crea un esquema para tus contactos (las personas a las que enviarás un mensaje SMS) y crea un nuevo modelo llamado Contacts para añadir y obtener los contactos de tu base de datos.

Luego, agrega este código para ayudar a enviar mensajes SMS usando la API de mensajes de Vonage.

const vonage = new Vonage({
    apiKey: process.env.API_KEY,
    apiSecret: process.env.API_SECRET,
    applicationId: process.env.APPLICATION_ID,
    privateKey: process.env.PRIVATE_KEY
})

El código anterior crea un nuevo objeto de Vonage e ingresa tu clave de API, secreto, ID de aplicación y la clave privada de tu aplicación.

Ahora, vamos a crear algunos endpoints. Añade el siguiente código a app.js:

app.post('/contacts', function(req, res) {
    const contact = new Contacts({
        name: req.body.name
    })
    contact.save()
    res.redirect('/')
})

Ahora, cuando envíes una petición POST a /contactseste código crea un nuevo contacto en tu MongoDB y redirige al usuario a la página de inicio.

Vamos a crear un endpoint para obtener todos los contactos de tu base de datos. Añade el siguiente código a app.js:

app.get('/contacts', function(req, res) {
    Contacts.find({}, function(err, contacts) {
        if(err){
            console.log(err)
       }
       else {
           res.json(contacts)
       }
   })
})

Este código obtiene todos los contactos de tu base de datos y los devuelve como JSON cuando envías una petición GET a /contacts.

Ahora, vamos a definir un endpoint para enviar un mensaje SMS. Añade este código a app.js:

app.post('/alert', function(req, res) {
    let long = req.body['coordinates']['long']
    let lat = req.body['coordinates']['lat']
    let contacts = req.body['contacts']
    for (let i = 0; i <= contacts.length; i++) {
        vonage.channel.send({
                'type': 'sms',
                "number": contacts[i].number
            }, {
                'type': 'sms',
                "number": process.env.FROM_NUMBER
            }, {
                'content': {
                    'type': 'text',
                    'text': `SOS! Your friend is in an emergency! Their latitude is ${lat} and` +
                        `their longitude is ${long}!`
                }
            },
            (err, data) => {
                if (err) {
                    console.error(err)
                } else {
                    console.log(data.message_uuid)
                }
            }
        )
    }
})

Este punto final acepta una solicitud POST con JSON que contiene la latitud y longitud del usuario y una lista de números a los que enviar un mensaje SMS.

let long = req.body['coordinates']['long']
let lat = req.body['coordinates']['lat']
let contacts = req.body['contacts']

Luego, recorre los contactos y usa Messages API de Vonage para enviar un mensaje a cada número.

for (let i = 0; i <= contacts.length; i++) {
    vonage.channel.send({
                'type': 'sms',
                'number': contacts[i].number
            }, {
                'type': 'sms',
                'number': process.env.FROM_NUMBER
            }, {
                'content': {
                    'type': 'text',
                    'text': `SOS! Your friend is in an emergency! Their latitude is ${lat} and` +
                        `their longitude is ${long}!`
                }
            },

Por último, vamos a actualizar nuestro punto final de la página de inicio para gestionar cuándo los usuarios van a la página de inicio de nuestra aplicación web. Cambia este código de antes:

app.get('/', function(req, res) {
    res.send('Hello World!')
})

A esto:

app.get('/', function(req, res) {
    res.sendFile('index.html')
})

Ahora, su página de inicio servirá el archivo index.html, que está a punto de crear.

Sigue adelante y crea un nuevo archivo llamado index.html y añade el siguiente código:

<!DOCTYPE html>
<html lang='en'>
   <head>
      <meta charset='UTF-8'>
      <title>Emergency Broadcast</title>
      <link rel='stylesheet' href='style.css'>
   </head>
   <body>
      <h1 id='top'>Add Contact</h1>
      <form action='/contacts' method='POST'>
         <div>
            <input id='name' class='forms' type='text' name='name' placeholder='name'> <br>
            <input id='number' class='forms' type='text' name='number' placeholder='number'>
         </div>
         <div>
            <input type='submit' value='Add' class='tons' id='add'>
         </div>
      </form>
      <br> <br>
      <h1>Your Contacts</h1>
      <div></div>
      <div id='contacts'></div>
      <button onclick='alert_them()' class='tons' id='alert'>ALERT</button>
   </body>
</html>

El HTML anterior crea un formulario que permite introducir el nombre y el número de una persona y pulsar un botón Añadir. Al pulsar Añadir el formulario envía una petición POST a /contactsque crea un nuevo contacto en su base de datos. Este HTML también tiene un botón ALERT. Cuando lo pulsas, envía una petición POST a /alertenviando un mensaje SMS a todos los contactos de su base de datos.

Por último, tienes que añadir algo de JavaScript a este HTML para mostrar la lista de contactos del usuario y preparar los datos para enviarlos a /alert.

Después del botón ALERT en tu HTML, añade una etiqueta script y define un objeto llamado data.

<script>
    let data = {}
</script>

Utilizaremos data para almacenar los datos que enviaremos a /alert.

A continuación, llama a una función llamada httpPostAsync e introduce ‘/contacts’y create_contacts:

<script>
    let data = {}
    httpPostAsync('/contacts', create_contacts)
</script>

Ahora, define create_contacts:

function create_contacts(contacts) {
    data['contacts'] = []
    for (let i = 0; i < contacts.length; i++) {
        let contact = contacts[i]
        data['contacts'].push(contact)
        const newDiv = document.createElement('div')
        newDiv.className = 'left'
        const newContent = document.createTextNode(contact.name)
        newDiv.appendChild(newContent)
        const currentDiv = document.getElementById('contacts')
        document.body.insertBefore(newDiv, currentDiv)
    }
}

Esta es una función callback httpPostAsync será llamada cuando obtenga los datos de contacto del servidor. Acepta contactos como parámetro (los datos de contacto). Primero, esta función añade un array a data['contacts']. Luego, recorre los contactos del servidor y añade cada contacto al array, y crea un nuevo HTML div con el nombre de cada contacto.

Ahora, debe definir httpPostAsync:

function httpPostAsync(theUrl, callback) {
    let xmlHttp = new XMLHttpRequest()
    xmlHttp.onreadystatechange = function() {
        if (xmlHttp.readyState == 4 && xmlHttp.status == 200)
            callback(JSON.parse(xmlHttp.responseText))
    }
    xmlHttp.open('GET', theUrl, true)
    xmlHttp.send()
}

Este código envía una solicitud GET a una URL y pasa el JSON que recibió en la respuesta a una función de devolución de llamada.

Por último, hay que definir una función que responda cuando un usuario pulse el botón ALERTAR.

function alert_them() {
    function success(position) {
        data['coordinates'] = {}
        data['coordinates'] = position.coords.latitude
        data['coordinates'] = position.coords.longitude
        let xmlHttp = new XMLHttpRequest()
        xmlHttp.open('POST', '/alert', true)
        xmlHttp.setRequestHeader('Content-Type', 'application/json')
        xmlHttp.send(JSON.stringify(data))
        alert('Message Sent!')
    }

    function error() {
        console.log('error')
    }
    if (!navigator.geolocation) {
        console.log('Geolocation is not supported by your browser')
    } else {
        navigator.geolocation.getCurrentPosition(success, error)
    }
}

Esta función comprueba si navigator.geolocation es true. Navigator.geolocation permite obtener la ubicación del usuario. Tienes que comprobar si es cierto porque algunas versiones de navegador no lo soportan. Si es cierto, la función anterior llama a navigator.geolocation.getCurrentPosition(success, error) y pasa dos funciones: una que se encarga de lo que ocurre si el navegador obtiene correctamente la ubicación del usuario y otra que se encarga de los errores.

La función success añade las coordenadas del usuario a data['coordinates'] y envía una solicitud POST a /alert con los datos.

function success(position) {
    data['coordinates'] = {}
    data['coordinates'] = position.coords.latitude
    data['coordinates'] = position.coords.longitude
    let xmlHttp = new XMLHttpRequest()
    xmlHttp.open('POST', '/alert', true)
    xmlHttp.setRequestHeader('Content-Type', 'application/json')
    xmlHttp.send(JSON.stringify(data))
}

Su punto final /alert envía un mensaje SMS a todos los contactos de la base de datos para informarles de que el remitente está en apuros, junto con su latitud y longitud. Ahora todo lo que necesitas es dar estilo a tu aplicación con algo de CSS. Crea un nuevo archivo en public llamado style.css y añade el siguiente código:

body {
    background-color: lavenderblush;
    text-align: center
}

h1 {
    color: #111;
    font-family: 'Helvetica Neue', sans-serif;
    font-size: 30px;
    font-weight: bold;
    letter-spacing: -1px;
    line-height: 1;
    text-align: center; 
}

.forms {
    height: 2.5em;
    width: 30%;
}

.tons {
    margin-top: 1em;
    background-color: #4CAF50; /* Green */
    border: none;
    color: #f8f8ff;
    padding: 15px 32px;
    text-align: center;
    text-decoration: none;
    display: inline-block;
    font-size: 22px;
    font-family: Arial, serif;
}

.custom-field input {
    border: none;
    -webkit-appearance: none;
    -ms-appearance: none;
    -moz-appearance: none;
    appearance: none;
    background: #f2f2f2;
    padding: 12px;
    border-radius: 3px;
    width: 250px;
    font-size: 14px;
}

#alert {
    margin-bottom: 5em;
    margin-top:1em;
    background-color:red;
}

#alert:hover {
    background-color: black;
}

#add {
    background-color:black;
}

#add:hover {
    background-color: pink;
}

#top {
    margin-top: 5em;
    margin-bottom: 1.5em;
}

.cons{
    font-size: 22px;
}

#number {
    margin-top: 1em;
}

Ahora, cuando vayas a la página de inicio de tu sitio web, deberías ver un sitio web como el de la imagen del principio de este artículo.

Añádase como contacto y pulse alerta.

Debería recibir un mensaje de texto con su longitud y latitud para informarle de que se encuentra en una situación de emergencia.

Reflexiones finales

Esta demo es sólo un punto de partida. Hay un montón de características que puedes añadirle. Por ejemplo, si estuvieras usando esto en producción, te gustaría crear una función para manejar diferentes usuarios (iniciar sesión con un nombre de usuario y contraseña, etc.). También podrías añadir funciones como editar contactos y añadir opciones para saber qué tipo de emergencia se está produciendo. Si decides desarrollar esta demo, me encantaría ver lo que haces: asegúrate de enviarnos lo que construyas a Twitter. Además, asegúrate de unirte a la comunidad de desarrolladores de Vonage para obtener más contenido y tutoriales increíbles. Puedes seguir a Vonage en Twitter aquí y únete a nuestro canal de Slack aquí. Espero que hayas disfrutado de este tutorial. ¡Gracias por leernos!

Compartir:

https://a.storyblok.com/f/270183/400x394/540f26da70/cory-althoff.png
Cory AlthoffAntiguo miembro del equipo de Vonage

Cory Althoff es defensor de los desarrolladores en Vonage y autor de dos libros: El programador autodidacta" y "El informático autodidacta". Book Authority nombró a "The Self-Taught Programmer" uno de los mejores libros de programación de todos los tiempos, y The Next Web lo incluyó en la lista de los diez libros que te ayudarán a convertirte en un mejor ingeniero de software. Cory vive en la zona de la bahía con su mujer y su hija.