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 posible
s: 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.