具有自适应卡片的生成选项卡

警告

自适应卡片选项卡在新 Teams 客户端中不可用。 经典 Teams 客户端预计将在 2024 年 3 月 31 日弃用。 如果你的应用使用自适应卡片选项卡,我们建议将选项卡重新生成为基于 Web 的选项卡。有关详细信息,请参阅 Teams 的“生成”选项卡

使用传统方法开发选项卡时,可能会遇到以下问题:

  • HTML 和 CSS 注意事项
  • 加载时间缓慢
  • iFrame 约束
  • 服务器维护和成本

可以在 Teams 中生成自适应卡片选项卡。 可以将自适应卡片呈现到选项卡,而不是在 iFrame 中嵌入 Web 内容。使用自适应卡呈现前端时,后端由机器人提供支持。 机器人负责接受请求,并使用呈现的自适应卡片进行适当的响应。

可以在桌面、Web 和移动设备上使用现成的用户界面(UI)构建基块来生成选项卡。 本文可帮助你了解需对应用清单执行的更改。 本文还介绍了如何使用自适应卡片在选项卡中调用活动请求和发送信息,以及它在 TeamsJS v1.x) 工作流中称为任务模块 (模式对话框的影响。

下图显示了如何在桌面和移动设备中使用自适应卡片生成选项卡:

屏幕截图显示了在选项卡中呈现的自适应卡片的示例。

先决条件

在开始使用自适应卡片生成选项卡之前,必须:

对应用清单的更改

呈现选项卡的个人应用必须在其应用清单中包含 staticTabs 数组。 在 staticTab 定义中提供 contentBotId 属性时,会呈现自适应卡片选项卡。 静态选项卡定义必须包含 contentBotId 以指定自适应卡片选项卡,或包含 contentUrl 以指定典型的托管 Web 内容选项卡体验。

注意

属性 contentBotId 在清单版本 1.9 或更高版本中可用。

contentBotId 属性提供自适应卡片选项卡必须与之通信的 botId。 为自适应卡片选项卡配置的 entityId 在每个调用请求的 tabContext 参数z 发送,可用于区分由同一机器人提供支持的自适应卡片选项卡。 有关其他静态选项卡定义字段的详细信息,请参阅 清单架构

以下是自适应卡片选项卡清单示例:

{
  "$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/fetchtask/submit 请求和响应。 有关详细信息,请参阅 在 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/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 托管网页。

  4. 登录后,关闭窗口。 身份验证代码 会发送到 Teams 客户端。

  5. 然后,Teams 客户端会向服务重新发出 tab/fetch 请求,其中包括托管网页提供的身份验证代码。

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 中显示自适应卡片。 View View View

分步指南

按照 分步 指南使用自适应卡片生成选项卡。

后续步骤

另请参阅