@@ -244,6 +244,8 @@ async def _send_to_skill(
244
244
# Process replies in the response.Body.
245
245
response .body : List [Activity ]
246
246
response .body = ExpectedReplies ().deserialize (response .body ).activities
247
+ # Track sent invoke responses, so more than one is not sent.
248
+ sent_invoke_response = False
247
249
248
250
for from_skill_activity in response .body :
249
251
if from_skill_activity .type == ActivityTypes .end_of_conversation :
@@ -254,12 +256,18 @@ async def _send_to_skill(
254
256
await self .dialog_options .conversation_id_factory .delete_conversation_reference (
255
257
skill_conversation_id
256
258
)
257
- elif await self ._intercept_oauth_cards (
259
+ elif not sent_invoke_response and await self ._intercept_oauth_cards (
258
260
context , from_skill_activity , self .dialog_options .connection_name
259
261
):
260
- # do nothing. Token exchange succeeded, so no oauthcard needs to be shown to the user
261
- pass
262
+ # Token exchange succeeded, so no oauthcard needs to be shown to the user
263
+ sent_invoke_response = True
262
264
else :
265
+ # If an invoke response has already been sent we should ignore future invoke responses as this
266
+ # represents a bug in the skill.
267
+ if from_skill_activity .type == ActivityTypes .invoke_response :
268
+ if sent_invoke_response :
269
+ continue
270
+ sent_invoke_response = True
263
271
# Send the response back to the channel.
264
272
await context .send_activity (from_skill_activity )
265
273
0 commit comments