Como ya sabréis, del 30 de mayo al 1 de junio tuvo lugar, en Madrid, APIdays Mediterránea, conferencia centrada exclusivamente en el desarrollo de APIs y su arquitectura. Se dieron montones de ponencias alrededor del ecosistema API: desde charlas sobre diseño de APIs RESTful hasta charlas de negocio para sacarle todo el beneficio posible a una API. Tuvimos la suerte de contar con ponentes tanto internacionales como nacionales, que compartieron su conocimiento y experiencia.

El primer día, fue el Iberian Hackathon, un hackday centrado en desarrollar aplicaciones sobre APIs, en el cual, participé. Los premios se dividían en categorías, en función de las APIs empleadas en la aplicación. Las APIs patrocinadoras fueron APIcultur, Mashape, XING y Twilio, aunque se podían complementar con otras.

Yo participé en la categoría de XING. Para los que no conozcáis XING, se trata de una red social de ámbito profesional, que te permite hacer networking de forma sencilla.

Mi primera idea fue desarrollar una aplicación móvil Android que permitiera migrar los contactos de tu red de Linkedin a XING De modo que, tras obtener la lista de tus contactos de LinkedIn, se migraran a XING; en el caso que el contacto no tuviera perfil en XING, enviaría una invitación por email para unirse a la red, en otro caso, enviaría la petición directamente.

Desafortunadamente, la API no proporciona, por el momento, la búsqueda de usuarios por nombre, por lo que tuve que cambiar mi idea inicial. Tras analizar más en profundidad las posibilidades que ofrecía la API, finalmente, la aplicación desarrollada lista los emails de los contactos almacenados en el teléfono móvil y tras pulsar el botón “Enviar” se envían peticiones de contacto e invitaciones por email.

Screenshot_2013-06-16-21-15-30Screenshot_2013-06-16-21-16-17Screenshot_2013-06-16-21-16-51Screenshot_2013-06-16-21-18-40Screenshot_2013-06-16-21-29-05

Veamos en detalle la implementación:

La API de XING es REST y utiliza OAuth 1.0 para autentificar al usuario y dar permiso a la aplicación para acceder a sus datos.  De modo que, para obtener un token de acceso válido (necesario para realizar cualquier petición sobre la API) la aplicación debe seguir los siguientes pasos:

  • Obtener un request token de la API.
  • Redireccionar al usuario a una URL proporcionada por la API en la que deberá autenticarse y dar permiso a la app para acceder a sus datos antes de ser redireccionado de vuelta a la aplicación.
  • Intercambiar el request token del primer paso por el access token devuelto.

Para la gestión de dicho flujo he usado la librería Java scribe-java de @fernadezpablo que facilita enormemente el trabajo, ya que abstrae toda la lógica mencionada y soporta numerosas APIs OAuth out-of-the-box, entre ellas, la de XING.

Tan sencillo que se configura en una línea del siguiente modo:

OAuthService service = new ServiceBuilder()
.provider(XingApi.class)
.apiKey("YOUR_API_KEY")
.apiSecret("YOUR_API_SECRET")
.build();

Tras esto se obtiene el request token:

Token requestToken = service.getRequestToken();
String authURL = service.getAuthorizationUrl(requestToken);

Y se carga la URL obtenida en una vista web.

En el momento que se obtiene el verificador (cuando el usuario hace login con su cuenta):

String verifier = uri.getQueryParameter("oauth_verifier");
Verifier v = new Verifier(verifier);

Se obtiene el access token:

Token accessToken = service.getAccessToken(requestToken, v);
String accessTokenXing = accessToken.getToken();
String accessSecretXing = accessToken.getSecret();

En este punto ya se puede preguntar por los recursos protegidos:

OAuthRequest request = new OAuthRequest(Verb.GET, PROTECTED_RESOURCE_URL);
service.signRequest(accessToken, request);

Nótese que se debe cambiar el verbo en función de la petición a realizar.

Para terminar, se obtiene la respuesta y se trata la información obtenida (las peticiones devuelven los resultados en formato JSON):

Response response = request.send();
String result = response.getBody();

Como curiosidad se debe activar Javascript sobre la vista web para que todo funcione correctamente.

Para la aplicación desarrollada se han utilizado las siguientes peticiones sobre la API:

Buscar usuarios por su dirección de email (GET)

/v1/users/find_by_emails

Devuelve la lista de usuarios que coincide con la lista de emails proporcionada. En el caso de que el email no se encuentre en XING o sea incorrecto, se devuelve null.

Ejemplo de respuesta:

https://api.xing.com/v1/users/find_by_emails?emails=existing_user@xing.com,unknown_user@xing.com

{
"results": {
"items": [
{
"email": "existing_user@xing.com",
"hash": null,
"user": {
"id": "10368_ddec16"
}
},
{
"email": "unknown_user@xing.com",
"hash": null,
"user": null
}
],
"total": 2
}
}

Una vez obtenidos los usuarios se hacen peticiones de contacto para los usuarios registrados en XING (los que en la petición previa tuvieran id) y para los que no tienen perfil, se envía una invitación por email para unirse a la red.

Iniciar petición de contacto (POST)

/v1/users/:user_id/contact_requests

Inicia una petición de contacto entre el usuario actual (sender) y el usuario especificado (recipient).

Ejemplo:

https://api.xing.com/v1/users/3455987_6ae897/contact_requests

Enviar invitaciones (POST)

/v1/users/invite

Envía invitaciones por email a contactos que no tienen perfil en XING. El usuario puede enviar hasta 2000 invitaciones por semana. Esta llamada se encuentra en estado EXPERIMENTAL.

Ejemplo de respuesta:

https://api.xing.com/v1/users/invite?to_emails=user1@example.com,user2@example.com&message=Join+XING+today&user_fields=id,display_name,permalink

{
"invitation_stats": {
"total_addresses": 7,
"invitations_sent": 3,
"already_invited": [
"kven.sever@example.net"
],
"already_member": [{
"id": "666666_abcdef",
"email": "sark.midt@xing.com",
"display_name": "Sark Midt"
}, {
"id": "12345_abcdef",
"email": "kennart.loopmann@xing.com",
"display_name": "Kennart Loopmann"
}],
"invalid_addresses": [
"@example.f"
]
}
}

Para más información podéis visitar el portal de desarrolladores de XING:

https://dev.xing.com/

Por último, quiero destacar la magnífica organización del evento y animarles a que sigan realizando muchos más como este. Es una experiencia muy enriquecedora que te permite relacionarte con expertos y te da la oportunidad de seguir aprendiendo haciendo lo que te gusta.

Autor: Pablo Guardiola, Ganador de la Hackatón Iberica de APIdays Mediterránea en 
       la Categoría XING.
       Conecta con Pablo en Twitter: @Guardiola31337
Tagged with →  
Share →