You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

BotFramework-Webchat中Adaptive Cards非最新消息交互禁用异常排查

如何禁用BotFramework WebChat中非最新消息Adaptive卡片的指定操作和输入控件

我需要实现一个功能:禁用对话中非最新消息的Adaptive Cards里的Action.Submit类型操作以及所有输入控件。我尝试用React版BotFramework-Webchat的attachmentMiddleware来实现,代码如下:

const attachmentMiddleware = () => next => ({ activity, attachment, ...others }) => {
      if (attachment.contentType === "application/vnd.microsoft.card.custom") {
        attachment.contentType = "application/vnd.microsoft.card.adaptive"
      }
      const { activities } = store.getState()
      const messageActivities = activities.filter(
        activity =>
          activity.type === "message" &&
          typeof activity.suggestedActions === "undefined" // 过滤掉建议操作
      )
      const recentBotMessage = messageActivities.pop() === activity
      const AdaptiveCardContent = Components.AdaptiveCardContent
      switch (attachment.contentType) {
        case "application/vnd.microsoft.card.adaptive":
          return (
            <AdaptiveCardContent
              actionPerformedClassName="card__action--performed"
              content={
                attachment.content
              }
              disabled={!recentBotMessage}
            />
          )
        default:
          return next({ activity, attachment, ...others })
      }
    }

这个方案通过给非机器人最新消息的AdaptiveCardContent组件设置disabled属性来实现禁用,整体效果良好,但容器上的Action.OpenUrl操作存在异常:功能已失效,但外观仍显示为可点击状态。

从实际效果来看:

  • 底部的Action.Submit类型“主要操作”已被正确禁用;
  • Action.ToggleVisibility(用于切换文本可见性的按钮)仍正常工作,符合预期;
  • Action.OpenUrl(“Open in new tab”)虽看起来可点击,但实际点击无响应,且HTML元素上没有添加aria-disabled="true"属性。

我推测问题源于BotFramework-Webchat源码botframework-webchat\src\adaptiveCards\Attachment\AdaptiveCardRenderer.tsx的第107-108行代码:

// Only listen to event if it is not disabled and have "tapAction" prop.
const handleClickAndKeyPressForTapAction = !disabled && tapAction ? handleClickAndKeyPress : undefined;

但我无法理解为什么Action.ToggleVisibility能正常工作,而Action.OpenUrl会出现上述异常。

我还尝试过修改传入AdaptiveCardContent的卡片内容,但这种方式会导致用户输入值丢失(疑似usePersistValuesModEffect被覆盖),或者引发卡片重渲染的不良影响。

请问这是disabled属性的Bug还是预期行为?有没有可行方案实现仅禁用输入控件和Action.Submit操作?


编辑:

以下是传入<AdaptiveCardContent>组件的attachment.content值,即Adaptive卡片内容:

{
    "contentType": "application/vnd.microsoft.card.adaptive",
    "content": {
        "type": "AdaptiveCard",
        "version": "1.3",
        "speak": "",
        "body": [
            {
                "type": "Container",
                "id": "content",
                "items": [
                    {
                        "type": "TextBlock",
                        "weight": "bolder",
                        "text": "A title",
                        "wrap": true
                    },
                    {
                        "type": "Container",
                        "items": [
                            {
                                "type": "TextBlock",
                                "id": "descriptionPreview",
                                "text": "Some Content",
                                "wrap": true
                            }
                        ],
                        "spacing": "medium",
                        "separator": true
                    },
                    {
                        "type": "Container",
                        "items": [
                            {
                                "type": "Container",
                                "items": [
                                    {
                                        "type": "ColumnSet",
                                        "id": "nonBlocking3",
                                        "columns": [
                                            {
                                                "type": "Column",
                                                "width": "stretch",
                                                "items": [
                                                    {
                                                        "type": "TextBlock",
                                                        "id": "toggleKCostDown",
                                                        "weight": "bolder",
                                                        "text": "Cost",
                                                        "wrap": true
                                                    },
                                                    {
                                                        "type": "TextBlock",
                                                        "id": "toggleCostUp",
                                                        "weight": "bolder",
                                                        "text": "Cost",
                                                        "wrap": true,
                                                        "isVisible": false
                                                    }
                                                ],
                                                "verticalContentAlignment": "center"
                                            }
                                        ],
                                        "style": "accent",
                                        "selectAction": {
                                            "type": "Action.ToggleVisibility",
                                            "targetElements": [
                                                "toggleCostDown",
                                                "toggleCostDownChevron",
                                                "toggleCostUp",
                                                "toggleCostUpChevron",
                                                "contentCost"
                                            ]
                                        },
                                        "bleed": true
                                    },
                                    {
                                        "type": "TextBlock",
                                        "id": "contentCost",
                                        "text": "Some info about costs.",
                                        "wrap": true,
                                        "isVisible": false
                                    }
                                ]
                            }
                        ],
                        "bleed": true
                    },
                    {
                        "type": "Container",
                        "id": "nonBlocking4",
                        "items": [
                            {
                                "type": "ColumnSet",
                                "columns": [
                                    {
                                        "type": "Column",
                                        "width": "50px",
                                        "items": [
                                          {
                                            "type": "Column",
                                            "width": "70",
                                            "items": [
                                                {
                                                  "type": "TextBlock",
                                                  "weight": "bolder",
                                                  "text": "Open in new tab",
                                                  "wrap": true
                                                }
                                            ]
                                          }
                                        ]
                                    }
                                ]
                            }
                          ],
                        "style": "accent",
                        "selectAction": {
                            "type": "Action.OpenUrl",
                            "url": "https://google.com",
                            "title": "Open in new tab"
                        },
                        "spacing": "medium"
                    }
                ]
            },
            {
                "type": "TextBlock",
                "weight": "bolder",
                "text": "Have you found what you are looking for?",
                "wrap": true
            },
            {
                "type": "ColumnSet",
                "columns": [
                    {
                        "type": "Column",
                        "width": "stretch",
                        "items": [
                            {
                                "type": "ActionSet",
                                "actions": [
                                    {
                                        "type": "Action.Submit",
                                        "data": "No",
                                        "title": "No",
                                        "style": "destructive"
                                    }
                                ]
                            }
                        ]
                    },
                    {
                        "type": "Column",
                        "width": "stretch",
                        "items": [
                            {
                                "type": "ActionSet",
                                "actions": [
                                    {
                                        "type": "Action.Submit",
                                        "data": "Yes",
                                        "title": "Yes",
                                        "style": "positive"
                                    }
                                ]
                            }
                        ]
                    }
                ],
                "spacing": "medium",
                "separator": true
            }
        ]
    }
}

内容的提问来源于stack exchange,提问作者JackH

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.11 19:10:34