Desarrollando un agente de chat que informe el clima

En este tutorial desarrollaremos con App Engine un pequeño agente de chat que nos informe sobre el estado del tiempo actual de la ciudad que le indiquemos y lo hará utilizando la red XMPP tal como lo hace GTalk. Si no sabes que es App Engine o no has desarrollado anteriormente, es recomendable que leas este pequeño tutorial

Para obtener la información del estado del tiempo podemos utilizar cualquier servicio público como el de Yahoo, Msn, etc., en mi caso utilizaré Google Weather API.

Antes de iniciar...
Antes de iniciar, dejemos en claro el sencillo ejemplo que deseamos hacer. Si tienes algún servicio compatible con el protocolo XMPP como por ejemplo Gtalk (chat de Google), Pidgin, iChat, etc., agrega la siguiente cuenta a tus contactos,

clima-byte@appspot.com

Una vez agregada la cuenta, abre una ventana de chat con este contacto y escribe el nombre de la ciudad de la cual deseas obtener la información actual del estado del tiempo,


Como lo puedes ver en la imagen anterior, del otro lado hay un pequeño agente que te responde inmediatamente con el estado del tiempo actual de la ciudad que le especificas... Lo anterior es una sencilla aplicación que hace uso de un Servlet y del protocolo XMPP desde App Engine.

XMPP

El Extensible Messaging and Presence Protocol es un protocolo open source basado en XML para la transmisión/recepción de mensajes y es mejor conocido como XMPP (anteriormente llamado Jabber). La ventaja de utilizar el protocolo XMPP es que no se requiere de un servidor central, cada uno de nosotros puede ser un servidor y/o el cliente. Cada usuario de la red XMPP, tiene un identificar único conocido como JID (Jabber ID), dicho identificador es del tipo:


usuario@dominio.com


donde el @dominio es el nombre del dominio del servidor que proporciona este servicio. Google App Engine ofrece soporte para XMPP por lo que al momento de registrarnos para obtener una cuenta y crear una aplicación en App Engine, nuestro JID será:


id-aplicacion@appspot.com


El id-aplicación será aquel que indiquemos al momento de crear una aplicación en App Engine.


Para más información sobre el protocolo XMPP puedes consultar la wikipedia en español o ingles.

Google Weather API.

Se trata de un sencillo servicio que basta con invocar la siguiente URL y nos regresará la información del estado del tiempo en formato XML.


Peguen la url anterior en un navegador y obtendrán un xml con la información actual y un pronostico del tiempo de los próximos días.

Dado que la información es regresada en formato XML, vamos a necesitar un pequeño y sencillo parser xml que haremos nosotros utilizando SAX.

Desarrollando el agente...

  • Creamos un Google Web Application Project (recuerda leer este tutorial en caso de no haber desarrollado antes con App Engine). Le podemos llamar AgenteTiempo
  • Al crear el proyecto, se creará un Servlet y aquí será donde obtendremos un servicio XMPP para comunicarnos con algún JID, pero antes de ellos, vamos a desarrollar el pequeño parser.
  • Creamos una clase llamada EstadoTiempo con los siguientes atributos y sus respectivos setters y getters,
    • private String condition;
    • private String humidity;
    • private String temp_c;
    • private String temp_f;
    • private String wind_condition;
  • Creamos una clase llamada SaxEstadoTiempoHandler que extienda de la clase DefaultHandler. Puedes ver el código aquí. Podemos ver que sobre-escribimos el método startElement(...) y mediante el parámetro localName verificamos si se trata del elemento deseado. Como podemos ver en la siguiente imagen, nos interesan los elementos señalados en la región amarilla, condition, temp_f, temp_c, humidity y wind_condition, por lo cual en el código Java preguntamos por dichos elementos y obtenemos el valor de su atributo "data" desde el método resolveAttrib.
  • Ahora en el Servlet que se generó al crear el proyecto vamos a parsear el XML utilizando el handler creado anteriormente. Como podemos ver en la siguiente imagen, hemos creado un método privado y utilizado un objeto de la clase XMLReader pasandole como handler la clase SaxEstadoTiempoHandler. En el método parse de XMLReader le pasamos un objeto InputStreamReader que contiene un stream de bytes que representa el XML devuelto por la url del API de Google Weather.
  • Es importante indicar una codificación ISO ya que al pasarle a la url el atributo "hl=es" nos devolvera los resultados con acentos y nuestro programa podría arrojar una excepción. Una vez invocado el método parse del objeto XMLReader, construimos en un StringBuilder la respuesta que le devolveremos al usuario.
  • El cuerpo del mensaje que el contacto de chat envie a nuestro agente se realiza mediante un POST, por lo cual debemos utilizar el método doPost. Ver código fuente completo del Servlet.
  • Ya para finalizar, debemos agregar en el appengine-web.xml las siguientes etiquetas, tal y como lo describe la documentación de Google sobre el protocolo XMPP 
  • Además de esto, en el archivo web.xml debemos modificar el url-pattern de nuestro servlet y cambiarlo por:
/_ah/xmpp/message/chat/

Y listo!!!! Finalmente estamos listos para publicar nuestro proyecto en la nube de App Engine! Como lo mencione al inicio de este tutorial, puedes ver el resultado, agregando al contacto clima-byte@appspot a tus contactos de GTalk o de algún otro servicio que utilice la red XMPP como jabber.org o desde Pidgin.


Se te puede quedar como ejercicio que el agente también proporcione el pronóstico de los próximos días! O incluso hacer algo diferente! Por ejemplo un ejercicio que se conecte al DataStore de Google usando JDO donde se encuentren almacenadas las calificaciones de alumnos y el agente le muestre las calificaciones de todas las materias actuales al alumno, claro esta, mediante alguna clave para evitar que algún curioso vea información que no le corresponde.

Saludos!!