|
|
|
|
@@ -8,9 +8,9 @@ read_when:
|
|
|
|
|
> "Abandon all hope, ye who enter here."
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Updated: 2026-01-16
|
|
|
|
|
Updated: 2026-01-21
|
|
|
|
|
|
|
|
|
|
Status: text + DM attachments are supported; channel/group attachments require Microsoft Graph permissions. Polls are sent via Adaptive Cards.
|
|
|
|
|
Status: text + DM attachments are supported; channel/group file sending requires `sharePointSiteId` + Graph permissions (see [Sending files in group chats](#sending-files-in-group-chats)). Polls are sent via Adaptive Cards.
|
|
|
|
|
|
|
|
|
|
## Plugin required
|
|
|
|
|
Microsoft Teams ships as a plugin and is not bundled with the core install.
|
|
|
|
|
@@ -403,7 +403,7 @@ Clawdbot handles this by returning quickly and sending replies proactively, but
|
|
|
|
|
Teams markdown is more limited than Slack or Discord:
|
|
|
|
|
- Basic formatting works: **bold**, *italic*, `code`, links
|
|
|
|
|
- Complex markdown (tables, nested lists) may not render correctly
|
|
|
|
|
- Adaptive Cards are used for polls; other card types are not yet supported
|
|
|
|
|
- Adaptive Cards are supported for polls and arbitrary card sends (see below)
|
|
|
|
|
|
|
|
|
|
## Configuration
|
|
|
|
|
Key settings (see `/gateway/configuration` for shared channel patterns):
|
|
|
|
|
@@ -422,6 +422,7 @@ Key settings (see `/gateway/configuration` for shared channel patterns):
|
|
|
|
|
- `channels.msteams.teams.<teamId>.requireMention`: per-team override.
|
|
|
|
|
- `channels.msteams.teams.<teamId>.channels.<conversationId>.replyStyle`: per-channel override.
|
|
|
|
|
- `channels.msteams.teams.<teamId>.channels.<conversationId>.requireMention`: per-channel override.
|
|
|
|
|
- `channels.msteams.sharePointSiteId`: SharePoint site ID for file uploads in group chats/channels (see [Sending files in group chats](#sending-files-in-group-chats)).
|
|
|
|
|
|
|
|
|
|
## Routing & Sessions
|
|
|
|
|
- Session keys follow the standard agent format (see [/concepts/session](/concepts/session)):
|
|
|
|
|
@@ -471,6 +472,75 @@ Teams recently introduced two channel UI styles over the same underlying data mo
|
|
|
|
|
Without Graph permissions, channel messages with images will be received as text-only (the image content is not accessible to the bot).
|
|
|
|
|
By default, Clawdbot only downloads media from Microsoft/Teams hostnames. Override with `channels.msteams.mediaAllowHosts` (use `["*"]` to allow any host).
|
|
|
|
|
|
|
|
|
|
## Sending files in group chats
|
|
|
|
|
|
|
|
|
|
Bots can send files in DMs using the FileConsentCard flow (built-in). However, **sending files in group chats/channels** requires additional setup:
|
|
|
|
|
|
|
|
|
|
| Context | How files are sent | Setup needed |
|
|
|
|
|
|---------|-------------------|--------------|
|
|
|
|
|
| **DMs** | FileConsentCard → user accepts → bot uploads | Works out of the box |
|
|
|
|
|
| **Group chats/channels** | Upload to SharePoint → share link | Requires `sharePointSiteId` + Graph permissions |
|
|
|
|
|
| **Images (any context)** | Base64-encoded inline | Works out of the box |
|
|
|
|
|
|
|
|
|
|
### Why group chats need SharePoint
|
|
|
|
|
|
|
|
|
|
Bots don't have a personal OneDrive drive (the `/me/drive` Graph API endpoint doesn't work for application identities). To send files in group chats/channels, the bot uploads to a **SharePoint site** and creates a sharing link.
|
|
|
|
|
|
|
|
|
|
### Setup
|
|
|
|
|
|
|
|
|
|
1. **Add Graph API permissions** in Entra ID (Azure AD) → App Registration:
|
|
|
|
|
- `Sites.ReadWrite.All` (Application) - upload files to SharePoint
|
|
|
|
|
- `Chat.Read.All` (Application) - optional, enables per-user sharing links
|
|
|
|
|
|
|
|
|
|
2. **Grant admin consent** for the tenant.
|
|
|
|
|
|
|
|
|
|
3. **Get your SharePoint site ID:**
|
|
|
|
|
```bash
|
|
|
|
|
# Via Graph Explorer or curl with a valid token:
|
|
|
|
|
curl -H "Authorization: Bearer $TOKEN" \
|
|
|
|
|
"https://graph.microsoft.com/v1.0/sites/{hostname}:/{site-path}"
|
|
|
|
|
|
|
|
|
|
# Example: for a site at "contoso.sharepoint.com/sites/BotFiles"
|
|
|
|
|
curl -H "Authorization: Bearer $TOKEN" \
|
|
|
|
|
"https://graph.microsoft.com/v1.0/sites/contoso.sharepoint.com:/sites/BotFiles"
|
|
|
|
|
|
|
|
|
|
# Response includes: "id": "contoso.sharepoint.com,guid1,guid2"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
4. **Configure Clawdbot:**
|
|
|
|
|
```json5
|
|
|
|
|
{
|
|
|
|
|
channels: {
|
|
|
|
|
msteams: {
|
|
|
|
|
// ... other config ...
|
|
|
|
|
sharePointSiteId: "contoso.sharepoint.com,guid1,guid2"
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Sharing behavior
|
|
|
|
|
|
|
|
|
|
| Permission | Sharing behavior |
|
|
|
|
|
|------------|------------------|
|
|
|
|
|
| `Sites.ReadWrite.All` only | Organization-wide sharing link (anyone in org can access) |
|
|
|
|
|
| `Sites.ReadWrite.All` + `Chat.Read.All` | Per-user sharing link (only chat members can access) |
|
|
|
|
|
|
|
|
|
|
Per-user sharing is more secure as only the chat participants can access the file. If `Chat.Read.All` permission is missing, the bot falls back to organization-wide sharing.
|
|
|
|
|
|
|
|
|
|
### Fallback behavior
|
|
|
|
|
|
|
|
|
|
| Scenario | Result |
|
|
|
|
|
|----------|--------|
|
|
|
|
|
| Group chat + file + `sharePointSiteId` configured | Upload to SharePoint, send sharing link |
|
|
|
|
|
| Group chat + file + no `sharePointSiteId` | Attempt OneDrive upload (may fail), send text only |
|
|
|
|
|
| Personal chat + file | FileConsentCard flow (works without SharePoint) |
|
|
|
|
|
| Any context + image | Base64-encoded inline (works without SharePoint) |
|
|
|
|
|
|
|
|
|
|
### Files stored location
|
|
|
|
|
|
|
|
|
|
Uploaded files are stored in a `/ClawdbotShared/` folder in the configured SharePoint site's default document library.
|
|
|
|
|
|
|
|
|
|
## Polls (Adaptive Cards)
|
|
|
|
|
Clawdbot sends Teams polls as Adaptive Cards (there is no native Teams poll API).
|
|
|
|
|
|
|
|
|
|
@@ -479,6 +549,82 @@ Clawdbot sends Teams polls as Adaptive Cards (there is no native Teams poll API)
|
|
|
|
|
- The gateway must stay online to record votes.
|
|
|
|
|
- Polls do not auto-post result summaries yet (inspect the store file if needed).
|
|
|
|
|
|
|
|
|
|
## Adaptive Cards (arbitrary)
|
|
|
|
|
Send any Adaptive Card JSON to Teams users or conversations using the `message` tool or CLI.
|
|
|
|
|
|
|
|
|
|
The `card` parameter accepts an Adaptive Card JSON object. When `card` is provided, the message text is optional.
|
|
|
|
|
|
|
|
|
|
**Agent tool:**
|
|
|
|
|
```json
|
|
|
|
|
{
|
|
|
|
|
"action": "send",
|
|
|
|
|
"channel": "msteams",
|
|
|
|
|
"target": "user:<id>",
|
|
|
|
|
"card": {
|
|
|
|
|
"type": "AdaptiveCard",
|
|
|
|
|
"version": "1.5",
|
|
|
|
|
"body": [{"type": "TextBlock", "text": "Hello!"}]
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**CLI:**
|
|
|
|
|
```bash
|
|
|
|
|
clawdbot message send --channel msteams \
|
|
|
|
|
--target "conversation:19:abc...@thread.tacv2" \
|
|
|
|
|
--card '{"type":"AdaptiveCard","version":"1.5","body":[{"type":"TextBlock","text":"Hello!"}]}'
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
See [Adaptive Cards documentation](https://adaptivecards.io/) for card schema and examples. For target format details, see [Target formats](#target-formats) below.
|
|
|
|
|
|
|
|
|
|
## Target formats
|
|
|
|
|
|
|
|
|
|
MSTeams targets use prefixes to distinguish between users and conversations:
|
|
|
|
|
|
|
|
|
|
| Target type | Format | Example |
|
|
|
|
|
|-------------|--------|---------|
|
|
|
|
|
| User (by ID) | `user:<aad-object-id>` | `user:40a1a0ed-4ff2-4164-a219-55518990c197` |
|
|
|
|
|
| User (by name) | `user:<display-name>` | `user:John Smith` (requires Graph API) |
|
|
|
|
|
| Group/channel | `conversation:<conversation-id>` | `conversation:19:abc123...@thread.tacv2` |
|
|
|
|
|
| Group/channel (raw) | `<conversation-id>` | `19:abc123...@thread.tacv2` (if contains `@thread`) |
|
|
|
|
|
|
|
|
|
|
**CLI examples:**
|
|
|
|
|
```bash
|
|
|
|
|
# Send to a user by ID
|
|
|
|
|
clawdbot message send --channel msteams --target "user:40a1a0ed-..." --message "Hello"
|
|
|
|
|
|
|
|
|
|
# Send to a user by display name (triggers Graph API lookup)
|
|
|
|
|
clawdbot message send --channel msteams --target "user:John Smith" --message "Hello"
|
|
|
|
|
|
|
|
|
|
# Send to a group chat or channel
|
|
|
|
|
clawdbot message send --channel msteams --target "conversation:19:abc...@thread.tacv2" --message "Hello"
|
|
|
|
|
|
|
|
|
|
# Send an Adaptive Card to a conversation
|
|
|
|
|
clawdbot message send --channel msteams --target "conversation:19:abc...@thread.tacv2" \
|
|
|
|
|
--card '{"type":"AdaptiveCard","version":"1.5","body":[{"type":"TextBlock","text":"Hello"}]}'
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
**Agent tool examples:**
|
|
|
|
|
```json
|
|
|
|
|
{
|
|
|
|
|
"action": "send",
|
|
|
|
|
"channel": "msteams",
|
|
|
|
|
"target": "user:John Smith",
|
|
|
|
|
"message": "Hello!"
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
```json
|
|
|
|
|
{
|
|
|
|
|
"action": "send",
|
|
|
|
|
"channel": "msteams",
|
|
|
|
|
"target": "conversation:19:abc...@thread.tacv2",
|
|
|
|
|
"card": {"type": "AdaptiveCard", "version": "1.5", "body": [{"type": "TextBlock", "text": "Hello"}]}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
Note: Without the `user:` prefix, names default to group/team resolution. Always use `user:` when targeting people by display name.
|
|
|
|
|
|
|
|
|
|
## Proactive messaging
|
|
|
|
|
- Proactive messages are only possible **after** a user has interacted, because we store conversation references at that point.
|
|
|
|
|
- See `/gateway/configuration` for `dmPolicy` and allowlist gating.
|
|
|
|
|
|