Freigeben über


Suche mit Nachrichtenerweiterungen

Wichtig

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

Suchbasierte Nachrichtenerweiterungen ermöglichen es Ihnen, Ihren Dienst abzufragen und diese Informationen in Form einer Karte direkt in Ihrer Nachricht zu posten.

Screenshot: Beispiel einer Karte für die Nachrichtenerweiterung.

In den folgenden Abschnitten wird die Vorgehensweise beschrieben:

Hinzufügen einer Nachrichtenerweiterung zu Ihrer App

Eine Nachrichtenerweiterung ist ein in der Cloud gehosteter Dienst, der auf Benutzeranforderungen lauscht und mit strukturierten Daten wie einer Karte antwortet. Sie integrieren Ihren Dienst über Bot Framework-Objekte Activity in Microsoft Teams. Unsere .NET- und Node.js-Erweiterungen für das Bot Builder SDK können Ihnen helfen, Ihrer App Nachrichtenerweiterungsfunktionen hinzuzufügen.

Screenshot, der die aktionsbasierte Nachrichtenerweiterung in Teams zeigt.

Registrieren im Bot Framework

Sie müssen zunächst einen Bot beim Microsoft Bot Framework registrieren. Die Microsoft-App-ID und die Rückrufendpunkte für Ihren Bot, wie dort definiert, werden in Ihrer Nachrichtenerweiterung verwendet, um Benutzeranforderungen zu empfangen und darauf zu reagieren. Denken Sie daran, den Microsoft Teams-Kanal für Ihren Bot zu aktivieren.

Notieren Sie sich ihre Bot-App-ID und das App-Kennwort. Sie müssen die App-ID in Ihrem App-Manifest angeben.

Aktualisieren Ihres App-Manifests

Wie bei Bots und Registerkarten aktualisieren Sie das Manifest Ihrer App, um die Nachrichtenerweiterungseigenschaften einzuschließen. Diese Eigenschaften steuern, wie Ihre Nachrichtenerweiterung im Microsoft Teams-Client angezeigt wird und wie sie sich verhält. Nachrichtenerweiterungen werden ab Manifest v1.0 unterstützt.

Deklarieren Der Nachrichtenerweiterung

Um eine Nachrichtenerweiterung hinzuzufügen, fügen Sie eine neue JSON-Struktur der obersten Ebene in Ihr Manifest mit der -Eigenschaft ein composeExtensions . Sie können nur eine einzelne Nachrichtenerweiterung für Ihre App erstellen.

Hinweis

Das Manifest bezieht sich auf Nachrichtenerweiterungen als composeExtensions. Dies dient der 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 identisch sein. Ja
scopes Array, das angibt, ob diese Erweiterung zu - oder team -Bereichen (oder beides) hinzugefügt personal werden kann. Ja
canUpdateConfiguration Aktiviert das Menüelement "Einstellungen ". Nein
commands Array von Befehlen, die diese Nachrichtenerweiterung unterstützt. Sie sind auf 10 Befehle beschränkt. Ja

Hinweis

Wenn Sie die canUpdateConfiguration -Eigenschaft im App-Manifest auf true festlegen, können Sie das Menüelement Einstellungen für Ihre Nachrichtenerweiterung anzeigen. Um Einstellungen zu aktivieren, müssen Sie auch und onSettingsUpdatebehandelnonQuerySettingsUrl.

Definieren von Befehlen

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

Screenshot: Beispiel mit einer Liste von Nachrichtenerweiterungen in Teams

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

Eigenschaftenname Zweck Pflichtfeld? Minimale Manifestversion
id Eindeutige ID, die Sie diesem Befehl zuweisen. Die Benutzeranforderung enthält diese ID. Ja 1.0
title Befehlsname. Dieser Wert wird auf der Benutzeroberfläche angezeigt. Ja 1.0
description Hilfetext, der angibt, was dieser Befehl bewirkt. Dieser Wert wird auf der Benutzeroberfläche angezeigt. Ja 1.0
type Legen Sie den Typ des Befehls fest. Mögliche Werte sind query und action. Wenn nicht vorhanden, wird der Standardwert auf queryfestgelegt. Nein 1.4
initialRun Optionaler Parameter, der mit query Befehlen verwendet wird. Wenn dieser Wert auf true festgelegt ist, gibt an, dass dieser Befehl ausgeführt werden soll, sobald der Benutzer diesen Befehl auf der Benutzeroberfläche auswäht. Nein 1.0
fetchTask Optionaler Parameter, der mit action Befehlen verwendet wird. Legen Sie diesen Wert auf true fest, um die adaptive Karte oder Web-URL abzurufen, die im Aufgabenmodul angezeigt werden soll. Dies wird verwendet, wenn die Eingabe für den action Befehl dynamisch ist, 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 und ein Beispiel für den Wert, der bereitgestellt werden soll. Dieser Wert wird auf der Benutzeroberfläche angezeigt. Ja 1.0
parameter.title Kurzer benutzerfreundlicher Parametertitel oder -bezeichnung. Ja 1.0
parameter.inputType Legen Sie auf den typ der erforderlichen Eingabe fest. Mögliche Werte sind text, textarea, number, date, time, . toggle Der Standardwert ist auf textfestgelegt. Nein 1.4
context Optionales Array von Werten, das den Kontext definiert, in dem die Nachrichtenaktion verfügbar ist. Mögliche Werte sind message, composeoder commandBox. Der Standardwert ist ["compose", "commandBox"]. Nein 1,5

Nachrichtenerweiterungen vom Suchtyp

Legen Sie für die suchbasierte Nachrichtenerweiterung den type Parameter auf fest query. Im Folgenden finden Sie ein Beispiel für ein Manifest mit einem einzelnen Suchbefehl. Einer einzelnen Nachrichtenerweiterung können bis zu 10 verschiedene Befehle zugeordnet sein. Dies kann sowohl mehrere Such- als auch mehrere aktionsbasierte Befehle umfassen.

Beispiel für 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",
  "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 Nachrichtenerweiterung testen, indem Sie Ihre App hochladen.

Um Ihre Nachrichtenerweiterung zu öffnen, wechseln 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 Nachrichtenerweiterung aus.

Hinzufügen von Ereignishandlern

Der Großteil Ihrer Arbeit umfasst das onQuery -Ereignis, das alle Interaktionen im Nachrichtenerweiterungsfenster behandelt.

Wenn Sie im Manifest auf true festlegencanUpdateConfiguration, aktivieren Sie das Menüelement Einstellungen für Ihre Nachrichtenerweiterung und müssen auch und onSettingsUpdatebehandelnonQuerySettingsUrl.

Behandeln von onQuery-Ereignissen

Eine Nachrichtenerweiterung empfängt ein onQuery Ereignis, wenn etwas im Nachrichtenerweiterungsfenster geschieht oder an das Fenster gesendet wird.

Wenn Ihre Nachrichtenerweiterung eine Konfigurationsseite verwendet, sollte Ihr Handler für onQuery zuerst nach gespeicherten Konfigurationsinformationen suchen. Wenn die Nachrichtenerweiterung nicht konfiguriert ist, geben Sie eine config Antwort mit einem Link zu Ihrer Konfigurationsseite zurück. Die Antwort von der Konfigurationsseite wird auch von onQuerybehandelt. Die einzige Ausnahme ist, wenn die Konfigurationsseite vom Handler für onQuerySettingsUrlaufgerufen wird. Weitere Informationen finden Sie im folgenden Abschnitt:

Wenn Ihre Nachrichtenerweiterung 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 Artikel.

Überprüfen Sie als Nächstes, ob initialRun festgelegt ist. Wenn ja, führen Sie entsprechende Maßnahmen aus, z. B. Das Bereitstellen von Anweisungen oder eine Liste von Antworten.

Der Rest des Handlers für onQuery fordert 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

Die onQuerySettingsUrl Ereignisse und onSettingsUpdate werden zusammen verwendet, um das Menüelement Einstellungen zu aktivieren.

Screenshot: Speicherorte des Menüelements

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

Empfangen und Beantworten von Abfragen

Jede Anforderung an Ihre Nachrichtenerweiterung erfolgt über ein Activity -Objekt, das an Ihre Rückruf-URL gesendet wird. Die Anforderung enthält Informationen zum Benutzerbefehl, z. B. ID- und Parameterwerte. Die Anforderung enthält auch Metadaten zum 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 Bot Framework-Standardobjekt Activity . Ihr Dienst sollte seine Logik für eine Activity ausführen, die auf invoke einen unterstützten Typ festgelegt und name auf einen unterstützten composeExtensions Typ festgelegt hattype, wie in der folgenden Tabelle gezeigt.

Zusätzlich zu den Standardmäßigen Botaktivitätseigenschaften enthält die Nutzlast die folgenden Anforderungsmetadaten:

Eigenschaftenname Zweck
type Art der Anforderung; muss sein invoke.
name Art des Befehls, der für Ihren Dienst ausgegeben wird. Die folgenden Typen werden unterstützt:
composeExtension/query
composeExtension/querySettingUrl
composeExtension/setting
composeExtension/selectItem
composeExtension/queryLink
from.id ID des Benutzers, der die Anforderung gesendet hat.
from.name Name des Benutzers, der die Anforderung gesendet hat.
from.aadObjectId Microsoft Entra-Objekt-ID des Benutzers, der die Anforderung gesendet hat.
channelData.tenant.id Microsoft Entra-Mandanten-ID.
channelData.channel.id Kanal-ID (wenn die Anforderung in einem Kanal erfolgt ist).
channelData.team.id Team-ID (wenn die Anforderung in einem Kanal erfolgt ist).
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 erkannten Speicherort des Benutzers.
Das platform Feld beschreibt die Messagingclientplattform.
Weitere Informationen finden Sie unterNicht-IRI-Entitätstypen – clientInfo.

Die Anforderungsparameter befinden sich im Value-Objekt, das die folgenden Eigenschaften enthält:

Eigenschaftenname Zweck
commandId Der Name des vom Benutzer aufgerufenen Befehls, der mit einem der im App-Manifest deklarierten Befehle übereinstimmt.
parameters Array von Parametern: Jedes Parameterobjekt enthält den Parameternamen zusammen mit dem 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"
    }
  ]
}

Alternativ (oder zusätzlich) zum Durchsuchen Ihres externen Diensts können Sie eine in das Meldungsfeld zum Verfassen eingefügte URL verwenden, um Ihren Dienst abzufragen und eine Karte zurückzugeben. Im folgenden Screenshot hat ein Benutzer eine URL für ein Arbeitselement in Azure DevOps eingefügt, das die Nachrichtenerweiterung in eine Karte aufgelöst hat.

Screenshot: Beispiel für das Entpacken von Links

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

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

Nachdem Sie die Domäne hinzugefügt haben, um am App-Manifest zu lauschen, müssen Sie Ihren Botcode so ändern, dass er auf die folgende Aufrufanforderung antwortet .

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

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

Reagieren auf Benutzeranforderungen

Wenn der Benutzer eine Abfrage ausführt, gibt Teams eine synchrone HTTP-Anforderung an Ihren Dienst aus. Während dieser Zeit hat Ihr Code 5 Sekunden Zeit, um eine HTTP-Antwort auf die Anforderung bereitzustellen. Während dieser Zeit kann Ihr Dienst eine weitere Suche oder eine andere Geschäftslogik durchführen, die für die Anforderung erforderlich ist.

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

Eigenschaftenname Zweck
composeExtension Antwortumschlag der obersten Ebene.
composeExtension.type Typ der Antwort. 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 Nachrichtenerweiterung einzurichten.
message: zeigt eine Nur-Text-Nachricht an.
composeExtension.attachmentLayout Gibt das Layout der Anlagen an. Wird für Antworten vom Typ resultverwendet.
Die folgenden Typen werden 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 resultverwendet.
Die folgenden Typen werden 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 configverwendet.
composeExtension.text Anzuzeigende Meldung. Wird für Antworten vom Typ messageverwendet.

Antwortkartentypen und Vorschauen

Wir unterstützen die folgenden Anlagentypen:

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

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

Weitere Informationen zur Connectorkarte für Microsoft 365-Gruppen finden Sie unter Verwenden der Connectorkarte für Microsoft 365-Gruppen.

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

  • Verwenden der preview -Eigenschaft im attachment -Objekt. Die preview Anlage kann nur eine Hero- oder Miniaturansichtskarte sein.
  • Extrahiert aus den grundlegenden titleEigenschaften , textund 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 Karte oder einer Connectorkarte für Microsoft 365-Gruppen in der Ergebnisliste anzeigen, indem Sie einfach ihre Vorschaueigenschaft festlegen. Dies ist nicht erforderlich, wenn die Ergebnisse bereits Hero- oder Miniaturansichtskarten sind. Wenn Sie die Vorschauanlage verwenden, muss es sich entweder um eine Hero- oder Miniaturansichtskarte handelt. 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, die verschiedene Kartenformate kombinieren: Connector für Microsoft 365-Gruppen und Adaptive. Obwohl Sie wahrscheinlich bei einem Kartenformat in Ihrer Antwort bleiben möchten, wird gezeigt, wie die preview -Eigenschaft jedes Elements in der attachments Auflistung explizit eine Vorschau im 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 im Manifest auf true festlegeninitialRun, gibt Microsoft Teams eine "Standardabfrage" aus, wenn der Benutzer die Nachrichtenerweiterung zum ersten Mal öffnet. Ihr Dienst kann auf diese Abfrage mit einer Reihe vorab aufgefüllter Ergebnisse antworten. Dies kann nützlich sein, um beispielsweise zuletzt angezeigte Elemente, Favoriten oder andere Informationen anzuzeigen, die nicht von der Benutzereingabe abhängig sind.

Die Standardabfrage hat dieselbe Struktur wie jede reguläre Benutzerabfrage, mit Ausnahme eines Parameters initialRun , dessen Zeichenfolgenwert ist true.

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 verschleierte ID des Benutzers, der die Anforderung ausgeführt hat, sowie den Anzeigenamen des Benutzers und die Microsoft Entra-Objekt-ID.

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

Die id Werte und aadObjectId entsprechen garantiert dem des authentifizierten Teams-Benutzers. Sie können als Schlüssel verwendet werden, um Anmeldeinformationen oder einen zwischengespeicherten Zustand in Ihrem Dienst nachzuschlagen. Darüber hinaus enthält jede Anforderung die Microsoft Entra-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 den Benutzer anmelden, bevor der Benutzer die Nachrichtenerweiterung verwenden kann. Wenn Sie einen Bot oder eine Registerkarte geschrieben haben, die den 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 openUrl vorgeschlagenen Aktion einschließlich der Authentifizierungs-URL zurück.
  4. Der Microsoft Teams-Client startet ein Popupfenster, in dem Ihre Webseite mit 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 gibt die Abfrage dann erneut an Ihren Dienst aus, die den in Schritt 5 übergebenen Authentifizierungscode enthält. Ihr Dienst muss überprüfen, ob der in Schritt 6 empfangene Authentifizierungscode mit dem aus Schritt 5 übereinstimmt, wodurch sichergestellt wird, dass ein böswilliger Benutzer nicht versucht, den Anmeldeflow zu spoofen oder zu kompromittieren. Dies wird effektiv „die Schleife schließen“, 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 Typ openUrl, welche 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 Anmeldeoberfläche 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 Anmeldeflows

Ihre Anmeldung muss reaktionsfähig sein und in ein Popupfenster passen. Sie sollte in das Microsoft Teams JavaScript-Client SDK integriert werden, das die Nachrichtenübergabe verwendet.

Wie bei anderen eingebetteten Umgebungen, die in Teams ausgeführt werden, muss Ihr Code im Fenster zuerst aufrufen microsoftTeams.initialize(). Wenn Ihr Code einen OAuth-Flow ausführt, können Sie die Teams-Benutzer-ID an Ihr Fenster übergeben, die sie dann an die URL der OAuth-Anmelde-URL übergeben kann.

Abschließen des Anmeldeflows

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

  1. Generieren sie einen Sicherheitscode. (Dies kann eine Zufallszahl sein.) Sie müssen diesen Code zusammen mit den Anmeldeinformationen, die sie durch die Anmeldung erhalten haben, wie z. B. OAuth 2.0-Token, in Ihrem Dienst zwischenspeichern.
  2. Rufen Sie microsoftTeams.authentication.notifySuccess auf, und übergeben Sie den Sicherheitscode.

An diesem Punkt wird das Fenster geschlossen, und die Steuerung wird an den Teams-Client übergeben. Der Client kann nun die ursprüngliche Benutzerabfrage zusammen mit dem Sicherheitscode in der state -Eigenschaft erneut 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 neu ausgestellte 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 den Aktionstyp für die eingehende Aktivität überprüfen invoke und dann die Hilfsmethode im NuGet-Paket Microsoft.Bot.Connector.Teams verwenden, um zu bestimmen, ob es sich um eine Nachrichtenerweiterungsaktivität 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