Cleans up the prose-level v2 references that the rename commit didn't touch. Skills now describe themselves and the codebase without "v2" versioning language. /add-X-v2 cross-references in setup, init-first-agent, and manage-channels updated to /add-X. Runtime path identifiers (data/v2.db, data/v2-sessions/, container name nanoclaw-v2) deliberately left as-is — renaming them breaks live installs without commensurate benefit. Verified: pnpm run build clean, 326 host tests pass. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
208 lines
6.3 KiB
Markdown
208 lines
6.3 KiB
Markdown
---
|
|
name: add-teams
|
|
description: Add Microsoft Teams channel integration via Chat SDK.
|
|
---
|
|
|
|
# Add Microsoft Teams Channel
|
|
|
|
Connect NanoClaw to Microsoft Teams for interactive chat in team channels, group chats, and direct messages.
|
|
|
|
## Install
|
|
|
|
NanoClaw doesn't ship channels in trunk. This skill copies the Teams adapter in from the `channels` branch.
|
|
|
|
### Pre-flight (idempotent)
|
|
|
|
Skip to **Credentials** if all of these are already in place:
|
|
|
|
- `src/channels/teams.ts` exists
|
|
- `src/channels/index.ts` contains `import './teams.js';`
|
|
- `@chat-adapter/teams` is listed in `package.json` dependencies
|
|
|
|
Otherwise continue. Every step below is safe to re-run.
|
|
|
|
### 1. Fetch the channels branch
|
|
|
|
```bash
|
|
git fetch origin channels
|
|
```
|
|
|
|
### 2. Copy the adapter
|
|
|
|
```bash
|
|
git show origin/channels:src/channels/teams.ts > src/channels/teams.ts
|
|
```
|
|
|
|
### 3. Append the self-registration import
|
|
|
|
Append to `src/channels/index.ts` (skip if the line is already present):
|
|
|
|
```typescript
|
|
import './teams.js';
|
|
```
|
|
|
|
### 4. Install the adapter package (pinned)
|
|
|
|
```bash
|
|
pnpm install @chat-adapter/teams@4.26.0
|
|
```
|
|
|
|
### 5. Build
|
|
|
|
```bash
|
|
pnpm run build
|
|
```
|
|
|
|
## Credentials
|
|
|
|
### Step 1: Create an Azure AD App Registration
|
|
|
|
1. Go to [Azure Portal](https://portal.azure.com) > **App registrations** > **New registration**
|
|
2. Name it (e.g., "NanoClaw")
|
|
3. Supported account types: **Single tenant** (your org only) or **Multi tenant** (any org)
|
|
4. Click **Register**
|
|
5. Copy the **Application (client) ID** and **Directory (tenant) ID** from the Overview page
|
|
|
|
### Step 2: Create a Client Secret
|
|
|
|
1. In the App Registration, go to **Certificates & secrets**
|
|
2. Click **New client secret**, description "nanoclaw", expiry 180 days
|
|
3. Click **Add** and **copy the Value immediately** (shown only once)
|
|
|
|
### Step 3: Create an Azure Bot
|
|
|
|
1. Go to Azure Portal > search **Azure Bot** > **Create**
|
|
2. Fill in:
|
|
- **Bot handle**: unique name (e.g., "nanoclaw-bot")
|
|
- **Type of App**: match your app registration (Single or Multi Tenant)
|
|
- **Creation type**: **Use existing app registration**
|
|
- **App ID**: paste from Step 1
|
|
- **App tenant ID**: paste from Step 1 (Single Tenant only)
|
|
3. Click **Review + create** > **Create**
|
|
|
|
Or use Azure CLI:
|
|
|
|
```bash
|
|
az group create --name nanoclaw-rg --location eastus
|
|
az bot create \
|
|
--resource-group nanoclaw-rg \
|
|
--name nanoclaw-bot \
|
|
--app-type SingleTenant \
|
|
--appid YOUR_APP_ID \
|
|
--tenant-id YOUR_TENANT_ID \
|
|
--endpoint "https://your-domain/api/webhooks/teams"
|
|
```
|
|
|
|
### Step 4: Configure Messaging Endpoint
|
|
|
|
1. Go to your Azure Bot resource > **Configuration**
|
|
2. Set **Messaging endpoint** to `https://your-domain/api/webhooks/teams`
|
|
3. Click **Apply**
|
|
|
|
### Step 5: Enable Teams Channel
|
|
|
|
1. In the Azure Bot resource, go to **Channels**
|
|
2. Click **Microsoft Teams** > Accept terms > **Apply**
|
|
|
|
Or via CLI:
|
|
|
|
```bash
|
|
az bot msteams create --resource-group nanoclaw-rg --name nanoclaw-bot
|
|
```
|
|
|
|
### Step 6: Create and Sideload Teams App
|
|
|
|
Create a `manifest.json`:
|
|
|
|
```json
|
|
{
|
|
"$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.16/MicrosoftTeams.schema.json",
|
|
"manifestVersion": "1.16",
|
|
"version": "1.0.0",
|
|
"id": "YOUR_APP_ID",
|
|
"packageName": "com.nanoclaw.bot",
|
|
"developer": {
|
|
"name": "NanoClaw",
|
|
"websiteUrl": "https://your-domain",
|
|
"privacyUrl": "https://your-domain",
|
|
"termsOfUseUrl": "https://your-domain"
|
|
},
|
|
"name": { "short": "NanoClaw", "full": "NanoClaw Assistant" },
|
|
"description": {
|
|
"short": "NanoClaw assistant bot",
|
|
"full": "NanoClaw personal assistant powered by Claude."
|
|
},
|
|
"icons": { "outline": "outline.png", "color": "color.png" },
|
|
"accentColor": "#4A90D9",
|
|
"bots": [{
|
|
"botId": "YOUR_APP_ID",
|
|
"scopes": ["personal", "team", "groupchat"],
|
|
"supportsFiles": false,
|
|
"isNotificationOnly": false
|
|
}],
|
|
"permissions": ["identity", "messageTeamMembers"],
|
|
"validDomains": ["your-domain"]
|
|
}
|
|
```
|
|
|
|
Create two icon PNGs (32x32 `outline.png`, 192x192 `color.png`), zip all three files together.
|
|
|
|
**Sideload in Teams:**
|
|
1. Open Teams > **Apps** > **Manage your apps**
|
|
2. Click **Upload an app** > **Upload a custom app**
|
|
3. Select the zip file
|
|
|
|
Sideloading requires Teams admin access. Free personal Teams does NOT support sideloading. Use a Microsoft 365 Business account or developer tenant.
|
|
|
|
### Step 7: Receive All Messages (Optional)
|
|
|
|
By default, the bot only receives messages when @-mentioned. To receive all messages in a channel without @-mention, add RSC permissions to `manifest.json`:
|
|
|
|
```json
|
|
{
|
|
"authorization": {
|
|
"permissions": {
|
|
"resourceSpecific": [
|
|
{ "name": "ChannelMessage.Read.Group", "type": "Application" }
|
|
]
|
|
}
|
|
}
|
|
}
|
|
```
|
|
|
|
### Configure environment
|
|
|
|
Add to `.env`:
|
|
|
|
```bash
|
|
TEAMS_APP_ID=your-app-id
|
|
TEAMS_APP_PASSWORD=your-client-secret
|
|
# For Single Tenant only:
|
|
TEAMS_APP_TENANT_ID=your-tenant-id
|
|
TEAMS_APP_TYPE=SingleTenant
|
|
```
|
|
|
|
Sync to container: `mkdir -p data/env && cp .env data/env/env`
|
|
|
|
### Webhook server
|
|
|
|
The Chat SDK bridge automatically starts a shared webhook server on port 3000 (configurable via `WEBHOOK_PORT` env var). The server handles `/api/webhooks/teams` for Teams and other webhook-based adapters. This port must be publicly reachable from the internet for Azure Bot Service to deliver activities.
|
|
|
|
For local development without a public URL, use a tunnel (e.g., `ngrok http 3000`) and update the messaging endpoint in Azure Bot Configuration.
|
|
|
|
## Next Steps
|
|
|
|
If you're in the middle of `/setup`, return to the setup flow now.
|
|
|
|
Otherwise, run `/manage-channels` to wire this channel to an agent group.
|
|
|
|
## Channel Info
|
|
|
|
- **type**: `teams`
|
|
- **terminology**: Teams has "teams" containing "channels." The bot can also receive DMs (personal scope) and group chat messages. Channels support threaded replies.
|
|
- **platform-id-format**: `teams:{base64-encoded-conversation-id}:{base64-encoded-service-url}` — auto-generated by the adapter, not human-readable. Use the auto-created messaging group ID for wiring.
|
|
- **how-to-find-id**: Send a message to the bot in the channel. NanoClaw auto-creates a messaging group and logs the platform ID. Use that messaging group ID for wiring.
|
|
- **supports-threads**: yes (channels only; DMs and group chats are flat)
|
|
- **typical-use**: Team collaboration with the bot in channels; personal assistant via DMs
|
|
- **default-isolation**: Separate agent group per team. DMs can share an agent group with your main channel for unified personal memory.
|