次の方法で共有


API ベースのメッセージ拡張機能

注:

API ベースのメッセージ拡張機能では、検索コマンドのみがサポートされます。

API (API ベース) を使用して構築されたメッセージ拡張機能では、Web サービスを使用してユーザーの要求と応答を管理し、ボットの登録は必要ありません。 API ベースのメッセージ拡張機能は、外部 API を Teams に直接統合し、アプリの使いやすさを高め、シームレスなユーザー エクスペリエンスを提供する、Microsoft Teamsアプリ機能です。 API ベースのメッセージ拡張機能は検索コマンドをサポートしており、Teams 内の外部サービスからデータをフェッチして表示するために使用でき、アプリケーション間の切り替えの必要性を減らすことでワークフローを合理化できます。 API ベースのメッセージ拡張機能は、アプリがサードパーティのデータ、アプリ、およびサービスと直接対話し、その機能を強化するのに役立ちます。 API ベースのメッセージ拡張機能を使用すると、次のことができます。

  • 製品発売時の最新ニュースカバレッジなど、リアルタイムの情報を取得します。
  • Figma でチームのデザイン ファイルなど、知識ベースの情報を取得する

Teams Toolkit を使用して API ベースのメッセージ拡張機能を構築する方法の詳細については、ビデオを参照してください。


従来のボットベースのメッセージ拡張機能 API ベースのメッセージ拡張機能
開発者は、Teams クライアントからの呼び出しコマンドを処理するサービスを構築、展開、保守する必要があります。 OpenAPI 仕様を使用してエンド サービスの API を記述できる場合、開発者は中間層処理サービスの必要性を排除できます。
このサービスは、受信クエリを処理し、開発者のエンド サービスを呼び出します。 Teams は 、OpenAPI 仕様 を直接使用して要求を作成し、開発者のエンド サービスと通信できます。

次の画像は、従来のメッセージ拡張機能と API メッセージ拡張機能を介したユーザー クエリのフローを示しています。

スクリーンショットは、従来のメッセージ拡張機能を使用したユーザー、Teams クライアント、および Teams ボット サービス間のユーザー クエリ フローを示しています。この図では、API 仕様、レンダリング テンプレート、API の相互関係も示しています。 従来のメッセージ拡張機能を使用したユーザー クエリ フロー。開発者は、Teams ボットからの要求を処理するカスタム ボット ハンドラー サービスを維持する必要があります。ハンドラー サービスは、クエリが呼び出されたときに開発者のサービスに要求を送信します。


API メッセージ拡張機能を使用したユーザー、Teams クライアント、および Teams ボット サービス間のクエリ フローを示すスクリーンショット。この図では、API 仕様、レンダリング テンプレート、API の相互関係も示しています。 API メッセージ拡張機能を使用したユーザー クエリ フロー。アプリ パッケージの OpenAPI 仕様で相互作用が明確に説明されている限り、開発者が管理するハンドラー サービスは必要ありません。



クエリ コマンドの呼び出し中に発生するイベントの概要を次に示します。

  1. ユーザーがクエリ コマンドを呼び出すと、クエリ コマンドのパラメーターが Teams Bot Serviceによって受信されます。

  2. クエリ コマンドは、アプリ マニフェスト ファイル内で定義されます。 コマンド定義には、OpenAPI 仕様ファイル内の への operationId 参照と、そのコマンドに対して Teams クライアントがレンダリングするパラメーターの詳細が含まれています。 参考までに、 operationId OpenAPI 仕様ファイル内の は、特定の HTTP 操作に固有です。

  3. その後、Teams Bot Serviceは、ユーザーが指定したパラメーターと、関連付けられている operationId の OpenAPI 仕様のコピーを使用して、開発者のエンドポイントの HTTP 要求を構築します。

  4. 認証が必要で、マニフェストで構成されている場合。 適切なトークンまたはキーに解決されます。 このトークンまたはキーは、送信要求の一部として使用されます。 [必要に応じて]

  5. Teams ボット サービスは、開発者のサービスに対して HTTP 要求を実行します。

  6. 開発者のサービスは、OpenAPI 仕様に記載されているスキーマに従って応答する必要があります。 これは JSON 形式です。

  7. Teams クライアントは、結果をユーザーに表示し直す必要があります。 前の手順の JSON 結果を UI に変換するために、Teams ボット サービスは応答レンダリング テンプレートを使用して、結果ごとにアダプティブ カードを構築します。

  8. アダプティブ カードはクライアントに送信され、UI でレンダリングされます。

API ベースのメッセージ拡張機能でクエリが呼び出されたときの大まかなシーケンス フローを示す図。

前提条件

アプリ定義パッケージには、この機能をサポートするさまざまな魅力的な成果物が含まれています。 作業を開始する前に、次のファイルの基本的な理解があることを確認してください。

OpenAPI Description (OAD)

OpenAPI description documenat は、API を記述するための業界標準として採用されています。 これにより、API を実装から抽象化し、人間が読み取り可能でコンピューターが読み取り可能な言語に依存しない定義を提供できます。 OpenAPI の説明 documenat では、拡張機能でサポートされる相互作用の概要が説明されています。これにより、Teams は、中間層処理サービスを必要とせずに、要求を構築し、サービスと直接通信できます。

OpenAPI の説明ドキュメントには、開発者のサービスと通信するための詳細が含まれています。 OpenAPI Description (OAD) ドキュメントの次のガイドラインに従っていることを確認します。

  • OpenAPI バージョン 2.0 および 3.0.x がサポートされています。
  • JSON と YAML は、サポートされている形式です。
  • 要求本文が存在する場合は、application/Json である必要があります。
  • プロパティの HTTPS プロトコル サーバー URL を servers.url 定義します。
  • POST メソッドと GET HTTP メソッドのみがサポートされています。
  • OpenAPI Description ドキュメントには、 が必要です operationId
  • 既定値のない必須パラメーターは 1 つだけ許可されます。
  • 既定値の必須パラメーターは省略可能と見なされます。
  • ユーザーは、ヘッダーまたは Cookie のパラメーターを入力しないでください。
  • 操作には、既定値のない必須のヘッダーパラメーターまたは Cookie パラメーターを含めてはいけません。
  • OpenAPI 説明ドキュメントにリモート参照がないことを確認します。
  • 要求の配列の構築はサポートされていません。ただし、JSON 要求本文内の入れ子になったオブジェクトはサポートされています。
  • Teams は、、anyOfallOf、および not (swagger.io) コンストラクトをサポートoneOfしていません。

次のコードは、OpenAPI Description ドキュメントの例です。

OpenAPI 説明ドキュメントのサンプル
openapi: 3.0.1
info:
title: OpenTools Plugin
description: A plugin that allows the user to find the most appropriate AI tools for their use cases, with their pricing information.
version: 'v1'
servers:
- url: https://gptplugin.opentools.ai
paths:
/tools:
 get:
   operationId: searchTools
   summary: Search for AI Tools
   parameters:
     - in: query
       name: search
       required: true
       schema:
         type: string
       description: Used to search for AI tools by their category based on the keywords. For example, ?search="tool to create music" will give tools that can create music.
   responses:
     "200":
       description: OK
       content:
         application/json:
           schema:
             $ref: '#/components/schemas/searchToolsResponse'
     "400":
       description: Search Error
       content:
         application/json:
           schema:
             $ref: '#/components/schemas/searchToolsError'
components:
schemas:
 searchToolsResponse:
   required:
     - search
   type: object
   properties:
     tools:
       type: array
       items:
         type: object
         properties:
           name:
             type: string
             description: The name of the tool.
           opentools_url:
             type: string
             description: The URL to access the tool.
           main_summary:
             type: string
             description: A summary of what the tool is.
           pricing_summary:
             type: string
             description: A summary of the pricing of the tool.
           categories:
             type: array
             items:
               type: string
             description: The categories assigned to the tool.
           platforms:
             type: array
             items:
               type: string
             description: The platforms that this tool is available on.
       description: The list of AI tools.
 searchToolsError:
   type: object
   properties:
     message:
       type: string
       description: Message of the error.

YAML で OpenAPI 定義を記述する方法の詳細については、「OpenAPI 構造体」を参照してください。

アプリ マニフェスト

アプリ マニフェストは Teams アプリのブループリントであり、Teams クライアント内でメッセージ拡張機能を呼び出す方法と場所を定義します。 これには、拡張機能でサポートされているコマンドと、メッセージの作成領域、コマンド バー、メッセージなど、アクセスできる場所が含まれます。 マニフェストは、適切な機能を確保するために、OpenAPI 仕様と応答レンダリング テンプレートにリンクします。

アプリ マニフェストには、クエリ コマンド定義が含まれています。 アプリ マニフェストの次のガイドラインに従っていることを確認します。

  • アプリ マニフェストのバージョンを に設定します 1.17
  • を に設定 composeExtensions.composeExtensionType します apiBased
  • フォルダー内の OpenAPI 説明ドキュメントへの相対パスとして定義 composeExtensions.apiSpecificationFile します。 これにより、アプリ マニフェストが API 仕様にリンクされます。
  • 応答レンダリング テンプレートへの相対パスとして定義 apiResponseRenderingTemplateFile します。 これは、API 応答のレンダリングに使用されるテンプレートの場所を指定します。
  • 各コマンドには、応答レンダリング テンプレートへのリンクが必要です。 これにより、各コマンドが対応する応答形式に接続されます。
  • アプリ マニフェストのプロパティは Commands.id 、OpenAPI 説明ドキュメントの と operationId 一致する必要があります。
  • 必須パラメーターに既定値がない場合、アプリ マニフェストのコマンド parameters.name は OpenAPI 説明ドキュメントの と parameters.name 一致する必要があります。
  • 必要なパラメーターがない場合、アプリ マニフェストのコマンド parameters.name は、OpenAPI Description ドキュメントの省略可能な parameters.name コマンドと一致する必要があります。
  • アプリ マニフェスト内の各コマンドのパラメーター名が、OpenAPI Description ドキュメントの操作に対して定義されているパラメーターの対応する名前と正確に一致していることを確認します。
  • 応答レンダリング テンプレートは、API からの応答を変換するために使用されるコマンドごとに定義する必要があります。
  • コマンドとパラメーターの説明は、128 文字を超えてはなりません。

API ベースのメッセージ拡張機能の定義を含むアプリ マニフェストの例を次に示します。

アプリ マニフェストの例
 {
 "$schema": "https://developer.microsoft.com/json-schemas/teams/vDevPreview/MicrosoftTeams.schema.json",
 +  "manifestVersion": "devPreview",
 "version": "1.0.0",
 "id": "04805b4b-xxxx-xxxx-xxxx-4dbc1cac8f89",
 "packageName": "com.microsoft.teams.extension",
 "developer": {
    "name": "Teams App, Inc.",
    "websiteUrl": "https://www.example.com",
    "privacyUrl": "https://www.example.com/termofuse",
    "termsOfUseUrl": "https://www.example.com/privacy"
 },
 "icons": {
    "color": "color.png",
    "outline": "outline.png"
 },
 "name": {
    "short": "AI tools",
    "full": "AI tools"
 },
 "description": {
    "short": "AI tools",
    "full": "AI tools"
 },
 "accentColor": "#FFFFFF",
 "composeExtensions": [
    {
 +      "composeExtensionType": "apiBased",
 +      "authorization": {
 +        "authType": "apiSecretServiceAuth ",
 +        "apiSecretServiceAuthConfiguration": {
 +            "apiSecretRegistrationId": "96270b0f-7298-40cc-b333-152f84321813"
 +        }
 +      },
 +      "apiSpecificationFile": "aitools-openapi.yml",
       "commands": [
       {
          "id": "searchTools",
          "type": "query",
          "context": [
             "compose",
             "commandBox"
          ],
          "title": "search for AI tools",
          "description": "search for AI tools",
          "parameters": [
             {
             "name": "search",
             "title": "search query",
             "description": "e.g. search='tool to create music'"
             }
          ],
 +          "apiResponseRenderingTemplateFile": "response-template.json"
       }
       ]
    }
 ],
 "validDomains": []
 }

パラメーター

名前 説明
composeExtensions.composeExtensionType Compose拡張機能の種類。 値を に更新します apiBased
composeExtensions.authorization API ベースのメッセージ拡張機能の承認に関する情報
composeExtensions.authorization.authType 可能な承認の種類の列挙型。 サポートされている値は noneapiSecretServiceAuthmicrosoftEntra です。
composeExtensions.authorization.apiSecretServiceAuthConfiguration サービス認証を実行するために必要なオブジェクトキャプチャの詳細。認証の種類が である apiSecretServiceAuth場合にのみ適用されます。
composeExtensions.authorization.apiSecretServiceAuthConfiguration.apiSecretRegistrationId 開発者が開発者ポータルを介して API キーを送信したときに返される登録 ID。
composeExtensions.apiSpecificationFile アプリ パッケージ内の OpenAPI Description ファイルを参照します。 型が の場合は apiBasedを含めます。
composeExtensions.commands.id 検索コマンドに割り当てる一意の ID。 ユーザー要求には、この ID が含まれています。 ID は、OpenAPI 説明で使用可能な ID と一致 operationId している必要があります。
composeExtensions.commands.context メッセージ拡張のエントリ ポイントが定義されている配列。 既定値は と commandBoxですcompose
composeExtensions.commands.parameters コマンドのパラメーターの静的リストを定義します。 この名前は、OpenAPI Description 内の にマップ parameters.name する必要があります。 要求本文スキーマでプロパティを参照している場合は、名前を パラメーターまたはクエリ パラメーターにマップする properties.name 必要があります。
composeExtensions.commands.apiResponseRenderingTemplateFile 開発者の API からアダプティブ カード応答への JSON 応答の書式設定に使用されるテンプレート。 [必須]

詳細については、「 composeExtensions」を参照してください。

応答レンダリング テンプレート

注:

Teams では、バージョン 1.5 までのアダプティブ カードがサポートされています。 アダプティブ カード デザイナーを使用する場合は、ターゲット バージョンを 1.5 に変更してください。

応答レンダリング テンプレートは、API からの結果を Teams 内でどのように表示するかを指定する定義済みの形式です。 テンプレートを使用して API の応答からアダプティブ カードやその他の UI 要素を作成し、Teams 内でシームレスで統合されたユーザー エクスペリエンスを確保します。 テンプレートは、表示される情報のレイアウトとスタイルを定義します。これには、テキスト、画像、対話型コンポーネントを含めることができます。 応答レンダリング テンプレートの次のガイドラインに従っていることを確認します。

  • 応答レンダリング テンプレート スキーマに対するテンプレートの構造を確立するには、 プロパティで$schemaスキーマ参照 URL を定義します。
  • でサポートされている値 responseLayoutlistgridであり、応答がどのように視覚的に表示されるかを決定します。 レイアウトの詳細については、「 ユーザー要求への応答」を参照してください。
  • 配列 jsonPath の場合、またはアダプティブ カードのデータがルート オブジェクトではない場合は、 が再取得されます。 たとえば、データが の下 productDetailsに入れ子になっている場合、JSON パスは になります productDetails
  • API 応答の関連データまたは配列へのパスとして定義 jsonPath します。 パスが配列を指している場合、配列内の各エントリはアダプティブ カード テンプレートとバインドされ、個別の結果として返されます。 [省略可能]
  • 応答レンダリング テンプレートを検証するためのサンプル応答を取得します。 これは、テンプレートが期待どおりに動作することを確認するためのテストとして機能します。
  • Fiddler や Postman などのツールを使用して API を呼び出し、要求と応答が有効であることを確認します。 この手順は、API が正しく機能していることをトラブルシューティングして確認するために重要です。
  • アダプティブ カード Designerを使用して、API 応答を応答レンダリング テンプレートにバインドし、アダプティブ カードをプレビューできます。 カード ペイロード エディターにアダプティブ カード テンプレートを挿入し、サンプル データ エディターにサンプル応答エントリを挿入します。

次のコードは、応答レンダリング テンプレートの例です。

応答レンダリング テンプレートの例
{
"version": "1.0",
"$schema": "developer.microsoft.com/json-schemas/teams/v1.17/MicrosoftTeams.ResponseRenderingTemplate.schema.json",
"jsonPath": "repairs",
"responseLayout": "grid",
"responseCardTemplate": {
  "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
  "type": "AdaptiveCard",
  "version": "1.4",
  "body": [
    {
      "type": "Container",
      "items": [
        {
          "type": "ColumnSet",
          "columns": [
            {
              "type": "Column",
              "width": "stretch",
              "items": [
                {
                  "type": "TextBlock",
                  "text": "Title: ${if(title, title, 'N/A')}",
                  "wrap": true
                },
                {
                  "type": "TextBlock",
                  "text": "Description: ${if(description, description, 'N/A')}",
                  "wrap": true
                },
                {
                  "type": "TextBlock",
                  "text": "Assigned To: ${if(assignedTo, assignedTo, 'N/A')}",
                  "wrap": true
                },
                {
                  "type": "Image",
                  "url": "${image}",
                  "size": "Medium",
                  "$when": "${image != null}"
                }
              ]
            },
            {
              "type": "Column",
              "width": "auto",
              "items": [
                {
                  "type": "Image",
                  "url": "${if(image, image, '')}",
                  "size": "Medium"
                }
              ]
            }
          ]
        },
        {
          "type": "FactSet",
          "facts": [
            {
              "title": "Repair ID:",
              "value": "${if(id, id, 'N/A')}"
            },
            {
              "title": "Date:",
              "value": "${if(date, date, 'N/A')}"
            }
          ]
        }
      ]
    }
  ]
  },
  "previewCardTemplate": {
  "title": "Title: ${if(title, title, 'N/A')}",
  "subtitle": "Description: ${if(description, description, 'N/A')}",
  "text": "Assigned To: ${if(assignedTo, assignedTo, 'N/A')}",
  "image": {
    "url": "${image}",
    "$when": "${image != null}"
    }
  }
 }

プレビュー カード

応答レンダリング テンプレート スキーマのプレビュー カード テンプレートは、JSON 応答を、ユーザーが検索結果を選択したときに表示されるプレビュー カードにマップするために使用されます。 プレビュー カードは、メッセージ作成ボックスのアダプティブ カードに展開されます。 プレビュー カード テンプレートは、アダプティブ カード テンプレートとメタデータも含む応答レンダリング テンプレートの一部です。

特定の単語を検索するときにプレビュー カードの配列を表示する新規作成拡張機能の例を示すスクリーンショット。この場合、'テスト アプリ' で 'a' を検索すると、それぞれ 'Title'、'Description' (切り捨てられた) および 'AssignedTo' のプロパティと値を示す 5 枚のカードが返されます。

拡張アダプティブ カード

ユーザーがプレビュー カードを選択した後のアダプティブ カードの展開の例。アダプティブ カードには、タイトル、完全な説明、AssignedTo、RepairId、および Date の値が表示されます。

パラメーター

プロパティ 説明 必須
version string 現在の応答レンダリング テンプレートのスキーマ バージョン。 はい
jsonPath string responseCardTemplate と previewCardTemplate を適用する必要がある結果の関連セクションへのパス。 設定されていない場合、ルート オブジェクトは関連セクションとして扱われます。 関連するセクションが配列の場合、各エントリは responseCardTemplate と previewCardTemplate にマップされます。 いいえ
responseLayout responseLayoutType メッセージ拡張ポップアップの結果のレイアウトを指定します。 サポートされている型は と gridですlist はい
responseCardTemplate adaptiveCardTemplate 結果エントリからアダプティブ カードを作成するためのテンプレート。 はい
previewCardTemplate previewCardTemplate 結果エントリからプレビュー カードを作成するためのテンプレート。 結果のプレビュー カードは、メッセージ拡張機能のポップアップ メニューに表示されます。 はい

Json パス

JSON パスは省略可能ですが、配列に使用するか、アダプティブ カードのデータとして使用するオブジェクトがルート オブジェクトではない場合に使用する必要があります。 JSON パスは、Newtonsoft によって定義された形式に従う必要があります。 このツールを使用できます。 JSON ツールを使用して、JSON パスが正しいかどうかを検証できます。 JSON パスが配列を指している場合、その配列内の各エントリはアダプティブ カード テンプレートにバインドされ、個別の結果として返されます。

たとえば、製品の一覧に対して次の JSON があり、エントリごとにカード結果を作成するとします。

{
   "version": "1.0",
   "title": "All Products",
   "warehouse": {
      "products": [
        ...
      ]
   }
}

ご覧のとおり、結果の配列は "products" の下にあり、これは "warehouse" の下に入れ子になっているため、JSON パスは "warehouse.products" になります。

を使用してhttps://adaptivecards.io/designer/、テンプレートを Card Payload エディターに挿入してアダプティブ カードをプレビューし、配列またはオブジェクトのサンプル応答エントリを取得し、右側の同じデータ エディターに挿入します。 カードが適切にレンダリングされ、好みに合っていることを確認します。 Teams はバージョン 1.5 までのカードをサポートし、デザイナーは 1.6 をサポートします。

OpenAPI スキーマ変換

注:

OpenAPI の説明ドキュメントで定義されているエンドポイントに送信される HTTP 要求で、受け入れ言語ヘッダーを送信します。 受け入れ言語は Teams クライアントロケールに基づいており、ローカライズされた応答を返す開発者が使用できます。

OpenAPI 記述ドキュメントの次のデータ型は、次のようにアダプティブ カード内の要素に変換されます。

  • stringnumberintegerboolean型は TextBlock に変換されます。

    • ソース スキーマ: string、、 numberintegerおよび boolean

       name:
         type: string
         example: doggie
      
    • ターゲット スキーマ: Textblock

      {
      "type": "TextBlock",
      "text": "name: ${if(name, name, 'N/A')}",
      "wrap": true
      }
      
  • array: 配列はアダプティブ カード内のコンテナーに変換されます。

    • ソース スキーマ: array

          type: array
                    items:
                    required:
                      - name
                    type: object
                      properties:
                      id:
                        type: integer
                      category:
                        type: object
                        properties:
                        name:
                          type: string
      
    • ターゲット スキーマ: Container

          {
                    "type": "Container",
                    "$data": "${$root}",
                    "items": [
                      {
                        "type": "TextBlock",
                        "text": "id: ${if(id, id, 'N/A')}",
                        "wrap": true
                      },
                      {
                        "type": "TextBlock",
                        "text": "category.name: ${if(category.name, category.name, 'N/A')}",
                        "wrap": true
                      }
                    ]
                  }
      
      
  • object: オブジェクトがアダプティブ カードの入れ子になったプロパティに変換されます。

    • ソース スキーマ: object

      components:
        schemas:
          Pet:
              category:
                type: object
              properties:
                id:
                  type: integer
                name:
                  type: string
      
      
    • ターゲット スキーマ: アダプティブ カードの入れ子になったプロパティ

      {
        "type": "TextBlock",
        "text": "category.id: ${if(category.id, category.id, 'N/A')}",
        "wrap": true
      },
      {
        "type": "TextBlock",
        "text": "category.name: ${if(category.name, category.name, 'N/A')}",
        "wrap": true
      }
      
      
  • image: プロパティがイメージ URL の場合は、アダプティブ カードの Image 要素に変換されます。

    • ソース スキーマ: image

          image:
            type: string
            format: uri
            description: The URL of the image of the item to be repaired
      
      
    • ターゲット スキーマ: "Image"

      {
            "type": "Image",
            "url": "${image}",
            "$when": "${image != null}"
          }
      
      

次の手順