Bot para chat de Facebook

Estándar

NOTA: El código aquí no funciona más. Ve a este enlace para una versión actualizada.

Muchas veces necesitamos comunicar algo a todos nuestros contactos en Facebook. Por ejemplo, para celebrar nuestra fiesta de cumpleaños, salir a pasear un rato, o tal vez para un evento masivo.

Pero sabemos que crear un “evento” en Facebook no es lo mejor: nadie los ve (me incluyo). Facebook se tomó la molestia de colocar a la barra lateral su panel de eventos, sabiendo que cuando visitan el sitio, la mayoría ve al centro. No sé lo que pensaría su creador, pero bueno, eso no es de mi incumbencia.

Ahora, ¿de qué forma hacemos llegar nuestro mensaje a todos nuestros amigos? Pues de ninguna. Siempre verás que cuando creas un evento, quienes primero lo ven son los que están online. Entonces, ¿para qué enviar a los demás el mensaje si ni siquiera lo van a ver?

Bueno, dejando ya de criticar a Facebook. Muchas veces me vi en aprietos al querer comunicar algo a todos los conectados, y tuve que ir de ventanita en ventanita haciendo “Ctrl+C“, “Ctrl+V” en cada uno de los campos. Y si tengo 40 conectados, créanme que no es nada bonito cansarse tocando tanto el teclado sólo para eso.

Vi en varios foros alguna solución al respecto, y veo que se quedaron con el Facebook del año 2011 (23 de abril y 10 de junio). La verdad me dispuse a probar cada uno de ellos. ¡Ninguno me funcionó! Se complica tanto la cosa cuando intentan hacer expresiones regulares y uno no entiende absolutamente ni mierda nada.

¡Venga el código!

Visto esto, y con la necesidad de informar masivamente, es que decidí hacer algo yo mismo. Pues con las experiencias que tengo viendo código en Internet, supe que no iba a encontrar algo que acertara. ¡Y pues aquí tengo un código JavaScript que funcionará para comunicar a todos los conectados del chat, a modo de bot para chat de Facebook!

/**
 * Send a message to all your online Facebook contacts
 *
 * @author Bryan Horna <bryanjhv@gmail.com>
 * @version 1.0
 */

// Your message
var message = "Hi! I'm trying my new Facebook Chat Bot." +
" Would you like how to build your own?" +
" Go to https://bryanjhvtk.wordpress.com/2013/12/02/bot-chat-facebook/";

// Only load jQuery if it isn't present yet
if ( !window.jQuery ) {
  var _jQ = document.createElement( "script" );
  _jQ.setAttribute( "type", "text/javascript" );
  _jQ.setAttribute( "id", "_jQ" );
  _jQ.setAttribute( "src", "//code.jquery.com/jquery-1.10.2.min.js" + "?r=" + ( new Date() ).getTime() );
  document.getElementsByTagName( "head" )[ 0 ].appendChild( _jQ );
  _jQ.onload = function() {

    // If jQuery is now loaded, send the message
    sendAll( message );
  };
}

// When DOM is ready for work
var sendAll = function( msg ) {
  jQuery( document ).ready(function( $ ) {

    var fb_ = "https://m.facebook.com";

    // Get all online contacts
    $.ajax({
      url: fb_ + "/buddylist.php",
      success: function( src ) {
        var buddies = $( ".buddylistItem a", $.parseHTML( src ) );
        for ( var i = 0; i < buddies.length; i++ ) {
          var oneBuddy = $( buddies[ i ] ).attr( "href" );
          var fields = {};

          // Get contact by contact
          $.ajax({
            url: fb_ + oneBuddy,
            success: function( buddyPage ) {
              var form = $( "#composer_form", $.parseHTML( buddyPage ) )[ 0 ];
              var inputs = $( "input", form );
              for ( var j = 0; j < inputs.length; j++ ) {
                fields[ $( inputs[ j ] ).attr( "name" ) ] = $( inputs[ j ] ).attr( "value" );
              }

              // But "Reply" button isn't important now
              delete fields[ "send" ];

              // Add our message
              fields[ $( $( "textarea", form )[ 0 ] ).attr( "name" ) ] = msg;

              // Now, send the POST message
              $.ajax({
                url: fb_ + $( form ).attr( "action" ),
                type: "POST",
                data: fields,
                success: function( wasSent ) {

                  // Do what you want here
                  alert( "Message successfully sent to " + oneBuddy.match( /[0-9]+/i ) + "." );
                },
                error: function( code ) {
                  // Handle message not sent
                }
              });
            },
            error: function( code ) {
              // Handle get one buddy failed
            }
          });
        }
      },
      error: function( code ) {
        // Handle get buddies list failed
      }
    });
  });
};

// If jQuery has loaded, send now
sendAll( message );

Explicación del código

El código aquí expuesto aún está en fase beta, por lo que no garantizo su funcionamiento hasta ver resultados en otros usuarios. Pues tengo Facebook en inglés, y tal vez cambie algo, pero no creo que mucho. De todas maneras, explico su funcionamiento:

  • Primero que nada, verificamos si jQuery ya está cargado en la página (tal vez algo innecesario, porque Facebook no lo usa, o al menos nunca lo pude apreciar, pero tal vez también usas Greasemonkey y algún script ya lo cargó).
  • Luego se crea la función sendAll(), la cual como indica el nombre, envía el mensaje a todos los conectados. Dentro de ella, podemos destacar:
    • Se hace una petición al sitio móvil de Facebook en la pestaña de contactos.
    • Se parsea con jQuery el HTML obtenido con el GET, a fin de obtener cada ítem que aparece en dicha lista en el momento de la petición.
    • Iniciamos un bucle, a fin de ir enviando contacto por contacto el mensaje. Por ello, si tienes muchos contactos, tal vez sientas que el script se pone un poco lento. Es normal, tampoco quieras que XMLHttpRequest sea de gran velocidad como Comet o XMPP.
    • Obtenemos el enlace de cada contacto, pues ese es el que nos llevará a la página del usuario y permitirá obtener los campos del formulario de envío de mensajes móviles.
    • Hacemos una segunda petición GET, esta vez al enlace de cada contacto. Si ya tenías un historial de conversación, te lleva a una página (el script no hace eso, la redirección es automática). Sino, te lleva al enlace que se colocó.
    • Iniciamos buscando los campos que hay en el formulario, luego de parsear la página HTML con jQuery. Todos estos son guardados en el objeto JavaScript “field”. Luego de eso, eliminamos la clave “send”, pues es la correspondiente al botón de submit del formulario, y no nos interesa si enviaremos la petición vía POST.
    • Finalmente, hacemos una petición del tipo POST a la dirección obtenida del “action” del formulario (verás que varía si ya tienes historial de conversación o no). Los datos enviados son los que están en “field”, incluido nuestro mensaje.
  • Y finamente se hace la llamada a la función.

Cabe destacar que aún falta optimizar un poco esto, para que tal vez haga el trabajo más rápido, o haga menos peticiones AJAX y se reduzca un gran número de variables, o tal vez usando expresiones regulares en vez de jQuery. Si logro mejorarlo, iré publicando las actualizaciones.

Además, faltaría tener la capacidad de seleccionar los contactos a los que quieres enviar el mensaje, pues tuve que disculparme con muchos de mis amigos por los mensajes que les llegaron mientras probaba en mi cuenta. El script funciona hasta el día de hoy, sin saber su funcionamiento o validez en un futuro, pero asegurando que si ya no sirve, lo actualizaré.

Dime en los comentarios si te logró funcionar, para así poder publicar el código como un script en Greasemonkey.

P.D.: En cuanto tenga tiempo, lo subo a un servidor para que lo puedan incluir sin abrir la consola del navegador (F12), sino en la barra de direcciones. Además, poder pasarle como parámetro a la URL el mensaje que se quiere enviar, en lugar de modificar el código.

Actualización al 03/12/2013

Anduve probando en varias cuentas de Facebook de mis amigos, en la página web para escritorio, y lamentablemente no se envían los mensajes, se complican las conexiones AJAX hasta lograr perderse. Luego, hice un diagnóstico y concluí en que se debe ejecutar este código en una ventana abierta con la página móvil de Facebook (https://m.facebook.com) y ponerlo en la consola.

También tuve un problema en Google Chrome con la extensión Tampermonkey, así que tuve que ejecutarlo en Mozilla Firefox, por lo que debe ser ejecutado en Mozilla Firefox para funcionar.

Anuncios

¿Y tú qué opinas?

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s