Skip to content

Commit 0f7f7bb

Browse files
steipeteEvizero
andcommitted
fix: msteams attachments + plugin prompt hints
Co-authored-by: Christof <[email protected]>
1 parent 5fe8c4a commit 0f7f7bb

50 files changed

Lines changed: 2739 additions & 174 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ Docs: https://docs.clawd.bot
1111
- Docs: add per-message Gmail search example for gog. (#1220) Thanks @mbelinky.
1212
- Onboarding: remove the run setup-token auth option (paste setup-token or reuse CLI creds instead).
1313
- Signal: add typing indicators and DM read receipts via signal-cli.
14+
- MSTeams: add file uploads, adaptive cards, and attachment handling improvements. (#1410) Thanks @Evizero.
1415

1516
### Fixes
1617
- Config: avoid stack traces for invalid configs and log the config path.

docs/channels/msteams.md

Lines changed: 149 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ read_when:
88
> "Abandon all hope, ye who enter here."
99
1010

11-
Updated: 2026-01-16
11+
Updated: 2026-01-21
1212

13-
Status: text + DM attachments are supported; channel/group attachments require Microsoft Graph permissions. Polls are sent via Adaptive Cards.
13+
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.
1414

1515
## Plugin required
1616
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
403403
Teams markdown is more limited than Slack or Discord:
404404
- Basic formatting works: **bold**, *italic*, `code`, links
405405
- Complex markdown (tables, nested lists) may not render correctly
406-
- Adaptive Cards are used for polls; other card types are not yet supported
406+
- Adaptive Cards are supported for polls and arbitrary card sends (see below)
407407

408408
## Configuration
409409
Key settings (see `/gateway/configuration` for shared channel patterns):
@@ -422,6 +422,7 @@ Key settings (see `/gateway/configuration` for shared channel patterns):
422422
- `channels.msteams.teams.<teamId>.requireMention`: per-team override.
423423
- `channels.msteams.teams.<teamId>.channels.<conversationId>.replyStyle`: per-channel override.
424424
- `channels.msteams.teams.<teamId>.channels.<conversationId>.requireMention`: per-channel override.
425+
- `channels.msteams.sharePointSiteId`: SharePoint site ID for file uploads in group chats/channels (see [Sending files in group chats](#sending-files-in-group-chats)).
425426

426427
## Routing & Sessions
427428
- 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
471472
Without Graph permissions, channel messages with images will be received as text-only (the image content is not accessible to the bot).
472473
By default, Clawdbot only downloads media from Microsoft/Teams hostnames. Override with `channels.msteams.mediaAllowHosts` (use `["*"]` to allow any host).
473474

475+
## Sending files in group chats
476+
477+
Bots can send files in DMs using the FileConsentCard flow (built-in). However, **sending files in group chats/channels** requires additional setup:
478+
479+
| Context | How files are sent | Setup needed |
480+
|---------|-------------------|--------------|
481+
| **DMs** | FileConsentCard → user accepts → bot uploads | Works out of the box |
482+
| **Group chats/channels** | Upload to SharePoint → share link | Requires `sharePointSiteId` + Graph permissions |
483+
| **Images (any context)** | Base64-encoded inline | Works out of the box |
484+
485+
### Why group chats need SharePoint
486+
487+
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.
488+
489+
### Setup
490+
491+
1. **Add Graph API permissions** in Entra ID (Azure AD) → App Registration:
492+
- `Sites.ReadWrite.All` (Application) - upload files to SharePoint
493+
- `Chat.Read.All` (Application) - optional, enables per-user sharing links
494+
495+
2. **Grant admin consent** for the tenant.
496+
497+
3. **Get your SharePoint site ID:**
498+
```bash
499+
# Via Graph Explorer or curl with a valid token:
500+
curl -H "Authorization: Bearer $TOKEN" \
501+
"https://graph.microsoft.com/v1.0/sites/{hostname}:/{site-path}"
502+
503+
# Example: for a site at "contoso.sharepoint.com/sites/BotFiles"
504+
curl -H "Authorization: Bearer $TOKEN" \
505+
"https://graph.microsoft.com/v1.0/sites/contoso.sharepoint.com:/sites/BotFiles"
506+
507+
# Response includes: "id": "contoso.sharepoint.com,guid1,guid2"
508+
```
509+
510+
4. **Configure Clawdbot:**
511+
```json5
512+
{
513+
channels: {
514+
msteams: {
515+
// ... other config ...
516+
sharePointSiteId: "contoso.sharepoint.com,guid1,guid2"
517+
}
518+
}
519+
}
520+
```
521+
522+
### Sharing behavior
523+
524+
| Permission | Sharing behavior |
525+
|------------|------------------|
526+
| `Sites.ReadWrite.All` only | Organization-wide sharing link (anyone in org can access) |
527+
| `Sites.ReadWrite.All` + `Chat.Read.All` | Per-user sharing link (only chat members can access) |
528+
529+
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.
530+
531+
### Fallback behavior
532+
533+
| Scenario | Result |
534+
|----------|--------|
535+
| Group chat + file + `sharePointSiteId` configured | Upload to SharePoint, send sharing link |
536+
| Group chat + file + no `sharePointSiteId` | Attempt OneDrive upload (may fail), send text only |
537+
| Personal chat + file | FileConsentCard flow (works without SharePoint) |
538+
| Any context + image | Base64-encoded inline (works without SharePoint) |
539+
540+
### Files stored location
541+
542+
Uploaded files are stored in a `/ClawdbotShared/` folder in the configured SharePoint site's default document library.
543+
474544
## Polls (Adaptive Cards)
475545
Clawdbot sends Teams polls as Adaptive Cards (there is no native Teams poll API).
476546

@@ -479,6 +549,82 @@ Clawdbot sends Teams polls as Adaptive Cards (there is no native Teams poll API)
479549
- The gateway must stay online to record votes.
480550
- Polls do not auto-post result summaries yet (inspect the store file if needed).
481551

552+
## Adaptive Cards (arbitrary)
553+
Send any Adaptive Card JSON to Teams users or conversations using the `message` tool or CLI.
554+
555+
The `card` parameter accepts an Adaptive Card JSON object. When `card` is provided, the message text is optional.
556+
557+
**Agent tool:**
558+
```json
559+
{
560+
"action": "send",
561+
"channel": "msteams",
562+
"target": "user:<id>",
563+
"card": {
564+
"type": "AdaptiveCard",
565+
"version": "1.5",
566+
"body": [{"type": "TextBlock", "text": "Hello!"}]
567+
}
568+
}
569+
```
570+
571+
**CLI:**
572+
```bash
573+
clawdbot message send --channel msteams \
574+
--target "conversation:19:[email protected]" \
575+
--card '{"type":"AdaptiveCard","version":"1.5","body":[{"type":"TextBlock","text":"Hello!"}]}'
576+
```
577+
578+
See [Adaptive Cards documentation](https://adaptivecards.io/) for card schema and examples. For target format details, see [Target formats](#target-formats) below.
579+
580+
## Target formats
581+
582+
MSTeams targets use prefixes to distinguish between users and conversations:
583+
584+
| Target type | Format | Example |
585+
|-------------|--------|---------|
586+
| User (by ID) | `user:<aad-object-id>` | `user:40a1a0ed-4ff2-4164-a219-55518990c197` |
587+
| User (by name) | `user:<display-name>` | `user:John Smith` (requires Graph API) |
588+
| Group/channel | `conversation:<conversation-id>` | `conversation:19:[email protected]` |
589+
| Group/channel (raw) | `<conversation-id>` | `19:[email protected]` (if contains `@thread`) |
590+
591+
**CLI examples:**
592+
```bash
593+
# Send to a user by ID
594+
clawdbot message send --channel msteams --target "user:40a1a0ed-..." --message "Hello"
595+
596+
# Send to a user by display name (triggers Graph API lookup)
597+
clawdbot message send --channel msteams --target "user:John Smith" --message "Hello"
598+
599+
# Send to a group chat or channel
600+
clawdbot message send --channel msteams --target "conversation:19:[email protected]" --message "Hello"
601+
602+
# Send an Adaptive Card to a conversation
603+
clawdbot message send --channel msteams --target "conversation:19:[email protected]" \
604+
--card '{"type":"AdaptiveCard","version":"1.5","body":[{"type":"TextBlock","text":"Hello"}]}'
605+
```
606+
607+
**Agent tool examples:**
608+
```json
609+
{
610+
"action": "send",
611+
"channel": "msteams",
612+
"target": "user:John Smith",
613+
"message": "Hello!"
614+
}
615+
```
616+
617+
```json
618+
{
619+
"action": "send",
620+
"channel": "msteams",
621+
"target": "conversation:19:[email protected]",
622+
"card": {"type": "AdaptiveCard", "version": "1.5", "body": [{"type": "TextBlock", "text": "Hello"}]}
623+
}
624+
```
625+
626+
Note: Without the `user:` prefix, names default to group/team resolution. Always use `user:` when targeting people by display name.
627+
482628
## Proactive messaging
483629
- Proactive messages are only possible **after** a user has interacted, because we store conversation references at that point.
484630
- See `/gateway/configuration` for `dmPolicy` and allowlist gating.

docs/tools/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ Notes:
322322
Send messages and channel actions across Discord/Slack/Telegram/WhatsApp/Signal/iMessage/MS Teams.
323323

324324
Core actions:
325-
- `send` (text + optional media)
325+
- `send` (text + optional media; MS Teams also supports `card` for Adaptive Cards)
326326
- `poll` (WhatsApp/Discord/MS Teams polls)
327327
- `react` / `reactions` / `read` / `edit` / `delete`
328328
- `pin` / `unpin` / `list-pins`

0 commit comments

Comments
 (0)