Teams Bot Adaptive Card action.Submit returns undefined but works in Bot Emulator

Viewed 245

I am having an issue with Teams Bot adaptive card action submit, when testing Bot Emulator it works as expected, but when it's published and performing the same action in Teams conversation, the action submit returns undefined. I have attempted with both adaptive card version 1.0, and version 1.3, the issue is the same in both cases. Anyone know a solution for this?

2 Answers

The other answer provides some useful background, but I think it's only applicable to specific scenarios - I think the issue you're having here is that you're sending a raw string value in the data property ("My Action") which Teams doesn't like, but the emulator doesn't mind at all. You can see more about that described in this Microsoft blog post. You should instead be sending an actual object. I describe it in more detail in this answer: QnA Maker Bot AdaptiveCards: how to add Data object in C#.

What @billoverton is referring to is a specific use case where you want the button behaviour to be, for instance, actually putting a message into the text stream as a response, as well as sending it to your bot. There are various options for these specific use cases, as described here, but they are optional if you want this specific behaviour. If you're happy for the user to click the button and that to simply invoke the message to your bot, you don't need the "msteams" section in the data payload.

A "standard" action.submit won't work in Teams. You need to add an msteams object under the data attribute. I'm guessing you are using a standard definition like

{
    "type": "ActionSet",
    "actions": [
        {
            "type": "Action.Submit",
            "title": "My Action",
            "data": "My Action"
        }
    ]
}

For Teams, it instead needs to look like this:

{
    "type": "ActionSet",
    "actions": [
        {
            "type": "Action.Submit",
            "title": "My Action",
            "data": {
                "msteams": {
                    "type": "imBack",
                    "value": "My Action"
                }
            }
        }
    ]
}

Of course when you do this, it won't work in the emulator or any non-teams channel. I've seen some people update their onMessage handler to account for this by extracting the value so a single card definition can work for both channels, but it made the selection a backchannel event for one of the channels (can't remember if it was web or Teams) which was not the experience I was looking for. So instead, I just conditionally display a Teams or non-Teams card based on channel. For example:

if (context.activity.channelId == 'msteams') {
    var welcomeCard = CardHelper.GetMenuCardTeams();
} else {
    var welcomeCard = CardHelper.GetMenuCard();
}

If you are not using a helper to generate your cards you can define them explicitly here, though I do recommend using a helper to keep things clean. This does mean that you need to maintain two versions of your cards, but for me it was worth it to ensure a consistent experience across channels.

Related