276 lines
6.7 KiB
Markdown
276 lines
6.7 KiB
Markdown
# Teams Bot Service
|
|
|
|
AI-powered Microsoft Teams meeting bot. Joins meetings, captures live transcripts, monitors chat, and responds via voice and/or chat messages.
|
|
|
|
## Architecture
|
|
|
|
```
|
|
┌───────────────┐ ┌───────────────────────┐
|
|
│ │ WebSocket │ │
|
|
│ Gateway │◄──────────────────────────────────►│ Bot Service │
|
|
│ │ transcripts, status, chat, │ │
|
|
│ ● AI engine │ audioChunks, voiceGreeting │ Joins Teams meetings │
|
|
│ ● TTS │ │ as a participant │
|
|
│ ● Sessions │ playAudio, sendChatMessage, │ │
|
|
│ ● Billing │ stopAudio │ Capabilities: │
|
|
│ │ │ ├ Live transcripts │
|
|
│ │ HTTP │ ├ Chat messages │
|
|
│ │────────────────────────────────────► ├ Voice playback │
|
|
└───────────────┘ join, leave, status │ └ Audio capture │
|
|
└───────────────────────┘
|
|
```
|
|
|
|
| Path | Protocol | Purpose |
|
|
|------|----------|---------|
|
|
| Gateway ↔ Bot | WebSocket | Real-time transcript, chat, audio, status exchange |
|
|
| Gateway → Bot | HTTP | Session control (join, leave, status) |
|
|
|
|
## Integration Guide
|
|
|
|
### How It Works
|
|
|
|
1. Gateway sends a **POST** to the Bot with a meeting URL and optional credentials
|
|
2. Bot joins the meeting and appears as a regular participant
|
|
3. A **WebSocket** connection is established for real-time data exchange
|
|
4. Bot streams transcript segments and chat messages to the Gateway
|
|
5. Gateway can send TTS audio or chat responses back into the meeting
|
|
|
|
### Step 1: Start a Session
|
|
|
|
```http
|
|
POST /api/bot
|
|
Content-Type: application/json
|
|
|
|
{
|
|
"sessionId": "550e8400-e29b-41d4-a716-446655440000",
|
|
"meetingUrl": "https://teams.microsoft.com/meet/123456789?p=abc123",
|
|
"botName": "AI Assistant",
|
|
"instanceId": "feature-instance-uuid",
|
|
"gatewayWsUrl": "wss://gateway.example.com/api/teamsbot/ws",
|
|
"language": "de-DE",
|
|
"botAccountEmail": "bot@example.com",
|
|
"botAccountPassword": "decrypted-password",
|
|
"transferMode": "caption"
|
|
}
|
|
```
|
|
|
|
| Field | Required | Description |
|
|
|-------|----------|-------------|
|
|
| `sessionId` | Yes | Unique session UUID (generated by Gateway) |
|
|
| `meetingUrl` | Yes | Teams meeting URL (classic or short format) |
|
|
| `botName` | No | Display name in meeting (default: env `BOT_NAME`) |
|
|
| `instanceId` | No | Feature instance ID for Gateway WebSocket path |
|
|
| `gatewayWsUrl` | No | Gateway WebSocket base URL (default: env `GATEWAY_WS_URL`) |
|
|
| `language` | No | BCP-47 language code (default: `de-DE`) |
|
|
| `botAccountEmail` | No | Microsoft account for authenticated join |
|
|
| `botAccountPassword` | No | Decrypted password for authenticated join |
|
|
| `transferMode` | No | `caption` or `audio` |
|
|
|
|
If `botAccountEmail` + `botAccountPassword` are provided, the bot joins as an authenticated user. Otherwise, it joins as an anonymous guest.
|
|
|
|
**Response:**
|
|
|
|
```json
|
|
{
|
|
"success": true,
|
|
"sessionId": "550e8400-e29b-41d4-a716-446655440000",
|
|
"message": "Bot deployment initiated"
|
|
}
|
|
```
|
|
|
|
### Step 2: Receive Data via WebSocket
|
|
|
|
After deployment, the Bot connects to the Gateway at:
|
|
|
|
```
|
|
wss://{gatewayHost}/api/teamsbot/{instanceId}/bot/ws/{sessionId}
|
|
```
|
|
|
|
#### Messages: Bot → Gateway
|
|
|
|
**Transcript segment:**
|
|
|
|
```json
|
|
{
|
|
"type": "transcript",
|
|
"sessionId": "...",
|
|
"transcript": {
|
|
"speaker": "Jane Doe",
|
|
"text": "Hey Bot, can you summarize this?",
|
|
"timestamp": "2026-02-18T10:30:00.000Z",
|
|
"isFinal": true
|
|
}
|
|
}
|
|
```
|
|
|
|
**Chat message:**
|
|
|
|
```json
|
|
{
|
|
"type": "chatMessage",
|
|
"sessionId": "...",
|
|
"chat": {
|
|
"speaker": "Jane Doe",
|
|
"text": "Please summarize the discussion",
|
|
"timestamp": "2026-02-18T10:31:00.000Z"
|
|
}
|
|
}
|
|
```
|
|
|
|
**Status update:**
|
|
|
|
```json
|
|
{
|
|
"type": "status",
|
|
"sessionId": "...",
|
|
"status": "joined",
|
|
"message": "Bot joined the meeting"
|
|
}
|
|
```
|
|
|
|
Status values: `connecting` | `in_lobby` | `joined` | `left` | `error`
|
|
|
|
**Voice greeting request** (bot asks Gateway for TTS):
|
|
|
|
```json
|
|
{
|
|
"type": "voiceGreeting",
|
|
"sessionId": "...",
|
|
"text": "Hello, I am ready.",
|
|
"language": "de-DE"
|
|
}
|
|
```
|
|
|
|
**Raw audio chunk** (`transferMode: "audio"` only):
|
|
|
|
```json
|
|
{
|
|
"type": "audioChunk",
|
|
"sessionId": "...",
|
|
"audio": {
|
|
"data": "<base64-encoded PCM16>",
|
|
"sampleRate": 16000,
|
|
"format": "pcm16",
|
|
"timestamp": "2026-02-18T10:30:00.500Z"
|
|
}
|
|
}
|
|
```
|
|
|
|
**Keepalive:**
|
|
|
|
```json
|
|
{ "type": "ping" }
|
|
```
|
|
|
|
#### Messages: Gateway → Bot
|
|
|
|
**Play TTS audio:**
|
|
|
|
```json
|
|
{
|
|
"type": "playAudio",
|
|
"sessionId": "...",
|
|
"audio": {
|
|
"data": "<base64-encoded MP3>",
|
|
"format": "mp3"
|
|
}
|
|
}
|
|
```
|
|
|
|
**Send chat message:**
|
|
|
|
```json
|
|
{
|
|
"type": "sendChatMessage",
|
|
"sessionId": "...",
|
|
"text": "Here is my summary of the discussion..."
|
|
}
|
|
```
|
|
|
|
**Stop audio playback:**
|
|
|
|
```json
|
|
{ "type": "stopAudio", "sessionId": "..." }
|
|
```
|
|
|
|
**Keepalive response:**
|
|
|
|
```json
|
|
{ "type": "pong" }
|
|
```
|
|
|
|
### Step 3: Leave the Meeting
|
|
|
|
```http
|
|
POST /api/bot/:sessionId/leave
|
|
```
|
|
|
|
```json
|
|
{
|
|
"success": true,
|
|
"message": "Leave initiated"
|
|
}
|
|
```
|
|
|
|
### Step 4: Check Status
|
|
|
|
```http
|
|
GET /api/bot/:sessionId/status
|
|
```
|
|
|
|
```json
|
|
{
|
|
"sessionId": "550e8400-e29b-41d4-a716-446655440000",
|
|
"state": "in_meeting",
|
|
"error": null
|
|
}
|
|
```
|
|
|
|
### Health Check
|
|
|
|
```http
|
|
GET /health
|
|
```
|
|
|
|
Returns `200 OK` with `{ "status": "ok", "timestamp": "..." }`.
|
|
|
|
## Meeting URL Formats
|
|
|
|
Both formats are supported:
|
|
|
|
```
|
|
# Classic
|
|
https://teams.microsoft.com/l/meetup-join/19%3ameeting_xxx/0?context=...
|
|
|
|
# Short
|
|
https://teams.microsoft.com/meet/123456789?p=abc123
|
|
```
|
|
|
|
## Running the Service
|
|
|
|
### Local
|
|
|
|
```bash
|
|
npm install
|
|
cp .env.sample .env # Configure Gateway URL, bot name, etc.
|
|
npm run dev # Dev mode
|
|
```
|
|
|
|
### Docker
|
|
|
|
```bash
|
|
docker build -t teams-bot .
|
|
|
|
docker run -p 4100:4100 \
|
|
-e GATEWAY_WS_URL=wss://gateway.example.com/api/teamsbot/ws \
|
|
teams-bot
|
|
```
|
|
|
|
## Configuration
|
|
|
|
| Variable | Description | Default |
|
|
|----------|-------------|---------|
|
|
| `PORT` | HTTP server port | `4100` |
|
|
| `GATEWAY_WS_URL` | Gateway WebSocket base URL | — |
|
|
| `BOT_NAME` | Default bot display name | — |
|
|
| `LOG_LEVEL` | Log level (`debug`, `info`, `warn`, `error`) | `info` |
|