Инициирование действий с расширениями для обмена сообщениями

Важно!

Статьи в этом разделе основаны на пакете SDK Bot Framework версии 3. Если вы ищете текущую документацию (версии 4.6 или более поздней версии пакета SDK), см. раздел Взаимодействие с расширениями сообщений, ориентированное на задачи .

Расширения сообщений на основе действий позволяют пользователям активировать действия во внешних службах во время работы в Teams.

На снимку экрана показан пример расширения сообщения карта.

Добавление расширения сообщений в приложение

Расширение сообщений — это облачная служба, которая прослушивает запросы пользователей и отвечает структурированными данными, такими как карта. Вы интегрируете службу с Microsoft Teams с помощью объектов Bot Framework Activity . Расширения .NET и Node.js для пакета SDK Bot Builder помогут вам добавить в приложение функциональные возможности расширения сообщений.

Снимок экрана: расширение сообщений на основе действий в Teams.

Регистрация в Bot Framework

Если вы еще не сделали этого, сначала необходимо зарегистрировать бота в Microsoft Bot Framework. Идентификатор приложения Майкрософт и конечные точки обратного вызова для бота, как определено там, будут использоваться в вашем расширении сообщений для получения запросов пользователей и ответа на них. Не забудьте включить канал Microsoft Teams для бота.

Запишите идентификатор приложения бота и пароль приложения. Необходимо указать идентификатор приложения в манифесте приложения.

Обновление манифеста приложения

Как и в случае с ботами и вкладками, вы обновляете манифест приложения, включив в него свойства расширения сообщений. Эти свойства определяют, как расширение сообщений отображается и ведет себя в клиенте Microsoft Teams. Расширения сообщений поддерживаются начиная с манифеста версии 1.0.

Объявление расширения сообщений

Чтобы добавить расширение сообщения, добавьте в манифест новую структуру JSON верхнего уровня со свойством composeExtensions . В настоящее время вы можете создать одно расширение сообщений для приложения.

Примечание.

Манифест ссылается на расширения сообщений как composeExtensions. Это необходимо для обеспечения обратной совместимости.

Определение расширения — это объект, имеющий следующую структуру:

Имя свойства Назначение Обязательный?
botId Уникальный идентификатор приложения Майкрософт для бота, зарегистрированный в Bot Framework. Обычно он должен совпадать с идентификатором общего приложения Teams. Да
scopes Массив, объявляющий, может ли это расширение быть добавлено в personal области или team (или и то, и другое). Да
canUpdateConfiguration Включает пункт меню "Параметры ". Нет
commands Массив команд, поддерживаемых этим расширением сообщений. Вы можете использовать только 10 команд. Да

Определение команд

Расширение сообщений должно объявить одну команду, которая появляется, когда пользователь выбирает приложение с помощью кнопки Дополнительные параметры () в поле создания.

Снимок экрана: пример, на котором показан список расширений сообщений в Teams.

В манифесте приложения элемент команды представляет собой объект со следующей структурой:

Имя свойства Назначение Обязательный? Минимальная версия манифеста
id Уникальный идентификатор, назначенный этой команде. Запрос пользователя будет включать этот идентификатор. Да 1.0
title Имя команды. Это значение выводится в пользовательском интерфейсе. Да 1.0
description Текст справки, указывающий, что делает эта команда. Это значение выводится в пользовательском интерфейсе. Да 1.0
type Задайте тип команды. Возможные значения: query и action. Если этот параметр отсутствует, по умолчанию задается queryзначение . Нет 1.4
initialRun Необязательный параметр, используемый с query командами. Если задано значение true, указывает, что эта команда должна быть выполнена, как только пользователь выберет эту команду в пользовательском интерфейсе. Нет 1.0
fetchTask Необязательный параметр, используемый с action командами. Задайте значение true, чтобы получить адаптивный карта или URL-адрес веб-сайта, отображаемый в модуле задачи. Используется, если входные данные action команды являются динамическими, а не статическими наборами параметров. Обратите внимание, что если задано значение true, статический список параметров для команды игнорируется. Нет 1.4
parameters Статический список параметров для команды. Да 1.0
parameter.name Имя параметра. Оно отправляется в службу в составе запроса пользователя. Да 1.0
parameter.description Описывает цели этого параметра и пример значения, которое должно быть предоставлено. Это значение выводится в пользовательском интерфейсе. Да 1.0
parameter.title Короткое понятное название параметра или метка. Да 1.0
parameter.inputType Задайте необходимый тип входных данных. Возможные значения: text, textarea, number, date, time, . toggle По умолчанию задано значение text. Нет 1.4
context Необязательный массив значений, определяющий контекст, в который доступно действие сообщения. Возможные значения: message, composeили commandBox. Значение по умолчанию: ["compose", "commandBox"]. Нет 1.5

Расширения сообщений типа действия

Чтобы инициировать действия из расширения сообщений, задайте type для параметра значение action. Одно расширение сообщений может содержать до 10 различных команд и включать несколько команд на основе поиска и действий.

Примечание.

justInTimeInstall функции при отправке приложения в каталог приложений, но при отправке пользовательского приложения происходит сбой.

Пример полного манифеста приложения

Следующий код является примером манифеста с поиском и командой create:

{
  "$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://todobotservice.azurewebsites.net/",
    "privacyUrl": "http://todobotservice.azurewebsites.net/privacy",
    "termsOfUseUrl": "http://todobotservice.azurewebsites.net/termsofuse"
  },
  "name": {
    "short": "To Do",
    "full": "To Do"
  },
  "description": {
    "short": "Find or create a new task in To Do",
    "full": "Find or create a new task in To Do"
  },
  "icons": {
    "outline": "todo-outline.jpg",
    "color": "todo-color.jpg"
  },
  "accentColor": "#ff6a00",
  "composeExtensions": [
    {
      "botId": "57a3c29f-1fc5-4d97-a142-35bb662b7b23",
      "canUpdateConfiguration": true,
      "commands": [
        {
          "id": "searchCmd",
          "description": "Search you Todo's",
          "title": "Search",
          "initialRun": true,
          "context": ["commandBox", "compose"],
          "parameters": [
            {
              "name": "searchKeyword",
              "description": "Enter your search keywords",
              "title": "Keywords"
            }
          ]
        },
        {
          "id": "addTodo",
          "description": "Create a To Do item",
          "title": "Create To Do",
          "type": "action",
          "context": ["commandBox", "message", "compose"],
          "parameters": [
            {
              "name": "Name",
              "description": "To Do Title",
              "title": "Title",
              "inputType": "text"
            },
            {
              "name": "Description",
              "description": "Description of the task",
              "title": "Description",
              "inputType": "textarea"
            },
            {
              "name": "Date",
              "description": "Due date for the task",
              "title": "Date",
              "inputType": "date"
            }
          ]
        },
        {
          "id": "reassignTodo",
          "description": "Reassign a todo item",
          "title": "Reassign a todo item",
          "type": "action",
          "fetchTask": false,
          "parameters": [
            {
              "name": "Name",
              "title": "Title"
              "inputType": "text"
            }
          ]
        }
      ]
    }
  ],
  "permissions": [
    "identity",
    "messageTeamMembers"
  ],
  "validDomains": [
    "todobotservice.azurewebsites.net",
    "*.todobotservice.azurewebsites.net"
  ]
}

Инициализация действий из сообщений

Вы можете инициировать действия из области создания сообщений, а также из сообщения с помощью расширения сообщений, что позволяет отправлять содержимое сообщения боту для обработки. При необходимости можно ответить на это сообщение с помощью метода, описанного в разделе Ответить на отправку. Ответ включается в виде ответа на сообщение, которое пользователи могут изменить перед отправкой.

Пользователи могут получить доступ к расширению сообщений из параметра "Действие" в меню переполнения ... , как показано на следующем рисунке:

Снимок экрана: запуск действия из сообщения.

Чтобы расширение сообщений работало из сообщения, добавьте context параметр в объект расширения commands сообщения в манифесте приложения, как показано в следующем примере. Допустимые строки для массива context : "message", "commandBox"и "compose". Значение по умолчанию — ["compose", "commandBox"]. Полные сведения о параметре см. в context разделе Определение команд:

"composeExtensions": [
  {
    "botId": "57a3c29f-1fc5-4d97-a142-35bb662b7b23",
    "canUpdateConfiguration": true,
    "commands": [
      {
        "id": "reassignTodo",
        "description": "Reassign a todo item",
        "title": "Create To Do",
        "type": "Action",
        "context": ["message"],
        "fetchTask": true
    }]
    ...

Следующий код является примером объекта, value содержащего сведения о сообщении, которое отправляется в рамках composeExtensions запроса боту:

{
  "name": "composeExtension/submitAction",
  "type": "invoke",
...
  "value": {
    "commandId": "setReminder",
    "commandContext": "message",
    "messagePayload": {
      "id": "1111111111",
      "replyToId": null,
      "createdDateTime": "2019-02-25T21:29:36.065Z",
      "lastModifiedDateTime": null,
      "deleted": false,
      "subject": "Message subject",
      "summary": null,
      "importance": "normal",
      "locale": "en-us",
      "body": {
        "contentType": "html",
        "content": "this is the message"
    },
      "from": {
        "device": null,
        "conversation": null,
        "user": {
          "userIdentityType": "aadUser",
          "id": "wxyz12ab8-ab12-cd34-ef56-098abc123876",
          "displayName": "Jamie Smythe"
        },
        "application": null
      },
      "reactions": [
        {
          "reactionType": "like",
          "createdDateTime": "2019-02-25T22:40:40.806Z",
          "user": {
            "device": null,
            "conversation": null,
            "user": {
              "userIdentityType": "aadUser",
              "id": "qrst12346-ab12-cd34-ef56-098abc123876",
              "displayName": "Jim Brown"
            },
            "application": null
          }
        }
      ],
      "mentions": [
        {
          "id": 0,
          "mentionText": "Sarah",
          "mentioned": {
            "device": null,
            "conversation": null,
            "user": {
              "userIdentityType": "aadUser",
              "id": "ab12345678-ab12-cd34-ef56-098abc123876",
              "displayName": "Sarah"
            },
            "application": null
          }
        }
      ]
    }
  ...

Тестирование с помощью отправки

Вы можете протестировать расширение для сообщений, отправив приложение. Дополнительные сведения см. в разделе Отправка приложения в команду.

Чтобы открыть расширение для сообщений, перейдите в любой из чатов или каналов. Нажмите кнопку Дополнительные параметры () в поле создания и выберите расширение сообщения.

Сбор входных данных от пользователей

Существует три способа сбора информации от пользователя в Teams.

Статический список параметров

В этом методе достаточно определить статический список параметров в манифесте, как показано в команде Create To Do. Чтобы использовать этот метод, убедитесь fetchTask , что для параметра задано значение false и вы определяете параметры в манифесте.

Когда пользователь выбирает команду со статическими параметрами, Teams создает форму в модуле задач с заданными параметрами в манифесте. При нажатии кнопки composeExtensions/submitAction Submit боту отправляется объект . Дополнительные сведения об ожидаемом наборе ответов см. в разделе Реагирование на отправку.

Динамический ввод с помощью адаптивной карточки

В этом методе служба может определить пользовательскую адаптивную карточку для сбора входных данных пользователя. Для этого подхода задайте параметру fetchTask значение true в манифесте. Если задано значение fetchTasktrue, все статические параметры, определенные для команды, игнорируются.

В этом методе служба получает composeExtensions/fetchTask событие и отвечает ответом модуля задачи на основе адаптивной карточки. Ниже приведен пример ответа с адаптивной карточкой:

{
    "task": {
        "type": "continue",
        "value": {
            "card": {
                "contentType": "application/vnd.microsoft.card.adaptive",
                "content": {
                    "body": [
                        {
                            "type": "TextBlock",
                            "text": "Please enter the following information:"
                        },
                        {
                            "type": "TextBlock",
                            "text": "Name"
                        },
                        {
                            "type": "Input.Text",
                            "spacing": "None",
                            "title": "New Input.Toggle",
                            "placeholder": "Placeholder text"
                        },
                        {
                            "type": "TextBlock",
                            "text": "Date of birth"
                        },
                        {
                            "type": "Input.Date",
                            "spacing": "None",
                            "title": "New Input.Toggle"
                        }
                    ],
                    "type": "AdaptiveCard",
                    "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
                    "version": "1.0"
                }
            }
        }
    }
}

Бот также может ответить ответом проверки подлинности или конфигурации, если пользователю нужно пройти проверку подлинности или настроить расширение перед получением ввода пользователем.

Динамические входные данные с помощью веб-представления

В этом методе служба может отображать <iframe> мини-приложение на основе для отображения любого пользовательского интерфейса и сбора данных пользователя. Для этого подхода задайте параметру fetchTask значение true в манифесте.

Как и в потоке адаптивной карточки, служба отправляет fetchTask событие и отвечает ответом модуля задач на основе URL-адреса. Ниже приведен пример ответа с адаптивным карта:

{
    "task": {
        "value": {
            "url": "http://mywebapp.com/input"
        },
        "type": "continue"
    }
}

Запрос на установку бота для бесед

Если приложение содержит бот беседы, убедитесь, что он установлен в беседе перед загрузкой модуля задач, чтобы получить дополнительный контекст для модуля задачи. Например, может потребоваться получить список, чтобы заполнить элемент управления выбора людей или список каналов в команде.

Чтобы упростить этот поток, когда расширение сообщений впервые получает composeExtensions/fetchTask вызов, проверка, чтобы узнать, установлен ли бот в текущем контексте. Вы можете получить это, попытаясь получить вызов списка. Например, если бот не установлен, вы вернете адаптивную карточку с действием, которое запрашивает у пользователя установку бота. Пользователь должен иметь разрешение на установку приложений в этом расположении. Если установить не удается, в сообщении будет предложено обратиться к администратору.

Ниже приведен пример ответа:

{
  "type": "AdaptiveCard",
  "body": [
    {
      "type": "TextBlock",
      "text": "Looks like you haven't used Disco in this team/chat"
    }
  ],
  "actions": [
    {
      "type": "Action.Submit",
      "title": "Continue",
      "data": {
        "msteams": {
          "justInTimeInstall": true
        }
      }
    }
  ],
  "version": "1.0"
}

Когда пользователь завершит установку, бот получит еще одно сообщение вызова с name = composeExtensions/submitAction и value.data.msteams.justInTimeInstall = true.

Ниже приведен пример вызова:

{
  "value": {
    "commandId": "giveKudos",
    "commandContext": "compose",
    "context": {
      "theme": "default"
    },
    "data": {
      "msteams": {
        "justInTimeInstall": true
      }
    }
  },
  "conversation": {
    "id": "19:7705841b240044b297123ad7f9c99217@thread.skype"
  },
  "name": "composeExtension/submitAction",
  "imdisplayname": "Bob Smith"
}

Ответьте на вызов тем же ответом задачи, который вы ответили, если бот установлен.

Ответ на отправку

Когда пользователь завершит ввод входных данных, бот получает событие с заданными идентификатором composeExtensions/submitAction команды и значениями параметров.

Это различные ожидаемые ответы на .submitAction

Ответ модуля задач

Ответ модуля задач используется, когда расширению необходимо связать диалоги для получения дополнительных сведений. Ответ будет таким же, как fetchTask упоминалось ранее.

Ответ проверки подлинности и конфигурации расширений создания

Ответ проверки подлинности и конфигурации для создания расширений используется, когда расширение должно пройти проверку подлинности или настроить для продолжения. Дополнительные сведения см. в разделе проверка подлинности в разделе поиска.

Ответ на результат создания расширений

Ответ на результат создания расширений используется для вставки карта в поле создания в результате выполнения команды . Это тот же ответ, который используется в команде поиска, но он ограничен одним карта или одним результатом в массиве.

{
  "composeExtension": {
    "type": "result",
    "attachmentLayout": "list",
    "preview": {
          "contentType": "application/vnd.microsoft.card.thumbnail",
          "content": {
            "title": "85069: Create a cool app",
            "images": [
              {
                "url": "https://placekitten.com/200/200"
              }
            ]
          }
        },
    "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"
                }
              ]
            }
          ]
        }
      }
    ]
  }
}

Ответ с помощью сообщения адаптивной карточки, отправленного ботом

Ответ на действие отправки путем вставки сообщения с адаптивной карточкой в канал с помощью бота. Пользователь может предварительно просмотреть сообщение перед его отправкой, а также изменить или взаимодействовать с ним. Это может быть полезно в сценариях, когда необходимо собрать сведения от пользователей перед созданием ответа адаптивной карточки. В следующем сценарии показано, как использовать этот поток для настройки опроса без включения шагов настройки в сообщение канала.

  1. Пользователь выбирает расширение сообщения, чтобы активировать модуль задач.
  2. Пользователь использует модуль задач для настройки опроса.
  3. После отправки модуля задачи конфигурации приложение использует сведения, предоставленные в модуле задач, для создания адаптивной карточки и отправляет ее в ответ botMessagePreview клиенту.
  4. Пользователь может просмотреть сообщение адаптивной карточки, прежде чем бот вставит его в канал. Если бот еще не является участником канала, при нажатии кнопки Send добавляется бот.
  5. Взаимодействие с адаптивной карточкой изменяет сообщение перед его отправкой.
  6. Когда пользователь выберет Send, бот оправит сообщение в канале.

Примечание.

  • activityPreview должен содержать действие message с ровно одним вложением адаптивной карточки.
  • Outlook не поддерживает ответ с сообщением адаптивной карточки, отправленным ботом.

Чтобы включить этот поток, модуль задач должен ответить, как показано в следующем примере, который представляет пользователю сообщение предварительного просмотра:

{
  "composeExtension": {
    "type": "botMessagePreview",
    "activityPreview": {
      "type": "message",
      "attachments":  [
        {
          "contentType": "application/vnd.microsoft.card.adaptive",
          "content": << Card Payload >>
        }
      ]
    }
  }
}

Расширение сообщений должно реагировать на два новых типа взаимодействий: value.botMessagePreviewAction = "send" и value.botMessagePreviewAction = "edit". Следующий код является примером объекта, который value необходимо обработать:

{
  "name": "composeExtension/submitAction",
  "type": "invoke",
  "conversation": { "id": "19:c366b75791784100b6e8b515fd55b063@thread.skype" },
  "imdisplayname": "Pranav Smith",
  ...
  "value": {
    "botMessagePreviewAction": "send" | "edit",
    "botActivityPreview": [
      {
        "type": "message/card",
        "attachments": [
          {
            "content":
              {
                "type": "AdaptiveCard",
                "body": [{<<card payload>>}]
              },
            "contentType" : "application/vnd.microsoft.card.adaptive"
          }
        ],
        "context": { "theme": "default" }
      }
    ],
  }
}

При ответе на edit запрос необходимо ответить со значениями task , заполненными информацией, которую пользователь отправил. Отвечая на send запрос, необходимо отправить сообщение на канал, содержащий завершенную адаптивную карточку.

teamChatConnector.onComposeExtensionSubmitAction((
    event: builder.IEvent,
    request: teamBuilder.IComposeExtensionActionCommandRequest,
    callback: (err: Error, result: any, statusCode: number) => void) => {
        let invokeValue = (<any> event).value;

        if (invokeValue.botMessagePreviewAction ) {
            let attachment = invokeValue.botActivityPreview[0].attachments[0];

            if (invokeValue.botMessagePreviewAction === 'send') {
                let msg = new builder.Message()
                    .address(event.address)
                    .addAttachment(attachment);
                teamChatConnector.send([msg.toMessage()],
                    (error) => {
                        if(error){
                            // TODO: Handle error and callback.
                        }
                        else {
                            callback(null, null, 200);
                        }
                    }
                );
            }

            else if (invokeValue.botMessagePreviewAction === 'edit') {
              // Create the card and populate with user-inputted information.
              let card = { ... }

              let taskResponse = {
                task: {
                  type: "continue",
                  value: {
                    title: "Card Preview",
                    card: {
                      contentType: 'application/vnd.microsoft.card.adaptive',
                      content: card
                    }
                  }
                }
              }
              callback(null, taskResponse, 200);
            }

        else {
            let attachment = {
                  // Create Adaptive Card.
                };
            let activity = new builder.Message().addAttachment(attachment).toMessage();
            let response = teamBuilder.ComposeExtensionResponse.messagePreview()
                .preview(activity)
                .toResponse();
            callback(null, response, 200);
        }
    });

Дополнительные ресурсы

Примеры Bot Framework