microsoft / botbuilder-java

The Microsoft Bot Framework provides what you need to build and connect intelligent bots that interact naturally wherever your users are talking, from text/sms to Skype, Slack, Office 365 mail and other popular services.
http://botframework.com
MIT License
178 stars 115 forks source link

Error When Trigger Action.Execute From Adaptive Card in Teams Message #1477

Closed johnmiroki closed 1 year ago

johnmiroki commented 2 years ago

Github issues should be used for bugs and feature requests. Use Stack Overflow for general "how-to" questions.

Version

What package version of the SDK are you using. 4.14.2 Spring Boot 2.7.1

Describe the bug

Give a clear and concise description of what the bug is. When a button with "Action.Execute" is clicked, the request sends to Bot SDK. When SDK is reading the "value" from activity, it asumes it's a JsonNode, but in fact, it's LinkedHashMap, hence it sends error to Teams

see node = (JsonNode) obj; starting line 705 of ActivityHandler

        Object obj = activity.getValue();
        JsonNode node = null;
        if (obj instanceof JsonNode) {
            node = (JsonNode) obj;
        } else {
            AdaptiveCardInvokeResponse response = createAdaptiveCardInvokeErrorResponse(
                HttpURLConnection.HTTP_BAD_REQUEST, "BadRequest", "Value property instanceof not properly formed");
            throw new InvokeResponseException(HttpURLConnection.HTTP_BAD_REQUEST, response);
        }

To Reproduce

Steps to reproduce the behavior:

  1. Send an adaptive card to message, with action:
    {
      "type": "Action.Execute",
      "title": "Update Card",
      "id": "updateCard"
    }
  2. Click on the button "Update Card"
  3. Teams client gets response: {"errorCode":1008,"message":"<BotError>Bot returned unsuccessful status code BadRequest"}
  4. An error shows up "Unable to reach app. Please try again."
  5. No error logging in the backend

Expected behavior

Backend processes activity.getValue() as LinkedHashMap or whatever it could be (depending on the code deserializing activity json)

Screenshots

If applicable, add screenshots to help explain your problem.

Additional context

If I somehow convert activity.value into JsonNode, everything works. Two ways:

  1. Write a class extends BotController, and after Activity is passed in as controller parameter, substitute actitivy.value with a JsonNode activity.setValue(new ObjectMapper().convert(activity.getValue(), JsonNode.class))
  2. Write a class replacing the default BotController, where specifies Jackson to treat value as JsonNode

    private static class SFActivity extends Activity {
    @JsonDeserialize(as = JsonNode.class)
    @JsonProperty("value")
    private Object value;
    
    @Override
    public Object getValue() {
      return value;
    }
    
    @Override
    public void setValue(Object value) {
      this.value = value;
    }
    }
stevkan commented 1 year ago

@johnmiroki, thank you for your patience while I look into this. I will be attempting a repro and will let you know what I find.

stevkan commented 1 year ago

@johnmiroki, your assessment seems to be on point. We are deciding what the next steps should be and will respond once that has been decided.

johnmiroki commented 1 year ago

@stevkan Thank you for your confirmation!