
Compartilhar:
Mark era o responsável nominal pelas bibliotecas de clientes da Nexmo (embora ele só desenvolva as bibliotecas em Python e Java). Ele começou como desenvolvedor Java, já trabalha com Python há 18 anos e vem se aventurando cada vez mais com Go e Rust. Ele gosta de levar as linguagens de programação ao limite e, depois, ensinar essas técnicas a outros programadores. Ele tem um chapéu de viking, mas não é um viking, e no Twitter usa o nome Judy2k por motivos que prefere não revelar.
Como escapar de um encontro ruim (com a Fitbit e a Nexmo)
Tempo de leitura: 11 minutos
Então, seus amigos Bob e Carol marcaram um encontro às cegas para você, e acontece que eles são extremamente péssimos avaliadores de caráter. Seu par é mal-educado, tem péssimos modos à mesa e, para ser sincero, tem um cheiro estranho.
Você precisa dar o fora desse encontro, rápido.
Você tem duas opções. A primeira é um clássico que nunca falha. Você aponta para algo por trás do ombro deles e grita: “Olha aquilo!” Enquanto a pessoa estiver distraída, você derruba a cadeira com um chute e corre para a porta. Não se esqueça de pegar seu celular antes.
É claro que esse tipo de comportamento costuma magoar as pessoas. O que você precisa é de um telefonema de um amigo que precise de ajuda urgente, agora mesmo. E você sabe quem é seu amigo? A Nexmo é seu amigo. Não seria ótimo se você pudesse iniciar uma ligação só tocando no seu relógio? Vou mostrar como fazer exatamente isso, com o Fitbit Ionic e a API de voz da Nexmo Voice API.

Agradecimentos a @aaronbassett por essa ideia!
O Fitbit Ionic
Recentemente, ganhei um Fitbit Ionic para testar. Assim como todos os dispositivos Fitbit, ele é ótimo para monitorar sua saúde — contar seus passos, monitorar seu sono, etc. O que diferencia o Ionic é que você pode programá-lo facilmente usando JavaScript, CSS e SVG. Ele possui vários sensores para explorar, incluindo um acelerômetro, um barômetro, um giroscópio, um monitor de frequência cardíaca e um sensor de orientação. Também possui APIs para desenvolver e conectar-se a aplicativos complementares que rodam no seu celular.
Bem, suspeito que a Fitbit espera que você escreva aplicativos para monitorar suas atividades de snowboard, caiaque ou surfe. Eu queria criar algo que fosse um pouco menos cansativo de testar.
Voice API da Nexmo
A Voice API da Nexmo permite que você crie aplicativos capazes de fazer ou receber chamadas telefônicas. Ela contém recursos que permitem a criação de sistemas completos de menus de voz. Mas vamos usá-la apenas para fazer uma chamada de saída (da Nexmo) para o seu telefone, acionada por um aplicativo rodando no Ionic. A criação desse aplicativo requer vários componentes; portanto, vamos falar sobre as diferentes partes que precisamos desenvolver.
Foge daqui!
Vamos criar um aplicativo chamado Bail Out! para dar o fora em encontros ruins. Todo o código-fonte está no GitHub , caso você queira ver como fica quando tudo estiver montado.

A ideia básica parece bem simples. Temos um botão no Ionic. Quando você o pressiona, o Nexmo faz uma ligação para o seu celular. Na prática, é um pouco mais complexo. O Ionic não consegue fazer solicitações HTTP. Para obter conectividade com a internet, é preciso criar um aplicativo complementar que seja executado dentro do aplicativo Fitbit no seu celular. Assim, o Ionic se conecta ao aplicativo complementar, e este faz a solicitação HTTP.
Um erro comum que as pessoas cometem ao criar aplicativos móveis para o Nexmo pela primeira vez é incorporar sua chave secreta do Nexmo dentro do aplicativo! Não faça isso! Seria muito fácil para quem baixou seu aplicativo desmontá-lo, extrair sua chave secreta e, então, gastar todo o dinheiro da sua conta Nexmo!
Em vez disso, você precisa criar um pequeno serviço (ou função sem servidor!) que seja executado no seu servidor. Ele fica à espera de solicitações do seu aplicativo complementar e faz as chamadas para a Nexmo. É recomendável incluir algum mecanismo de autenticação, mas a principal vantagem é que, mesmo que alguém consiga acessar o seu serviço, o acesso ficará restrito ao conjunto específico de funcionalidades que o serviço disponibiliza. Nesse caso, apenas a capacidade de ligar para alguém e reproduzir uma mensagem pré-gravada.
Então, na verdade, temos três coisas para escrever:
Um aplicativo do Fitbit Ionic com um botão grande.
Um aplicativo complementar que recebe solicitações do aplicativo Ionic e envia uma solicitação HTTP ao nosso servidor.
Um pequeno servidor que recebe uma solicitação do aplicativo complementar e pede à Nexmo para ligar para o seu celular.

Isso vai ser divertido! Vamos começar...
Introdução
A primeira coisa que você vai querer fazer é acessar studio.fitbit.com— esse é o IDE online que a Fitbit desenvolveu para ajudar você a criar aplicativos para o Ionic. Depois de fazer o login, clique no botão botão “Novo Projeto” , selecione Inicial e clique em “Criar”.
Você deverá ver algo como um IDE online com a seguinte aparência:

Vale a pena instalar esse aplicativo de exemplo do Ionic e o aplicativo complementar no seu celular, só para ter certeza de que tudo está funcionando.
Conecte seu Ionic
Conectar seu Ionic pode ser um pouco complicado. Você precisa selecionar Configurações no seu Ionic e rolar a tela até o final, onde você verá Developer Bridge. Ao clicar nela, ele deve se conectar ao IDE. Isso pode demorar um pouco e, assim que a conexão for estabelecida, provavelmente você precisará clicar em Atualizar na seção Selecionar um dispositivo no Fitbit Studio. Com sorte, você deverá ver agora Ionic no menu e, ao selecioná-lo, deverá aparecer “Conectado”. O Ionic se desconecta após um curto período, portanto, você precisará repetir essas etapas de vez em quando.

Conecte seu celular
Você conecta seu celular de maneira semelhante.
Abra o aplicativo no seu celular (eu uso Android)
abra a página da sua conta de Account
Clique no seu dispositivo **Ionic** configurado
abra o **Menu do Desenvolvedor** e
ative ou desative a opção **Developer Bridge**.
A conexão pode demorar um pouco. Assim que estiver conectado, selecione **Atualizar** no Fitbit Studio, e você deverá ver seu celular na lista. Clique nele para conectá-lo ao Fitbit Studio.

Como instalar seus aplicativos
Agora vamos instalar o aplicativo de exemplo no celular e no Ionic, para verificar se tudo está funcionando. Pressione o botão na parte superior da tela.

Criação do aplicativo Ionic
Primeiro, vamos criar uma interface de usuário. Ela não vai fazer nada até que tenhamos escrito algum código, mas vai nos dar algo para ver. Nossa descrição da interface gráfica está em resources/index.gui, e é um subconjunto do SVG:
<svg>
<image id="connectivityicon" href="disconnected.png" x="100%-50" y="10" width="40" height="40"/>
<use id="bailoutbutton" href="#square-button-icon" y="0" width="100%" height="100%" fill="fb-red">
<set href="#text" attributeName="text-buffer" to="Bail!" />
<set href="#text" attributeName="font-size" to="100" />
<set href="#image" attributeName="href" to="icon.png" />
<set href="#image" attributeName="height" to="60" />
<set href="#image" attributeName="width" to="60" />
</use>
</svg>
Observe que quase tudo isso diz respeito à configuração do botão grande, que é um “botão quadrado com um ícone”. Também precisaremos de ícones para o botão grande e de imagens de “conectado” e “desconectado” para o ícone de conectividade. Você pode encontrá-los no repositório do GitHub: button_icon.png, connected.png, e disconnected.png. Todos eles devem ser colocados na resources pasta. Enquanto estiver lá, você também deve pegar icon.png, que substituirá o ícone padrão do logotipo do Fitbit no relógio por um logotipo de saída bem legal!
Você também precisará atualizar widgets.gui para que fique assim:
<svg>
<defs>
<link rel="stylesheet" href="styles.css" />
<link rel="import" href="/mnt/sysassets/widgets_common.gui" />
<link rel="import" href="/mnt/sysassets/widgets/square_button_widget.gui" />
</defs>
</svg>
Isso apenas torna o “widget de botão quadrado” disponível para nosso aplicativo.
Se quiser, você pode clicar em Executar novamente para ver a interface do usuário no relógio. Ela ainda não vai fazer nada. Vamos resolver isso...
O código do seu aplicativo Ionic deve ser colocado em um único index.js arquivo dentro do app diretório. Esse arquivo JavaScript é executado quando o aplicativo do relógio é iniciado. Coloquei todo o comportamento dentro de uma BailOutUI classe para evitar muitas variáveis e funções globais. Tudo é iniciado no construtor, que busca os elementos da interface do usuário (um botão grande e um ícone pequeno para indicar que o Ionic está conectado ao celular). Em seguida, ele inicia um temporizador de um segundo para atualizar o ícone de conectividade.
import document from "document";
import * as messaging from "messaging";
const CONNECTED_ICON = "connected.png";
const DISCONNECTED_ICON = "disconnected.png";
class BailOutUI {
constructor() {
// Look up our two UI elements:
this.bailOutButton = document.getElementById("bailoutbutton");
this.connectivityIcon = document.getElementById("connectivityicon");
// These two methods are callbacks, so we need to bind them to this instance:
this.bailOutActivate = this.bailOutActivate.bind(this);
this.connectivityCheck = this.connectivityCheck.bind(this);
this.bailOutButton.onactivate = this.bailOutActivate;
// Once a second, we see if we're connected to the companion app:
setInterval(this.connectivityCheck, 1000);
}
// Send a message to the companion app, telling it to trigger a "bail out".
bailOutActivate() {
messaging.peerSocket.send({
'type': 'event',
'event': 'bailout',
})
};
// Check if we have a connection to the companion app, and update the UI accordingly.
connectivityCheck() {
this.updateConnectivity(messaging.peerSocket.readyState == messaging.peerSocket.OPEN);
}
// Update the UI to indicate if we're connected to the companion app or not.
updateConnectivity(connected) {
this.connectivityIcon.href = connected ? CONNECTED_ICON : DISCONNECTED_ICON;
}
}
var ui = new BailOutUI(); O aplicativo complementar
Ok! Então, já criamos o aplicativo Ionic, e ele sabe como enviar uma mensagem para o aplicativo complementar (no bailOutActivate método). Mas, no momento, o aplicativo complementar não faz nada com a mensagem. Então, vamos criar o aplicativo complementar em companion/index.js.
import { me } from "companion";
import { settingsStorage } from "settings";
import * as messaging from "messaging";
// CHANGE THIS to your phone number:
const MY_PHONE_NUMBER = "447700900655";
// CHANGE THIS to your BailOut server URL:
const BAILOUT_ENDPOINT = "https://myngrokurl.ngrok.io/bail";
if (!me.permissions.granted("access_internet")) {
console.log("We're not allowed to access the internet :-(");
}
// Listen for the onmessage event
messaging.peerSocket.onmessage = function(evt) {
if (evt.data.type == "event") {
if (evt.data.event == "bailout") {
// Get the phone number from the settings screen:
fetch(BAILOUT_ENDPOINT, {
method: "POST",
body: JSON.stringify({ number: MY_PHONE_NUMBER }),
headers: {
"Content-Type": "application/json"
}
});
}
}
};
// Listen for the onerror event
messaging.peerSocket.onerror = function(err) {
// Handle any errors
console.log("Connection error: " + err.code + " - " + err.message);
};É recomendável alterar MY_PHONE_NUMBER para o seu celular e substituir o BAILOUT_ENDPOINT pelo URL do seu servidor (que vamos escrever daqui a pouco). Você também precisará abrir package.json e verificar se que a opção “Internet” esteja marcada na seção seção “Permissões solicitadas” — isso permitirá que o aplicativo complementar faça chamadas para o seu servidor. Então agora precisamos de um servidor.
O Servidor de Resgate
Para ser sincero, sou mais do tipo Python, mas como tudo aqui já está em JavaScript, vou escrever o servidor usando Node e ExpressJS. Se você preferir uma linguagem diferente, fique à vontade para portá-lo — existem bibliotecas de cliente da Nexmo para JavaScript, Java, Python, PHP, Rubye DotNet! É bem curto — ele aguarda uma solicitação POST do aplicativo complementar e a encaminha para a Voice API da Nexmo:
require("dotenv").config();
const express = require("express");
const Nexmo = require("nexmo");
const nexmo = new Nexmo({
apiKey: process.env.NEXMO_API_KEY,
apiSecret: process.env.NEXMO_API_SECRET,
applicationId: process.env.NEXMO_APPLICATION_ID,
privateKey: process.env.NEXMO_APPLICATION_PRIVATE_KEY_PATH
});
// Construct an absolute URL given a request object and the desired path.
function absoluteURL(req, path) {
return (
(req.get("x-forwarded-proto") || req.protocol) +
"://" +
req.get("host") +
path
);
}
const app = express();
// Post {number: 'your phone number'} to schedule a bail-out call.
app.post("/bail", express.json(), (req, res) => {
nexmo.calls.create({
to: [
{
type: "phone",
number: req.body.number
}
],
from: {
type: "phone",
number: process.env.NEXMO_NUMBER
},
answer_url: [absoluteURL(req, "/bail/emergency-message")]
});
res.json({ status: "ok" });
});
// This is called by Nexmo when the call is picked up.
// It tells Nexmo to read out a message, but it could do lots of things!
// Check out /api/voice/ncco to see what you could do!
app.get("/bail/emergency-message", (req, res) => {
res.json([
{
action: "talk",
voiceName: "Russell",
text: "Help! I've been arrested and I need you to bail me out!"
}
]);
});
app.listen(3000, () => {
console.log("BailOut Server on port 3000");
});
Enquanto estiver desenvolvendo, você pode executar o servidor localmente e usar o ngrok para torná-lo acessível publicamente na internet, para que seu celular possa acessá-lo. Temos um tutorial sobre como fazer isso!
Como configurar seu número Nexmo
Você precisará de um número da Nexmo (que é o número pelo qual a Nexmo entrará em contato com você quando ao ligar para o seu celular). Você pode obter um no Painel da Nexmo. Você também precisará configurar uma Application Nexmo para poder fazer chamadas. A maneira mais fácil de fazer isso é usando nossa ferramenta CLI:
Não se preocupe com as URLs “example.com” — você não precisará alterá-las para este aplicativo. Confira nexmo --help para ver tudo o que essa ferramenta incrível pode fazer por você!
Crie um arquivo chamado .env e configure-o com seus dados. Ele deve ficar mais ou menos assim:
Altere o arquivo para incluir suas credenciais da Nexmo, os detalhes do aplicativo que você acabou de criar e o número virtual da Nexmo que você adquiriu no Painel de Controle.
Executando o servidor
Agora que você já tem um servidor e um número da Nexmo, vá até o diretório que contém seu arquivo .env e inicie o servidor da seguinte maneira:
Certifique-se de que o ngrok esteja em execução ao mesmo tempo em outra janela!
Juntando tudo isso
Implemente seus aplicativos Ionic e complementares a partir do Fitbit Studio, aguarde até que o ícone de conexão fique verde e, em seguida, pressione o botão grande no meio da tela. Seu celular deve tocar!

Conclusão
Se você der uma olhada no repositório do GitHub deste projeto, você verá que adicionei uma tela de Configurações para que o usuário insira seu número de telefone, em vez de codificá-lo diretamente no aplicativo complementar. Também adiei a chamada de emergência por 30 segundos, para que ela não aconteça no momento em que você tocar no relógio! Você verá que também há registros adicionais para ajudar a diagnosticar a causa de quaisquer erros que aparecerem. Há alguns pontos (como no código do aplicativo complementar) em que seria uma boa ideia implementar algum tratamento de erros. Vou deixar isso por sua conta! Você também pode tentar alterar a mensagem que é lida para você ou alterar a voz.
O poder do JavaScript, aliado ao Fitbit Studio, pode tornar o início da criação de aplicativos para o Ionic realmente rápido. No entanto, há muito o que aprender sobre como desenvolver para o Ionic e para o celular, mas a documentação está melhorando a cada dia.
Se você gostou deste post, siga nosso conta da Nexmo Developer Twitter account. É meu account favorito de posts técnicos interessantes!
Você também pode se interessar por:
Compartilhar:
Mark era o responsável nominal pelas bibliotecas de clientes da Nexmo (embora ele só desenvolva as bibliotecas em Python e Java). Ele começou como desenvolvedor Java, já trabalha com Python há 18 anos e vem se aventurando cada vez mais com Go e Rust. Ele gosta de levar as linguagens de programação ao limite e, depois, ensinar essas técnicas a outros programadores. Ele tem um chapéu de viking, mas não é um viking, e no Twitter usa o nome Judy2k por motivos que prefere não revelar.