Wednesday, October 27, 2010

Integración Facebook - ASP.NET con Graph API (II)

Como comentaba en la primera parte de este post sobre la Graph API de Facebook, para poder recuperar cualquier tipo de dato es necesario obtener un AccessToken de Facebook. Recordemos que existen 2 tipos de token, uno público y otro privado.

Lo primero que haremos en este post una vez tengamos los datos de nuestra aplicación residente en nuestro perfil de Developer de Facebook (appId, appSecret, GroupId,...), será la llamada al siguiente método de la API para C# que hemos modificado convenientemenre y que será con la que trabajaremos.



///
/// Gets the access token for public access.
///

/// The app id.
/// The app secret.
/// Public access token.
public static string GetAccessToken(string appId, string appSecret)
{
if (string.IsNullOrEmpty(appId) string.IsNullOrEmpty(appSecret))
{
return null;
}

var url = string.Format(
"https://graph.facebook.com/oauth/access_token?type=client_cred&client_id={0}&client_secret={1}",
appId,
appSecret);

string accessTokenValue = null;
var request = WebRequest.Create(url) as HttpWebRequest;

try
{
if (request != null)
{
ServicePointManager.ServerCertificateValidationCallback = new System.Net.Security.RemoteCertificateValidationCallback (CertificateValidationCallBack);

using (var response
= request.GetResponse() as HttpWebResponse)
{
if (response != null)
{
var reader = new StreamReader(response.GetResponseStream());
accessTokenValue = reader.ReadToEnd().Replace("access_token=", string.Empty);
}
}
}
}
catch (WebException e)
{
throw new FacebookAPIException("Server Error", e.Message);
}

return accessTokenValue;
}


Como veis, este método static de la API lo que hace es únicamente crear un WebRequest a la dirección https://graph.facebook.com/oauth, y recuperar el parámetro access_token que devuelve dicha llamada. Ése será nuestro public AccessToken a partir de ahora, almacenado en PublicToken al hacer la siguiente llamada:


this.PublicToken = FacebookAPI.GetAccessToken(AppId, AppSecret);


Las consultas públicas las haremos a través de la Graph API, pasando este PublicToken siempre como parámetro. Así, en cada nueva consulta de, por ejemplo, el muro de un grupo de Facebook del cual tenemos su identificador (GroupId), instanciamos un nuevo objeto FacebookAPI y asignamos los datos recuperados a un objeto JSON.


///
/// Gets or sets the feed.
///

/// The wall's feed.
public JSONObject Feed
{
get
{
return this.feed;
}
set
{
this.feed = value;
}
}



// API call and get data from Facebook
var api = new FacebookAPI(this.Token);

// Format url
var url = string.Format("/{0}/feed", GroupId);

// Format args - get all data
var args = new Dictionary
{
{ "metadata", "1" }
};
this.Feed = api.Get(url, args);


Lo que la llamada a api.Get("/[GroupId]/feed") devuelve es el objeto JSON del que tendremos que hacer el DataBind con el control web que hemos incluído en nuestra aplicación. En mi caso es un Repeater.



///
/// Handles the ItemDataBound event of the rptDataWall control.
///

/// The source of the event.
/// The instance containing the event data.
protected void RptDataWallItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item e.Item.ItemType == ListItemType.AlternatingItem)
{
var apiItem = new FacebookAPI(this.Token);

// Get controls
var lbCreatedTime = (Label)e.Item.FindControl("lbCreatedTime");
var lbFrom = (Label)e.Item.FindControl("lbFrom");
var lbMessage = (Label)e.Item.FindControl("lbMessage");
var imgUserPic = (Image)e.Item.FindControl("imgUserPic");
var rptDataWallReply = (Repeater)e.Item.FindControl("rptDataWallReply");

// Databind
lbCreatedTime.Text = ((JSONObject)e.Item.DataItem).Dictionary["created_time"].DateTime.ToShortDateString() + " @ " + ((JSONObject)e.Item.DataItem).Dictionary["created_time"].DateTime.ToShortTimeString();
lbFrom.Text = ((JSONObject)e.Item.DataItem).Dictionary["from"].Dictionary["name"].String;
lbMessage.Text = ((JSONObject)e.Item.DataItem).Dictionary["message"].String;

// Get profile picture
var urlPictureProfile = string.Format("/{0}/picture", ((JSONObject)e.Item.DataItem).Dictionary["from"].Dictionary["id"].String);
imgUserPic.ImageUrl = apiItem.GetProfilePicture(
urlPictureProfile,
null).AbsoluteUri;

// Replies - FB restriction: only show when logged
if (((JSONObject)e.Item.DataItem).Dictionary.ContainsKey("comments"))
{
rptDataWallReply.ItemDataBound += new RepeaterItemEventHandler(this.RptDataWallReplyItemDataBound);
rptDataWallReply.DataSource = ((JSONObject)e.Item.DataItem).Dictionary["comments"].Dictionary["data"].Array;
rptDataWallReply.DataBind();
}
}
}


Así, estamos mostrando en el Repeater una cadena de posts de un wall de un grupo de Facebook. Algo del estilo como la siguiente imagen.




Y ya tenemos un muro más parecido al Notepad que al Facebook al que estamos habituados ;)

En la siguiente parte del post nos centraremos en obtener un token privado y en cómo sacarle rendimiento (obtener comentarios de comentarios, postear en el muro de un grupo, etc...).

No comments:

Post a Comment