miércoles, 1 de agosto de 2012

Uso de GTalk desde SHELL para el envio de alertas

... o para hablar con nuestro RaspberryPi

He pensado que para enviar las alertas de la alarma y esas cosas, además de mandar un email, sería muy interesante que mandase una conversación por GTalk, para que salte la ventanita de turno en el móvil y en el pc del curro. Y ya que estamos, como yo no puedo hacer las cosas tan sencillas, voy a hacer que las ordenes que le digo desde GTalk las ejecute el servidor, muy interesante.

envío de mensajes automáticos usando GTalk

Estos son los pasos:
apt-get update
apt-get install sendxmpp
echo "# my account" > ~/.sendxmpprc
echo "mygmailuser@gmail.com;talk.google.com mygmailpassword gmail.com" >> ~/.sendxmpprc
chmod 700 ~/.sendxmpprc
cp -v ~/.sendxmpprc /etc/sendxmpprc
vaaale, no ha dado fallos, vamos a enviar un mensaje de prueba:
echo "This is a test IM" | sendxmpp -t receivergmailuser@gmail.com
donde receivergmailuser@gmail.com es donde enviamos el mensaje. A mi me ha llegado al Android, al Pidgin en el pc del curro y en la ventana emergente de gmail.com ¡perfecto!. Integrarlo con el script de la alarma del post correspondiente es muy fácil:
#!/bin/bash
# alarma laser
# programado por Juanmol para http://rsppi.blogspot.com
gpio -g mode 18 out
gpio -g mode 17 in
gpio -g write 18 0
sleep 1
while ((1));
do
 if [ "$(gpio -g read 17)" -eq "0" ];
 then
  echo "no pasa nada, relajate";
  sleep 0.5;
 else
  echo "ALARMA!! ALARMA!!";
  echo "ALARMA!! ALARMA!!" | sendxmpp -t receivergmailuser@gmail.com;
  sleep 10;
 fi
done

recepción de mensajes por GTalk y actuando en RaspberryPi

El paso anterior era bastante sencillo, ahora lo vamos a complicar un poco más. Voy a usar centerim como cliente para consola de GTalk:
apt-get install centerim
Ahora hay que abrir centerim y configurar la cuenta de GMail que enviara los mensajes. Aquí te dejo una web con las instrucciones.
Con el cliente ya configurado, inicia una conversación con aquella otra cuenta que vaya a ser la que envíe las ordenes, para crear los archivos necesarios. Tienes que hablarte a ti mismo, es una conversación de lo más entretenida.
Para hacerlo más interesante (y seguro), vamos a hacer que sólo atienda aquellas ordenes que vengan precedidas por un código/pin/clave, para nuestro ejemplo: 9988. Voy a usar mi demonio en bash, que use en este otro post. Creamos /usr/local/bin/demoniogtalk.sh :
#!/bin/bash
# demonio GTalk
# programado por Juanmol para http://rsppi.blogspot.com
rm -f /root/.centerim/jreceivergmailuser@gmail.com/history
touch /root/.centerim/jreceivergmailuser@gmail.com/history
tail -f /root/.centerim/jreceivergmailuser@gmail.com/history | perl -ne 'system("/usr/local/bin/filtrogtalk.sh $_")'
jreceivergmailuser@gmail.com es la cuenta de GTalk que enviará las ordenes, tienes que buscarla en ~/.centerim/ . Estos archivos se crearon cuando estuviste hablando contigo mismo ¿a que ahora no te parece tan raro?.
Ahora creamos /usr/local/bin/filtrogtalk.sh :
#!/bin/bash
# programado por Juanmol para http://rsppi.blogspot.com
if [ $(echo $@ | grep 9988 | wc -l) = 1 ];
then
 /usr/local/bin/ejecutadorgtalk.sh $(echo $@ | cut -f2 -d\:);
 echo "Orden recibida" | sendxmpp -t receivergmailuser@gmail.com ;
 rm -f /root/.centerim/jreceivergmailuser@gmail.com ;
fi
receivergmailuser@gmail.com es la que envía las ordenes. Y cambia '9988' por tu código/pin/clave.
Llegados a este punto podemos hacer una prueba, hacemos lo siguiente:
screen -d -m -S centerim centerim
/bin/bash /usr/local/bin/demoniogtalk.sh 2> /dev/null & 
con la 1ª linea, dejamos en ejecución dentro de un screen, al centerim. Tenemos que hacerlo así por la propia naturaleza de centerim, que no permite quedarse en segundo plano. La 2ª línea es la que deja en segundo plano al demonio. Ahora desde el cliente donde tenemos registrada la cuenta que envía (en nuestro ejemplo receivergmailuser@gmail.com), le decimos cosas y no tiene que responder nada, pero si le decimos por ejemplo:
9988: rsppi mola
A los pocos segundos nos responderá con un "Orden recibida". Ahora vamos a crear /usr/local/bin/ejecutadorgtalk.sh con un pequeño ejemplo:
#!/bin/bash
# desarrollado por juanmol para http://rsppi.blogspot.com
log=/var/log/ejecutadorgtalk.log
case $1 in
 alarma)
  if [ $2 = on ];
  then
   echo se enciende la alarma >> $log;
   echo "conectando alarma" | sendxmpp -t -u mygmailuser -o gmail.com -p mygmailpassword receivergmailuser@gmail.com ;

  else
   echo se apaga la alarma >> $log;
   echo "apagando alarma" | sendxmpp -t -u mygmailuser -o gmail.com -p mygmailpassword receivergmailuser@gmail.com ;
  fi
 ;;
 * )
 echo no se reconoce el evento $1 >> $log
 ;;
esac
como vemos, este script recibe, por ahora, la orden "alarma on" o "alarma off" y actúa en consecuencia. Para nuestra alarma láser, habría que ejecutar dentro del on:
/bin/bash /usr/local/bin/alarmalaser.sh
y dentro del off, siendo un poco guarrete:
killall alarmalaser.sh
Para que todo arranque con el sistema, añadimos las siguientes líneas al final del archivo /etc/rc.local :
screen -d -m -S centerim centerim
sleep 5 && /bin/bash /usr/local/bin/demoniogtalk.sh 2> /dev/null & 
Una vez más, esta forma de "programar" es un poco especial, yo lo llamo "un poco de scripting callejero", no vayas a usar estos ejemplos en el trabajo, ni se los enseñes a tu suegro, no es muy presentable.

edición 5 de Marzo de 2013:
afortunadamente han actualizado algunos paquetes y ahora la instalación es aún más fácil. He realizado los cambios sobre el contenido anterior.

32 comentarios:

  1. Cuando intento hacer el test, el raspberry me muestra los siguientes errores por consola:

    Use of uninitialized value $args{"file"} in lc at /usr/share/perl5/Net/XMPP/Debug.pm line 154.
    Use of uninitialized value within @_ in lc at /usr/share/perl5/XML/Stream/Parser.pm line 71.
    Use of uninitialized value within @_ in lc at /usr/share/perl5/XML/Stream/Parser.pm line 71.
    Use of uninitialized value in string eq at /usr/local/bin/sendxmpp line 482.
    Error 'AuthSend': [?]

    ResponderEliminar
    Respuestas
    1. la verdad es que ese error ... no se por donde cogerlo, lo siento. Mira a ver si es cosa de la version de perl, que lo dudo mucho. La mia es la v5.14.2. Otra cosa que puedes comprobar es ver si tienes estos paquetes instalados:
      libnet-xmpp-perl
      libxml-parser-perl
      libauthen-sasl-perl
      siento no poder ayudarte mucho más :-/

      Eliminar
    2. pues no se, he comprobado los paquetes y los tengo todos instalados y la versión de perl es exactamente la misma, desinstalaré todo y volveré a probar de nuevo.

      Eliminar
  2. Hola.

    He seguido los pasos (en la medida de lo posible) que indicas y al margen de algún pequeño error y modificación, he conseguido que funcione. Pero me he encontrado con un pequeño efecto secundario no deseado: Creo que el screen interfiere con el xbmc impidiendo su correcta ejecución. He de decir que yo no usé raspbian, sino raspbmc, pero dudo que eso influya......
    Así que de momento, y a la espera de mayores investigaciones, lo he desinstalado para poder seguir usando mi raspberry como reproductor multimedia.

    ResponderEliminar
    Respuestas
    1. Hola!, Estoy intentando seguir esta guía y estoy en tu misma situación, utilizo raspbmc. Lograste algo?
      He intentado instalarlo, con los más de 100 paquetes que me dice que tengo que instalar, y con todo ello, el xbmc no arranca!!

      Perdona por reflotar esto después de un año :)

      Eliminar
    2. Mismo problema, alguien ha encontrado una solucion a esto?

      Eliminar
    3. Tengo el mismo problema con raspbmc (ultima versión a la fecha) al instalar centerim, configuras todo y funciona correctamente, pero cuando reinicias ... zasss ... se queda en bucle y no carga la interfaz XBMC. Si le das a ESC puedes acceder a la consola de comandos, pero nada

      Eliminar
  3. Tengo problemas con parte del script...

    Mandar mensajes con el XMPP me va genial. Pero a mitad del post empecé a fallar. Primero el link a l pagina que indica como configurar el centerim no funciona. Aun y asi instalé el centerim. Pero vi que no estaba la opcion de configurar una cuenta XMPP. Asi que al entrar a la página del centerim vi que estaba la version 5. Quité centerim e instalé centerim 5.

    Centerim 5 ha cambiado la direccion del log de historiales, asi que si antes se llamaba:
    /root/.centerim/jreceivergmailuser@gmail.com/history
    ahora se llama:
    /root/.centerim5/clogs/XMPP/cuentadeceterim@gmail.com/tucuentapersonal@gmail.com

    Por tanto todos los scripts cambian un poco y hice estos cambios:
    Creo /usr/local/bin/demoniogtalk.sh :

    #!/bin/bash
    # demonio GTalk
    # programado por Juanmol para http://rsppi.blogspot.com
    rm -f /root/.centerim5/clogs/XMPP/cuentadeceterim@gmail.com/tucuentapersonal@gmail.com
    touch /root/.centerim5/clogs/XMPP/cuentadeceterim@gmail.com/tucuentapersonal@gmail.com
    tail -f /root/.centerim5/clogs/XMPP/cuentadeceterim@gmail.com/tucuentapersonal@gmail.com | perl -ne 'system("/usr/local/bin/filtrogtalk.sh $_")'

    Ahora creo /usr/local/bin/filtrogtalk.sh :
    #!/bin/bash
    # programado por Juanmol para http://rsppi.blogspot.com
    if [ $(echo $@ | grep 9988 | wc -l) = 1 ];
    then
    /usr/local/bin/ejecutadorgtalk.sh $(echo $@ | cut -f2 -d\:);
    echo "Orden recibida" | sendxmpp -t -u mygmailuser -o gmail.com -p mygmailpassword receivergmailuser@gmail.com ;
    rm -f /root/.centerim5/clogs/XMPP/cuentadeceterim@gmail.com ;
    fi

    Luego hago ejecuto ceterim5 en un screen y me va de lujo. Veo mi raspberry conectada por gtalk
    screen -d -m -S centerim5 centerim5

    luego ejecuto el demonio,... pero nada de nada. Ningun mensaje. Aunque ponga 9988 al inicio no me llega nada.
    /bin/bash /usr/local/bin/demoniogtalk.sh 2> /dev/null &

    Que paso tengo mal?

    ResponderEliminar
  4. Acabo de ver como se hace la configuracion del ceterim como tu dices... pero aun y ponerlo todo como el post no va el script del demonio.

    El screen con el centerim funciona perfecto tanto como superusuario como con el usuari pi, pero no me arranca al poner el codigo en /etc/rc.local

    Alguna pista?

    ResponderEliminar
    Respuestas
    1. asegurate de no haberlo arrancado antes. En rc.local se ejecutaria como root, que segun dices te funciona. Asegurate de no usar rutas relativas. Si sigue sin ir, pega aqui el codigo del rc.local, a ver si vos que le falla.

      Eliminar
  5. Como el script del demonio no iba fui acotando fallos... asi que solo puse la linea que si me funciona como root, pero no en rc.local. Pego rc.local:

    #
    # By default this script does nothing.

    # Print the IP address
    _IP=$(hostname -I) || true
    if [ "$_IP" ]; then
    printf "Mi direccion IP es %s\n" "$_IP"
    fi

    screen -d -m -S centerim centerim

    exit 0
    #
    # By default this script does nothing.

    # Print the IP address
    _IP=$(hostname -I) || true
    if [ "$_IP" ]; then
    printf "Mi direccion IP es %s\n" "$_IP"
    fi

    screen -d -m -S centerim centerim

    exit 0

    Como ves muy sencillo y deberia funcionar... pero no.


    ResponderEliminar
    Respuestas
    1. lo as pegado aquí dos veces, asegúrate de no tenerlo así en el archivo de verdad.
      Si como me dices, ejecutándolo tal cual como root no te falla, prueba a ver si te funciona poniéndolo después del "exit 0".
      Si sigue sin irte, vamos a tener que probar una ñapa:
      sleep 10 && screen -d -m -S centerim centerim
      (pero no se lo digas a nadie)

      Eliminar
    2. Pues no funciona ni con la ñapa,...
      Si una vez he logueado hago screen -d -m -S centerim centerim veo como se loggea bien la cuenta, pero al añadirlo en /etc/rc.local no se ejecuta,...

      Para ver si realmente se habia iniciado he hecho:
      ps axf | grep -i screen

      root@raspberrypi:/home/pi# ps axf | grep -i screen
      1998 pts/0 S+ 0:00 \_ grep -i screen
      1877 ? Ss 0:00 SCREEN -d -m -S centerim centerim

      Parece estar iniciado, no? Que sera el error? Configure el centerim tanto como usuario "pi" como "root". Por lo que veo parece que quiza se inicia, pero como si se abriera la ventana de configuracion inicial por no estar configurado,... Que se yo. Ya no se que pensar...

      Eliminar
  6. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  7. /usr/local/bin/sendxmpp: line 1: syntax error near unexpected token `newline'
    /usr/local/bin/sendxmpp: line 1: `'

    ese error es al enviar el mensaje de prueba.

    ResponderEliminar
  8. a mi me da este error, no se si alguien sabe a que se debe. Tambien decir que en vez de instalar el sendxmpp-0.0.8 instale la ultima version que encontre, la released version 1.23, supongo que no afectará.

    /usr/local/bin/sendxmpp: line 1: syntax error near unexpected token `newline'
    /usr/local/bin/sendxmpp: line 1: `'

    Saludos.

    ResponderEliminar
    Respuestas
    1. tengo pendiente actualizar el post en breve, hay cosas que han cambiado

      Eliminar
  9. Yo lo acabo de instalar, siguiendo estos sencillos pasos y los mensajes de pruebas llegan bien.

    apt-get install libnet-xmpp-per

    cd /tmp
    git clone https://github.com/lhost/sendxmpp.git
    cd sendxmpp/
    perl Makefile.PL; # perl Makefile.PL PREFIX=/usr
    make
    make install

    echo "mygmailuser@gmail.com;talk.google.com mygmailpassword" >> ~/.sendxmpprc
    chmod 700 ~/.sendxmpprc
    cp -v ~/.sendxmpprc /etc/sendxmpprc

    ResponderEliminar
  10. A mi para que me funcione el Centerim con Gtalk he tenido que añadir en su config:

    jab_ssl 1

    ResponderEliminar
  11. Hoy he intentado mandar un sendxmpp con algun caracter con acento:
    echo "Rubén" | sendxmpp -t -u usuariodersspi -o gmail.com -p superpassword correopersonal@gmail.com

    Al hacer el envio me sale este error:
    utf8 "\xBA" does not map to Unicode at /usr/local/bin/sendxmpp line 99, line 1.

    Y me llega a mi gtalk: "Rub鮊"

    Como puedo resolver este error de codificación de utf8 a ascii?
    Quiza es por mi locale?

    ResponderEliminar
  12. Creo que ya no se puede instalar como pone arriba, hay que hacerlo como dice Marcos porque los enlaces y todo eso ya no valen, han movido todo a github. Si lo instalais como dice Marcos un par de comments más arriba funciona:

    apt-get install libnet-xmpp-per

    cd /tmp
    git clone https://github.com/lhost/sendxmpp.git
    cd sendxmpp/
    perl Makefile.PL; # perl Makefile.PL PREFIX=/usr
    make
    make install

    echo "mygmailuser@gmail.com;talk.google.com mygmailpassword" >> ~/.sendxmpprc
    chmod 700 ~/.sendxmpprc
    cp -v ~/.sendxmpprc /etc/sendxmpprc

    ResponderEliminar
    Respuestas
    1. tengo pendiente una actualización, pero nunca tengo tiempo :(

      Eliminar
  13. Basandome en todo lo anterior he modificado un poco los scripts y funciona perfectamente pero he retocado los ficheros

    #PARA QUE CARGUE AL INICIO
    /etc/rc.local
    #!/bin/sh -e
    #
    # rc.local
    #
    # This script is executed at the end of each multiuser runlevel.
    # Make sure that the script will "exit 0" on success or any other
    # value on error.
    #
    # In order to enable or disable this script just change the execution
    # bits.
    #
    # By default this script does nothing.

    # Print the IP address
    _IP=$(hostname -I) || true
    if [ "$_IP" ]; then
    printf "My IP address is %s\n" "$_IP"
    fi

    # Cliente para el dominio midomino.no-ip.com
    /usr/local/bin/noip2
    # variable para el centerim que se ejecuta sobre el terminal virtual screen UTF-8
    export LANG=es_ES.UTF-8
    sudo screen -d -m -S -q -t "centerim" centerim
    # demonio para escuchar los mensajes de Gtalk
    sudo /usr/local/bin/demoniogtalk.sh 2> /dev/null &

    exit 0

    #DEMONIO QUE ESCUCHA LO QUE LLEGA AL CENTERIM
    /usr/local/bin/demoniogtalk.sh
    #!/bin/bash
    # demonio GTalk
    rm -f /root/.centerim/jdestino@gmail.com/history
    rm -f /tmp/gtalk.log
    touch /root/.centerim/jdestino@gmail.com/history
    touch /tmp/gtalk.log
    tail -f /root/.centerim/jdestino@gmail.com/history | gawk 'BEGIN { FS = ":" } ; {if ($1 ~ /9238/) system("/usr/local/bin/ejecutadorgtalk.sh "$2) }'


    # SCRIPT QUE HACE LO QUE SE LE INDICA SI LA CLAVE ES CORRECTA 9238
    /usr/local/bin/ejecutadorgtalk.sh
    #!/bin/bash
    #paso a minusculas los parametros
    CADENA=`echo $* | tr [:upper:] [:lower:]`
    USR=usuario_origen
    PWD=XXXXXX
    USR_DEST=destino@gmail.com
    SERV=gmail.com

    case $CADENA in
    alarmaon)
    echo "Conectando alarma" | /usr/local/bin/sendxmpp -t -u $USR -o $SERV -p $PWD $USR_DEST ;
    ;;
    alarmaoff)
    echo "Apagando alarma" | /usr/local/bin/sendxmpp -t -u $USR -o $SERV -p $PWD $USR_DEST ;
    ;;
    ayuda)
    echo -e "Instrucciones:\n\talarmaon\n\talarmaoff" | /usr/local/bin/sendxmpp -t -u $USR -o $SERV -p $PWD $USR_DEST ;
    ;;
    * )
    echo "No se reconoce la orden: '$CADENA'" >> /tmp/gtalk.log ;
    echo "No se reconoce la orden: '$CADENA'" | /usr/local/bin/sendxmpp -t -u $USR -o $SERV -p $PWD $USR_DEST ;
    ;;
    esac


    y ya de paso pues lo uso para saber cuando se conecta el usuario pi
    en .bashrc he metido al final

    USR=usuario_origen
    PWD=XXXXXX
    USR_DEST=destino@gmail.com
    SERV=gmail.com

    export LANG=es_ES.UTF-8
    # me mando un aviso para saber cuando alguien se loguea en esta cuenta
    echo "Acceso a "$(hostname)" como "$USER" el "$(date) | /usr/local/bin/sendxmpp -t -u $USR -o $SERV -p $PWD $USR_DEST ;

    los mensajes que se envías por gtalk son del estilo
    9238:alarmaon
    9238:alarmaoff
    9238:ayuda
    9238:este mensaje no vale para nada pero lo procesa
    9876:a ver si cuela pero la clave 9876 no vale solo la 9238

    ResponderEliminar
  14. A mi al enviar el mensaje de pruebas me sale el siguiente error:

    /tmp#echo "Acceso a "$(hostname)" como "$USER" el "$(date) | /usr/local/bin/sendxmpp -t -u $USR -o $SERV -p $PWD $USR_DEST ;
    Use of uninitialized value in string eq at /usr/local/bin/sendxmpp line 496.
    Error 'AuthSend': [?]


    Alguien sabe de que puede ser ???
    He estado revisando pero no localizo el error....

    ResponderEliminar
  15. Hola,
    centerim tiene incluído un sistema llamado external (mira en el apartado 9 del README) que te evita tener que hacer tú mismo el demonio de escucha y emplear sendxmpp para las respuestas.
    El rendimiento es bastante mejor que con este apaño que has hecho, que de todas formas, está muy bien.

    Enhorabuena por tu blog, estoy disfrutando mucho de él y de mi RPi.

    ResponderEliminar
    Respuestas
    1. tengo que reapañear el apaño, así que me va a venir muy bien esto que me dices, gracias por la info.

      Eliminar
  16. Antes de nada decirte, Juan Mol, que tu blog me encanta y me está haciendo divertirme aún mas con mi Raspberry Pi. Grandísimo trabajo!

    Me gustaría responder a las personas que les está dando el error de "AuthSend" yo también lo he sufrido ":(".
    En mi caso, me daba el error debido a que tenía activada la "Verificación a dos pasos" por eso no terminaba de loguearse.
    Una vez desactivada, me ha permitido intentar enviar mensajes, pero se perdían en el limbo, y es porque mis dos cuentas no se conocían. Debéis de entrar en gmail (En cualquiera de las cuentas) y enviar una solicitud de chat, así se creará un vínculo de amistad (que bonito) y entonces los mensajes se recibirán perfectamente :)

    ResponderEliminar
  17. Buenas,
    Lo primero: enhorabuena por este gran blog!!

    Lo segundo: no consigo recibir ningún mensaje en mi Gtalk. Se inscriben los mensajes en el historial, centerim se ejecuta (correctamente configurado), pero nada... Si pongo echo "This is a test IM" | sendxmpp -t receivergmailuser@gmail.com llega sin problemas, pero no me funciona con el demonio...

    ResponderEliminar
  18. Buenas,

    pues estoy con un caso curioso, defino el .sendxmpprc con mis datos ( emisor ) y cuando mando el echo

    echo "test" | sendxmpp -t cuentadestino@gmail.com, recibo yo mismo el mensaje en el gtalk del emisor

    ResponderEliminar
  19. pi@raspberrypi:~$ echo "Ola ke ase" | sendxmpp -t micorreo@gmail.com
    Use of uninitialized value in string eq at /usr/bin/sendxmpp line 479.
    Error 'AuthSend': [?]

    Y ahí se queda..

    ResponderEliminar
    Respuestas
    1. prueba mejor con centerim http://rsppi.blogspot.com.es/2013/07/uso-de-hangouts-gtalk-para-el-envio-de.html

      Eliminar
    2. >>sudo apt-get update
      >>sudo apt-get install sendxmpp
      >>echo “# nombre_cuenta” > ~/.sendxmpprc
      >>echo “nombre_cuenta@gmail.com;talk.google.com mygmailpassword gmail.com” >> ~/.sendxmpprc
      >>sudo chmod 600 /etc/sendxmpprc
      >>cp -v ~/.sendxmpprc /etc/sendxmpprc
      >>sudo echo "Mensaje de prueba" | sendxmpp -t mail_al_que_envias@gmail.com -f /etc/sendxmpprc
      OJO!!! La contrasña con la que mandas el mensaje no debe tener caracteres tipo (!, $, /,....) o te dara error.
      OJO!!! Debes tener el contacto al que mandas el gtalk en la agenda de la cuenta desde que lo mandas

      Eliminar