A Claude Code / OpenCode skill for extracting complete transcripts from Teams meeting recordings hosted on SharePoint/OneDrive.
Microsoft Teams records meetings and stores them in SharePoint/OneDrive. The transcript is visible in the browser but:
- Download is often blocked (permission denied)
- Copy-paste is incomplete (virtual scrolling only copies the visible chunk)
- No export button in Teams or Stream
This skill solves all three problems automatically.
1. Opens the SharePoint Stream video page
2. Auto-detects if the player loaded (or if OAuth is needed)
3. Clicks the transcript button
4. Scrolls through the transcript panel in chunks (600px at a time)
5. Accumulates ALL text entries using Set deduplication (handles DOM recycling)
6. Returns the complete transcript as plain text
The core insight: SharePoint Stream uses virtual scrolling in its transcript panel — DOM nodes are recycled as you scroll. Simple querySelectorAll only captures the currently visible 20-30 items. This skill connects via Chrome DevTools Protocol (CDP) to run JavaScript that scrolls, extracts, and accumulatessimultaneously — getting every entry regardless of DOM recycling.
# Clone into your skills directory
mkdir -p ~/.claude/skills
git clone https://github.com/stanley6635/teams-transcript-extractor.git ~/.claude/skills/teams-transcript-extractorFor OpenCode: clone into your opencode skills directory.
- Node.js 21+ — for native
WebSocketsupport (zero npm dependencies) - Chrome — with remote debugging enabled
Option A: Use bb-browser (recommended)
If you have bb-browser installed, it handles Chrome profile management and authentication automatically.
Option B: Launch Chrome manually
# macOS
open -a "Google Chrome" --args --remote-debugging-port=9222
# Linux
google-chrome --remote-debugging-port=9222
# Windows
"C:\Program Files\Google\Chrome\Application\chrome.exe" --remote-debugging-port=9222Open your SharePoint/OneDrive in that Chrome window and log in. The session persists for future extractions.
Just paste a Teams recording URL and ask:
"Extract the transcript from this meeting: https://hoyagw-my.sharepoint.com/..."
The skill auto-detects, auto-recovers from OAuth issues, and handles everything.
# Find the tab ID first
curl -s http://localhost:9222/json/list | python3 -c "import json,sys;[print(t['id'],t['title']) for t in json.load(sys.stdin)]"
# Extract transcript
node extract.js --port 9222 --tab-id <tab-id> --output transcript.txt| Problem | Solution |
|---|---|
| Stream player not loading (OAuth expired) | Detects unhealthy page → navigates to SharePoint home → triggers OAuth flow → returns to video |
| Virtual scrolling truncates copy-paste | CDP chunked scroll + Set dedup captures all entries |
| No download permission | Extracts via DOM instead of file download API |
| Encrypted transcript API response | Bypasses API entirely, reads rendered UI |
| Different screen sizes / zoom levels | Scrolls by pixel height, adapts to any viewport |
This skill has been tested and works on:
| Meeting | Duration | Language | Entries | Chars |
|---|---|---|---|---|
| HSO Pulse Live Q&A | ~60 min | English | 474 | 57,449 |
| 新入职同事产品培训安排 | ~87 min | Chinese | 331 | 27,227 |
Both used the same DOM structure ([role="list"] + [role="listitem"]), confirming cross-region consistency.
- SharesPoint Stream UI changes — If Microsoft changes the transcript panel's DOM structure, selectors may need updating. Tested working as of June 2026.
- Requires Chrome — Uses Chrome DevTools Protocol; won't work with Firefox/Safari.
- Login required — You must log into Microsoft 365 once per Chrome session. MFA is supported.
- Not for CI/CD — This is a desktop automation tool, not a headless API. It runs in your local Chrome with your login session.
Found a case where it doesn't work? Open an issue with:
- The URL (if you can share) or a description of the page structure
- The browser console output
- Any error messages
DOM structure changes are the most likely breakage — if you notice the transcript panel looks different after a Microsoft update, check if the selectors in extract.js still match.
MIT