domingo, 4 de abril de 2010

Jugando con Facebook

El dilema era: crear otro blog para escribir cosas mas técnicas y menos diarias o seguir usando este...como se puede ver abajo el dilema fue resuelto.

Desde hace un tiempo tenía ganas de poder integrar Facebook con GeneXus, de hecho en la charla que dimos con Javier Larrosa en la  XVIII GeneXus Meeting del 2008 algo habíamos mostrado. En esa oportunidad lo hicimos a través de los External Objects de GeneXus, utilizamos una librería desarrollada por Microsoft para interactuar con Facebook. La idea no estaba mal y de hecho pudimos comunicarnos muy fácilmente a través de dicha librería.

El problema con esto es que estábamos usando un producto de un tercero pudiéndolo hacerlo directamente a través de la API de Facebook. Esto tenía como inconveniente que siempre que ese tercero cambie nosotros debemos cambiar nuestro External Object para actualizar la lista de métodos/propiedades.

Eso fue justamente lo que nos paso luego del evento, Microsoft cambió varias interfaces de dicha librería debido a cambios en la propia API de Facebook, y lo que nosotros teníamos funcionando y que de hecho mostramos en la demo de la charla dejó de funcionar.

Lo interesante de utilizar un External Object era que teníamos la API de Facebook encapsulada en dicho objeto y era muy fácil su utilización.

Podíamos seguir en la línea de utilizar una librería de un tercero o podíamos nosotros mismos interactuar con la API de Facebook sin necesidad de un tercero, y esa es justamente la línea que elegimos, desarrollar una serie de User Controls que resuelvan la comunicación con Facebook desde nuestros objetos.

En cualquier caso, ya sea utilizando una librería de un tercero o accediendo a la API directamente, tenemos que crear una aplicación en Facebook, para lo cual primero que nada debemos agregar a nuestro perfil de Facebook la application: Developer. Y luego crear una nueva Application, esto nos permitirá obtener una ApiKey con la cual podremos acceder a la API. Acá pueden saber un poco mas al respecto.

La idea de los User Controls es utilizar la JavaScript Client Library, para acceder a la API a través de código javascript. No queremos hostear una app en Facebook, por lo cual cuando creemos nuestra app en Developer solo nos interesará:

Basic -  API Key, Key necesaria para poder interactuar con la API


Connect - Connect URL, url donde Facebook enviará una session válida para comunicarnos con ellos

Como pueden ver, también configuré un valor para Base Domain, en este caso localhost. Esto se debe a que tendremos una comunicación entre nuestra app y Facebook a través de js, por lo cual habrá una Cross Domain Communication, por lo cual debemos crear un Channel entre nuestra app y Facebook, para lo cual necesitamos crear un archivo xd_receiver.htm y almacenarlo en nuestro server. Pueden obtener mas detalles aquí, pero a los efectos de la utilización de los User Controles en GeneXus solo tenemos que tener en cuenta dos cosas:

1. cuando creamos la app en Facebook indicar un Base Domain, con lo cual indicamos el nombre del dominio en el cual estará el archivo xd_receiver.htm
2. cuando utilicemos el User Control: FacebookConnect, el cual nos permitirá conectarnos con Facebook, debemos indicar la ruta a dicho archivo a través de la property xdChannelUrl, cuyo valor por defecto es "/xd_receiver.htm".


Por lo cual si en el UC indicamos como xdChannelUrl el valor "/xd_receiver.htm",  entonces en el caso de .Net debemos almacenar el archivo en: C:\Inetpub\wwwroot, y en el caso de Java utilizando tomcat como webserver en: C:\Program Files\Apache Software Foundation\Tomcat 6.0\webapps\ROOT.

Los tres User Controls que tenemos al día de hoy son:

FacebookConnect: necesario para establecer la conexión entre nuestra app y Facebook.

Text: text del botón que se agregara a nuestro form y que nos permitirá establecer la comunicación con Facebook, valor por defecto: "Connect with Facebook".

ApiKey: como mencionamos antes es la Key asociada a la app que creamos en Facebook.

xdChannelUrl: url o ruta al archivo xd_receiver.htm que nos permitirá establecer una cross domain communication entre nuestra app y Facebook, valor por defecto: "/xd_receiver.htm"

Size: tamaño del boton, valores posibles: small, medium, large, or xlarge, valor por defecto: "medium".

FacebookLoggedUser: muestra la foto de perfil y el nombre del usuario logeado a Facebook.

Width: width de la foto, valor por defecto: 50

Height: height de la foto, valor por defecto: 50

FacebookLogo: true/false, indica si se quiere mostrar el logo de Facebook o no en la foto, valor por defecto: true.

Linked: true/false, indica si se quiere tener un link al perfil de Facebook en la foto de perfil, valor por defecto: true.

FacebookShare: permite compartir un link en el muro del usuario logeado

Link: link a compartir una vez que el user hace click en el boton asociado

Type: tipo de boton, valores posibles: box_count, button_count, button, icon, or icon_link, valor por defecto: button_count

Pueden obtener los controles en la gallery de GeneXus.

Si se fijan el código de estos User Controls es muy simple, por lo cual pueden chequear la docum de la JavaScript Client Library de Facebook y desarrollar el propio en base a sus necesidades.

update


Dado algunos cambios que sufrió la api de Facebook he realizado algunos cambios. Paso a hacer deprecated la JavaScript Client Library y con ello varios métodos y formas de realizar determinadas acciones.

Eliminé los user controls FacebookLoggedUser y FacebookShare dado que el Facebook Markup Language (FBML), lenguage utilizado en dichos controles, paso a ser deprecated (o en vías de serlo). De todos modos quedó todo armado hacer lo que hacían estos controles

Realicé cambios en la implementación del FacebookConnect los cuales son transparentes para quien utiliza el control, pero que eran necesarios para que funcione la autorización y autenticidad con Facebook.

Agregué un nuevo user control, FacebookFriends, que me pareció interesante pensando en el desarrollo de una aplicación que lo utilizara para explotar los datos obtenidos. Como su nombre lo indica el FacebookFriends obtiene la lista de los amigos del usuario logeado, deja cargada una colección con dichos datos.

Para que funcione el FacebookFriends es necesario tener un FacebookConnect de modo de resolver la autorizcion y autenticacion, una vez que el usario se logea a Facebook y permite acceso para que nuestra app
acceda a la lista de sus amigos obtendremos la collection de amigos a través de un sdt.

Cuando se arrastra el user control FacebookFriends se importa el xpz con el sdt que utilizara el uc para cargar la lista de amigos, la información de los amigos que se esta cargando hoy en día (podría agregarse mas data) son: id y nombre.

Para cargar la foto de todos mis amigos en un free style grid podría hacer algo como esto:


Event FacebookFriends1.AfterFriendsLoaded
for &friend in &friends
&imagesDataItem = new()
&imagesDataItem.Id = &friend.id
&imagesDataItem.Thumbnail = "http://graph.facebook.com/" + &friend.id + "/picture"
&imagesDataItem.Image = "http://graph.facebook.com/"+ &friend.id + "/picture?type=large"
&imagesDataItem.Caption = &friend.name
&imagesData.Add(&imagesDataItem)
endfor
&tic = Servernow()
 
EndEvent

en el evento AfterFriendsLoaded del user control FacebookFriends  cargo un sdt con la información de los amigos (id, name y foto).

Event grid1.Load
for &imagesDataItem in &imagesData
image1.FromURL(&imagesDataItem.Image)
grid1.Load()
endfor
EndEvent


y luego en el evento load de la grid cargo las fotos.


Notar que estoy usando otra sdt para cargar los datos de cada amigo cuando en realidad el UC podría ya devolver dicha información, esto es solo a los efectos de mostrar que dado el id de un user en Facebook puedo obtener información de dicho user consultando la Graph API.


Toda la documentación necesaria para interactuar con Facebook vía js esta en la JavaScript SDK.

Estos dos controles los pueden encontrar en el Marketplace de GeneXus.

4 comentarios:

Enrique Almeida dijo...

Muy bueno..

David Giordano dijo...

Esa!! Excelente, muy bueno :)

cimasan dijo...

Creo que resolviendo toda la primera parte, luego el hacer un UC queda simple. Hay mucho con lo que jugar en FB. Un saludo!

nocuser dijo...

Hola Alejandro, acabo de instalar el User Control, pero al ejecutar el modelo donde tengo el web panel que lo contiene y hacer click en Conectar con facebook, me salta un error de
------------------------------
Invalid API key specified


The application you are trying to access does not exist or has been disabled.

------------------------------

Verifico y existe esa API Key en mi perfil de facebook...
Cuál podría ser el problema?
Ademas, no tenes un ejemplo donde lo estés implementando?
Muchas gracias!!!!