Teams eingehend WebHooks

Eine sehr interessante und einfache API zur Interaktion mit Teams sind die Webhooks. Auf dieser Seite stelle ich die Funktionsweise anhand von Beispielen vor.

Beachten Sie dazu auch die Seite Teams ausgehend WebHooks

Aufgabenstellung

Die Arbeit in Teams mit dem normalen Client ist nichts besonderes. Auch weitere Dienste als Webseite über eine URL einzubinden oder einen der Microsoft Connectoren zu nutzen, die z.B. einen RSS-Feed regelmäßig abfragen, geht noch einfach von der Hand. Aber es gibt Anforderungen, bei denen etwas mehr Interaktion und schnellere Reaktion wünschenswert ist. Es gibt dazu natürlich auch die Funktion eines Teams Bot, der von einem Anwender kontaktiert werden kann mehr oder weniger interaktiv mit dem Anwender kommuniziert. eine Bot-Entwicklung ist aber etwas umfangreicher und es gibt sehr oft die Anforderung, etwas dazwischen nutzen zu können, z.B.

  • Ich möchte eine Nachricht in einem Kanal posten
    Das kann z.B. ein Monitoring-System sein, welches einen Status dort meldet. Auch ein Helpdesk-System könnte dort ein neues Ticket bereitstellen und ein Anwender kann dieses dann "annehmen". Eine gewisse Interaktion zur Reaktion wäre interessant
  • Benachrichtigung bei Aktionen im Kanal
    Auch in der Gegenrichtung kann es interessant sein, Meldungen in einem Kanal automatisch zu erfassen. Das unterscheidet sich von einem Bot, der aktiv angesprochen wird. Über WebHooks kann ein Prozess quasi informiert werden, wenn in einem Channel was passiert ist. Denkbar sind Aktionen zu Compliance, Archivierung, Reporting aber auch die Funktion als Trigger

Die Optionen sind Vielfältig und anders als bei Graph oder anderen "high level APIs", die man am besten mit entsprechenden Libraries nutzt, sind Webhooks einfache HTTP-Aufrufe. Die sind so einfach, dass Sie sogar von Kleinstrechner wie einem  Arduino oder ESP8266 oder aus Sprachen wie PHP, Perl, JavaScript etc. angesprochen werden können, für die es keine Libraries gibt.

Incoming Webhook einrichten

Zuerst beschäftige ich mich mit den eingehenden WebHooks. Dazu gibt es schon einige Hinweise im Internet und der Weg ist sehr einfach. Sie müssen sich zuerst in einem Team-Kanal einen WebHook erstellen. Dazu gehe ich in das Team unter Apps.

Dort suche ich dann auf "Weitere Apps" nach den WebHooks und schon nach den ersten Buchstaben sollten sie den Eintrag sehen:

Ansonsten können Sie auch direkt den Link https://teams.microsoft.com/l/app/203a1e2c-26cc-47ca-83ae-be98f960b6b2 ansurfen. Im nächsten Dialog müssen Sie das Team auswählen, in dem der Webhook installiert wird.

Nach dem Klick auf "Öffnen" wählen Sie dann den Kanal aus:

Damit sind wir aber noch nicht fertig. Sie können dann noch ein Bild für die Nachrichten hinterlegen

Erst mit den Klick auf "Erstellen bekommen Sie dann eine sehr lange URL, die nicht mal in das Fenster passt aber hier kopiert werden kann.

Hier ein Beispiel:

https://outlook.office.com/webhook/ee883945-c42f-4703-836f-5f6087e4e408@de21c301-a4ae-4292-aa09-6db710a590a6/IncomingWebhook/77e0b356b3a5469987fe0474411841d2/b39bb717-ea64-46cd-ab57-00186effe82c

Aufbau
https://outlook.office.com/webhook/<guid des Office Group>@<TenantID>/IncomingWebhook/<zeichenfolge>/<guid>

Zwei Dinge finde ich da interessant:

  • Hostname outlook.office.com
    Der Hostname für den Service ist nicht teams.com oder teams.microsoft.com sondern eigentlich der Exchange Zugang. Das ist aber auch logisch, denn Nachrichten in Kanälen liegen ja in Office Groups und das ist ein Ablageort in Exchange.
  • Keine Authentifizierung
    Die Angabe der URL reicht komplett aus. Unsicher ist das aber nicht, denn auch die langen Zeichenketten können ja wie Anmeldeinformationen gewertet werden und sind sicher, solange niemand den HTTPS-Kanal aufbricht. Wer die URL kennt kann natürlich Daten so in den Kanal senden.

So eine Veränderung bleibt natürlich nicht unbemerkt. Im Unterhaltung-Kanal landet eine entsprechende Meldung

Und auch auf dem Team-Level erscheint die neue "App"

Incoming Webhook verwalten

Bereits eingerichtete Webhooks können Sie über die Konfiguration der Connectoren auf dem Kanal sehen.

Hier lassen Sie sich dann die bereits konfigurierten Connectoren anzeigen und bestehende Webhooks erneut anzeigen und löschen.

Nachricht als Adaptive Card erstellen

Ehe wir nun eine Message an den Kanal senden können, müssen wir natürlich noch die Nachricht selbst erstellen. Microsoft hat sich hier eine Lösung einfallen lassen, die plattformübergreifend werden soll. "Adaptive Cards" ist der Schlüsselbegriff, über die Microsoft Benachrichtigungen nicht nur schön formatieren, sondern auch mit Interaktion versehen will und die nicht nur ein Teams, sondern auch in Outlook, Auf Webseiten und anderen Plattformen immer passende angezeigt werden sollen.

Fehlerbehandlung

Ich verzichte mal auf all die Fehler, die nicht direkt mit Teams etwas zu tun haben, z.B. fehlende Namensauflösung, Probleme beim HTTPProxy oder Firewall, PowerShell Code Signing u.a. Wenn Sie grundsätzlich schon mal einen HTTP-Post zu outlook.office365.com absetzen können, dann kann es fast nur noch an der URL oder dem Payload liegen. Wenn ihre eigene Message nicht auf Anhieb funktioniert, dann gibt es mehrere Ansatzpunkte:

Fehler Lösung
Invalid webhook URL

Klassischer Cut-Copy-Paste-Fehler. Die URL ist nicht korrekt. Prüfen Sie noch mal die komplette URL, nicht dass Sie abgeschnitten wurde.

Summary or Text is required.

Sie haben entgegen meiner Beschreibung vergessen, zwischen den Properties "Version" und "Body" eine "Summary

Bad payload received by generic incoming webhook.

JSON ist einfach aber Menschen überlesen doch mal das ein oder andere Sonderzeichen. Wenn ich meine Message in der Variable "$Body" habe, dann kann ich einfach folgende Funktion nutzen, um die Gültigkeit des JSON-Strings zu prüfen.

$body | convertfrom-json -asHashtable

Name                           Value
----                           -----
actions                        {System.Collections.Hashtable}
body                           {System.Collections.Hashtable, System.Collections.Hashtable}
version                        1.0
type                           AdaptiveCard
summary                        Update der MSXFAQ
                               http://adaptivecards.io/schemas/adaptive-card.json

Sollt hier schon ein Fehler vorliegen, dann haben Sie irgendwo ein Zeichen vergessen, z.B. ein Komma am Ende der Zeilen etc.

IoT und WebHooks

Aufgrund der sehr einfachen Funktion dieser Webhooks ganz ohne Username, Kennwort o.ä. bietet es sich gerade zu an, diese Funktion auch in Geräten zu verwenden, die andere APIs nicht nutzen können. Sie könnten den Code in PHP-Seiten ihrer Webseite einbinden und z.B. einen "Form Post" eines Kontaktformulars so in einen Teams Channel senden. Interessant ist aber auch, dass noch kleinere Systeme entsprechende Meldungen generieren können. Theoretisch könnten Sie auch einen MQTT zu Teams-Gateway bauen, bei dem ein Prozess einen "Subscribe" auf bestimmte MQTT-Kanäle macht und die Werte dann in Teams sendet.

Das sind natürlich alles Beispiele, die ihre Daten am besten in ein Monitoring-System einspielen und nicht direkt zu Teams. Aber auch Monitoring-Systeme könnten solche Meldungen dann zu Teams weiter leiten.

Aktuell habe ich noch keinen konkreten Fall, um mit meinen Arduinos, ESP8266, ESP32 u.a. mal einen Webhook von Teams zu füttern. Aber mit den entsprechenden HTTP-Libraries ist das sehr einfach umzusetzen.

Push only, kein Polling

Sowohl ausgehende Webhooks als auch eingehende Webhooks sind getriggerte Aktionen. Ein eingehender Webhook kann einfach eine Meldung in einen Kanal ablegen. Ein ausgehender Webhooks kann auf eine neue Meldung quasi nur in Echtzeit reagieren und genau eine Antwort darauf liefern. Beide Schnittstellen erlauben aber weder einen Zugriff als frühere Chats und Nachrichten noch ein Polling durch einen Client. Es fehlt also die Funktion, wie diese in EWS vorhanden ist, damit ein Service nach einer Unterbrechung z.B. frühere Nachrichten aufarbeiten kann. Dies ist nicht das Ziel von Webhooks. Für solche Anforderungen sind anderen APIs, insbesondere die Graph API erforderlich. Diesen APIs fehlt dann natürlich die "Echtzeit-Komponente".

Weitere Links