Создание вкладок с использованием адаптивных карточек

Предупреждение

Вкладки адаптивных карточек недоступны в новом клиенте Teams. Ожидается, что классический клиент Teams станет нерекомендуемым до 31 марта 2024 г. Если в приложении используются вкладки адаптивной карточки, рекомендуется перестроить вкладку как веб-вкладку. Дополнительные сведения см. в разделе Создание вкладок для Teams.

При разработке вкладки с помощью традиционного метода могут возникнуть следующие проблемы.

  • Вопросы HTML и CSS
  • Длительная загрузка
  • Ограничения iFrame
  • Обслуживание и затраты сервера

Вы можете создавать вкладки адаптивных карточек в Teams. Вместо того, чтобы внедрять веб-содержимое в iFrame, можно преобразовать адаптивные карточки на вкладку. В то время как внешний интерфейс отображается с помощью адаптивных карточек, серверная часть работает на основе бота. Бот отвечает за принятие запросов и соответствующий ответ с помощью отрисованной адаптивной карточки.

Вы можете создавать вкладки с помощью готовых рабочих блоков пользовательского интерфейса на компьютере, в Интернете и на мобильных устройствах. Эта статья поможет вам понять, какие изменения необходимо внести в манифест приложения. В этой статье также описано, как действие вызова запрашивает и отправляет сведения на вкладке с адаптивными карточками, а также его влияние на рабочий процесс модального диалога (в TeamsJS версии 1.x называется модальным модулем задач).

На следующем рисунке показаны вкладки сборки с адаптивными карточками на настольных компьютерах и мобильных устройствах.

Снимок экрана: пример адаптивной карточки, отображаемой на вкладках.

Предварительные условия

Прежде чем приступить к созданию вкладок с помощью адаптивных карточек, необходимо сделать следующее.

Изменения манифеста приложения

Личные приложения, которые отрисовывают вкладки, должны включать массив staticTabs в манифест приложения. Вкладки адаптивной карточки отрисовываются, когда свойство contentBotId предоставляется в определении staticTab. Определения статических вкладок должны содержать либо contentBotId, указывая вкладку адаптивной карточки, либо contentUrl, указывая типичную вкладку с веб-содержимым.

Примечание.

Свойство contentBotId доступно в манифесте версии 1.9 или более поздней.

Предоставьте свойству contentBotIdbotId, с которым адаптивная карточка должна взаимодействовать. Класс 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/fetch и tab/submit — это действия, которые охватываются в этом разделе.

Примечание.

  • Ботам необходимо отправлять все ответы на URL-адрес службы. URL-адрес службы получен в составе входящей полезной нагрузки activity.
  • Размер полезной нагрузки вызова увеличен до 80 КБ.

Извлечение адаптивной карточки для отрисовки на вкладке

tab/fetch — это первый запрос на вызов, который ваш бот получает, когда пользователь открывает вкладку адаптивной карточки. Когда бот получает запрос, он отправляет ответ о продолжении или вкладку аутетификация в ответ. Ответ continue включает массив для карточек, который отображается вертикально вкладке в другом массиве.

Примечание.

Дополнительные сведения об ответе auth см. в разделе Проверка подлинности.

Следующий код содержит примеры запроса 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.

Когда пользователь нажал кнопку на вкладке адаптивной карточки, запрос tab/submit запускается к боту с соответствующими данными через функцию Action.Submit адаптивной карточки. Данные адаптивной карточки доступны через свойство данных запроса tab/submit. Вы получите один из следующих ответов на ваш запрос:

  • Код состояния HTTP 200 не имеет тела. Две сотни пустых ответов не приводит к никаким действиям клиента.
  • Стандартная 200 вкладка continue отвечать, как объяснено в разделе Адаптивная карточка. Отклик вкладки continue активирует клиента, чтобы обновить отрисовку адаптивной карточки с помощью адаптивных карточек, предоставленных в массиве карточек отклика continue.

Следующий код содержит примеры запроса 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/fetch для вызова и task/submit запросов и ответов. Дополнительные сведения см. в статье Использование диалогов в ботах Microsoft Teams.

С появлением вкладки "Адаптивная карточка" изменилось то, как бот отвечает на запрос task/submit. Если вы используете вкладку Адаптивная карточка, бот отвечает на task/submit запрос вызова стандартной вкладкой continue и закрывает диалоговое окно. Вкладка "Адаптивная карточка" обновляется путем отрисовки нового списка карточек, предоставленных в основной части отклика на вкладке continue.

Вызов 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 могут иметь ответ continue или auth. Когда запрос tab/fetch запускается и получает в ответ вкладку auth, пользователю отображается страница входа.

Получение кода проверки подлинности через вызов tab/fetch

  1. Откройте приложение. Появится страница входа.

    Примечание.

    Логотип приложения предоставляется через свойство icon, определенное в манифесте приложения. Заголовок, который появляется после определения логотипа в свойстве title, возвращаемом в теле ответа auth.

  2. Щелкните ссылку Войти. Вы будете перенаправлены на URL-адрес проверки подлинности, предоставленный в свойстве value в теле ответа auth.

  3. Открывается всплывающее окно. Это всплывающее окно размещено на веб-странице с использованием URL-адреса проверки подлинности.

  4. После входа закройте окно. Код проверки подлинности отправляется в клиент Teams.

  5. Затем клиент Teams повторно передает запрос tab/fetch службе, которая включает код проверки подлинности, предоставленный вашей веб-страницей.

Поток данных проверки подлинности tab/fetch

На следующем изображении представлен обзор работы потока данных проверки подлинности для вызова tab/fetch.

Снимок экрана: пример потока проверки подлинности вкладок адаптивной карточки.

tab/fetch: ответ auth

Этот фрагмент программного кода представляет собой пример ответа на проверку подлинности 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

Пошаговые инструкции

Следуйте инструкциям из пошагового руководства по созданию вкладки с адаптивными карточками.

Следующее действие

См. также