SharePoint Designer Splash Screen

Dłuższy czas temu zostałem poproszony o przemyślenie możliwości zbudowania mechanizmu do notyfikowania pracowników aplikacji zbudowanej na SharePoint 2013 o zmianach w niej wprowadzanych. Jednak, nie chodziło o używanie alertów, czy też tworzenie dedykowanego rozwiązania. Klientowi chodziło o coś w rodzaju newslettera, którym mógłby wysyłać wiadomości w formacie HTML do wybranych użytkowników lub grup użytkowników swojej aplikacji i ogólnie mających dostęp i konta w SharePoint (ale również i z poza organizacji).

Ponieważ klient nie miał budżetu na inwestowanie w rozwiązania firm trzecich wybór dość naturalnie padł na tandem: pudełkowe możliwości SharePoint 2013 i workflow napisany w SharePoint Designer 2013, operujący na możliwościach platformy Workflow 2013 (skonfigurowany był Workflow Manager).

Przygotowania

Na początku przygotowałem dwie listy SharePoint, w dedykowanej witrynie zespołu:

  1. Newslettery, zbudowana z kolumn:
    1. Tytuł wiadomości (Title, tekst, wymagane)
    2. Treść wiadomości (Body, wiele linijek tekstu, włączona opcja formatowania HTML, wymagane)
  2. Skrzynka nadawcza, zbudowana z kolumn:
    1. Nazwa wysyłki/ kampanii (Title, tekst, wymagane)
    2. Odbiorcy SP (Recipients_SP, Osoba lub grupa, możliwe grupy, wielokrotny wybór)
    3. Odbiorcy Email (Recipients_EMAIL, wiele linijek tekstu, sam tekst)
    4. Data wysyłki (SendDate, data i czas, wymagane)
    5. Testowa wysyłka (TestDelivery, true/false)
    6. Wysłano (IsSent, true/false)
    7. Newsletter do wysłania (Newsletter, lookup do listy Newslettery, wymagane)

Dodatkowo, w trakcie analizy potencjalnych kroków, jakie workflow będzie wykonywać zauważyłem, iż konieczne będą operacje na ciągach znaków. W szczególności dlatego, że wstawianym w polu „RichHTML” obiekty, jak obrazy, SharePoint zmienia ścieżkę z bezwzględnej, na względną. Wyświetlenie takich obrazów w aplikacji do odczytywania emaili tym samym byłoby niemożliwe. Stąd konieczność użycia akcji „Replace Substring in a String”. Drugą kwestią była konieczność dzielenia ciągu znaków, wg zadanego znaku podziału, na kolekcję, ponieważ możliwe było podanie wielu odbiorców, rozdzielonych średnikiem. Tym samym zdecydowałem się na wykorzystanie zestawu akcji „Plumsail – String processing„, która rozszerza akcje SPD o szereg dodatkowych, służących operacjom na stringach.

   Pamiętaj, że to rozwiązanie nie może zastąpić aplikacji do wysyłki masowej. Ma służyć notyfikacji wąskich grup odbiorców. Wysyłane przez opisywane rozwiązanie wiadomości są przetwarzane przez serwer Exchange i mogą podlegać throttling, czy wręcz być wycinane z uwagi na zabezpieczenie maszyny przed przeciążeniem.

Workflow

Celem workflowu było symulowanie działania timerjoba, który uruchomi się co określoną liczbę minut, sprawdzi listę Wysyłek i dla wszystkich niewysłanych jeszcze wiadomości, których data wysyłki jest starsza lub równa dacie bieżącej, rozpocznie rozsyłanie wiadomości. Z grubsza tyle 🙂

Ponieważ workflow miał operować na całej liście wysyłek, dodatkowo pauzować się i uruchamiać co określony czas uznałem, iz najlepszy ku temu będzie przepływ pracy witryny. Dodatkowo, z uwagi na konieczność używania wywołań REST do listy wysyłek oraz do listy userinfo wybrałem platformę SharePoint 2013 Workflow.

Jak wygląda rozwiązanie krok, po kroku? Sam workflow jest dość długi, zawiera wiele akcji i operacji. Jego obraz w Visio wygląda jak poniżej:

SharePoint Designer Newsletter Workflow

Krok 1 – zmienne inicjujące

Naturalnie nie jest to konieczne. Można te informacje na sztywno zaszyć w definicji przepływu, jednak chciałem zrobić rozwiązanie generyczne, które będzie działać dla różnych klientów. W chwili pierwszego uruchomienia przepływ pracy wymaga podania następujących danych:

  1. AllowExternalEMails – ogólnie, czy ma mieć możliwość wysyłania wiadomości do odbiorców spoza organizacji.
  2. OrganizationDomain – domena adresów email organizacji – by umieć odróżnić mail zewnętrzny od własnego.
  3. RunInterval – co ile minut ma być sprawdzana lista wysyłek.
  4. SendOlderThan – data graniczna pierwszego uruchomienia joba.
  5. SiteCollectionAbsoluteURL – bezwzględny adres URL głównej kolekcji witryn aplikacji (rozpoczynający się od http). Np.: http://root/sites/nazwa_witryny.
  6. SiteCollectionRelativeURL – względny adres URL głównej kolekcji witryn aplikacji (rozpoczynający się od /). Np.: /sites/nazwa_witryny.
  7. SiteURL – względny adres URL witryny, w której działa timerjob newslettera (rozpoczynający się od /). Np.: /podwitryna.

Krok 2 – timer

To pierwszy etap procesu. Dodaje wskazany w zmiennej „RunInterval” czas do daty pierwszego uruchomienia i czeka, aż data nadejdzie. Do tego etapu proces wraca za każdym razem, gdy wykona wszystkie, pozostałe zadania.

Krok 3 – zebranie listy wysyłek

Workflow, korzystając z akcji zapytania REST, odpytuje listę wysyłek o wszystkie elementy, których data wysyłki jest starsza lub równa bieżącej dacie oraz nie zostały jeszcze wysłane. W tym celu korzysta z następującego zapytania:

[%Parameter: SiteCollectionRelativeURL%][%Parameter: SiteURL%]/_api/web/Lists/GetbyTitle('Outbox')/items?$filter=((Send_date%20le%20datetime'[%Parameter: SendOlderThan%]')%20and%20(Sent%20eq%200))

Następnie, dla każdego, znalezionego rekordu, wykonywane są poniższe kroki.

Krok 4 – parametry i dane wysyłki

Workflow pobiera informacje o wysyłce: tytuł, czy testowa, id powiązanego newslettera. Następnie pobiera z listy Newsletterów, korzystając ponownie z zapytania REST, dane powiązanej wiadomości. Z tak pobranej wiadomości odczytuje Tytuł i Treść. Następnie przetwarza Treść:

Process newsletter's Body using SharePoint Designer

Tak, jak napisałem powyżej, wstawianym w polu „RichHTML” obrazom SharePoint zmienia ścieżkę z bezwzględnej, na względną (robi to również dla łączy), wobec czego konieczne jest użycie akcji „Replace Substring in a String” w celu ponownej zamiany adresów na bezwzględne.

Następnie, w zależności od tego, czy wysyłka jest testowa, czy nie, przechodzi do odpowiedniego etapu.

Krok 5 – wysyłka testowa

Jeśli wiadomość oznaczona jest jako wysyłka testowa, wówczas proces przygotowuje wiadomość e-mail i wysyła ją do użytkownika, który zlecił wysyłkę (CreatedBy), jednak wcześniej odpytuje listę UserInfo, poprzez api REST, o dane użytkownika, by poznać jego adres e-mail.

Po zakończonej wysyłce oznacza ją jako „Wysłaną”.

Krok 6 – przygotowanie do wysyłki produkcyjnej

Etap zaczyna się od odczytania listy odbiorców z pola „Recipients_SP”. Następnie, dla każdego rekordu odpytuje listę UserInfo i próbuje, z otrzymanej odpowiedzi, pobrać adres e-mail i typ zawartości:

Calling UserInfo list from SharePoint Designer workflow

Następnie sprawdza, czy wartość pobrana z pola adres email jest niepusta oraz, czy typ zawartości odpowiada elementowi typu „User” –  nazwa zaczyna się od „0x010A” (źródło).

Jeśli jednak nazwa typu zawartości zaczyna się od „0x010B” – oznacza to, że przetwarzany rekord to grupa SharePoint. W takim wypadku proces „otwiera grupę” – z interfejsu REST odbiera wszystkich jej członków i dla każdego członka ponownie RESTem odczytuje adres e-mail.

   Proces dodaje każdy, znaleziony adres e-mail do zmiennej tekstowej, rozdzielając je znakiem „;”.

Na koniec łączy adresy email z adresami podanymi w polu „Recipients_EMAIL” i finalnie rozdziela przygotowany ciąg adresów e-mail korzystając z akcji Plumsail „Split string” i zapisuje do słownika.

Krok 7 – usuwanie duplikatów

Aby dany odbiorca nie otrzymał wiadomości dwukrotnie (np. raz gdy został dodany jako odbiorca, drugi raz przez fakt obecności w grupie użytkowników SP), proces pobiera kolejny rekord ze słownika, sprawdza czy taki już istnieje w finalnym słowniku odbiorców i jeśli nie – dodaje go tam. Jeśli istnieje, przechodzi do kolejnego rekordu ze słownika.

Krok 8 – wysyłka produkcyjna

Finalnie proces przechodzi do wysyłki produkcyjnej. Dla każdego adresu ze słownika wykonuje tę samą operację – składa wiadomość e-mail i korzystając z akcji „Email” wysyła do wskazanego odbiorcy. Sprawdza przy tym, czy istnieje zgoda na wysyłkę wiadomości do odbiorców z zewnątrz. Jeśli nie – adresy mailowe spoza domeny pomija.

Po zakończeniu wysyłki do odbiorców oznacza element na liście „Wysyłki” jako „Wysłany” i powraca do kroku 1, czyli czekania na kolejne uruchomienie.

Uruchomienie

Teraz pozostaje już tylko przejść do przepływów pracy witryny i uruchomić tak przygotowany proces:

Newsletter TimerJob - first run

Po wypełnieniu parametrów i kliknięciu „Start” workflow zaczyna przetwarzać informacje i szukać newsletterów do wysyłki, które dostarczy wprost do skrzynki:

Newsletter sent by the Newsletter TimerJob

   Pamiętaj, że w SharePoint Online nie istnieje możliwość wysłania wiadomości e-mail do użytkowników zewnętrznych, przez przepływ pracy na platformie SharePoint Workflow 2013. Jest to możliwe wyłącznie przy użyciu platformy SharePoint Workflow 2010.

Podoba Ci się to rozwiązanie? Chciałbyś dowiedzieć się więcej lub użyć go u siebie? Zostaw info w komentarzu lub od razu skontaktuj się ze mną!

 

 

 

Cześć! Nazywam się Tomasz. Jestem wielkim fanem automatyzacji procesów i analizy biznesowej. Skupiam się na rozwijaniu moich umiejętności w pracy z produktami Nintex i Microsoft: w szczególności Office 365, SharePoint. Posiadam ponad 8 lat doświadczenia w pracy z SharePoint.