I downloaded the sample python Echo Bot from Microsoft's Github repo and set up the configuration using values from my Azure Bot (AppTenantId, AppId, AppPassword, SubscriptionId, etc.)
It works perfectly fine when using the local Bot Emulator program. It POSTs correctly and returns an echoed response.
However, I have the following problem after deploying the code to my Azure Web App Service. These are the steps I took:
- Deployed my project.zip file containing config.py, app.py, and any other related files.
- Tested that the
/api/messages/endpoint is active and responsive. - Attempted to communicate with my Web App Service deployment by using the Azure Bot
Test in Local Web Chatblade. - Confirmed the endpoint being accessed is HTTPS. All HTTP requests are forwarded to HTTPS otherwise.
My issue is that I'm only receiving GET requests. All requests from the Azure Bot Local Web Chat pane are being received as GET. If I access the endpoint using a browser, I also get a GET requests. I printed the HEADER and METHOD attributes of my request object and they confirm that I am receiving GET. I'm not sure why this is happening.
This is my app.py file. It calls the Echo bot module for all requests.
app.py
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
import sys
import traceback
from datetime import datetime
from botbuilder.core import (
TurnContext,
)
from botbuilder.integration.aiohttp import CloudAdapter, ConfigurationBotFrameworkAuthentication
from botbuilder.schema import Activity, ActivityTypes
from fastapi import FastAPI, Request
from fastapi.middleware.cors import CORSMiddleware
from bots import EchoBot
from config import DefaultConfig
CONFIG = DefaultConfig()
# Create adapter.
# See https://aka.ms/about-bot-adapter to learn more about how bots work.
ADAPTER = CloudAdapter(ConfigurationBotFrameworkAuthentication(CONFIG))
# Catch-all for errors.
async def on_error(context: TurnContext, error: Exception):
# This check writes out errors to console log .vs. app insights.
# NOTE: In production environment, you should consider logging this to Azure
# application insights.
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
# Create the Bot
BOT = EchoBot()
APP = FastAPI()
APP.add_middleware(
CORSMiddleware,
allow_origins=["*"], # or set specific domains
allow_methods=["*"],
allow_headers=["*"],
)
@APP.api_route("/api/messages", methods=["GET", "POST"])
#@APP.post()
async def messages(req: Request):
print("METHOD:", req.method)
print("HEADERS:", dict(req.headers))
if req.method == "GET":
return {"status": "ok"} # Health check
return await ADAPTER.process(req, BOT)
def init_func(*argv):
# uvicorn.run(APP, host="localhost", port=CONFIG.PORT)
return APP
if __name__ == "__main__":
try:
APP = init_func(None)
# APP = init_func(None)
# uvicorn.run(APP, host="localhost", port=CONFIG.PORT)
except Exception as error:
raise error
echo.py
# Copyright (c) Microsoft Corporation. All rights reserved.
# Licensed under the MIT License.
from botbuilder.core import ActivityHandler, MessageFactory, TurnContext
from botbuilder.schema import ChannelAccount
class EchoBot(ActivityHandler):
async def on_members_added_activity(
self, members_added: [ChannelAccount], turn_context: TurnContext
):
for member in members_added:
if member.id != turn_context.activity.recipient.id:
await turn_context.send_activity("Hello! How can I help you?")
async def on_message_activity(self, turn_context: TurnContext):
return await turn_context.send_activity(
MessageFactory.text(f"Echo: {turn_context.activity.text}")
)