viernes, 10 de mayo de 2013

Malas noticias

Aparentemente googlevoice no funciona en Argentina.. asi que la solucion que habia pensado que iba a funcionar para poder usar WhatsApi para enviar mensajes desde la PC no se va a poder utilizar...

Espero mañana poder tener novedades!.

jueves, 9 de mayo de 2013

Enviar mensajes con Whatsapp desde la PC

No se descubre nada si se dice que Whatsapp esta siendo cada vez más popular, y creo que la siguiente es una pregunta que nos hemos hecho varios ¿Se pueden enviar mensajes utilizando una PC por medio de Whatsapp?. En primera instancia y sabiendo que los mensajes de Whatsapp son enviados vía Web (Es decir no utiliza las lineas telefónicas) podríamos decir que si es posible, ahora la pregunta del millón es ¿Como?.

Bueno, la forma mas "sencilla" y directa es instalar un emulador de Android en nuestra computadora, y luego instalarle Whatsapp, configurarlo y LISTO!.

No gastaremos tiempo en explicar como hacer la descarga de BlueStack ya que esta lleno de tutoriales dando vueltas por la web, ni tampoco explicaremos como hacer la configuración de WhatsApp, ya que también se encuentra en muchos sitios. Para los mas perezosos aquí les dejo el link en donde se muestra como instalar BlueStack y como configurar WhatsApp.

Tutorial instalacion BlueStack configura WhatsApp

Para la gran mayoría de las personas, la instalación de este emulador y la configuración de WhatsApp, seria suficiente para satisfacer sus necesidades, de todas formas a muuuuuuuchos les gustaría tener mas control sobre lo que se puede hacer, como enviar mensajes de forma automática, o realizar alguna acción algo mas compleja al recibir un mensaje.

Seguramente que si llegamos a este punto, contamos con algún conocimiento al menos básico de programación ya que tenemos que empezar a ver cosas algo mas complejas.
Solo como anécdota, les puedo contar que la gente de WhatsApp se encuentra muy pero muy reacia a la posibilidad de que los usuarios tengan algún tipo de control sobre el envió de mensajes desde fuera de los teléfonos moviles, quizás sea un tema de estructura o de capacidad, no se bien a que se debe, pero se que están permanentemente realizando actualizaciones que hacen laburar cada vez mas a los cráneos que han logrado desenmarañar por medio de ingeniería inversa las directrices de la comunicación por medio de WhatsApp.

Como la mayoría sabe, el nombre de usuario en WhatsApp no es ni mas ni menos que el numero telefonico competo del usuario, con esta idea innovadora los creadores de WhatsApp lograban desligar al usuario final de los tediosos pasos para la registracion de sus cuentas, sin embargo como todos sabemos Whatsapp no solicita un password a la hora de loguearnos al sistema, sino que genera uno en base a de algunos datos de nuestro telefono movil. En primera instancia era un md5 del IMEI invertido, luego fue un dato en base64 del mismo imei o de la MAC de acuerdo al sistema operativo que se utilizaba. El tema es que habian graves problemas de seguridad, ya que teniendo el numero de telefono y el imei o la MAC de un telefono ajeno, se podia suplantar la identidad de alguna persona, y hasta incluso segun cuenta la leyenda se podian leer conversaciones y cambiar foto de perfil y estado de WhatsApp... :)...

La ultima medida que tomaron los señores "Whatsapperos" fue brindar una clave mas compleja a sus usuarios, y por lo tanto mas dificil de comprender su armado. De todas formas hecha la ley, hecha la trampa.. :)..

Existe una API (Application Programming Interface), ingeniosamente llamada WhatsApi, que se ha desarrollado y se ha liberado al mundo, la misma permite tener control sobre gran parte de la mensajería de WhatsApp, lamentablemente esta API "deschavo" algunos de los graves problemas de seguridad con los que contaba WhatsApp, por lo cual la empresa comenzó acciones legales contra los creadores para que bajen dicha API de la Web, de todas formas ya se había extendido demasiado, por lo cual a estas alturas es casi imposible evitar que cualquiera pueda tenerla en sus manos. Por este motivo a la gente de WhatsApp Inc. no les quedo otra que poner manos a la obra y tratar de tapar esos baches. Ahí es que comenzó el tire y afloje entre los dueños de WhatsApp y los creadores de WhatsApi, el sistema de mensajería realizaba cambios en su validación de usuarios y la comunidad actualizaba la API para soportar ese cambio. Ahora se llego a un punto en el que no se ha podido descifrar el método de creación de la clave, peroooooooooooooo, aún así se puede seguir usando esta API.

Por ahora solo dejare un link en donde dice cuales serian los pasos a seguir para poder comenzar o continuar trabajando con WhatsApi. Aún no he podido probar a fondo esta solución, pero en breves lo haré y lo comentare para que haya algo en Español.

Continuar usando Whatsapi

Eso seria todo por ahora. Nos estamos viendo en la próxima publicación.

jueves, 7 de marzo de 2013

Recomendada programacion orientada a objetos PHP

Ya hace un tiempo que programo con PHP, cerca de 2 años, el tema es que hasta hace 1 mas o menos no comprendía los beneficios de programar orientado a objetos (Ojo no soy un purista de esto, si me queda mas sencillo resolver algo proceduralmente lo haría sin ponerme colorado). 

La estructura basica que estoy usando es una forma de "modelado" en la cual por cada clase tengo dos clases, una que se ocupa de toda la comunicacion con la Base de datos y otra que es el objeto propiamente dicho al cual simplemente le envio mensajes tales como:
  • $usr = Usuario::obtenerPorId($id) y me devuelve un objeto Usuario al cual luego le puedo hacer cosas tales como  $usr->getNick() y me devolvería el nombre de usuario.. :)
Entonces si vamos al ejemplo de la clase usuario tendría las siguiente clases:
  • Usuario.php
  • dUsuario.php
Con estas clases podria resolver toda la lógica. 

La clase Usuario tendría toda la lógica incluyendo los geters y los seters y se ocuparía de hacer el mapeo a objetos de las tablas relacionales. 
Yo para hacer esto suelo tener un método estático que se ocupa de hacer dicho mapeo.
Simplemente le paso un registro de la base de datos obtenido con mysql_fetch_array o con mysqli.. :)

public static function  mapearTablaConObjeto($reg){
    $usuario = New Usuario();
    $usuario->setNick($reg["nombre"]);
    $usuario->setMail($reg["mail"]);
    $usuario->setPass($reg["clave"]);
    $usuario->setSid($reg["sid"]);
    $usuario->setIp($reg["ip"]);
    $usuario->setIdUsuario($reg["idUsuario"]);
    $usuario->setUltimaAccion($reg["ultima_accion"]);
    $usuario->setOnline($reg["online"]);
    $usuario->setPerfil($reg["perfil"]);
    return $usuario;
}

Basicamente la clase Usuario suele devolver un usuario en particular o un arreglo de varios usuarios.
Para mostrar un ejemplo voy a poner obtenerUsuarioPorId($id)

    /*
     * OBTIENE UN USUARIO A PARTIR DE UN ID
     */
    public static function obtenerUsuarioPorId($idUsuario){
        $reg_usuario = dObtenerUsuarioPorId($idUsuario);
if(!is_null($reg_usuario)){
    return Usuario::mapearTablaConObjeto($reg_usuario);
}
return NULL;
    }

Aquí lo que se hace es llamar a la función que se encuentra en dUsuario.php y se ocupa de obtener un usuario de la Base de Datos. 

Nota: Es importante que los datos lleguen validados. Es decir que si tiene que entrar un entero, sea un entero y que si tiene que ser una cadena sea una cadena valida. 

La función dObtenerUsuarioPorId($idUsuario) se veria como sigue:

function  dObtenerUsuarioPorId ($id){

    global $conexion;

    $registros = mysql_query("select * from usuarios 
                              where idUsuario=$id",$conexion) or
    die("Problemas en el select USUARIO:".mysql_error());
    if(mysql_num_rows($registros))
return mysql_fetch_array($registros);
    return NULL;
}

Puede verse que la dObtenerUsuarioPorId obtiene un usuario por un id, y en caso de que no recupere ninguno devuelve NULL, la funcion obtenerUsuarioPorId si recibe NULL devuelve NULL y si recibe un registro hace el mapeo y devuelve el objeto usuario!! para ser utilizado como plazca. 

Luego se podrían hacer cosas tales como:

include_once "Usuario.php";

$usr = Usuario::obtenerUsuarioPorId(1);
if(!is_null($usr)){
    echo $usr->getNick();   // Muestra el nick del usuario 1
    // Cambio el nick del objeto pero no lo persisto en la BD
    $usr->setNick("Otro nick");  
    echo $usr->getNick();  // Muestra "Otro nick"
    $usr = Usuario::obtenerUsuarioPorId(1); // Vuelvo a obtener el usuario 1
    // Como no lo habia guardado en la BD vuelvo a mostrar el nick del usuario 1
    echo $usr->getNick(); 
    // Cambio el nick del objeto pero aún no lo persisto en la BD
    $usr->setNick("Otro nick"); 
    // Guardo los cambios en la BD. Si el usr->isNew() inserto sino actualizo
    $usr->save();  
    echo $usr->getNick();  // Muestra "Otro nick"
    $usr = Usuario::obtenerUsuarioPorId(1); // Obtengo el usuario 1.
    echo $usr->getNick();   // Muestro "Otro nick" porque ya habia guardado los cambio. :) 
}

Espero que se haya entendido más o menos cual es mi idea, porque fue una explicación medio rapida.. :).. cualquier consulta hagan!. jeje 

Saludos! 

El proyecto de un juego de navegador

Bueno el proyecto del juego de navegador quedara relegado por el momento... :). es necesario a mi entender tener ciertos privilegios sobre la Base de Datos que en el servicio de hosting con el que cuento no los tienen (Y tampoco tengo el dinero para invertir, no es mucho pero tengo otras prioridades por el momento).

Para hacer que un juego on-line funcione, le cuento a los mas despistados tienen que resolver casi todo del lado del servidor sin estar obligado a que el usuario intervenga ni este conectado.
El usuario simplemente ejecuta una acción

Por ejemplo:

  • Transportar recursos o realizar un ataque.

Pero no tiene que ejecutar ninguna acción para que el transporte llegue a destino, simplemente envía y espera a que pase el tiempo necesario para que la acción concluya, el usuario puede estar conectado o fuera de linea al momento de la llegada, pero lo que es seguro es que la acción debe finalizar igual.. :)

La forma que encontré de desarrollar esta "Asincronidad" o "Desatendimiento" de las acciones fue utilizar Eventos de la Base de datos.. :)

En un primero momento lo hacia con javascript que cuando viera que se terminaba un tiempo revisara que se había finalizado... perooooo eso obliga al usuario a estar conectado o al menos con el navegador abierto.. jejeje detalles de diseño..

Si a alguno se le ocurre otra idea bienvenida, pense en usar Cron pero no hubo caso.