Notificaciones a Aplicaciones Windows Phone desde SharePoint Parte I

Escrito por Adrian Diaz Cervera - 21/11/2012

Una de las nuevas características que introduce SharePoint 2013 es que permite a los dispositivos móviles registrarse en nuestra aplicación. Una vez registrado el dispositivo se puede escribir código de controlador de eventos para interactuar con el servicio de notificaciones push de Microsoft (MPNS o Microsoft Push Notifications Service) o con servicios de notificación de otras plataformas de dispositivos móviles.      

Una de las características de los móviles con WP es que tienen un servicio de notificaciones Push, que permite que cualquier aplicación externa pueda comunicarse con este servicio y de esta forma mostrar un aviso a nuestra aplicación tal y como se muestra en esta figura.

 

Existen tres tipos de notificaciones que podemos utilizar en los dispositivos con Windows Phone 7.5 (en la versión 8 se han añadido más tipos de notificaciones):

Notificaciones Toast: Es aquella que se muestra ocupando la parte superior de la pantalla, con un color de fondo igual al color de resaltado del dispositivo. Se compone de tres elementos:

·Titulo: Texto en negrita que se muestra justo a continuación del icono de la aplicación y se establece en la propiedad Text1 del elemento del esquema XML.

·Subtitulo: Texto sin negrita mostrado después del titulo y establecido por la propiedad Text2 del esquema XML.

·Parámetro: Un parámetro que no será mostrado pero será enviado a la aplicación cuando el usuario presione la notificación Toast, definido en la propiedad Param del esquema XML.

Notificaciones Tile: Actualiza el Live Tile para la aplicación en la pantalla de inicio del teléfono, cambiando el gráfico, el título del mosaico, y el contador numérico en el mosaico. Son recibidas incluso si la aplicación está ejecutando. Al trabajar con notificaciones Tile debemos tener en cuenta las siguientes restricciones:

·A ser posible usaremos locales y no remotas para los tiles, de esta forma reduciremos el consumo de transferencia y evitaremos retardos al enviar imágenes con la notificación.

·Las imágenes para los tiles deben estar en formato png o jpg.

·No está soportado HTTPS para imágenes remotas.

·El tamaño máximo de imagen remota es de 80KB, si la imagen tiene un tamaño será descartada y no se descargará.

·Si por alguna razón la imagen frontal o trasera falla al descargarse, ninguna de las demás propiedades se establecerá.

Notificaciones RAW(o en bruto): Nos permite enviar información a nuestra aplicación para que este la procese y use. No es un tipo de notificación para mostrar directamente al usuario, como lo son las notificaciones Toast y Tile. Este tipo de notificación nos permite enviar información a nuestra aplicación de cualquier tipo, otorga mayor flexibilidad que los tipos anteriores, porque no estamos obligados a usar unos campos concretos.

Para hacer mas ameno la explicación vamos a ponernos en un ejemplo mas o menos real, tenemos en un servidor SharePoint donde tenemos la información de los números de Compartimos, así como los artículos que hay en la revista. En base a estos datos tenemos una aplicación Windows Phone en la que se visualiza esta información y recibe las notificaciones cada vez que sale un nuevo número de la revista.

Manos a la obra

 

En primer lugar, vamos a realizar la parte que tenemos que implementar en la nueva versión de nuestro servidor favorito.

Para permitir que en el sitio puedan subscribirse los dispositivos móviles para poder recibir las notificaciones que se producen en los eventos del sitio tenemos que activar esta característica:

 

Esta característica la podemos activar con el siguiente código en C# añadido en el momento que activamos nuestra característica y de esta forma siempre que despleguemos nuestra solución tendremos activada la característica y nos olvidamos de problemas (para mi esta es la opción adecuada):

 

spWeb.Features.Add(new Guid(PushNotificationFeatureId), false);

 

A continuación partimos que tenemos dos listas en SharePoint:
Revista esta compuesta por estas tres columnas:
  • Titulo: donde se guarda el titulo de este número de la revista
  • Fecha: de publicación de la revista
  • Imagen: Donde almacenamos la caratula de la revista
  • Número de artículos
Articulo esta compuesta por tres columnas:
  • Titulo : donde se guarda el titulo del artículo
  • Autor: persona que ha escrito el artículo en la revista     
  • Contenido: En este campo es de tipo multi línea y en el que esta almacenado el desarrollo del artículo.
  • Revista de tipo Lookup donde indicamos en que número de la revista se ha publicado este artículo.
Nuestra intención es que cada vez que se agregue un elemento a lista Revista dentro de nuestra aplicación se envié:
  • una notificación Toast en la que se indique que ha salido un nuevo ejemplar de nuestra revista.     
  • una notificación Tile en el que le enviaremos la nueva portada de la Revista, asi como el número de artículos que la componen.
  • una notificación Raw que la utilizara la aplicación Windows Phone internamente para tareas de administración interna.
Para crearnos las listas bien la podemos hacer de dos formas con la interfaz de usuario de SharePoint o mediante programación como por ejemplo el siguiente código para crear la lista Articulo:

 

internal void CreateListArticulo(SPWeb spWeb)

{

string listTitle = "Articulos";

string listDescription = "Lista donde están los articulos publicados en la revista CompartiMOSS.";

 

Dictionary<string, SPFieldType> columns = new Dictionary<string, SPFieldType>();

columns.Add("Autor", SPFieldType.Text);

columns.Add("Contenido", SPFieldType.Note);

 

Guid listId = spWeb.Lists.Add(listTitle, listDescription, SPListTemplateType.GenericList);

SPList list = spWeb.Lists[listId];

SPView view = list.DefaultView;

 

foreach (string key in columns.Keys)

{

list.Fields.Add(key, columns[key], false);

view.ViewFields.Add(key);

}

 

list.Update();

view.Update();

}

 

Una vez ya tenemos las listas creadas, abrimos un proyecto SharePoint 2013 en blanco. Agregamos una clase Notificacion en la que nos vamos a crear los métodos que se encargaran de enviar las notificaciones a los dispositivos Windows Phone subscritos a nuestra lista.
 
Creamos un procedimiento que se va a encargar de enviar las notificaciones. La principal novedad es que vamos a utilizar una variable de tipo SPPushNotificationSubscriber este tipo de variable es una de las novedades del modelo de objetos de SP2013. Lo importante de este tipo de variables es que tienen almacenado la dirección Uri donde tenemos que enviar la notificación. Este procedimiento es valido para los tres tipos de notificaciones en base a que tipo de notificación pondemos un valor distinto en la variable “notificationType”. Dependiendo de que tipo de notificación sea, la variable message tendrá una estructura de XML diferente

 

/// <summary>  

/// Procedimiento para enviar la notificación WP

/// </summary>

/// <param name="notificationType">Tile = 1, Toast = 2, Raw = 3</param>

/// <param name="subscriber"></param>

/// <param name="message">Mensaje de la notificacion</param>

/// <param name="intervalValue">Intervalo para esperar la notificacion</param>

/// <returns></returns>

private void SendPushNotification(NotificationTypeEnum notificationType, SPPushNotificationSubscriber subscriber, string message, int intervalValue)

{

// Creamos un objeto HTTP Web Request que es el encargado de comunicar.

string subscriptionUri = subscriber.ServiceToken;

HttpWebRequest sendNotificationRequest = (HttpWebRequest)WebRequest.Create(subscriptionUri);

 

// MPNS espera un vector de bytes por lo que lo codificamos el mensaje.

byte[] notificationMessage = Encoding.Default.GetBytes(message);

 

 

//Establecemos las propiedad del HTTPRequest para enviar la notificación

sendNotificationRequest.Method = WebRequestMethods.Http.Post;

sendNotificationRequest.ContentLength = notificationMessage.Length;

sendNotificationRequest.ContentType = "text/xml";

sendNotificationRequest.Headers.Add("X-MessageID", Guid.NewGuid().ToString());

 

switch (notificationType)

{

case NotificationTypeEnum.Tile:

sendNotificationRequest.Headers.Add("X-WindowsPhone-Target", "token");

break;

case NotificationTypeEnum.Toast:

sendNotificationRequest.Headers.Add("X-WindowsPhone-Target", "toast");

break;

case NotificationTypeEnum.Raw:

// En el caso de las notificaciones Raw no se especifica ningún tipo de cabecera.

break;

}

 

sendNotificationRequest.Headers.Add("X-NotificationClass", intervalValue.ToString());

 

 

using (Stream requestStream = sendNotificationRequest.GetRequestStream())

{

requestStream.Write(notificationMessage, 0, notificationMessage.Length);

}

 

try

{

//Enviamos la notificación, en un caso real esperaríamos la respuesta y bien la almacenamos en alguna lista o tomamos alguna determinación como volver a enviar la notificación.

HttpWebResponse response = (HttpWebResponse)sendNotificationRequest.GetResponse();

 

 

}

}   

 

A continuación en esta clase vamos a añadirle el procedimiento PushToast, que será el que invoquemos para enviar la notificación al móvil. Este procedimiento va a generar la estructura del XML que tenemos que enviar, tiene tres valores que hay que rellenar Text1, donde en nuestro caso estará el titulo del articulo, Text2 que en nuestro caso pondremos el nombre de la persona que ha escrito el articulo, y en la parte del Param la vamos a dejar en blanco (generalmente en el param se pone una pagina que se quiera mostrar cuando en el dispositivo móvil)..

 

public void PushToast(SPPushNotificationSubscriber subscriber, string toastTitle, string toastMessage,

string toastParam, ToastIntervalValuesEnum intervalValue)

{

string toastNotification = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +

"<wp:Notification xmlns:wp=\"WPNotification\">" +

"<wp:Toast>" +

"<wp:Text1>" + toastTitle + "</wp:Text1>" +

"<wp:Text2>" + toastMessage + "</wp:Text2>" +

"<wp:Param>" + toastParam + "</wp:Param>" +

"</wp:Toast> " +

"</wp:Notification>";

 

SendPushNotification(NotificationTypeEnum.Toast, subscriber, toastNotification, (int)intervalValue);

}

 

También añadiremos un procedimiento PushTile que como parámetros tiene los siguientes: Imagen de Fondo, Contador, Titulo, Imagen de Fondo Trasera y Titulo de fondo.

 

public void PushTile(SPPushNotificationSubscriber subscriber, string tileFrontal, string tileImagenF, string tileContador,string tileTrasero,

string tileImagenT,string tileContenido, ToastIntervalValuesEnum intervalValue)

{

// Construct toast notification message from parameter values.

string tileNotification = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +

"<wp:Notification xmlns:wp=\"WPNotification\">" +

"<wp:Tile>" +

"<wp:BackgroundImage>" + tileImagenF + "</wp:BackgroundImage>" +

"<wp:Count>" + tileContador + "</wp:Count>" +

"<wp:Title>" + tileFrontal + "</wp:Title>" +

"<wp:BackBackgroundImage>" + tileImagenT + "</wp:BackBackgroundImage>" +

"<wp:BackTitle>" + tileTrasero + "</wp:BackTitle>" +

"<wp:BackContent>" + tileContador + "</wp:BackContent>" +

"</wp:Tile> " +

"</wp:Notification>";

 

return SendPushNotification(NotificationTypeEnum.Toast, subscriber, tileNotification, (int)intervalValue);

}

 

Finalmente añadiremos un procedimiento PushRaw donde no se establece ningún tipo de parametrización, le enviaremos un mensaje con la estructura que nosotros queramos. Va a ser una notificación interna que se utiliza para labores internas en la aplicación móvil.

 

public void PushRaw(SPPushNotificationSubscriber subscriber, string rawMessage, RawIntervalValuesEnum intervalValue)

{

return SendPushNotification(NotificationTypeEnum.Raw, subscriber, rawMessage, (int)intervalValue);

}

 

A continuación a nuestro proyecto le añadimos un EventReceiver (Receptor de Eventos), seleccionamos una Lista Personalizada y seleccionamos el evento de añadir un elemento en una lista.
 
Implementamos el siguiente código consulta todos los dispositivos móviles que están subscritos en este sitio y a cada dispositivo le envía una notificación con los datos que acabamos de añadir en la lista.

/// <summary>

/// Cuando añadimos un elemento a la lista.

/// </summary>

public override void ItemAdded(SPItemEventProperties properties)

{

SPWeb spWeb = properties.Web;

SPPushNotificationSubscriberCollection pushSubscribers = spWeb.PushNotificationSubscribers;

PushNotification pushNotification = new PushNotification();

 

SPListItem listItem = properties.ListItem;

 

 

string titleRevista = listItem["Title"].ToString();

string fechaRevista = listItem["Fecha"].ToString();

string imagenRevista = listItem["Imagen"].ToString();

string contadorRevista = listItem["contador"].ToString();

 

 

foreach (SPPushNotificationSubscriber ps in pushSubscribers)

{

// Envio de notificaciones Toast pushNotification.PushToast(ps,titleRevista, fechaRevista, string.Empty, ToastIntervalValuesEnum.ImmediateToast);

// Envio de notificaciones Tile

pushNotification.PushTile(ps,titleRevista, string.Empty,imagenRevista, contadorRevista, string.Empty, string.Empty ToastIntervalValuesEnum.ImmediateTile);

//Envio de notificaciones Raw

pushNotification.PushRaw(ps,titleRevista, "Nuevo Numero" , ToastIntervalValuesEnum.ImmediateRaw);

 

 

}

base.ItemAdded(properties);

}

.

¿Como enviar las notificaciones en SharePoint2010 ?

Tal y como habéis visto con anterioridad, en la nueva versión de SharePoint el gran beneficio que tiene es que se almacena internamente los dispositivos que están subscritos a nuestras listas, que esto no es más que hay una lista oculta en el que se almacena esta información. Por lo tanto el primer paso para empezar es crearnos una lista “Subscriptores” que solo va a tener dos campos Guid y ChannelUri (el Guid para tener un control de los dispositivos que tenemos almacenados y el ChannelUri para tener la dirección a la cual enviamos la notificación).

El siguiente paso al igual que en SharePoint 2013 es crearnos una clase PushNotificacion, la única diferencia es que no vamos a utilizar las variables de tipo SPPushNotificationSubscriber y las vamos a sustituir por cadenas de tipo string(lo único que necesitamos para enviar la notificación es la dirección URI). El código resultante quedaría de la siguiente forma:

 

 

private void SendPushNotification(NotificationTypeEnum notificationType, string subscriber, string message, int intervalValue)

{

// Creamos un objeto HTTP Web Request que es el encargado de comunicar.

HttpWebRequest sendNotificationRequest = (HttpWebRequest)WebRequest.Create(subscriber);

 

El resto del código a implementar es exactamente igual.
 
Una vez ya tenemos implementada la clase PushNotification, añadimos un eventReceiver (del mismo tipo que en el sitio de 2013), y ahora lo que tenemos que implementar es el funcionamiento del objeto “SPPushNotificationSubscriberCollection” que no es más que consultar las direcciones URI que tenemos almacenada en la lista de subscriptores para hacerlo en 2010- Una vez tenemos los subscriptores les enviamos la notificación a los dispositivos vinculados. Aquí está el código que implementa esta acción:
 

       public override void ItemAdding(SPItemEventProperties properties)

       {

           base.ItemAdding(properties);

 

 

           List<stringSubscripterGetListSubscriptores(properties);

          SPListItem listItem = properties.ListItem;

 

 

            string titleRevista = listItem["Title"].ToString();

string fechaRevista = listItem["Fecha"].ToString();

string imagenRevista = listItem["Imagen"].ToString();

string contadorRevista = listItem["contador"].ToString();

 

           foreach (string UriSubcripcion in Subscripter)

           {

                // Envio de notificaciones Toast 

                pushNotification.PushToast(UriSubcripcion,titleArticulo, autorArticulo, string.Empty, ToastIntervalValuesEnum.ImmediateToast); 

// Envio de notificaciones Tile

pushNotification.PushTile(UriSubcripcion,titleRevista, string.Empty,imagenRevista, contadorRevista, string.Empty, string.Empty ToastIntervalValuesEnum.ImmediateTile);

//Envio de notificaciones Raw

pushNotification.PushRaw(UriSubcripcion,titleRevista, "Nuevo Numero" , ToastIntervalValuesEnum.ImmediateRaw);

  

           }                      

       }

  /// <summary>

        /// Devuelve las direcciones de los dispositivos subscriptos

        /// </summary>

        /// <param name="properties"></param>

        /// <returns></returns>

       private List<string> GetListSubscriptores(SPItemEventProperties properties)

       {

           List<stringresultado = new List<string>();

           foreach (SPListItem item in properties.Web.Lists["Subscriptores"].GetItems())

           {

               resultado.Add(item["ChannelUri"].ToString());

           }

           return resultado;

       }

 

Resumen

En este artículo hemos visto una de las grandes novedades que trae consigo SharePoint2013 y es como enviar notificaciones a dispositivos moviles que estan subscritos a estas listas de SharePoint. De la misma forma hemos visto como es relativamente utilizar las listas de Sharepoint en Windows Phone y otorgarle un plus de interacción con el usuario, algo que esta moda esta con la llegada de los nuevos productos de Microsoft.

A su vez tambien es visto como a pesar de todas estas mejoras en SharePoint 2013 no es mas que una evolución de SharePoint2010, en la que mejora muchas cosas, pero esto no impide que se puedan hacer, aunque para ello es necesario realizar unas pequeñas modificaciones. Muchos de nosotros nos va a tocar pelearnos durante un cierto tiempo con la versión 2010 y siempre es muy util obtener todas las mejoras posibles y que esten adaptadas a las necesidades del usuario final de la aplicación.

Para el siguiente número dejamos la parte de como implementar la aplicación Windows Phone tanto en su versión 7.5 como en la recientemente liberada 8, un paso más para hacer el circulo cada vez más estrecho y más sencillo para el desarrollador con lo cual siempre se puede ofrecer un mejor producto al cliente final.

Referencias

Novedades de los dispositivos móviles (SharePoint 2013 Preview)

How to: Configure and use push notifications in SharePoint 2013 apps for WindowsPhone

 

Adrián Díaz Cervera
MCPD SharePoint 2010
Microsoft Active Professional 2012
***