Repository: microsoft/botbuilder-python

Issue:
SkillHandler doesn't return ResourceResponse when forwarding activities (Python)
See [parent](https://github.com/microsoft/botframework-sdk/issues/5919)


Discussion:

Resolving patch:
diff --git a/libraries/botbuilder-core/botbuilder/core/skills/skill_handler.py b/libraries/botbuilder-core/botbuilder/core/skills/skill_handler.py
--- a/libraries/botbuilder-core/botbuilder/core/skills/skill_handler.py
+++ b/libraries/botbuilder-core/botbuilder/core/skills/skill_handler.py
@@ -151,7 +151,14 @@ async def _process_activity(
         if not skill_conversation_reference:
             raise KeyError("SkillConversationReference not found")
 
+        if not skill_conversation_reference.conversation_reference:
+            raise KeyError("conversationReference not found")
+
+        # If an activity is sent, return the ResourceResponse
+        resource_response: ResourceResponse = None
+
         async def callback(context: TurnContext):
+            nonlocal resource_response
             context.turn_state[
                 SkillHandler.SKILL_CONVERSATION_REFERENCE_KEY
             ] = skill_conversation_reference
@@ -177,7 +184,7 @@ async def callback(context: TurnContext):
                 self._apply_event_to_turn_context_activity(context, activity)
                 await self._bot.on_turn(context)
             else:
-                await context.send_activity(activity)
+                resource_response = await context.send_activity(activity)
 
         await self._adapter.continue_conversation(
             skill_conversation_reference.conversation_reference,
@@ -185,7 +192,11 @@ async def callback(context: TurnContext):
             claims_identity=claims_identity,
             audience=skill_conversation_reference.oauth_scope,
         )
-        return ResourceResponse(id=str(uuid4()))
+
+        if not resource_response:
+            resource_response = ResourceResponse(id=str(uuid4()))
+
+        return resource_response
 
     @staticmethod
     def _apply_eoc_to_turn_context_activity(


Test patch:
diff --git a/libraries/botbuilder-core/tests/skills/test_skill_handler.py b/libraries/botbuilder-core/tests/skills/test_skill_handler.py
--- a/libraries/botbuilder-core/tests/skills/test_skill_handler.py
+++ b/libraries/botbuilder-core/tests/skills/test_skill_handler.py
@@ -238,6 +238,42 @@ async def test_on_send_to_conversation(self):
         )
         assert activity.caller_id is None
 
+    async def test_forwarding_on_send_to_conversation(self):
+        self._conversation_id = await self._test_id_factory.create_skill_conversation_id(
+            self._conversation_reference
+        )
+
+        resource_response_id = "rId"
+
+        async def side_effect(
+            *arg_list, **args_dict
+        ):  # pylint: disable=unused-argument
+            fake_context = Mock()
+            fake_context.turn_state = {}
+            fake_context.send_activity = MagicMock(return_value=Future())
+            fake_context.send_activity.return_value.set_result(
+                ResourceResponse(id=resource_response_id)
+            )
+            await arg_list[1](fake_context)
+
+        mock_adapter = Mock()
+        mock_adapter.continue_conversation = side_effect
+        mock_adapter.send_activities = MagicMock(return_value=Future())
+        mock_adapter.send_activities.return_value.set_result([])
+
+        sut = self.create_skill_handler_for_testing(mock_adapter)
+
+        activity = Activity(type=ActivityTypes.message, attachments=[], entities=[])
+        TurnContext.apply_conversation_reference(activity, self._conversation_reference)
+
+        assert not activity.caller_id
+
+        response = await sut.test_on_send_to_conversation(
+            self._claims_identity, self._conversation_id, activity
+        )
+
+        assert response.id is resource_response_id
+
     async def test_on_reply_to_activity(self):
         self._conversation_id = await self._test_id_factory.create_skill_conversation_id(
             self._conversation_reference