Skip to content

Commit a92d8e7

Browse files
github-actions[bot]examples-bot
andauthored
[Example] 470 — Microsoft Teams Real-Time Transcription Bot (Node.js) (#183)
## New example: Microsoft Teams Real-Time Transcription Bot <!-- metadata type: example number: 470 slug: microsoft-teams-transcription-bot-node language: Node.js products: stt integrations: microsoft-teams --> **Integration:** Microsoft Teams | **Language:** Node.js | **Products:** STT ### What this shows A Node.js bot that uses the BotFramework SDK and Microsoft Graph Communications Calling API to join Teams meetings, capture live audio as linear16 PCM, stream it to Deepgram's live WebSocket STT endpoint (nova-3), and post real-time transcription captions back into the meeting chat. ### Required secrets - `MICROSOFT_APP_ID` — Azure Bot Service app registration - `MICROSOFT_APP_PASSWORD` — Azure AD client secret - `MICROSOFT_APP_TENANT_ID` — Azure AD tenant ID - `BOT_BASE_URL` — Public HTTPS callback URL ### Tests ✅ Tests passed (Deepgram streaming pipeline verified; server endpoint tests skipped due to missing Azure credentials) ``` Note: Missing Azure credentials (MICROSOFT_APP_ID, MICROSOFT_APP_PASSWORD, MICROSOFT_APP_TENANT_ID, BOT_BASE_URL) — skipping server integration tests, running Deepgram streaming test only Downloading test audio... Audio ready: 829866 bytes of linear16 16kHz Skipping server endpoint tests (missing Azure credentials) Testing CallingHandler Deepgram streaming pipeline... Deepgram connection established Sent 256000 bytes (8.0s) of audio PASS: Deepgram streaming — received 2 transcript(s), 89 chars All tests passed ``` Closes #136 --- *Built by Engineer on 2026-04-05* --------- Co-authored-by: examples-bot <noreply@deepgram.com>
1 parent 4a713e2 commit a92d8e7

10 files changed

Lines changed: 2410 additions & 0 deletions

File tree

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
# Deepgram — https://console.deepgram.com/
2+
DEEPGRAM_API_KEY=
3+
4+
# Azure Bot Service — https://portal.azure.com/
5+
MICROSOFT_APP_ID=
6+
MICROSOFT_APP_PASSWORD=
7+
MICROSOFT_APP_TENANT_ID=
8+
9+
# Public callback URL for media (must be HTTPS with valid cert)
10+
# e.g. https://your-bot.example.com
11+
BOT_BASE_URL=
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
save-exact=true
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
# Microsoft Teams Real-Time Transcription Bot
2+
3+
A Node.js bot that joins Microsoft Teams meetings via the BotFramework SDK and Graph Communications Calling API, streams meeting audio to Deepgram's live speech-to-text API, and posts real-time transcription captions back into the meeting chat.
4+
5+
## What you'll build
6+
7+
An Express server that acts as a Teams bot: it receives messages through the Bot Framework messaging endpoint, joins meetings through the Graph Communications Calling API, captures meeting audio as linear16 PCM, streams it to Deepgram for real-time transcription, and posts final transcripts back into the meeting chat.
8+
9+
## Prerequisites
10+
11+
- Node.js 18+
12+
- Deepgram account — [get a free API key](https://console.deepgram.com/)
13+
- Microsoft Azure account — [sign up](https://portal.azure.com/)
14+
- An Azure Bot Service registration with Teams channel enabled
15+
- Azure AD app registration with `Calls.JoinGroupCall.All` and `Calls.AccessMedia.All` application permissions
16+
- A public HTTPS endpoint (use [ngrok](https://ngrok.com/) or [dev tunnels](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/) for local development)
17+
18+
## Environment variables
19+
20+
| Variable | Where to find it |
21+
|----------|-----------------|
22+
| `DEEPGRAM_API_KEY` | [Deepgram console](https://console.deepgram.com/) |
23+
| `MICROSOFT_APP_ID` | [Azure portal](https://portal.azure.com/) → App registrations → Overview → Application (client) ID |
24+
| `MICROSOFT_APP_PASSWORD` | Azure portal → App registrations → Certificates & secrets → Client secret value |
25+
| `MICROSOFT_APP_TENANT_ID` | Azure portal → App registrations → Overview → Directory (tenant) ID |
26+
| `BOT_BASE_URL` | Your public HTTPS URL (e.g. `https://your-bot.example.com`) |
27+
28+
Copy `.env.example` to `.env` and fill in your values.
29+
30+
## Install and run
31+
32+
```bash
33+
pnpm install
34+
pnpm start
35+
```
36+
37+
Then expose the server publicly (for local dev):
38+
39+
```bash
40+
ngrok http 3978
41+
```
42+
43+
Configure your Azure Bot Service:
44+
1. Set the messaging endpoint to `https://<your-url>/api/messages`
45+
2. Set the calling webhook to `https://<your-url>/api/calling/callback`
46+
3. Enable the Microsoft Teams channel
47+
48+
In a Teams meeting chat, mention the bot and say **join** to start transcription.
49+
50+
## Key parameters
51+
52+
| Parameter | Value | Description |
53+
|-----------|-------|-------------|
54+
| `model` | `nova-3` | Deepgram's latest and most accurate STT model |
55+
| `encoding` | `linear16` | 16-bit signed PCM — matches Graph Communications audio format |
56+
| `sample_rate` | `16000` | 16 kHz — standard for Teams meeting audio |
57+
| `smart_format` | `true` | Adds punctuation and formatting to transcripts |
58+
| `interim_results` | `true` | Provides partial transcripts while speech is ongoing |
59+
| `utterance_end_ms` | `1000` | Detects end of speech after 1 second of silence |
60+
| `tag` | `deepgram-examples` | Tags traffic in Deepgram console for identification |
61+
62+
## How it works
63+
64+
1. A user mentions the bot in a Teams meeting chat and sends **join**
65+
2. The bot calls the Graph Communications API to join the meeting as a participant with app-hosted media
66+
3. Graph streams meeting audio as linear16 PCM to the bot's notification endpoint
67+
4. The bot forwards each audio chunk to a Deepgram live WebSocket connection
68+
5. Deepgram returns interim and final transcripts in real-time
69+
6. Final transcripts are posted back to the meeting chat via the Bot Framework messaging API
70+
7. When the user sends **leave**, the bot hangs up the call and closes the Deepgram connection
71+
72+
## Azure AD permissions required
73+
74+
| Permission | Type | Description |
75+
|-----------|------|-------------|
76+
| `Calls.JoinGroupCall.All` | Application | Join group calls and meetings |
77+
| `Calls.AccessMedia.All` | Application | Access media streams in calls |
78+
79+
These must be granted as **application permissions** (not delegated) and require admin consent.
80+
81+
## Starter templates
82+
83+
[deepgram-starters](https://github.com/orgs/deepgram-starters/repositories)
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
{
2+
"name": "deepgram-teams-transcription-bot",
3+
"version": "1.0.0",
4+
"description": "Microsoft Teams bot that transcribes meetings in real-time using Deepgram STT",
5+
"main": "src/index.js",
6+
"packageManager": "pnpm@10.30.3",
7+
"scripts": {
8+
"start": "node src/index.js",
9+
"test": "node tests/test.js"
10+
},
11+
"dependencies": {
12+
"@azure/identity": "4.13.1",
13+
"@deepgram/sdk": "5.0.0",
14+
"@microsoft/microsoft-graph-client": "3.0.7",
15+
"botbuilder": "4.23.3",
16+
"dotenv": "16.6.1",
17+
"express": "4.22.1"
18+
},
19+
"engines": {
20+
"node": ">=18"
21+
},
22+
"pnpm": {
23+
"overrides": {
24+
"axios": ">=1.15.0"
25+
}
26+
}
27+
}

0 commit comments

Comments
 (0)