mirror of
https://github.com/HKUDS/nanobot.git
synced 2026-04-29 22:35:52 +00:00
fix(msteams): harden availability check and migrate docs to README
- Check both jwt and cryptography in MSTEAMS_AVAILABLE guard so partial installs fail early with a clear message instead of at runtime - Add aclose() to test FakeHttpClient so stop() won't crash - Move MSTEAMS.md into README.md following the same details/summary pattern used by every other channel - Note in README that validateInboundAuth defaults to false
This commit is contained in:
parent
b48f497f8d
commit
43bd8aac8d
51
README.md
51
README.md
@ -276,6 +276,7 @@ Connect nanobot to your favorite chat platform. Want to build your own? See the
|
|||||||
| **Email** | IMAP/SMTP credentials |
|
| **Email** | IMAP/SMTP credentials |
|
||||||
| **QQ** | App ID + App Secret |
|
| **QQ** | App ID + App Secret |
|
||||||
| **Wecom** | Bot ID + Bot Secret |
|
| **Wecom** | Bot ID + Bot Secret |
|
||||||
|
| **Microsoft Teams** | App ID + App Password + public HTTPS endpoint |
|
||||||
| **Mochat** | Claw token (auto-setup available) |
|
| **Mochat** | Claw token (auto-setup available) |
|
||||||
|
|
||||||
<details>
|
<details>
|
||||||
@ -861,6 +862,56 @@ nanobot gateway
|
|||||||
|
|
||||||
</details>
|
</details>
|
||||||
|
|
||||||
|
<details>
|
||||||
|
<summary><b>Microsoft Teams</b> (MVP — DM only)</summary>
|
||||||
|
|
||||||
|
> Direct-message text in/out, tenant-aware OAuth, conversation reference persistence.
|
||||||
|
> Uses a public HTTPS webhook — no WebSocket; you need a tunnel or reverse proxy.
|
||||||
|
|
||||||
|
**1. Install the optional dependency**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pip install nanobot-ai[msteams]
|
||||||
|
```
|
||||||
|
|
||||||
|
**2. Create a Teams / Azure bot app registration**
|
||||||
|
|
||||||
|
Create or reuse a Microsoft Teams / Azure bot app registration. Set the bot messaging endpoint to a public HTTPS URL ending in `/api/messages`.
|
||||||
|
|
||||||
|
**3. Configure**
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"channels": {
|
||||||
|
"msteams": {
|
||||||
|
"enabled": true,
|
||||||
|
"appId": "YOUR_APP_ID",
|
||||||
|
"appPassword": "YOUR_APP_SECRET",
|
||||||
|
"tenantId": "YOUR_TENANT_ID",
|
||||||
|
"host": "0.0.0.0",
|
||||||
|
"port": 3978,
|
||||||
|
"path": "/api/messages",
|
||||||
|
"allowFrom": ["*"],
|
||||||
|
"replyInThread": true,
|
||||||
|
"mentionOnlyResponse": "Hi — what can I help with?",
|
||||||
|
"validateInboundAuth": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
> - `replyInThread: true` replies to the triggering Teams activity when a stored `activity_id` is available.
|
||||||
|
> - `mentionOnlyResponse` controls what Nanobot receives when a user sends only a bot mention (`<at>Nanobot</at>`). Set to `""` to ignore mention-only messages.
|
||||||
|
> - `validateInboundAuth: true` (recommended for production) enables inbound Bot Framework bearer-token validation (signature, issuer, audience, lifetime, `serviceUrl`). **Default is `false`** — set explicitly to `true` for production deployments.
|
||||||
|
|
||||||
|
**4. Run**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
nanobot gateway
|
||||||
|
```
|
||||||
|
|
||||||
|
</details>
|
||||||
|
|
||||||
## 🌐 Agent Social Network
|
## 🌐 Agent Social Network
|
||||||
|
|
||||||
🐈 nanobot is capable of linking to the agent social network (agent community). **Just send one message and your nanobot joins automatically!**
|
🐈 nanobot is capable of linking to the agent social network (agent community). **Just send one message and your nanobot joins automatically!**
|
||||||
|
|||||||
@ -1,68 +0,0 @@
|
|||||||
# Microsoft Teams (MVP)
|
|
||||||
|
|
||||||
This repository includes a built-in `msteams` channel MVP for Microsoft Teams direct messages.
|
|
||||||
|
|
||||||
## Current scope
|
|
||||||
|
|
||||||
- Direct-message text in/out
|
|
||||||
- Tenant-aware OAuth token acquisition
|
|
||||||
- Conversation reference persistence for replies
|
|
||||||
- Public HTTPS webhook support through a tunnel or reverse proxy
|
|
||||||
|
|
||||||
## Not yet included
|
|
||||||
|
|
||||||
- Group/channel handling
|
|
||||||
- Attachments and cards
|
|
||||||
- Polls
|
|
||||||
- Richer Teams activity handling
|
|
||||||
|
|
||||||
## Example config
|
|
||||||
|
|
||||||
```json
|
|
||||||
{
|
|
||||||
"channels": {
|
|
||||||
"msteams": {
|
|
||||||
"enabled": true,
|
|
||||||
"appId": "YOUR_APP_ID",
|
|
||||||
"appPassword": "YOUR_APP_SECRET",
|
|
||||||
"tenantId": "YOUR_TENANT_ID",
|
|
||||||
"host": "0.0.0.0",
|
|
||||||
"port": 3978,
|
|
||||||
"path": "/api/messages",
|
|
||||||
"allowFrom": ["*"],
|
|
||||||
"replyInThread": true,
|
|
||||||
"mentionOnlyResponse": "Hi — what can I help with?",
|
|
||||||
"validateInboundAuth": false,
|
|
||||||
"restartNotifyEnabled": false,
|
|
||||||
"restartNotifyPreMessage": "Nanobot agent initiated a gateway restart. I will message again when the gateway is back online.",
|
|
||||||
"restartNotifyPostMessage": "Nanobot gateway is back online."
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
|
|
||||||
## Behavior notes
|
|
||||||
|
|
||||||
- `replyInThread: true` replies to the triggering Teams activity when a stored `activity_id` is available.
|
|
||||||
- `replyInThread: false` posts replies as normal conversation messages.
|
|
||||||
- If `replyInThread` is enabled but no `activity_id` is stored, Nanobot falls back to a normal conversation message.
|
|
||||||
- `mentionOnlyResponse` controls what Nanobot receives when a user sends only a bot mention such as `<at>Nanobot</at>`.
|
|
||||||
- Set `mentionOnlyResponse` to an empty string to ignore mention-only messages.
|
|
||||||
- `validateInboundAuth: true` enables inbound Bot Framework bearer-token validation.
|
|
||||||
- `validateInboundAuth: false` leaves inbound auth unenforced, which is safer while first validating a new relay, tunnel, or proxy path.
|
|
||||||
- When enabled, Nanobot validates the inbound bearer token signature, issuer, audience, token lifetime, and `serviceUrl` claim when present.
|
|
||||||
- `restartNotifyEnabled: true` enables optional Teams restart-notification configuration for external wrapper-script driven restarts.
|
|
||||||
- `restartNotifyPreMessage` and `restartNotifyPostMessage` control the before/after announcement text used by that external wrapper.
|
|
||||||
|
|
||||||
## Setup notes
|
|
||||||
|
|
||||||
1. Create or reuse a Microsoft Teams / Azure bot app registration.
|
|
||||||
2. Set the bot messaging endpoint to a public HTTPS URL ending in `/api/messages`.
|
|
||||||
3. Forward that public endpoint to `http://localhost:3978/api/messages`.
|
|
||||||
4. Start Nanobot with:
|
|
||||||
|
|
||||||
```bash
|
|
||||||
nanobot gateway
|
|
||||||
```
|
|
||||||
|
|
||||||
5. Optional: if you use an external restart wrapper (for example a script that stops and restarts the gateway), you can enable Teams restart announcements with `restartNotifyEnabled: true` and have the wrapper send `restartNotifyPreMessage` before restart and `restartNotifyPostMessage` after the gateway is back online.
|
|
||||||
@ -32,7 +32,10 @@ from nanobot.channels.base import BaseChannel
|
|||||||
from nanobot.config.paths import get_workspace_path
|
from nanobot.config.paths import get_workspace_path
|
||||||
from nanobot.config.schema import Base
|
from nanobot.config.schema import Base
|
||||||
|
|
||||||
MSTEAMS_AVAILABLE = importlib.util.find_spec("jwt") is not None
|
MSTEAMS_AVAILABLE = (
|
||||||
|
importlib.util.find_spec("jwt") is not None
|
||||||
|
and importlib.util.find_spec("cryptography") is not None
|
||||||
|
)
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
import jwt
|
import jwt
|
||||||
|
|||||||
@ -52,6 +52,9 @@ class FakeHttpClient:
|
|||||||
self.calls.append((url, kwargs))
|
self.calls.append((url, kwargs))
|
||||||
return FakeResponse(self.payload, should_raise=self.should_raise)
|
return FakeResponse(self.payload, should_raise=self.should_raise)
|
||||||
|
|
||||||
|
async def aclose(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def make_channel(tmp_path, monkeypatch):
|
def make_channel(tmp_path, monkeypatch):
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user