创建并发送任务模块Create and send the task module

重要

本节中的代码示例基于 Bot 框架 SDK 的4.6 和更高版本。The code samples in this section are based on 4.6 and later versions of the Bot Framework SDK. 如果要查找早期版本的文档,请参阅文档的资源文件夹中的 "消息扩展-V3 SDK " 一节。If you're looking for documentation for earlier versions, see the Messaging Extensions - v3 SDK section in the Resources folder of the documentation.

如果您不使用应用程序清单中定义的参数填充任务模块,则需要创建向用户显示的任务模块。If you are not populating your task module with parameters defined in your app manifest, you'll need to create the task module to be presented to your users. 您可以使用自适应卡片或嵌入的 web 视图。You can use either an Adaptive Card or an embedded web view.

初始调用请求The initial invoke request

使用此方法,您的服务将Activity接收类型composeExtension/fetchTask的对象,您需要使用包含自适应卡片task的对象或嵌入的 web 视图的 URL 来进行响应。Using this method you service will receive an Activity object of type composeExtension/fetchTask, and you'll need to respond with a task object containing either the adaptive card or a URL to the embedded web view. 除了标准 bot 活动属性,初始调用负载还包含以下请求元数据:In addition to the standard bot activity properties, the initial invoke payload contains the following request metadata:

属性名称Property name 用途Purpose
type 请求类型;必须为invokeType of request; must be invoke.
name 向您的服务发出的命令的类型。Type of command that is issued to your service. 将为composeExtension/fetchTaskWill be composeExtension/fetchTask.
from.id 发送请求的用户的 ID。ID of the user that sent the request.
from.name 发送请求的用户的名称。Name of the user that sent the request.
from.aadObjectId 发送请求的用户的 Azure Active Directory 对象 id。Azure Active Directory object id of the user that sent the request.
channelData.tenant.id Azure Active Directory 租户 ID。Azure Active Directory tenant ID.
channelData.channel.id 通道 ID (如果请求是在通道中发出的)。Channel ID (if the request was made in a channel).
channelData.team.id "工作组 ID" (如果请求是在通道中进行的)。Team ID (if the request was made in a channel).
value.commandId 包含调用的命令的 Id。Contains the Id of the command that was invoked.
value.commandContext 触发事件的上下文。The context that triggered the event. 将为composeWill be compose.
value.context.theme 用户的客户端主题,对于嵌入的 web 视图格式很有用。The user's client theme, useful for embedded web view formatting. 将为default contrastdarkWill be default, contrast or dark.

示例 fetchTask 请求Example fetchTask request

protected override async Task<MessagingExtensionActionResponse> OnTeamsMessagingExtensionFetchTaskAsync(ITurnContext<IInvokeActivity> turnContext, MessagingExtensionAction action, CancellationToken cancellationToken)
{
  //handle fetch task
}

来自邮件的初始调用请求Initial invoke request from a message

从邮件(而不是撰写区域或命令栏)调用 bot 时,初始请求中value的对象将包含从其调用邮件扩展的邮件的详细信息。When your bot is invoked from a message rather than the compose area or the command bar, the value object in the initial request will contain the details of the message your messaging extension was invoked from. 下面是此对象的一个示例。An example of this object is below. reactions mentions数组是可选的,如果原始邮件中没有反应或提及,则不会显示。The reactions and mentions arrays are optional, and will not be present if there are no reactions or mentions in the original message.

protected override async Task<MessagingExtensionActionResponse> OnTeamsMessagingExtensionFetchTaskAsync(ITurnContext<IInvokeActivity> turnContext, MessagingExtensionAction action, CancellationToken cancellationToken)
{
  var messageText = action.MessagePayload.Body.Content;
  var fromId = action.MessagePayload.From.User.Id;

  //finish handling the fetchTask
}

响应 fetchTaskRespond to the fetchTask

使用包含自适应卡片或 web task URL 的taskInfo对象的对象或简单的字符串消息来响应调用请求。Respond to the invoke request with a task object that contains either a taskInfo object with the adaptive card or web URL, or a simple string message.

属性名称Property name 用途Purpose
type 可以是continue显示窗体,也message可以是一个简单的弹出窗口。Can be either continue to present a form, or message for a simple popup.
value 或者是taskInfo窗体的对象,或者是string邮件的。Either a taskInfo object for a form, or a string for a message.

TaskInfo 对象的架构为:The schema for the taskInfo object is:

属性名称Property name 用途Purpose
title 任务模块的标题。The title of the task module.
height 可以是整数(以像素为单位),也small可以mediumlarge,或。Can be either an integer (in pixels), or small, medium, large.
width 可以是整数(以像素为单位),也small可以mediumlarge,或。Can be either an integer (in pixels), or small, medium, large.
card 自适应卡片,用于定义表单(如果使用一个)。The adaptive card defining the form (if using one).
url 要作为嵌入 web 视图在任务模块内打开的 URL。The URL to be opened inside of the task module as an embedded web view.
fallbackUrl 如果客户端不支持任务模块功能,则在浏览器选项卡中打开此 URL。If a client does not support the task module feature, this URL is opened in a browser tab.

使用自适应卡片With an adaptive card

使用自适应卡片时,需要使用包含自适应卡片的task value对象进行响应。When using an adaptive card, you'll need to respond with a task object with the value object containing an adaptive card.

使用自适应卡片的 fetchTask 响应示例Example fetchTask response with an adaptive card

除了 Bot 框架 SDK 之外,本示例还使用AdaptiveCards NuGet 包This sample uses the AdaptiveCards NuGet package in addition to the Bot Framework SDK.

protected override async Task<MessagingExtensionActionResponse> OnTeamsMessagingExtensionFetchTaskAsync(ITurnContext<IInvokeActivity> turnContext, MessagingExtensionAction action, CancellationToken cancellationToken)
{
  string placeholder = "Not invoked from message";

  if (action.MessagePayload != null)
  {
      var messageText = action.MessagePayload.Body.Content;
      var fromId = action.MessagePayload.From.User.Id;
      placeholder = "Invoked from message";
  }

  var response = new MessagingExtensionActionResponse()
  {
    Task = new TaskModuleContinueResponse()
    {
      Value = new TaskModuleTaskInfo()
      {
        Height = "small",
        Width = "small",
        Title = "Example task module",
        Card = new Attachment()
        {
          ContentType = AdaptiveCard.ContentType,
          Content = new AdaptiveCard("1.0")
          {
            Body = new List<AdaptiveElement>()
            {
              new AdaptiveTextInput() { Id = "FormField1", Placeholder = placeholder},
              new AdaptiveTextInput() { Id = "FormField2", Placeholder = "FormField2"},
              new AdaptiveTextInput() { Id = "FormField3", Placeholder = "FormField3"},
            },
            Actions = new List<AdaptiveAction>()
            {
              new AdaptiveSubmitAction()
              {
                Type = AdaptiveSubmitAction.TypeName,
                Title = "Submit",
              },
            },
          },
        },
      },
    },
  };
  return response;
}

嵌入的 web 视图With an embedded web view

使用嵌入的 web 视图时,需要使用包含要加载的 web task表单 URL 的value对象的对象进行响应。When using an embedded web view, you'll need to respond with a task object with the value object containing the URL to the web form you'd like to load. 您要加载的任何 URL 的域必须包含在应用程序清单validDomains中的阵列中。The domains of any URL you want to load must be included in the validDomains array in your app's manifest. 有关生成嵌入的 web 视图的完整信息,请参阅任务模块文档See the task module documentation for complete information on building your embedded web view.

protected override async Task<MessagingExtensionActionResponse> OnTeamsMessagingExtensionFetchTaskAsync(ITurnContext<IInvokeActivity> turnContext, MessagingExtensionAction action, CancellationToken cancellationToken)
{
  string placeholder = "Not invoked from message";

  if (action.MessagePayload != null)
  {
      var messageText = action.MessagePayload.Body.Content;
      var fromId = action.MessagePayload.From.User.Id;
      placeholder = "Invoked from message";
  }

  var response = new MessagingExtensionActionResponse()
  {
    Task = new TaskModuleContinueResponse()
    {
      Value = new TaskModuleTaskInfo()
      {
        Height = "small",
        Width = "small",
        Title = "Example task module",
        Url = "https://contoso.com/msteams/taskmodules/newcustomer",
        },
      },
    },
  };
  return response;
}

后续步骤Next steps

如果您允许用户从任务模块中向后发送响应,则需要处理提交操作。If you allow your users to send a response back from the task module, you'll need to handle the submit action.

了解更多Learn more

在快速入门中试用:Try it out in a quickstart: