响应对话框提交操作
重要
本部分中的代码示例基于 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 消息扩展操作 | 此示例演示如何定义操作命令、创建对话和响应对话提交操作。 | View | View | View |
消息扩展操作预览 | 此示例演示如何使用 Bot Framework v4 在消息传递扩展中使用操作预览。 | View | View | View |
Teams 消息扩展搜索 | 此示例演示如何生成基于搜索的消息扩展。 它会搜索 NuGet 包,并在基于搜索的消息扩展中显示结果。 | View | View | View |