8000 add task module fetch scenario (#508) · TheCompuGuru/botbuilder-python@ff83d09 · GitHub
[go: up one dir, main page]

Skip to content

Commit ff83d09

Browse files
author
Eric Dahlvang
authored
add task module fetch scenario (microsoft#508)
1 parent af94017 commit ff83d09

File tree

8 files changed

+248
-0
lines changed

8 files changed

+248
-0
lines changed

scenarios/task-module/app.py

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT License.
3+
4+
import json
5+
import sys
6+
from datetime import datetime
7+
8+
from aiohttp import web
9+
from aiohttp.web import Request, Response, json_response
10+
from botbuilder.core import (
11+
BotFrameworkAdapterSettings,
12+
TurnContext,
13+
BotFrameworkAdapter,
14+
)
15+
from botbuilder.schema import Activity, ActivityTypes
16+
from bots import TaskModuleBot
17+
from config import DefaultConfig
18+
19+
CONFIG = DefaultConfig()
20+
21+
# Create adapter.
22+
# See https://aka.ms/about-bot-adapter to learn more about how bots work.
23+
SETTINGS = BotFrameworkAdapterSettings(CONFIG.APP_ID, CONFIG.APP_PASSWORD)
24+
ADAPTER = BotFrameworkAdapter(SETTINGS)
25+
26+
27+
# Catch-all for errors.
28+
async def on_error(context: TurnContext, error: Exception):
29+
# This check writes out errors to console log .vs. app insights.
30+
# NOTE: In production environment, you should consider logging this to Azure
31+
# application insights.
32+
print(f"\n [on_turn_error] unhandled error: {error}", file=sys.stderr)
33+
34+
# Send a message to the user
35+
await context.send_activity("The bot encountered an error or bug.")
36+
await context.send_activity(
37+
"To continue to run this bot, please fix the bot source code."
38+
)
39+
# Send a trace activity if we're talking to the Bot Framework Emulator
40+
if context.activity.channel_id == "emulator":
41+
# Create a trace activity that contains the error object
42+
trace_activity = Activity(
43+
label="TurnError",
44+
name="on_turn_error Trace",
45+
timestamp=datetime.utcnow(),
46+
type=ActivityTypes.trace,
47+
value=f"{error}",
48+
value_type="https://www.botframework.com/schemas/error",
49+
)
50+
# Send a trace activity, which will be displayed in Bot Framework Emulator
51+
await context.send_activity(trace_activity)
52+
53+
54+
ADAPTER.on_turn_error = on_error
55+
56+
# Create the Bot
57+
BOT = TaskModuleBot()
58+
59+
60+
# Listen for incoming requests on /api/messages
61+
async def messages(req: Request) -> Response:
62+
# Main bot message handler.
63+
if "application/json" in req.headers["Content-Type"]:
64+
body = await req.json()
65+
else:
66+
return Response(status=415)
67+
68+
activity = Activity().deserialize(body)
69+
auth_header = req.headers["Authorization"] if "Authorization" in req.headers else ""
70+
71+
try:
72+
invoke_response = await ADAPTER.process_activity(
73+
activity, auth_header, BOT.on_turn
74+
)
75+
if invoke_response:
76+
return json_response(
77+
data=invoke_response.body, status=invoke_response.status
78+
)
79+
return Response(status=201)
80+
except PermissionError:
81+
return Response(status=401)
82+
except Exception:
83+
return Response(status=500)
84+
85+
86+
APP = web.Application()
87+
APP.router.add_post("/api/messages", messages)
88+
89+
if __name__ == "__main__":
90+
try:
91+
web.run_app(APP, host="localhost", port=CONFIG.PORT)
92+
except Exception as error:
93+
raise error
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT License.
3+
4+
from .teams_task_module_bot import TaskModuleBot
5+
6+
__all__ = ["TaskModuleBot"]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
# Copyright (c) Microsoft Corp. All rights reserved.
2+
# Licensed under the MIT License.
3+
4+
import json
5+
from typing import List
6+
import random
7+
from botbuilder.core import CardFactory, MessageFactory, TurnContext
8+
from botbuilder.schema import (
9+
ChannelAccount,
10+
HeroCard,
11+
CardAction,
12+
CardImage,
13+
Attachment,
14+
)
15+
from botbuilder.schema.teams import (
16+
MessagingExtensionAction,
17+
MessagingExtensionActionResponse,
18+
MessagingExtensionAttachment,
19+
MessagingExtensionResult,
20+
TaskModuleResponse,
21+
TaskModuleResponseBase,
22+
TaskModuleContinueResponse,
23+
TaskModuleMessageResponse,
24+
TaskModuleTaskInfo,
25+
TaskModuleRequest,
26+
)
27+
from botbuilder.core.teams import TeamsActivityHandler, TeamsInfo
28+
from botbuilder.azure import CosmosDbPartitionedStorage
29+
from botbuilder.core.teams.teams_helper import deserializer_helper
30+
31+
class TaskModuleBot(TeamsActivityHandler):
32+
async def on_message_activity(self, turn_context: TurnContext):
33+
reply = MessageFactory.attachment(self._get_task_module_hero_card())
34+
await turn_context.send_activity(reply)
35+
36+
def _get_task_module_hero_card(self) -> Attachment:
37+
task_module_action = CardAction(
38+
type="invoke",
39+
title="Adaptive Card",
40+
value={"type": "task/fetch", "data": "adaptivecard"},
41+
)
42+
card = HeroCard(
43+
title="Task Module Invocation from Hero Card",
44+
subtitle="This is a hero card with a Task Module Action button. Click the button to show an Adaptive Card within a Task Module.",
45+
buttons=[task_module_action],
46+
)
47+
return CardFactory.hero_card(card)
48+
49+
async def on_teams_task_module_fetch(
50+
self, turn_context: TurnContext, task_module_request: TaskModuleRequest
51+
) -> TaskModuleResponse:
52+
reply = MessageFactory.text(
53+
f"OnTeamsTaskModuleFetchAsync TaskModuleRequest: {json.dumps(task_module_request.data)}"
54+
)
55+
await turn_context.send_activity(reply)
56+
57+
# base_response = TaskModuleResponseBase(type='continue')
58+
card = CardFactory.adaptive_card(
59+
{
60+
"version": "1.0.0",
61+
"type": "AdaptiveCard",
62+
"body": [
63+
{"type": "TextBlock", "text": "Enter Text Here",},
64+
{
65+
"type": "Input.Text",
66+
"id": "usertext",
67+
"placeholder": "add some text and submit",
68+
"IsMultiline": "true",
69+
},
70+
],
71+
"actions": [{"type": "Action.Submit", "title": "Submit",}],
72+
}
73+
)
74+
75+
task_info = TaskModuleTaskInfo(
76+
card=card, title="Adaptive Card: Inputs", height=200, width=400
77+
)
78+
continue_response = TaskModuleContinueResponse(type="continue", value=task_info)
79+
return TaskModuleResponse(task=continue_response)
80+
81+
async def on_teams_task_module_submit(
82+
self, turn_context: TurnContext, task_module_request: TaskModuleRequest
83+
) -> TaskModuleResponse:
84+
reply = MessageFactory.text(
85+
f"on_teams_messaging_extension_submit_action_activity MessagingExtensionAction: {json.dumps(task_module_request.data)}"
86+
)
87+
await turn_context.send_activity(reply)
88+
89+
message_response = TaskModuleMessageResponse(type="message", value="Thanks!")
90+
return TaskModuleResponse(task=message_response)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
#!/usr/bin/env python3
2+
# Copyright (c) Microsoft Corporation. All rights reserved.
3+
# Licensed under the MIT License.
4+
5+
import os
6+
7+
8+
class DefaultConfig:
9+
""" Bot Configuration """
10+
11+
PORT = 3978
12+
APP_ID = os.environ.get("MicrosoftAppId", "")
13+
APP_PASSWORD = os.environ.get(
14+
"MicrosoftAppPassword", ""
15+
)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
botbuilder-core>=4.4.0b1
2+
flask>=1.0.3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
{
2+
"$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.5/MicrosoftTeams.schema.json",
3+
"manifestVersion": "1.5",
4+
"version": "1.0.0",
5+
"id": "<<YOUR-MICROSOFT-APP-ID>>",
6+
"packageName": "com.microsoft.teams.samples",
7+
"developer": {
8+
"name": "Microsoft",
9+
"websiteUrl": "https://example.azurewebsites.net",
10+
"privacyUrl": "https://example.azurewebsites.net/privacy",
11+
"termsOfUseUrl": "https://example.azurewebsites.net/termsofuse"
12+
},
13+
"icons": {
14+
"color": "color.png",
15+
"outline": "outline.png"
16+
},
17+
"name": {
18+
"short": "Task Module",
19+
"full": "Simple Task Module"
20+
},
21+
"description": {
22+
"short": "Test Task Module Scenario",
23+
"full": "Simple Task Module Scenario Test"
24+
},
25+
"accentColor": "#FFFFFF",
26+
"bots": [
27+
{
28+
"botId": "<<YOUR-MICROSOFT-APP-ID>>",
29+
"scopes": [
30+
"personal",
31+
"team",
32+
"groupchat"
33+
],
34+
"supportsFiles": false,
35+
"isNotificationOnly": false
36+
}
37+
],
38+
"permissions": [
39+
"identity",
40+
"messageTeamMembers"
41+
]
42+
}