KEMBAR78
Blog de Iván López: Google Calendar
Mostrando entradas con la etiqueta Google Calendar. Mostrar todas las entradas
Mostrando entradas con la etiqueta Google Calendar. Mostrar todas las entradas

domingo, 20 de mayo de 2007

Usando el API de Google Calendar: Alarmas por SMS

   Hace un tiempo descubrí Google Calendar, y aunque no lo utilizo mucho tiene una característica que me llamó la atención desde el principio. Una vez que defines una cita o evento, puedes asociarle un recordatorio para que te avise por email o con un pop-up si tienes la web abierta; hasta aquí ninguna novedad. Lo realmente novedoso es que también permite avisarte por medio de un SMS al móvil y además, en el caso de España es gratis. Sólo hay que asociar a nuestra cuenta de google nuestro número de teléfono móvil y después de una verificación de identidad podemos añadir el aviso por sms como recordatorio de las citas.

   Teniendo esto en mente pensé que sería realmente útil poder enviar alarmas al móvil con el estado de los servidores de casa. Así, si normalmente tenemos alguna tarea programada en crontab que nos avisa por email cuando termina mal, algún monitor de los servicios, espacio en los filesystems,... podríamos añadir una llamada a un programa adicional que introdujese un evento en nuestro calendario de google para que nos llegara el aviso por medio de un sms al móvil y así estar informados en todo momento del estado de nuestras máquinas :-).

   Pues dicho y hecho, me puse a buscar y lo que encontré no pudo ser mejor. Google proporciona un acceso completo a su API, con ejemplos, foros, y además disponible desde varios lenguajes de programación (Java, .Net, PHP y Python). De todos estos, el que más conozco y con el que más he trabajado (aunque ya haga tiempo que no lo toco demasiado) es Java. Además, tiene la ventaja de que al ser multiplataforma podría monitorizar también máquinas windows.

   Me instalé Eclipse y la máquina virtual de Sun 1.5 (ojo que esto es importante, no funciona con la 1.4.2) por medio de un simple apt-get. De la web de google descargué las librerías cliente para java y me puse a probar alguno de los ejemplos. La verdad es que el código es muy sencillo y está muy bien explicado. Hay ejemplos de autenticación, consulta de los eventos del calendario entre determinadas fechas, alta de eventos, borrado, actualización...

   Después de realizar un par de pruebas tenía un esqueleto que funcionaba aunque había que afinar. Examinando con más detalle las clases con Eclipse y con unas pocas pruebas posteriores terminé la versión 0.1 que permite insertar un evento en nuestro calendario y recibir un aviso por sms en 1 minuto. Aspectos a tener en cuenta del código:
  • Para conseguir que llegue el aviso dentro de un minuto lo que hago es poner la hora de comienzo del evento dentro de 6 minutos y la notificación por sms 5 minutos antes. Aunque por código es posible fijar el recordatorio dentro de 1 minuto, luego, cuando se envía la petición se nos muestra un error diciendo que no es válida.
  • Parece que la clase DateTime de Google no se lleva muy bien con la clase Date. Al principio creé un objeto con la hora actual para asignarselo al comienzo del evento, pero una vez asignado, la fecha que ponía era de dos horas antes!. Lo resolví creando un TimeZone para "Europe/Madrid" y utilizándolo en la creación de dicho objeto. Luego hablando con un compañero y comentándole esas 2 horas de diferencia (yo pensé que debería ser sólo una por eso de que estamos en zona GMT+1), me dijo que, con el cambio a horario de verano hemos pasado "automáticamente" a GMT+2. En fin, misterio aclarado. Gracias Jose!.
  • El programa recibe como parámetros el usuario, el password y el texto que queremos enviar. Aunque a priori no hay limitación en la longitud del texto, al móvil sólo nos llegarán los primeros 57 caracteres.
  • Después de construir la petición y enviarla, por la consola aparece un error. Según he investigado parece como si la versión que utilizo de las librerías de google fuera antigua, aunque realmente estoy trabajando con la última. En principio no afecta al funcionamiento, aunque queda un poco "feo".
  • Adicionalmente, es necesario descargar las librerías mail.jar del API JavaMail y activation.jar del Framework de Sun JavaBeansActivation.

  •    Y ya, sin más divagaciones, el código:
    /*
    * Programa para el envío de alarmas por SMS al móvil por medio del API Google Calendar
    *
    * Iván López Martín
    * http://lopezivan.blogspot.com
    *
    */

    import java.net.URL;
    import java.util.Calendar;
    import java.util.GregorianCalendar;
    import java.util.TimeZone;

    import com.google.gdata.client.calendar.CalendarService;
    import com.google.gdata.data.DateTime;
    import com.google.gdata.data.Person;
    import com.google.gdata.data.PlainTextConstruct;
    import com.google.gdata.data.extensions.EventEntry;
    import com.google.gdata.data.extensions.Reminder;
    import com.google.gdata.data.extensions.When;


    public class EnviaSMS {

    public static void main(String[] args) {

    // Comprobamos los argumentos necesarios: usuario, password y texto del mensaje
    if (args.length < 3) {
    System.err.println("Uso: EnviaSMS <usuario> <password> <texto>");
    return;
    }

    String userName = args[0];
    String userPassword = args[1];
    String sms = "";
    // El máximo son 57 caracteres
    for(int i=2; i<args.length; i++) {
    sms = sms + args[i] + " ";
    }
    sms = sms.trim();

    try {
    URL feedUrl = new URL("http://www.google.com/calendar/feeds/" + userName + "/private/full");

    CalendarService myService = new CalendarService("EnviaSMS");

    // Nos autenticamos en google Calendar
    myService.setUserCredentials(userName, userPassword);

    // Creamos el evento
    EventEntry myEntry = new EventEntry();
    myEntry.setTitle(new PlainTextConstruct(sms));

    Person author = new Person(userName, null, userName);
    myEntry.getAuthors().add(author);

    // Definimos la zona horaria
    TimeZone tz = TimeZone.getTimeZone("Europe/Madrid");

    Calendar cal = GregorianCalendar.getInstance();
    cal.add(Calendar.MINUTE, 6);
    DateTime startTime = new DateTime(cal.getTime(), tz); //6m

    cal.add(Calendar.MINUTE, 1);
    DateTime endTime = new DateTime(cal.getTime(), tz); //7m

    // Definimos la hora de comienzo y de fin del evento
    When eventTimes = new When();
    eventTimes.setStartTime(startTime);
    eventTimes.setEndTime(endTime);
    myEntry.addTime(eventTimes);

    // Añadimos el recordatorio sólo como SMS y que avise 5 minutos antes
    Reminder reminder = new Reminder();
    reminder.setMinutes(new Integer(5));
    reminder.setMethod(Reminder.Method.SMS);
    myEntry.getReminder().add(reminder);

    // Enviamos la petición para insertar el evento en el calendario
    EventEntry insertedEntry = (EventEntry)myService.insert(feedUrl, myEntry);
    } catch (Exception e) {
    e.printStackTrace();
    }
    }
    }

       Para la ejecución desde la línea de comandos, he creado un pequeño script:
    ivan@doraemon:~$ cat enviaSMS.sh 
    #!/bin/sh
    #################################
    # Iván López Martín #
    # http://lopezivan.blogspot.com #
    #################################
    SMS_HOME=/home/ivan/workspace/GoogleCalendar

    CLASSPATH=$SMS_HOME/lib/activation.jar:$SMS_HOME/lib/gdata-calendar-1.0.jar:$SMS_HOME/lib/gdata-client-1.0.jar:$SMS_HOME/lib/mail.jar:$SMS_HOME/bin

    java -classpath $CLASSPATH EnviaSMS $@

    ivan@doraemon:~$ ./enviaSMS.sh usuario@gmail.com password "Visita el blog de Iván López. http://lopezivan.blogspot.com"

       En nuestro calendario de google aparece el nuevo evento con las opciones que hemos indicado:

       Y un minuto después, en el móvil el sms:


       Como ya he dicho, se trata de la versión 0.1, aunque me parece que no la voy a modificar mucho más porque lo único que necesito es el envío de los sms. No voy a borrar los eventos del calendario, ni actulizarlos, ni consultarlos desde el programa,...

       Cualquiera es libre de modificar el código, usarlo y mejorarlo siempre que por favor respete el comentario del autor y el enlace a este blog. Además, si lo mejoras por favor házmelo saber para poder actulizar este artículo.

       Que lo disfrutéis...