Tutorial 1: Java + Twitter
Hola a todos. Como ya os dije, en Geeky Theory aprenderemos a crear un cliente de Twitter programado en Java. Ya publicamos una introducción a lo que serán estos tutoriales, la cual podéis ver clickando aquí. Este el primero de ellos, en el que empezaremos a picar código.
Para comenzar, nos descargaremos la librería Twitter4j, que es la que vamos a utilizar en esta serie de tutoriales. La documentación oficial la podéis ver en twitter4j.org, pero os voy a dejar el link de la librería para el que quiera ir directo al grano.
Al darle a descargar, nos aparecerá la siguiente ventana:
Lo guardamos y listo. En este JAR tenemos todo lo necesario para comenzar nuestra aventura.
Llega la hora de comenzar el proyecto. Yo lo haré con NetBeans, pero podéis utilizar el IDE que queráis.
1º- Creamos un nuevo proyecto al que llamaremos TwitterJavaGT e importamos la librería Twitter4j.
Si sabes cómo crear proyectos e incluir librerías externas, puedes ir al paso 2º.
Por ahora no tendremos ninguna librería externa incluida en el proyecto. Por ello, ahora la vamos a importar.
Vamos a las propiedades del proyecto y en "Libraries", hacemos click en "Add JAR/Folder":
Buscamos el JAR que nos acabamos de descargar y lo seleccionamos. Ahora nos aparecerá una ventana como la siguiente:
Pinchamos en "OK" y, como vemos, ya tenemos la librería incluida en el proyecto.
2º. Crear una aplicación en la página de desarrolladores de Twitter.
Si ya estás registrado o sabes cómo hacerlo, puedes ir directamente al apartado 3º.
Vamos a la página de desarrolladores de Twitter para registrar una nueva aplicación y registrarnos también como Twitter developers. Qué bien suena eso, ¿no? (https://dev.twitter.com/ ):
A continuación, crearemos la aplicación. Yo la he llamado así, pero podéis llamarla como queráis, lógicamente:
Aceptamos términos y condiciones, rellenamos Captcha... y ya tenemos registrada nuestra aplicación. Ahora, se nos abrirá una página con nuestros datos. Vamos a Settings, donde podremos añadir una imagen y, marcaremos los permisos de la siguiente manera:
Ahora llega la parte más importante: OAuth Tool.
OAuth (Open Authorization) es un protocolo abierto, propuesto por Blaine Cook y Chris Messina, que permite autorización segura de un API de modo estándar y simple para aplicaciones de escritorio, móviles, y web.
Para desarrolladores de consumidores, OAuth es un método de interactuar con datos protegidos y publicarlos. Para desarrolladores de proveedores de servicio, OAuth proporciona a los usuarios un acceso a sus datos al mismo tiempo que protege las credenciales de su cuenta. En otras palabras, OAuth permite a un usuario del sitio A compartir su información en el sitio A (proveedor de servicio) con el sitio B (llamado consumidor) sin compartir toda su identidad.
Fuente: Wikipedia
Para ver nuestros Tokens y autorizaciones, vamos a OAuth Tools. No debemos compartir lo "secret".
3º. Picar código como si no hubiese mañana.
Os cuento cómo vamos a enfocar el programa. Lo primero que hace la aplicación al ejecutarse, es pedir un código para que sea autorizada a acceder a tu cuenta de Twitter. Automáticamente se abrirá una ventana en el navegador con vuestro pin. Lo metéis en consola y asunto arreglado. Ya le habéis dado el permiso a la aplicación. Para no tener que estar siempre metiendo el pin, es mejor guardar las claves de acceso en algún archivo para que la aplicación pueda acceder a él cada vez que se inicie. Es más que nada por comodidad, porque si no, tendríamos que estar autorizando a la aplicación cada vez que a ejecutemos. Por ahora, lo guardaremos en un fichero .txt, aunque en los siguientes tutoriales podremos guardar los datos de un modo más "seguro" o algo más trabajado. Además de esto, lo que haremos será mostrar unos cuantos tweets por consola y, escribir un tweet, el cual podremos ver desde nuestro timeline.
Lo primero que hacemos es crear una clase llamada "Autorización", desde la cual daremos permiso a la aplicación para acceder a nuestra cuenta. En este caso, como ya he dicho antes, leeremos unos tweets y escribiremos otro.
En la clase "Autorizacion" (mejor nombrarla sin acentos, no me lo tengáis en cuenta), haremos los imports necesarios. Yo no suelo ponerlos todos antes de comenzar, sobre todo si hay bastantes. Normalmente los voy haciendo sobre la marcha, según las necesidades.
package twitterjavagt; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.logging.Level; import java.util.logging.Logger; import twitter4j.Twitter; import twitter4j.TwitterException; import twitter4j.TwitterFactory; import twitter4j.auth.AccessToken; import twitter4j.auth.RequestToken; import twitter4j.conf.ConfigurationBuilder; /** * * @author Mario Pérez * */ public class Autorizacion {}
A continuación, crearemos el constructor de la clase, es decir, lo primero que ejecutaremos nada más crear el objeto. Si queréis saber cómo funciona un constructor, podéis verlo aquí.
Crearemos varios objetos, con el fin de poder obtener nuestro Access Token y nuestro Access Token Secret. Son muy importantes los objetos a los que he llamado "configBuilder" (la base de la autorización), "OAuthTwitter" (para lanzar el configBuilder), "requestToken" (para los Tokens) y "accessToken" (para poder acceder). El string "url" es para guardar la URL que abrirá el navegador. Aquí tenéis el código:
Autorizacion() throws IOException, TwitterException { //Constructor de la clase ConfigurationBuilder configBuilder = new ConfigurationBuilder(); configBuilder.setDebugEnabled(true) .setOAuthConsumerKey("String con el Consumer key de la aplicación (Ver en la web de Twitter Developer)") .setOAuthConsumerSecret("String con el Consumer secret de la aplicación (Ver en la web de Twitter Developer)"); Twitter OAuthTwitter = new TwitterFactory(configBuilder.build()).getInstance(); RequestToken requestToken = null; AccessToken accessToken = null; String url = null;
Como podéis observar, "accessToken" está inicializado a null. Hasta que no cambie su valor de null, no dejaremos de intentar acceder. En el código siguiente, mediante un do-while. La parte en la que se utiliza el Request Token, la he introducido en un try-catch por si nos da problemas. Siempre es conveniente dejar los try-catch que tengamos con el menor código posible. Por otra parte, a la hora de abrir la URL en cuestión, he utilizado un código muy sencillo. Hay más maneras de hacerlo, pero esta la he encontrado fácil y funcional. Como lo he probado en Firefox, he puesto ese navegador, aunque podéis poner el que queráis. Se puede optimizar esta parte del código.
Tras esto, al abrirse el navegador, tendremos una ventana con un PIN. Este PIN lo introduciremos en la aplicación, por consola, y ya tendremos hecha la autorización.
do{ try { requestToken = OAuthTwitter.getOAuthRequestToken(); System.out.println("Request Token obtenido con éxito."); System.out.println("Request Token: " + requestToken.getToken()); System.out.println("Request Token secret: " + requestToken.getTokenSecret()); url = requestToken.getAuthorizationURL(); System.out.println("URL:"); System.out.println(requestToken.getAuthorizationURL()); } catch (TwitterException ex) { Logger.getLogger(TwitterJavaGT.class.getName()).log(Level.SEVERE, null, ex); } BufferedReader lectorTeclado = new BufferedReader(new InputStreamReader(System.in)); //Abro el navegador. Firefox, en este caso. Runtime runtime = Runtime.getRuntime(); try { runtime.exec("firefox " + url); } catch (Exception e) { } //Nos avisa de que introduciremos el PIN a continuación System.out.print("Introduce el PIN del navegador y pulsa intro.nn PIN: "); //Leemos el PIN String pin = lectorTeclado.readLine(); if (pin.length() > 0) { accessToken = OAuthTwitter.getOAuthAccessToken(requestToken, pin); } else { accessToken = OAuthTwitter.getOAuthAccessToken(requestToken); } } while (accessToken==null);
A continuación, mostraremos por consola los resultados obtenidos, es decir, el access token y el access token secret. Además, los guardaremos en un fichero .txt llamado auth_file.txt:
System.out.println("nnAccess Tokens obtenidos con éxito."); System.out.println("Access Token: " + accessToken.getToken()); System.out.println("Access Token secret: " + accessToken.getTokenSecret()); FileOutputStream fileOS = null; File file; String content = accessToken.getToken() + "n" + accessToken.getTokenSecret(); try { file = new File("/home/mario/auth_file.txt"); fileOS = new FileOutputStream(file); //Si el archivo no existe, se crea if (!file.exists()) { file.createNewFile(); } //Se obtiene el contenido en Bytes byte[] contentInBytes = content.getBytes(); fileOS.write(contentInBytes); fileOS.flush(); fileOS.close(); System.out.println("Escritura realizada con éxito."); } catch (IOException e) { e.printStackTrace(); } finally { try { if (fileOS != null) { fileOS.close(); } } catch (IOException e) { e.printStackTrace(); } } }
Este es el código completo de la clase "Autorización":
package twitterjavagt; import java.io.BufferedReader; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.util.logging.Level; import java.util.logging.Logger; import twitter4j.Twitter; import twitter4j.TwitterException; import twitter4j.TwitterFactory; import twitter4j.auth.AccessToken; import twitter4j.auth.RequestToken; import twitter4j.conf.ConfigurationBuilder; /** * * @author Mario Pérez * */ public class Autorizacion { Autorizacion() throws IOException, TwitterException { //Constructor de la clase ConfigurationBuilder configBuilder = new ConfigurationBuilder(); configBuilder.setDebugEnabled(true) .setOAuthConsumerKey("String con el Consumer key de la aplicación (ver en la web de Twitter Developer)") .setOAuthConsumerSecret("String con el Consumer secret de la aplicación (ver en la web de Twitter Developer)"); Twitter OAuthTwitter = new TwitterFactory(configBuilder.build()).getInstance(); RequestToken requestToken = null; AccessToken accessToken = null; String url = null; do { try { requestToken = OAuthTwitter.getOAuthRequestToken(); System.out.println("Request Tokens obtenidos con éxito."); System.out.println("Request Token: " + requestToken.getToken()); System.out.println("Request Token secret: " + requestToken.getTokenSecret()); url = requestToken.getAuthorizationURL(); System.out.println("URL:"); System.out.println(requestToken.getAuthorizationURL()); } catch (TwitterException ex) { Logger.getLogger(TwitterJavaGT.class.getName()).log(Level.SEVERE, null, ex); } BufferedReader lectorTeclado = new BufferedReader(new InputStreamReader(System.in)); //Abro el navegador. Firefox, en este caso. Runtime runtime = Runtime.getRuntime(); try { runtime.exec("firefox " + url); } catch (Exception e) { } //Nos avisa de que introduciremos el PIN a continuación System.out.print("Introduce el PIN del navegador y pulsa intro.nn PIN: "); //Leemos el PIN String pin = lectorTeclado.readLine(); if (pin.length() > 0) { accessToken = OAuthTwitter.getOAuthAccessToken(requestToken, pin); } else { accessToken = OAuthTwitter.getOAuthAccessToken(requestToken); } } while (accessToken == null); System.out.println("nnAccess Tokens obtenidos con éxito."); System.out.println("Access Token: " + accessToken.getToken()); System.out.println("Access Token secret: " + accessToken.getTokenSecret()); FileOutputStream fileOS = null; File file; String content = accessToken.getToken() + "n" + accessToken.getTokenSecret(); try { file = new File("/home/mario/auth_file.txt"); fileOS = new FileOutputStream(file); //Si el archivo no existe, se crea if (!file.exists()) { file.createNewFile(); } //Se obtiene el contenido en Bytes byte[] contentInBytes = content.getBytes(); fileOS.write(contentInBytes); fileOS.flush(); fileOS.close(); System.out.println("Escritura realizada con éxito."); } catch (IOException e) { e.printStackTrace(); } finally { try { if (fileOS != null) { fileOS.close(); } } catch (IOException e) { e.printStackTrace(); } } } }
Ahora, vamos a crear la clase principal del proyecto, es decir, la que se ejecutará cuando abramos la aplicación. La llamaremos "TwitterJavaGT", igual que el proyecto.
Como en la clase de antes, hacemos los imports necesarios:
package twitterjavagt; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; import twitter4j.Paging; import twitter4j.ResponseList; import twitter4j.Status; import twitter4j.Twitter; import twitter4j.TwitterException; import twitter4j.TwitterFactory; import twitter4j.conf.ConfigurationBuilder; public class TwitterJavaGT { }
Ahora veremos el código del constructor, el cual es muy parecido al de la clase "Autorizacion":
TwitterJavaGT() throws TwitterException { Twitter twitter; ConfigurationBuilder configBuilder = new ConfigurationBuilder(); String Token = new String(); //Los almaceno en un string, ya que pueden variar según la cuenta String TokenSecret = new String(); File archivo = null; FileReader fileR = null; BufferedReader lecturaTeclado = null;
Hasta ahora, lo único que hemos hecho ha sido declarar algunas de las variables necesarias para la ejecución del programa. A continuación, veremos cómo leer los tokens de acceso del fichero creado anteriormente:
try { // Apertura del fichero y creacion de BufferedReader archivo = new File("/home/mario/auth_file.txt"); fileR = new FileReader(archivo); lecturaTeclado = new BufferedReader(fileR); // Lectura del fichero String linea = new String(); int n = 1; while ((linea = lecturaTeclado.readLine()) != null) { if (n == 1) { //La primera línea es el Access Token System.out.println(linea); Token = linea; } else if (n == 2) { //La segunda línea es el Access Token Secret System.out.println(linea); TokenSecret = linea; } n++; } } catch (Exception e) { e.printStackTrace(); } finally { // En el finally cerramos el fichero, para asegurarnos // que se cierra tanto si todo va bien como si salta // una excepción. try { if (null != fileR) { fileR.close(); } } catch (Exception e2) { e2.printStackTrace(); } }
Tras haber hecho esto, ya tenemos los tokens guardados en sus respectivas variables. Lo que nos queda para configurar la aplicación es el configBuild, igual que lo hemos hecho en la clase anterior:
configBuilder.setDebugEnabled(true) .setOAuthConsumerKey("XXXXXXXXXXXXXXXXXXXXXXX") .setOAuthConsumerSecret("XXXXXXXXXXXXXXXXXXXXXXX") .setOAuthAccessToken(Token) .setOAuthAccessTokenSecret(TokenSecret); twitter = new TwitterFactory(configBuilder.build()).getInstance();
Bueno, pues ha llegado la hora de obtener los tweets del timeline. Para ello, creamos un nuevo objeto página, con el cual definimos el número de tweets que vamos a ver en consola. A continuación, creamos un listado y mostramos los tweets con un bucle for. Finalmente, escribiremos un twitt desde nuestra cuenta:
Paging pagina = new Paging(); pagina.setCount(40); ResponseList listado = twitter.getHomeTimeline(pagina); for (int i = 0; i < listado.size(); i++) { System.out.println(listado.get(i).getText()); } //Actualizar tu estado Status tweetEscrito = twitter.updateStatus("[TUTORIAL] Twitter+Java @geekytheory www.geekytheory.com"); } Para acabar con el código de la clase, nos falta un main. En él, crearemos un objeto de la clase "Autorizacion" y luego otro de la clase TwitterJavaGT. Su código es el siguiente: public static void main(String ar[]) throws TwitterException { try { Autorizacion aut = new Autorizacion(); } catch (IOException | TwitterException ex) { Logger.getLogger(TwitterJavaGT.class.getName()).log(Level.SEVERE, null, ex); } TwitterJavaGT twitter = new TwitterJavaGT(); } Ya tenemos hecha la clase TwitterJavaGT. El código completo es el siguiente: package twitterjavagt; import java.io.BufferedReader; import java.io.File; import java.io.FileReader; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; import twitter4j.Paging; import twitter4j.ResponseList; import twitter4j.Status; import twitter4j.Twitter; import twitter4j.TwitterException; import twitter4j.TwitterFactory; import twitter4j.conf.ConfigurationBuilder; public class TwitterJavaGT { TwitterJavaGT() throws TwitterException { Twitter twitter; ConfigurationBuilder configBuilder = new ConfigurationBuilder(); String Token = new String(); //Los almaceno en un string, ya que pueden variar según la cuenta String TokenSecret = new String(); File archivo = null; FileReader fileR = null; BufferedReader lecturaTeclado = null; try { // Apertura del fichero y creacion de BufferedReader archivo = new File("/home/mario/auth_file.txt"); fileR = new FileReader(archivo); lecturaTeclado = new BufferedReader(fileR); // Lectura del fichero String linea = new String(); int n = 1; while ((linea = lecturaTeclado.readLine()) != null) { if (n == 1) { //La primera línea es el Access Token System.out.println(linea); Token = linea; } else if (n == 2) { //La segunda línea es el Access Token Secret System.out.println(linea); TokenSecret = linea; } n++; } } catch (Exception e) { e.printStackTrace(); } finally { // En el finally cerramos el fichero, para asegurarnos // que se cierra tanto si todo va bien como si salta // una excepción. try { if (null != fileR) { fileR.close(); } } catch (Exception e2) { e2.printStackTrace(); } } configBuilder.setDebugEnabled(true) .setOAuthConsumerKey("XXXXXXXXXXXXXXXXXXXXX") .setOAuthConsumerSecret("XXXXXXXXXXXXXXXXXXXXXXXX") .setOAuthAccessToken(Token) .setOAuthAccessTokenSecret(TokenSecret); twitter = new TwitterFactory(configBuilder.build()).getInstance(); //Recuperar listado de ultimos tweets escritos Paging pagina = new Paging(); pagina.setCount(50); ResponseList listado = twitter.getHomeTimeline(pagina); for (int i = 0; i < listado.size(); i++) { System.out.println(listado.get(i).getText()); } //Actualizar tu estado Status tweetEscrito = twitter.updateStatus("[TUTORIAL] Twitter+Java @geekytheory www.geekytheory.com"); } public static void main(String ar[]) throws TwitterException { try { Autorizacion aut = new Autorizacion(); } catch (IOException | TwitterException ex) { Logger.getLogger(TwitterJavaGT.class.getName()).log(Level.SEVERE, null, ex); } TwitterJavaGT twitter = new TwitterJavaGT(); } } Si ejecutamos el programa, obtenemos lo siguiente:
Vemos que nos pide un PIN. Si todo ha ido bien, también se nos habrá abierto una página Web parecida a la siguiente:
Autorizamos a la aplicación y veremos un pin en la pantalla. Lo introducimos en consola y veremos los 40 últimos tweets de nuestro timeline:
Además, hemos puesto un tweet, que podemos ver en el timeline:
geekytheorygeekytheory.com31 de enero de 2013
Como podemos ver, también se ha creado un archivo en el directorio especificado:
¿Te animas a probar si funcionan los botones de "Seguir" y "Retwittear"?
En el próximo tutorial aprenderemos a hacer lo mismo de hoy pero de un modo gráfico. Además, añadiremos la funcionalidad de que si ya hemos autorizado a la aplicación, no nos pida de nuevo el PIN.
Aprovechando la ocasión y, debido a que estamos comenzando con proyectos importantes, hemos creado una cuenta en BitBucket, con el fin de que podáis acceder a todos los códigos de manera libre y gratuita. Os dejo el enlace: https://bitbucket.org/GeekyTheory
En Geeky Theory creemos que hay que fomentar la filosofía del Open Source y de compartir conocimientos. Precisamente por eso estamos escribiendo aquí.
Ha sido un tutorial bastante largo y con mucha información. Puede que tengáis alguna duda o algún problema. En caso de que sea así, os invito a que dejéis un comentario. Si no tenéis problema alguno con esto, también os agradeceríamos que nos escribieseis un comentario contándonos qué os ha parecido el tutorial y qué podríamos mejorar. De todo se aprende.
Ya para finalizar, hago una recopilación de lo aprendido en este tutorial:
- Importar librerías externas (Twitter4j en este caso).
- Aprender qué es OAuth.
- Registrarnos como Twitter Developers.
- Registrar una aplicación en Twitter.
- Utilizar varias clases en un proyecto.
- Conectarnos con Twitter mediante keys y tokens (OAuth).
- Leer el timeline.
- Escribir tweets.
- Crear ficheros.
- Leer de ficheros.
¡Esperamos vuestros comentarios y, sobre todo, que compartáis el conocimiento!
¡Saludos geeks!