title: Teams Bot throws Unauthorized error when attempting to send message back
body: <p>I am attempting to build a simple MS Teams bot using the Python bot framework SDK. When testing my bot locally using the emulator, everything works fine. I registered the bot using the legacy portal here <a href="https://dev.botframework.com/bots" rel="nofollow noreferrer">https://dev.botframework.com/bots</a> as I do not want to create an Azure subscription.</p>
  
  <p>I added the app id and app secret to the bot and deployed it on an EC2 machine using API Gateway (with HTTP proxy integration) to get an HTTPS url for the messaging endpoint.</p>
  
  <p>When deployed, the code is able to receive and parse messages from both the testing functionality on the dev framework page and from an actual deployed app on Teams. However, when attempting to respond to the message, I get an Unauthorized error message.</p>
  
  <p>Here is the stack trace:</p>
  
  <pre><code>[on_turn_error] unhandled error: Operation returned an invalid status code 'Unauthorized'
  Traceback (most recent call last):
    File "/usr/local/lib/python3.7/site-packages/botbuilder/core/bot_adapter.py", line 103, in run_pipeline
      context, callback
    File "/usr/local/lib/python3.7/site-packages/botbuilder/core/middleware_set.py", line 69, in receive_activity_with_status
      return await self.receive_activity_internal(context, callback)
    File "/usr/local/lib/python3.7/site-packages/botbuilder/core/middleware_set.py", line 79, in receive_activity_internal
      return await callback(context)
    File "/usr/local/lib/python3.7/site-packages/botbuilder/core/activity_handler.py", line 28, in on_turn
      await self.on_message_activity(turn_context)
    File "/home/ec2-user/bot/bot.py", line 24, in on_message_activity
      return await turn_context.send_activity(response)
    File "/usr/local/lib/python3.7/site-packages/botbuilder/core/turn_context.py", line 165, in send_activity
      result = await self.send_activities([activity_or_text])
    File "/usr/local/lib/python3.7/site-packages/botbuilder/core/turn_context.py", line 198, in send_activities
      return await self._emit(self._on_send_activities, output, logic())
    File "/usr/local/lib/python3.7/site-packages/botbuilder/core/turn_context.py", line 276, in _emit
      return await logic
    File "/usr/local/lib/python3.7/site-packages/botbuilder/core/turn_context.py", line 193, in logic
      responses = await self.adapter.send_activities(self, output)
    File "/usr/local/lib/python3.7/site-packages/botbuilder/core/bot_framework_adapter.py", line 444, in send_activities
      raise error
    File "/usr/local/lib/python3.7/site-packages/botbuilder/core/bot_framework_adapter.py", line 431, in send_activities
      activity.conversation.id, activity.reply_to_id, activity
    File "/usr/local/lib/python3.7/site-packages/botframework/connector/aio/operations_async/_conversations_operations_async.py", line 533, in reply_to_activity
      raise models.ErrorResponseException(self._deserialize, response)
  botbuilder.schema._models_py3.ErrorResponseException: Operation returned an invalid status code 'Unauthorized'
  </code></pre>
  
  <p>My app code is:</p>
  
  <pre><code>CONFIG = DefaultConfig()
  SETTINGS = BotFrameworkAdapterSettings(CONFIG.APP_ID, CONFIG.APP_PASSWORD,
                                         CONFIG.APP_AUTH_TENANT, CONFIG.APP_OAUTH_ENDPOINT)
  ADAPTER = BotFrameworkAdapter(SETTINGS)
  
  
  # Catch-all for errors.
  async def on_error(context: TurnContext, error: Exception):
      print(f"\n [on_turn_error] unhandled error: {error}", file=sys.stderr)
      traceback.print_exc()
  
      # Send a message to the user
      await context.send_activity("The bot encountered an error or bug.")
      await context.send_activity("To continue to run this bot, please fix the bot source code.")
      # Send a trace activity if we're talking to the Bot Framework Emulator
      if context.activity.channel_id == "emulator":
          # Create a trace activity that contains the error object
          trace_activity = Activity(
              label="TurnError",
              name="on_turn_error Trace",
              timestamp=datetime.utcnow(),
              type=ActivityTypes.trace,
              value=f"{error}",
              value_type="https://www.botframework.com/schemas/error",
          )
          # Send a trace activity, which will be displayed in Bot Framework Emulator
          await context.send_activity(trace_activity)
  
  
  ADAPTER.on_turn_error = on_error
  APP_ID = SETTINGS.app_id
  dynamodb = boto3.resource("dynamodb")
  CONVERSATION_REFERENCES = dynamodb.Table("ConversationReferences")
  
  # Create the Bot
  BOT = MyBot(CONVERSATION_REFERENCES)
  
  
  # Listen for incoming requests on /api/messages
  async def messages(req):
      print(f"Message Received - {str(datetime.now())}")
      json_request = await req.json()
      print(f"Request Body: {json_request}")
      activity = Activity().deserialize(json_request)
      print("Request successfully deserialized")
      auth_header = req.headers["Authorization"] if "Authorization" in req.headers else ""
      try:
          print("Sending activity to adapter")
          response = await ADAPTER.process_activity(activity, auth_header, BOT.on_turn)
          if response:
              return Response(status=response.status, text=response.body)
          return Response(status=201)
      except Exception as exception:
          raise exception
  
  async def health(req):
      return Response(status=200, text="Working")
  
  APP = web.Application(middlewares=[aiohttp_error_middleware])
  APP.router.add_post("/api/messages", messages)
  APP.router.add_get("/health", health)
  
  if __name__ == "__main__":
      web.run_app(APP)
  </code></pre>
  
  <p>And my bot code is:</p>
  
  <pre><code>class MyBot(ActivityHandler):
  
      def __init__(self, conversation_references):
          self.conversation_references = conversation_references
  
      async def on_message_activity(self, turn_context: TurnContext):
          print("Message received by bot adapter")
          # The next two lines also cause an unauthorized error. I commented them out to try and simplify
          # team_details = await teams.TeamsInfo.get_members(turn_context)
          # user = team_details[1].email
          user = "test@test.com"
          conversation = self.conversation_references.get_item(Key={"user": user})
          if "Item" in conversation:
              response = "You are already registered"
          else:
              conversation = TurnContext.get_conversation_reference(turn_context.activity)
              item = {"user": user, "conversation": conversation.as_dict()}
              self.conversation_references.put_item(Item=item)
              response = "You have been successfully registered!"
          return await turn_context.send_activity(response)
  </code></pre>
  
  <p>Update: When testing locally, I did not add the app id and password to the emulator. When I do, in debug mode I get the following error message: "An error occurred while POSTing "/INSPECT open" command to conversation xxxxxx|livechat: 400: The bot's Microsoft App ID or Microsoft App Password is incorrect."</p>
  
  <p>I am 100% sure the id and password are correct, though, as I've manually used the token endpoint from the registration page to get an access token with those credentials. It may be related to the fact that in the code and using the endpoint manually I can specify the Directory (tenant) ID, while I cannot do so using the emulator.</p>
  
  <p>Another strange point is that when the emulator returns that response it doesn't actually seem to be making a request to my local endpoint, so I'm not sure where the 400 response is even coming from.</p>