无法让 imBack 在设置为与团队合作的自适应卡上工作

Can't get imBack to work on Adaptive Cards that are set up to work with teams

我的机器人有一张菜单卡,我最近发现它不适用于团队。我想使用 imBack 方法在聊天中显示消息。靠他们自己,我可以通过以下方式完成此操作:

// For directline/webchat
"type": "Action.Submit",
"title": "Get Order Status",
"data": "Get Order Status"
},

// For MS Teams
"type": "Action.Submit",
"title": "Get Order Status",
"data": {
    "msteams": {
        "type": "imBack",
        "value": "Get Order Status"
    },
},

但是,如果我使用 directline/webchat 版本,我会在 Teams 中遇到一般的机器人错误(我认为该错误是因为该按钮没有创建 imBack 消息,因此 LUIS 查询为空且全部我的代码引用了 topIntent 和 score 等 LUIS 属性失败。由于机器人设计,LUIS 需要每次调用。)同样,如果我使用 Teams 版本,出于同样的原因,我会在 directline/webchat 中收到一般机器人错误。起初,我尝试添加其他对象,例如我为其他频道 ID 为 msteams 创建的对象,但这并没有改变行为。根据信息 here,我能够添加文本属性并通过以下方式将其从 context.activity.value 复制到 context.activity.text:

// In my card definition
"type": "Action.Submit",
"title": "Get Order Status",
"data": {
    "msteams": {
        "type": "imBack",
        "value": "Get Order Status"
    },
    "text": "Get Order Status"
},

// In my onMessage handler
if (context.activity.channelData.postBack) {
    context.activity.text = context.activity.value.text;
}

当我以这种方式实施时,技术上它在两个渠道中都有效。但是,菜单选择(在本例中为 Get Order Status)不会作为来自用户的消息出现在聊天 window 中(并且通过扩展,不会显示在directline/webchat 频道的聊天记录)(它适用于 Teams 频道)。如果我在仅 directline/webchat 的实现中只有数据属性中的文本,我真的希望它的行为方式相同。有什么方法可以设置卡片(例如,通过不同格式的数据对象根据通道发送不同的数据)and/or onMessage 处理程序,以便在单击按钮时,文本显示在聊天中 window 无论通道如何,并且通过扩展,文本将通过 LUIS,这样我就不会因为 LUIS 属性为空而收到机器人错误?

我的想法是为 Teams 创建一个单独的卡片助手,并根据 channelId 从我的菜单意图中调用它,但如果可能的话,我想要一个比这更优雅的解决方案,尤其是因为我有几张带有这样提交按钮的不同卡片。

如果你的卡没有输入,那么我怀疑你想要一张英雄卡而不是自适应卡。英雄卡中的 imBack 将自动按照您希望的方式在网络聊天和团队中工作。虽然 Adaptive Cards 旨在适应其宿主的风格,但 Adaptive Cards 没有内置的“imBack”功能。字符串提交操作是 Web Chat 的一项功能,而 Adaptive Cards 中的 Bot Framework 操作是 Teams 的一项功能。您正在尝试让 Adaptive Cards 做一些他们自己无法做的事情,因此如果您想要这样做,您需要考虑您的特定渠道。

来自这个答案:

My blog post explains that if you want to use a string submit action you will need to do it differently in Web Chat and Teams: https://blog.botframework.com/2019/07/02/using-adaptive-cards-with-the-microsoft-bot-framework/

If you want to have the same submit action work the same way in both channels, it will need to be an object submit action. If you want a string submit action to work on both channels then your bot will need to check which channel the activity came from and react accordingly.

“imBack”属性 在 MS Teams 中运行良好。最好让 webcat 和 msteams 的 属性“数据”不同。对于 MS Teams,使用结构:

 "msteams": {
    "type": "imBack",
     "value": <value>
             }
       }

虽然 Kyle 的答案是正确的,具体取决于您的用例,但对我来说,正确的解决方案最终是在调用助手时根据通道在卡片助手功能之间切换。所以在我最初的问题中,我仍然在使用

// For directline/webchat
"type": "Action.Submit",
"title": "Get Order Status",
"data": "Get Order Status"
},

// For MS Teams
"type": "Action.Submit",
"title": "Get Order Status",
"data": {
    "msteams": {
        "type": "imBack",
        "value": "Get Order Status"
    },
},

但我在两个完全独立的助手中构建卡片,对我来说称为 GetMenuCardGetMenuCardTeams。然后,在我需要显示菜单卡的任何地方,我都会先进行以下检查:

if (context.activity.channelId == 'meteams') {
    var menuCard = CardHelper.GetMenuCardTeams(cardOptions);
} else {
    var menuCard = CardHelper.GetMenuCard(cardOptions);
}

请注意,您需要根据检查的位置调整变量。 context.activity.channelId 适用于大多数地方。如果您在瀑布中,则需要 step.context.activity.channelId(或者您命名步骤上下文变量的任何名称,step 和 stepContext 似乎是人们最常使用的)。在我的 QnA 对话框中,我没有传递上下文,只是 activity,但它仍然可以通过 activity.channelId 工作(那个助手只是传回一个答案,而不是发送 activity,这就是为什么我不需要上下文)。因此,您不需要上下文来设置辅助函数,但您至少需要 activity 或获取频道 ID 的方法。

我已经实现了它并发现它是我预期用例的最佳解决方案。但是,如果您不想弄乱所有 if 语句,只想让一张卡片在两个通道中按预期工作,Kyle 的答案是使用 Hero Cards 是更好的方法。