アダプティブ カードを使用してタブをビルドする

警告

アダプティブ カード タブは、新しい Teams クライアントでは使用できません。 クラシック Teams クライアントは、2024 年 3 月 31 日までに非推奨となる予定です。 アプリでアダプティブ カード タブを使用している場合は、Web ベースのタブとしてタブを再構築することをお勧めします。詳細については、「 Teams のタブをビルドする」を参照してください。

従来の方法を使用してタブを開発する場合、次の問題が発生する可能性があります。

  • HTML と CSS
  • 読み込み時間が遅い
  • iFrame 制約
  • サーバーのメンテナンスとコスト

Teams でアダプティブ カード タブを構築できます。 Web コンテンツを iFrame に埋め込む代わりに、アダプティブ カードをタブにレンダリングできます。フロントエンドはアダプティブ カードでレンダリングされますが、バックエンドはボットによって動作します。 ボットは、要求を受け入れ、レンダリングされるアダプティブ カードで適切に応答する役割を担います。

デスクトップ、Web、モバイルでネイティブな既製のユーザー インターフェイス (UI) 構成要素を使用してタブを構築できます。 この記事は、アプリ マニフェストに対して行う必要がある変更を理解するのに役立ちます。 また、この記事では、呼び出しアクティビティがアダプティブ カードを使用してタブで情報を要求および送信する方法と、モーダル ダイアログ (TeamsJS v1.x のタスク モジュールと呼ばれる) ワークフローへの影響についても説明します。

次の図は、デスクトップとモバイルのアダプティブ カードを含むビルド タブを示しています。

スクリーンショットは、タブにレンダリングされたアダプティブ カードの例を示しています。

前提条件

アダプティブ カードを使用してタブを作成する前に、次の作業を行う必要があります。

アプリ マニフェストの変更

タブをレンダリングする個人用アプリには、アプリ マニフェストに staticTabs 配列を含める必要があります。 アダプティブ カード タブは、contentBotId プロパティが staticTab 定義で指定されたときにレンダリングされます。 静的タブ定義には、アダプティブ カード タブを指定する contentBotId または一般的なホストされた Web コンテンツ タブ エクスペリエンスを指定する contentUrl のいずれかが含まれている必要があります。

注:

プロパティは contentBotId マニフェスト バージョン 1.9 以降で使用できます。

[アダプティブ カード] タブが通信する必要のある botIdcontentBotId プロパティに指定します。 [アダプティブ カード] タブ用に構成された entityId は、各呼び出し要求の tabContext パラメーターで送信され、同じボットから電力を供給されるアダプティブ カード タブを区別するために使用できます。 その他の静的タブ定義フィールドの詳細については、[マニフェスト スキーマ] を参照してください。

アダプティブ カード タブ マニフェストの例を次に示します。

{
  "$schema": "https://raw.githubusercontent.com/OfficeDev/microsoft-teams-app-schema/preview/DevPreview/MicrosoftTeams.schema.json",
  "manifestVersion": "1.9",
  "id": "00000000-0000-0000-0000-000000000000",
  "version": "0.0.1",
  "developer": {
    "name": "Contoso",
    "websiteUrl": "https://contoso.yourwebsite.com",
    "privacyUrl": "https://contoso.yourwebsite.com/privacy.html",
    "termsOfUseUrl": "https://contoso.yourwebsite.com/terms.html"
  },
  "name": {
    "short": "Contoso",
    "full": "Contoso Home"
  },
  "description": {
    "short": "Add short description here",
    "full": "Add full description here"
  },
  "icons": {
    "outline": "icon-outline.png",
    "color": "icon-color.png"
  },
  "accentColor": "#D85028",
  "configurableTabs": [],
  "staticTabs": [
    {
      "entityId": "homeTab",
      "name": "Home",
      "contentBotId": "00000000-0000-0000-0000-000000000000",
      "scopes": ["personal"]
    },
    {
      "entityId": "moreTab",
      "name": "More",
      "contentBotId": "00000000-0000-0000-0000-000000000000",
      "scopes": ["personal"]
    }
  ],
  "connectors": [],
  "composeExtensions": [],
  "permissions": ["identity", "messageTeamMembers"],
  "validDomains": [
    "contoso.yourwebsite.com",
    "token.botframework.com"
  ]
}

アクティビティを呼び出す

アダプティブ カード タブとボット間の通信は、invoke アクティビティを通じて行われます。 各 invoke アクティビティには、対応する 名前が付けられます。 各アクティビティの名前を使用して、各要求を区別します。 tab/fetchtab/submit は、このセクションで取り上げるアクティビティです。

注:

  • ボットは、すべての応答を サービス URL に送信する必要があります。 サービス URL は、着信 activity ペイロードの一部として受信されます。
  • 呼び出しペイロード のサイズが 80kb に増加しました。

タブにレンダリングするアダプティブ カードをフェッチする

tab/fetch は、ユーザーがアダプティブ カード タブを開いたときにボットが受信する最初の呼び出し要求です。 ボットがリクエストを受信すると、タブ [続行] 応答またはタブ [認証] 応答のいずれかを送信します。 [続行] 応答には [カード] の配列が含まれており、配列の順序でタブに垂直方向にレンダリングされます。

注:

[認証] 応答の詳細については、「認証」を参照してください。

次のコードは、tab/fetch 要求と応答の例を示しています。

tab/fetch要求

// tab/fetch POST request: agents/{botId}/invoke
{
    "name": "tab/fetch",
    "value: {
        "tabContext": {
            "tabEntityId": "{tab_entity_id}"
        },
        "context": {
            "theme": "default"
            }
    },
    "conversation": {
        "id": "{generated_conversation_id}"
    },
    "imdisplayname": "{user_display_name}"
}

tab/fetch応答

// tab/fetch **continue** POST response:
{
    "tab": {
        "type": "continue",
        "value": {
            "cards": [
                {
                    "card": adaptiveCard1,
                },
                {
                    "card": adaptiveCard2,
                },
                {
                    "card": adaptiveCard3
                }  
            ]
        },
    },
    "responseType": "tab"
}

アダプティブ カードからの送信を処理する

アダプティブ カードがタブにレンダリングされると、ユーザーの操作に応答できます。 この応答は、tab/submit 呼び出し要求によって処理されます。

ユーザーが [アダプティブ カード] タブのボタンを選択すると、アダプティブ カードの Action.Submit 機能を使用して、対応するデータを使用してボットに tab/submit 要求が トリガーされます。 アダプティブ カード データは、tab/submit 要求のデータ プロパティを使用して使用できます。 要求に対して次のいずれかの応答を受け取ります。

  • 本文のない HTTP 状態コード 200 応答。 空の 200 応答では、クライアントによってアクションが実行されることはありません。
  • アダプティブ カードのフェッチで説明されているように、標準 200 タブは応答を続行します。 タブの応答を続行すると、クライアントはレンダリングされたアダプティブ カード タブを、継続応答のカード配列に用意されたアダプティブ カードで更新します。

次のコードは、tab/submit 要求と応答の例を示しています。

tab/submit要求

// tab/submit POST request: agents/{botId}/invoke:
{
    "name": "tab/submit",
    "value": {
        "data": {
            "type": "tab/submit",
            //...<data properties>
            },
        "context": {
            "theme": "default"
            },
        "tabContext": {
            "tabEntityId": "{tab_entity_id}"
            },
        },
    "conversation": {
           "id": "{generated_conversation_id}" 
        },
    "imdisplayname": "{user_display_name}"
}

tab/submit応答

//tab/fetch **continue** POST response:
{
    "tab": {
        "type": "continue",
        "value": {
            "cards": [
              {
                "card": adaptiveCard1,
                },
              {
                "card": adaptiveCard2,
                } 
            ]
        },
    },
    "responseType": "tab"
}

ダイアログ ワークフローについて

モーダル ダイアログでは、アダプティブ カードを使用して、要求とtask/submit応答を呼び出task/fetchすこともできます。 詳細については、「 Microsoft Teams ボットでのダイアログの使用」を参照してください。

[アダプティブ カード] タブの導入により、ボットが task/submit リクエストに応答する方法が変更されました。 [アダプティブ カード] タブを使用している場合、ボットは呼び出し要求に task/submit 応答し、標準タブ の続行 応答を使用してダイアログを閉じます。 [アダプティブ カード] タブは、[続行] タブの応答本文で提供されるカードの新しいリストをレンダリングすることで更新されます。

task/fetch を呼び出す

次のコードは、task/fetch 要求と応答の例を示しています。

task/fetch要求

// task/fetch POST request: agents/{botId}/invoke
{
    "name": "task/fetch",
    "value": {
        "data": {
            "type": "task/fetch"
        },
        "context": {
            "theme": "default",
        },
        "tabContext": {
            "tabEntityId": "{tab_entity_id}"
        }
    },
    "imdisplayname": "{user_display_name}",
    "conversation": {
        "id": "{generated_conversation_id}"
    } 
}

task/fetch応答

// task/fetch POST response: agents/{botId}/invoke
{
    "task": {
        "value": {
            "title": "Ninja Cat",
            "height": "small",
            "width": "small",
            "card": {
                "contentType": "application/vnd.microsoft.card.adaptive",
                "content": adaptiveCard,
            }
        },
    "type": "continue"
    },
    "responseType": "task"
}

task/submit を呼び出す

次のコードは、task/submit 要求と応答の例を示しています。

task/submit要求

// task/submit POST request: agent/{botId}/invoke:
{
    "name": "task/submit",
    "value": {
        "data": {serialized_data_object},
        "context": {
            "theme": "default"
        },
    "tabContext": {
        "tabEntityId": "{tab_entity_id}"
        },
    },
    "conversation": {
        "id": "{generated_conversation_id}"
    },
    "imdisplayname": "{user_display_name}",
}

task/submit Tab 応答の種類

// tab/fetch **continue** POST response: 
{
    "task":{
        "value": {
            "tab": {
                "type": "continue",
                "value": {
                    "cards": [
                        {
                            "card": adaptiveCard1
                        },
                        {
                            "card": adaptiveCard2
                        }
                    ]
                }
            }
        },
        "type": "continue"
    },
    "responseType": "task"
}

認証

前のセクションでは、ほとんどの開発パラダイムをダイアログの要求と応答からタブ要求と応答に拡張できることを確認しました。 認証の処理に関しては、[アダプティブ カード] タブのワークフローは、メッセージ拡張の認証パターンに従います。 詳細については、「認証の追加」を参照してください。

tab/fetch 要求には、[続行] または [認証] レスポンスのいずれかを含めることができます。 tab/fetch 要求がトリガーされ、タブ [認証] 応答を受信すると、サインイン ページがユーザーに表示されます。

tab/fetch[呼び出し] を使用して認証コードを取得するには

  1. アプリを開きます。 サインイン ページが表示されます。

    注:

    アプリ のロゴは、アプリ マニフェストで定義されている icon プロパティを通じて提供されます。 ロゴの後に表示されるタイトルは、タブ [認証] 応答本文に返される title プロパティで定義されています。

  2. [サインイン] を選びます。 [認証] 応答本文の value プロパティで提供される認証 URL にリダイレクトされます。

  3. ポップアップ ウィンドウが表示されます。 このポップアップ ウィンドウでは、認証 URL を使用して Web ページをホストします。

  4. サインインした後、ウィンドウを閉じます。 認証コードは、Teams クライアントに送信されます。

  5. その後、Teams クライアントはサービスへのtab/fetch要求を再発行します。これには、ホストされている Web ページによって提供される認証コードが含まれます。

tab/fetch 認証データ フロー

次の図は、tab/fetch 呼び出しに対する認証データ フローのしくみの概要を示しています。

アダプティブ カード タブ認証フローの例を示すスクリーンショット。

tab/fetch 認証応答

次のコードは、tab/fetch 認証応答の例を示しています。

// tab/auth POST response (openURL)
{
    "tab": {
        "type": "auth",
        "suggestedActions":{
            "actions":[
                {
                    "type": "openUrl",
                    "value": "https://example.com/auth",
                    "title": "Sign in to this app"
                }
            ]
        }
    }
}

次のコードは、再発行された要求の例を示しています。

{
    "name": "tab/fetch",
    "type": "invoke",
    "timestamp": "2021-01-15T00:10:12.253Z",
    "channelId": "msteams",
    "serviceUrl": "https://smba.trafficmanager.net/amer/",
    "from": {
        "id": "{id}",
        "name": "John Smith",
        "aadObjectId": "00000000-0000-0000-0000-000000000000"
    },
    "conversation": {
        "tenantId": "{tenantId}",
        "id": "tab:{guid}"
    },
    "recipients": {
        "id": "28:00000000-0000-0000-0000-000000000000",
        "name": "ContosoApp"
    },
    "entities": [
        {
            "locale": "en-us",
            "country": "US",
            "platform": "Windows",
            "timezone": "America/Los_Angeles",
            "type": "clientInfo"
        }
    ],
    "channelData": {
        "tenant": { "id": "00000000-0000-0000-0000-000000000000" },
        "source": { "name": "message" }
    },
    "value": {
        "tabContext": { "tabEntityId": "homeTab" },
        "state": "0.43195668034524815"
    },
    "locale": "en-US",
    "localTimeZone": "America/Los_Angeles"
}

コード サンプル

サンプルの名前 説明 .NET Node.js マニフェスト
[Teams] タブにアダプティブ カードを表示する Microsoft Teams タブ サンプル コードです。これは、Teams でアダプティブ カードを表示する方法を示しています。 表示 表示 表示

ステップ バイ ステップのガイド

ステップ バイ ステップ ガイドに従って、アダプティブ カードを使用してタブを構築します。

次の手順

関連項目