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

使用Microsoft Bot Framework为Facebook Messenger实现轮播卡片按钮payload异常问题

I see exactly what's going on here—you're running into a common conflict between how your carousel card buttons are set up and how builder.Prompts.choice handles user input. Let's break this down and fix it step by step:

The Root Cause

  • Mismatched Button Type + Prompt Logic: You’re using imBack for card buttons, which sends the payload as visible chat text. When you pass that concatenated string to Prompts.choice, the prompt’s input parser can’t tell different button clicks apart, leading to the same payload being detected every time.
  • Incorrect Option Format: The third parameter in Prompts.choice expects a list of distinct options (strings or structured objects), not a single string of combined values. Your current setup confuses the prompt’s matching system.

Step-by-Step Fix

1. Switch Card Buttons to postBack

First, replace imBack with postBack for your card buttons. This sends the payload directly to the bot without displaying it in the chat window—cleaner and far more reliable for prompt interactions:

export function SuboffertCard(subOffert: SubOffertCard, session?: builder.Session) {
  return new builder.HeroCard(session)
    .title(subOffert.title)
    .subtitle(subOffert.subtitle)
    .images([
      builder.CardImage.create(session, subOffert.image)
        .tap(builder.CardAction.showImage(session, subOffert.image)),
    ])
    .buttons([
      // Use postBack to send silent, unique payloads
      builder.CardAction.postBack(session, `select:get_${subOffert.title}`, polyglot.t("select")),
      builder.CardAction.postBack(session, `select:info_${subOffert.title}`, polyglot.t("info"))
    ])
}

2. Fix the Choice Prompt Configuration

Next, update your prompt to map each card button’s payload as a distinct, explicit option. We’ll also hide the default text list (since we’re using card buttons) to keep the UI clean:

let msg = new builder.Message(session)
  .attachmentLayout(builder.AttachmentLayout.carousel)
  .attachments(subOfferts.map(subOffert => SuboffertCard(subOffert, session)));

// Build a proper list of options that match your card button payloads
const promptOptions = subOfferts.flatMap(subOffert => [
  { 
    value: `select:get_${subOffert.title}`, 
    action: { type: 'postBack', title: polyglot.t("select") } 
  },
  { 
    value: `select:info_${subOffert.title}`, 
    action: { type: 'postBack', title: polyglot.t("info") } 
  }
]);

// Call the prompt with proper options and hide redundant text list
builder.Prompts.choice(session, msg, promptOptions, {
  listStyle: builder.ListStyle.none
});

Why This Works

  • postBack ensures each button sends a unique, hidden payload that the bot can parse accurately.
  • Explicitly defining options with matching value and action lets the choice prompt correctly map button clicks to their intended payloads.
  • listStyle: builder.ListStyle.none removes the unnecessary text options below the carousel, so users only interact with your designed card buttons.

As a shortcut, you can even omit the promptOptions entirely—Bot Framework’s Prompts.choice will auto-detect postBack buttons in your carousel and use their payloads as options. But explicitly defining them gives you more control and avoids any auto-detection quirks.

内容的提问来源于stack exchange,提问作者Popescu Denisa Elena

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:34:12