Push Notifications w SharePoint

Mateusz Chodkowski

Push Notifications w SharePoint
Lipiec 25, 2017 Katarzyna Sobczak

Push Notifications w SharePoint

Notyfikacje podbijają nasze urządzenia – aplikacje na telefony zasypują nas nimi codziennie, a strony internetowe coraz częściej proszą o umożliwienie im wypychania aktualizacji w formie notyfikacji. Chcąc iść z duchem czasu, można podobne rozwiązanie zaproponować klientom korzystającym z SharePoint. W tym celu posłużymy się językiem JavaScript.

Case study

Klient chce otrzymywać powiadomienia push wtedy, gdy na ważnych dla niego listach/bibliotekach dokumentów dojdzie do zmian (np. dodanie aktualności, dodanie nowego zadania, etc.). Powiadomienie ma się wyświetlić nawet jeśli użytkownik ma schowaną przeglądarkę lub jest na innej karcie.

Obostrzenia

Zakładamy, że użytkownicy korzystają z jednej z przeglądarek: Google Chrome, Opery, Firefox, lub Microsoft Edge. Niestety Internet Explorer nie wspiera notyfikacji push.

Realizacja

Będziemy potrzebowali trzech kluczowych składników, są to:

  1. Mechanizm notyfikacji
  2. ClientContext SharePointa
  3. Ciasteczka

Mechanizm będzie działał w bardzo prosty sposób. Co pewien czas będzie sprawdzał ostatnią datę modyfikacji na monitorowanej liście. Następnie porówna tą datę z datą zapisaną w ciasteczku. Jeżeli okaże się, że jest to nowa modyfikacja listy – zapisujemy w ciasteczku nową datę i wypychamy powiadomienie.

Mechanizm notyfikacji

Funkcja sendNotification przyjmie jako argumenty tekst do wyświetlenia w powiadomieniu, następnie adres URL, do którego przekieruje kliknięcie w powiadomienie, oraz adres obrazka, który będzie ikoną w powiadomieniu. Dodatkowo mamy tu także fragment Notification.requestPermission, który poprosi użytkownika o umożliwienie wyświetlania notyfikacji.


sendNotification: function (info, url, icon) {
    var notify = function (listName, url, icon) {
        var options = { icon: icon };
        var notification = new Notification(info, options);
        notification.onclick = function (event) {
            event.preventDefault(); 
            window.open(url, '_blank');
        };
    };
    // Sprawdzamy czy przeglądarka obsługuje powiadomienia.
    if (!("Notification" in window)) {
        alert("Ta przeglądarka nie obsługuje powiadomień, wypróbuj Google Chrome!");
    }
    // Sprawdźmy czy uprawnienia dla powiadomienia zostały nadane
    else if (Notification.permission === "granted") {
    // jeżeli są tworzymy powiadomienie
        notify(info, url, icon);
    }
    // W innym przypadku tworzymy zapytanie o uprawnienia
    else if (Notification.permission !== 'denied') {
        Notification.requestPermission(function (permission) {
        //Jeżeli użytkownik zaakceptuje tworzymy powiadomienie
        if (permission === "granted") {
            notify(info, url, icon);
        }
    });
    }
}

SharePoint ClientContext

W naszym rozwiązaniu wykorzystamy kontekst SharePointa aby wyciągnąć z listy datę ostatniej modyfikacji. Taką informację znajdziemy za pomocą funkcji get_lastItemModifiedDate().


var clientContext = new SP.ClientContext(siteUrl);
setInterval(function () {
  for (var i = 0; i < mcNotification.observedLists.length; i++) {
   let item = mcNotification.observedLists[i];
   let oList = clientContext.get_web().get_lists().getByTitle(item.listName);
   let x = clientContext.load(oList);
   clientContext.executeQueryAsync(function () {
    let lastmodified = oList.get_lastItemModifiedDate();
    item.lastDate = new Date(mcNotification.readCookie(item.listName));
    if (lastmodified > item.lastDate) {
     item.lastDate = lastmodified;
     mcNotification.eraseCookie(item.listName);
     mcNotification.createCookie(item.listName, item.lastDate, 3);
     mcNotification.sendNotification(item.textInfo, item.linkUrl, logo);
    }
   }, function (sender, args) {
    console.log('Request failed. ' + args.get_message() + '\n' + args.get_stackTrace());
   });
 }
}, refreshTime);

Ciasteczka

Do modyfikacji ciasteczek skorzystamy z poniższych metod. Można to oczywiście zrobić prościej, za pomocą biblioteki jquery-cookies, jednak pracując nad projektem postanowiłem, że będziemy unikać angażowania dodatkowych bibliotek.


createCookie: function (name, value, days) {
    var expires = "";
    if (days) {
        var date = new Date();
        date.setTime(date.getTime() + (days * 24 * 60 * 60 * 1000));
        expires = "; expires=" + date.toUTCString();
    }
    document.cookie = name + "=" + value + expires + "; path=/";
},
readCookie: function (name) {
    var nameEQ = name + "=";
    var ca = document.cookie.split(';');
    for (var i = 0; i < ca.length; i++) {
        var c = ca[i];
        while (c.charAt(0) == ' ') c = c.substring(1, c.length);
        if (c.indexOf(nameEQ) == 0) return c.substring(nameEQ.length, c.length);
    }
    return null;
},
eraseCookie: function (name) {
    mcNotification.createCookie(name, "", -1);
}

Dodatkowo, w widoku, który ma wysyłać notyfikacje (w moim wypadku default.aspx) musimy dodać kilka dodatkowych referencji.


/_layouts/15/MicrosoftAjax.js
/_layouts/15/sp.runtime.js
/_layouts/15/sp.js
/_Layouts/15/SP.RequestExecutor.js
    $(document).ready(function () {
        SP.SOD.executeFunc('sp.js', 'SP.ClientContext');
        currentContext = new SP.ClientContext.get_current();
    });
 </script>

Ostateczna wersja

Ostatecznie opakujemy to w pojedynczy obiekt i dodamy nieco sterowania. Finalna wersja skryptu znajduje się tutaj.

Jak widać, na samym końcu następuje rejestracja list, które będą monitorowane. Jako argumenty przekazujemy kolejno: nazwę listy, adres do którego ma przenosić powiadomienie oraz tekst powiadomienia.


mcNotification.registerList('Lista aktualności', "http://sp-matcho/SitePages/NewsArchive.aspx", "Zmiany w aktualnościach!");

mcNotification.registerList('Galeria', "http://sp-matcho/SitePages/Galeria.aspx", "Hura działa!");

W dalszej kolejności następuje uruchomienie całego rozwiązania, gdzie argumenty to kolejno: czas odświeżania, adres site’a na którym uruchamiamy skrypt i adres obrazka, który będzie wyświetlany razem z powiadomieniem.


mcNotification.run(1000, '/', "someicon.png");

Efekt końcowy

Podziel się

Autor: Mateusz Chodkowski

Mateusz Chodkowski

Mateusz-Chodkowski

Programista .NET i SharePoint, twórca aplikacji front-end i projektant procesów WEBCON BPS. Fascynatem programowania w .NET oraz JavaScript, projektant i entuzjasta cyfryzacji “papierowych” procesów biznesowych, a prywatnie miłośnik historii oraz rysunku.

Zespół: Apps

Ostatnie artykuły autora

Migracja archiwalnych skanów umów do nowego procesu WEBCON BPS

Migracja archiwalnych skanów umów do nowego procesu WEBCON BPS

Cyfryzacja papierowych procesów, poza licznymi zaletami, wiąże się również z wyzwaniami, takimi jak migracja archiwalnych danych. Co zrobić z archiwalnymi danymi? Jak w prosty sposób migrować archiwalne dane do procesu WEBCON BPS?

Proces modyfikacji wzorca do generowania dokumentów w WEBCON BPS

Proces modyfikacji wzorca do generowania dokumentów w WEBCON BPS

W artykule omówiono kwestię podmiany wzorców, na podstawie których procesy WEBCON BPS generują pliki. Rozwiązanie to pozwala na wykonanie takiej czynności ręcznie, jednak można zautomatyzować ten proces i dodać do niego element kontroli.

Niestandardowe wykresy w WEBCON BPS

Niestandardowe wykresy w WEBCON BPS

Artykuł porusza problem skomplikowanych raportów na podstawie danych z procesów WEBCON BPS. Rozwiązanie Business Process Suite pozwala na szybkie „wyklikanie” wykresów jako elementów strony SharePoint. Co jednak zrobić, gdy klient wymaga bardziej szczegółowego rozwiązania?

Skontaktuj się z Mateuszem

 

Administratorem danych gromadzonych z wykorzystaniem formularza jest A.P.N. Promise S.A. Podane przez Ciebie dane będą przetwarzane w zakresie niezbędnym do podjęcia kontaktu lub realizacji określonego żądania zgodnie z art. 6 ust. 1 lit. b RODO przez okres niezbędny dla realizacji Twojego zgłoszenia. Wszelkie informacje w zakresie przetwarzania podanych przez Ciebie w formularzu danych oraz posiadanych uprawnieniach znajdziesz w Polityce prywatności. Kliknij i dowiedz się więcej jeżeli informacje podane powyżej nie są dostatecznie jasne!