microsoft / BotFramework-Composer

Dialog creation and management for Microsoft Bot Framework Applications
https://docs.microsoft.com/en-us/composer/
MIT License
869 stars 372 forks source link

Bot returning error "Operation returned an invalid status code 'BadRequest'" in MS Teams #9054

Closed krassussofficial closed 2 years ago

krassussofficial commented 2 years ago

Describe the bug

I created a bot in BF Composer. It relies mostly on a series of adaptive Hero Cards. In Emulator and in Azure Web Chat the bot works fine but once I uploaded it to MS Teams (using App Studio) it returned error: Operation returned an invalid status code 'BadRequest'

Initial hero card loads fine and the problem occurs once user chooses an option from the initial hero card (it should be followed by another hero card).

In Azure portal in Teams Channel I'm getting the following error:

March 17, 2022, 9:04 AM GMT+1
Invalid image URI

but I don't see how it relates and how it's problem only on Teams.

I'm using also App Insights but haven't seen anything useful there.

Help would be greatly appreciated.

Version

2.1.2

Browser

OS

To Reproduce

Steps to reproduce the behavior:

  1. Created a bot in BF Composer consisting of multiple Hero Cards
  2. Upload the Bot to MS Teams using App Studio
  3. The error occurs

Expected behavior

After user chooses an option on initial hero card, another one should pop up, like in a menu.

Screenshots

Additional context

krassussofficial commented 2 years ago

I found out I'm using adaptive cards version 1.2

anishprasad01 commented 2 years ago

Hi @krassussofficial,

To start with, have you tried installing the manifest as shown here? (I know this sample is a code bot, but this should work regardless). Sometimes installing the bot this way can fix some issues.

Additionally, I believe Teams can only pull from https endpoints. Ensure that the image you're pulling is coming from one such endpoint.

krassussofficial commented 2 years ago

Hi @anishprasad01,

I tried using the manifest but I'm getting similar results. Similar, because the first time I loaded the bot to Teams and chose an option from initial adaptive card it responded with: Oops, looks like I'm stuck. Can you try to ask me in a different way?

But with a second try it returned the good old

Operation returned an invalid status code 'BadRequest'

I don't think the images (icons) are a problem because they're pulled from the same location as images (icons) for the initial card which displays fine.

In logs (Apps Insights) it's clear that the bot recognizes correct intent. In this case the user wanted to get into Access Request section of the bot and clicked proper option on the adaptive card. Here's a bit from the logs: (Newest from the top)

ActionId | Microsoft.BeginDialog[AccessRequest] -- | -- DialogId | BeginDialog[AccessRequest] -- | -- Expression | ((turn.recognized.intent == 'AccessRequestRedirect') && ((turn.dialogEvent.name == 'recognizedIntent') && True)) -- | --

If you have any suggestions or need any more data from me let me know. I'll be happy to provide.

anishprasad01 commented 2 years ago

The next thing I'd suggest is debugging locally with ngrok. This will allow you to run the bot in your local environment and see where in the code errors occur. This may help us understand what's breaking and if there is an exception with a more detailed error message that might help debug the issue. You can step through problematic code with a debugger and see if something is out of place.

If we have an exception or error message that might explain that BadRequest, then we might be able to isolate a fix.

krassussofficial commented 2 years ago

I used the ngrok but unfortunately while Teams are still returning BadRequest

ngrok is saying: 200 OK

screens attached

image image
anishprasad01 commented 2 years ago

Ngrok is just telling you the inbound request was received successfully, it doesn't necessarily know what happened in the code handling the request.

Is this a C# bot? Have you tried running your code in Visual Studio, rather than Composer? Your Composer project folder should have a csproj or sln file which you can open in Visual Studio and then run the bot in the debugger, allowing you to see error messages and where they occur. Note that the port you will need to forward with Ngrok might be different.

krassussofficial commented 2 years ago

Hi @anishprasad01 I tried debugging it with VS today but there's some kind of issue. The bot doesn't start the conversation because it's encountering an error and starts looping in it. The error is still in the part that comes from a template. It appears that the bot fails to add a member to the conversation? here are the logs:

`IT_Bot Information: 0 : 'conversationUpdate' ==> beginDialog ==> IT_Bot

IT_Bot Information: 0 : 2: 'conversationUpdate' ==> activityReceived ==> OnConversationUpdateActivity[]

IT_Bot Information: 0 : Executing Dialog: IT_Bot Rule[0]: OnConversationUpdateActivity: ((turn.activity.type == 'conversationUpdate') && ((turn.dialogEvent.name == 'activityReceived') && True))

IT_Bot Information: 0 : 2: 'conversationUpdate' ==> beginDialog ==> ActionScope[ForEachElement(=turn.Activity.membersAdded)]

IT_Bot Information: 0 : 2: 'conversationUpdate' ==> beginDialog ==> ForEachElement(=turn.Activity.membersAdded)

IT_Bot Information: 0 : 2: 'conversationUpdate' ==> beginDialog ==> ActionScope[IfCondition(=string(dialog.foreach.value.id) != st...4dYt8L2B7c3pgpBoUtxsnkYsgdWwdlPWXUBBERDSIkg=]

IT_Bot Information: 0 : 2: 'conversationUpdate' ==> beginDialog ==> IfCondition(=string(dialog.foreach.value.id) != string(turn.Activity.Recipient.id)|IfCondition(=exists(user.greeted)|SendActivity(${S...)

IT_Bot Information: 0 : 2: 'conversationUpdate' ==> EndDialog ==> IfCondition(=string(dialog.foreach.value.id) != string(turn.Activity.Recipient.id)|IfCondition(=exists(user.greeted)|SendActivity(${S...)

IT_Bot Information: 0 : 2: 'conversationUpdate' ==> ResumeDialog ==> ActionScope[IfCondition(=string(dialog.foreach.value.id) != st...4dYt8L2B7c3pgpBoUtxsnkYsgdWwdlPWXUBBERDSIkg=]

IT_Bot Information: 0 : 2: 'conversationUpdate' ==> EndDialog ==> ActionScope[IfCondition(=string(dialog.foreach.value.id) != st...4dYt8L2B7c3pgpBoUtxsnkYsgdWwdlPWXUBBERDSIkg=]

IT_Bot Information: 0 : 2: 'conversationUpdate' ==> beginDialog ==> ActionScope[IfCondition(=string(dialog.foreach.value.id) != st...4dYt8L2B7c3pgpBoUtxsnkYsgdWwdlPWXUBBERDSIkg=]

IT_Bot Information: 0 : 2: 'conversationUpdate' ==> beginDialog ==> IfCondition(=string(dialog.foreach.value.id) != string(turn.Activity.Recipient.id)|IfCondition(=exists(user.greeted)|SendActivity(${S...)

IT_Bot Information: 0 : 2: 'conversationUpdate' ==> EndDialog ==> IfCondition(=string(dialog.foreach.value.id) != string(turn.Activity.Recipient.id)|IfCondition(=exists(user.greeted)|SendActivity(${S...)

IT_Bot Information: 0 : 2: 'conversationUpdate' ==> beginDialog ==> TrueIfCondition(=string(dialog.foreach.value.id) != string(turn.Activity.Recipient.id)|IfCondition(=exists(user.greeted)|SendActivity(${S...)

IT_Bot Information: 0 : 2: 'conversationUpdate' ==> beginDialog ==> IfCondition(=exists(user.greeted)|SendActivity(${SendActivity_GreetingReturni...))

IT_Bot Information: 0 : 2: 'conversationUpdate' ==> EndDialog ==> IfCondition(=exists(user.greeted)|SendActivity(${SendActivity_GreetingReturni...))

IT_Bot Information: 0 : 2: 'conversationUpdate' ==> beginDialog ==> FalseIfCondition(=exists(user.greeted)|SendActivity(${SendActivity_GreetingReturni...))

IT_Bot Information: 0 : 2: 'conversationUpdate' ==> beginDialog ==> SendActivity(${SendActivity_GreetingNewUser...) 'IT_Bot.exe' (CoreCLR: clrhost): Loaded 'C:\repo\Chatbotv2\IT_Bot-17.03\IT_Bot\bin\Debug\netcoreapp3.1\Microsoft.IdentityModel.Clients.ActiveDirectory.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.

IT_Bot Information: 0 : 2: 'conversationUpdate' ==> error ==> ForEachElement(=turn.Activity.membersAdded)

IT_Bot Information: 0 : 2: 'conversationUpdate' ==> error ==> IT_Bot

'IT_Bot.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.23\System.Diagnostics.StackTrace.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.

'IT_Bot.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.23\System.Reflection.Metadata.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.

IT_Bot Information: 0 : 3: 'conversationUpdate' ==> error ==> OnError(error)

IT_Bot Information: 0 : Executing Dialog: IT_Bot Rule[4]: OnError: ((turn.dialogEvent.name == 'error') && True)

IT_Bot Information: 0 : 3: 'conversationUpdate' ==> beginDialog ==> ActionScope[TraceActivity(=IT_Bot.OnError),TelemetryTrackEve...eFJ4qilp/FqaYlRxuVaF0I4PvSq0fm10wQVysyselZk=]

IT_Bot Information: 0 : 3: 'conversationUpdate' ==> beginDialog ==> TraceActivity(=IT_Bot.OnError)

IT_Bot Information: 0 : 3: 'conversationUpdate' ==> error ==> TraceActivity(=IT_Bot.OnError) `

anishprasad01 commented 2 years ago

Could you scrub your project of any secrets or other personal information and share a small reproducible example with me? You can use my work email on my profile. It's hard for me to see what's going on from these logs, so I'd like to try and run the bot myself.

krassussofficial commented 2 years ago

Yes, thank you @anishprasad01 I just sent you an email.

anishprasad01 commented 2 years ago

@krassussofficial,

I took a look at your bot, and both your root and skill bots are complaining about missing LUIS and QnA keys and regions. I would like to confirm that this is only because you removed them before sharing the bot with me, and that your bot has the keys and regions filled in the root and skill. C# bots made in Composer should work in Visual Studio without issue.

krassussofficial commented 2 years ago

Hi @anishprasad01 Yes, I removed it prior to sharing, I have no problems publishing the bot to Azure. Both QnA and LUIS resources are connected without issues. Let me know if you have any further questions. Best regards!

krassussofficial commented 2 years ago

@anishprasad01

Part of the issue was the appsettings.json file which was completely different from "Advanced Settings" in Composer, the only issue I have now is that the bot doesn't connect to QnA KB (401 Unauthorized) despite having proper keys and endpoints in the appsettings.json...

anishprasad01 commented 2 years ago

So you can now connect to the bot in Teams, but any requests that use QnA fail?

krassussofficial commented 2 years ago

@anishprasad01 Exactly, there's no connection to QnA in my local bot. Is the local bot, running in VS, using the KB's downloaded just like Composer (located in ..../knowledge-base/source/) or is it actually connecting to the one in Azure?

krassussofficial commented 2 years ago

@anishprasad01

Weird thing happened today:

From the very morning I can't access my LUIS resource: I'm getting a 401 (unauthorized) error and during "conversation" using adaptive cards when I check the LuisV3 Trace that's what I'm getting:

image

and when asking a direct question:

image

in appsettings.json I have specified

"luis": { "authoringEndpoint": "https://xxxxxxx-authoring.cognitiveservices.azure.com/", "authoringRegion": "westus", "defaultLanguage": "en-us", "endpoint": "https://xxxxxx-luis.cognitiveservices.azure.com/", "environment": "composer", "name": "xxxx-luis", "authoringKey": "", "endpointKey": "authoring key here" },

And I'm getting 401

When I add endpoint key (as 'authoringKey') - still 401 When switch places between keys - 403 (forbidden)

(This if for new LUIS resource)

any Ideas?

anishprasad01 commented 2 years ago

Let me try to create a new QnA and LUIS resource and connect them to the copy of your bot and see if I can get it working.

anishprasad01 commented 2 years ago

@krassussofficial,

So here's what I did:

The result: (Ignore the "Sorry, I did not understand". I entered some gibberish to establish connection to the bot which it didn't understand) image

The second hero card seems to be rendering fine. No errors popped up in Teams or in the bot. I'm thinking that the problem is probably a mismatch in the keys or some other configuration item. I have made no changes whatsoever to your bot itself. Only the appsettings.

krassussofficial commented 2 years ago

Hi @anishprasad01,

I have finally properly configured the bot solution in VS. Now I can debug the Teams channel using VS. The error happens (as before) when a user chooses one of the options on the card you sent in screenshot above. Could you see what happens when you choose "Access Request" for example? I get the BadRequest Below I'm attaching logs from VS debugger:

==========================================================

IT_Bot Information: 0 : 5: 'message' ==> activityReceived ==> IT-Init IT_Bot Information: 0 : 4: 'message' ==> recognizeUtterance ==> CrossTrainedRecognizerSet IT_Bot Information: 0 : 5: 'message' ==> recognizedIntent ==> OnIntent(AccessRequestRedirect)[] IT_Bot Information: 0 : Executing Dialog: IT-Init Rule[1]: OnIntent: ((turn.recognized.intent == 'AccessRequestRedirect') && ((turn.dialogEvent.name == 'recognizedIntent') && True)) IT_Bot Information: 0 : 5: 'message' ==> beginDialog ==> ActionScope[BeginDialog[AccessRequest]] IT_Bot Information: 0 : 5: 'message' ==> beginDialog ==> BeginDialog[AccessRequest] IT_Bot Information: 0 : 'message' ==> beginDialog ==> AccessRequest IT_Bot Information: 0 : 1: 'message' ==> beginDialog ==> OnBeginDialog(beginDialog) IT_Bot Information: 0 : Executing Dialog: AccessRequest Rule[0]: OnBeginDialog: ((turn.dialogEvent.name == 'beginDialog') && True) IT_Bot Information: 0 : 1: 'message' ==> beginDialog ==> ActionScope[SendActivity(${SendActivity_XCXUVv()})] IT_Bot Information: 0 : 1: 'message' ==> beginDialog ==> SendActivity(${SendActivity_XCXUVv()}) IT_Bot Information: 0 : 5: 'message' ==> error ==> SendActivity(${SendActivity_XCXUVv()}) IT_Bot Information: 0 : 1: 'message' ==> error ==> AccessRequest 'IT_Bot.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.23\System.Diagnostics.StackTrace.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. 'IT_Bot.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.23\System.Reflection.Metadata.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled. IT_Bot Information: 0 : 5: 'message' ==> error ==> IT-Init IT_Bot Information: 0 : 5: 'message' ==> error ==> greeting_teams Microsoft.Bot.Builder.Dialogs.Adaptive.Runtime.CoreBotAdapter: Error: [OnTurnError] unhandled error : Operation returned an invalid status code 'BadRequest'

Microsoft.Bot.Schema.ErrorResponseException: Operation returned an invalid status code 'BadRequest' at Microsoft.Bot.Connector.Conversations.ReplyToActivityWithHttpMessagesAsync(String conversationId, String activityId, Activity activity, Dictionary2 customHeaders, CancellationToken cancellationToken) at Microsoft.Bot.Connector.ConversationsExtensions.ReplyToActivityAsync(IConversations operations, String conversationId, String activityId, Activity activity, CancellationToken cancellationToken) at Microsoft.Bot.Builder.CloudAdapterBase.SendActivitiesAsync(ITurnContext turnContext, Activity[] activities, CancellationToken cancellationToken) at Microsoft.Bot.Builder.TurnContext.<>c__DisplayClass31_0.<<SendActivitiesAsync>g__SendActivitiesThroughAdapter|1>d.MoveNext() --- End of stack trace from previous location where exception was thrown --- at Microsoft.Bot.Builder.SetSpeakMiddleware.<>c__DisplayClass3_0.<<OnTurnAsync>b__0>d.MoveNext() --- End of stack trace from previous location where exception was thrown --- at Microsoft.Bot.Builder.TurnContext.SendActivityAsync(IActivity activity, CancellationToken cancellationToken) at Microsoft.Bot.Builder.Dialogs.Adaptive.Actions.SendActivity.BeginDialogAsync(DialogContext dc, Object options, CancellationToken cancellationToken) at Microsoft.Bot.Builder.Dialogs.DialogContext.BeginDialogAsync(String dialogId, Object options, CancellationToken cancellationToken) at Microsoft.Bot.Builder.Dialogs.Adaptive.Actions.ActionScope.BeginActionAsync(DialogContext dc, Int32 offset, CancellationToken cancellationToken) at Microsoft.Bot.Builder.Dialogs.Adaptive.Actions.ActionScope.BeginDialogAsync(DialogContext dc, Object options, CancellationToken cancellationToken) at Microsoft.Bot.Builder.Dialogs.DialogContext.BeginDialogAsync(String dialogId, Object options, CancellationToken cancellationToken) at Microsoft.Bot.Builder.Dialogs.Adaptive.AdaptiveDialog.ContinueActionsAsync(DialogContext dc, Object options, CancellationToken cancellationToken) at Microsoft.Bot.Builder.Dialogs.Adaptive.AdaptiveDialog.BeginDialogAsync(DialogContext dc, Object options, CancellationToken cancellationToken) at Microsoft.Bot.Builder.Dialogs.DialogContext.BeginDialogAsync(String dialogId, Object options, CancellationToken cancellationToken) at Microsoft.Bot.Builder.Dialogs.Adaptive.Actions.BeginDialog.BeginDialogAsync(DialogContext dc, Object options, CancellationToken cancellationToken) at Microsoft.Bot.Builder.Dialogs.DialogContext.BeginDialogAsync(String dialogId, Object options, CancellationToken cancellationToken) at Microsoft.Bot.Builder.Dialogs.Adaptive.Actions.ActionScope.BeginActionAsync(DialogContext dc, Int32 offset, CancellationToken cancellationToken) at Microsoft.Bot.Builder.Dialogs.Adaptive.Actions.ActionScope.BeginDialogAsync(DialogContext dc, Object options, CancellationToken cancellationToken) at Microsoft.Bot.Builder.Dialogs.DialogContext.BeginDialogAsync(String dialogId, Object options, CancellationToken cancellationToken) at Microsoft.Bot.Builder.Dialogs.Adaptive.AdaptiveDialog.ContinueActionsAsync(DialogContext dc, Object options, CancellationToken cancellationToken) at Microsoft.Bot.Builder.Dialogs.Adaptive.AdaptiveDialog.ContinueDialogAsync(DialogContext dc, CancellationToken cancellationToken) at Microsoft.Bot.Builder.Dialogs.DialogContext.ContinueDialogAsync(CancellationToken cancellationToken) at Microsoft.Bot.Builder.Dialogs.Adaptive.AdaptiveDialog.ContinueActionsAsync(DialogContext dc, Object options, CancellationToken cancellationToken) at Microsoft.Bot.Builder.Dialogs.Adaptive.AdaptiveDialog.ContinueDialogAsync(DialogContext dc, CancellationToken cancellationToken) at Microsoft.Bot.Builder.Dialogs.DialogContext.ContinueDialogAsync(CancellationToken cancellationToken) at Microsoft.Bot.Builder.Dialogs.DialogExtensions.InnerRunAsync(ITurnContext turnContext, String dialogId, DialogContext dialogContext, CancellationToken cancellationToken) at Microsoft.Bot.Builder.Dialogs.DialogExtensions.InternalRunAsync(ITurnContext turnContext, String dialogId, DialogContext dialogContext, DialogStateManagerConfiguration stateConfiguration, CancellationToken cancellationToken) at Microsoft.Bot.Builder.Dialogs.DialogExtensions.InternalRunAsync(ITurnContext turnContext, String dialogId, DialogContext dialogContext, DialogStateManagerConfiguration stateConfiguration, CancellationToken cancellationToken) at Microsoft.Bot.Builder.Dialogs.DialogExtensions.RunAsync(Dialog dialog, ITurnContext turnContext, IStatePropertyAccessor1 accessor, CancellationToken cancellationToken) at Microsoft.Bot.Builder.Dialogs.Adaptive.AdaptiveDialogBot.OnTurnAsync(ITurnContext turnContext, CancellationToken cancellationToken) at Microsoft.Bot.Builder.SetSpeakMiddleware.OnTurnAsync(ITurnContext turnContext, NextDelegate next, CancellationToken cancellationToken) at Microsoft.Bot.Builder.ShowTypingMiddleware.OnTurnAsync(ITurnContext turnContext, NextDelegate next, CancellationToken cancellationToken) at Microsoft.Bot.Builder.MiddlewareSet.ReceiveActivityWithStatusAsync(ITurnContext turnContext, BotCallbackHandler callback, CancellationToken cancellationToken) at Microsoft.Bot.Builder.BotAdapter.RunPipelineAsync(ITurnContext turnContext, BotCallbackHandler callback, CancellationToken cancellationToken) 'IT_Bot.exe' (CoreCLR: clrhost): Loaded 'C:\Program Files\dotnet\shared\Microsoft.NETCore.App\3.1.23\Microsoft.Win32.Registry.dll'. Skipped loading symbols. Module is optimized and the debugger option 'Just My Code' is enabled.

anishprasad01 commented 2 years ago

As I recall, when I clicked it, I got one more hero card. When I clicked something on that second card, it got confused, since my LUIS and QnA resources do not have your content and aren't trained with your intents. It would just keep repeating "Sorry, I do not understand", which is to be expected. I didn't get a 400 error.

krassussofficial commented 2 years ago

Hi, @anishprasad01

I've been testing and it's clear that the bot has a problem with sending the adaptive cards. I added a response right before sending the card in the logic of the bot and the response displayed fine. Even from above logs:

IT_Bot Information: 0 : 1: 'message' ==> beginDialog ==> SendActivity(${SendActivity_XCXUVv()}) IT_Bot Information: 0 : 5: 'message' ==> error ==> SendActivity(${SendActivity_XCXUVv()})

SendActivity_XCXUVv() regards the hero card.

I honestly don't see how that is a configuration issue.

krassussofficial commented 2 years ago

I have found the issue and resolved it:

When specifying parameters for the Adaptive Card (Options) one cannot leave parameter # IconUrl() empty if the bot is to be published on Teams.

I'm closing this issue.

Thanks for help @anishprasad01 :)

anishprasad01 commented 2 years ago

Interesting. Thanks for following up with your resolution!

MdAbidHussain-91 commented 1 year ago

Hi,

I am facing the exact same issue. Can someone specify what was the exact issue in general.

Thanks