https://a.storyblok.com/f/270183/44318/fcaf6372c5/emergency-broadcast-system.png

Crie um sistema de transmissão de emergência com a Vonage, o Node e o MongoDB

Publicado em February 1, 2022

Tempo de leitura: 7 minutos

É difícil fazer qualquer coisa direito durante uma emergência, especialmente se você estiver em pânico! Se você estiver passando por uma emergência, algo tão simples quanto avisar a pessoa certa de que precisa de ajuda pode se tornar impossível. Hoje, vamos resolver isso criando um aplicativo web que permita que você clique em um único botão para notificar sua família de que está passando por uma emergência por meio de mensagem de texto e enviar sua localização. Vamos criar esse site usando Node.js, Express, MongoDB e a Messages API. O Node é um servidor web popular, e o Express é um framework que os desenvolvedores costumam usar junto com ele. O MongoDB é um banco de dados NoSQL, e a Messages API permite enviar mensagens rapidamente (como mensagens SMS) por meio de programação.

Seu aplicativo web ficará assim.

Emergency broadcast web app demo

Você pode adicionar contatos, visualizá-los e, ao pressionar o botão “Alerta”, o aplicativo envia uma mensagem SMS para todos os seus contatos, informando sua localização e que você está passando por uma emergência.

À medida que você for acompanhando, poderá encontrar todo o código deste projeto em este repositório do GitHub.

Pronto para começar? Vamos criar um aplicativo de transmissão de emergência!

Pré-requisitos

Para seguir este tutorial, você precisa do Node (você pode baixá-lo aqui). Você também precisa de um Account na Vonage, na qual você pode criar aqui. Você também precisará de uma Account no MongoDB.

Depois de se cadastrar no Account da MongoDB, você precisa configurar um banco de dados do MongoDB Atlas; você pode aprender a fazer na documentação do MongoDB.

Depois de criar sua conta na Vonage, você precisará realizar algumas configurações iniciais.

Instale a CLI do Vonage globalmente com este comando:

npm install @vonage/cli -g

Em seguida, configure a CLI com sua chave e seu segredo da API da Vonage. Você pode encontrar essas informações no Painel do Desenvolvedor.

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

Crie um novo diretório para o seu projeto e acesse-o com o comando `cd`:

mkdir my_project
cd my_project

Agora, use a CLI para criar um aplicativo da Vonage com este comando:

vonage apps:create

Navegue até “Mensagens”, clique na barra de espaço e pressione Enter. Agora você precisa de um número para poder receber chamadas. Você pode alugar um usando o comando a seguir (substituindo o código do país pelo seu). Por exemplo, se você estiver na Grã-Bretanha, substitua US por GB:

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

Agora, vincule o número ao seu aplicativo:

vonage apps:link --number=VONAGE_NUMBER APP_ID

Construindo o sistema de transmissão

Para começar, você precisa instalar as bibliotecas JavaScript que usará neste projeto da seguinte maneira:

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

Em seguida, crie um arquivo .env no seu projeto e adicione as seguintes variáveis:

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

Certifique-se de substituir tudo o que vem após cada sinal de igual em cada variável pelas informações das suas contas da Vonage e do MongoDB.

Agora, crie um arquivo chamado app.js e importe 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')

Vamos começar criando um "Hello, World!" aplicativo Express. Veja como:

const app = express()

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

app.listen(process.env.PORT)

Agora, execute seu código desta forma:

node app.js

Ao executar esse código e acessar seu servidor local (http://127.0.0.1:5000), deverá aparecer a seguinte mensagem: Hello, World!

Agora, adicione este código logo abaixoconst app = express():

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

Este código ajuda você a aceitar solicitações POST usando o Express e instrui o Express a servir arquivos estáticos a partir de um diretório chamado public.

É hora de adicionar o código para se conectar ao seu banco de dados MongoDB! Adicione este código ao seu aplicativo e atualize seu .env arquivo para incluir uma variável de ambiente chamada MONGO_URL que contenha o link para o seu banco de dados 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)

O código acima usa o Mongoose para se conectar ao seu banco de dados MongoDB, cria um esquema para seus contatos (as pessoas para quem você enviará uma mensagem SMS) e cria um novo modelo chamado Contacts para adicionar e recuperar os contatos do seu banco de dados.

Em seguida, adicione este código para ajudar a enviar mensagens SMS usando a SMS API da 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
})

O código acima cria um novo objeto Vonage e passa sua chave de API, seu segredo, o ID do aplicativo e a chave privada para o seu aplicativo.

Agora, vamos criar alguns endpoints. Adicione o código a seguir a app.js:

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

Agora, quando você enviar uma solicitação POST para /contacts, esse código cria um novo contato no seu MongoDB e redireciona o usuário para a página inicial.

Vamos criar um endpoint para obter todos os contatos do seu banco de dados. Adicione o código a seguir 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 obtém todos os contatos do seu banco de dados e os retorna no formato JSON quando você envia uma solicitação GET para /contacts.

Agora, vamos definir um endpoint para enviar uma mensagem SMS. Adicione 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 endpoint aceita uma solicitação POST com JSON contendo a latitude e a longitude do usuário, além de uma lista de números para os quais enviar uma mensagem SMS.

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

Em seguida, o programa percorre os contatos e usa a Messages API do Vonage para enviar uma mensagem para 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 fim, vamos atualizar o endpoint da nossa página inicial para lidar com a situação em que os usuários acessam a página inicial do nosso aplicativo web. Altere este código que vimos anteriormente:

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

A isso:

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

Agora, sua página inicial exibirá o arquivo index.html, que você está prestes a criar.

Vá em frente e crie um novo arquivo chamado index.html e adicione o seguinte 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>

O código HTML acima cria um formulário que permite inserir o nome e o número de uma pessoa e clicar no botão “Adicionar”. Ao clicar em “Adicionar”, o formulário envia uma solicitação POST para /contacts, o que cria um novo contato em seu banco de dados. Esse código HTML também possui um botão “ALERT”. Ao clicar nele, ele envia uma solicitação POST para /alert, enviando uma mensagem SMS para todos os contatos em seu banco de dados.

Por fim, você precisa adicionar um pouco de JavaScript a este HTML para exibir a lista de contatos do usuário e preparar os dados a serem enviados para /alert.

Após o botão ALERT no seu código HTML, adicione uma tag de script e defina um objeto chamado data.

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

Vamos usar data para armazenar os dados a serem enviados para /alert.

Em seguida, chame uma função chamada httpPostAsync e passe ‘/contacts’e create_contacts:

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

Agora, defina 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 é uma função de retorno de chamada httpPostAsync será chamada quando receber os dados de contato do servidor. Ela aceita “contatos” como parâmetro (os dados de contato). Primeiro, essa função adiciona um array a data['contacts']. Em seguida, ela percorre os contatos do servidor e adiciona cada um deles à matriz, criando um novo elemento HTML div com o nome de cada contato.

Agora, você precisa 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 envia uma solicitação GET para uma URL e passa o JSON recebido na resposta para uma função de retorno de chamada.

Por fim, você precisa definir uma função que seja acionada quando um usuário clicar no botão ALERT.

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 função verifica se navigator.geolocation é true. Navigator.geolocation permite obter a localização do usuário. É preciso verificar se isso é verdade, pois algumas versões do navegador não oferecem suporte a essa funcionalidade. Se for verdade, a função acima chama navigator.geolocation.getCurrentPosition(success, error) e passa duas funções: uma que lida com o que acontece se o navegador conseguir obter a localização do usuário e outra que lida com erros.

A success função adiciona as coordenadas do usuário a data['coordinates'] e, em seguida, envia uma solicitação POST para /alert com os dados.

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))
}

Seu /alert endpoint envia então uma mensagem SMS para todos os contatos do banco de dados, informando que o remetente está em apuros, juntamente com a latitude e a longitude dele. Agora, basta estilizar seu aplicativo com um pouco de CSS. Crie um novo arquivo na pasta public chamado style.css e adicione o seguinte 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;
}

Agora, ao acessar a página inicial do seu site, você deverá ver uma página semelhante à da imagem no início deste artigo.

Adicione a si mesmo como contato e selecione “Alerta”.

Você deve receber uma mensagem de texto com suas coordenadas de longitude e latitude, informando que você está em uma situação de emergência.

Considerações finais

Essa demonstração é apenas um ponto de partida! Há uma infinidade de recursos que você pode adicionar a ela. Por exemplo, se você estivesse usando isso em ambiente de produção, seria interessante criar um recurso para gerenciar diferentes usuários (fazer login com nome de usuário e senha, etc.). Você também poderia adicionar recursos como editar contatos e incluir opções para os diferentes tipos de emergência. Se decidir desenvolver a partir desta demonstração, adoraria ver o que você criou: não deixe de nos enviar o que você criar no Twitter. Além disso, não deixe de participar da comunidade de desenvolvedores da Vonage para ter acesso a mais conteúdos e tutoriais incríveis. Você pode seguir a Vonage no Twitter aqui e participar do nosso canal no Slack aqui. Espero que você tenha gostado deste tutorial! Obrigado pela leitura!

Compartilhar:

https://a.storyblok.com/f/270183/400x394/540f26da70/cory-althoff.png
Cory AlthoffEx-funcionário da Vonage

Cory Althoff é defensor de desenvolvedores na Vonage e autor de dois livros: “The Self-Taught Programmer” e “The Self-Taught Computer Scientist”. O site Book Authority considerou “The Self-Taught Programmer” um dos melhores livros de programação de todos os tempos, e o The Next Web o listou como um dos dez livros que ajudarão você a se tornar um engenheiro de software melhor. Cory mora na Região da Baía com sua esposa e filha.