Twitter: Error leyendo tweets sin autentificar con la API 1.0

Twitter ha actualizado su API a la versión 1.1.

Uno de los cambios de esta API ha provocado que muchas de las páginas en las que había programado una lista de tweets para una cuenta de Twitter determinada dejaran de funcionar.
Por ejemplo en muchos casos programé bloques o muros de tweets utilizando Tweet! (plugin de jQuery).

La conexión que realiza este plugin, a día de hoy, se basa en la vieja API 1.0 en la que no eran necesarias las conexiones autentificadas. No me ha quedado otra que revisar página a página y adaptar el listado de tweets a la nueva API 1.1.

Por suerte, mucha gente se ha encontrado en el mismo problema y ya han encontrado una solución que permite no empezar desde 0.

En este repositorio de GitHub se pueden descargar los nuevos archivos php y js necesarios para que vuelva a funcionar.

Los pasos a seguir son los siguientes:

1) El repositorio utiliza como acceso a la API la dirección /twitter. En mi caso, como la mayoría de mis webs funcionan con CI, he tenido que crear un controlador llamado twitter en cada una de ellas.

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
 
class Twitter extends CI_Controller {
	public function index()
	{
		$this->twitteroauth->init();
		$this->twitteroauth->fetch();
	}
}

2) Sobrescribir el fichero de Tweet! jquery.tweet.js o su minificado, depende de cual hayamos utilizado.

3) Crear una app en Twitter. Entramos en https://dev.twitter.com/apps y creamos una aplicación rellenando el formulario, indicando como Callback URL y Website la dirección de nuestra página web. Una vez creada generará unos campos que son los que utilizaremos en las variables de configuración de la clase ezTweet si estáis siguiendo los archivos del repositorio. Los campos son App Consume Key, App Consumer Secret, App Access Token y App Access Token Secret.

4) Adaptar las librerías PHP y el archivo index.php para realizar la autentificación. De nuevo, en el caso de CI, hay que adaptarlo. Lo que he ido haciendo es crear librerías con el código que viene en index.php adaptado y las llamo desde el controlador de twitter. Es decir, me he cargado la clase ezTweet y he creado una nueva TwitterOauth que lo único diferente que tiene es que inicializa sus variables de configuración en una función init:

<?php  if ( ! defined('BASEPATH')) exit('No direct script access allowed');
/**
 * Current TwitterOauth Class
 *
 * @package	Twitter oAuth
 * @subpackage	Libraries
 * @category	Utils Functions
 */
class CI_TwitterOauth {
 
	// Your Twitter App Consumer Key
	private $consumer_key = '';
 
	// Your Twitter App Consumer Secret
	private $consumer_secret = '';
 
	// Your Twitter App Access Token
	private $user_token = '';
 
	// Your Twitter App Access Token Secret
	private $user_secret = '';
 
	// Path to tmhOAuth libraries
	private $lib = '';
 
	// Enable caching
	private $cache_enabled = true;
 
	// Cache interval (minutes)
	private $cache_interval = 15;
 
	// Path to writable cache directory
	private $cache_dir = './';
 
	// Enable debugging
	private $debug = true;
 
	/**************************************************************************************/
 
	public function init() {
 
		$this->CI =& get_instance();
 
		// Initialize paths and etc.
		$this->pathify($this->cache_dir);
		$this->pathify($this->lib);
		$this->message = '';
 
		// Set server-side debug params
		if($this->debug === true) {
			error_reporting(-1);
		} else {
			error_reporting(0);
		}
 
		$this->consumer_key = 'CONSUMER KEY AQUÍ';
		$this->consumer_secret = 'CONSUMER SECRET AQUÍ';
		$this->user_token = 'USER TOKEN AQUÍ';
		$this->user_secret = 'USER SECRET AQUÍ';
		$this->lib = APPPATH. 'libraries/lib/';   // En mi caso tengo los archivos tmhOAuth.php y tmhUtilities.php del repositorio en application/libraries/lib
		$this->cache_enabled = true;
		$this->cache_interval = 15;
		$this->cache_dir = './';
		$this->debug = true;
	}
 
	public function fetch() {
		echo json_encode(
			array(
				'response' => json_decode($this->getJSON(), true),
				'message' => ($this->debug) ? $this->message : false
			)
		);
	}
 
	private function getJSON() {
		if($this->cache_enabled === true) {
			$CFID = $this->generateCFID();
			$cache_file = $this->cache_dir.$CFID;
 
			if(file_exists($cache_file) && (filemtime($cache_file) > (time() - 60 * intval($this->cache_interval)))) {
				return file_get_contents($cache_file, FILE_USE_INCLUDE_PATH);
			} else {
 
				$JSONraw = $this->getTwitterJSON();
				$JSON = $JSONraw['response'];
 
				// Don't write a bad cache file if there was a CURL error
				if($JSONraw['errno'] != 0) {
					$this->consoleDebug($JSONraw['error']);
					return $JSON;
				}
 
				if($this->debug === true) {
					// Check for twitter-side errors
					$pj = json_decode($JSON, true);
					if(isset($pj['errors'])) {
						foreach($pj['errors'] as $error) {
							$message = 'Twitter Error: "'.$error['message'].'", Error Code #'.$error['code'];
							$this->consoleDebug($message);
						}
						return false;
					}
				}
 
				if(is_writable($this->cache_dir) && $JSONraw) {
					if(file_put_contents($cache_file, $JSON, LOCK_EX) === false) {
						$this->consoleDebug("Error writing cache file");
					}
				} else {
					$this->consoleDebug("Cache directory is not writable");
				}
				return $JSON;
			}
		} else {
			$JSONraw = $this->getTwitterJSON();
 
			if($this->debug === true) {
				// Check for CURL errors
				if($JSONraw['errno'] != 0) {
					$this->consoleDebug($JSONraw['error']);
				}
 
				// Check for twitter-side errors
				$pj = json_decode($JSONraw['response'], true);
				if(isset($pj['errors'])) {
					foreach($pj['errors'] as $error) {
						$message = 'Twitter Error: "'.$error['message'].'", Error Code #'.$error['code'];
						$this->consoleDebug($message);
					}
					return false;
				}
			}
			return $JSONraw['response'];
		}
	}
 
	private function getTwitterJSON() {
		require $this->lib.'tmhOAuth.php';
		require $this->lib.'tmhUtilities.php';
 
		$tmhOAuth = new tmhOAuth(array(
			'host'                  => $_POST['request']['host'],
			'consumer_key'          => $this->consumer_key,
			'consumer_secret'       => $this->consumer_secret,
			'user_token'            => $this->user_token,
			'user_secret'           => $this->user_secret,
			'curl_ssl_verifypeer'   => false
		));
 
		$url = $_POST['request']['url'];
		$params = $_POST['request']['parameters'];
 
		$tmhOAuth->request('GET', $tmhOAuth->url($url), $params);
		return $tmhOAuth->response;
	}
 
	private function generateCFID() {
		// The unique cached filename ID
		return md5(serialize($_POST)).'.json';
	}
 
	private function pathify(&$path) {
		// Ensures our user-specified paths are up to snuff
		$path = realpath($path).'/';
	}
 
	private function consoleDebug($message) {
		if($this->debug === true) {
			$this->message .= 'tweet.js: '.$message."\n";
		}
	}
}
Etiquedado como

Deja un comentario

Tu dirección de correo electrónico no será publicada.