响应对话框提交操作

重要

本部分中的代码示例基于 v4.6 及更高版本的 Bot Framework SDK。 如果要查找早期版本的文档,请参阅文档的 Resources 文件夹中 的消息扩展 - v3 SDK 部分。

本文档指导你了解应用如何响应操作命令,例如用户的对话 (TeamsJS v1.x 中称为任务模块) 提交操作。 用户提交对话框后,Web 服务会收到一 composeExtensions/submitAction 条调用消息,其中包含命令 ID 和参数值。 应用有 5 秒的时间响应调用。

有以下响应选项:

如果应用在五秒内未响应,Teams 客户端会在发送错误消息“ 无法访问应用”之前重试请求两次。 如果机器人在超时后答复,则忽略响应。

注意

  • 在机器人回复调用请求后,应用必须推迟任何长时间运行的操作。 长时间运行的操作结果可以作为消息传递。
  • 应用有 5 秒的时间响应调用消息。

对于身份验证或配置,在用户完成该过程后,原始调用将重新发送到 Web 服务。 下表根据消息扩展的调用位置 commandContext 显示了可用的响应类型:

响应类型 撰写 命令栏 邮件
卡片响应 ✔️ ✔️ ✔️
另一个对话框 ✔️ ✔️ ✔️
带自适应卡片的机器人 ✔️ ✔️
无响应 ✔️ ✔️ ✔️

注意

  • 选择 Action.Submit through ME 卡时,它会发送名为 composeExtensions 的调用活动,其中的值等于通常的有效负载。
  • 当通过对话选择 Action.Submit 时,将收到名为 onCardButtonClicked 的消息活动,其中值等于常用有效负载。

如果应用包含对话机器人,请在对话中安装机器人,然后加载对话。 机器人可用于获取对话的更多上下文。 若要安装对话机器人,请参阅请求安装对话机器人

submitAction 调用事件

接收调用消息的示例如下所示:

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

使用插入到撰写消息区域的卡片进行响应

响应 composeExtensions/submitAction 请求的最常见方式是将卡片插入到撰写消息区域。 用户将卡片提交到对话。 有关使用卡片的详细信息,请参阅卡片和卡片操作

protected override async Task<MessagingExtensionActionResponse> OnTeamsMessagingExtensionSubmitActionAsync(
  ITurnContext<IInvokeActivity> turnContext, MessagingExtensionAction action, CancellationToken cancellationToken)
{
    var response = new MessagingExtensionActionResponse
    {
        ComposeExtension = new MessagingExtensionResult
        {
            AttachmentLayout = "list",
            Type = "result",
        },
    };
    var createCardData = ((JObject)action.Data).ToObject<CreateCardData>();
var card = new HeroCard
{
     Title = createCardData.Title,
     Subtitle = createCardData.Subtitle,
     Text = createCardData.Text,
};
    var attachments = new List<MessagingExtensionAttachment>();
    attachments.Add(new MessagingExtensionAttachment
    {
        Content = card,
        ContentType = HeroCard.ContentType,
        Preview = card.ToAttachment(),
    });
    response.ComposeExtension.Attachments = attachments;
    return response;
}

使用另一个对话框进行响应

可以选择使用其他对话框响应 submitAction 事件。 它在以下方案中很有用:

  • 收集大量信息。
  • 根据用户输入动态更改信息集合。
  • 验证用户提交的信息,并在出现错误时重新发送带有错误消息的表单。

响应方法与响应初始 fetchTask 事件相同。 如果使用的是 Bot Framework SDK,则两个提交操作都会触发相同的事件。 若要使此操作正常工作,必须添加确定正确响应的逻辑。

使用自适应卡片获取机器人响应

注意

  • 使用自适应卡片获取机器人响应的先决条件是,必须将 对象添加到 bot 应用清单,并定义机器人所需的范围。 为机器人使用与消息扩展相同的 ID。

  • Outlook 不支持使用自适应卡片进行机器人响应。

你还可以通过使用机器人将带有自适应卡片的消息插入频道来响应 submitAction。 用户可以在提交消息之前预览它。 在创建自适应卡片响应之前收集用户信息,或者在有人与卡片交互后更新卡片时,此功能非常有用。

以下方案演示了应用 Polly 如何在包含频道对话中的配置步骤的情况下配置轮询:

若要配置轮询,请执行以下操作:

  1. 用户选择消息扩展来调用对话框。

  2. 用户使用对话框配置投票。

  3. 当用户提交对话框时,应用使用提供的信息将轮询生成为自适应卡片,并将其作为 botMessagePreview 响应发送到客户端。

  4. 然后,用户可以在机器人将自适应卡片消息插入频道之前预览它。 如果应用不是频道的成员,请选择 Send 添加它。

    注意

    • 用户还可以选择邮件 Edit ,这将他们返回到原始对话框。
    • 与自适应卡片的交互会在发送消息之前更改消息。
  5. 用户选择 Send后,机器人会将消息发布到频道。

响应初始提交操作

对话必须使用机器人发送到通道的卡片预览来响应初始 composeExtensions/submitAction 消息。 用户可以在发送之前验证卡片,如果机器人已安装,则尝试在对话中安装机器人。

protected override async Task<MessagingExtensionActionResponse> OnTeamsMessagingExtensionSubmitActionAsync(
  ITurnContext<IInvokeActivity> turnContext, MessagingExtensionAction action, CancellationToken cancellationToken)
{
  dynamic createCardData = ((JObject) action.Data).ToObject(typeof(JObject));
  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 发送和编辑事件

消息扩展必须响应两种新类型的 composeExtensions/submitAction 调用,其中 value.botMessagePreviewAction = "send"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 编辑

如果用户在发送前编辑卡片,则通过选择“编辑”,你将收到一个带有 value.botMessagePreviewAction = editcomposeExtensions/submitAction 调用。 通过返回你发送的对话来响应开始交互的初始 composeExtensions/fetchTask 调用。 用户可以通过重新输入原始信息来启动该过程。 使用可用信息更新对话框,以便用户无需从头开始填写所有信息。 有关响应初始 fetchTask 事件的详细信息,请参阅响应初始 fetchTask 事件

响应 botMessagePreview 发送

在用户选择“发送”后,你将收到带有 value.botMessagePreviewAction = sendcomposeExtensions/submitAction 调用。 Web 服务必须使用自适应卡片创建消息并将其发送到对话,并回复调用。

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();
}

机器人消息的用户归属

在机器人代表用户发送消息的情况下,将消息归因给该用户有助于参与并显示更自然的交互流。 此功能允许机器人代表用户显示消息,该用户的姓名显示在自适应卡片响应标头中。

下图显示机器人发送的自适应卡片消息。 左侧图像没有用户属性,右侧图像具有用户属性。 具有用户属性的图像以以下格式显示用户名:通过机器人 (Megan Bowen 通过自适应卡片标头中的轮询)

用户归属机器人

若要在团队中使用用户归属,必须将 OnBehalfOf 提及实体添加到发送到团队的 Activity 有效负载中的 ChannelData

// 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
      }  
    }
  };

OnBehalfOf实体架构的详细信息

以下部分介绍了 OnBehalfOf 数组中的实体:

字段 类型 说明
itemId 整数 介绍项目的标识。 其值必须是 0
mentionType 字符串 介绍“人员”的提及。
mri String 邮件资源标识符 (代表发送邮件的人员的 MRI) 。 消息发件人名称将显示为“<用户> 通过 <机器人名称>”。
displayName String 人员的姓名。 在姓名解析不可用的情况下用作回退。

代码示例

示例名称 Description .NET Node.js 清单
Teams 消息扩展操作 此示例演示如何定义操作命令、创建对话和响应对话提交操作。 View View View
消息扩展操作预览 此示例演示如何使用 Bot Framework v4 在消息传递扩展中使用操作预览。 View View View
Teams 消息扩展搜索 此示例演示如何生成基于搜索的消息扩展。 它会搜索 NuGet 包,并在基于搜索的消息扩展中显示结果。 View View View

后续步骤

另请参阅