v2026.1 Open Portal ↗
On this page

Microsoft Teams Integration

Prerequisites

RequirementDetails
Microsoft 365 tenantTeams admin or Global admin role
Azure subscriptionApp registration permissions
StackFlow rolesuper_admin
Teams channelDedicated IT Incidents channel recommended

Step 1: Register a Bot in Azure

  1. Open the Azure Portal and go to Azure Bot Services → Create
  2. Set the bot handle to StackFlowBot and select Multi Tenant for the Microsoft App Type
  3. Create a new App registration with the bot — note the App ID and create a Client Secret
  4. Under Configuration → Messaging endpoint, set: https://your-instance.stackflow-tech.com/prod/api/webhooks/teams/bot
  5. Under Channels, enable the Microsoft Teams channel
Tenant ID: The StackFlow Azure tenant ID is df4d171f-6cca-4c87-84cd-f299e4fca3a9. When registering for multi-tenant use, you can configure the bot to work with any Teams tenant that installs it.

Step 2: Configure Incoming Webhook

  1. In Microsoft Teams, open the target channel and click ⋯ → Connectors
  2. Find Incoming Webhook and click Configure
  3. Name it StackFlow Alerts and upload the StackFlow logo
  4. Click Create and copy the generated webhook URL
# The Teams webhook URL format:
https://your-org.webhook.office.com/webhookb2/GUID/IncomingWebhook/HASH/GUID

Step 3: Connect in StackFlow

  1. Navigate to Admin → Integration Hub → Microsoft Teams → Configure
  2. Enter the Bot App ID and Client Secret from the Azure Bot registration
  3. Enter the Incoming Webhook URL for each priority channel
  4. Enter the Azure Tenant ID: df4d171f-6cca-4c87-84cd-f299e4fca3a9
  5. Click Save & Test

Adaptive Cards for Approvals

StackFlow sends Adaptive Cards to Teams for change and request approvals. The card includes action buttons that invoke the StackFlow API directly:

{
  "$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
  "type": "AdaptiveCard",
  "version": "1.4",
  "body": [
    {"type": "TextBlock", "size": "Large", "weight": "Bolder", "text": "Change Request Approval Required"},
    {"type": "FactSet", "facts": [
      {"title": "Change ID:", "value": "{{change.id}}"},
      {"title": "Description:", "value": "{{change.short_description}}"},
      {"title": "Risk:", "value": "{{change.risk}}"},
      {"title": "Scheduled:", "value": "{{change.scheduled_start}}"}
    ]}
  ],
  "actions": [
    {"type": "Action.Http", "title": "Approve", "method": "POST",
     "url": "https://your-instance.stackflow-tech.com/prod/api/changes/{{change.id}}/approve",
     "headers": [{"name": "Authorization", "value": "Bearer {{teams_bot_token}}"}]},
    {"type": "Action.Http", "title": "Reject", "method": "POST",
     "url": "https://your-instance.stackflow-tech.com/prod/api/changes/{{change.id}}/reject",
     "headers": [{"name": "Authorization", "value": "Bearer {{teams_bot_token}}"}]}
  ]
}

Field Reference

FieldRequiredDescription
Bot App IDYesAzure Bot Application (client) ID
Client SecretYesAzure App Registration client secret
Tenant IDYesAzure AD tenant ID
Incident Webhook URLYesTeams Incoming Webhook for incident notifications
Approval Webhook URLNoSeparate channel for approval requests
Notify on P1/P2 onlyNoLimit Teams noise to high-priority incidents (default: false)

Testing the Integration

  1. Go to Admin → Integration Hub → Microsoft Teams → Test
  2. Click Send Test Card — an Adaptive Card should appear in your Teams channel within 15 seconds
  3. Create a P1 incident and verify the Teams notification is received
  4. Submit a change request and verify the approval card appears in the approver's Teams DM

Troubleshooting

IssueCauseFix
Webhook returns 429Teams rate-limiting (> 4 req/s per webhook)StackFlow queues messages; check SQS queue depth in CloudWatch
Card not renderingAdaptive Card schema version mismatchEnsure Teams client is updated; try "version": "1.2" for older clients
Action buttons failBot token expiredClient credentials tokens expire after 1 hour; StackFlow auto-refreshes, check Lambda logs
Bot not receiving messagesMessaging endpoint not verifiedEnsure the bot endpoint returns 200 with valid JSON within 5 seconds