Buscando la forma de leer Twitter con PHP para una aplicación, me encontré que muchos códigos fuente en PHP no funcionan porque son para la versión antigua de Twitter, otros códigos fuente PHP son para la versión moderna pero te obligan a registrarte, sacarte una clave de identificación, etc, y era como matar moscas a cañonazos.
Así que seguí buscando y encontré que hay otros métodos mucho más sencillos, incluso demasiado sencillos, así que he investigado un poco y aquí saco el trabajo de mis investigaciones sobre como obtener datos de Twitter con PHP, por si a alguien le resulta útil.
Primero muestro el código paso a paso y al final del artículo dejo un enlace para descargar todo el código completo que captura mensajes (y otros datos) de Twitter con PHP.
Warning!
Cuidado con hacer demasiadas peticiones a Twitter con estas rutinas, si haces más de 120 peticiones en menos de 15 minutos, te banearán y dejarán de funcionar. Para prevenir esto se puede hacer un temporizador, de manera que grabe los datos y no se vuelva a conectar a Twitter hasta pasado 1 minuto (de este modo serían 60 peticiones por hora como máximo). Más adelante hablaré en otro artículo sobre como implementar un temporizador de este tipo con PHP.Desactivar la caché con PHP
Para empezar, es altamente recomendable para este tipo de programas desactivar todo tipo de cachés, ya que en algunos navegadores mal configurados y sobretodo en dispositivos móviles, cuando se recarga la página, se visualiza la página web guardada en la caché del disco duro (o equivalente) y no se visualiza la del servidor web. Y por tanto, no se verían las nuevas publicaciones, siempre se verían las mismas.
Con el siguiente código en PHP, forzamos a que una página en PHP se cargue siempre desde el servidor y no de la caché:
// Desactivamos todo tipo de caches
header( "Expires: Mon, 20 Dec 1998 01:00:00 GMT" );
header( "Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT" );
header( "Cache-Control: no-cache, must-revalidate" );
header( "Pragma: no-cache" );
Convirtiendo texto en «enlaces Twitter»
La siguiente función no es mía, la publico el usuario Walter en los comentarios de la web Css-tricks.com, y su misión es procesar un texto y convertir ciertas cadenas a enlaces Twitter. Por ejemplo si se encuentra «Me gusta la #tecnologia moderna» convierte la palabra «#tecnologia» en un enlace que al clicarlo, visualizas los últimos tweets relacionados con #tecnlogia.
function twitterify($ret) {
$ret = preg_replace("#(^|[\n ])([\w]+?://[\w]+[^ \"\n\r\t< ]*)#" , "\\1\\2", $ret);
$ret = preg_replace("#(^|[\n ])((www|ftp)\.[^ \"\t\n\r< ]*)#", "\\1\\2", $ret);
$ret = preg_replace("/@(\w+)/", "@\\1", $ret);
$ret = preg_replace("/#(\w+)/", "#\\1", $ret);
return $ret;
}
Leer Twitter con PHP y obtener datos y mensajes de un usuario
Ahora pasamos al capturador de mensajes de un usuario (sólo de un usuario, no de otras cosas), que permitirá leer Twitter con PHP y obtener sus datos en tu propia web.
Al inicio tenemos la variable «$usuario» donde le asignaremos un nombre de usuario de Twitter, en este caso al usuario David Bravo del cual soy un fan suyo (aunque él no me conozca). Y en la variable «$numDeTweets» le asignamos cuantos mensajes queremos ver, en nuestro caso le ponemos un 5 porque queremos visualizar sus últimos 5 mensajes:
$usuario= "@dbravo";
$numDeTweets=5; // numero de tweets que se quieren visualizar
$twitter = "https://api.twitter.com/1/statuses/user_timeline/".$usuario.".xml?count=".$numDeTweets."&include_rts=1callback=?";
$xml = simplexml_load_file($twitter) or die("Error en la conexión");
foreach($xml->status as $datos){
$text = "
Hora: ".date("Y/m/d H:i:s",strtotime($datos->created_at)); // extrae la fecha
$text = $text."
Mensaje: ".twitterify($datos->text); // extrae el texto
$text = $text."
Id: ".($datos->id);
$text = $text."
source: ".($datos->source);
$text = $text."
in_reply_to_status_id: ".($datos->in_reply_to_status_id);
$text = $text."
retweeted: ".($datos->retweeted);
$text = $text."
retweet_count: ".($datos->retweet_count);
$text = $text."
in_reply_to_screen_name: ".($datos->in_reply_to_screen_name);
$text = $text."
in_reply_to_user_id: ".($datos->in_reply_to_user_id);
$text = $text."
in_reply_to_status_id: ".($datos->in_reply_to_user_id);
$text = $text."
favorited: ".($datos->favorited);
$text = $text."
truncated: ".($datos->truncated);
/*
// No funcionan
$text = $text."
profile_image_url:
profile_image_url)."\">";
$text = $text."
profile_image_url: ".($datos->profile_image_url);
$text = $text."
geo: ".($datos->geo);
$text = $text."
retweet: ".($datos->retweet);
$text = $text."
user: ".($datos->user);
$text = $text."
place: ".($datos->place);
$text = $text."
coordinates: ".($datos->coordinates);
$text = $text."
contributors: ".($datos->contributors);
$text = $text."
screen_name: ".($datos->screen_name);
$text = $text."
name: ".($datos->name);
$text = $text."
followers_count: ".($datos->followers_count);
$text = $text."
mentions: ".($datos->mentions);
$text = $text."
links: ".($datos->links);
$text = $text."
domains: ".($datos->domains);
*/
echo $text."
-------------------";
}
Como se puede ver en el anterior ejemplo, al final hay toda una serie de objetos que los he dejado como comentarios. En teoría deberían funcionar según la documentación oficial hasta el momento y según otras webs que hablan sobre el tema, pero en mis pruebas estos objetos devuelven siempre el valor en blanco. Por si a alguien le interesan, aquí las dejo.
Leer mensajes de cualquier cosa en Twitter, usando su buscador
Ahora haremos algo parecido a lo anterior pero con otro método. En lugar de leer o capturar los tweets de un usuario, vamos a extraer los datos de una búsqueda, ya sea una palabra o un hashtag o cualquier otra cosa que se haya publicado en Twitter.
El problema es que tan sólo se puede recuperar un número limitado de mensajes (sólo los últimos 15 tweets).
// Captura mensajes que contengan la palabra #tecnologia en Twitter
echo "
------ TWEETS SOBRE LA PALABRA #tecnologia ------
";
$tema= "#tecnologia";
$twitter = "http://search.twitter.com/search.json?q=$tema";
$manejadorCurl = curl_init();
curl_setopt($manejadorCurl, CURLOPT_URL, $twitter);
curl_setopt($manejadorCurl, CURLOPT_RETURNTRANSFER, 1);
$respuesta = curl_exec($manejadorCurl);
curl_close($manejadorCurl);
$json = json_decode($respuesta);
foreach ($json->results as $datos)
{
$text = "
Hora: ".date("Y/m/d H:i:s",strtotime($datos->created_at)); // extrae la fecha
$text = $text."
profile_image_url:
profile_image_url)."\">";
$text = $text."
Mensaje: ".twitterify($datos->text); // extrae el texto
$text = $text."
Id: ".($datos->id);
$text = $text."
source: ".($datos->source);
// El objeto "geo" no se lee bien, a veces da error tipo "Catchable fatal error:
// Object of class stdClass could not be converted to string in ..."
// $text = $text."
geo: ".($datos->geo);
/*
// No funcionan
$text = $text."
retweeted: ".($datos->retweeted);
$text = $text."
retweet_count: ".($datos->retweet_count);
$text = $text."
in_reply_to_screen_name: ".($datos->in_reply_to_screen_name);
$text = $text."
in_reply_to_user_id: ".($datos->in_reply_to_user_id);
$text = $text."
in_reply_to_status_id: ".($datos->in_reply_to_user_id);
$text = $text."
favorited: ".($datos->favorited);
$text = $text."
truncated: ".($datos->truncated);
$text = $text."
retweet: ".($datos->retweet);
$text = $text."
user: ".($datos->user);
$text = $text."
place: ".($datos->place);
$text = $text."
coordinates: ".($datos->coordinates);
$text = $text."
contributors: ".($datos->contributors);
$text = $text."
screen_name: ".($datos->screen_name);
$text = $text."
name: ".($datos->name);
$text = $text."
followers_count: ".($datos->followers_count);
$text = $text."
mentions: ".($datos->mentions);
$text = $text."
links: ".($datos->links);
$text = $text."
domains: ".($datos->domains);
*/
echo $text."
-------------------";
}
Igual que antes, algunas etiquetas no devuelven nada (cadena vacía) pero aquí las dejo por si lo necesitáis para algo.
Important!
El objeto «geo» es un misterio para mi, en algunos mensajes de Twitter he descubierto que contiene «algo» porque me provoca un error en el servidor tipo «Object of class stdClass could not be converted to string in …», pero no consigo extraer la información.
He probado diferentes métodos, tratarlo como una array, etc y no he encontrado la forma de visualizar el contenido del objeto llamado «geo». En algunas webs sugieren que podrían ser las coordenadas desde donde se envió el mensaje, pero nadie explica como leerlas con un método que funcione. ¿Lo sabes tu por casualidad?
Descargar el código fuente completo
Y ya para acabar, dejo aquí en un fichero todo el código completo para leer mensajes de Twitter con PHP, funcionando y comprobado, así os ahorro tiempo:
Por favor, si te son útiles estas rutinas o las perfeccionas, o descubres fallos, o encuentras más información sobre más objetos que se puedan extraer, publica un comentario. Gracias.