Skip to content

Commit d9f9e93

Browse files
committed
feat!: move msteams to plugin
1 parent dae34f3 commit d9f9e93

73 files changed

Lines changed: 711 additions & 243 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
@@ -2,6 +2,7 @@
22

33
## 2026.1.15 (unreleased)
44

5+
- **BREAKING:** Microsoft Teams is now a plugin; install `@clawdbot/msteams` via `clawdbot plugins install @clawdbot/msteams`.
56
- CLI: set process titles to `clawdbot-<command>` for clearer process listings.
67
- Heartbeat: tighten prompt guidance + suppress duplicate alerts for 24h. (#980) — thanks @voidserf.
78
- Plugins: add provider auth registry + `clawdbot models auth login` for plugin-driven OAuth/API key flows.

docs/channels/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ Text is supported everywhere; media and reactions vary by channel.
1717
- [Slack](/channels/slack) — Bolt SDK; workspace apps.
1818
- [Signal](/channels/signal) — signal-cli; privacy-focused.
1919
- [iMessage](/channels/imessage) — macOS only; native integration.
20-
- [Microsoft Teams](/channels/msteams) — Bot Framework; enterprise support.
20+
- [Microsoft Teams](/channels/msteams) — Bot Framework; enterprise support (plugin, installed separately).
2121
- [Matrix](/channels/matrix) — Matrix protocol (plugin, installed separately).
2222
- [Zalo](/channels/zalo) — Zalo Bot API; Vietnam's popular messenger (plugin, installed separately).
2323
- [WebChat](/web/webchat) — Gateway WebChat UI over WebSocket.

docs/channels/msteams.md

Lines changed: 45 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,20 +3,43 @@ summary: "Microsoft Teams bot support status, capabilities, and configuration"
33
read_when:
44
- Working on MS Teams channel features
55
---
6-
# Microsoft Teams (Bot Framework)
6+
# Microsoft Teams (plugin)
77

88
> "Abandon all hope, ye who enter here."
99
1010

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

1313
Status: text + DM attachments are supported; channel/group attachments require Microsoft Graph permissions. Polls are sent via Adaptive Cards.
1414

15+
## Plugin required
16+
Microsoft Teams ships as a plugin and is not bundled with the core install.
17+
18+
**Breaking change (2026.1.15):** MS Teams moved out of core. If you use it, you must install the plugin.
19+
20+
Explainable: keeps core installs lighter and lets MS Teams dependencies update independently.
21+
22+
Install via CLI (npm registry):
23+
```bash
24+
clawdbot plugins install @clawdbot/msteams
25+
```
26+
27+
Local checkout (when running from a git repo):
28+
```bash
29+
clawdbot plugins install ./extensions/msteams
30+
```
31+
32+
If you choose Teams during configure/onboarding and a git checkout is detected,
33+
Clawdbot will offer the local install path automatically.
34+
35+
Details: [Plugins](/plugin)
36+
1537
## Quick setup (beginner)
16-
1) Create an **Azure Bot** (App ID + client secret + tenant ID).
17-
2) Configure Clawdbot with those credentials.
18-
3) Expose `/api/messages` (port 3978 by default) via a public URL or tunnel.
19-
4) Install the Teams app package and start the gateway.
38+
1) Install the Microsoft Teams plugin.
39+
2) Create an **Azure Bot** (App ID + client secret + tenant ID).
40+
3) Configure Clawdbot with those credentials.
41+
4) Expose `/api/messages` (port 3978 by default) via a public URL or tunnel.
42+
5) Install the Teams app package and start the gateway.
2043

2144
Minimal config:
2245
```json5
@@ -73,11 +96,12 @@ Example:
7396
```
7497

7598
## How it works
76-
1. Create an **Azure Bot** (App ID + secret + tenant ID).
77-
2. Build a **Teams app package** that references the bot and includes the RSC permissions below.
78-
3. Upload/install the Teams app into a team (or personal scope for DMs).
79-
4. Configure `msteams` in `~/.clawdbot/clawdbot.json` (or env vars) and start the gateway.
80-
5. The gateway listens for Bot Framework webhook traffic on `/api/messages` by default.
99+
1. Install the Microsoft Teams plugin.
100+
2. Create an **Azure Bot** (App ID + secret + tenant ID).
101+
3. Build a **Teams app package** that references the bot and includes the RSC permissions below.
102+
4. Upload/install the Teams app into a team (or personal scope for DMs).
103+
5. Configure `msteams` in `~/.clawdbot/clawdbot.json` (or env vars) and start the gateway.
104+
6. The gateway listens for Bot Framework webhook traffic on `/api/messages` by default.
81105

82106
## Azure Bot Setup (Prerequisites)
83107

@@ -166,21 +190,25 @@ This is often easier than hand-editing JSON manifests.
166190
3. Check gateway logs for incoming activity
167191

168192
## Setup (minimal text-only)
169-
1. **Bot registration**
193+
1. **Install the Microsoft Teams plugin**
194+
- From npm: `clawdbot plugins install @clawdbot/msteams`
195+
- From a local checkout: `clawdbot plugins install ./extensions/msteams`
196+
197+
2. **Bot registration**
170198
- Create an Azure Bot (see above) and note:
171199
- App ID
172200
- Client secret (App password)
173201
- Tenant ID (single-tenant)
174202

175-
2. **Teams app manifest**
203+
3. **Teams app manifest**
176204
- Include a `bot` entry with `botId = <App ID>`.
177205
- Scopes: `personal`, `team`, `groupChat`.
178206
- `supportsFiles: true` (required for personal scope file handling).
179207
- Add RSC permissions (below).
180208
- Create icons: `outline.png` (32x32) and `color.png` (192x192).
181209
- Zip all three files together: `manifest.json`, `outline.png`, `color.png`.
182210

183-
3. **Configure Clawdbot**
211+
4. **Configure Clawdbot**
184212
```json
185213
{
186214
"msteams": {
@@ -198,12 +226,12 @@ This is often easier than hand-editing JSON manifests.
198226
- `MSTEAMS_APP_PASSWORD`
199227
- `MSTEAMS_TENANT_ID`
200228

201-
4. **Bot endpoint**
229+
5. **Bot endpoint**
202230
- Set the Azure Bot Messaging Endpoint to:
203231
- `https://<host>:3978/api/messages` (or your chosen path/port).
204232

205-
5. **Run the gateway**
206-
- The Teams channel starts automatically when `msteams` config exists and credentials are set.
233+
6. **Run the gateway**
234+
- The Teams channel starts automatically when the plugin is installed and `msteams` config exists with credentials.
207235

208236
## History context
209237
- `channels.msteams.historyLimit` controls how many recent channel/group messages are wrapped into the prompt.

docs/plugin.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,11 @@ See [Voice Call](/plugins/voice-call) for a concrete example plugin.
3535

3636
## Available plugins (official)
3737

38+
- Microsoft Teams is plugin-only as of 2026.1.15; install `@clawdbot/msteams` if you use Teams.
3839
- [Voice Call](/plugins/voice-call)`@clawdbot/voice-call`
3940
- [Matrix](/channels/matrix)`@clawdbot/matrix`
4041
- [Zalo](/channels/zalo)`@clawdbot/zalo`
42+
- [Microsoft Teams](/channels/msteams)`@clawdbot/msteams`
4143

4244
Clawdbot plugins are **TypeScript modules** loaded at runtime via jiti. They can
4345
register:

docs/reference/RELEASING.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ Use `pnpm` (Node 22+) from the repo root. Keep the working tree clean before tag
1212

1313
1) **Version & metadata**
1414
- [ ] Bump `package.json` version (e.g., `1.1.0`).
15+
- [ ] Run `pnpm plugins:sync` to align extension package versions + changelogs.
1516
- [ ] Update CLI/version strings: [`src/cli/program.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/cli/program.ts) and the Baileys user agent in [`src/provider-web.ts`](https://github.com/clawdbot/clawdbot/blob/main/src/provider-web.ts).
1617
- [ ] Confirm package metadata (name, description, repository, keywords, license) and `bin` map points to [`dist/entry.js`](https://github.com/clawdbot/clawdbot/blob/main/dist/entry.js) for `clawdbot`.
1718
- [ ] If dependencies changed, run `pnpm install` so `pnpm-lock.yaml` is current.

extensions/msteams/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Changelog
2+
3+
## 2026.1.15
4+
5+
### Features
6+
- Microsoft Teams channel plugin (Bot Framework) with polls, media, threads, and gateway monitor.

extensions/msteams/index.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import type { ClawdbotPluginApi } from "../../src/plugins/types.js";
2+
3+
import { msteamsPlugin } from "./src/channel.js";
4+
5+
const plugin = {
6+
id: "msteams",
7+
name: "Microsoft Teams",
8+
description: "Microsoft Teams channel plugin (Bot Framework)",
9+
register(api: ClawdbotPluginApi) {
10+
api.registerChannel({ plugin: msteamsPlugin });
11+
},
12+
};
13+
14+
export default plugin;

extensions/msteams/package.json

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"name": "@clawdbot/msteams",
3+
"version": "2026.1.15",
4+
"type": "module",
5+
"description": "Clawdbot Microsoft Teams channel plugin",
6+
"clawdbot": {
7+
"extensions": ["./index.ts"]
8+
},
9+
"dependencies": {
10+
"@microsoft/agents-hosting": "^1.1.1",
11+
"@microsoft/agents-hosting-express": "^1.1.1",
12+
"@microsoft/agents-hosting-extensions-teams": "^1.1.1",
13+
"express": "^5.2.1",
14+
"proper-lockfile": "^4.1.2"
15+
}
16+
}

src/msteams/attachments.test.ts renamed to extensions/msteams/src/attachments.test.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,19 @@ const saveMediaBufferMock = vi.fn(async () => ({
66
contentType: "image/png",
77
}));
88

9-
vi.mock("../media/mime.js", () => ({
9+
const modulePaths = vi.hoisted(() => {
10+
const downloadModuleUrl = new URL("./attachments/download.js", import.meta.url);
11+
return {
12+
mimeModulePath: new URL("../../../../src/media/mime.js", downloadModuleUrl).pathname,
13+
storeModulePath: new URL("../../../../src/media/store.js", downloadModuleUrl).pathname,
14+
};
15+
});
16+
17+
vi.mock(modulePaths.mimeModulePath, () => ({
1018
detectMime: (...args: unknown[]) => detectMimeMock(...args),
1119
}));
1220

13-
vi.mock("../media/store.js", () => ({
21+
vi.mock(modulePaths.storeModulePath, () => ({
1422
saveMediaBuffer: (...args: unknown[]) => saveMediaBufferMock(...args),
1523
}));
1624

0 commit comments

Comments
 (0)