Wir bei b-nova haben für unsere interne Kommunikation das bekannte Slack im Einsatz. Slack ist nicht nur für den direkten Austausch gut, sondern kann über eine strukturierte Administration mithilfe von Channels und Features die Arbeit koordinieren und über aktuelle Zustände informieren. So werden zum Beispiel automatisch und zentral in einer einzigen App Status-Meldungen einer laufenden CI/CD-Pipeline dargestellt oder spezifische Alerts an die entsprechenden Zielgruppen ausgelöst. Nichtsdestotrotz sind gewisse Inputs von Hand nötig und erfordern dabei nicht selten kurzfristig intensive Copy-/Pasting-Sessions. Dadurch bin ich auf die Idee gekommen diese immer wiederkehrende, repetitive Tasks mit einem Slackbot zu automatisieren. Nach einer kurzen Suche bin ich auf einen Guide gestossen, welcher mithilfe von Kotlin und Kotr einen Slackbot auf Heroku bereitstellt. Kotlin ist dafür bestens geeignet und habe dadurch kurzerhand einen Slackbot damit geschrieben. Hier zeige ich Ihnen wie das geht.
Die Anforderungen an den Bot
Der Bot ist ganz simpel gestrickt. Er stellt einen GET-Endpunkt als Webservice zur Verfügung. Sobald dieser aufgerufen wird, wird eine Nachricht in einem definierten Channel auf Slack ausgelöst. Dieses Szenario kann man dann in einem zweiten Schritt beliebig anpassen und konfigurieren. Hierbei geht es in erster Linie wie man ein solchen Bot in mit einem zeitgenössischen Framework exponiert und wie dieser Bot als App so einfach wie möglich in einem Cloud-Dienst bereitstellt.
In unserem Fall haben wir uns für Ktor, dem von JetBrains entwickelten Kotlin-Framework und Heroku als den App-Provider entschieden. Mit Kotlin kann wie gewohnt mit der JVM-Umgebung arbeiten und doch lesbaren und _maintain_baren Code schreiben. Heroku ist ein beliebter Provider welche eine Vielzahl von Sprachen und Tools unterstützt und womit man mit Minimalaufwand eine Applikation launchen kann.
Der Stack
-
Slack
-
Kotlin
-
Kotr Framework
-
Gradle w/ Kotlin DSL
-
Gradle Shadow für FatJar
-
Heroku
Setup
Für die Entwicklung nutzen wir ausschliesslich JetBrains IntelliJ. Stellen Sie auch sicher, dass Sie die neuste Version der IDE installiert haben. Kotlin und Kotr werden beide Default-mässig, als hausinterne JetBrains-Produkte, mit der IntelliJ-IDE mitausgeliefert und erfordern mit den neueren Versionen der IDE kein zusätzliche Installation mehr.
Erstellen des Kotr-Projekts
Im New Project-Fenster, Ktor als Framework wählen. Hier verwenden wir die Version 1.6.2 des Frameworks.
Im zweiten Fenster der Projekterstellung, sollten Sie noch das GSON-Feature als Plugin dem Projekt hinzufügen. Einfach danach suchen und hinzufügen.
Sobald das Projekt erstellt ist, führen wir ein gradle run
aus, um das Vanilla-Projekt versuchsweise zu starten. Kotr setzt Default-mässig einen Server-Endpunkt auf dem Port 8080.
|
|
Initial kann das etwas dauern da noch eine DSL downloaded wird und der Gradle-Daemon gestartet werden muss. Beim Aufruf von http://0.0.0.0:8080 sollte ein Hello World! ausgegeben werden.
Perfekt! Ktor läuft und liefert uns ein nettes Hello World! als Standard-Ausgabewert. Soweit so gut. Jetzt können wir uns darum kümmern dass Slack unsere Applikation als App erkennen kann.
Erstellen der Slack-App
Um Slack wissen zu lassen, dass wir eine App mit der Slack-API verbinden möchten, müssen wir zuerst eine App über Slack deklarieren. Dazu müssen Sie sich mit ihrem Slack-Profil in ihrem Workspace der Wahl anmelden. Es sei angemerkt: dies geht ausschliesslich über den Browser und nicht etwa über die Slack-App.
Erstellen Sie die App per Create an app wie folgt:
Wir wählen hier From scratch an und kommen in zweiten Erstellungschritt zur Auswahl für den App-Namen sowie dem Ziel-Workspace. In unserem Fall wählten wir TechUp Slack Bot als Name und unseren hausinternea b-nova-Workspace. Bestätigen Sie mit dem grünen Button Create App.
Jetzt ist die Slack-App erstellt. Wir müssen aber noch ein paar Konfigurationen an der App vornehmen. Zuerst erstellen wir notwendige OAuth-Scopes welche definieren was unsere App darf und nicht darf. In unserem Fall wollen wir sicherstellen, dass die App Nachrichten in Slack schreiben darf. Dazu fügen wir unter dem Tab OAuth & Permissions > Scopes einen Scope per Add an OAuth Scope hinzu.
Der gewünsche Scope ist chat:write
. Einfach anwählen und anklicken.
Jetzt müssen wir noch den gewünschten Ziel-Workspace installieren, bzw. den Token für die App generieren lassen. Dazu den grünen Install to Workspace-Button unter OAuth & Permissions > OAuth Tokens for Your Workspace anwählen.
Sie werden im Anschluss aufgefordert die Permissions bezüglich Send messages zu erlauben. Grünen Allow-Button anwählen. Klar.
Sehr gut. Jetzt sollte alles passen. Der Token sollte jetzt auch generiert worden sein. Diesen Token brauchen wir sodass sich die App beim Zugriff auf Slack und dessen API identifizieren kann. Bitte diesen Token irgendwo in ihre Zwischenlage kopieren.
Mit dem OAuth-Token für Slack im Gepäch bauen wir unsere Ktor-App soweit aus, dass wir eine Nachricht in unseren gewünschten Slack-Channel schreiben können.
Slackbot lernt zu schreiben
Wir haben bereits eine main-Funktion in unserer Application.kt
-Klasse. Diese erweitern wir jetzt um eine Slack-Schreibfunktionalität.
Die src/
-Directory sollte wie folgt aussehen.
|
|
Die Application.kt
ist unser Einstiegspunkt in die App. Diese stellt einen Server über 0.0.0.0 bereit. Wichtig hier ist, dass der Port aus den Environment-Variablen herausgelesen wird, da auf Heroku der Port nicht immer zwingend 8080 sein wird. Dies geht ganz einfach wie hier auf Zeile 9 gezeigt ist:
|
|
Die module()
-Funktion wird in unserer Routing.kt
deklariert. Diese wiederrum ruft für das Routing die homeRoute()
-Funktion auf.
|
|
Die homeRoute()
-Funktion übernimmt die eigentliche Funktionalität des Schreibens der Hello b-nova! 👋-Nachricht. Der gewünschte Ziel-Channel ist hier #sandbox und ist ein privater Channel den ich zu Testzwecken erstellt hatte. Wichtig hier ist auch das Auslesen des Tokens aus den Environment-Variablen.
|
|
Jetzt müssen wir noch die gewünschten Dependencies in unserer build.gradle.kts
definieren, sowie das Shadow-Gradle-Plugin nutzen um ein FatJar beim Build generieren zu lassen.
|
|
In den gradle.properties
legen wir noch die gewisse Properties welche in erster Linie die Versionierung unserer Dependencies vorgibt.
|
|
Jetzt können wir ein gradle run
in IntelliJ als Run-Konfiguration vornehmen. Hierzu einfach beachten, dass eine Environment-Variable für den SLACK_TOKEN
gesetzt ist.
Beim Anstossen wird das Ganze auf http://0.0.0.0:8080
deployed.
|
|
Beim Aufruf des http://0.0.0.0:8080
-Endpunkts, sollte neben einer Response des GET-Aufrufs eine Nachricht im Ziel-Channel ausgelöst werden. Falls nicht, kann es daran liegen, dass der Bot dem Channel noch nicht hinzugefügt worden ist. In diesem Fall wird ein Fehler not_in_channel
geworfen. Dies kann man ganz einfach erledigen indem man den Bot per @TechUp Slack Bot
in Slack addressiert und im Anschluss durch Slack aufgefordert wird den Bot als User hinzuzufügen.
Yupie! Hat geklappt, oder?
Falls nicht, bitte einfach mit unserer TechUp-Repository auf GitHub abgleichen. Als nächstes möchten wir die Applikation auf Heroku deployen und laufen lassen, sodass sie rund um die Uhr erreichbar ist.
Heroku als App-Provider
Heroku bietet die Möglichkeit Apps schnell und unkompliziert zu deployen. Dazu müssen wir uns zuerst ein Konto erstellen und die App deklarieren.
Zuerst erstellen wir die App auf Heroku. Der Name hier ist techup-slackbot welcher in der Europe-Zone gehostet werden soll.
Danach konfigurieren wir die App wie folgt. Wichtig dabei ist der SLACK_TOCKEN
.
Heroku erwartet beim Builden ein Procfile
auf Projektebene. Dies soll den Pfad zu unserem FatJar enthalten.
|
|
Wir werden zuerst Heroku lokal laufen lassen, um zu testen ob Heroku unsere App auch richtig buildet. Das hat den Vorteil dass es viel schneller geht und dass keine Buildtime auf dem Heroku-Server anfällt. Hierzu müssen wir in einer .env
-File noch die Environemnt-Variablen definieren.
|
|
Mit der Heroku-CLI kann man jetzt bequem einen Login vornehmen und im Anschluss das Ganze lokal bauen und testen lassen.
|
|
Das Deployment nach Heroku wird ganz einfach mit einem Push der Git-Repository angestossen.
|
|
Sobald dies erfolgt, sollte die App auf Heroku deployed und bereits am laufen sein. Beim Aufruf der App unter https://{app-name}.herokuapp.com/ oder direkt über den Open App-Button
wird die Slack-Nachricht nochmals ausgelöst
Glückwunsch ! Sie haben soeben ihren ersten Slackbot mit Kotlin/Ktor und Heroku gebaut! 🥳
Fazit
Mit dem gewählten Stack kann man relativ schnell und bequem einen Slackbot schreiben. Dabei wirken Kotlin, Kotr und Gradle allesamt sehr modern und bringen die Applikation auf das nächste Level. Wir bei b-nova haben mittlerweile mehrerer solcher Bots im Einsatz und werden diese bei Bedarf weiter ausbauen können. Bauen auch Sie einen Slackbot und lernen Sie die Vorteile des Deployments auf Heroku kennen. Stay tuned! 📻
Weiterführende Links und Quellen
https://plusmobileapps.com/2020/10/09/ktor-slackbot-heroku.html
https://devcenter.heroku.com/articles/heroku-cli