We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
[PORT] Implement hash for App Insights session ID
> Port this change from botbuilder-dotnet/master branch:
https://github.com/microsoft/botbuilder-dotnet/pull/3317

Addresses this issue reported in JS https://github.com/microsoft/botbuilder-js/issues/1512

App Insights has a maximum session ID of 64 characters, but in some instances for some channels (such as reported with Teams) this may be exceeded due to conversation ID currently being used for session ID.  This PR hashes the conversation ID and sets this as the session ID.  It also adds an additional telemetry property to ensure we retain the original conversation ID within the telemetry.

The hashed ID is only used for Application Insights and the original conversation ID and activity are left untouched.


# Changed projects
* integration





--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `libraries/botbuilder-applicationinsights/botbuilder/applicationinsights/processor/telemetry_processor.py`
Content:
```
1 # Copyright (c) Microsoft Corporation. All rights reserved.
2 # Licensed under the MIT License.
3 import json
4 from abc import ABC, abstractmethod
5 
6 
7 class TelemetryProcessor(ABC):
8     """Application Insights Telemetry Processor base class for Bot"""
9 
10     @property
11     def activity_json(self) -> json:
12         """Retrieve the request body as json (Activity)."""
13         body_text = self.get_request_body()
14         body = json.loads(body_text) if body_text is not None else None
15         return body
16 
17     @abstractmethod
18     def can_process(self) -> bool:
19         """Whether the processor can process the request body.
20         :return: True if the request body can be processed, False otherwise.
21         :rtype: bool
22         """
23         return False
24 
25     @abstractmethod
26     def get_request_body(self) -> str:  # pylint: disable=inconsistent-return-statements
27         """Retrieve the request body from flask/django middleware component."""
28         raise NotImplementedError()
29 
30     def __call__(self, data, context) -> bool:
31         """ Traditional Web user and session ID's don't apply for Bots.  This processor
32         replaces the identifiers to be consistent with Bot Framework's notion of
33         user and session id's.
34 
35         Each event that gets logged (with this processor added) will contain additional
36         properties.
37 
38         The following properties are replaced:
39         - context.user.id    - The user ID that Application Insights uses to identify
40         a unique user.
41         - context.session.id - The session ID that APplication Insights uses to
42         identify a unique session.
43 
44         In addition, the additional data properties are added:
45         - activityId - The Bot Framework's Activity ID which represents a unique
46         message identifier.
47         - channelId - The Bot Framework "Channel" (ie, slack/facebook/directline/etc)
48         - activityType - The Bot Framework message classification (ie, message)
49 
50         :param data: Data from Application Insights
51         :type data: telemetry item
52         :param context: Context from Application Insights
53         :type context: context object
54         :returns:  bool -- determines if the event is passed to the server (False = Filtered).
55         """
56 
57         post_data = self.activity_json
58         if post_data is None:
59             # If there is no body (not a BOT request or not configured correctly).
60             # We *could* filter here, but we're allowing event to go through.
61             return True
62 
63         # Override session and user id
64         from_prop = post_data["from"] if "from" in post_data else None
65         user_id = from_prop["id"] if from_prop is not None else None
66         channel_id = post_data["channelId"] if "channelId" in post_data else None
67         conversation = (
68             post_data["conversation"] if "conversation" in post_data else None
69         )
70         conversation_id = conversation["id"] if "id" in conversation else None
71         context.user.id = channel_id + user_id
72         context.session.id = conversation_id
73 
74         # Additional bot-specific properties
75         if "id" in post_data:
76             data.properties["activityId"] = post_data["id"]
77         if "channelId" in post_data:
78             data.properties["channelId"] = post_data["channelId"]
79         if "type" in post_data:
80             data.properties["activityType"] = post_data["type"]
81         return True
82
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/libraries/botbuilder-applicationinsights/botbuilder/applicationinsights/processor/telemetry_processor.py b/libraries/botbuilder-applicationinsights/botbuilder/applicationinsights/processor/telemetry_processor.py
--- a/libraries/botbuilder-applicationinsights/botbuilder/applicationinsights/processor/telemetry_processor.py
+++ b/libraries/botbuilder-applicationinsights/botbuilder/applicationinsights/processor/telemetry_processor.py
@@ -1,7 +1,9 @@
 # Copyright (c) Microsoft Corporation. All rights reserved.
 # Licensed under the MIT License.
+import base64
 import json
 from abc import ABC, abstractmethod
+from _sha256 import sha256
 
 
 class TelemetryProcessor(ABC):
@@ -11,8 +13,9 @@
     def activity_json(self) -> json:
         """Retrieve the request body as json (Activity)."""
         body_text = self.get_request_body()
-        body = json.loads(body_text) if body_text is not None else None
-        return body
+        if body_text:
+            return body_text if isinstance(body_text, dict) else json.loads(body_text)
+        return None
 
     @abstractmethod
     def can_process(self) -> bool:
@@ -67,15 +70,34 @@
         conversation = (
             post_data["conversation"] if "conversation" in post_data else None
         )
-        conversation_id = conversation["id"] if "id" in conversation else None
+
+        session_id = ""
+        if "id" in conversation:
+            conversation_id = conversation["id"]
+            session_id = base64.b64encode(
+                sha256(conversation_id.encode("utf-8")).digest()
+            ).decode()
+
+        # Set the user id on the Application Insights telemetry item.
         context.user.id = channel_id + user_id
-        context.session.id = conversation_id
 
-        # Additional bot-specific properties
+        # Set the session id on the Application Insights telemetry item.
+        # Hashed ID is used due to max session ID length for App Insights session Id
+        context.session.id = session_id
+
+        # Set the activity id:
+        # https://github.com/Microsoft/botframework-obi/blob/master/botframework-activity/botframework-activity.md#id
         if "id" in post_data:
             data.properties["activityId"] = post_data["id"]
+
+        # Set the channel id:
+        # https://github.com/Microsoft/botframework-obi/blob/master/botframework-activity/botframework-activity.md#channel-id
         if "channelId" in post_data:
             data.properties["channelId"] = post_data["channelId"]
+
+        # Set the activity type:
+        # https://github.com/Microsoft/botframework-obi/blob/master/botframework-activity/botframework-activity.md#type
         if "type" in post_data:
             data.properties["activityType"] = post_data["type"]
+
         return True

{"golden_diff": "diff --git a/libraries/botbuilder-applicationinsights/botbuilder/applicationinsights/processor/telemetry_processor.py b/libraries/botbuilder-applicationinsights/botbuilder/applicationinsights/processor/telemetry_processor.py\n--- a/libraries/botbuilder-applicationinsights/botbuilder/applicationinsights/processor/telemetry_processor.py\n+++ b/libraries/botbuilder-applicationinsights/botbuilder/applicationinsights/processor/telemetry_processor.py\n@@ -1,7 +1,9 @@\n # Copyright (c) Microsoft Corporation. All rights reserved.\n # Licensed under the MIT License.\n+import base64\n import json\n from abc import ABC, abstractmethod\n+from _sha256 import sha256\n \n \n class TelemetryProcessor(ABC):\n@@ -11,8 +13,9 @@\n     def activity_json(self) -> json:\n         \"\"\"Retrieve the request body as json (Activity).\"\"\"\n         body_text = self.get_request_body()\n-        body = json.loads(body_text) if body_text is not None else None\n-        return body\n+        if body_text:\n+            return body_text if isinstance(body_text, dict) else json.loads(body_text)\n+        return None\n \n     @abstractmethod\n     def can_process(self) -> bool:\n@@ -67,15 +70,34 @@\n         conversation = (\n             post_data[\"conversation\"] if \"conversation\" in post_data else None\n         )\n-        conversation_id = conversation[\"id\"] if \"id\" in conversation else None\n+\n+        session_id = \"\"\n+        if \"id\" in conversation:\n+            conversation_id = conversation[\"id\"]\n+            session_id = base64.b64encode(\n+                sha256(conversation_id.encode(\"utf-8\")).digest()\n+            ).decode()\n+\n+        # Set the user id on the Application Insights telemetry item.\n         context.user.id = channel_id + user_id\n-        context.session.id = conversation_id\n \n-        # Additional bot-specific properties\n+        # Set the session id on the Application Insights telemetry item.\n+        # Hashed ID is used due to max session ID length for App Insights session Id\n+        context.session.id = session_id\n+\n+        # Set the activity id:\n+        # https://github.com/Microsoft/botframework-obi/blob/master/botframework-activity/botframework-activity.md#id\n         if \"id\" in post_data:\n             data.properties[\"activityId\"] = post_data[\"id\"]\n+\n+        # Set the channel id:\n+        # https://github.com/Microsoft/botframework-obi/blob/master/botframework-activity/botframework-activity.md#channel-id\n         if \"channelId\" in post_data:\n             data.properties[\"channelId\"] = post_data[\"channelId\"]\n+\n+        # Set the activity type:\n+        # https://github.com/Microsoft/botframework-obi/blob/master/botframework-activity/botframework-activity.md#type\n         if \"type\" in post_data:\n             data.properties[\"activityType\"] = post_data[\"type\"]\n+\n         return True\n", "issue": "[PORT] Implement hash for App Insights session ID\n> Port this change from botbuilder-dotnet/master branch:\nhttps://github.com/microsoft/botbuilder-dotnet/pull/3317\n\nAddresses this issue reported in JS https://github.com/microsoft/botbuilder-js/issues/1512\r\n\r\nApp Insights has a maximum session ID of 64 characters, but in some instances for some channels (such as reported with Teams) this may be exceeded due to conversation ID currently being used for session ID.  This PR hashes the conversation ID and sets this as the session ID.  It also adds an additional telemetry property to ensure we retain the original conversation ID within the telemetry.\r\n\r\nThe hashed ID is only used for Application Insights and the original conversation ID and activity are left untouched.\n\n\r\n# Changed projects\r\n* integration\r\n\r\n\r\n\n\n", "before_files": [{"content": "# Copyright (c) Microsoft Corporation. All rights reserved.\n# Licensed under the MIT License.\nimport json\nfrom abc import ABC, abstractmethod\n\n\nclass TelemetryProcessor(ABC):\n    \"\"\"Application Insights Telemetry Processor base class for Bot\"\"\"\n\n    @property\n    def activity_json(self) -> json:\n        \"\"\"Retrieve the request body as json (Activity).\"\"\"\n        body_text = self.get_request_body()\n        body = json.loads(body_text) if body_text is not None else None\n        return body\n\n    @abstractmethod\n    def can_process(self) -> bool:\n        \"\"\"Whether the processor can process the request body.\n        :return: True if the request body can be processed, False otherwise.\n        :rtype: bool\n        \"\"\"\n        return False\n\n    @abstractmethod\n    def get_request_body(self) -> str:  # pylint: disable=inconsistent-return-statements\n        \"\"\"Retrieve the request body from flask/django middleware component.\"\"\"\n        raise NotImplementedError()\n\n    def __call__(self, data, context) -> bool:\n        \"\"\" Traditional Web user and session ID's don't apply for Bots.  This processor\n        replaces the identifiers to be consistent with Bot Framework's notion of\n        user and session id's.\n\n        Each event that gets logged (with this processor added) will contain additional\n        properties.\n\n        The following properties are replaced:\n        - context.user.id    - The user ID that Application Insights uses to identify\n        a unique user.\n        - context.session.id - The session ID that APplication Insights uses to\n        identify a unique session.\n\n        In addition, the additional data properties are added:\n        - activityId - The Bot Framework's Activity ID which represents a unique\n        message identifier.\n        - channelId - The Bot Framework \"Channel\" (ie, slack/facebook/directline/etc)\n        - activityType - The Bot Framework message classification (ie, message)\n\n        :param data: Data from Application Insights\n        :type data: telemetry item\n        :param context: Context from Application Insights\n        :type context: context object\n        :returns:  bool -- determines if the event is passed to the server (False = Filtered).\n        \"\"\"\n\n        post_data = self.activity_json\n        if post_data is None:\n            # If there is no body (not a BOT request or not configured correctly).\n            # We *could* filter here, but we're allowing event to go through.\n            return True\n\n        # Override session and user id\n        from_prop = post_data[\"from\"] if \"from\" in post_data else None\n        user_id = from_prop[\"id\"] if from_prop is not None else None\n        channel_id = post_data[\"channelId\"] if \"channelId\" in post_data else None\n        conversation = (\n            post_data[\"conversation\"] if \"conversation\" in post_data else None\n        )\n        conversation_id = conversation[\"id\"] if \"id\" in conversation else None\n        context.user.id = channel_id + user_id\n        context.session.id = conversation_id\n\n        # Additional bot-specific properties\n        if \"id\" in post_data:\n            data.properties[\"activityId\"] = post_data[\"id\"]\n        if \"channelId\" in post_data:\n            data.properties[\"channelId\"] = post_data[\"channelId\"]\n        if \"type\" in post_data:\n            data.properties[\"activityType\"] = post_data[\"type\"]\n        return True\n", "path": "libraries/botbuilder-applicationinsights/botbuilder/applicationinsights/processor/telemetry_processor.py"}], "after_files": [{"content": "# Copyright (c) Microsoft Corporation. All rights reserved.\n# Licensed under the MIT License.\nimport base64\nimport json\nfrom abc import ABC, abstractmethod\nfrom _sha256 import sha256\n\n\nclass TelemetryProcessor(ABC):\n    \"\"\"Application Insights Telemetry Processor base class for Bot\"\"\"\n\n    @property\n    def activity_json(self) -> json:\n        \"\"\"Retrieve the request body as json (Activity).\"\"\"\n        body_text = self.get_request_body()\n        if body_text:\n            return body_text if isinstance(body_text, dict) else json.loads(body_text)\n        return None\n\n    @abstractmethod\n    def can_process(self) -> bool:\n        \"\"\"Whether the processor can process the request body.\n        :return: True if the request body can be processed, False otherwise.\n        :rtype: bool\n        \"\"\"\n        return False\n\n    @abstractmethod\n    def get_request_body(self) -> str:  # pylint: disable=inconsistent-return-statements\n        \"\"\"Retrieve the request body from flask/django middleware component.\"\"\"\n        raise NotImplementedError()\n\n    def __call__(self, data, context) -> bool:\n        \"\"\" Traditional Web user and session ID's don't apply for Bots.  This processor\n        replaces the identifiers to be consistent with Bot Framework's notion of\n        user and session id's.\n\n        Each event that gets logged (with this processor added) will contain additional\n        properties.\n\n        The following properties are replaced:\n        - context.user.id    - The user ID that Application Insights uses to identify\n        a unique user.\n        - context.session.id - The session ID that APplication Insights uses to\n        identify a unique session.\n\n        In addition, the additional data properties are added:\n        - activityId - The Bot Framework's Activity ID which represents a unique\n        message identifier.\n        - channelId - The Bot Framework \"Channel\" (ie, slack/facebook/directline/etc)\n        - activityType - The Bot Framework message classification (ie, message)\n\n        :param data: Data from Application Insights\n        :type data: telemetry item\n        :param context: Context from Application Insights\n        :type context: context object\n        :returns:  bool -- determines if the event is passed to the server (False = Filtered).\n        \"\"\"\n\n        post_data = self.activity_json\n        if post_data is None:\n            # If there is no body (not a BOT request or not configured correctly).\n            # We *could* filter here, but we're allowing event to go through.\n            return True\n\n        # Override session and user id\n        from_prop = post_data[\"from\"] if \"from\" in post_data else None\n        user_id = from_prop[\"id\"] if from_prop is not None else None\n        channel_id = post_data[\"channelId\"] if \"channelId\" in post_data else None\n        conversation = (\n            post_data[\"conversation\"] if \"conversation\" in post_data else None\n        )\n\n        session_id = \"\"\n        if \"id\" in conversation:\n            conversation_id = conversation[\"id\"]\n            session_id = base64.b64encode(\n                sha256(conversation_id.encode(\"utf-8\")).digest()\n            ).decode()\n\n        # Set the user id on the Application Insights telemetry item.\n        context.user.id = channel_id + user_id\n\n        # Set the session id on the Application Insights telemetry item.\n        # Hashed ID is used due to max session ID length for App Insights session Id\n        context.session.id = session_id\n\n        # Set the activity id:\n        # https://github.com/Microsoft/botframework-obi/blob/master/botframework-activity/botframework-activity.md#id\n        if \"id\" in post_data:\n            data.properties[\"activityId\"] = post_data[\"id\"]\n\n        # Set the channel id:\n        # https://github.com/Microsoft/botframework-obi/blob/master/botframework-activity/botframework-activity.md#channel-id\n        if \"channelId\" in post_data:\n            data.properties[\"channelId\"] = post_data[\"channelId\"]\n\n        # Set the activity type:\n        # https://github.com/Microsoft/botframework-obi/blob/master/botframework-activity/botframework-activity.md#type\n        if \"type\" in post_data:\n            data.properties[\"activityType\"] = post_data[\"type\"]\n\n        return True\n", "path": "libraries/botbuilder-applicationinsights/botbuilder/applicationinsights/processor/telemetry_processor.py"}]}