Archivo

Entradas Etiquetadas ‘twitter4j’

Enviando Tweets desde Java usando Twitter4J: ¿Como proteger consumerKey and consumerSecret?

Sábado, 18 de Julio de 2009

Bueno, mientras buscaba como agregar soporte para Facebook en StupidZombie, me conseguí con un problema interesante. Twitter4J requiere que definamos consumerKey y consumerSecret en el objeto Twitter en cada llamada.

Lo cual trae problemas, ya que si distribuimos esas claves entonces cualquiera puede hacerse pasar por nuestra aplicación (No es un problema en una aplicación web pero si en una de escritorio). El problema es peor si la aplicación es OpenSource porque entonces un Script-Kiddie puede hacer de las suyas sin mucho esfuerzo.

1
2
//twitter.setOAuthConsumer(consumerKey, consumerSecret);
accessToken = twitter.getOAuthAccessToken(token, tokenSecret, pin);

Lo que mas me preocupa es que autenticación de escritorio no funciona si no lo definimos. Por ejemplo, en el código que escribí la vez pasada esto es lo que ocurre si no incluimos la linea que esta comentada en el párrafo anterior:

1
2
3
Jul 18, 2009 10:18:49 PM com.kodegeek.blog.twitter.TwitterPing getAccessToken
INFO: Token=Ujq2pzpG7PwZVAJmGHjWrDiVzFz6wfmxzx9r85y7s TokenSecret=hBHVuOWdJPBe5r3iVXklSJuwawssjqoBslLHXhzlE Pin=4129706
Exception in thread "AWT-EventQueue-0" java.lang.IllegalStateException: Neither user ID/password combination nor OAuth consumer key/secret combination supplied

Por ahora ando preguntándole al autor como resolver este asunto. La gente de Java API de FaceBook tiene una solución a este problema, lo hacen creando algo llamado ‘temporary secret

Actualización: El siguiente “hack” parece funcionar, pues el código de HttpClient revizar por NULL o cadenas de caracteres vacias:

1
2
3
		Twitter twitter = new Twitter();
		twitter.setOAuthConsumer(" ", " ");
		twitter.setOAuthAccessToken(accessToken);

internet, java, kodegeek, opensource, programación , , ,

Como enviar Tweets desde Java usando Twitter4J

Domingo, 5 de Julio de 2009

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:

  1. Autoriza la aplicación contra su cuenta de Twitter
  2. 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).
  3. 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:

Registered applications
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:

Allowing KodeGeek
Hora de autorizar a KodeGeek :)

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):

KodeGeek twitter application
La autorización trabajó

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í:

Ping number, required for desktop appsNú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:

After geting the auth tokens
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!:

Success, tweet update
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: , , , ,

Blogalaxia: , , , ,

To2Blogs: , , , ,

Technorati: , , , ,

Del.icio.us: , , , ,

java, kodegeek, opensource, programación , , , , , ,