Skip to content

ACS Call Automation playToAll silent in Teams Online Meeting (CallConnected + PlayCompleted, list_participants=0) #598

Description

@cunddtech

Microsoft Azure Support Ticket — Teams Bidirectional Media (Voice + Live Avatar)

Stand: 2026-06-30
Sprache Ticket: Englisch (Copy-Paste unten)
Portal: Azure Portal → Help + support → Create a support request
Schritt-für-Schritt (Deutsch): MICROSOFT_SUPPORT_TICKET_PORTAL_WALKTHROUGH_2026-06-30.md
Issue type: Technical → Azure Communication Services (primary) + cross-reference Microsoft Teams / Graph Cloud Communications


Kurz (Deutsch, intern)

Wir bauen STELLA — einen KI-Copilot für Teams-Meetings mit bidirektionaler Kommunikation:

Phase Ziel
1 — Voice only STELLA spricht hörbar in der Meeting-Leitung (TTS), hört Teilnehmer (STT), antwortet intelligent
2 — Voice + Video Live-Avatar (Runway) als sichtbare Kachel im Meeting-Grid, synchron zu Audio

Blocker: ACS Call Automation (playToAll) meldet CallConnected + PlayCompleted, aber list_participants=0kein hörbares Audio (Ghost Leg). Das bleibt bestehen auch nach native onlineMeetings-Erstellung + Application Access Policy.

Bitte an Microsoft: Empfohlener Architekturpfad für produktionsreife Bot-Media in Teams (Audio rein/raus, später Video) — ACS vs Application-hosted Media vs andere.


Copy-Paste: Support Request (English)

Title

ACS Call Automation playToAll silent in Teams Online Meeting (PlayCompleted, participants=0) — guidance for bidirectional voice + live avatar video

Problem description

We are building STELLA, a multi-tenant AI meeting copilot integrated with Microsoft Teams. Our production stack uses:

  • Azure Communication Services (ACS) resource: cdtech-communication (region: Europe)
  • Microsoft 365 tenant: fe87c2f4-700c-4a68-9bd7-218fde87a857 (C&D Technologies GmbH)
  • Organizer UPN: mj@ilovestella.de (also mj@cdtechnologies.de)
  • Backend: Python/FastAPI on Azure Railway (https://api.cdtechnologies.de)
  • Teams Graph App (application permissions): Client ID 4b1d32ba-6c39-4a0b-b320-31981ce0654b (GRAPH_CLIENT_ID_TEAMS)

We need guidance on the correct Microsoft-recommended architecture for:

  1. Outbound audio (Phase 1): Bot TTS audible to all meeting participants (not operator-only Sidecar/browser audio).
  2. Inbound audio (Phase 1): Bot receives participant speech for STT / conversational AI (bidirectional voice).
  3. Outbound video (Phase 2): Live AI avatar (H.264) as a visible participant tile in the Teams meeting grid, lip-synced to TTS.
  4. Scalable multi-tenant SaaS: Each customer uses their own M365 tenant; we orchestrate via delegated/app permissions and tenant-specific organizer mailboxes.

Current architecture (what we built)

┌─────────────────────────────────────────────────────────────────────────────┐
│ STELLA Backend (Railway, Linux, Python)                                      │
│  • Meeting create: Graph POST /users/{org}/onlineMeetings (native)           │
│  • Copilot session, TTS (Azure Speech de-DE-KatjaNeural → WAV)               │
│  • ACS Call Automation: connect_call(groupCallId) + playToAll(audioUrl)    │
│  • Callbacks: POST /api/teams/copilot-acs-media/events                       │
│  • Bot Framework: meeting chat text (works)                                    │
│  • Sidecar UI: browser STT chunks → backend (works, not meeting-wide)        │
└───────────────┬───────────────────────────────┬─────────────────────────────┘
                │ HTTPS                          │ Graph / Bot Framework
                ▼                                ▼
┌───────────────────────────┐    ┌────────────────────────────────────────────┐
│ ACS (cdtech-communication)│    │ Teams Online Meeting                        │
│ Call Automation API       │───▶│ groupCall / thread v2                       │
│ (invisible bot leg)       │    │ Human participants + meeting chat           │
└───────────────────────────┘    └────────────────────────────────────────────┘

Optional (scaffold, Windows VM — not production-ready):
┌─────────────────────────────────────────────────────────────────────────────┐
│ teams-media-bot (.NET 8, Azure Windows VM)                                   │
│  • Target: Microsoft.Graph.Communications.Calls.Media (Application-hosted)   │
│  • StellaBridge HTTP: push PCM + H.264 frames                                │
│  • Today: ACS relay fallback only; GraphCommunicationsService = deferred     │
│  • URL: https://teams-media-bot.cdtechnologies.de (health often timeout)     │
└─────────────────────────────────────────────────────────────────────────────┘

Live avatar source (Phase 2):
┌─────────────────────────────────────────────────────────────────────────────┐
│ Runway Live API → WebRTC/video frames → transcode → Media Bot VideoSocket    │
│ (Sidecar bridge today: operator-only video; not in Teams grid)               │
└─────────────────────────────────────────────────────────────────────────────┘

Separate channels (important):

Channel Technology Status
Meeting chat (text, @mentions) Bot Framework + Graph ✅ Works
Meeting audio broadcast (TTS to all) ACS playToAll ❌ Ghost Leg — silent
Operator Sidecar TTS Browser audio ✅ Operator hears only
Transcript post-meeting Graph onlineMeeting transcript ✅ (after meeting ends)
Live STT from all participants Not implemented ❌ Need inbound media path
Visible avatar tile Graph Application-hosted media (planned) ❌ Not wired

Symptom (Ghost Leg)

When joining a native Teams online meeting (created via Graph onlineMeetings, not calendar fallback):

  • ACS connect_call succeeds; webhook CallConnected received.
  • ACS playToAll with publicly reachable HTTPS WAV URL succeeds; webhook PlayCompleted received.
  • ACS list_participants returns count=0 consistently after connect.
  • No audible media in Teams client for human participants.
  • Sidecar/browser TTS works for operator only (not acceptable for product).

Application Access Policy (Teams PowerShell) already applied:

  • Policy: Tag:STELLA-Graph-OnlineMeetings → AppId 4b1d32ba-6c39-4a0b-b320-31981ce0654b
  • Granted to: mj@ilovestella.de, mj@cdtechnologies.de, mc@ilovestella.de
  • Meeting create returns _source: onlineMeetings (MS… meeting ID) — Ghost Leg persists.

Reproduction evidence (2026-06-30, Policy Test)

Field Value
Meeting subject STELLA onlineMeetings Policy Test 2026-06-30
onlineMeeting ID MSplYzJiODRlNy01MTJlLTQyMzUtOTYzYi01YjJlOTA0MjNhNmMqMCoqMTk6bWVldGluZ19OalpqTkdVek5HVXROVEkxT1MwMFlXRTVMVGt3Wm1FdE1HSTFNbUZpWlRZek1HRTFAdGhyZWFkLnYy
groupCallId (thread) 66c4e34e-5259-4aa9-90fa-0b52abe630a5
ACS call_connection_id 6d003a80-a129-48b2-a1ec-22e979b71feb
Join URL thread 19:meeting_NjZjNGUzNGUtNTI1OS00YWE5LTkwZmEtMGI1MmFiZTYzMGE1@thread.v2
Callback URL https://api.cdtechnologies.de/api/teams/copilot-acs-media/events
Backend flags TEAMS_COPILOT_AUDIO_PREFER_RAILWAY_ACS=true, Runway broadcast off
Human in call Yes (Teams desktop, mic bar active, second machine)
Result PlayCompleted, no audible output in meeting

Earlier retest (calendar fallback, same symptom):

  • groupCallId: e6613890-2b4e-4b2d-80b9-1b716e146e36
  • ACS call: 1e003a80-2f9a-4348-a143-3b8206013c61

Graph / Entra permissions (Teams app 4b1d32ba…)

Application permissions (admin consented), including:

  • Calls.JoinGroupCall.All, Calls.InitiateGroupCall.All
  • OnlineMeetings.ReadWrite.All, OnlineMeetings.Read.All
  • Calendars.ReadWrite, Calendars.Read
  • Chat.ReadWrite.All, TeamsAppInstallation.ReadWriteForChat.All (auto-install still 403 without Consent variant)
  • User.Read.All, CallRecords.Read.All, etc.

Bot Framework app (separate registration) handles /api/teams/bot/messages — chat works; does not provide meeting media.


What we need from Microsoft

Please advise on the recommended production path for our goals:

A) Outbound meeting audio (Phase 1 — voice only)

  1. Is ACS Call Automation playToAll into Teams native online meetings a supported scenario? If yes, why would list_participants=0 + silent audio occur despite CallConnected/PlayCompleted?
  2. Should we use Graph Cloud Communications / Application-hosted media bot instead (Windows VM + Calls.AccessMedia.All + media platform certificate)?
  3. Is there a service-hosted media bot or Teams Real-time API path that avoids Windows VM ops but still delivers audible mixed audio?
  4. Any tenant-level enablement required beyond Application Access Policy (e.g. Cloud Communications error 7504, policy flags)?

B) Inbound audio — bidirectional voice (Phase 1)

  1. How should a bot receive participant audio for STT in a Teams meeting?
    • Graph AudioSocket / subscribed media?
    • ACS receive path?
    • Teams transcription API (too high latency for live dialog)?
  2. Minimum architecture for full-duplex voice (human speaks → bot hears → bot responds with TTS in meeting)?

C) Outbound video — live avatar (Phase 2)

  1. Recommended approach to inject live H.264 video (AI avatar, ~25 fps) as a visible meeting participant:
    • Application-hosted media only?
    • Can ACS carry video into Teams grid or audio-only?
  2. Can audio and video use the same Graph call leg, or must they be separate?
  3. Licensing / SKU requirements (Teams Premium, Copilot, etc.)?

D) Multi-tenant SaaS

  1. For customer tenants (not our own): recommended onboarding — Application Access Policy per tenant, consent model, hosted vs customer-deployed media bot?
  2. Any certification or Teams store requirements for a copilot with media injection?

Alternatives we are evaluating (please comment)

Option Our understanding Question for Microsoft
ACS Call Automation Simple HTTP, Linux-friendly; current Ghost Leg Supported for Teams meetings? Fix for participants=0?
Application-hosted Media Bot Windows VM, Graph Communications SDK, AudioSocket/VideoSocket Is this the only supported path for grid video + reliable audio?
Service-hosted media bot Microsoft hosts media stack Available for our scenario / tenant size?
Teams RTMP / live events Not interactive meeting Not suitable — need 2-way
Screen share / computer sound Operator workaround only Not productizable
Azure OpenAI Realtime + ACS Voice AI patterns Overlap with Teams meeting join?

Business context

  • Product: STELLA — AI copilot for regulated industries (energy consulting, sales meetings).
  • Use case: AI assistant joins customer Teams meetings, introduces itself (ISB compliance script), answers questions audibly, later with live avatar.
  • Requirement: Bidirectional communication; voice-first MVP, video avatar second phase.
  • Scale: Multi-tenant; each customer brings their own M365 tenant.

Severity / impact

  • Severity: High — blocks core product capability (audible AI in Teams meetings).
  • Workaround: Operator shares "computer sound" from browser Sidecar — not acceptable for customers.

Attachments / logs we can provide on request

  • ACS webhook event sequence (CallConnected, PlayCompleted timestamps)
  • Redacted Railway logs for call_connection_id above
  • Graph meeting create response (onlineMeetings)
  • Architecture ADR: docs/architecture/TEAMS_LIVE_AVATAR_MEDIA_BOT_DECISION_2026-06.md (private repo — summary included above)

Contact

  • Primary: Markus Jaszczyk — mj@ilovestella.de / mj@cdtechnologies.de
  • Organization: C&D Technologies GmbH
  • Tenant ID: fe87c2f4-700c-4a68-9bd7-218fde87a857

Nach dem Absenden

  1. Correlation IDs aus Azure Portal notieren und in docs/ops/TEAMS_ACS_GHOST_LEG_INCIDENT_2026-06-30.md ergänzen.
  2. Antwort mit Architektur-Empfehlung → ADR aktualisieren + P1 Media Bot Scope anpassen.
  3. Falls 7504 / tenant enablement nötig: separates Enablement-Ticket referenzieren.

Verwandte interne Docs

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions