Repository: microsoft/botbuilder-python

Issue:
Additional channel/chat lifecycle events (Python)
See [parent](https://github.com/microsoft/botframework-sdk/issues/5892)


Discussion:
This item is assigned to @JuanAr from Southworks. Having problems with Github at the moment.

Resolving patch:
diff --git a/libraries/botbuilder-core/botbuilder/core/teams/teams_activity_handler.py b/libraries/botbuilder-core/botbuilder/core/teams/teams_activity_handler.py
--- a/libraries/botbuilder-core/botbuilder/core/teams/teams_activity_handler.py
+++ b/libraries/botbuilder-core/botbuilder/core/teams/teams_activity_handler.py
@@ -1,6 +1,8 @@
 # Copyright (c) Microsoft Corporation. All rights reserved.
 # Licensed under the MIT License.
 
+# pylint: disable=too-many-lines
+
 from http import HTTPStatus
 from botbuilder.schema import ChannelAccount, ErrorResponseException, SignInConstants
 from botbuilder.core import ActivityHandler, InvokeResponse
@@ -510,6 +512,18 @@ async def on_conversation_update_activity(self, turn_context: TurnContext):
                     return await self.on_teams_channel_renamed(
                         channel_data.channel, channel_data.team, turn_context
                     )
+                if channel_data.event_type == "teamArchived":
+                    return await self.on_teams_team_archived(
+                        channel_data.team, turn_context
+                    )
+                if channel_data.event_type == "teamDeleted":
+                    return await self.on_teams_team_deleted(
+                        channel_data.team, turn_context
+                    )
+                if channel_data.event_type == "teamHardDeleted":
+                    return await self.on_teams_team_hard_deleted(
+                        channel_data.team, turn_context
+                    )
                 if channel_data.event_type == "channelRestored":
                     return await self.on_teams_channel_restored(
                         channel_data.channel, channel_data.team, turn_context
@@ -518,6 +532,14 @@ async def on_conversation_update_activity(self, turn_context: TurnContext):
                     return await self.on_teams_team_renamed_activity(
                         channel_data.team, turn_context
                     )
+                if channel_data.event_type == "teamRestored":
+                    return await self.on_teams_team_restored(
+                        channel_data.team, turn_context
+                    )
+                if channel_data.event_type == "teamUnarchived":
+                    return await self.on_teams_team_unarchived(
+                        channel_data.team, turn_context
+                    )
 
         return await super().on_conversation_update_activity(turn_context)
 
@@ -536,6 +558,48 @@ async def on_teams_channel_created(  # pylint: disable=unused-argument
         """
         return
 
+    async def on_teams_team_archived(  # pylint: disable=unused-argument
+        self, team_info: TeamInfo, turn_context: TurnContext
+    ):
+        """
+        Invoked when a Team Archived event activity is received from the connector.
+        Team Archived correspond to the user archiving a team.
+
+        :param team_info: The team info object representing the team.
+        :param turn_context: A context object for this turn.
+
+        :returns: A task that represents the work queued to execute.
+        """
+        return
+
+    async def on_teams_team_deleted(  # pylint: disable=unused-argument
+        self, team_info: TeamInfo, turn_context: TurnContext
+    ):
+        """
+        Invoked when a Team Deleted event activity is received from the connector.
+        Team Deleted corresponds to the user deleting a team.
+
+        :param team_info: The team info object representing the team.
+        :param turn_context: A context object for this turn.
+
+        :returns: A task that represents the work queued to execute.
+        """
+        return
+
+    async def on_teams_team_hard_deleted(  # pylint: disable=unused-argument
+        self, team_info: TeamInfo, turn_context: TurnContext
+    ):
+        """
+        Invoked when a Team Hard Deleted event activity is received from the connector.
+        Team Hard Deleted corresponds to the user hard deleting a team.
+
+        :param team_info: The team info object representing the team.
+        :param turn_context: A context object for this turn.
+
+        :returns: A task that represents the work queued to execute.
+        """
+        return
+
     async def on_teams_team_renamed_activity(  # pylint: disable=unused-argument
         self, team_info: TeamInfo, turn_context: TurnContext
     ):
@@ -550,6 +614,34 @@ async def on_teams_team_renamed_activity(  # pylint: disable=unused-argument
         """
         return
 
+    async def on_teams_team_restored(  # pylint: disable=unused-argument
+        self, team_info: TeamInfo, turn_context: TurnContext
+    ):
+        """
+        Invoked when a Team Restored event activity is received from the connector.
+        Team Restored corresponds to the user restoring a team.
+
+        :param team_info: The team info object representing the team.
+        :param turn_context: A context object for this turn.
+
+        :returns: A task that represents the work queued to execute.
+        """
+        return
+
+    async def on_teams_team_unarchived(  # pylint: disable=unused-argument
+        self, team_info: TeamInfo, turn_context: TurnContext
+    ):
+        """
+        Invoked when a Team Unarchived event activity is received from the connector.
+        Team Unarchived correspond to the user unarchiving a team.
+
+        :param team_info: The team info object representing the team.
+        :param turn_context: A context object for this turn.
+
+        :returns: A task that represents the work queued to execute.
+        """
+        return
+
     async def on_teams_members_added_dispatch(  # pylint: disable=unused-argument
         self,
         members_added: [ChannelAccount],


Test patch:
diff --git a/libraries/botbuilder-core/tests/teams/test_teams_activity_handler.py b/libraries/botbuilder-core/tests/teams/test_teams_activity_handler.py
--- a/libraries/botbuilder-core/tests/teams/test_teams_activity_handler.py
+++ b/libraries/botbuilder-core/tests/teams/test_teams_activity_handler.py
@@ -1,5 +1,9 @@
-from typing import List
+# Copyright (c) Microsoft Corporation. All rights reserved.
+# Licensed under the MIT License.
+
+# pylint: disable=too-many-lines
 
+from typing import List
 import aiounittest
 from botbuilder.core import BotAdapter, TurnContext
 from botbuilder.core.teams import TeamsActivityHandler
@@ -116,12 +120,42 @@ async def on_teams_channel_deleted(
             channel_info, team_info, turn_context
         )
 
+    async def on_teams_team_archived(
+        self, team_info: TeamInfo, turn_context: TurnContext
+    ):
+        self.record.append("on_teams_team_archived")
+        return await super().on_teams_team_archived(team_info, turn_context)
+
+    async def on_teams_team_deleted(
+        self, team_info: TeamInfo, turn_context: TurnContext
+    ):
+        self.record.append("on_teams_team_deleted")
+        return await super().on_teams_team_deleted(team_info, turn_context)
+
+    async def on_teams_team_hard_deleted(
+        self, team_info: TeamInfo, turn_context: TurnContext
+    ):
+        self.record.append("on_teams_team_hard_deleted")
+        return await super().on_teams_team_hard_deleted(team_info, turn_context)
+
     async def on_teams_team_renamed_activity(
         self, team_info: TeamInfo, turn_context: TurnContext
     ):
         self.record.append("on_teams_team_renamed_activity")
         return await super().on_teams_team_renamed_activity(team_info, turn_context)
 
+    async def on_teams_team_restored(
+        self, team_info: TeamInfo, turn_context: TurnContext
+    ):
+        self.record.append("on_teams_team_restored")
+        return await super().on_teams_team_restored(team_info, turn_context)
+
+    async def on_teams_team_unarchived(
+        self, team_info: TeamInfo, turn_context: TurnContext
+    ):
+        self.record.append("on_teams_team_unarchived")
+        return await super().on_teams_team_unarchived(team_info, turn_context)
+
     async def on_invoke_activity(self, turn_context: TurnContext):
         self.record.append("on_invoke_activity")
         return await super().on_invoke_activity(turn_context)
@@ -365,6 +399,72 @@ async def test_on_teams_channel_deleted_activity(self):
         assert bot.record[0] == "on_conversation_update_activity"
         assert bot.record[1] == "on_teams_channel_deleted"
 
+    async def test_on_teams_team_archived(self):
+        # arrange
+        activity = Activity(
+            type=ActivityTypes.conversation_update,
+            channel_data={
+                "eventType": "teamArchived",
+                "team": {"id": "team_id_1", "name": "archived_team_name"},
+            },
+            channel_id=Channels.ms_teams,
+        )
+
+        turn_context = TurnContext(NotImplementedAdapter(), activity)
+
+        # Act
+        bot = TestingTeamsActivityHandler()
+        await bot.on_turn(turn_context)
+
+        # Assert
+        assert len(bot.record) == 2
+        assert bot.record[0] == "on_conversation_update_activity"
+        assert bot.record[1] == "on_teams_team_archived"
+
+    async def test_on_teams_team_deleted(self):
+        # arrange
+        activity = Activity(
+            type=ActivityTypes.conversation_update,
+            channel_data={
+                "eventType": "teamDeleted",
+                "team": {"id": "team_id_1", "name": "deleted_team_name"},
+            },
+            channel_id=Channels.ms_teams,
+        )
+
+        turn_context = TurnContext(NotImplementedAdapter(), activity)
+
+        # Act
+        bot = TestingTeamsActivityHandler()
+        await bot.on_turn(turn_context)
+
+        # Assert
+        assert len(bot.record) == 2
+        assert bot.record[0] == "on_conversation_update_activity"
+        assert bot.record[1] == "on_teams_team_deleted"
+
+    async def test_on_teams_team_hard_deleted(self):
+        # arrange
+        activity = Activity(
+            type=ActivityTypes.conversation_update,
+            channel_data={
+                "eventType": "teamHardDeleted",
+                "team": {"id": "team_id_1", "name": "hard_deleted_team_name"},
+            },
+            channel_id=Channels.ms_teams,
+        )
+
+        turn_context = TurnContext(NotImplementedAdapter(), activity)
+
+        # Act
+        bot = TestingTeamsActivityHandler()
+        await bot.on_turn(turn_context)
+
+        # Assert
+        assert len(bot.record) == 2
+        assert bot.record[0] == "on_conversation_update_activity"
+        assert bot.record[1] == "on_teams_team_hard_deleted"
+
     async def test_on_teams_team_renamed_activity(self):
         # arrange
         activity = Activity(
@@ -387,6 +487,50 @@ async def test_on_teams_team_renamed_activity(self):
         assert bot.record[0] == "on_conversation_update_activity"
         assert bot.record[1] == "on_teams_team_renamed_activity"
 
+    async def test_on_teams_team_restored(self):
+        # arrange
+        activity = Activity(
+            type=ActivityTypes.conversation_update,
+            channel_data={
+                "eventType": "teamRestored",
+                "team": {"id": "team_id_1", "name": "restored_team_name"},
+            },
+            channel_id=Channels.ms_teams,
+        )
+
+        turn_context = TurnContext(NotImplementedAdapter(), activity)
+
+        # Act
+        bot = TestingTeamsActivityHandler()
+        await bot.on_turn(turn_context)
+
+        # Assert
+        assert len(bot.record) == 2
+        assert bot.record[0] == "on_conversation_update_activity"
+        assert bot.record[1] == "on_teams_team_restored"
+
+    async def test_on_teams_team_unarchived(self):
+        # arrange
+        activity = Activity(
+            type=ActivityTypes.conversation_update,
+            channel_data={
+                "eventType": "teamUnarchived",
+                "team": {"id": "team_id_1", "name": "unarchived_team_name"},
+            },
+            channel_id=Channels.ms_teams,
+        )
+
+        turn_context = TurnContext(NotImplementedAdapter(), activity)
+
+        # Act
+        bot = TestingTeamsActivityHandler()
+        await bot.on_turn(turn_context)
+
+        # Assert
+        assert len(bot.record) == 2
+        assert bot.record[0] == "on_conversation_update_activity"
+        assert bot.record[1] == "on_teams_team_unarchived"
+
     async def test_on_teams_members_added_activity(self):
         # arrange
         activity = Activity(