'Teams Invoke_response being rejected by Teams?
I have a teams app running on a standalone server with an AzureBot setup for message extensions on the app. I've got a class implementing message handling extending TeamsActivityHandler which all seems to be working. The issue is when I come to respond with an InvokeResponse. I place this into an activity with the right type, I get no errors but Teams seems to be rejecting the message as it doesn't give me an ID for the POST request containing the response. Is there something I'm missing when creating the Activity?
async def handle(turn_context):
invoke_response = await message_handler.on_invoke_activity(turn_context)
# invoke_response is an instance of botbuilder.schema._models_py3.InvokeResponse
result = await turn_context.send_activity(Activity(type=ActivityTypes.invoke_response, value=invoke_response))
self.logger.info(result)
Solution 1:[1]
I was totally unaware that message extensions followed a standard request response model rather than a request request model as the bot does. Here is a full working example using flask - ms example here :
import asyncio
import json
from botbuilder.core.teams import TeamsActivityHandler
from botbuilder.schema import Activity, CardAction, HeroCard
from botbuilder.core import (
BotFrameworkAdapter,
BotFrameworkAdapterSettings, TurnContext, CardFactory, MessageFactory,
)
from botbuilder.schema.teams import (
MessagingExtensionAttachment,
MessagingExtensionQuery,
MessagingExtensionResult,
MessagingExtensionResponse,
)
from flask import request, Response
from flask_restful import Resource
class ActivityHandler(TeamsActivityHandler):
async def on_teams_messaging_extension_query(self, turn_context: TurnContext, query: MessagingExtensionQuery):
search_query = str(query.parameters[0].value).strip()
if search_query == '':
await turn_context.send_activity(
MessageFactory.text('You cannot enter a blank string for the search')
)
return
# TODO: Implement a search returning objects
search_results = self._get_search_results(search_query)
attachments = []
for obj in search_results:
hero_card = HeroCard(
title=obj['name'], tap=CardAction(type='invoke', value=obj)
)
attachment = MessagingExtensionAttachment(
content_type=CardFactory.content_types.hero_card,
content=HeroCard(title=obj['name']),
preview=CardFactory.hero_card(hero_card),
)
attachments.append(attachment)
return MessagingExtensionResponse(
compose_extension=MessagingExtensionResult(
type='result', attachment_layout='list', attachments=attachments
)
)
class TeamsMessageExtensionsBot(Resource):
def __init__(self):
self.event_loop = asyncio.new_event_loop()
asyncio.set_event_loop(self.event_loop)
app_config = BotFrameworkAdapterSettings(app_id='YOUR-BOT-ID',
app_password='YOUR-BOT-PASSWORD')
self.bot_framework_adaptor = BotFrameworkAdapter(app_config)
def post(self):
message_handler = ActivityHandler()
if 'application/json' in request.headers['Content-Type']:
body = request.json
else:
return Response(status=415)
activity = Activity().deserialize(body)
auth_header = (
request.headers['Authorization'] if 'Authorization' in request.headers else ''
)
try:
task = self.event_loop.create_task(
self.bot_framework_adaptor.process_activity(activity, auth_header, message_handler.on_turn)
)
invoke_response = self.event_loop.run_until_complete(asyncio.gather(task))[0]
if invoke_response:
self.logger.info(invoke_response.body)
return Response(response=json.dumps(invoke_response.body),
status=invoke_response.status, mimetype='application/json')
return Response(status=201)
except Exception as exception:
raise exception
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | James MV |