¿Cómo crear Timer Jobs en Sharepoint Online?

La forma de crear Timer Jobs en SharePoint Online es diferente a como se venían creando en las aplicaciones de granja en las versiones OnPremise.

No es posible crear soluciones usando el modelo de objetos de servidor, ni desplegar soluciones de granja que interactuen con la administración central. Es por esto que nos vemos en la necesidad de crear una solución que use el modelo de objetos cliente (CSOM) para simular el comportamiento que teníamos con los Timer Jobs tradicionales. Estas soluciones se programan y se implementan en un escenario externo a SharePoint, por lo que éste no es responsable de su ejecución.

Existen varias posibilidades para la creación de Jobs remotos en SharePoint Online:

  • Una de ellas, serían los WebJobs de Azure.
  • La otra, sería la creación de una aplicación de consola que se ejecute mediante una tarea programada de servidor para no tener la necesidad de tener un entorno de Azure habilitado. Esta posibilidad será en la que nos vamos a centrar en este post.

Pasos previos

Para poder interactuar con SharePoint Online desde una aplicación de consola usaremos el paquete de NuGet AppForSharePointOnlineWebToolkit. 

Una vez instalado el paquete, vemos que se han añadido todas las Dlls y clases necesarias para poder trabajar correctamente.

A continuación, tenemos que configurar nuestra aplicación de consola para que la conexión sea correcta. Para ello, editaremos el fichero App.config y añadiremos las entradas correspondientes a la URL del site, el nombre de la lista con la que vamos a interactuar, el ID del cliente y el secreto del cliente:

<add key=»SiteUrl» value=»Site>»/>

<add key=»ClientId» value=»db22d478-4a9b-461c-8240-616dd1cfbbe0″/>

<add key=»ClientSecret» value=»KoowtUu3tpdwSYo0WCczGTnAVyZpkIHOPcxd24KQefM=»/>

Para generar el ID del cliente y el secreto del cliente correcto para nuestra aplicación, accedemos a la página:

https:///_layouts/15/appregnew.aspx 

Pulsamos sobre «Generar» para obtener el ID del cliente y posteriormente sobre «Generar» para la Clave secreta del cliente.

Esos datos generados son los que incluiremos en la App.config de la aplicación de consola.

El siguiente paso será la configuración de los permisos de nuestra aplicación de consola para poder interactuar con SharePoint Online. Estos permisos los configuraremos en la URL:

https:///_layouts/15/appinv.aspx

En esta página de aplicación, añadiremos el ID de cliente generado anteriormente, pulsaremos «Buscar» para obtener la información de nuestra aplicación y poder configurar los permisos correctos.

Una vez añadidos los permisos, nos aparece la ventana de confirmación de nuestra aplicación, en la que nos indica qué permisos se van a otorgar:

Programación del Job

Ya tenemos nuestra aplicación de consola configurada correctamente para interactuar con SharePoint Online, posteriormente programaremos las acciones que va a realizar nuestro Timer Job. 

En este ejemplo, se va a comprobar si se ha creado un elemento en una lista en los últimos siete días. En caso de que se haya creado, se envía un correo al administrador del site.

static void Main(string[] args)

{

Uri siteUrl = new Uri(ConfigurationManager.AppSettings[«SiteUrl»]);

 

//Get the realm for the URL

string realm = TokenHelper.GetRealmFromTargetUrl(siteUrl);

 

//Get the access token for the URL

string accessToken = TokenHelper.GetAppOnlyAccessToken(TokenHelper.SharePointPrincipal, siteUrl.Authority, realm).AccessToken;

 

//Get client context with access token

using (var ctx =

TokenHelper.GetClientContextWithAccessToken(siteUrl.ToString(), accessToken))

{

DateTime startDate = DateTime.Now.Date;

DateTime endDate = DateTime.Now.AddDays(-7);

 

 

if (ListExists(ctx.Web, «ParteActividad»))

{

List listParteActividad = ctx.Web.Lists.GetByTitle(«ParteActividad»);

 

for (DateTime day = startDate; day >= endDate; day = day.AddDays(-1))

{

CamlQuery queryPersonaParteActividad = new CamlQuery();

queryPersonaParteActividad.ViewXml = «Scope=\»RecursiveAll\»><Query><Where><Eq><FieldRef Name=’Created’/><Value IncludeTimeValue=’False’ Type=’DateTime’>» + day.ToString(«yyyy-MM-ddTHH:mm:ssZ») + «</Value></Eq></Where></Query>»;

ListItemCollection collListItemPersonasParte = listParteActividad.GetItems(queryPersonaParteActividad);

ctx.Load(collListItemPersonasParte);

ctx.ExecuteQuery();

 

if (collListItemPersonasParte.Count > 0)

{

string htmlBodyInit = «Se ha creado un elemento el día » + day.ToShortDateString();

string htmlSubject = «Comprobación elemento»;

 

SendEmail(ctx, «administrador@bravent.net», htmlSubject, htmlBodyInit);

break;

}

 

}

}

}

}

 

public static void SendEmail(ClientContext ctx, string email, string htmlSubject, string htmlBody)

{

var emailp = new EmailProperties();

emailp.To = new List<string> { email };

emailp.Body = htmlBody;

emailp.Subject = htmlSubject;

Utility.SendEmail(ctx, emailp);

ctx.ExecuteQuery();

}

 

public static bool ListExists(Web web, string listTitle)

{

ListCollection lists = web.Lists;

IEnumerable<List> results = web.Context.LoadQuery<List>(lists.Where(list => list.Title == listTitle));

web.Context.ExecuteQuery();

List existingList = results.FirstOrDefault();

 

if (existingList != null)

{

return true;

}

 

emailp.Body = htmlBody;

emailp.Subject = htmlSubject;

Utility.SendEmail(ctx, emailp);

ctx.ExecuteQuery();

}

 

public static bool ListExists(Web web, string listTitle)

{

ListCollection lists = web.Lists;

IEnumerable<List> results = web.Context.LoadQuery<List>(lists.Where(list => list.Title == listTitle));

web.Context.ExecuteQuery();

List existingList = results.FirstOrDefault();

 

if (existingList != null)

{

return true;

}

 

return false;

}

Con la aplicación de consola creada, solo nos queda alojar la aplicación en el servidor donde se va a ejecutar y configurar la tarea programada para que se ejecute cuando lo necesitemos.

¡Y hasta aquí todo por hoy!

Esperamos que os haya gustado el post.

Si necesitáis ayuda o más información, podéis poneros en contacto con nosotros. 

Estaremos encantados de atenderos.

¡Feliz semana! 🙂