microsoft-teams-botbuilder 2.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- microsoft_teams_botbuilder-2.0.0/.gitignore +51 -0
- microsoft_teams_botbuilder-2.0.0/PKG-INFO +33 -0
- microsoft_teams_botbuilder-2.0.0/README.md +17 -0
- microsoft_teams_botbuilder-2.0.0/pyproject.toml +41 -0
- microsoft_teams_botbuilder-2.0.0/src/microsoft_teams/botbuilder/__init__.py +12 -0
- microsoft_teams_botbuilder-2.0.0/src/microsoft_teams/botbuilder/botbuilder_plugin.py +131 -0
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.egg-info/
|
|
6
|
+
|
|
7
|
+
# Environments
|
|
8
|
+
.env
|
|
9
|
+
.venv
|
|
10
|
+
env/
|
|
11
|
+
venv/
|
|
12
|
+
ENV/
|
|
13
|
+
env.bak/
|
|
14
|
+
venv.bak/
|
|
15
|
+
|
|
16
|
+
# mypy
|
|
17
|
+
.mypy_cache/
|
|
18
|
+
.dmypy.json
|
|
19
|
+
dmypy.json
|
|
20
|
+
|
|
21
|
+
# pytest-cov
|
|
22
|
+
.coverage
|
|
23
|
+
.coverage.*
|
|
24
|
+
htmlcov/
|
|
25
|
+
coverage.xml
|
|
26
|
+
|
|
27
|
+
.copilot-instructions.md
|
|
28
|
+
|
|
29
|
+
# other
|
|
30
|
+
.DS_STORE
|
|
31
|
+
*.bak
|
|
32
|
+
*~
|
|
33
|
+
*.tmp
|
|
34
|
+
|
|
35
|
+
ref/
|
|
36
|
+
py.typed
|
|
37
|
+
|
|
38
|
+
.env.claude/
|
|
39
|
+
.claude/
|
|
40
|
+
tmpclaude-*-cwd
|
|
41
|
+
|
|
42
|
+
examples/**/.vscode/
|
|
43
|
+
examples/**/appPackage/
|
|
44
|
+
examples/**/infra/
|
|
45
|
+
examples/**/teamsapp*
|
|
46
|
+
examples/**/aad.manifest.json
|
|
47
|
+
|
|
48
|
+
# Node (from tab)
|
|
49
|
+
node_modules
|
|
50
|
+
dist/
|
|
51
|
+
build/
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: microsoft-teams-botbuilder
|
|
3
|
+
Version: 2.0.0
|
|
4
|
+
Summary: BotBuilder plugin for Microsoft Teams
|
|
5
|
+
Project-URL: Homepage, https://github.com/microsoft/teams.py/tree/main/packages/botbuilder/src/microsoft/teams/botbuilder
|
|
6
|
+
Author-email: Microsoft <TeamsAISDKFeedback@microsoft.com>
|
|
7
|
+
License-Expression: MIT
|
|
8
|
+
Keywords: agents,ai,bot,microsoft,teams
|
|
9
|
+
Requires-Python: <3.15,>=3.12
|
|
10
|
+
Requires-Dist: botbuilder-core>=4.14.0
|
|
11
|
+
Requires-Dist: botbuilder-integration-aiohttp>=4.17.0
|
|
12
|
+
Requires-Dist: microsoft-teams-api>=2.0.0
|
|
13
|
+
Requires-Dist: microsoft-teams-apps>=2.0.0
|
|
14
|
+
Requires-Dist: microsoft-teams-common>=2.0.0
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
|
|
17
|
+
# Microsoft Teams BotBuilder
|
|
18
|
+
|
|
19
|
+
<p>
|
|
20
|
+
<a href="https://pypi.org/project/microsoft-teams-botbuilder/" target="_blank">
|
|
21
|
+
<img src="https://img.shields.io/pypi/v/microsoft-teams-botbuilder" />
|
|
22
|
+
</a>
|
|
23
|
+
<a href="https://pypi.org/project/microsoft-teams-botbuilder" target="_blank">
|
|
24
|
+
<img src="https://img.shields.io/pypi/dw/microsoft-teams-botbuilder" />
|
|
25
|
+
</a>
|
|
26
|
+
</p>
|
|
27
|
+
|
|
28
|
+
A package used to make the `microsoft-teams-apps` package backwards compatible with legacy bots built using
|
|
29
|
+
`BotBuilder`.
|
|
30
|
+
|
|
31
|
+
<a href="https://microsoft.github.io/teams-sdk" target="_blank">
|
|
32
|
+
<img src="https://img.shields.io/badge/📖 Getting Started-blue?style=for-the-badge" />
|
|
33
|
+
</a>
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Microsoft Teams BotBuilder
|
|
2
|
+
|
|
3
|
+
<p>
|
|
4
|
+
<a href="https://pypi.org/project/microsoft-teams-botbuilder/" target="_blank">
|
|
5
|
+
<img src="https://img.shields.io/pypi/v/microsoft-teams-botbuilder" />
|
|
6
|
+
</a>
|
|
7
|
+
<a href="https://pypi.org/project/microsoft-teams-botbuilder" target="_blank">
|
|
8
|
+
<img src="https://img.shields.io/pypi/dw/microsoft-teams-botbuilder" />
|
|
9
|
+
</a>
|
|
10
|
+
</p>
|
|
11
|
+
|
|
12
|
+
A package used to make the `microsoft-teams-apps` package backwards compatible with legacy bots built using
|
|
13
|
+
`BotBuilder`.
|
|
14
|
+
|
|
15
|
+
<a href="https://microsoft.github.io/teams-sdk" target="_blank">
|
|
16
|
+
<img src="https://img.shields.io/badge/📖 Getting Started-blue?style=for-the-badge" />
|
|
17
|
+
</a>
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "microsoft-teams-botbuilder"
|
|
3
|
+
dynamic = ["version"]
|
|
4
|
+
description = "BotBuilder plugin for Microsoft Teams"
|
|
5
|
+
authors = [{ name = "Microsoft", email = "TeamsAISDKFeedback@microsoft.com" }]
|
|
6
|
+
readme = "README.md"
|
|
7
|
+
requires-python = ">=3.12,<3.15"
|
|
8
|
+
repository = "https://github.com/microsoft/teams.py"
|
|
9
|
+
keywords = ["microsoft", "teams", "ai", "bot", "agents"]
|
|
10
|
+
license = "MIT"
|
|
11
|
+
dependencies = [
|
|
12
|
+
"botbuilder-core>=4.14.0",
|
|
13
|
+
"botbuilder-integration-aiohttp>=4.17.0",
|
|
14
|
+
"microsoft-teams-apps",
|
|
15
|
+
"microsoft-teams-api",
|
|
16
|
+
"microsoft-teams-common"
|
|
17
|
+
]
|
|
18
|
+
|
|
19
|
+
[project.urls]
|
|
20
|
+
Homepage = "https://github.com/microsoft/teams.py/tree/main/packages/botbuilder/src/microsoft/teams/botbuilder"
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
[build-system]
|
|
24
|
+
requires = ["hatchling", "hatch-teams-build"]
|
|
25
|
+
build-backend = "hatchling.build"
|
|
26
|
+
|
|
27
|
+
[tool.hatch.version]
|
|
28
|
+
source = "teams-build"
|
|
29
|
+
|
|
30
|
+
[tool.hatch.metadata.hooks.teams-build]
|
|
31
|
+
|
|
32
|
+
[tool.hatch.build.targets.wheel]
|
|
33
|
+
packages = ["src/microsoft_teams", "src/microsoft"]
|
|
34
|
+
|
|
35
|
+
[tool.hatch.build.targets.sdist]
|
|
36
|
+
include = ["src"]
|
|
37
|
+
|
|
38
|
+
[tool.uv.sources]
|
|
39
|
+
microsoft-teams-apps = { workspace = true }
|
|
40
|
+
microsoft-teams-api = { workspace = true }
|
|
41
|
+
microsoft-teams-common = { workspace = true }
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
Licensed under the MIT License.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import logging
|
|
7
|
+
|
|
8
|
+
from .botbuilder_plugin import BotBuilderPlugin, BotBuilderPluginOptions
|
|
9
|
+
|
|
10
|
+
logging.getLogger(__name__).addHandler(logging.NullHandler())
|
|
11
|
+
|
|
12
|
+
__all__ = ["BotBuilderPlugin", "BotBuilderPluginOptions"]
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Copyright (c) Microsoft Corporation. All rights reserved.
|
|
3
|
+
Licensed under the MIT License.
|
|
4
|
+
"""
|
|
5
|
+
|
|
6
|
+
import importlib.metadata
|
|
7
|
+
import logging
|
|
8
|
+
from types import SimpleNamespace
|
|
9
|
+
from typing import Annotated, Optional, TypedDict, Unpack, cast
|
|
10
|
+
|
|
11
|
+
from microsoft_teams.api import Credentials
|
|
12
|
+
from microsoft_teams.apps import (
|
|
13
|
+
DependencyMetadata,
|
|
14
|
+
HttpServer,
|
|
15
|
+
Plugin,
|
|
16
|
+
PluginBase,
|
|
17
|
+
)
|
|
18
|
+
from microsoft_teams.apps.http import HttpRequest, HttpResponse
|
|
19
|
+
|
|
20
|
+
from botbuilder.core import (
|
|
21
|
+
ActivityHandler,
|
|
22
|
+
TurnContext,
|
|
23
|
+
)
|
|
24
|
+
from botbuilder.integration.aiohttp import (
|
|
25
|
+
CloudAdapter,
|
|
26
|
+
ConfigurationBotFrameworkAuthentication,
|
|
27
|
+
)
|
|
28
|
+
from botbuilder.schema import Activity
|
|
29
|
+
|
|
30
|
+
version = importlib.metadata.version("microsoft-teams-botbuilder")
|
|
31
|
+
|
|
32
|
+
logger = logging.getLogger(__name__)
|
|
33
|
+
|
|
34
|
+
# Constants for app types
|
|
35
|
+
SINGLE_TENANT = "singletenant"
|
|
36
|
+
MULTI_TENANT = "multitenant"
|
|
37
|
+
|
|
38
|
+
|
|
39
|
+
class BotBuilderPluginOptions(TypedDict, total=False):
|
|
40
|
+
"""Options for configuring the BotBuilder plugin."""
|
|
41
|
+
|
|
42
|
+
handler: ActivityHandler
|
|
43
|
+
adapter: CloudAdapter
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
@Plugin(name="botbuilder", version=version, description="BotBuilder plugin for Microsoft Bot Framework integration")
|
|
47
|
+
class BotBuilderPlugin(PluginBase):
|
|
48
|
+
"""
|
|
49
|
+
BotBuilder plugin that provides Microsoft Bot Framework integration.
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
# Dependency injections
|
|
53
|
+
credentials: Annotated[Optional[Credentials], DependencyMetadata(optional=True)]
|
|
54
|
+
http_server: Annotated[HttpServer, DependencyMetadata()]
|
|
55
|
+
|
|
56
|
+
def __init__(self, **options: Unpack[BotBuilderPluginOptions]):
|
|
57
|
+
"""
|
|
58
|
+
Initialize the BotBuilder plugin.
|
|
59
|
+
|
|
60
|
+
Args:
|
|
61
|
+
options: Configuration options for the plugin
|
|
62
|
+
"""
|
|
63
|
+
super().__init__()
|
|
64
|
+
self.handler: Optional[ActivityHandler] = options.get("handler")
|
|
65
|
+
self.adapter: Optional[CloudAdapter] = options.get("adapter")
|
|
66
|
+
|
|
67
|
+
async def on_init(self) -> None:
|
|
68
|
+
"""Initialize the plugin when the app starts."""
|
|
69
|
+
if not self.adapter:
|
|
70
|
+
# Extract credentials for Bot Framework authentication
|
|
71
|
+
client_id: Optional[str] = None
|
|
72
|
+
client_secret: Optional[str] = None
|
|
73
|
+
tenant_id: Optional[str] = None
|
|
74
|
+
|
|
75
|
+
if self.credentials:
|
|
76
|
+
client_id = getattr(self.credentials, "client_id", None)
|
|
77
|
+
client_secret = getattr(self.credentials, "client_secret", None)
|
|
78
|
+
tenant_id = getattr(self.credentials, "tenant_id", None)
|
|
79
|
+
|
|
80
|
+
config = SimpleNamespace(
|
|
81
|
+
APP_TYPE=SINGLE_TENANT if tenant_id else MULTI_TENANT,
|
|
82
|
+
APP_ID=client_id,
|
|
83
|
+
APP_PASSWORD=client_secret,
|
|
84
|
+
APP_TENANTID=tenant_id,
|
|
85
|
+
)
|
|
86
|
+
|
|
87
|
+
bot_framework_auth = ConfigurationBotFrameworkAuthentication(configuration=config)
|
|
88
|
+
self.adapter = CloudAdapter(bot_framework_auth)
|
|
89
|
+
|
|
90
|
+
logger.debug("BotBuilder plugin initialized successfully")
|
|
91
|
+
|
|
92
|
+
# Register the messaging endpoint route via adapter (bypasses HttpServer's default route)
|
|
93
|
+
self.http_server.adapter.register_route("POST", self.http_server.messaging_endpoint, self._handle_activity)
|
|
94
|
+
|
|
95
|
+
async def _handle_activity(self, request: HttpRequest) -> HttpResponse:
|
|
96
|
+
"""
|
|
97
|
+
Handler for the messaging endpoint.
|
|
98
|
+
|
|
99
|
+
Runs Bot Framework CloudAdapter auth + handler first,
|
|
100
|
+
then routes through HttpServer.handle_request for SDK-level JWT validation and pipeline.
|
|
101
|
+
"""
|
|
102
|
+
if not self.adapter:
|
|
103
|
+
raise RuntimeError("plugin not registered")
|
|
104
|
+
|
|
105
|
+
body = request["body"]
|
|
106
|
+
headers = request["headers"]
|
|
107
|
+
|
|
108
|
+
try:
|
|
109
|
+
# Parse activity from body
|
|
110
|
+
activity_bf = cast(Activity, Activity().deserialize(body))
|
|
111
|
+
|
|
112
|
+
if not activity_bf.type:
|
|
113
|
+
return HttpResponse(status=400, body={"detail": "Missing activity type"})
|
|
114
|
+
|
|
115
|
+
async def logic(turn_context: TurnContext) -> None:
|
|
116
|
+
if not turn_context.activity.id:
|
|
117
|
+
return
|
|
118
|
+
# Handle activity with botframework handler
|
|
119
|
+
if self.handler:
|
|
120
|
+
await self.handler.on_turn(turn_context)
|
|
121
|
+
|
|
122
|
+
# Grab the auth header from the inbound request
|
|
123
|
+
auth_header = headers.get("authorization") or headers.get("Authorization") or ""
|
|
124
|
+
await self.adapter.process_activity(auth_header, activity_bf, logic)
|
|
125
|
+
|
|
126
|
+
# Route through HttpServer for SDK auth + Teams pipeline
|
|
127
|
+
return await self.http_server.handle_request(request)
|
|
128
|
+
|
|
129
|
+
except Exception as err:
|
|
130
|
+
logger.error(f"Error processing activity: {err}", exc_info=True)
|
|
131
|
+
return HttpResponse(status=500, body={"detail": str(err)})
|