Microsoft Teams Context sinnvoll nutzen: QuickLinks pro Team und Kanal

Eine leichtgewichtige Microsoft Teams Tab App, die den aktuellen Teams Context ausliest und anhand einer statischen JSON-Konfiguration entscheidet, welche Links angezeigt werden – ohne Graph, Datenbank oder Backend-API.

· 11 min read
Microsoft Teams Teams Tab TeamsJS SDK JSON React Microsoft 365 Agents Toolkit

Links zu internen Unternehmensanwendungen gehören zu diesen kleinen Reibungspunkten, die im Arbeitsalltag selten groß eskalieren, aber ständig Zeit kosten.

Fast jede Organisation kennt das: SharePoint-Portale, Dashboards, HR-Ressourcen, Projektwikis, Ticketsysteme, Dokumentationen, Onboarding-Guides, interne Formulare, Power BI Reports oder Azure DevOps Boards. Mit der Zeit entsteht daraus schnell ein kleiner Link-Dschungel.

Das Problem dabei: Nicht jeder Link ist für jede Person gleich relevant.

Ein Entwicklungsteam braucht andere Ressourcen als der Vertrieb. Die Buchhaltung arbeitet mit anderen Systemen als das Projektmanagement. Und selbst innerhalb eines Teams können einzelne Kanäle unterschiedliche Werkzeuge benötigen. Ein Kanal für Frontend-Entwicklung hat möglicherweise andere relevante Links als ein Kanal für Backend, DevOps oder Architektur.

Um für dieses Problem eine Lösung zu finden, habe ich ein kleines Sample entwickelt, welches eine einfache Frage beantworten soll:

Können wir in Microsoft Teams QuickLinks so anzeigen, dass sie sich automatisch am aktuellen Team oder Kanal orientieren, ohne dafür Microsoft Graph, eine Datenbank oder eine eigene Backend-API zu benötigen?

Das Ergebnis ist die Teams QuickLinks App: eine leichtgewichtige Microsoft Teams Tab App, die den aktuellen Teams Context ausliest und anhand einer statischen JSON-Konfiguration entscheidet, welche Links angezeigt werden.

Das Repository zum Sample findest du hier:

https://github.com/rwenz02/tab-context-quicklinks

Die Grundidee

Die App soll keine vollständige Enterprise-Linkplattform ersetzen. Sie soll vielmehr ein kleines, verständliches Pattern zeigen:

Teams Context lesen, Konfiguration auflösen, passende Links anzeigen.

Wenn die App in einem bestimmten Team oder Kanal geöffnet wird, erkennt sie den aktuellen Kontext. Anschließend prüft sie, ob es für diesen Kontext ein passendes Linkset in der Konfigurationsdatei gibt.

Dadurch können zum Beispiel folgende Szenarien abgebildet werden:

  • Ein Vertriebsteam sieht Links zu CRM, Angebotsunterlagen und Sales-Dashboards.
  • Ein Entwicklungsteam sieht Links zu Azure DevOps, technischer Dokumentation und Deployment-Pipelines.
  • Ein bestimmter Kanal innerhalb eines Teams sieht noch spezifischere Links, etwa für Enterprise Sales, Frontend-Entwicklung oder Projektcontrolling.
  • Wird die App außerhalb eines Team-Kontexts geöffnet, beispielsweise als persönliche App, werden allgemeine Standardlinks angezeigt.

Der Fokus liegt bewusst auf Einfachheit. Keine Benutzerverwaltung. Keine Backend-Logik. Keine Graph-Abfragen. Keine Datenbank. Die App entscheidet ausschließlich anhand des Teams Contexts und einer JSON-Datei, welche Links angezeigt werden.

Die Teams QuickLinks App zeigt abhängig vom aktuellen Microsoft Teams Team oder Kanal unterschiedliche Links an.

Befindet sich eine Nutzerin oder ein Nutzer beispielsweise in einem Sales-Team, können vertriebsbezogene Links angezeigt werden. Gibt es innerhalb dieses Teams einen Kanal für Enterprise Sales, kann für diesen Kanal eine eigene Linkliste hinterlegt werden.

Ähnlich wäre ein Entwicklungsteam denkbar, das verschiedene Kanäle für Frontend, Backend, DevOps oder Architektur besitzt. Jeder dieser Kanäle könnte eigene Links erhalten, ohne dass dafür eine komplexe Administrationslösung notwendig ist.

Die App unterstützt aktuell folgende Funktionen:

  • Anzeige von QuickLinks abhängig vom aktuellen Team
  • Anzeige von QuickLinks abhängig vom aktuellen Kanal
  • Fallback auf allgemeine Standardlinks
  • Suchfunktion nach Linktiteln
  • nutzerseitiges Pinning von favorisierten Links
  • zentral vorkonfigurierte Pins über die JSON-Konfiguration
  • Unterstützung von Fluent UI Icons
  • leichtgewichtige Konfiguration ohne Backend

Die nutzerseitige Pin-Funktion wird lokal im Teams Client gespeichert. Dadurch können Nutzerinnen und Nutzer Links für sich selbst hervorheben, ohne dass dafür eine zentrale Speicherung notwendig ist.

Architektur: bewusst simpel gehalten

Die Architektur der App ist absichtlich sehr schlank.

Die Anwendung besteht im Kern aus einer React-basierten Teams Tab App. Beim Start lädt sie eine JSON-Konfigurationsdatei und liest über das TeamsJS SDK den aktuellen Teams Context aus.

Aus diesem Kontext sind vor allem zwei Informationen relevant:

  • die groupId des aktuellen Teams
  • die channelId des aktuellen Kanals

Anhand dieser Werte wird geprüft, ob in der JSON-Konfiguration ein passendes Linkset vorhanden ist.

Die App benötigt dafür:

  • keine Microsoft Graph Permissions
  • keine SharePoint Permissions
  • keine eigene Backend-API
  • keine Datenbank
  • keine serverseitige Benutzerlogik

Damit eignet sich das Sample besonders gut, um das Pattern hinter kontextbezogenen Teams Tabs zu verstehen.

Die App in Aktion

Bevor wir uns die Konfiguration genauer anschauen, hier ein kurzer Blick auf die App im Teams Client.

Die App kann sowohl als persönliche App als auch als Tab innerhalb eines Teams oder Kanals verwendet werden. Je nach Kontext wird ein anderes Linkset geladen. Wird kein spezifisches Team oder kein spezifischer Kanal erkannt, greift die App auf das default-Linkset zurück.

Die App als persönliche App und als Kanal-Tab

Neben der kontextbezogenen Anzeige können Nutzerinnen und Nutzer eigene Links pinnen. Diese Pins werden lokal im Teams Client gespeichert und verändern nicht die zentrale JSON-Konfiguration.

Links pinnen und entpinnen

Für längere Linklisten gibt es außerdem eine einfache Suchfunktion. Die Suche filtert die angezeigten QuickLinks anhand des Linktitels.

Suchfunktion für QuickLinks

Konfiguration über JSON

Die QuickLinks werden über eine zentrale JSON-Datei konfiguriert. Im Sample liegt diese Datei unter:

public/config/quicklinks.json

Die Datei wird zur Laufzeit von der App geladen. Dadurch steckt die gesamte Logik, welche Links in welchem Kontext angezeigt werden, in einer einzigen Konfigurationsdatei.

Die Grundstruktur sieht so aus:

{
  "default": {
    "title": "Personal QuickLinks",
    "description": "Useful resources for all users.",
    "links": []
  },
  "teams": {}
}

Der Bereich default enthält Links, die angezeigt werden, wenn kein spezifisches Team oder kein spezifischer Kanal erkannt wird. Das ist zum Beispiel relevant, wenn die App als persönliche Teams App geöffnet wird oder wenn für das aktuelle Team keine eigene Konfiguration vorhanden ist.

Der Bereich teams enthält team- und kanalbezogene Linksets. Als Schlüssel wird dabei die Microsoft Teams groupId verwendet.

Ein einfaches teambezogenes Linkset kann beispielsweise so aussehen:

{
  "teams": {
    "00000000-0000-0000-0000-000000000002": {
      "title": "Development QuickLinks",
      "description": "Engineering tools and technical documentation.",
      "links": [
        {
          "id": "azure-devops",
          "title": "Azure DevOps",
          "description": "Open boards, repositories and pipelines.",
          "url": "https://dev.azure.com/contoso",
          "icon": "Code",
          "pinnedByDefault": true
        },
        {
          "id": "dev-docs",
          "title": "Developer Documentation",
          "description": "Browse the internal developer knowledge base.",
          "url": "https://docs.contoso.com",
          "icon": "Dictionary"
        }
      ]
    }
  }
}

Jeder Link besitzt mindestens folgende Eigenschaften:

  • id
  • title
  • url

Optional können weitere Eigenschaften ergänzt werden:

  • description
  • icon
  • pinnedByDefault

Die id ist besonders wichtig, da sie intern verwendet wird, um gepinnte Links wiederzuerkennen. Sie sollte deshalb innerhalb des jeweiligen Linksets eindeutig und möglichst stabil sein. Wenn sich nur der Titel oder die URL eines Links ändert, sollte die id nach Möglichkeit gleich bleiben.

Mit pinnedByDefault: true können Administratorinnen und Administratoren Links zentral hervorheben. Diese Links erscheinen für alle Nutzerinnen und Nutzer im jeweiligen Kontext initial als gepinnt.

Zusätzlich können Nutzerinnen und Nutzer eigene Links pinnen oder entpinnen. Diese nutzerseitigen Pins werden lokal im Teams Client gespeichert.

Kanalbezogene Linksets

Neben teambezogenen Links können auch kanalbezogene Links definiert werden. Dafür wird innerhalb eines Teams der Bereich channels ergänzt.

Ein Beispiel:

{
  "teams": {
    "00000000-0000-0000-0000-000000000001": {
      "title": "Sales QuickLinks",
      "description": "Tools and resources for the Sales team.",
      "links": [
        {
          "id": "dynamics-sales",
          "title": "Dynamics 365 Sales",
          "url": "https://contoso.crm.dynamics.com",
          "icon": "Briefcase",
          "pinnedByDefault": true
        }
      ],
      "channels": {
        "19:example-channel-id@thread.tacv2": {
          "title": "Enterprise Sales QuickLinks",
          "description": "Resources for enterprise deal management.",
          "links": [
            {
              "id": "enterprise-pricing",
              "title": "Enterprise Pricing Calculator",
              "description": "Calculate custom pricing for enterprise deals.",
              "url": "https://pricing.contoso.com",
              "icon": "Calculator",
              "pinnedByDefault": true
            }
          ]
        }
      }
    }
  }
}

Die App entscheidet anschließend anhand des aktuellen Teams Contexts, welches Linkset angezeigt wird.

Die Auflösung erfolgt nach folgender Priorität:

  1. Wenn eine passende Konfiguration für das aktuelle Team und den aktuellen Kanal existiert, wird diese verwendet.
  2. Wenn keine passende Kanal-Konfiguration existiert, aber eine Konfiguration für das aktuelle Team vorhanden ist, wird das Team-Linkset verwendet.
  3. Wenn weder Team noch Kanal gefunden werden, wird das default-Linkset angezeigt.

Wichtig ist dabei: Die Linksets werden aktuell nicht zusammengeführt. Eine kanalbezogene Konfiguration ersetzt also die teambezogene Linkliste für diesen Kanal. Das macht das Verhalten sehr vorhersehbar, sollte aber beim Aufbau der JSON-Datei berücksichtigt werden.

Woher bekomme ich die benötigten IDs?

Für die Konfiguration werden die IDs des jeweiligen Teams und Kanals benötigt.

Die groupId eines Teams lässt sich über Microsoft Teams herausfinden. Über Link zum Team abrufen enthält die generierte URL die entsprechende Team-ID.

Für Kanäle kann über Link zum Kanal abrufen die jeweilige channelId ermittelt werden. Diese hat häufig ein Format wie:

19:example-channel-id@thread.tacv2

Für ein Sample ist dieser Ansatz ausreichend und bewusst transparent. In einer produktiveren Variante könnte man die Ermittlung der IDs natürlich komfortabler gestalten, zum Beispiel über eine kleine Admin-Oberfläche.

Sicherheit und Berechtigungen

Ein wichtiger Punkt bei diesem Sample war für mich, die App so leichtgewichtig wie möglich zu halten.

Viele Microsoft 365 Apps benötigen schnell zusätzliche Berechtigungen, App Registrations, Microsoft Graph Scopes oder sogar Admin Consent. Für diesen Use Case wäre das aus meiner Sicht überdimensioniert gewesen.

Die QuickLinks App benötigt aktuell:

  • keine Microsoft Graph Scopes
  • keine SharePoint-Berechtigungen
  • keine eigene Backend-API
  • keine serverseitige Authentifizierungslogik
  • keine Datenbank

Es werden keine Daten aus Microsoft Graph gelesen, keine Benutzerprofile abgefragt und keine Dateien, Listen oder Teams-Inhalte verarbeitet.

Stattdessen nutzt die App lediglich den Teams Context, der einer Teams Tab App über das TeamsJS SDK zur Verfügung steht. Darüber kann die App erkennen, in welchem Team und in welchem Kanal sie geöffnet wurde. Die eigentliche Entscheidung, welche Links angezeigt werden, erfolgt anschließend lokal anhand der JSON-Konfiguration.

Die nutzerseitige Pin-Funktion wird im lokalen Speicher des Teams Clients abgelegt. Das bedeutet: Die Information, welche Links eine Nutzerin oder ein Nutzer selbst angepinnt hat, bleibt lokal im jeweiligen Client und wird nicht zentral synchronisiert oder in einer Datenbank gespeichert.

Wichtig ist aber auch die fachliche Abgrenzung:

Die App ist keine Sicherheits- oder Berechtigungslogik. Sie steuert nur, welche Links in welchem Teams-Kontext angezeigt werden. Sie verhindert nicht, dass jemand einen Link kennt oder manuell aufruft.

Die eigentliche Zugriffskontrolle muss weiterhin im jeweiligen Zielsystem stattfinden. Wenn ein Link beispielsweise auf ein SharePoint-Portal, ein Dashboard oder ein Fachverfahren verweist, muss dieses Zielsystem selbst prüfen, ob die jeweilige Person Zugriff hat.

Die App hilft also bei der Sichtbarkeit und Orientierung, ersetzt aber keine Autorisierung.

Lokales Debugging und Deployment mit dem Microsoft 365 Agents Toolkit

Für die lokale Entwicklung und das Deployment habe ich das Microsoft 365 Agents Toolkit für Visual Studio Code verwendet.

Das Toolkit eignet sich gut für Teams App Samples, weil es viele wiederkehrende Schritte direkt aus der Entwicklungsumgebung heraus unterstützt: lokales Debugging, das Starten der App im Teams Client, Provisionierung benötigter Ressourcen und Deployment der Anwendung.

Für dieses Sample ist der Entwicklungsprozess bewusst einfach gehalten.

Nach dem Klonen des Repositories und dem Installieren der npm-Abhängigkeiten kann die App über Visual Studio Code lokal gestartet und direkt in Microsoft Teams getestet werden.

Die konkreten Schritte zum lokalen Debugging und Deployment sind im Repository dokumentiert:

https://github.com/rwenz02/tab-context-quicklinks

Dort finden sich auch die benötigten Voraussetzungen, npm-Skripte und Hinweise zur Konfiguration der App.

Weitere Informationen zum Microsoft 365 Agents Toolkit findest du in der offiziellen Microsoft-Dokumentation:

https://learn.microsoft.com/en-us/microsoftteams/platform/toolkit/agents-toolkit-fundamentals

Limitierungen der App

Die QuickLinks App ist bewusst als leichtgewichtiges Sample umgesetzt. Sie soll primär veranschaulichen, wie sich der Teams Context nutzen lässt, um Links abhängig vom aktuellen Team oder Kanal anzuzeigen.

Das heißt nicht, dass die App nicht auch produktiv genutzt werden kann. Durch die einfache Architektur gibt es aber einige Limitierungen.

Statische Konfiguration

Die Links werden aktuell aus einer JSON-Datei geladen. Änderungen erfolgen nicht über eine Administrationsoberfläche.

Wenn neue Links ergänzt, bestehende Links angepasst oder Team-Konfigurationen verändert werden sollen, muss die JSON-Datei geändert und die App neu bereitgestellt werden.

Keine zentrale Synchronisierung von Pins

Die nutzerseitige Pin-Funktion wird lokal im Teams Client gespeichert. Dadurch bleiben Pins einfach und datensparsam.

Der Nachteil: Pins werden nicht zwischen verschiedenen Geräten, Browsern oder Teams-Clients synchronisiert.

Keine Kombination von Linksets

Aktuell werden Linksets nicht miteinander kombiniert.

Wenn für einen Kanal eine eigene Konfiguration vorhanden ist, ersetzt diese die Team-Konfiguration für diesen Kontext. Das ist einfach und vorhersehbar, kann aber in manchen Szenarien zu starr sein.

Eine alternative Logik wäre, Team-Links und Kanal-Links zusammenzuführen. Das wäre flexibler, aber auch etwas komplexer.

Keine rollen- oder gruppenbasierte Personalisierung

Die App unterscheidet aktuell nicht nach Benutzerrollen, Gruppenmitgliedschaften oder Entra ID Gruppen.

Das ist bewusst so gewählt, weil dafür Microsoft Graph oder eine andere Datenquelle notwendig wäre. Für dieses Sample soll der Teams Context ausreichen.

Sichtbarkeit ist keine Berechtigung

Die App entscheidet nur, welche Links angezeigt werden. Sie schützt die Zielsysteme nicht.

Wenn ein Link sichtbar ist, bedeutet das nicht automatisch, dass die Person Zugriff auf das Zielsystem hat. Umgekehrt könnte eine Person einen bekannten Link auch manuell aufrufen. Die Berechtigungsprüfung muss immer im Zielsystem erfolgen.

Ideen zur Weiterentwicklung

Aus den aktuellen Limitierungen ergeben sich einige mögliche Erweiterungen für produktivere Szenarien.

Denkbar wären zum Beispiel:

  • eine Administrationsoberfläche zur Pflege der Links
  • Speicherung der Konfiguration in SharePoint, Azure Storage oder einer Datenbank
  • Synchronisierung nutzerseitiger Pins über ein Backend
  • rollen- oder gruppenbasierte Linkanzeige über Microsoft Graph
  • Import- und Exportfunktionen für Linkkonfigurationen
  • Validierung der JSON-Konfiguration vor dem Deployment
  • Zusammenführen von Team- und Kanal-Linksets
  • Unterstützung mehrerer Linkkategorien
  • Mandantenweite Standardlinks mit zusätzlicher Team-spezifischer Erweiterung

Damit könnte aus dem Sample nach und nach eine vollwertigere interne Linklösung entstehen.

Fazit

Die Teams QuickLinks App zeigt, wie sich mit relativ wenig Infrastruktur ein praktisches Microsoft Teams Szenario umsetzen lässt.

Der eigentliche Kern ist nicht die Linkliste selbst, sondern das dahinterliegende Pattern:

Nutze den Teams Context, um Inhalte abhängig vom aktuellen Team oder Kanal anzuzeigen.

Für einfache Szenarien reicht dafür eine statische JSON-Konfiguration völlig aus. Man benötigt keine Graph Permissions, keine Datenbank und keine Backend-API. Dadurch bleibt die App leichtgewichtig, verständlich und einfach anpassbar.

Natürlich gibt es Limitierungen. Für größere produktive Szenarien wären eine Administrationsoberfläche, zentrale Speicherung und eventuell gruppenbasierte Logik sinnvolle nächste Schritte.

Als Sample zeigt die App aber sehr gut, wie man Teams Tabs kontextbezogener gestalten kann, ohne sofort eine große Architektur aufzubauen.

Gerade für interne Tools, kleine Fachbereichslösungen oder Proofs of Concept kann dieses Pattern eine pragmatische Grundlage sein.