[Google+ Portable SDK .NET] Obtener publicaciones del muro (y VII)

Esta es la última entrega de esta serie dedicada a Google plus, en ella vamos a ver cómo recuperar aquellas publicaciones de nuestro muro marcadas con accesibilidad pública. En este caso vamos a hacer una petición “LIST” al recurso “ACTIVITIES” de Google Plus, la cual consiste en hacer una petición HTTP GET a la url

https://www.googleapis.com/plus/v1/people/<id_usuario>/activities/<coleccion>

donde <id_usuario> representa el id de la cuenta de google o podemos usar el literal “me” para hacer referencia a nuestra propia cuenta. El valor de <coleccion> debe ser “public“.

Los posibles parámetros de esta petición son:

– access_token: token de acceso recuperado en la 3ª entrega.

– maxResult: su valor de ser el literal “public

– maxResult: (opcional) Número de amigos a recuperar por página. Su valor debe estar en el rango 1-100.

– pageToken: (opcional) este campo permite acceder a la siguiente pagina de resultados. Cuando obtenemos la primera página, unos de los campos que recuperamos en el “nextPageToken“, el cual nos permitirá acceder a la siguiente página.

– fields: (opcional) permite configurar los campos que queremos recuperar.

id,items,kind,nextLink,nextPageToken,selfLink,title,updated

Vamos a recordar la hoja de ruta para esta serie de artículos

1. Crear aplicación Google +

2. Obtener código de autorización

3. Obtener Token de acceso

4. Obtener información del perfil

5. Amigos en los círculos

6. Buscar Amigos

7. Obtener las publicaciones del muro (actual)

Toda la lógica de esta petición ha sido incluida en el método “ObtenerPublicacionesAsync” de la clase “smpGooglePlusApi

        public async Task<Publicaciones> ObtenerPublicacionesAsync(string token, string idUsuario = "me", string tokenPagina = "", int numResultadosPagina = 10, string campos = "", string coleccion = "public")
        {
            Publicaciones resultadoPublicaciones = new Publicaciones();
            StringBuilder cadUrl = new StringBuilder();

            if (string.IsNullOrEmpty(token))
                throw new ArgumentException("token");

            if (string.IsNullOrEmpty(idUsuario))
                idUsuario = "me";

            if (string.IsNullOrEmpty(coleccion))
                coleccion = "public";

            if (numResultadosPagina > 100)
                throw new ArgumentException("numResultadosPagina maximo 100");

            HttpClient cliente = new HttpClient();
            cadUrl.AppendFormat(Declaraciones.URL_ACTIVITIES_LIST, idUsuario.UrlEncode(), coleccion.UrlEncode());
            cadUrl.AppendFormat("?access_token={0}&maxResults={1}", token.UrlEncode(), numResultadosPagina.ToString().UrlEncode());

            if (!string.IsNullOrEmpty(tokenPagina))
                cadUrl.AppendFormat("&pageToken={0}", tokenPagina.UrlEncode());

            if (!string.IsNullOrEmpty(campos))
                cadUrl.AppendFormat("&fields={0}", campos.UrlEncode());

            HttpResponseMessage respuestaHttp = await cliente.SendAsync(new HttpRequestMessage(HttpMethod.Get, cadUrl.ToString())).ConfigureAwait(false);
            RespuestaGooglePlus respuestaGooglePlus = await UtilidadesGenerales.ProcesarRespuestaAsync(respuestaHttp);

            if (respuestaGooglePlus.Estado == EstadoGooglePlus.Correcto)
            {
                if (!string.IsNullOrEmpty(respuestaGooglePlus.ContenidoRespuesta))
                {
                    JObject resultado = JObject.Parse(respuestaGooglePlus.ContenidoRespuesta);
                    resultadoPublicaciones.nextPageToken = (resultado["nextPageToken"] != null ? resultado["nextPageToken"].ToString() : string.Empty);
                    resultadoPublicaciones.etag = (resultado["etag"] != null ? resultado["etag"].ToString() : string.Empty);
                    resultadoPublicaciones.title = (resultado["title"] != null ? resultado["title"].ToString() : string.Empty);
                    resultadoPublicaciones.updated = (resultado["updated"] != null ? resultado["updated"].ToString() : string.Empty);

                    if (resultado["items"] != null)
                    {
                        JArray arrayPublicaciones = JArray.Parse(resultado["items"].ToString());
                        if (arrayPublicaciones != null)
                        {
                            resultadoPublicaciones.items = new List<Publicacion>();
                            foreach (JObject item in arrayPublicaciones)
                            {
                                Publicacion pub = ParsearPublicacion(item);
                                if (pub != null)
                                {
                                    await CargarComentariosPublicacion(token, pub, string.Empty, 500);
                                    await CargarUsuariosPublicacion(token, pub, string.Empty, 20);
                                }
                                resultadoPublicaciones.items.Add(pub);
                            }
                        }
                    }
                }
            }

            return resultadoPublicaciones;
        }

en el cual realizamos las siguiente operaciones:

1. Comprobamos que los valores de entrada son correctos: token, idusuario, coleccion, numRegistrosPagina…

2. Creamos la url según lo explicado al principio de este artículo.

3. Utilizamos la librería Http Client para hacer una petición HTTP GET a la url anterior.

4. Si la respuesta ha sido correcta, usamos la librería json.net para parsear la cadena JSON (de la respuesta HTTP) a un objeto del tipo  “Publicaciones“.

namespace smpClienteGooglePlus.Entidades
{

    public class Publicaciones
    {
        public string kind { get; set; }
        public string etag { get; set; }
        public string nextPageToken { get; set; }
        public string title { get; set; }
        public string updated { get; set; }
        public List<Publicacion> items { get; set; }
    }

    public class Publicacion
    {
        public string kind { get; set; }
        public string etag { get; set; }
        public string title { get; set; }
        public string published { get; set; }
        public string updated { get; set; }
        public string id { get; set; }
        public string url { get; set; }
        public Actor actor { get; set; }
        public string verb { get; set; }
        public Elementos elementos { get; set; }
        public Provider provider { get; set; }
        public Access access { get; set; }
        public Comentarios comentarios { get; set; }
        public BusquedaUsuarios usuariosPlus { get; set; }
        public BusquedaUsuarios usuariosShared { get; set; }
    }

    public class Actor
    {
        public string id { get; set; }
        public string displayName { get; set; }
        public string url { get; set; }
        public Image image { get; set; }
    }

    public class Elementos
    {
        public string objectType { get; set; }
        public string content { get; set; }
        public string url { get; set; }
        public Replies replies { get; set; }
        public Plusoners plusoners { get; set; }
        public Resharers resharers { get; set; }
        public List<Attachment> attachments { get; set; }
    }

    public class Replies
    {
        public int totalItems { get; set; }
        public string selfLink { get; set; }
    }

    public class Plusoners
    {
        public int totalItems { get; set; }
        public string selfLink { get; set; }
    }

    public class Resharers
    {
        public int totalItems { get; set; }
        public string selfLink { get; set; }
    }
    public class Attachment
    {
        public string objectType { get; set; }
        public string displayName { get; set; }
        public string id { get; set; }
        public string content { get; set; }
        public string url { get; set; }
        public Image image { get; set; }
        public Image fullImage { get; set; }
    }

    public class Provider
    {
        public string title { get; set; }
    }

    public class Access
    {
        public string kind { get; set; }
        public string description { get; set; }
        public List<AccessItem> items { get; set; }
    }

    public class AccessItem
    {
        public string type { get; set; }
    }

}

Nota: estas clases han sido creados usando la funcionalidad “Pegar JSON como clases. (con unos ligeros retoques…)

El único punto a destacar el proceso de parseo, es que la colección de las publicaciones está incluida en el array JSON “items”, el cual es convertido a una instancia “JArray” usando el método “JArray.Parse“. Cada elemento del array es convertido a una instancia del tipo “Publicacion” invocando a la función “ParsearPublicación

        public Publicacion ParsearPublicacion(JObject item)
        {
            Publicacion publicacion = new Publicacion();

            publicacion.kind = (item["kind"] != null ? item["kind"].ToString() : string.Empty);
            publicacion.etag = (item["etag"] != null ? item["etag"].ToString() : string.Empty);
            publicacion.title = (item["title"] != null ? item["title"].ToString() : string.Empty);
            publicacion.published = (item["published"] != null ? item["published"].ToString() : string.Empty);
            publicacion.updated = (item["updated"] != null ? item["updated"].ToString() : string.Empty);
            publicacion.id = (item["id"] != null ? item["id"].ToString() : string.Empty);
            publicacion.url = (item["url"] != null ? item["url"].ToString() : string.Empty);
            if (item["actor"] != null)
            {
                publicacion.actor = new Actor();
                publicacion.actor.id = (item["actor"]["id"] != null ? item["actor"]["id"].ToString() : string.Empty);
                publicacion.actor.displayName = (item["actor"]["displayName"] != null ? item["actor"]["displayName"].ToString() : string.Empty);
                publicacion.actor.url = (item["actor"]["url"] != null ? item["actor"]["url"].ToString() : string.Empty);
                if (item["actor"]["image"] != null)
                {
                    publicacion.actor.image = new Entidades.Image();
                    publicacion.actor.image.url = (item["actor"]["image"]["url"] != null ? item["actor"]["image"]["url"].ToString() : string.Empty);
                }
            }
            publicacion.verb = (item["verb"] != null ? item["verb"].ToString() : string.Empty);
            if (item["object"] != null)
            {
                publicacion.elementos = new Elementos();
                publicacion.elementos.objectType = (item["object"]["objectType"] != null ? item["object"]["objectType"].ToString() : string.Empty);
                publicacion.elementos.content = (item["object"]["content"] != null ? item["object"]["content"].ToString() : string.Empty);
                publicacion.elementos.url = (item["object"]["url"] != null ? item["object"]["url"].ToString() : string.Empty);
                int tempInt = 0;
                if (item["object"]["replies"] != null)
                {
                    publicacion.elementos.replies = new Replies();
                    if (item["object"]["replies"]["totalItems"] != null)
                    {
                        tempInt = 0;
                        if (int.TryParse(item["object"]["replies"]["totalItems"].ToString(),out tempInt))
                            publicacion.elementos.replies.totalItems=tempInt;
                    }
                    publicacion.elementos.replies.selfLink = (item["object"]["replies"]["selfLink"] != null ? item["object"]["replies"]["selfLink"].ToString() : string.Empty);
                }
                if (item["object"]["plusoners"] != null)
                {
                    publicacion.elementos.plusoners = new Plusoners();
                    if (item["object"]["plusoners"]["totalItems"] != null)
                    {
                        tempInt = 0;
                        if (int.TryParse(item["object"]["plusoners"]["totalItems"].ToString(), out tempInt))
                            publicacion.elementos.plusoners.totalItems = tempInt;
                    }
                    publicacion.elementos.plusoners.selfLink = (item["object"]["plusoners"]["selfLink"] != null ? item["object"]["plusoners"]["selfLink"].ToString() : string.Empty);
                }
                if (item["object"]["resharers"] != null)
                {
                    publicacion.elementos.resharers = new Resharers();
                    if (item["object"]["resharers"]["totalItems"] != null)
                    {
                        tempInt = 0;
                        if (int.TryParse(item["object"]["resharers"]["totalItems"].ToString(), out tempInt))
                            publicacion.elementos.resharers.totalItems = tempInt;
                    }
                    publicacion.elementos.resharers.selfLink = (item["object"]["resharers"]["selfLink"] != null ? item["object"]["resharers"]["selfLink"].ToString() : string.Empty);
                }
                if (item["object"]["attachments"] != null)
                {
                    JArray arrayAdjuntos = JArray.Parse(item["object"]["attachments"].ToString());

                    if (arrayAdjuntos != null)
                    {
                        publicacion.elementos.attachments = new List<Attachment>();

                        foreach (JObject item_attachment in arrayAdjuntos)
                        {
                            Attachment attachment = new Attachment();
                            attachment.objectType = (item_attachment["objectType"] != null ? item_attachment["objectType"].ToString() : string.Empty);
                            attachment.id = (item_attachment["id"] != null ? item_attachment["id"].ToString() : string.Empty);
                            attachment.displayName = (item_attachment["displayName"] != null ? item_attachment["displayName"].ToString() : string.Empty);
                            attachment.content = (item_attachment["content"] != null ? item_attachment["content"].ToString() : string.Empty);
                            attachment.url = (item_attachment["url"] != null ? item_attachment["url"].ToString() : string.Empty);
                            int alto = 0;
                            int ancho = 0;
                            if (item_attachment["image"] != null)
                            {
                                attachment.image = new Entidades.Image();
                                attachment.image.url = (item_attachment["image"]["url"] != null ? item_attachment["image"]["url"].ToString() : string.Empty);
                                attachment.image.type = (item_attachment["image"]["type"] != null ? item_attachment["image"]["type"].ToString() : string.Empty);
                                if (item_attachment["image"]["height"] != null)
                                {
                                    alto = 0;
                                    if (int.TryParse(item_attachment["image"]["height"].ToString(), out alto))
                                        attachment.image.height = alto;
                                }
                                if (item_attachment["image"]["width"] != null)
                                {
                                    ancho = 0;
                                    if (int.TryParse(item_attachment["image"]["width"].ToString(), out ancho))
                                        attachment.image.width = ancho;
                                }
                            }
                            if (item_attachment["fullImage"] != null)
                            {
                                attachment.fullImage = new Entidades.Image();
                                attachment.fullImage.url = (item_attachment["fullImage"]["url"] != null ? item_attachment["fullImage"]["url"].ToString() : string.Empty);
                                attachment.fullImage.type = (item_attachment["fullImage"]["type"] != null ? item_attachment["fullImage"]["type"].ToString() : string.Empty);
                                if (item_attachment["fullImage"]["height"] != null)
                                {
                                    alto = 0;
                                    if (int.TryParse(item_attachment["fullImage"]["height"].ToString(), out alto))
                                        attachment.image.height = alto;
                                }
                                if (item_attachment["fullImage"]["width"] != null)
                                {
                                    ancho = 0;
                                    if (int.TryParse(item_attachment["fullImage"]["width"].ToString(), out ancho))
                                        attachment.image.width = ancho;
                                }
                            }
                            publicacion.elementos.attachments.Add(attachment);
                        }

                    }

                }
            }
            if (item["provider"] != null)
            {
                publicacion.provider = new Provider();
                publicacion.provider.title = (item["provider"]["title"] != null ? item["provider"]["title"].ToString() : string.Empty);
            }
            if (item["access"] != null)
            {
                publicacion.access = new Access();
                publicacion.access.kind = (item["access"]["kind"] != null ? item["access"]["kind"].ToString() : string.Empty);
                publicacion.access.description = (item["access"]["description"] != null ? item["access"]["description"].ToString() : string.Empty);
                if (item["access"]["items"] != null)
                {
                    JArray arrayAccesss = JArray.Parse(item["access"]["items"].ToString());
                    if (arrayAccesss != null)
                    {
                        publicacion.access.items = new List<AccessItem>();
                        foreach (JObject reg in arrayAccesss)
                        {
                            AccessItem ai = new AccessItem();
                            ai.type = (reg["type"] != null ? reg["type"].ToString() : string.Empty);

                            publicacion.access.items.Add(ai);
                        }
                    }
                }

            }
            return publicacion;
        }

En la siguiente imagen podemos ver el aspecto del proyecto de ejemplo para WPF con todas las funciones incluidas en este artículo y en los anteriores.

googleplus_parte7_demowpf

En la librería portable smpClienteGooglePlus, también se incluyen otros métodos no explicados en esta serie de artículos, por este motivo vamos a hacer un resumen de las peticiones incluidas del HTTP API de Google Plus:

1. People:

a) get: smpGooglePlusApi.ObtenerPerfilAsync

b) search: smpGooglePlusApi.BuscarUsuariosAsync

c) listByActivity: smpGooglePlusApi.ObtenerUsuariosActividadAsync

d) list: smpGooglePlusApi.ObtenerAmigosAsync

2. Activities:

a) list: smpGooglePlusApi.ObtenerPublicacionesAsync

b) get: smpGooglePlusApi.ObtenerPublicacionAsync

c) search: smpGooglePlusApi.BuscarPublicacionesAsync

3. Comments:

a) list: smpGooglePlusApi.ObtenerComentariosAsync

b) get: smpGooglePlusApi.ObtenerComentarioAsync

4. Momments: Este punto lo tenemos pendiente, nos da constantemente error “Parse error” y además el simulador web de google tampoco funciona. Esperamos en breve ampliar esta librería para incluir los 3 métodos.

a) insert:

b) list:

c) delete:

En el siguiente enlace podéis descargar el código de ejemplo.