Poesía Binaria

Creando un pequeño bot para Twitter en PHP paso a paso (parte 1)


En esta serie de posts veremos información paso a paso para crear un bot en Twitter. Este tipo de bots pueden ser muy útiles para programar publicaciones, para conocer información periódica de nuestra cuenta, para detectar menciones y tomar decisiones, y muchas cosas más. Todo ello lo quiero enfocar desde un punto de vista agnóstico del framework que vayamos a utilizar. Lo voy a basar en PHP porque la mayoría de los scripts los tengo hechos en este lenguaje y me va a resultar útil para un par de proyectos en el futuro.

También debo agradecer a Josep Maria por sugerirme hacer este post.

Autentificación con OAuth

Hace mucho tiempo, cuando Twitter empezó, y empezaron a surgir los servicios web, cada proveedor tenía su propia API, que funcionaba de una forma diferente. En principio me refiero a la autentificación o autorización de los servicios, aunque también me refiero a la forma de llamar los diferentes recursos. Poco a poco, todos los grandes servicios van utilizando una forma similar de trabajar, lo cual hace que sea muy parecida la forma de interactuar con la API de Twitter, Facebook, LinkedIn, Google, Dropbox, plataformas de pago como Paypal, sistemas de trading como CoinBase, incluso comercios online como Magento.
El problema de la autentificación, aunque ya estamos acostumbrados a ello es que una aplicación debe utilizar un servicio como si fuera el usuario. Y debemos garantizar la seguridad de todas las partes, especialmente la del usuario. Antiguamente (y todavía vemos alguna aplicación así), si en lugar de ir a la web del servicio queremos que un programa, u otra webapp utilicen el servicio por nosotros (o queremos automatizarlo en un script) debíamos introducir el nombre de usuario y contraseña (nuestro) en dicho programa. Pero claro, las contraseñas, por definición deberían ser intransferibles. Es como si para hacer un pago en una tienda online tuviéramos que dar nuestra clave del banco (y con eso diéramos a la tienda control total sobre nuestros ahorros).

Pero es que si damos la contraseña a las aplicaciones que utilizamos podemos tener varios problemas:

Entonces surgió OAuth, como una forma de autorizar a las aplicaciones a realizar acciones en nuestras cuentas de usuario de diferentes servicios. No necesitamos enviar nuestra contraseña a nadie. Sólo tenemos que estar identificados en el servicio con nuestro usuario y la aplicación podrá hacer el resto.

Para ello (y para el ejemplo utilizo Twitter como servicio):

Una vez hecho esto, se solucionan algunos problemas:

API de Twitter

Todo esto, al ser un estándar abierto y, además, al utilizar Twitter una API REST para comunicarnos con él hace que el lenguaje de programación en el que hagamos las aplicaciones sea lo de menos. No dependemos de ninguna característica especial, ni función propia del lenguaje, sólo necesitamos que sea capaz de hacer peticiones HTTP, lo cual, desde hace mucho tiempo se puede hacer independientemente del lenguaje utilizado. Sólo necesitaremos la documentación de Twitter para saber qué podemos pedir y qué petición debemos hacer para pedirlo.

Es más, gracias a esta independencia del lenguaje, ellos se libran de tener que hacer y mantener bibliotecas en muchos lenguajes de programación y plataformas. Ellos tienen algunas publicadas, pero si alguna no existe no es muy difícil crearla. Lo cual deja la puerta abierta a muchos desarrolladores que publican sus bibliotecas y su visión de cómo hacer las cosas.

Para los ejemplos, yo he utilizado la biblioteca TwitterOAuth de Abraham Williams para PHP. Pero podríamos utilizar cualquier otra en nuestros proyectos.

Dar de alta la aplicación

Lo que haremos aquí será decirle a Twitter que vamos a crear una aplicación. Para ello vamos a apps.twitter.com, donde veremos un listado de todas nuestras aplicaciones y pulsaremos sobre Create New App:

Tras esto nos preguntará algunos datos de nuestra aplicación:

Lo vemos todo en esta pantalla.
. Tras esto, nos mostrará una pantalla más con información:

Esta pantalla muestra datos sobre nuestra recién creada aplicación, siendo lo más importante nuestra Consumer Key o API Key. Será la primera parte del identificador de nuestra aplicación en Twitter. Y que nuestro sistema pueda interactuar con la plataforma. Aunque todavía nos falta un trozo, la Consumer Secret o API Secret. Esta segunda clave debe ser privada y jamás, bajo ningún concepto enseñársela a nadie. La Consumer Secret o API Secret podemos obtenerla si vamos a la pestaña Keys And Access Tokens. Vale, yo os estoy enseñando la mía, pero para cuando se ha lanzado el post, dichas claves ya no estarán vigentes. Podemos ver esta información en la siguiente captura:

Estas claves tendrán que ser enviadas por nuestra aplicación y, en los ejemplos podremos ver que las claves están en el código, aunque podemos almacenarlas de modo más elegante en un archivo YAML, Json, Ini, base de datos, etc. Son claves que nuestra aplicación deberá utilizar sea cual sea el usuario que venga.

Enviando peticiones con cURL a pelo

Algo que me encanta es que todas estas APIs pueden ser utilizadas desde cualquier sitio. Incluso podemos ejecutar comandos en la terminal que envíen un tweet o reciban cierta información. Y es lo que vamos a hacer a modo de prueba de concepto.

Para ello, seguimos en la pestaña Keys and Access Tokens y pulsamos el botón Create my access token. Lo podemos ver en la imagen abajo del todo. Con esto, vamos a obtener un nuevo token de acceso (access token) que autorice a nuestra aplicación a utilizar los servicios de Twitter con nuestro usuario actual. Este token de acceso será una ristra de números y letras lo suficientemente larga como para que dé pereza escribirla a mano. Con esto, podemos deducir que si queremos que otro usuario utilice nuestra aplicación, el nuevo usuario deberá autorizarnos a utilizar su cuenta de usuario (ya veremos cómo hacer todo esto).

Ahora que hemos generado el token de acceso, una vez utilizado, éste puede ser revocado. Es decir, le diremos a Twitter que la aplicación ya no tiene permiso para acceder a nuestro Twitter. O puede ser regenerado, o lo que es lo mismo, la aplicación seguirá teniendo permiso, pero hemos cambiado las claves:

Bueno, vamos al lío. Enviar las peticiones a cURL puede ser complicado, aunque tenemos bibliotecas que nos ayudarán enormemente en nuestra tarea. Y, para este ejemplo, vamos a eliminar la parte de autentificación de la aplicación y autorización del usuario de Twitter. Vamos a utilizar directamente el access token de usuario y access token secret que ya tenemos.

No me voy a extender mucho en la explicación, pero para que el protocolo sea seguro y que nadie con una petición a la API de Twitter sea capaz de realizar acciones en nombre de un usuario (por ejemplo, robar tweets, leer mensajes privados, enviar tweets desde su cuenta, etc). La API requiere una autorización cada vez que hacemos una petición a la misma (la autorización la tenemos gracias al consumer key de la aplicación y al access token de usuario), y dicha autorización va firmada. Dichas firmas se realizan con el algoritmo de hash HMAC SHA1 a través de una clave generada por el consumer secret de la aplicación y el access token secret del usuario (y estos datos no se enviarán nunca, sólo las firmas generadas con ellos). Es decir, antes de enviar una petición, la firmamos y le añadimos a la petición la firma que hemos hecho. De esta forma, si alguien es capaz de ver la petición que hemos hecho al sistema, no será capaz de realizar una petición en nuestro nombre.

Para realizar la petición, además de Bash, necesitaremos cURL. para hacer la petición web, openSSL para generar el hash, base64 (que seguramente lo tengamos, es parte de las coreutils), perl con el módulo MURI::Escape para hacer parámetros amigables para transmisión por HTTP (urlencode) y jq para que la salida en JSON sea más bonita.

Descargando los últimos tweets

Para descargar los últimos tweets de mi timeline tengo que hacer una petición GET a https://api.twitter.com/1.1/statuses/home_timeline.json para ello, primero voy a montar los datos de autorización:

OAUTH=»oauth_consumer_key=\»vzuqfbaWlITW88d2Sju3Zjtts\»,
oauth_nonce=\»caracteresaleatorios$(date +%s)\»,
oauth_signature_method=\»HMAC-SHA1\»,
oauth_timestamp=\»$(date +%s)\»,
oauth_token=\»xxxxxxxx-yuuN1jaqAeYUwmQNnMSORPJEdPp1cueC3wX93M9fb\»,
oauth_version=\»1.0\»»

En este caso, meteremos en la variable $OAUTH toda esa información. Siendo:

Ahora, para descargar los tweets debemos poner el siguiente comando:

curl --get ‘https://api.twitter.com/1.1/statuses/home_timeline.json’ --header «Authorization: OAuth $OAUTH,           oauth_signature=\»$(perl -MURI::Escape -e ‘print uri_escape($ARGV[0]);’ «$(echo -n «GET&$(perl -MURI::Escape -e ‘print uri_escape($ARGV[0]);’ «https://api.twitter.com/1.1/statuses/home_timeline.json»)&$(echo $OAUTH | sed -e ‘s/»//g’ -e ‘s/, /%26/g’ -e ‘s/=/%3D/g’)» | openssl dgst -sha1 -hmac «RAFPICdxIa5hwpw1ISqXktt9TmXgLfMFFVdOcZRZPuNDSueOYX&ilq0HTbfQDansSCpI0RN26xrdyvLMLsmmNTtXEZ3YrByu» -binary |base64)»)\»» --header «Expect:» --verbose | jq

Este comando, que puede resultar muy largo envía la petición a Twitter incluyendo la cabecera de Authorization con los datos del protocolo OAuth que hemos visto en la variable anterior. Además, adjunta la firma (que es lo más largo. Una vez hecha la petición, como Twitter nos envia la información en formato JSON, se la pasamos a jq para poder visualizarla bien en pantalla.

Algunas órdenes útiles que podemos extraer de la línea anterior son:

perl -MURI::Escape -e ‘print uri_escape($ARGV[0]);’ «texto complicado»

Hace un urlencode en el texto complicado. Con esto, extraeremos una cadena de texto derivada del texto complicado convirtiendo algunos caracteres conflictivos a su código hexadecimal (%20, %3D, %26…). Según especifica Twitter en su documentación, tenemos que hacer esto a ciertas cadenas de texto antes de aplicar el algoritmo de firmado.
echo «texto complicado» | sed -e ‘s/»//g’ -e ‘s/, /%26/g’ -e ‘s/=/%3D/g’

Es algo parecido a lo anterior, un poco rebuscado y propio de esta cadena en particular. Como estamos en Bash he reducido algunas cosas. Los elementos de la cadena $OAUTH están separados por comas, pero si los colocásemos como datos HTTP estarían separados por & y los valores no tendrían comillas. Eso hacemos, eliminamos las comillas dobles, y cambiamos los «, » por «%26» y los «=» por %3D. En la práctica lo haremos de forma más elegante, esto es sólo una prueba.

echo «texto para firmar» | openssl dgst -sha1 -hmac «clave_para_firmar» -binary | base64

Nos devuelve el texto para firmar firmado con el algoritmo hmac-sha1 y la clave para firmar.

La documentación de Twitter, nos dice que la clave para firmar es el Consumer Secret, un ampersand (&) y el Access Token Secret, todo seguido. También nos habla del contenido de la signature antes de ser cifrada. Ésta debe ser:

PROTOCOLO&URL&argumentos

Por lo que, PROTOCOLO es GET, la URL la urlencodeamos y hacemos lo mismo con los argumentos. Todo lo separamos con ampersands (&).

Enviando un tweet desde consola

Esto será un poco más largo, pero la explicación será prácticamente la misma que en el caso anterior. Sólo que tenemos un nuevo campo, el status y será una petición de tipo POST:

OAUTH=»oauth_consumer_key=\»vzuqfbaWlITW88d2Sju3Zjtts\»,
oauth_nonce=\»caracteresaleatorios$(date +%s)\»,
oauth_signature_method=\»HMAC-SHA1\»,
oauth_timestamp=\»$(date +%s)\»,
oauth_token=\»xxxxxxxx-yuuN1jaqAeYUwmQNnMSORPJEdPp1cueC3wX93M9fb\»,
oauth_version=\»1.0\»»
curl -X POST ‘https://api.twitter.com/1.1/statuses/update.json’ --header «Authorization: OAuth $OAUTH,
oauth_signature=\»$(perl -MURI::Escape -e ‘print uri_escape($ARGV[0]);’ «$(echo -n «POST&$(perl -MURI::Escape -e ‘print uri_escape($ARGV[0]);’ «https://api.twitter.com/1.1/statuses/update.json»)&$(echo $OAUTH | sed -e ‘s/»//g’ -e ‘s/, /%26/g’ -e ‘s/=/%3D/g’)»$(perl -MURI::Escape -e ‘print uri_escape($ARGV[0]);’ «&status=Every time when I look in the mirror… All these lines on my face getting clearer») | openssl dgst -sha1 -hmac «RAFPICdxIa5hwpw1ISqXktt9TmXgLfMFFVdOcZRZPuNDSueOYX&ilq0HTbfQDansSCpI0RN26xrdyvLMLsmmNTtXEZ3YrByu» -binary |base64)»)\»» --header «Expect: » -d «status=Every time when I look in the mirror… All these lines on my face getting clearer» --verbose

Vale, sí hay que liarla para enviar un tweet desde consola (a pelo), pero esto está muy bien para saber qué necesitamos hacer, o si queremos desarrollar una aplicación que lo haga y conocer un poco cómo funciona todo. El problema es que el tweet tenemos que escribirlo dos veces, una para enviar el tweet y otra para crear la firma. Recordemos que pequeñas variaciones en el contenido a firmar crean cadenas de firma totalmente distintas.

El tweet que envié arriba es el siguiente:

Empezamos nuestro proyecto

No voy a hacer una aplicación web. Aunque será fácil convertirlo en web, mi propósito es hacer una aplicación que se ejecute en segundo plano y esté todo el tiempo corriendo, por lo que será una aplicación de consola. Podríamos haber implementado la primera parte de la autorización como web para que sea más sencillo, pero también de esta forma podemos ver y controlar el proceso de envío de información Aplicación/Twitter/Usuario.

Lo primero que necesitamos es tener Composer instalado en nuestro ordenador. Con esto será muy fácil instalar la biblioteca y actualizarla posteriormente. Una vez tenemos composer, crearemos un directorio para nuestra aplicación y ejecutaremos:

composer require abraham/twitteroauth

Con ello, se crearán varios archivos de composer y tendremos un directorio llamado vendor dentro del cual tendremos la biblioteca TwitterOAuth instalada. Y si en algún momento queremos actualizar, tanto TwitterOAuth como el resto de bibliotecas que hayamos incluido con composer en nuestro proyecto, basta con hacer:
composer update

Vamos al código en PHP

Los ejemplos anteriores los hemos hecho gracias a que conocíamos el Access Token y el Access Token Secret del usuario, que éramos nosotros. Pero normalmente un usuario de la aplicación usará nuestra interfaz y tendrá que ser nuestra aplicación la que ayudándose de Twitter obtenga la autorización del usuario para trabajar en su nombre. Así que vamos a trabajar a partir de ahora en el código.

Como he dicho antes, quiero hacerlo lo más agnóstico posible, de framework, de bases de datos y de todo, para poder incorporarlo en nuestros proyectos, y para entender bien cómo funciona. Además, lo que me interesa en principio para este post es la obtención de autorización y el envío de tweets desde nuestro script. Así que, vamos a dividirlo en dos scripts, para tener las cosas claras y separadas.

Lo primero, será para preparar nuestro proyecto con composer, para que se carguen automáticamente los archivos PHP al proyecto, haciendo que el autoload de composer busque los archivos del espacio de nombres Poesia dentro de lib. Para ello editamos composer.json dejándolo así:


GeSHi Error: GeSHi could not find the language json (using path /var/www/binarideas/poesiabinaria.net/www/wp-content/plugins/codecolorer/lib/geshi/) (code 2)

Ahora ejecutando

composer update

El sistema será capaz de buscar elementos dentro del espacio de nombres Poesia dentro de lib/ sin tener que incluirlos (utilizando los namespaces y el autoload).

El proyecto lo voy a dividir en varias partes. La primera de ellas valdrá para que el usuario autorice a la aplicación a trabajar con su Twitter. En este caso, la aplicación conectará con Twitter, y obtendrá unos tokens de acceso temporales con los que generaremos una URL con la que pediremos permiso a Twitter. Éste, cuando nos otorga el permiso le dará un PIN al usuario que tendrá que introducir en la aplicación para así poder pedirle a Twitter el token de acceso definitivo del usuario.

Si esto fuera una aplicación web no tendríamos que hacer que el usuario entrara en el navegador para autorizar, simplemente redirigiríamos a una URL de Twitter, y luego Twitter, llamaría a nuestra callback_url con la que volveríamos a la apliación con un código de verificación (el PIN) y con éste pediríamos el token de acceso y el token secreto definitivos para el usuario.

Pequeñas clases de ayuda

Dentro del directorio del proyecto tendremos un directorio llamado lib que contendrá algunos archivos útiles para mí. En este caso, con el objetivo de hacer el proyecto independiente de bibliotecas ni sistemas de base de datos y, para que vosotros podáis utilizar el que más os guste. He incluido dentro de lib/Config.php un Singleton que obtiene el consumer key y el consumer secret.

Ya que, en una aplicación real podremos tener varios, y cada uno los puede gestionar como quiera, sólo me interesa que alguien llame a Config::consumerKey() y Config::consumerSecret(), por dentro podrá funcionar como deseéis. Es más, al final, los valores están puestos a pelo, como vemos en lib/Config.php:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
<?php
namespace Poesia;

class Config {
    /* $config designa a la propia instancia a modo de Singleton */
    private static $config = null;
    private $__consumerKey = null;
    private $__consumerSecret = null;

    private static function instance() {
        if (!self::$config)
            self::$config = new self;

        return self::$config;
    }

    public static function consumerKey() {
        return self::instance()->_consumerKey();
    }

    public static function consumerSecret() {
        return self::instance()->_consumerSecret();
    }

    private function _consumerKey() {
        return $this->__consumerKey;
    }

    private function _consumerSecret() {
        return $this->__consumerSecret;
    }

    private function __construct() {
        /* Aquí cargamos la configuración de base de datos, archivo, o como queramos */
        $this->__consumerKey ="vzuqfbaWlITW88d2Sju3Zjtts";
        $this->__consumerSecret = "RAFPICdxIa5hwpw1ISqXktt9TmXgLfMFFVdOcZRZPuNDSueOYX";
    }
};

El segundo archivo corresponde con el almacén de datos del usuario, lib/User.php. En un sistema real seguro que preferís hacerlo con bases de datos. Pero para este ejemplo, me interesa que User::getUserData($nombre) y User::updateUserData($datos) funcionen. Al primero tendremos que pasarle el nombre del usuario, lo que va detrás de la @ en Twitter. El segundo necesita un array devuelto por la autorización de Twitter que contendrá:

Aunque la clase no verifica los valores, cuando necesitas volver a los datos de usuario es importante que los tenga.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<?php
namespace Poesia;

class User {
    protected static $filename = "etc/users.dat";

    protected static function getData() {
        $data = (file_exists(self::$filename))?file_get_contents(self::$filename):null;
        if (!$data)
            return array();
        $data = json_decode($data, true);
        return $data;
    }

    protected static function saveData($data) {
        file_put_contents(self::$filename, json_encode($data));
    }

    public static function getUserData($user) {

        $data = self::getData();
        return $data[$user]??null;
    }

    public static function updateUserData($data) {
        $user = $data['screen_name'];
        $currentData = self::getData();
        $currentData[$user] = $data;
        self::saveData($currentData);
    }
};

Por último, incluimos el archivo lib/Util.php con utilidades varias que necesitaremos. Aunque a priori esté un poco vacío, siempre me gusta dejar un archivo así abierto para meter cosas que no encajan en ningún lado:

1
2
3
4
5
6
7
8
<?php
namespace Poesia;

class Util {
    public static function panic($error) {
        die("Error: $error);
    }
};

Auth.php

Aunque podemos hacerlo todo en un solo archivo PHP, como aquí mi objetivo es que todo quede lo más claro posible, he querido abrir varios archivos. El primero de ellos será auth.php y su misión será pedir un Access Token a Twitter en nombre del usuario para que así nuestra aplicación pueda utilizar la cuenta de Twitter.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
<?php
require_once ('vendor/autoload.php');

use Abraham\TwitterOAuth\TwitterOAuth;

$tw = new TwitterOAuth(Poesia\Config::consumerKey(), Poesia\Config::consumerSecret());
/* Como URL de callback usaremos "oob", según la documentación debemos utilizar
   oauth_callback para mantener la compatibilidad y el valor oob para que Twitter
   no redirija a ningún lado, sino que devuelva un PIN que introduciremos en la
   aplicación para terminar la autorización. */

try {
    $requestToken = $tw->oauth('oauth/request_token', ['oauth_callback' => 'oob']);

    $url = $tw->url('oauth/authorize', [
        'oauth_token' => $requestToken['oauth_token'],
    ]);

    echo "Ve a $url para autorizar la aplicación.\nLuego vuelve e inserta el PIN.\n";
    echo "PIN:";
    while ((!fscanf(STDIN, "%s", $pin)) || (!trim($pin)) )
        echo "PIN: ";

    $tw->setOauthToken($requestToken['oauth_token'], $requestToken['oauth_token_secret']);
    $userData = $tw->oauth('oauth/access_token', [
        'oauth_verifier' => intval($pin)
    ]);

    /* Visualizamos los datos de acceso del usuario */
    var_dump($userData);
    Poesia\User::updateUserData($userData);
    $tw->setOauthToken($userData['oauth_token'], $userData['oauth_token_secret']);
    $credentials = $tw->get("account/verify_credentials");
    /* Ya podemos hacer peticiones a Twitter si queremos */
    //var_dump($credentials);
} catch (\Exception $e) {
    Poesia\Util::panic('Hubo un error'.$e);
}

Ahora, si desde consola, ejecutamos php auth.php nos dará una URL que debemos visitar. La URL será de Twitter y nos presentará algo como esto:

Una vez pulsamos el botón para autorizar la aplicación, nos entregará un PIN:

Luego, volveremos a nuestra aplicación e introduciremos el PIN facilitado por Twitter. La aplicación le dará este código a Twitter. Es ahora cuando Twitter nos dará un access token y un access token secret nuevo y que podremos utilizar de aquí en adelante.

El sistema, tal y como está planteado, serviría para que la misma aplicación pueda manejar las cuentas de varios usuarios, por lo que podemos almacenar Access Tokens de todos y utilizarlos según nos vaya interesando tanto para leer tweets como para enviarlos. En este ejemplo todo se almacena en un fichero dentro de etc/users.dat (como dice en lib/User.php)que en realidad es un json que contiene un array con todos los datos de los usuarios. Más adelante, en los siguientes ejemplos, manejaremos esos tokens para realizar acciones en Twitter.

Por último, el script visualiza el contenido enviado por Twitter donde podemos ver el ID de usuario, el nombre en pantalla, y los tokens. Además, algo que está comentado es que podemos paasrle al objeto $tw los tokens de acceso del usuario y empezar a trabajar. Como vemos, llamamos a account/verify_credentials que devolverá información del usuario actual como el nombre, locaclización, descripción, web, último tweet, fecha de creación de la cuenta, número de tweets y muchas cosas más.

Últimos tweets

Ahora vamos con un ejemplo práctico en el que descargamos la lista de los últimos tweets del usuario actual.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?php
require_once ('vendor/autoload.php');


$username = "Gaspar_FM";              /* Puede que queramos que nuestro sistema
                                   maneje varias Access Tokens de varios usuarios.*/


use Abraham\TwitterOAuth\TwitterOAuth;
$user = Poesia\User::getUserData($username);
if (!$user)
    Poesia\Util::panic('El usuario no ha autorizado la aplicación');

$tw = new TwitterOAuth(Poesia\Config::consumerKey(), Poesia\Config::consumerSecret(),
                       $user['oauth_token'], $user['oauth_token_secret']);
$content = $tw->get("statuses/home_timeline");

foreach ($content as $tweet) {
    $time = strtotime($tweet->created_at);
    echo $tweet->user->name." (@".$tweet->user->screen_name.") el ".date('d/m/Y H:i:s', $time).":\n";
    echo "    ".$tweet->text."\n";
    echo "-----------------\n\n";
}

A partir de aquí podemos investigar las posibilidades que tiene todo esto. Podríamos hacer un var_dump($tweet) para ver la información que nos envía Twitter. Es un ejercicio interesante que nos puede abrir un mundo de posibilidades.

Enviar un tweet

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<?php
require_once ('vendor/autoload.php');


$username = "Gaspar_FM";              /* Puede que queramos que nuestro sistema
                                   maneje varias Access Tokens de varios usuarios.*/


$tweet = "The past is gone. It went by, like dusk to dawn isn't that the way. Everybody's got the dues in life to pay";

use Abraham\TwitterOAuth\TwitterOAuth;

$user = Poesia\User::getUserData($username);
if (!$user)
    Poesia\Util::panic('El usuario no ha autorizado la aplicación');

$tw = new TwitterOAuth(Poesia\Config::consumerKey(), Poesia\Config::consumerSecret(),
                       $user['oauth_token'], $user['oauth_token_secret']);

$content = $tw->post("statuses/update", ['status'=> $tweet]);

var_dump($content);

Igual que hemos hecho hasta ahora, llamamos a la API con una petición de actualización de estado. Donde podemos incluir enlaces si queremos.

Más consideraciones

Aunque el post se está alargando mucho, debo decir que las peticiones que nuestra aplicación puede hacer sobre un recurso de un usuario están limitadas. Es decir, por supuesto podríamos desarrollar una aplicación que se ponga a leer tweets de todo el mundo buscando, almacenándolos y recopilando información. Pero el número de peticiones para lectura de tweets que podemos hacer está limitado.

Es normal, esto es un servicio gratuito que ofrece twitter y algo que consume muchos recursos en sus servidores. Además, podemos ver que la información que nos entrega de cada tweet es muy grande, así que debemos comprender que para generar una salida hace falta una gran maquinaria detrás.

Por eso debemos tener controlado el número de peticiones que hacemos a Twitter y, al menos, controlado que de vez en cuando nos devolverá un error. Es más, las peticiones a Twitter, a veces fallan, puede que por culpa de Twitter, puede que por culpa de la red, o puede que porque no hemos hecho la petición correcta así que debemos utilizar mucho el try { } catch para capturar los posibles problemas que nos devuelva la aplicación.

Posibilidades a nuestro alcance

¡Es vuestro turno! Me gustaría saber lo que programaríais con esta sencilla guía. Además, podéis ver el listado de cosas que podéis hacer en la documentación de la API de Twitter y algún ejemplo más en la web de TwitterOauth.
.
Foto principal: unsplash-logoVincent van Zalinge

También podría interesarte....

Quiero informarle sobre la herramienta que le ayudará en la creación de publicaciones con vídeos para su sitio web o blog. Hay una gran cantidad de software, lo que simplifica enormemente la tarea de agregar video al sitio web. Freemake Video Converter es una herramienta de conversión que admite casi todos los formatos de vídeo como material de origen, convierte videos a HTML5 (H.264, WebM, VP8) y proporciona un código listo para su incorporación en el sitio web. Y también la instrucción paso a paso "Cómo insertar un video en su página web", que se abre en su navegador una vez completada la conversión.