Ayer no me apetecía nada de nada estudiar, y pensé que para aprender algo nuevo, y de paso mejorar un poco “Compartir en Tuenti” era buena idea echar un ojo a cURL. Se me ocurrió que podría ser útil que el plugin para WordPress pudiera actualizar nuestros estados con enlaces a las nuevas entradas del blog de forma automática. No era algo nuevo, ya que los plugins para Twitter, a pesar de que emplean un API, lo que hacen es eso, twittear con los cambios del blog (@Tecno_Caos).
A falta de API en Tuenti sólo queda intentar eso, emplear cURL, que es una librería preparada para conectar y comunicarse con muchos tipos de servidores y muchos tipos de protocolos. Actualmente libcurl soporta los protocolos http, https, ftp, gopher, telnet, dict, file y ldap. libcurl también soporta certificados HTTPS, HTTP, POST, HTTP PUT, subida de ficheros usando FTP (también se puede hacer con la extensión FTP de PHP), formularios HTTP, proxies, cookies, y autenticaciones usuario+contraseña (copy & paste de PHP.net). El uso que yo quería darle era simple, con poder usar POST y GET me valía, así que ahora voy a explicar las funciones principales:
- curl_init(), para iniciar la sesión cURL y obtener el manejador. Opcionalmente recibe una URL como parámetro. Se usa simplemente así:
- curl_setopt(), es la función que más he usado, se emplea para fijar valores a parámetros de configuración. La lista de parámetros es muy amplia. Un ejemplo de su uso sería:
- curl_exec(), para ejecutar la petición con todos los parámetros de configuración que hemos fijado. Si ponemos la opción CURLOPT_RETURNTRANSFER a TRUE devuelve la salida de la ejecución en una variable en lugar de imprimirla, que es el comportamiento por defecto (funciona como un echo):
- curl_close(), para cerrar la sesión cURL:
$handler = curl_init();
curl_setopt($handler, CURLOPT_POST, false); //Fijo la peticion POST a false, lo que activa la peticion GET
$response = curl_exec ($handler);
curl_close($handler);
He tenido algunos problemas con las Cookies. Se supone que puede hacer que se guarden en un fichero configurando CURLOPT_COOKIEJAR y CURLOPT_COOKIEFILE, pero aunque he conseguido que las Cookies se guardaran correctamente, el Javascript de la página no hacía bien las modificaciones sobre el fichero, así que decidí hacerlas a mano modificando el valor de CURLOPT_COOKIE.
Como creo que lo mejor es que pegue aquí una clase que me he creado para iniciar sesión en Tuenti y hacer un par de cosas más, y que comente cada linea interesante…
class Tuenti{ var $handler; var $response; var $ruta_cookie; var $cookie; var $csfr; var $user_id; function crearCookie(){ ruta_cookie = "cookie.txt"; $fp = fopen($this->ruta_cookie, "w"); //creo un fichero para almacenar las Cookies fclose($fp); chmod($this->ruta_cookie, 0777); //le cambio los permisos por si acaso... } function __construct(){ $this->handler = curl_init(); curl_setopt($this->handler, CURLOPT_COOKIESESSION, true ); curl_setopt($this->handler, CURLINFO_HEADER_OUT, true ); curl_setopt($this->handler, CURLOPT_COOKIEJAR, $this->ruta_cookie); //Fichero donde se guardan Cookies al cerrar conexion curl_setopt($this->handler, CURLOPT_COOKIEFILE, $this->ruta_cookie); //Fichero donde se almacenan las Cookies curl_setopt($this->handler, CURLOPT_FAILONERROR, false ); curl_setopt($this->handler, CURLOPT_TIMEOUT, false ); curl_setopt($this->handler, CURLOPT_AUTOREFERER, true); //Cambio de HTTP Referer automatico curl_setopt($this->handler, CURLOPT_FOLLOWLOCATION, true); //Sigue automaticamente las URL que devuelve la cabecera HTTP curl_setopt($this->handler, CURLOPT_VERBOSE, false ); curl_setopt($this->handler, CURLOPT_USERAGENT,"Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_4; en-US) AppleWebKit/533.4 (KHTML, like Gecko) Chrome/5.0.375.127 Safari/533.4"); //Cambia el User-Agent, la informacion sobre el navegador usado por el cliente curl_setopt($this->handler, CURLOPT_HTTPHEADER, array("Accept-Language: es-ES,es;q=0.8", "Accept: application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5", "Proxy-Connection: keep-alive", "Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3")); //Configuracion de la cabecera HTTP curl_setopt($this->handler, CURLOPT_POST, false); //Inicialmente configurado con GET curl_setopt($this->handler, CURLOPT_HEADER, true); //Devuelve las cabeceras junto con la respuesta del servidor curl_setopt($this->handler, CURLOPT_CONNECTTIMEOUT, false); curl_setopt($this->handler, CURLOPT_RETURNTRANSFER, true); //Redirige la salida de curl_exec a una variable } function iniciarSesionTuenti($login, $pass){ $url_base = "http://www.tuenti.com/?m=login"; //Primera carga de la pagina curl_setopt($this->handler, CURLOPT_POST, false); //Por GET curl_setopt($this->handler, CURLOPT_URL, $url_base); //Fijo la URL de destino $this->response = curl_exec ($this->handler); //Ejecuto //Mostrar el formulario de login curl_setopt($this->handler, CURLOPT_POST, false); $this->cookie = "manual_logout=deleted; ue=deleted; em=deleted; fa=deleted; et=deleted; domain=.tuenti.com; expires=Sun, 30-Aug-2020 12:11:30 GMT; path=/;"; curl_setopt($this->handler, CURLOPT_COOKIE, $this->cookie); //Modifico la Cookie con los valores devueltos en la HTTP Header de los Set-Cookie, lo que el server receptor quiere que anadamos a la cookie curl_setopt($this->handler, CURLOPT_URL, $url_base); //Fijo la URL $this->response = curl_exec ($this->handler); //Iniciar sesion $url_login = "https://www.tuenti.com/?m=Login&func=do_login"; curl_setopt($this->handler, CURLOPT_POST, true); // Lo preparo para un POST curl_setopt($this->handler, CURLOPT_POSTFIELDS, "email=$login&remember=1&timezone=2&input_password=$pass"); //Cadena con las variables enviadas por POST y sus valores. Tambien puede recibir un array asociativo (clave - valor) $this->cookie = "ourl=deleted; manual_logout=deleted; ue=deleted; em=deleted; fa=deleted; et=deleted; domain=.tuenti.com; expires=Sun, 30-Aug-2020 12:11:30 GMT; path=/;"; //Modifico la Cookie de nuevo curl_setopt($this->handler, CURLOPT_COOKIE, $this->cookie); curl_setopt($this->handler, CURLOPT_SSL_VERIFYPEER, false); // Que no compruebe nada del SSL curl_setopt($this->handler, CURLOPT_SSL_VERIFYHOST, false); // Pasando de SSL curl_setopt($this->handler, CURLOPT_URL, $url_login); // Fijo URL $this->response = curl_exec ($this->handler); $resultados = array(); preg_match('/sid=([a-zA-Z0-9]*);/', $this->response, $resultados); // Obtengo el valor de la sesion (sid) de usuario del Set-Cookie que aparece en la cabecera HTTP de la respuesta, para anadirlo a la Cookie $sid = $resultados[1]; //Entrar en el perfil"; $url_hash = "https://www.tuenti.com/"; curl_setopt($this->handler, CURLOPT_POST, false); $this->cookie = "sid=$sid; lang=es_ES; ourl=deleted; manual_logout=deleted; ue=deleted; em=deleted; fa=deleted; et=deleted; domain=.tuenti.com; expires=Sun, 30-Aug-2020 12:11:30 GMT; path=/;"; curl_setopt($this->handler, CURLOPT_COOKIE, $this->cookie); curl_setopt($this->handler, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($this->handler, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($this->handler, CURLOPT_URL, $url_hash); $this->response = curl_exec ($this->handler); //Tener hash; $url_hash = "https://www.tuenti.com/"; curl_setopt($this->handler, CURLOPT_POST, false); $this->cookie = "redirect_url=m=home&func=view_home; tempHash=m=home&func=view_home; max-age=30; sid=$sid; lang=es_ES; ourl=deleted; manual_logout=deleted; ue=deleted; em=deleted; fa=deleted; et=deleted; domain=.tuenti.com; expires=Sun, 30-Aug-2020 12:11:30 GMT; path=/;"; curl_setopt($this->handler, CURLOPT_COOKIE, $this->cookie); curl_setopt($this->handler, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($this->handler, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($this->handler, CURLOPT_URL, $url_hash); $this->response = curl_exec ($this->handler); $resultados = array(); preg_match('/user_id=([0-9]*)"/', $this->response, $resultados); //Ahora busco el user_id en el HTML de la respuesta, para mandarlo con otro formulario $this->user_id = $resultados[1]; } function compartirEnlace($url_post, $mensaje){ $url_base = "http://www.tuenti.com/?m=Share&func=index&url=".urlencode($url_post); // Uso urlencode para codificar los parametros de la URL //Primera carga de la pagina curl_setopt($this->handler, CURLOPT_POST, false); curl_setopt($this->handler, CURLOPT_URL, $url_base); $this->cookie .=" redirect_url=deleted; lp=1;"; curl_setopt($this->handler, CURLOPT_COOKIE, $this->cookie); $this->response = curl_exec ($this->handler); $resultados = array(); preg_match('/CSFR: \'([a-zA-Z0-9]*)\'/', $this->response, $resultados); // Busco el CSFR en el codigo HTML de la respuesta $this->csfr = $resultados[1]; //Envio de nuevo estado $url_envio = "https://wwwb21.tuenti.com/?m=Share&func=process_share_status&ajax=1&store=0&ajax_target=canvas"; curl_setopt($this->handler, CURLOPT_POST, true); curl_setopt($this->handler, CURLOPT_POSTFIELDS, "url=".urlencode($url_post)."&csfr=".$this->csfr."&status_body=".urlencode($mensaje)."〈=es_ES"); // Respondo incluyendo el CSFR curl_setopt($this->handler, CURLOPT_COOKIE, $this->cookie); curl_setopt($this->handler, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($this->handler, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($this->handler, CURLOPT_URL, $url_envio); $this->response = curl_exec ($this->handler); } function cerrarSesion(){ //Cerrar sesion $url_envio = "https://wwwb21.tuenti.com/?m=Logout&func=log_out&ajax=1&store=0&ajax_target=canvas"; curl_setopt($this->handler, CURLOPT_POST, true); curl_setopt($this->handler, CURLOPT_POSTFIELDS, "user_id=".$this->user_id."&csfr=".$this->csfr); // Uso el user_id y el csfr para cerrar sesion por POST curl_setopt($this->handler, CURLOPT_COOKIE, $this->cookie); curl_setopt($this->handler, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($this->handler, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($this->handler, CURLOPT_URL, $url_envio); $this->response = curl_exec ($this->handler); } function salir(){ unlink($this->ruta_cookie); // Destruyo el fichero de Cookies curl_close($this->handler); // Cierro la sesion de cURL unset($this->response); // Libero de memoria la respuesta } }
Con todo esto ya puedo hacer que mi plugin cambie mi estado por mi con las URLs a mis entradas nuevas, cosa que espero que haga con esta… Creo que esta noche lanzaré la versión que incluye los cambios.
Me han servido de ayuda PHP.net y dos tutoriales que encontre, este (con una clase de regalo muy práctica) y este otro (con un interesante caso práctico).
Si usáis cURL para algo y tenéis dudas (o me echáis con algo que no haya dicho/usado bien) comentario…

Si se configura Twitter en Tuenti y además se tiene FaceBook, se podría usar un pequeño truco para que al publicar los artículos del blog en la frase de estado de Tuenti llegue hasta FaceBook por lo que quizás estaría bien ofrecer en el plugin la opción de añadir #fb al final de lo que se publica en la frase de estado, o quizás que permita configurar el formato que se publicará de la frase de estado con variables, por ejemplo:
Visita $blog_url : $post_url #fb
Esperemos que esta novedad del plugin no lo vea con malos ojos Tuenti, ya que no son muy amigables de los programas que automatizan cosas hacia sus servidores (por esto mismo no habiamos sugerido esta idea antes, pero ya que la lanzas…gran trabajo!!)
Saludos.
Y no hay alguna manera de enviar un nuevo status, pero sin compartir enlaces?