Como enviar Tweets desde Java usando Twitter4J
Una de las cosas que quiero hacer para la versión 1.1 de StupidZombie es agregarle soporte para actualizar el estado de Twitter cada vez que hacemos un ping. Como siempre es el asunto de construir algo desde cero o utilizar una herramienta existente y en el caso de StupidZombie lo que quiero es implementar la funcionalidad lo más rápido posible (por ejemplo, no tengo tiempo para seguir los cambios en el API de Twitter).
Después de buscar en la red me conseguí que Twitter4J es quizas la versión más madura para Java (recuerden, StupidZombie está escrito en ese lenguaje). Ni corto ni perezoso me puse a echar código y al final me decidí escribir una pequeña aplicación en Swing la cual hace lo siguiente:
- Autoriza la aplicación contra su cuenta de Twitter
- Obtiene un PIN y claves especiales de autorización (lo cual no es lo mismo que su usuario clave, a eso se le conoce como OAuth).
- Envia un mensaje (tweet) a su cuenta en Twitter desde la aplicación en Java
Nota, si usted es el desarrollador de la aplicación entonces lo primero que hay que hacer es registrar una aplicación nueva en Twitter (sus usuarios pueden saltarse este paso). Una vez terminado se ve como lo siguiente:

Aplicaciones registradas en Twitter
Una vez registrada debemos pasar “Consumer key” y “Consumer Secret” a nuestro código de Twitter4j, yo lo hago en el constructor:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | private TwitterPing(String consumerKey, String consumerSecret) throws TwitterException { super("KodeGeek simple Twitter pinger"); if (consumerKey == null) { throw new IllegalArgumentException("Consumer key is missing"); } if (consumerSecret == null) { throw new IllegalArgumentException("Consumer secret is missing"); } twitter = new Twitter(); twitter.setOAuthConsumer(consumerKey, consumerSecret); requestToken = twitter.getOAuthRequestToken(); setPreferredSize(new Dimension(600, 400)); } |
Desde la aplicación en Swing hacemos clic en el botón que dice “Authorize KodeGeek on Tweeter”. Si el soporte de Java para escritorio está activado entonces el navegador por omisión se arrancará e iremos a Twitter:
El código que hace esto es super sencillo :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | /** * Send the user to the authorization webpage * @throws Exception */ private void sendUserToAuthUrl() throws Exception { final TwitterPing instance = this; log.log(Level.INFO, String.format("Got authorization URL: %s", requestToken.getAuthorizationURL())); if (Desktop.isDesktopSupported()) { Desktop.getDesktop().browse(new URI(requestToken.getAuthorizationURL())); log.info("Redirection was successfull."); } else { EventQueue.invokeLater(new Runnable() { @Override public void run() { JOptionPane.showMessageDialog( instance, String.format("Cannot call default browser, please go to this URL instead: %s", requestToken.getAuthorizationURL()), "Problems trying to send the user to default page", JOptionPane.ERROR_MESSAGE); } }); } } |
Si la autorización es aceptada (como se ve a continuación):
Entonces podemos pedir el token de acceso usando el PIN obtenido en el paso anterior:
1 2 3 4 5 6 7 8 9 10 | /** * Call this method only after the user has authorized the application * @throws TwitterException */ private void getAccessToken(final String pin) throws TwitterException { log.info(String.format("Got token: %s, Got secret: %s", requestToken.getToken(), requestToken.getTokenSecret())); accessToken = twitter.getOAuthAccessToken(requestToken, pin); if (accessToken != null) log.info(String.format("Got access token for user %s", accessToken.getScreenName())); } |
Lo cual se ve así:
Número PIN para darle acceso a nuestro cliente a la cuenta de Twitter
Si todo va bien entonces podemos mostrar los 3 pedazos de la autorización necesarios para poder enviar un Tweet:

La aplicación tiene todo lo que necesita. Hora de enviar un tweet
Ya hacer el tweet es trivial con el siguiente pedazo de código:
1 2 3 4 5 6 7 8 9 10 | /** * Send a tween using an existing AccessToken * @param tweet The update to set * @throws TwitterException If there is a problem updating the status * @return The status of the tweet */ private Status sendTweet(final String tweet) throws TwitterException { twitter.setOAuthAccessToken(accessToken); return twitter.updateStatus(tweet); } |
Al final, ¡exito!:

Como se ve nuestro mensaje en Twitter, enviado desde Java
El protocolo de Twitter soporta muchísimas cosas más. En particular le recomiendo que se lean la documentación relacionada para entender más como trabajan las cosas, en especial la autenticación usando OAth. Ahhh, y por supuesto aquí les dejo el código fuente completo para que se diviertan echando código.
Hasta la siguiente entrega, dentro de unas horas me sale ir a una parrillada
Veneblogs: twitter, twitter4j, swing, kodegeek, stupidzombie
Blogalaxia: twitter, twitter4j, swing, kodegeek, stupidzombie
To2Blogs: twitter, twitter4j, swing, kodegeek, stupidzombie
Technorati: twitter, twitter4j, swing, kodegeek, stupidzombie
Del.icio.us: twitter, twitter4j, swing, kodegeek, stupidzombie


Muy bueno el tutorial, pero aun asi de momento te quedas en el mismo punto que me he quedado yo, te comento para ver si tu sabes como solucionarlo, porque yo de momento con lo que me he mirado no he encontrado la manera.
Con el codigo de este programa tenemos lo que queriamos, mandar mensajes desde nuestra aplicación ya registrada en twitter… pero ¿Y si queremos usarla en el futuro? ¿hay que volver a logear en twitter y a devolver un pin?
Es que realmente lo suyo seria que al usar el programa en un futuro pues… digamos que se pudiera guardar de alguna manera ese anterior acceso… me explico fatal pero creo que mas o menos lo he dejado claro jeje
PD: Si finalmente no hubiera manera pues tendré que pedir el pin cada vez que se acceda a la aplicación “pero no es para nada practico”
@Pakiyopgd
No entiendo bien lo que quieres decir, en Español por favor
@josevnz
Según esta aplicación, cada vez que el usuario la use tendrá que llevar a cabo el proceso de obtener el pin desde twitter, ¿hay alguna manera para que no se tenga que repetir este proceso y que el usuario mande los mensajes cada vez que abra el programa? es decir, sin autenticarse en twitter
Al final seguramente lo que haré será serializar el objeto twitter una vez tratado con el pin, espero que asi pueda conseguir lo que intento
El API dice que una vez que obtengas el pin lo guardas en una base de datos, archivo o lo que sea y de allí en adelante lo usas una y otra vez. Solamente se refresca si algo cambia en el lado de Twitter (por ejemplo te revocan las credenciales o expiran).
-Jose
@josevnz
Si, eso mismo es lo que habia pensado, en guardar el pin, aunque por lo que veo no tengo que serializar el objeto entero, solo basta con el pin, bueno, pues probaré y veré que tal
@Pakiyopgd
lo que ocupas guardar es el accessToken y el accessTokenSecret, no el pin..
saludos
@Pakiyopgd
Tengo la misma duda tuya, he investigado sobre como solucionar ese problema, lo ideal fuera que poder obtener el id del usuario “twitter.verifyCredentials().getId()” o en su defecto el nombre de usuario “twitter.getScreenName()” pero el problema esta que para obtener esos datos tenemos que enviarle antes al Objeto “Twitter” el token de autorizacion “twitter.setOAuthAccessToken(accessToken);” y caemos en un circulo vicioso, no podemos obtener el “accessToken” sin tener el id o el username, y no podemos tener el id o el username si tener el “accessToken”
Bueno la solucion que se me ocurre es que la primera vez que el usuario te envia su pin deberiamos guardar en una base de datos el nombre de usuario “twitter.getScreenName()” el accessToken y el accessTokenSecret y tambien guardar una “cookie” con su nombre de usuario, asi la proxima vez que el usuario entre podemos obtener el nombre de usuario desde la cookie e ir a nuestra DB y obtener el accessToken y el accessTokenSecret por medio del nombre de usuario…
lo unico es que esto de las cookies solo se puede hacer desde web(jsp o servlet)
para Swing, es decir desde una aplicacion de escritorio podemos hacerlo guardando un archivo de texto o lo que sea en un directorio temporal “File tempFile = File.createTempFile(“twitterTeporalFile”, “txt”)” con esa linea java me crea el archivo “twitterTeporalFile4809529757928467823.txt” ese monton de numeros los pone java aleatoreamente(o algo asi) y me lo crea en el directorio “C:\Users\JorG\AppData\Local\Temp” bueno despues de esto podriamos renombrar ese archivo y quitarle los numeros o a la hora de obtener el archivo obetener el nombre y filtrar esos numeros masomenos asi “elStringConElNombreDelFile.startsWith(“twitterTeporalFile”)” y bla bla bla bla…
en fin hay que ser creativo