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

Node.js读取Teams含Action.ShowCard的自适应卡片输入值问题

Fixing Undefined Values from Adaptive Cards with Action.ShowCard in Microsoft Teams (Node.js)

我之前也踩过这个坑!当用Action.ShowCard嵌套input.date、input.choice这类控件时,直接在onMessage里取context.activity.value或者userText返回undefined,大概率是两个原因:要么卡片的JSON配置没做好,导致提交时数据没传过来;要么Bot代码里没正确捕获自适应卡片的提交事件。

为什么会出现这个问题?

普通用户发文本消息时,onMessage会触发,但自适应卡片的Submit动作虽然也是message类型的activity,它的value字段只有在用户点击了配置好的Action.Submit按钮时才会携带输入数据。如果你的Action.ShowCard里的控件没关联到正确的Submit按钮,或者控件的id没设置对,就会导致数据丢失,拿到undefined。

一步步解决问题

1. 先检查你的自适应卡片JSON

确保所有输入控件都有唯一的id,并且ShowCard内部(或者卡片顶级)有Action.Submit按钮,最好给Submit按钮加个data字段用来识别提交动作,方便后续Bot里判断。

示例卡片配置:

{
  "type": "AdaptiveCard",
  "version": "1.4",
  "body": [
    {
      "type": "TextBlock",
      "text": "请填写表单信息"
    }
  ],
  "actions": [
    {
      "type": "Action.ShowCard",
      "title": "展开填写",
      "card": {
        "type": "AdaptiveCard",
        "body": [
          {
            "type": "Input.Date",
            "id": "selectedDate",
            "placeholder": "选择日期"
          },
          {
            "type": "Input.ChoiceSet",
            "id": "selectedOption",
            "choices": [
              { "title": "选项A", "value": "optA" },
              { "title": "选项B", "value": "optB" }
            ],
            "placeholder": "选择一个选项"
          }
        ],
        "actions": [
          {
            "type": "Action.Submit",
            "title": "提交表单",
            "data": {
              "action": "submitForm"
            }
          }
        ]
      }
    }
  ]
}

这里的关键点:每个输入控件都有唯一id,ShowCard里的Submit按钮带了data.action,方便Bot识别这是表单提交。

2. 在Node.js Bot代码里正确捕获提交

不要只处理普通文本消息,要在onMessage里先判断context.activity.value是否存在——这才是自适应卡片提交时携带数据的地方。

示例代码:

const { ActivityHandler } = require('botbuilder');

class TeamsFormBot extends ActivityHandler {
    constructor() {
        super();

        this.onMessage(async (context, next) => {
            // 先判断是不是自适应卡片提交
            if (context.activity.value) {
                const submitData = context.activity.value;
                
                // 根据之前设置的action判断是哪个提交动作
                if (submitData.action === 'submitForm') {
                    // 从value里取出控件对应id的值
                    const selectedDate = submitData.selectedDate;
                    const selectedOption = submitData.selectedOption;

                    // 这里写你的验证逻辑,比如检查日期是否合法,选项是否有效
                    await context.sendActivity(`收到你的提交啦!日期:${selectedDate},选项:${selectedOption}`);
                }
            } else {
                // 处理普通文本消息
                await context.sendActivity('收到你的文本消息了😉');
            }

            await next();
        });
    }
}

module.exports.TeamsFormBot = TeamsFormBot;

3. 常见排查小技巧

  • 用Bot Framework Emulator查看activity的详细内容,看看value字段到底有没有数据——如果Emulator里都没有,那肯定是卡片配置的问题;如果有数据但Bot里拿不到,再查代码逻辑。
  • 确保卡片的version是1.0以上,Teams对低版本的自适应卡片支持可能有问题。
  • 检查控件的id有没有重复,重复的话会导致数据覆盖或者无法读取。
  • 确认Bot已经正确安装到Teams频道,权限没问题——有时候权限不足也会导致数据传递失败。

进阶提示:用Dialog管理提交流程

如果你的Bot需要处理复杂的会话流程,推荐把卡片提交的逻辑放到Dialog里,这样可以更好地管理会话状态,比如:

// 瀑布流Dialog的示例步骤
async function handleSubmitStep(stepContext) {
    const submitData = stepContext.context.activity.value;
    const selectedDate = submitData.selectedDate;
    
    // 这里做验证,比如检查日期是否在有效范围内
    if (!selectedDate) {
        await stepContext.context.sendActivity('请选择一个有效的日期哦');
        return await stepContext.replaceDialog('FormDialog');
    }

    // 验证通过,结束Dialog并返回数据
    return await stepContext.endDialog(submitData);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.09 07:37:42