APIs e Microsserviços

10 abr, 2015

Chrome Extension com API forecast.io

Publicidade

As extensões do Chrome existem para que possamos criar coisas úteis que melhorem a experiência na navegação ou então nos facilite o acesso às informações das quais precisamos. Extensões como leitores de RSS e alertas de e-mail são as mais comuns.

Nesse artigo, eu vou explicar como criar uma extensão simples que faz o acesso à API do site forecast.io

Os arquivos desse artigo estão disponíveis no meu Github no endereço.

Começando a Chrome extension

Primeiro de tudo, é importante preparar o ambiente para a chrome extension. O arquivo manifest.json é onde ficam as informações básicas para o Chrome carregar a extensão.

Abaixo está o arquivo manifest.json, usado para o projeto.

{
  "manifest_version": 2,
  "name": "Forecast.io",
  "description": "Aqui vai a descrição da sua extensão",
  "version": "1.0",
  "browser_action": {
    "default_icon": "clear-day.png",
    "default_popup": "popup.html"
  },
  "permissions": [
    "geolocation",
    "alarms",
    "<all_urls>"
  ],
  "background": {
    "scripts": ["background.js"],
    "persistent": false
  }
 }

Onde:

  • manifest_version = Sempre deve ser deixado o valor 2
  • name = Nome da sua extensão
  • description = Descrição da extensão
  • version = Seu controle de versão, posteriormente deverá ser atribuído um novo valor a cada nova versão
  • browser_action = Definições do botão de ação que fica na barra de ferramentas
  • permissions = Quais permissões serão necessárias para a extensão funcionar
  • background = Definições dos arquivos que rodarão em background

As permissões que foram definidas são geolocation, alarms e <all_urls>. A permissão de geolocation possibilita a utilização da API de geolocalização sem que seja necessário solicitar a aprovação do usuário, pois ao instalar a extensão, ele concorda com esse funcionalidade.

A permissão de alarms possibilita a utilização da API chrome.alarms, que é responsável por agendar a execução tarefas na Chrome extension.

A permissão <all_urls> solicita acesso à todas as URL para a Chrome extension. Esse tipo de permissão deve ser usado com moderação, o melhor nesse caso é definir quais urls são autorizadas. Ex: http://*.google.com/&#8221;, você pode conferir os padrões de URL no link https://developer.chrome.com/extensions/match_patterns.

Serviço de background

O serviço de background é onde está toda a programação que busca os dados da API.

O arquivo background.js possui a chave da API, as funções de geo localização e de acesso ao JSON da API e os listeners da Chrome extension.

Abaixo está o arquivo background.js:

var APIKEY = '6ee8de3e1a315894761e9006065cffde';
var latitude = 0;
var longitude = 0;
var lastResult = null;

function getLocation(callback) {
    if (navigator.geolocation) {
        navigator.geolocation.getCurrentPosition(showPosition, showError);
    }

    if (callback) {
    	callback();
    }
}

function showPosition(position) {
	latitude = position.coords.latitude;
	longitude = position.coords.longitude;

	getJSON('https://api.forecast.io/forecast/' + APIKEY + '/' + 
		latitude + ',' + longitude + '?units=si&lang=pt&exclude=minutely,hourly,daily,alerts,flags', 
		function(result) {
			chrome.browserAction.setIcon({
	            path: "/" + result.currently.icon + ".png"
	        });

	        lastResult = result;
		});
}


function getJSON(url, callback) {
	var x = new XMLHttpRequest();
	x.open('GET', url);
	x.responseType = 'json';
	x.onload = function() {
		callback(x.response);
	};
	x.send();
}

function showError(error) {
	var statusDiv = document.getElementById("status");

    switch(error.code) {
        case error.PERMISSION_DENIED:
            console.log("Usered the request for Geolocation.");
            break;
        case error.POSITION_UNAVAILABLE:
            console.log("Locationrmation is unavailable.");
            break;
        case error.TIMEOUT:
            console.log("Theest to get user location timed out.");
            break;
        case error.UNKNOWN_ERROR:
            console.log("Anown error occurred.");
            break;
    }
}

chrome.runtime.onInstalled.addListener(function() {
	chrome.alarms.create("forecast", {
	   delayInMinutes: 0,
	   periodInMinutes: 10
	});
});

chrome.alarms.onAlarm.addListener(function( alarm ) {
	getLocation();
});

chrome.runtime.onMessage.addListener(function(request, sender, sendResponse) {
	if (request.action == "getCurrentForecast") {
		getLocation(function() {
			sendResponse(lastResult);
		});
	}
});

Nesse arquivo temos alguns listeners que são detalhados abaixo:

onInstalled

Executado quando a extensão é instalada, atualizada ou quando o Chrome é atualizado. Neste listener criamos um alarme para ser executado a cada 10 minutos.

onAlarm

Executado quando um alarme atinge o tempo definido. Neste momento, fazemos uma chamada à função getLocation() que é a responsável por obter a geo localização.

Após encontrar a posição, a função showPosition() é chamada para atualizar o ícone da extensão para o clima atual.

onMessage

Executado quando recebe uma mensagem da popup. Para esta extensão, quando clicamos no ícone, apresentamos um popup que apresenta uma imagem do clima atual, a descrição e a temperatura.

Este fluxo vou explicar mais abaixo na seção do popup.

Popup

A popup é apresentada ao clicar no ícone da extensão. Toda a sua programação é feita utilizando HTML, CSS e Javascript, o que torna bem simples sua construção.

O arquivo popup.html tem um HTML bem simples, que possui uma imagem para o ícone do clima atual, um div para mostrar a descrição e outro div para a temperatura.

Arquivo popup.html abaixo:

<!doctype html>
<html>
 <head>
 <meta charset="utf-8">
 <script src="popup.js"></script>
 <link href="popup.css" rel="stylesheet">
 </head>
 <body>
 <img id="ico" />
 <div id="status">Carregando...</div>
 <div id="temperature"></div>
 </body>
</html>

Arquivo popup.css abaixo:

body {
	text-align: center;
	width: 300px;
	height: 300px;
	font-size: 18pt;
	font-family: Tahoma;
	vertical-align: middle;
}

#ico {
	display: none;
	margin: 0 auto;
}

#temperature {
	display: none;
	font-size: 26pt;
}

Arquivo popup.js abaixo:

function sendMessage() {
	chrome.runtime.sendMessage({action: "getCurrentForecast"}, function(response) {
		if (response == null) {
			setTimeout(sendMessage, 2000);
		} else {
			showResult(response);
		}
	});
}

function showResult(response) {
	var statusDiv = document.getElementById("status");
	var icoImg = document.getElementById("ico");
	var temperatureDiv = document.getElementById("temperature");

	statusDiv.textContent = response.currently.summary;

	temperatureDiv.style.display = "block";
	temperatureDiv.textContent = response.currently.temperature.toString().split('.')[0] + "˚C";

	icoImg.style.display = "block";
	icoImg.src = chrome.extension.getURL("/" + response.currently.icon + ".png");

}

document.addEventListener('DOMContentLoaded', sendMessage);

O listener que começa esse arquivo serve para saber quando a popup é solicitada pelo usuário.

Quando o popup é aberto, o chrome dispara o evento DOMContentLoaded e é nesse evento que enviamos a mensagem para o background solicitando os dados da última execução para podermos montar uma tela com as informações da temperatura.

Caso não consiga uma resposta (o que indica que ainda não conseguiu o retorno da API), a função espera 2 segundos para tentar novamente.

Caso a resposta esteja disponível, passamos para a função showResult apresentar o resultado na tela.

Instalação da Chrome extension

Para instalar a Chrome extension, você deve abrir o seu Chrome e digitar o endereço chrome://extension.

Será apresentada uma tela com as suas extensões, conforme abaixo:

captura-de-tela-2015-03-24-c3a0s-11-09-23

Para habilitar o modo de desenvolvimento, você deve marcar a caixa Developer mode (no meu caso o Chrome está em inglês).

captura-de-tela-2015-03-24-c3a0s-11-08-53

Agora você deve clicar no botão Load unpacked extension… (ou o equivalente no seu idioma).

Selecione a pasta da extensão onde estão os arquivos. Feito isso, sua extensão deve aparecer no browser e provavelmente já estará funcionando.

captura-de-tela-2015-03-24-c3a0s-11-14-17

Conclusão

A extensão pode ser evoluída para apresentar alertas de temperatura a cada mudança, ou então você pode criar um histórico, ou até mesmo mostrar os dados de máxima e mínima para o dia.

Você pode evoluir a extensão como quiser – se fizer isso, coloque no Github e deixe o link nos comentários.

Caso tenha alguma dúvida ou sugestão, pode deixar seu comentário que eu responderei com prazer.