Repository: microsoft/botbuilder-python

Issue:
[PORT] Add Teams specific telemetry properties 
> Port this change from botbuilder-dotnet/master branch:
https://github.com/microsoft/botbuilder-dotnet/pull/4256

Add Teams specific telemetry properties when activity received via the Teams channel.

See also https://github.com/microsoft/botframework-sdk/issues/5855



# Changed projects
* Microsoft.Bot.Builder
* Microsoft.Bot.Builder.Tests






Discussion:

Resolving patch:
diff --git a/libraries/botbuilder-core/botbuilder/core/telemetry_logger_middleware.py b/libraries/botbuilder-core/botbuilder/core/telemetry_logger_middleware.py
--- a/libraries/botbuilder-core/botbuilder/core/telemetry_logger_middleware.py
+++ b/libraries/botbuilder-core/botbuilder/core/telemetry_logger_middleware.py
@@ -1,9 +1,11 @@
 # Copyright (c) Microsoft Corporation. All rights reserved.
 # Licensed under the MIT License.
 """Middleware Component for logging Activity messages."""
-
 from typing import Awaitable, Callable, List, Dict
 from botbuilder.schema import Activity, ConversationReference, ActivityTypes
+from botbuilder.schema.teams import TeamsChannelData, TeamInfo
+from botframework.connector import Channels
+
 from .bot_telemetry_client import BotTelemetryClient
 from .bot_assert import BotAssert
 from .middleware_set import Middleware
@@ -183,6 +185,10 @@ async def fill_receive_event_properties(
             if activity.speak and activity.speak.strip():
                 properties[TelemetryConstants.SPEAK_PROPERTY] = activity.speak
 
+        TelemetryLoggerMiddleware.__populate_additional_channel_properties(
+            activity, properties
+        )
+
         # Additional properties can override "stock" properties
         if additional_properties:
             for prop in additional_properties:
@@ -288,3 +294,25 @@ async def fill_delete_event_properties(
                 properties[prop.key] = prop.value
 
         return properties
+
+    @staticmethod
+    def __populate_additional_channel_properties(
+        activity: Activity, properties: dict,
+    ):
+        if activity.channel_id == Channels.ms_teams:
+            teams_channel_data: TeamsChannelData = activity.channel_data
+
+            properties["TeamsTenantId"] = (
+                teams_channel_data.tenant
+                if teams_channel_data and teams_channel_data.tenant
+                else ""
+            )
+
+            properties["TeamsUserAadObjectId"] = (
+                activity.from_property.aad_object_id if activity.from_property else ""
+            )
+
+            if teams_channel_data and teams_channel_data.team:
+                properties["TeamsTeamInfo"] = TeamInfo.serialize(
+                    teams_channel_data.team
+                )


Test patch:
diff --git a/libraries/botbuilder-core/tests/test_telemetry_middleware.py b/libraries/botbuilder-core/tests/test_telemetry_middleware.py
--- a/libraries/botbuilder-core/tests/test_telemetry_middleware.py
+++ b/libraries/botbuilder-core/tests/test_telemetry_middleware.py
@@ -7,11 +7,14 @@
 from typing import Dict
 from unittest.mock import Mock
 import aiounittest
+from botframework.connector import Channels
+
 from botbuilder.core import (
     NullTelemetryClient,
     TelemetryLoggerMiddleware,
     TelemetryLoggerConstants,
     TurnContext,
+    MessageFactory,
 )
 from botbuilder.core.adapters import TestAdapter, TestFlow
 from botbuilder.schema import (
@@ -19,7 +22,9 @@
     ActivityTypes,
     ChannelAccount,
     ConversationAccount,
+    ConversationReference,
 )
+from botbuilder.schema.teams import TeamInfo, TeamsChannelData, TenantInfo
 
 
 class TestTelemetryMiddleware(aiounittest.AsyncTestCase):
@@ -228,6 +233,47 @@ async def process(context: TurnContext) -> None:
         ]
         self.assert_telemetry_calls(telemetry, telemetry_call_expected)
 
+    async def test_log_teams(self):
+        telemetry = Mock()
+        my_logger = TelemetryLoggerMiddleware(telemetry, True)
+
+        adapter = TestAdapter(
+            template_or_conversation=ConversationReference(channel_id=Channels.ms_teams)
+        )
+        adapter.use(my_logger)
+
+        team_info = TeamInfo(id="teamId", name="teamName",)
+
+        channel_data = TeamsChannelData(
+            team=team_info, tenant=TenantInfo(id="tenantId"),
+        )
+
+        activity = MessageFactory.text("test")
+        activity.channel_data = channel_data
+        activity.from_property = ChannelAccount(
+            id="userId", name="userName", aad_object_id="aaId",
+        )
+
+        test_flow = TestFlow(None, adapter)
+        await test_flow.send(activity)
+
+        telemetry_call_expected = [
+            (
+                TelemetryLoggerConstants.BOT_MSG_RECEIVE_EVENT,
+                {
+                    "text": "test",
+                    "fromId": "userId",
+                    "recipientId": "bot",
+                    "recipientName": "Bot",
+                    "TeamsTenantId": TenantInfo(id="tenantId"),
+                    "TeamsUserAadObjectId": "aaId",
+                    "TeamsTeamInfo": TeamInfo.serialize(team_info),
+                },
+            ),
+        ]
+
+        self.assert_telemetry_calls(telemetry, telemetry_call_expected)
+
     def create_reply(self, activity, text, locale=None):
         return Activity(
             type=ActivityTypes.message,