Repository: microsoft/botbuilder-python

Issue:
BotFrameworkAdapter.create_conversation overrides parameters.channel_data
## Version
4.13

## Describe the bug
A Teams bot using BotFrameworkAdapter can't create conversation in a team channel. turn_context.adapter.create_conversation() raises a parameter error of HTTP request.

## To Reproduce
Steps to reproduce the behavior:
1. Deploy a bot using BotFrameworkAdapter and turn_context.adapter.create_conversation() method to create a conversation in a team channel. To do it, conversation_parameters argument of create_conversation() must have channel_data attribute that has information of the channel to use.
2. Show the logs of the bot. If you use Azure, Log-in to the Azure portal with a web browser, click "app service", click the bot app and click Log Stream.
3. Log-in Teams.
4. Make the bot creating a conversation in a team channel.
5. See an error.
6. Confirm the error logs in the log window you opened at step 2.

## Expected behavior
A conversation will be created without any error.

## Screenshots
No.

## Additional context
No.

## Additional Information
parameters.channel_data looks overridden in create_conversation() below:
https://github.com/microsoft/botbuilder-python/blob/main/libraries/botbuilder-core/botbuilder/core/bot_framework_adapter.py#L369

IMO, it should be:
```
if parameters.channel_data is None:
    parameters.channel_data = {}
parameters.channel_data["tenant"] = {"tenantId": reference.conversation.tenant_id}
```



Discussion:
Thank you for the report, @yosshy 

Can you provide some code to help us reproduce the issue? Are you following a sample, perhaps?

Also, are you able to reproduce this problem with a local bot or only with a deployed bot?
@v-kydela thank you for your reply. I'm not following a sample but creating a new bot for our purpose. Currently, I can't provide our code soon.

If "a local bot" means one running with Bot Framework Emulator, we can't reproduce it because it is not for a team channel but for 1:1 chat, IMO. So, we can do it only with a deployed one.
Hi @yosshy 

While Emulator is useful for testing local bots, Emulator is just another client and does not define where the bot is running. You can test local bots on Emulator or Teams, and you can test deployed bots on Emulator or Teams.

If you're unfamiliar with tunneling, please refer to this documentation: https://docs.microsoft.com/azure/bot-service/bot-service-debug-channel-ngrok
Hi @v-kydela ,

Thank you for your description about local bots. I have no local environment for a local bot but I'll prepare it soon.
@yosshy - Have you prepared a local environment yet?
@cleemullins - I think this is a legitimate bug rather than a support issue. A suggested fix was provided in the original post, but I think it should be applied to the other SDK's as well. Can this be escalated?
@yosshy - As a workaround, you can bypass the adapter by calling `connector_client.conversations.create_conversation` directly as seen in [this sample](https://github.com/microsoft/BotBuilder-Samples/blob/main/samples/python/58.teams-start-thread-in-channel/bots/teams_start_thread_in_channel.py#L35)

@EricDahlvang - To reproduce this bug, you need to call `adapter.create_conversation` as described in the original repro steps. The sample can be modified to do so.
I'll go ahead and unassign myself so it can be triaged
@axelsrz can you take a look and confirm this is a bug in the product.
We will add this bug to our current iteration to provide a fix, as well as track this fix on our other SDKs.
To those that have reproduced this error, what data is being put into ConversationParameters.channel_data?  Specifically, how does that differ from sample 57.teams-conversation-bot, which doesn't populate channel_data at all?  What I'm trying to chase down is whether we still have to add tenant id to channel_data.

Resolving patch:
diff --git a/libraries/botbuilder-core/botbuilder/core/bot_framework_adapter.py b/libraries/botbuilder-core/botbuilder/core/bot_framework_adapter.py
--- a/libraries/botbuilder-core/botbuilder/core/bot_framework_adapter.py
+++ b/libraries/botbuilder-core/botbuilder/core/bot_framework_adapter.py
@@ -340,6 +340,7 @@ async def create_conversation(
             If the conversation is established with the specified users, the ID of the activity
             will contain the ID of the new conversation.
         """
+
         try:
             if not service_url:
                 service_url = reference.service_url
@@ -366,8 +367,10 @@ async def create_conversation(
             # Mix in the tenant ID if specified. This is required for MS Teams.
             if reference.conversation and reference.conversation.tenant_id:
                 # Putting tenant_id in channel_data is a temporary while we wait for the Teams API to be updated
-                parameters.channel_data = {
-                    "tenant": {"tenantId": reference.conversation.tenant_id}
+                if parameters.channel_data is None:
+                    parameters.channel_data = {}
+                parameters.channel_data["tenant"] = {
+                    "tenantId": reference.conversation.tenant_id
                 }
 
                 # Permanent solution is to put tenant_id in parameters.tenant_id


Test patch: