ANALIZANDO EL API DE TUENTI
Esta semana (el pasado jueves, concretamente), Tuenti sacó (¡por fin!) su app oficial para la plataforma de Apple, iPhone / iPod (gama 'Touch'). Asumimos que para construir esta aplicación se ha hecho de uso de un API que conecte la aplicación con el sistema de Tuenti, y que eventual -mente este API será pública. Así que aquí va un repaso preliminar sobre lo que podría ser la futura API (pública, esperemos) de Tuenti. El proceso "básico" (sin profundizar en el sistema XMPP, que ese es de hecho bastante fácil de de diseccionar, y sin profundizar tampoco en el sistema de fotografías, carga de fotografías o perfiles de usuario, puesto que esto es únicamente un texto orientativo): I. LA SALSA 1. Login: a) Envía un request ("getChallenge") indicando que se trata de un request en relación al login, y recibe una respuesta con una marca de tiempo y unos valores JSON (seed, challenge) b) Envía un request ("getSession"), incluyendo el seed y challenge previamente obtenidos junto con un valor llamado "passcode", que parece ser un hash MD5. También se envía "application_key" (es un token) junto con el email del usuario y la versión del API La respuesta de esta petición consiste en un array JSON que incluye un token de sesión, junto con unas URL que hacen referencia al "servidor de upload" y "servidor" (URL del API). 2. Peticiones: -> En todas las peticiones se incluye el token de sesión a) Envía una petición con un array multidimensional: el JSON contiene un valor "requests" que a su vez contiene un array con dos elementos que son a su vez arrays, en este caso el nombre de la petición y sus parámetros: "getUserNotifications" y "getFriendsNotifications", son arrays multidimensionales con los datos parámetros para obtener nuevas notificaciones disponibles (respuesta por analizar, aún). Recibe: salsa! Un enorme array JSON de varias dimensiones con toda la información sobre el "timeline" del usuario, desde requests pendientes (privados, eventos, comentarios) hasta el timeline de actividad de sus amigos. b) Amigos, muchísimos: se envía una petición para obtener un array doble con información sobre el propio usuario (self) y su lista de contactos. El API devuelve un puñado de información de todos los usuarios, de los cuales se destaca el servidor XMPP y el número de teléfono. Sin embargo no se incluye el URL del avatar en la lista íntegra de amigos. Hay que destacar que en los parámetros de la petición se incluye un conjunto llamado "fields", que indica qué datos se desean obtener del servidor. II. EL GATO Y EL RATÓN El API no tiene mucho misterio. Se basa esencialmente en JSON y funciona bastante bien, es tan rápido como la web. El quid reside en el sistema de login, que por motivos obvios no voy a analizar aquí (esto ya depende de la voluntad de quién quiera llevar estas inves- tigaciones a término). III. HABLANDO EN CLARO Para ilustrar lo explicado, mejor algo real. He modificado datos como el token, la sesión, el seed/challenge o el passcode así como datos de mis contactos. Los headers de la sesión están puestos en formato Pickle (Python). Todas las comuni- caciones se efectuan usando POST. HTTP ENDPOINT http://api.tuenti.com/api/ PICKLED HEADERS {"requests":[["getChallenge",{"type":"login"}]],"version":"0.4"} RAW RESPONSE [{"timestamp":1264202878,"seed":"LSqa42ZK(...)glEq8Ej\/ieB4(...)XGMw Kc=","challenge":"tRXY7(...)k7hKmti7gFrP(...)nv3Cs="}] HTTP ENDPOINT http://api.tuenti.com/api/ PICKLED HEADERS {"requests":[["getSession",{"passcode":"605718f(...))297d7bfe9f","app lication_key":"MDI3MDFmZjU4MGExNWM0YmEyYjA5MzRkODlmMjg0MTU6MC4xMzk0OD YwMCAxMjYxMDYwNjk2","timestamp":1264202878,"seed":"LSqa42ZK(...)glEq8E j\/ieB4(...)XGMwKc=","email":"adrian@navarro.at"}]],"version":"0.4"} RAW RESPONSE [{"session_id":"NjE0OTc3Nj(...)Q1MWYxNWYyMTc4ZjJiOThmYTR(...)DIwMj g3OQ","user_id":6149xxxx,"server":"http:\/\/api.tuenti.com\/api\/ ", "upload_server":"http:\/\/fotos.api.tuenti.com\/api\/","chat_server": "xmpp9.tuenti.com"}] HTTP ENDPOINT http://api.tuenti.com/api/ PICKLED HEADERS {"requests":[["getUserNotifications",{}],["getFriendsNotifications", {"page_size":10,"page":0}]],"session_id":""NjE0OTc3Nj(...)Q1MWYxNWYy MTc4ZjJiOThmYTR(...)DIwMjg3OQ","version":"0.4"} RAW RESPONSE [{"unread_friend_messages":{"count":0},"unread_spam_messages":{"count":0 },"new_profile_wall_posts":{"count":0},"new_friend_requests":{"count":0," users":[]},"accepted_friend_requests":{"count":0,"friends":[]},"new_photo_ wall_posts":{"count":0,"photos":[]},"new_tagged_photos":{"count":0,"photos" :[]},"new_event_invitations":{"count":0,"events":[]}},{ (FRIENDS) }