Ostatnio zainteresowałem się tematem w jaki sposób można stworzyć aplikację wykorzystującą popularny wśród programistów komunikator Slack. Zacząłem drążyć temat aż natknąłem się na framework o nazwie Bolt. Dzięki niemu jesteśmy w stanie naprawdę szybko stworzyć taką aplikację i to właśnie to chciałbym zaprezentować w tym artykule. Spróbujemy krok po kroku przejść przez taki proces korzystając przy tym z systemu Windows.

Aplikacja witająca użytkownika

Naszym celem będzie napisanie programu, który przekaże nam w komunikatorze wiadomość z naszym imieniem o ile zostanie ono podane. W innym przypadku poprosi nas o podanie imienia jako argumentu. Należy zacząć od utworzenia projektu, w moim przypadku będzie to projekt oparty o Maven. W pliku pom.xml musimy dodać niezbędne zależności.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
  ...

  <dependencies>
    <dependency>
      <groupId>com.slack.api</groupId>
      <artifactId>bolt</artifactId>
      <version>1.12.1</version>
    </dependency>
    <dependency>
      <groupId>com.slack.api</groupId>
      <artifactId>bolt-servlet</artifactId>
      <version>1.12.1</version>
    </dependency>
    <dependency>
      <groupId>com.slack.api</groupId>
      <artifactId>bolt-jetty</artifactId>
      <version>1.12.1</version>
    </dependency>
  </dependencies>
</project>

bolt oraz bolt servlet są niezbędne do działania naszej aplikacji. Natomiast jeżeli nie będziemy korzystali z żadnego innego webowego frameworka jak np. Spring Boot należy dodać jeszcze bolt-jetty. Dzięki niemu nasz program zostanie uruchomiony na serwerze HTTP o nazwie Jetty.

Teraz musimy napisać kawałek kodu, w którym utworzymy komendę wykorzystywaną w Slacku. Z tego powodu inicjalizujemy zmienną typu App i wywołujemy na niej metodę command przekazując nazwę komendy oraz jej obsługę w postaci lambdy. Następnie tworzymy obiekt SlackAppServer, aby uruchomić serwer HTTP.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
package pl.devcezz;

import com.slack.api.bolt.App;
import com.slack.api.bolt.jetty.SlackAppServer;

public class MyApp {

  public static void main(String[] args) throws Exception {
    var app = new App();

    app.command("/hello", (req, ctx) -> {
      String text = req.getPayload().getText();
      if (text != null && !text.isEmpty()) {
        return ctx.ack(
          ":tada: Yeah! Nice to meet you, " + text + "! :tada:"
        );
      } else {
        return ctx.ack("Please type your name. :sob:");
      }
    });

    var server = new SlackAppServer(app);
    server.start();
  }
}

Zabawa z ustawieniami

Skoro napisaliśmy kod naszej aplikacji teraz musimy ją jakoś uruchomić. Zanim to zrobimy należy ustawić wartości dla dwóch zmiennych środowiskowych: SLACK_SIGNING_SECRET oraz SLACK_BOT_TOKEN. Pierwszą z nich otrzymamy tworząc testowy workspace i rejestrując w nim aplikację. Logujemy się, więc do Slacka na stronie slack.com (użyłem do tego Google Auth) i klikamy ‘Create Another Workspace’. Jeżeli mamy zainstalowaną aplikację desktopową Slacka na Windowsie możemy przejść przez ten proces właśnie w niej lub wykorzystać do tego przeglądarkę.

Kroki tworzenia własnego workspace
Kroki tworzenia własnego workspace

Ekran po utworzeniu własnego workspace
Ekran po utworzeniu własnego workspace

Teraz możemy przejść do konfiguracji naszej aplikacji. Wchodzimy, więc na api.slack.com/apps, wybieramy przycisk ‘Create an App’, a następnie opcję ‘From scratch’. Podajemy nazwę aplikacji i wybieramy dla jakiego workspace ma ona zostać stworzona.

Wybieramy sposób konfiguracji naszej aplikacji
Wybieramy sposób konfiguracji naszej aplikacji

Przewijamy w dół do sekcji ‘App Credentials’. W niej znajdujemy niezbędny dla nas token o nazwie ‘Signing Secret’, wystarczy go sobie wyświetlić i skopiować.

Uzyskiwanie App Credentials

SLACK_BOT_TOKEN otrzymujemy natomiast wybierając na tej samej stronie co przed chwilą zakładkę ‘Install App’. Dostajemy informację, że musimy dodać chociaż jedno uprawnienie, aby zainstalować aplikację. Klikamy, więc w link ukryty pod słowami ‘permission scope’ i przechodzimy do sekcji ‘Scopes’. Tutaj dla ‘Bot Token Scopes’ dodajemy uprawnienie ‘chat:write’ i wracamy jeszcze raz do zakładki ‘Install App’. Teraz jesteśmy w stanie wybrać ‘Install to Workspace’. Na następnym ekranie zostaniemy poproszeni o nadanie uprawnień naszej aplikacji do stworzonego workspace. Potwierdzamy dzięki czemu uzyskamy token ‘Bot User OAuth Token’, który będzie wartością dla zmiennej środowiskowej SLACK_BOT_TOKEN .

Wymagane jest nadanie uprawnień, aby zainstalować aplikację do workspace
Wymagane jest nadanie uprawnień, aby zainstalować aplikację do workspace

Wybieramy jedno z dostępnych uprawnień
Wybieramy jedno z dostępnych uprawnień

Po instalacji aplikacji uzyskujemy niezbędny token
Po instalacji aplikacji uzyskujemy niezbędny token

Pora na uruchomienie aplikacji

Skoro nasza aplikacja korzysta z Maven to wykorzystajmy to. Otwórzmy konsolę i będąc w głównym katalogu naszej aplikacji Javowej wywołajmy następujące polecenia.

1
2
3
4
export SLACK_SIGNING_SECRET="$(slack signing secret)"
export SLACK_BOT_TOKEN="$(slack bot token)"

mvn compile exec:java -Dexec.mainClass="pl.devcezz.MyApp"

Dwa pierwsze wiersze ustawią nam niezbędne zmienne środowiskowe, które opisałem wcześniej. Następnie skompilujemy nasz kod wykorzystując Maven i uruchomimy naszą aplikację wskazując, gdzie znajduje się główna klasa. Po zaciągnięciu odpowiednich bibliotek aplikacja powinna uruchomić się prawidłowo.

Zalecane jest jeszcze, aby skorzystać z projektu ngrok. Dzięki niemu udało mi się wyłapać błąd 401 okazujący się mało intuicyjnym komunikatem ‘/hello failed with the error “dispatch_failed”’. W przypadku Windows musimy utworzyć konto na ngrok, ściągnąć wymagany zip, rozpakować go, wejść do utworzonego katalogu i w nim otworzyć konsolę. Następnie podajemy dwie komendy.

1
2
./ngrok authtoken $(ngrok token)
./ngrok http 3000

Instalacja ngrok
Instalacja ngrok

Uruchomienie ngrok
Uruchomienie ngrok

Wybraliśmy port 3000, ponieważ jest to domyślny port dla serwera Jetty. Przechodząc na stronę dashboard.ngrok.com/endpoints/status dostajemy adres URL, pod którym mapowany jest ‘localhost:3000’. Musimy go skopiować, aby jeszcze skonfigurować komendę obsługującą naszą aplikację. Należy zaznaczyć, że przy każdym uruchomieniu komendy ./ngrok http 3000 będziemy uzyskiwać nowe adresy URL. Ma to znaczenia dla ostatniego kroku.

Tunelowane endpointy w ngrok
Tunelowane endpointy w ngrok

Ustawienie komendy w Slack

Wracamy do ustawień aplikacji na stronie Slacka. Przechodzimy tym razem do zakładki ‘Slash Commands’ i wybieramy przycisk ‘Create New Command’. Konieczne jest podanie nazwy komendy, którą użyjemy w Slack, URL do obsługi żądania oraz opis. UWAGA! Przy podawaniu URL kopiujemy adres uzyskany z aplikacji ngrok i dodajemy jeszcze do niego ‘/slack/events’ na końcu.

Zakładka do tworzenia komenda Slacka
Zakładka do tworzenia komenda Slacka

W 'Request URL' podajemy adres uzyskany z ngrok zakończony '/slack/events'
W ‘Request URL’ podajemy adres uzyskany z ngrok zakończony ‘/slack/events’

Na koniec wchodzimy do zakładki ‘Install App’, wybieramy ‘Reinstall to Workspace’ i potwierdzamy. Warto tutaj podkreślić, że za każdym wywołaniem komendy ./ngrok http 3000 generowany jest nowy adres URL, który musimy podmienić w skonfigurowanej przed chwilą komendzie.

Jeżeli wszystko zadziała zgodnie z planem to przechodząc do Slacka i wpisując polecenie /hello powinniśmy dostać komunikat ‘Please type your name. 😭’. Jeżeli natomiast podany /hello DevCezz otrzymamy ‘🎉 Yeah! Nice to meet you, DevCezz! 🎉’.

Wynik działania funkcjonalności

W przypadku, gdy coś pójdzie nie tak możemy skorzystać dobrodziejstw ngrok. Przechodzimy pod adres http://localhost:4040/inspect/http w przeglądarce i możemy sprawdzić jakie odpowiedzi otrzymaliśmy od serwera Slacka. W moim przypadku, jak wspomniałem wcześniej, otrzymywałem błąd 401, ponieważ zapomniałem ustawić zmiennych środowiskowych wykorzystując polecenie export.

Gdy zmienne środowiskowe zostały ustawione od razu otrzymałem status 200
Gdy zmienne środowiskowe zostały ustawione od razu otrzymałem status 200

Podsumowanie

Uważam, że ta zabawa ma potencjał. Dzięki niej możemy stworzyć aplikację służącą do powiadamiania nas o jakiś wydarzeniach wykorzystując inny kanał wiadomości jakim jest popularny Slack. Istnieje również możliwość zamiany serwera Jetty na Spring Boot. Zachęcam do przestudiowania przykładu znajdującego się pod adresem slack.dev/java-slack-sdk/guides/getting-started-with-bolt, a dokładniej pod nagłówkiem ‘OK, What about Spring Boot?’. Możemy również wykorzystać API Slacka to stworzenia klienta zamiast aplikacji jak w tym wpisie, jednak to być może zostawię sobie na inny artykuł.