Sending a card to Teams when an incident opens is a half-day project. Letting a major incident commander acknowledge, page additional responders, and attach a postmortem link all from Teams is a six-week project. Most teams ship the easy half and pretend the hard half does not exist.
What a two-way integration actually requires
Three durable bindings:
- Conversation-to-record — a Teams channel or Slack channel mapped to a
incidentrecord, persisted across both systems - Identity — a way to resolve the chat user to the platform user without re-auth on every message
- Adaptive surface — interactive cards that round-trip state changes
Fail at any of these and you have notifications, not collaboration.
The conversation binding
In Teams, the binding lives in the channel’s extensionContext. In Slack, it is the channel ID stored on the record. Use a dedicated table:
Table: u_chat_conversation_link
Columns:
source_table (incident, change_request, etc)
source_sys_id
platform (teams | slack)
channel_id (string)
team_or_workspace_id (string)
created_by_chat_user (string)
This table is your single source of truth for “where is the live conversation about this record.”
Identity: cache the mapping
Do not call Graph API or Slack users.lookupByEmail on every message. Cache email-to-platform-user mappings in u_chat_user_map with a 30-day TTL. Refresh on cache miss.
Adaptive cards round-tripping
For Teams, build the card with Action.Submit payloads that include the source table and sys_id. Your bot endpoint validates the payload, applies the change, and replies with a refresh.
Card Action: acknowledge_major
Payload:
table: incident
sys_id: <id>
user: <teams_user_id>
action: ack
The receiving Script Include validates the user has the major_incident_manager role on the platform and updates the record.
What breaks at scale
- Channel proliferation: every P3 incident creates a channel, the workspace fills up. Rule: only P1 and P2 get a dedicated channel, lower priorities use a shared support channel.
- Token expiry: bot tokens expire silently. Monitor
mid_serverintegration logs and alert on auth errors. - Attachment size: Slack rejects attachments above 1GB. Build a graceful link-out fallback.
What to do this week
Audit your existing chat integration. Confirm the conversation-link table exists and is populated. If you are still relying on channel name parsing to find the record, that is your refactor target this sprint.