Teams Integration

Microsoft Teams is R1’s operator-facing notification surface: user feedback, deploy changelogs, and security digests all land in Teams channels. The architecture is a hybrid: outbound posts go through Power Automate webhooks (Adaptive Cards over HTTP POST), reading messages uses the Microsoft Graph API, and in-thread replies go through the Azure Bot Framework. Webhook/Graph/Bot client code lives in-repo; the Power Automate flows, Azure Bot registration, and Entra app setup are external infrastructure.

Channels and Webhooks

Env varPurposeTrigger
TEAMS_SUPPORT_WEBHOOK_URLManual user reports (bug, idea, confusing UI)Runtime, POST /api/feedback/report
TEAMS_AUTOMATED_WEBHOOK_URLAuto-detected friction (rage clicks, slow API, slow LCP, JS errors, error screens)Runtime, POST /api/feedback/auto
TEAMS_UPDATES_WEBHOOK_URLChangelog digest to the Updates channelpromote-image.yml on staging/production promotion
TEAMS_SECURITY_WEBHOOK_URLWeekly security-scan digestsecurity-scan-scheduled.yml, Mondays 08:00 UTC

Runtime Feedback Posting

backend/src/services/feedback/feedback-service.ts builds Adaptive Cards (buildReportCard() / buildAutoCard(): color-coded category containers, FactSet context, optional screenshot, Sentry links) and POSTs them via postToWebhook() — 10-second timeout, fire-and-forget: failures are logged, never thrown, and the API always answers 202. Screenshots (≤2 MB base64) are stored in object storage with a 30-day presigned URL. Routes: backend/src/routes/feedback.ts. Details on the product side: Feedback System.

Changelog Digest (28 KB Cap)

scripts/compile-changelog.sh posts an Adaptive Card titled with environment, timestamp, and SHA, containing the bilingual changelog fragments. Invoked by .github/workflows/promote-image.yml on staging/production promotions (added in PR#1331).

Teams Workflows hard-limits card payloads at ~28 KB. The script enforces MAX_PAYLOAD_BYTES=20480 (8 KB headroom); oversized digests degrade to a summary card linking to the GitHub compare view and Actions run instead of being silently dropped (PR#1746). Caveat the script documents: Teams returns HTTP 202 for accepted, not delivered — async processing can still fail.

Weekly Security Digest

The weekly-digest job in .github/workflows/security-scan-scheduled.yml runs on cron 0 8 * * 1 (skipped on the daily scan trigger) and executes scripts/security-scan-reconcile/digest.ts: open security tracking issues, overdue count (>60 days, security:overdue), breakdowns by severity and scanner, top-5 oldest issues with links. See Security Scanning for the underlying two-track scan policy.

Adaptive Cards

All posts use application/vnd.microsoft.card.adaptive, schema version 1.4. Builders live in three places: the backend feedback service, compile-changelog.sh (build_card_json()), and the MCP sender (tools/teams-feedback-mcp/src/teams-sender.ts). The MCP side also parses received cards (tools/teams-feedback-mcp/src/adaptive-card.ts extracts title, facts, image URLs, Sentry replay links) for triage.

Read/Reply Hybrid — teams-feedback MCP

tools/teams-feedback-mcp/ is an MCP server used for feedback triage sessions:

  • Read (Graph API): lists recent support-channel messages and fetches hosted attachments via graph-client.ts (OAuth2 client credentials, graph.microsoft.com/.default scope). Tools: list-support-messages, get-message-attachments.
  • Reply (Bot Framework): in-thread replies via teams-sender.ts posting to the Bot Framework conversations API (api.botframework.com/.default scope), with <at> mention support. Tool: reply-to-message.
  • Post (webhook): new channel posts go through the Power Automate webhooks, same as everything else. Tool: post-update.

Configuration: TEAMS_BOT_CLIENT_ID / TEAMS_BOT_CLIENT_SECRET / TEAMS_BOT_TENANT_ID (Entra app), TEAMS_TEAM_ID, TEAMS_SUPPORT_CHANNEL_ID, TEAMS_UPDATES_CHANNEL_ID, TEAMS_BOT_SERVICE_URL. A standalone debug poller exists at scripts/teams-graph-poll.ts (PR#1737). Card payload surfacing in the MCP: PR#1536.

In-Repo vs External

In-repoExternal (Azure/M365)
Webhook posting (backend feedback, changelog script, security digest)Power Automate flows behind the webhook URLs
teams-feedback MCP server (Graph read, Bot reply)Azure Bot registration + service endpoint
Adaptive Card builders and parserEntra tenant / Azure AD app configuration

There is no Bot Framework SDK dependency — the MCP talks to Graph and Bot Framework REST endpoints directly.

See Also