Suchen mit Messaging-Erweiterungen

Wichtig

Die Artikel in diesem Abschnitt basieren auf dem v3 Bot Framework SDK. Wenn Sie nach aktueller Dokumentation (Version 4.6 oder höher) des SDK suchen, lesen Sie den Abschnitt "Aufgabenorientierte Interaktionen mit Messaging-Erweiterungen".

Suchbasierte Messaging-Erweiterungen ermöglichen es Ihnen, Ihren Dienst abfragt und diese Informationen in Form einer Karte direkt in Ihrer Nachricht zu posten.

Beispiel für eine Messaging-Erweiterungskarte

In den folgenden Abschnitten wird dies beschrieben:

Hinzufügen einer Messaging-Erweiterung zu Ihrer App

Eine Messaging-Erweiterung ist ein in der Cloud gehosteter Dienst, der Benutzeranforderungen überwacht und mit strukturierten Daten wie z. B. einer Karteantwortet. Sie integrieren Ihren Dienst mit Microsoft Teams über Bot Activity Framework-Objekte. Unsere .NET- und Node.js-Erweiterungen für das Bot Builder SDK können Ihnen helfen, Ihrer App Messaging-Erweiterungsfunktionen hinzuzufügen.

Diagramm des Nachrichtenflusses für Messaging-Erweiterungen

Registrieren im Bot Framework

Wenn sie dies noch nicht getan haben, müssen Sie zuerst einen Bot beim Microsoft Bot Framework registrieren. Die Dort definierten Microsoft-App-ID- und Rückrufendpunkte für Ihren Bot werden in Ihrer Messaging-Erweiterung verwendet, um Benutzeranforderungen zu empfangen und darauf zu reagieren. Denken Sie daran, den Microsoft Teams-Kanal für Ihren Bot zu aktivieren.

Notieren Sie Ihre Bot-App-ID und Ihr App-Kennwort. Sie müssen die App-ID in Ihrem App-Manifest angeben.

Aktualisieren des App-Manifests

Wie bei Bots und Registerkarten aktualisieren Sie das Manifest Ihrer App, um die Eigenschaften der Messaging-Erweiterung einzuschließen. Diese Eigenschaften steuern, wie Ihre Messaging-Erweiterung im Microsoft Teams Client angezeigt wird und wie sie sich verhält. Messaging-Erweiterungen werden ab Version 1.0 des Manifests unterstützt.

Deklarieren Der Messaging-Erweiterung

Um eine Messaging-Erweiterung hinzuzufügen, fügen Sie eine neue JSON-Struktur auf oberster Ebene in Ihr Manifest mit der composeExtensions Eigenschaft ein. Derzeit sind Sie auf die Erstellung einer einzelnen Messaging-Erweiterung für Ihre App beschränkt.

Hinweis

Das Manifest bezieht sich auf Messaging-Erweiterungen als composeExtensions . Dies dient zur Aufrechterhaltung der Abwärtskompatibilität.

Die Erweiterungsdefinition ist ein Objekt mit der folgenden Struktur:

Eigenschaftenname Zweck Pflichtfeld?
botId Die eindeutige Microsoft-App-ID für den Bot, wie bei Bot Framework registriert. Dies sollte in der Regel mit der ID für Ihre gesamte Teams-App übereinstimmen. Ja
scopes Array, das deklariert, ob diese Erweiterung zu bereichen (oder zu beiden) hinzugefügt werden personal team kann. Ja
canUpdateConfiguration Aktiviert Einstellungen Menüelement. Nein
commands Array von Befehlen, die von dieser Messaging-Erweiterung unterstützt werden. Sie sind auf 10 Befehle beschränkt. Ja

Definieren von Befehlen

Ihre Messaging-Erweiterung sollte einen Befehl deklarieren, der angezeigt wird, wenn der Benutzer Ihre App über die Schaltfläche "Weitere Optionen" () im Feld "Verfassen" auswählt.

Screenshot der Liste der Messaging-Erweiterungen in Teams

Im App-Manifest ist das Befehlselement ein Objekt mit der folgenden Struktur:

Eigenschaftenname Zweck Pflichtfeld? Mindestversion des Manifests
id Eindeutige ID, die Sie diesem Befehl zuweisen. Die Benutzeranforderung enthält diese ID. Ja 1.0
title Befehlsname. Dieser Wert wird in der Benutzeroberfläche angezeigt. Ja 1.0
description Hilfetext, der angibt, was dieser Befehl bewirkt. Dieser Wert wird in der Benutzeroberfläche angezeigt. Ja 1.0
type Legen Sie den Befehlstyp fest. Mögliche Werte sind query und action. Wenn dieser Wert nicht vorhanden ist, wird der Standardwert auf query . Nein 1.4
initialRun Optionaler Parameter, der mit Befehlen verwendet query wird. Wenn der Wert auf "true" festgelegt ist, wird angegeben, dass dieser Befehl ausgeführt werden soll, sobald der Benutzer diesen Befehl auf der Benutzeroberfläche auswählt. Nein 1.0
fetchTask Optionaler Parameter, der mit Befehlen verwendet action wird. Auf "true" festgelegt, um die adaptive Karte oder Web-URL abzurufen, die im Aufgabenmodulangezeigt werden soll. Dies wird verwendet, wenn die Eingaben für den action Befehl dynamisch sind, im Gegensatz zu einem statischen Satz von Parametern. Beachten Sie, dass die Statische Parameterliste für den Befehl ignoriert wird, wenn sie auf "true" festgelegt ist. Nein 1.4
parameters Statische Liste der Parameter für den Befehl. Ja 1.0
parameter.name Der Name des Parameters. Dies wird in der Benutzeranforderung an Ihren Dienst gesendet. Ja 1.0
parameter.description Beschreibt die Zwecke dieses Parameters oder ein Beispiel für den Wert, der angegeben werden soll. Dieser Wert wird in der Benutzeroberfläche angezeigt. Ja 1.0
parameter.title Kurzer benutzerfreundlicher Parametertitel oder -beschriftung. Ja 1.0
parameter.inputType Legen Sie den Typ der erforderlichen Eingabe fest. Mögliche Werte sind text , , , , , textarea number date time toggle . Der Standardwert ist auf text . Nein 1.4
context Optionales Array von Werten, das den Kontext definiert, in dem die Nachrichtenaktion verfügbar ist. Mögliche Werte sind message , compose oder commandBox . Der Standardwert lautet ["compose", "commandBox"]. Nein 1,5

Suchtyp-Nachrichtenerweiterungen

Legen Sie für suchbasierte Messaging-Erweiterung den type Parameter auf query . Unten sehen Sie ein Beispiel für ein Manifest mit einem einzigen Suchbefehl. Einer einzelnen Messaging-Erweiterung können bis zu 10 verschiedene Befehle zugeordnet sein. Dies kann sowohl mehrere Suchbefehle als auch mehrere aktionsbasierte Befehle umfassen.

Beispiel für ein vollständiges App-Manifest

{
  "$schema": "https://developer.microsoft.com/json-schemas/teams/v1.8/MicrosoftTeams.schema.json",
  "manifestVersion": "1.5",
  "version": "1.0",
  "id": "57a3c29f-1fc5-4d97-a142-35bb662b7b23",
  "packageName": "com.microsoft.teams.samples.bing",
  "developer": {
    "name": "John Developer",
    "websiteUrl": "http://bingbotservice.azurewebsites.net/",
    "privacyUrl": "http://bingbotservice.azurewebsites.net/privacy",
    "termsOfUseUrl": "http://bingbotservice.azurewebsites.net/termsofuse"
  },
  "name": {
    "short": "Bing",
    "full": "Bing"
  },
  "description": {
    "short": "Find Bing search results",
    "full": "Find Bing search results and share them with your team members."
  },
  "icons": {
    "outline": "bing-outline.jpg",
    "color": "bing-color.jpg"
  },
  "accentColor": "#ff6a00",
  "composeExtensions": [
    {
      "botId": "57a3c29f-1fc5-4d97-a142-35bb662b7b23",
      "canUpdateConfiguration": true,
      "commands": [{
          "id": "searchCmd",
          "description": "Search Bing for information on the web",
          "title": "Search",
          "initialRun": true,
          "parameters": [{
            "name": "searchKeyword",
            "description": "Enter your search keywords",
            "title": "Keywords"
          }]
        }
      ]
    }
  ],
  "permissions": [
    "identity",
    "messageTeamMembers"
  ],
  "validDomains": [
    "bingbotservice.azurewebsites.net",
    "*.bingbotservice.azurewebsites.net"
  ]
}

Testen per Upload

Sie können Ihre Messaging-Erweiterung testen, indem Sie Ihre App hochladen.

Um Ihre Messaging-Erweiterung zu öffnen, navigieren Sie zu einem Ihrer Chats oder Kanäle. Wählen Sie im Feld "Verfassen" die Schaltfläche "Weitere Optionen" () aus, und wählen Sie Ihre Messaging-Erweiterung aus.

Hinzufügen von Ereignishandlern

Der Großteil Ihrer Arbeit umfasst das onQuery Ereignis, das alle Interaktionen im Messaging-Erweiterungsfenster verarbeitet.

Wenn Sie canUpdateConfiguration true dies im Manifest festlegen, aktivieren Sie das Einstellungen Menüelement für Ihre Messaging-Erweiterung und müssen auch behandeln onQuerySettingsUrl und onSettingsUpdate .

Behandeln von onQuery-Ereignissen

Eine Messaging-Erweiterung empfängt ein onQuery Ereignis, wenn im Messaging-Erweiterungsfenster etwas passiert oder an das Fenster gesendet wird.

Wenn Ihre Messaging-Erweiterung eine Konfigurationsseite verwendet, sollte ihr Handler onQuery zunächst nach gespeicherten Konfigurationsinformationen suchen. Wenn die Messaging-Erweiterung nicht konfiguriert ist, geben Sie eine config Antwort mit einem Link zu Ihrer Konfigurationsseite zurück. Beachten Sie, dass die Antwort von der Konfigurationsseite auch von behandelt onQuery wird. Die einzige Ausnahme ist, wenn die Konfigurationsseite vom Handler aufgerufen onQuerySettingsUrl wird. Weitere Informationen finden Sie im folgenden Abschnitt:

Wenn Ihre Messaging-Erweiterung eine Authentifizierung erfordert, überprüfen Sie die Benutzerstatusinformationen. Wenn der Benutzer nicht angemeldet ist, befolgen Sie die Anweisungen im Abschnitt "Authentifizierung" weiter unten in diesem Thema.

Überprüfen Sie als Nächstes, ob initialRun sie festgelegt ist. Falls ja, ergreifen Sie entsprechende Maßnahmen, z. B. das Bereitstellen von Anweisungen oder eine Liste von Antworten.

Der restliche Handler fordert onQuery den Benutzer zur Eingabe von Informationen auf, zeigt eine Liste der Vorschaukarten an und gibt die vom Benutzer ausgewählte Karte zurück.

Behandeln von onQuerySettingsUrl- und onSettingsUpdate-Ereignissen

The onQuerySettingsUrl and events work together to enable the onSettingsUpdate Einstellungen menu item.

Screenshots der Speicherorte Einstellungen Menüelements

Der Handler für onQuerySettingsUrl gibt die URL für die Konfigurationsseite zurück. Nachdem die Konfigurationsseite geschlossen wurde, akzeptiert ihr Handler den onSettingsUpdate zurückgegebenen Zustand und speichert den zurückgegebenen Zustand. Dies ist der Fall, in dem die Antwort onQuery von der Konfigurationsseite nicht empfangen wird.

Empfangen und Beantworten von Abfragen

Jede Anforderung an Ihre Messaging-Erweiterung erfolgt über ein Activity Objekt, das in Ihrer Rückruf-URL bereitgestellt wird. Die Anforderung enthält Informationen zum Benutzerbefehl, z. B. ID- und Parameterwerte. Die Anforderung liefert auch Metadaten über den Kontext, in dem Ihre Erweiterung aufgerufen wurde, einschließlich Benutzer- und Mandanten-ID, sowie Chat-ID oder Kanal- und Team-IDs.

Empfangen von Benutzeranforderungen

Wenn ein Benutzer eine Abfrage ausführt, sendet Microsoft Teams Ihrem Dienst ein standardmäßiges Bot Activity Framework-Objekt. Der Dienst sollte seine Logik für einen Typ ausführen, der Activity type auf einen unterstützten Typ festgelegt und invoke auf diesen festgelegt name composeExtension wurde, wie in der folgenden Tabelle dargestellt.

Zusätzlich zu den standardmäßigen Bot-Aktivitätseigenschaften enthält die Nutzlast die folgenden Anforderungsmetadaten:

Eigenschaftenname Zweck
type Anforderungstyp; muss invoke .
name Typ des Befehls, der an Ihren Dienst ausgegeben wird. Derzeit werden die folgenden Typen unterstützt:
composeExtension/query
composeExtension/querySettingUrl
composeExtension/setting
composeExtension/selectItem
composeExtension/queryLink
from.id DIE ID des Benutzers, der die Anforderung gesendet hat.
from.name Name des Benutzers, der die Anforderung gesendet hat.
from.aadObjectId Azure Active Directory Objekt-ID des Benutzers, der die Anforderung gesendet hat.
channelData.tenant.id Azure Active Directory Mandanten-ID.
channelData.channel.id Kanal-ID (wenn die Anforderung in einem Kanal vorgenommen wurde).
channelData.team.id Team-ID (wenn die Anforderung in einem Kanal vorgenommen wurde).
clientInfo Optionale Metadaten über die Clientsoftware, die zum Senden der Nachricht eines Benutzers verwendet wird. Die Entität kann zwei Eigenschaften enthalten:
Das country Feld enthält den vom Benutzer erkannten Speicherort.
Das platform Feld beschreibt die Messaging-Clientplattform.
Weitere Informationen finden Sie unter Nicht-IRI-Entitätstypen – clientInfo.

Die Anforderungsparameter selbst befinden sich im Wertobjekt, das die folgenden Eigenschaften enthält:

Eigenschaftenname Zweck
commandId Der Name des vom Benutzer aufgerufenen Befehls, der einem der im App-Manifest deklarierten Befehle entspricht.
parameters Array von Parametern: Jedes Parameterobjekt enthält den Parameternamen sowie den vom Benutzer bereitgestellten Parameterwert.
queryOptions Paginierungsparameter:
skip: Anzahl für diese Abfrage überspringen
count: Anzahl der zurückzugebenden Elemente

Anforderungsbeispiel

{
  "name": "composeExtension/query",
  "value": {
    "commandId": "searchCmd",
    "parameters": [
      {
        "name": "searchKeywords",
        "value": "Toronto"
      }
    ],
    "queryOptions": {
      "skip": 0,
      "count": 25
    }
  },
  "type": "invoke",
  "timestamp": "2017-05-01T15:45:51.876Z",
  "localTimestamp": "2017-05-01T08:45:51.876-07:00",
  "id": "f:622749630322482883",
  "channelId": "msteams",
  "serviceUrl": "https://smba.trafficmanager.net/amer-client-ss.msg/",
  "from": {
    "id": "29:1C7dbRrC_5yzN1RGtZIrcWT0xz88KPGP9sxdpVpV8sODlgPHeQE9RqQ02hnpuKzy6zZ-AaZx6swUOMj_Dsdse3TQ4sIaeebbFBF-VgjJy_nY",
    "name": "Larry Jin",
    "aadObjectId": "cd723fa0-0591-416a-9290-e93ecf3a9b92"
  },
  "conversation": {
    "id": "19:skypespaces_8198cfe0dd2647ae91930f0974768a40@thread.skype"
  },
  "recipient": {
    "id": "28:b4922ea1-5315-4fd0-9b21-d941ab06e39f",
    "name": "TheComposeExtensionDev"
  },
  "entities": [
    {
    "type": "clientInfo",
      "country": "US",
      "platform": "Windows"
    }
  ]
}

Als Alternative (oder zusätzlich) zum Durchsuchen Ihres externen Diensts können Sie eine URL verwenden, die in das Feld zum Verfassen von Nachrichten eingefügt wurde, um Ihren Dienst abfragt und eine Karte zurückzugeben. Im folgenden Screenshot hat ein Benutzer eine URL für eine Arbeitsaufgabe in Azure DevOps eingefügt, die die Messaging-Erweiterung in eine Karte aufgelöst hat.

Beispiel für die Verbreitung von Links

Damit Ihre Messaging-Erweiterung auf diese Weise mit Links interagieren kann, müssen Sie zunächst das messageHandlers Array zu Ihrem App-Manifest hinzufügen, wie im folgenden Beispiel gezeigt:

"composeExtensions": [
  {
    "botId": "abc123456-ab12-ab12-ab12-abcdef123456",
    "messageHandlers": [
      {
        "type": "link",
        "value": {
          "domains": [
            "*.trackeddomain.com"
          ]
        }
      }
    ]
  }
]

Nachdem Sie die Domäne zum Überwachen des App-Manifests hinzugefügt haben, müssen Sie Ihren Botcode ändern, um auf die folgende Aufrufanforderung zu reagieren.

{
  "type": "invoke",
  "name": "composeExtension/queryLink",
  "value": {
    "url": "https://theurlsubmittedbyyouruser.trackeddomain.com/id/1234"
  }
}

Wenn Ihre App mehrere Elemente zurückgibt, wird nur das erste Element verwendet.

Antworten auf Benutzeranforderungen

Wenn der Benutzer eine Abfrage ausführt, Microsoft Teams eine synchrone HTTP-Anforderung an Ihren Dienst ausstellt. An diesem Punkt hat Ihr Code 5 Sekunden Zeit, um eine HTTP-Antwort auf die Anforderung bereitzustellen. Während dieser Zeit kann Ihr Dienst zusätzliche Nachschlagevorgänge oder eine beliebige andere Geschäftslogik ausführen, die für die Bearbeitung der Anforderung erforderlich ist.

Ihr Dienst sollte mit den Ergebnissen antworten, die mit der Benutzerabfrage übereinstimmen. Die Antwort muss einen HTTP-Statuscode 200 OK und ein gültiges Application/json-Objekt mit dem folgenden Text angeben:

Eigenschaftenname Zweck
composeExtension Antwortumschlag auf oberster Ebene.
composeExtension.type Antworttyp. Die folgenden Typen werden unterstützt:
result: zeigt eine Liste der Suchergebnisse an
auth: fordert den Benutzer zur Authentifizierung auf
config: fordert den Benutzer auf, die Messaging-Erweiterung einzurichten
message: zeigt eine Nur-Text-Nachricht an.
composeExtension.attachmentLayout Gibt das Layout der Anlagen an. Wird für Antworten vom Typ result verwendet.
Derzeit werden die folgenden Typen unterstützt:
list: eine Liste von Kartenobjekten, die Miniaturansichten, Titel und Textfelder enthalten
grid: ein Raster mit Miniaturansichten
composeExtension.attachments Array gültiger Anlagenobjekte. Wird für Antworten vom Typ result verwendet.
Derzeit werden die folgenden Typen unterstützt:
application/vnd.microsoft.card.thumbnail
application/vnd.microsoft.card.hero
application/vnd.microsoft.teams.card.o365connector
application/vnd.microsoft.card.adaptive
composeExtension.suggestedActions Vorgeschlagene Aktionen. Wird für Antworten vom Typ auth oder config verwendet.
composeExtension.text Anzuzeigende Meldung. Wird für Antworten vom Typ message verwendet.

Antwortkartentypen und Vorschauen

Wir unterstützen die folgenden Anlagentypen:

Weitere Informationen finden Sie unter Karten für eine Übersicht.

Weitere Informationen zur Verwendung der Miniaturansicht- und Herokartentypen finden Sie unter Hinzufügen von Karten und Kartenaktionen.

Weitere Dokumentationen zur Office 365 Connectorkarte finden Sie unter Verwenden Office 365 Connectorkarten.

Die Ergebnisliste wird auf der Microsoft Teams Benutzeroberfläche mit einer Vorschau der einzelnen Elemente angezeigt. Die Vorschau wird auf zwei Arten generiert:

  • Verwenden der preview Eigenschaft innerhalb des attachment Objekts. Die preview Anlage kann nur eine Hero- oder Miniaturansichtskarte sein.
  • Extrahiert aus den title grundlegenden text , und Eigenschaften image der Anlage. Diese werden nur verwendet, wenn die preview Eigenschaft nicht festgelegt ist und diese Eigenschaften verfügbar sind.

Sie können eine Vorschau einer adaptiven oder Office 365 Connectorkarte in der Ergebnisliste anzeigen, indem Sie einfach die Vorschaueigenschaft festlegen. dies ist nicht erforderlich, wenn die Ergebnisse bereits Favoriten- oder Miniaturansichtskarten sind. Wenn Sie die Vorschauanlage verwenden, muss es sich entweder um eine Hero- oder miniaturansichtskarte handeln. Wenn keine Vorschaueigenschaft angegeben ist, schlägt die Vorschau der Karte fehl, und es wird nichts angezeigt.

Anforderungsbeispiel

Dieses Beispiel zeigt eine Antwort mit zwei Ergebnissen, wobei verschiedene Kartenformate gemischt werden: Office 365 Connector und Adaptive. Während Sie wahrscheinlich bei einem Kartenformat in Ihrer Antwort bleiben möchten, wird gezeigt, wie die preview Eigenschaft jedes Elements in der Sammlung explizit eine Vorschau im attachments Hero- oder Miniaturansichtsformat definieren muss, wie oben beschrieben.

{
  "composeExtension": {
    "type": "result",
    "attachmentLayout": "list",
    "attachments": [
      {
        "contentType": "application/vnd.microsoft.teams.card.o365connector",
        "content": {
          "sections": [
            {
              "activityTitle": "[85069]: Create a cool app",
              "activityImage": "https://placekitten.com/200/200"
            },
            {
              "title": "Details",
              "facts": [
                {
                  "name": "Assigned to:",
                  "value": "[Larry Brown](mailto:larryb@example.com)"
                },
                {
                  "name": "State:",
                  "value": "Active"
                }
              ]
            }
          ]
        },
        "preview": {
          "contentType": "application/vnd.microsoft.card.thumbnail",
          "content": {
            "title": "85069: Create a cool app",
            "images": [
              {
                "url": "https://placekitten.com/200/200"
              }
            ]
          }
        }
      },
      {
        "contentType": "application/vnd.microsoft.card.adaptive",
        "content": {
          "type": "AdaptiveCard",
          "body": [
            {
              "type": "Container",
              "items": [
                {
                  "type": "TextBlock",
                  "text": "Microsoft Corp (NASDAQ: MSFT)",
                  "size": "medium",
                  "isSubtle": true
                },
                {
                  "type": "TextBlock",
                  "text": "September 19, 4:00 PM EST",
                  "isSubtle": true
                }
              ]
            },
            {
              "type": "Container",
              "spacing": "none",
              "items": [
                {
                  "type": "ColumnSet",
                  "columns": [
                    {
                      "type": "Column",
                      "width": "stretch",
                      "items": [
                        {
                          "type": "TextBlock",
                          "text": "75.30",
                          "size": "extraLarge"
                        },
                        {
                          "type": "TextBlock",
                          "text": "▼ 0.20 (0.32%)",
                          "size": "small",
                          "color": "attention",
                          "spacing": "none"
                        }
                      ]
                    },
                    {
                      "type": "Column",
                      "width": "auto",
                      "items": [
                        {
                          "type": "FactSet",
                          "facts": [
                            {
                              "title": "Open",
                              "value": "62.24"
                            },
                            {
                              "title": "High",
                              "value": "62.98"
                            },
                            {
                              "title": "Low",
                              "value": "62.20"
                            }
                          ]
                        }
                      ]
                    }
                  ]
                }
              ]
            }
          ],
          "version": "1.0"
        },
        "preview": {
          "contentType": "application/vnd.microsoft.card.thumbnail",
          "content": {
            "title": "Microsoft Corp (NASDAQ: MSFT)",
            "text": "75.30 ▼ 0.20 (0.32%)"
          }
        }
      }
    ]
  }
}

Standardabfrage

Wenn Sie initialRun true dies im Manifest festlegen, gibt Microsoft Teams eine Standardabfrage aus, wenn der Benutzer die Messaging-Erweiterung zum ersten Mal öffnet. Ihr Dienst kann auf diese Abfrage mit einer Reihe vorab ausgefüllter Ergebnisse antworten. Dies kann nützlich sein, um beispielsweise zuletzt angezeigte Elemente, Favoriten oder andere Informationen anzuzeigen, die nicht von benutzereingaben abhängig sind.

Die Standardabfrage weist die gleiche Struktur wie jede normale Benutzerabfrage auf, mit Ausnahme eines initialRun Parameters, dessen Zeichenfolgenwert true lautet.

Anforderungsbeispiel für eine Standardabfrage

{
  "type": "invoke",
  "name": "composeExtension/query",
  "value": {
    "commandId": "searchCmd",
    "parameters": [
      {
        "name": "initialRun",
        "value": "true"
      }
    ],
    "queryOptions": {
      "skip": 0,
      "count": 25
    }
  },
  ⋮
}

Identifizieren des Benutzers

Jede Anforderung an Ihre Dienste enthält die verborgene ID des Benutzers, der die Anforderung ausgeführt hat, sowie den Anzeigenamen des Benutzers und Azure Active Directory Objekt-ID.

"from": {
  "id": "29:1C7dbRrC_5yzN1RGtZIrcWT0xz88KPGP9sxdpVpV8sODlgPHeQE9RqQ02hnpuKzy6zZ-AaZx6swUOMj_Dsdse3TQ4sIaeebbFBF-VgjJy_nY",
  "name": "Larry Jin",
  "aadObjectId": "cd723fa0-0591-416a-9290-e93ecf3a9b92"
},

Die id und die Werte sind garantiert die des aadObjectId authentifizierten Teams Benutzers. Sie können als Schlüssel zum Nachschlagen von Anmeldeinformationen oder eines zwischengespeicherten Status in Ihrem Dienst verwendet werden. Darüber hinaus enthält jede Anforderung die Azure Active Directory Mandanten-ID des Benutzers, die verwendet werden kann, um die Organisation des Benutzers zu identifizieren. Falls zutreffend, enthält die Anforderung auch die Team- und Kanal-IDs, von denen die Anforderung stammt.

Authentifizierung

Wenn Ihr Dienst eine Benutzerauthentifizierung erfordert, müssen Sie sich beim Benutzer anmelden, bevor er die Messaging-Erweiterung verwenden kann. Wenn Sie einen Bot oder eine Registerkarte geschrieben haben, die sich beim Benutzer anmeldet, sollte dieser Abschnitt vertraut sein.

Die Sequenz sieht wie folgt aus:

  1. Der Benutzer gibt eine Abfrage aus, oder die Standardabfrage wird automatisch an Ihren Dienst gesendet.
  2. Ihr Dienst überprüft, ob sich der Benutzer zuerst authentifiziert hat, indem er die Teams-Benutzer-ID überprüft.
  3. Wenn sich der Benutzer nicht authentifiziert hat, senden Sie eine auth Antwort mit einer vorgeschlagenen Aktion einschließlich der openUrl Authentifizierungs-URL zurück.
  4. Der Microsoft Teams-Client startet ein Popupfenster, in dem Ihre Webseite mithilfe der angegebenen Authentifizierungs-URL gehostet wird.
  5. Nachdem sich der Benutzer angemeldet hat, sollten Sie Ihr Fenster schließen und einen "Authentifizierungscode" an den Teams Client senden.
  6. Der Teams-Client sendet dann die Abfrage erneut an Ihren Dienst, der den in Schritt 5 übergebenen Authentifizierungscode enthält.

Ihr Dienst sollte überprüfen, ob der in Schritt 6 empfangene Authentifizierungscode mit dem aus Schritt 5 übereinstimmt. Dadurch wird sichergestellt, dass ein böswilliger Benutzer nicht versucht, den Anmeldefluss zu spoofen oder zu kompromittieren. Dadurch wird die Schleife "geschlossen", um die sichere Authentifizierungssequenz abzuschließen.

Antworten mit einer Anmeldeaktion

Um einen nicht authentifizierten Benutzer zur Anmeldung aufzufordern, antworten Sie mit einer vorgeschlagenen Aktion vom openUrl Typ, die die Authentifizierungs-URL enthält.

Antwortbeispiel für eine Anmeldeaktion

{
  "composeExtension":{
    "type":"auth",
    "suggestedActions":{
      "actions":[
        {
          "type": "openUrl",
          "value": "https://example.com/auth",
          "title": "Sign in to this app"
        }
      ]
    }
  }
}

Hinweis

Damit die Anmeldeumgebung in einem Teams Popup gehostet werden kann, muss sich der Domänenteil der URL in der Liste der gültigen Domänen Ihrer App befinden. Weitere Informationen finden Sie unter "validDomains" im Manifestschema.

Starten des Anmeldeflusses

Ihre Anmeldeerfahrung sollte reaktionsfähig sein und in ein Popupfenster passen. Es sollte in das Microsoft Teams JavaScript-Client-SDKintegriert werden, das die Nachrichtenübergabe verwendet.

Wie bei anderen eingebetteten Oberflächen, die in Microsoft Teams ausgeführt werden, muss Ihr Code innerhalb des Fensters zuerst aufgerufen microsoftTeams.initialize() werden. Wenn Ihr Code einen OAuth-Fluss durchführt, können Sie die Teams Benutzer-ID an Ihr Fenster übergeben, die sie dann an die OAuth-Anmelde-URL übergeben kann.

Abschließen des Anmeldeflusses

Wenn die Anmeldeanforderung abgeschlossen ist und zurück zu Ihrer Seite geleitet wird, sollten die folgenden Schritte ausgeführt werden:

  1. Generieren Sie einen Sicherheitscode. (Dies kann eine Zufallszahl sein.) Sie müssen diesen Code in Ihrem Dienst zusammen mit den Anmeldeinformationen zwischenspeichern, die über den Anmeldefluss abgerufen werden, z. B. OAuth 2.0-Token.
  2. Rufen Sie microsoftTeams.authentication.notifySuccess den Sicherheitscode auf, und übergeben Sie ihn.

An diesem Punkt wird das Fenster geschlossen, und das Steuerelement wird an den Teams Client übergeben. Der Client kann jetzt die ursprüngliche Benutzerabfrage zusammen mit dem Sicherheitscode in der Eigenschaft erneut state ausführen. Ihr Code kann den Sicherheitscode verwenden, um die zuvor gespeicherten Anmeldeinformationen nachzuschlagen, um die Authentifizierungssequenz abzuschließen und dann die Benutzeranforderung abzuschließen.

Beispiel für erneutesued-Anforderung

{
    "name": "composeExtension/query",
    "value": {
        "commandId": "insertWiki",
        "parameters": [{
            "name": "searchKeyword",
            "value": "lakers"
        }],
        "state": "12345",
        "queryOptions": {
            "skip": 0,
            "count": 25
        }
    },
    "type": "invoke",
    "timestamp": "2017-04-26T05:18:25.629Z",
    "localTimestamp": "2017-04-25T22:18:25.629-07:00",
    "entities": [{
        "type": "clientInfo",
        "country": "US",
        "platform": "Web",
        
    }],
    "text": "",
    "attachments": [],
    "address": {
        "id": "f:7638210432489287768",
        "channelId": "msteams",
        "user": {
            "id": "29:1A5TJWHkbOwSyu_L9Ktk9QFI1d_kBOEPeNEeO1INscpKHzHTvWfiau5AX_6y3SuiOby-r73dzHJ17HipUWqGPgw",
            "aadObjectId": "fc8ca1c0-d043-4af6-b09f-141536207403"
        },
        "conversation": {
            "id": "19:7705841b240044b297123ad7f9c99217@thread.skype"
        },
        "bot": {
            "id": "28:c073afa8-7e77-4f92-b3e7-aa589e952a3e",
            "name": "maotestbot2"
        },
        "serviceUrl": "https://smba.trafficmanager.net/amer-client-ss.msg/",
        "useAuth": true
    },
    "source": "msteams"
}

SDK-Unterstützung

.NET

Um Abfragen mit dem Bot Builder SDK für .NET zu empfangen und zu verarbeiten, können Sie nach dem invoke Aktionstyp für die eingehende Aktivität suchen und dann die Hilfsmethode im NuGet-Paket "Microsoft.Bot.Connector.Teams" verwenden, um zu ermitteln, ob es sich um eine Messaging-Erweiterung handelt.

Beispielcode in .NET

public async Task<HttpResponseMessage> Post([FromBody]Activity activity)
{
    if (activity.Type == ActivityTypes.Invoke) // Received an invoke
    {
        if (activity.IsComposeExtensionQuery())
        {
            // This is the response object that will get sent back to the messaging extension request.
            ComposeExtensionResponse invokeResponse = null;

            // This helper method gets the query as an object.
            var query = activity.GetComposeExtensionQueryData();

            if (query.CommandId != null && query.Parameters != null && query.Parameters.Count > 0)
            {
                // query.Parameters has the parameters sent by client
                var results = new ComposeExtensionResult()
                {
                    AttachmentLayout = "list",
                    Type = "result",
                    Attachments = new List<ComposeExtensionAttachment>(),
                };
                invokeResponse.ComposeExtension = results;
            }

            // Return the response
            return Request.CreateResponse<ComposeExtensionResponse>(HttpStatusCode.OK, invokeResponse);
        } else
        {
            // Handle other types of Invoke activities here.
        }
    } else {
      // Failure case catch-all.
      var response = Request.CreateResponse(HttpStatusCode.BadRequest);
      response.Content = new StringContent("Invalid request! This API supports only messaging extension requests. Check your query and try again");
      return response;
    }
}

Node.js

Beispielcode in Node.js

require('dotenv').config();

import * as restify from 'restify';
import * as builder from 'botbuilder';
import * as teamBuilder from 'botbuilder-teams';

class App {
    run() {
        const server = restify.createServer();
        let teamChatConnector = new teamBuilder.TeamsChatConnector({
            appId: process.env.MICROSOFT_APP_ID,
            appPassword: process.env.MICROSOFT_APP_PASSWORD
        });

        // Command ID must match what's defined in manifest
        teamChatConnector.onQuery('<%= commandId %>',
            (event: builder.IEvent,
            query: teamBuilder.ComposeExtensionQuery,
            callback: (err: Error, result: teamBuilder.IComposeExtensionResponse, statusCode: number) => void) => {
                // Check for initialRun; i.e., when you should return default results
                // if (query.parameters[0].name === 'initialRun') {}

                // Check query.queryOptions.count and query.queryOptions.skip for paging

                // Return auth response
                // let response = teamBuilder.ComposeExtensionResponse.auth().actions([
                //     builder.CardAction.openUrl(null, 'https://authUrl', 'Please sign in')
                // ]).toResponse();

                // Return config response
                // let response = teamBuilder.ComposeExtensionResponse.config().actions([
                //     builder.CardAction.openUrl(null, 'https://configUrl', 'Please sign in')
                // ]).toResponse();

                // Return result response
                let response = teamBuilder.ComposeExtensionResponse.result('list').attachments([
                    new builder.ThumbnailCard()
                        .title('Test thumbnail card')
                        .text('This is a test thumbnail card')
                        .images([new builder.CardImage().url('https://bot-framework.azureedge.net/bot-icons-v1/bot-framework-default-9.png')])
                        .toAttachment()
                ]).toResponse();
                callback(null, response, 200);
            });
        server.post('/api/composeExtension', teamChatConnector.listen());
        server.listen(process.env.PORT, () => console.log(`listening to port:` + process.env.PORT));
    }
}

const app = new App();
app.run();

Siehe auch

Bot Framework-Beispiele.