响应任务模块提交操作Respond to the task module submit action

重要

本节中的代码示例基于 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.

用户提交任务模块后,web 服务将收到 composeExtension/submitAction 设置了命令 id 和参数值的 invoke 消息。Once a user submits the task module, your web service will receive a composeExtension/submitAction invoke message with the command id and parameter values set. 您的应用程序将有5秒的时间来响应调用,否则,用户将收到 "无法访问应用" 错误消息,并且团队客户端将忽略对该调用的任何答复。Your app will have five seconds to respond to the invoke, otherwise the user will receive an "Unable to reach the app" error message, and any reply to the invoke will be ignored by the Teams client.

您有以下选项可供您进行响应。You have the following options for responding.

下表显示了哪些类型的响应可基于邮件扩展的调用位置( commandContext )。The table below shows which types of responses are available based on the invoke location (commandContext) of the messaging extension. 对于身份验证或配置,一旦用户完成了流,原始调用将重新发送到您的 web 服务。For authentication or configuration, once the user completes the flow the original invoke will be re-sent to your web service.

响应类型Response Type 编撰compose 命令栏command bar messagemessage
卡片响应Card response xx xx xx
另一个任务模块Another task module xx xx xx
带有自适应卡片的 BotBot with Adaptive Card xx xx
无响应No response xx xx xx

SubmitAction 调用事件The submitAction invoke event

下面是接收调用消息的示例。Below are examples of receiving the invoke message.

protected override async Task<MessagingExtensionActionResponse> OnTeamsMessagingExtensionSubmitActionAsync(
  ITurnContext<IInvokeActivity> turnContext, MessagingExtensionAction action, CancellationToken cancellationToken) {
  //code to handle the submit action
}

使用插入撰写邮件区域中的卡片进行响应Respond with a card inserted into the compose message area

对请求做出响应的最常见方法 composeExtension/submitAction 是将卡片插入撰写邮件区域中。The most common way to respond to the composeExtension/submitAction request is with a card inserted into the compose message area. 然后,用户可以选择将该卡提交到对话中。The user can then choose to submit the card to the conversation. 有关使用卡片的详细信息,请参阅卡片和卡片操作For more information on using cards see cards and card actions.

protected override async Task<MessagingExtensionActionResponse> OnTeamsMessagingExtensionSubmitActionAsync(
  ITurnContext<IInvokeActivity> turnContext, MessagingExtensionAction action, CancellationToken cancellationToken)
{
    dynamic Data = JObject.Parse(action.Data.ToString());
    var response = new MessagingExtensionActionResponse
    {
        ComposeExtension = new MessagingExtensionResult
        {
            AttachmentLayout = "list",
            Type = "result",
        },
    };
    var card = new HeroCard
    {
        Title = Data["formField1"] as string,
        Subtitle = Data["formField2"]  as string,
        Text = Data["formField3"]  as string,
    };

    var attachments = new List<MessagingExtensionAttachment>();
    attachments.Add(new MessagingExtensionAttachment
    {
        Content = card,
        ContentType = HeroCard.ContentType,
        Preview = card.ToAttachment(),
    });

    response.ComposeExtension.Attachments = attachments;

    return response;

}

使用另一个任务模块进行响应Respond with another task module

您可以选择 submitAction 使用其他任务模块响应事件。You can choose to respond to the submitAction event with an additional task module. 这在以下情况中非常有用:This can be useful when:

  • 您需要收集大量信息。You need to collect large amounts of information.
  • 如果您需要根据用户输入动态更改要收集的信息If you need to dynamically change what information you're collecting based on user input
  • 如果需要验证用户提交的信息,并且可能会在出现错误时使用错误消息重新发送该表单。If you need to validate the information submitted by the user and potentially resend the form with an error message if something is wrong.

响应方法与响应初始 fetchTask 事件相同。The method for response is the same as responding to the initial fetchTask event. 如果您使用的是 Bot 框架 SDK,则相同的事件将触发这两个提交操作。If you're using the Bot Framework SDK the same event will trigger for both submit actions. 这意味着您需要确保添加确定正确响应的逻辑。This mean you need to be sure to add logic which determines the correct response.

使用自适应卡片的 Bot 响应Bot response with Adaptive Card

备注

此流要求您将对象添加 bot 到应用程序清单,并且您具有为 bot 定义的必要作用域。This flow requires that you add the bot object to your app manifest, and that you have the necessary scope defined for the bot. 使用与你的 bot 的邮件扩展相同的 Id。Use the same Id as your messaging extension for your bot.

您还可以通过将带有自适应卡片的邮件插入到使用 bot 的频道中来响应提交操作。You can also respond to the submit action by inserting a message with an Adaptive Card into the channel with a bot. 你的用户将能够在提交邮件之前预览邮件,并可能对其进行编辑/与之交互。Your user will be able to preview the message before submitting it, and potentially edit/interact with it as well. 当您需要在创建自适应卡片响应之前从用户处收集信息,或者在某人与他人交互后需要更新卡片时,这可能非常有用。This can be very useful in scenarios where you need to gather information from your users before creating an adaptive card response, or when you're going to need to update the card after someone interacts with it. 以下方案显示了应用程序 Polly 如何使用此流配置轮询,而不在通道对话中包括配置步骤。The following scenario shows how the app Polly uses this flow to configure a poll without including the configuration steps in the channel conversation.

  1. 用户单击邮件扩展可触发任务模块。The user clicks the messaging extension to trigger the task module.
  2. 用户使用任务模块配置投票。The user configures the poll with the task module.
  3. 提交任务模块后,应用使用提供的信息将轮询构建为自适应卡片,并将其作为响应发送 botMessagePreview 给客户端。After submitting the task module the app uses the information provided to build the poll as an Adaptive Card and sends it as a botMessagePreview response to the client.
  4. 然后,用户可以预览自适应卡片邮件,然后将其插入频道。The user can then preview the adaptive card message before the bot inserts it into the channel. 如果应用尚未成为频道的成员,则单击 Send "" 将添加它。If the app is not already a member of the channel, clicking Send will add the it.
    1. 用户还可以选择将 Edit 其返回到原始任务模块的邮件。The user can also chose to Edit the message, which returns them to the original task module.
  5. 与自适应卡片进行交互会在发送邮件之前对其进行更改。Interacting with the adaptive card changes the message before sending it.
  6. 用户单击机器人后,会将 Send 邮件发送到频道。Once the user clicks Send the bot posts the message to the channel.

响应初始提交操作Respond to initial submit action

若要启用此流,任务模块应 composeExtension/submitAction 使用 bot 将发送到频道的卡片的预览对初始邮件做出响应。To enable this flow your task module should respond to the initial composeExtension/submitAction message with a preview of the card that the bot will send to the channel. 这使用户可以在发送之前验证卡,还会在对话中尝试安装你的 bot (如果尚未安装)。This gives the user the opportunity to verify the card before sending, and also will attempt to install your bot in the conversation if it is not already installed.

protected override async Task<MessagingExtensionActionResponse> OnTeamsMessagingExtensionSubmitActionAsync(
  ITurnContext<IInvokeActivity> turnContext, MessagingExtensionAction action, CancellationToken cancellationToken)
{
  dynamic Data = JObject.Parse(action.Data.ToString());
  var response = new MessagingExtensionActionResponse
  {
    ComposeExtension = new MessagingExtensionResult
    {
      Type = "botMessagePreview",
      ActivityPreview = MessageFactory.Attachment(new Attachment
      {
        Content = new AdaptiveCard("1.0")
        {
          Body = new List<AdaptiveElement>()
          {
            new AdaptiveTextBlock() { Text = "FormField1 value was:", Size = AdaptiveTextSize.Large },
            new AdaptiveTextBlock() { Text = Data["FormField1"] as string }
          },
          Height = AdaptiveHeight.Auto,
          Actions = new List<AdaptiveAction>()
          {
            new AdaptiveSubmitAction
            {
              Type = AdaptiveSubmitAction.TypeName,
              Title = "Submit",
              Data = new JObject { { "submitLocation", "messagingExtensionFetchTask" } },
            },
          }
        },
        ContentType = AdaptiveCard.ContentType
      }) as Activity
    }
  };

  return response;
}

BotMessagePreview 发送和编辑事件The botMessagePreview send and edit events

现在,您的邮件扩展将需要对两种新的调用进行响应 composeExtension/submitAction ,其中 value.botMessagePreviewAction = "send"value.botMessagePreviewAction = "edit"Your message extension will now need to respond to two new varieties of the composeExtension/submitAction invoke, where value.botMessagePreviewAction = "send"and value.botMessagePreviewAction = "edit".

protected override async Task<MessagingExtensionActionResponse> OnTeamsMessagingExtensionBotMessagePreviewEditAsync(
  ITurnContext<IInvokeActivity> turnContext, MessagingExtensionAction action, CancellationToken cancellationToken)
{
  //handle the event
}

protected override async Task<MessagingExtensionActionResponse> OnTeamsMessagingExtensionBotMessagePreviewSendAsync(
  ITurnContext<IInvokeActivity> turnContext, MessagingExtensionAction action, CancellationToken cancellationToken)
{
  //handle the event
}

响应 botMessagePreview 编辑Respond to botMessagePreview edit

如果用户通过单击 "编辑" 按钮决定在发送前编辑卡片,您将收到带有的 composeExtension/submitAction invoke value.botMessagePreviewAction = editIf the user decides to edit the card before sending by clicking the Edit button, you will receive a composeExtension/submitAction invoke with value.botMessagePreviewAction = edit. 通常情况下,应通过返回发送的任务模块来响应开始交互的初始调用,以做出响应 composeExtension/fetchTaskYou should typically respond by returning the task module you sent in response to the initial composeExtension/fetchTask invoke that began the interaction. 这样一来,用户可以通过重新输入原始信息来开始此过程。This allows the user to start the process over by re-entering the original information. 此外,您还应考虑使用现在可用于预填充任务模块的信息,以便用户无需从头开始填写所有信息。You should also consider using the information you now have available to pre-populate the task module so the user doesn't have fill out all of the information from scratch.

请参阅响应初始 fetchTask 事件See responding to the initial fetchTask event.

响应 botMessagePreview sendRespond to botMessagePreview send

用户单击 "发送" 按钮后,您将收到 composeExtension/submitAction 带调用的 invoke value.botMessagePreviewAction = sendOnce the user clicks the Send button, you will receive a composeExtension/submitAction invoke with value.botMessagePreviewAction = send. 您的 web 服务将需要创建一个具有自适应卡片的主动消息,并将其发送到对话,同时还会回复调用。Your web service will need to create and send a proactive message with the Adaptive Card to the conversation, and also reply to the invoke.

protected override async Task<MessagingExtensionActionResponse> OnTeamsMessagingExtensionBotMessagePreviewSendAsync(
  ITurnContext<IInvokeActivity> turnContext, MessagingExtensionAction action, CancellationToken cancellationToken)
{
  var activityPreview = action.BotActivityPreview[0];
  var attachmentContent = activityPreview.Attachments[0].Content;
  var previewedCard = JsonConvert.DeserializeObject<AdaptiveCard>(attachmentContent.ToString(),
          new JsonSerializerSettings { NullValueHandling = NullValueHandling.Ignore });
  
  previewedCard.Version = "1.0";

  var responseActivity = Activity.CreateMessageActivity();
  Attachment attachment = new Attachment()
  {
    ContentType = AdaptiveCard.ContentType,
    Content = previewedCard
  };
  responseActivity.Attachments.Add(attachment);
  
  // Attribute the message to the user on whose behalf the bot is posting
  responseActivity.ChannelData = new {
    OnBehalfOf = new []
    {
      new
      {
        ItemId = 0,
        MentionType = "person",
        Mri = turnContext.Activity.From.Id,
        DisplayName = turnContext.Activity.From.Name
      }  
    }
  };
  
  await turnContext.SendActivityAsync(responseActivity);

  return new MessagingExtensionActionResponse();
}

Bot 消息的用户归属User attribution for bots messages

在 bot 代表用户发送邮件的情况下,将邮件的特性化到该用户可以帮助接洽,并展示更自然的交互流程。In scenarios where a bot sends messages on behalf of a user, attributing the message to that user can help with engagement and showcase a more natural interaction flow. 此功能使您可以将来自你的 bot 的邮件特性为其代表发送的用户。This feature allows you to attribute a message from your bot to a user on whose behalf it was sent.

在下面的图像中,左侧是由不带用户归属的 bot 发送的卡片邮件,右侧是由具有用户归属的 bot 发送的卡片。In the image below, on the left is a card message sent by a bot without user attribution and on the right is a card sent by a bot with user attribution.

屏幕截图

若要在团队中使用用户归属,您需要将 OnBehalfOf 提及实体添加到 ChannelData Activity 发送给团队的有效负载中。To use user attribution in teams, you need to add the OnBehalfOf mention entity to ChannelData in your Activity payload that is sent to Teams.

    OnBehalfOf = new []
    {
      new
      {
        ItemId = 0,
        MentionType = "person",
        Mri = turnContext.Activity.From.Id,
        DisplayName = turnContext.Activity.From.Name
      }  
    }

以下是对数组中的实体的说明 OnBehalfOfBelow is a description of the entities in the OnBehalfOf of Array:

实体架构的详细信息 OnBehalfOfDetails of OnBehalfOf entity schema

字段Field 类型Type 说明Description
itemId IntegerInteger 应为0Should be 0
mentionType StringString 应为 "person"Should be "person"
mri StringString 发送邮件的人员的邮件资源标识符(MRI)。Message resource identifier (MRI) of the person on whose behalf the message is sent. 邮件发件人名称将显示为 " <user> via <bot name> "。Message sender name would appear as "<user> via <bot name>".
displayName StringString 人员的姓名。Name of the person. 在案例名称解析中不可用时用作回退。Used as fallback in case name resolution is unavailable.

后续步骤Next Steps

添加搜索命令Add a search command

了解更多Learn more

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