Repository: microsoft/botbuilder-python

Issue:
Incorrect channel_data data type in TelemetryLoggerMiddleware
## Version
4.14

## Describe the bug
Channel data from Teams are incorrectly used in Telemetry Middleware. Bot is not able to respond to any message sent via Teams when the Telemetry is enabled. The same bot works fine when tested in Bot Framework Emulator.

## To Reproduce
Steps to reproduce the behavior:
1. Add Telemetry to your Python Bot:
```
TELEMETRY_CLIENT = ApplicationInsightsTelemetryClient(
    CONFIG.APPINSIGHTS_INSTRUMENTATION_KEY, telemetry_processor=AiohttpTelemetryProcessor(), client_queue_size=1
)
TELEMETRY_LOGGER_MIDDLEWARE = TelemetryLoggerMiddleware(TELEMETRY_CLIENT, True)
ADAPTER.use(TELEMETRY_LOGGER_MIDDLEWARE)
...
APP = web.Application(middlewares=[bot_telemetry_middleware, aiohttp_error_middleware])
```
2. Deploy to Azure and connect to Teams
3. Send a message from Teams to the bot.
4. See error:
```
2022-04-21T10:55:29.178590260Z     TelemetryLoggerMiddleware.__populate_additional_channel_properties(
2022-04-21T10:55:29.178594560Z   File "/usr/local/lib/python3.8/site-packages/botbuilder/core/telemetry_logger_middleware.py", line 307, in __populate_additional_channel_properties
2022-04-21T10:55:29.178599160Z     if teams_channel_data and teams_channel_data.tenant
2022-04-21T10:55:29.178603361Z AttributeError: 'dict' object has no attribute 'tenant'
```

## Additional context
I have found out that `activity.channel_data` is a dict, not an object. Therefore, I changed the following method in `telemetry_logger_middleware.py` to use the dict instead of the object and now it works fine. 
```
    @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']['id']
                if teams_channel_data and teams_channel_data.get("tenant", {}).get("id", None)
                else ""
            )

            properties["TeamsUserAadObjectId"] = (
                activity.from_property.aad_object_id if activity.from_property else ""
            )

            if teams_channel_data and teams_channel_data.get("team", None):
                properties["TeamsTeamInfo"] = TeamInfo.serialize(
                    teams_channel_data['team']
                )
```



Discussion:
Hi @ivopisarovic,

Thanks for your report. I am investigating.
Hi @ivopisarovic,

I took the Python core bot sample with telemetry and connected to it through Teams, and I am unable to reproduce this error.

A few clarification questions:

- You are unable to get a response back to *any* message sent to the bot? 
- Do you get welcome messages? 
- Does the bot work without telemetry?
- What type of bot is this? (Single Tenant, Multi, Managed Identity)
- Did you upload a Teams manifest, or did you connect via the "Open in Teams" link in the channel menu?
Thanks for looking into the problem. See my answers below. I will try to do further testing and I will try to prepare a demo, so you can test my code. 

>    You are unable to get a response back to any message sent to the bot?

Exactly, no response.

>    Do you get welcome messages?

No, even the welcome message sends some logs to Insights. Therefore, even this message fails.

>    Does the bot work without telemetry?

Good question, I have not tested it. But after the change I mentioned earlier it works. 

>    What type of bot is this? (Single Tenant, Multi, Managed Identity)

It is a multi tenant bot.

>    Did you upload a Teams manifest, or did you connect via the "Open in Teams" link in the channel menu?

I used the Open in Teams link.




> I used the Open in Teams link.

One thing I'd always recommend is using an app manifest. Sometimes bots don't work properly if you use `Open in Teams`, so app manifests are always your best bet. Adding an app manifest is effectively installing an app, which is what you would be doing if you deployed your bot as a production Teams app. 

If you haven't used a manifest before, you should be able to make use of one from another sample, such as [this one](https://github.com/microsoft/BotBuilder-Samples/tree/main/samples/python/57.teams-conversation-bot/teams_app_manifest). Simply fill in the marked fields, zip all three files into one archive named `manifest`, and upload this as a custom app to Teams.
Closing this issue due to inactivity. If you still require assistance, please comment and we can reopen the issue.

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
@@ -303,10 +303,12 @@ def __populate_additional_channel_properties(
         properties: dict,
     ):
         if activity.channel_id == Channels.ms_teams:
-            teams_channel_data: TeamsChannelData = activity.channel_data
+            teams_channel_data: TeamsChannelData = TeamsChannelData().deserialize(
+                activity.channel_data
+            )
 
             properties["TeamsTenantId"] = (
-                teams_channel_data.tenant
+                teams_channel_data.tenant.id
                 if teams_channel_data and teams_channel_data.tenant
                 else ""
             )
diff --git a/libraries/botbuilder-dialogs/setup.py b/libraries/botbuilder-dialogs/setup.py
--- a/libraries/botbuilder-dialogs/setup.py
+++ b/libraries/botbuilder-dialogs/setup.py
@@ -6,6 +6,7 @@
 
 REQUIRES = [
     "regex<=2019.08.19",
+    "emoji==1.7.0",
     "recognizers-text-date-time>=1.0.2a1",
     "recognizers-text-number-with-unit>=1.0.2a1",
     "recognizers-text-number>=1.0.2a1",


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
@@ -251,7 +251,7 @@ async def test_log_teams(self):
         channel_data = TeamsChannelData(
             team=team_info,
             tenant=TenantInfo(id="tenantId"),
-        )
+        ).serialize()
 
         activity = MessageFactory.text("test")
         activity.channel_data = channel_data
@@ -272,7 +272,7 @@ async def test_log_teams(self):
                     "fromId": "userId",
                     "recipientId": "bot",
                     "recipientName": "Bot",
-                    "TeamsTenantId": TenantInfo(id="tenantId"),
+                    "TeamsTenantId": "tenantId",
                     "TeamsUserAadObjectId": "aaId",
                     "TeamsTeamInfo": TeamInfo.serialize(team_info),
                 },