SharePoint Server ponuja native Timer Jobs, ki so inheritani iz SPJobDefinition razreda in se izvajajo v intervalih v SPSchedule objektu. V SharePoint Online tega ne moremo uporabljati. Lahko uporabljamo Windows Service/Task Scheduler za simulacijo Timer Jobsov v SP Online, ampak to vseeno ni kompletna cloud rešitev. Z uporabo Azure Functions lahko sedaj to dosežemo.
Imamo seznam dogodkov (ime dogodka + datum). Vsak dan hočemo preveriti, ali je že prišel dan določenega dogodka. Če je, hočemo obvestiti določeno osebo o temu. V spodnjem primeru vidimo, da moramo poslati obvestilo, da je potrebno spisati članek za PIKO.

Na Azure Portal gremo kreirati Azure Function app, ki bo vseboval kodo za implementacijo zgornje logike. Na Azure Portalu poiščite Function App ter dodate novega z naslednjimi lastnostmi:

Ko imamo kreiran Function App, lahko dodamo Timer Trigger – C# kot kaže spodnja slika. Funkcijo poimenujemo ExpiredDogodekIdentifier in nastavimo čas proženja (po defaultu je nastavljeno vsake 5 minut).


Preden vnesemo kodo za dostop do SP Online seznama, moramo uploadati SharePoint Client knjižnice, ki jih bo uporabljala naša koda. To storite preko Advanced tools (Kudu), kot prikazuje spodnja slika:

Preko Debug console Kudu menija izberete PowerShell. Pojdite v podmapo site/wwwroot/ExpiredDogodekIdentifier ter kreirajte novo mapo imenovano bin. Vanjo dodate naslednja dva dll-ja (drag-and-drop), ki ju najdete v mapi C:\Program Files\Common Files\microsoft shared\Web Server Extensions\16\ISAPI
- SharePoint.Client.dll
- SharePoint.Client.Runtime.dll
Tako lahko sedaj spišemo logiko naše Azure funkcije v run.csx datoteki:
#r "Microsoft.SharePoint.Client.Runtime.dll"
#r "Microsoft.SharePoint.Client.dll"
using System;
using System.Net;
using Microsoft.SharePoint.Client;
public static void Run(TimerInfo myTimer, TraceWriter log)
{
//vnesite Office365 username/password ali uporabite Azure Key Vault
string email = "{blank}@{blank}.onmicrosoft.com";
string password = "{blank}";
string webUrl = "https://{blank}.sharepoint.com/{blank}";
string listName = "Dogodki";
System.Security.SecureString securePassword = new System.Security.SecureString();
foreach (char pass in password) {
securePassword.AppendChar(pass);
}
// dobi uporabniške credentiale
SharePointOnlineCredentials spOnlineCredentials = newSharePointOnlineCredentials(email, securePassword);
try{
// kreiraj Client Context
using (var SPClientContext = new ClientContext(webUrl))
{
//poveži se na list in dobi expired elemente
SPClientContext.Credentials = spOnlineCredentials;
Web spWeb = SPClientContext.Site.RootWeb;
List spList = spWeb.Lists.GetByTitle(listName);
CamlQuery spQuery = new CamlQuery();
spQuery.ViewXml = "<View><Query><Where><Eq><FieldRef Name='Datum'/><Value Type='DateTime'><Today /></Value></Eq></Where></Query><RowLimit>100</RowLimit></View>";
ListItemCollection spListIems = spList.GetItems(spQuery);
SPClientContext.Load(spListIems);
SPClientContext.ExecuteQuery();
//Pošlji email za expired elementi
string emailBody = "<b>Naslednji dogodki so expired</b> </br><table style='border: 1px solid black;'>";
foreach (ListItem spListItem in spListIems)
{
emailBody += "<tr style='color:red;'><td><b>"+ spListItem["Title"] +"</b></td><td>"+spListItem["Datum"]+"</td></tr>";
}
emailBody += "</table>";
Microsoft.SharePoint.Client.Utilities.EmailProperties emailProperties = newMicrosoft.SharePoint.Client.Utilities.EmailProperties();
emailProperties.To = new string[] { email };
emailProperties.Subject = "Pozor : Expired dogodki";
emailProperties.Body = emailBody;
Microsoft.SharePoint.Client.Utilities.Utility.SendEmail(SPClientContext, emailProperties);
SPClientContext.ExecuteQuery();
log.Info($"Št. expired dogodkov: {spListIems.Count}");
}
}
catch(Exception ex){
log.Info($"Azure Function Exception: {ex.Message}");
}
}
Kodo poženete. Hkrati se vam v logu izpiše spodnje, na mail pa dobite vsebino expired dogodka.


Lep pozdrav!
Gašper Rupnik
{End.}

A fascinating debate is certainly price review. I do think that you should submit more about this topic, it may not be a taboo matter but usually people do not discuss these topics.