重要
本部分中的代码示例基于 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 如何在包含频道对话中的配置步骤的情况下配置轮询:
若要配置轮询,请执行以下操作:
- 用户选择消息扩展来调用对话框。 
- 用户使用对话框配置投票。 
- 当用户提交对话框时,应用使用提供的信息将轮询生成为自适应卡片,并将其作为 - botMessagePreview响应发送到客户端。
- 然后,用户可以在机器人将自适应卡片消息插入频道之前预览它。 如果应用不是频道的成员,请选择 - Send添加它。- 注意 - 用户还可以选择邮件 Edit,这将他们返回到原始对话框。
- 与自适应卡片的交互会在发送消息之前更改消息。
 
- 用户还可以选择邮件 
- 用户选择 - 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 = edit 的 composeExtensions/submitAction 调用。 通过返回你发送的对话来响应开始交互的初始 composeExtensions/fetchTask 调用。 用户可以通过重新输入原始信息来启动该过程。 使用可用信息更新对话框,以便用户无需从头开始填写所有信息。
有关响应初始 fetchTask 事件的详细信息,请参阅响应初始 fetchTask 事件。
响应 botMessagePreview 发送
在用户选择“发送”后,你将收到带有 value.botMessagePreviewAction = send 的 composeExtensions/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 消息扩展操作 | 此示例演示如何为 Microsoft Teams 创建基于作的消息扩展,使用户能够以交互方式生成内容。 它具有机器人、消息扩展和与用户输入的无缝集成,以增强功能。 | View | View | View | 
| 消息扩展作预览 | 此示例应用演示如何利用 Teams 消息扩展中的作预览,从而允许用户根据任务模块中的输入创建卡片。 它展示了机器人交互,这些交互通过将消息归于用户来增强用户参与度。 | View | View | View | 
| Teams 消息扩展搜索 | 此示例演示如何在 Microsoft Teams 中创建允许用户执行搜索和检索结果的消息扩展。 | View | View | View |