Skip to content

Microsoft Teams Integration

Integrate TruthVouch with Microsoft Teams to deliver governance alerts, run verification queries, and manage AI policies directly from Teams. Use Adaptive Cards for rich formatting and interactive workflows.

Setup

1. Register Azure App

In Azure Portal:

  1. Go to Azure Active Directory → App registrations
  2. Click “New registration”
  3. Name: “TruthVouch”
  4. Supported account types: “Accounts in this organizational directory”
  5. Redirect URI: https://api.truthvouch.com/auth/callback

2. Configure Permissions

Add these Microsoft Graph permissions:

  • Chat.Send
  • ChannelMessage.Send
  • Team.ReadBasic.All
  • User.Read

3. Create Client Secret

  • Go to Certificates & secrets
  • Create new client secret
  • Copy value (store securely)

4. Configure TruthVouch

Terminal window
truthvouch config teams \
--tenant-id your-tenant-id \
--client-id your-client-id \
--client-secret your-client-secret

Alert Notifications

Send Adaptive Card

from truthvouch.integrations.teams import TeamsAlertHandler
import json
handler = TeamsAlertHandler(
client_id="your-client-id",
client_secret="your-client-secret",
tenant_id="your-tenant-id"
)
# Define card template
card = {
"type": "message",
"attachments": [
{
"contentType": "application/vnd.microsoft.card.adaptive",
"contentUrl": None,
"content": {
"$schema": "http://adaptivecards.io/schemas/adaptive-card.json",
"type": "AdaptiveCard",
"version": "1.4",
"body": [
{
"type": "Container",
"items": [
{
"type": "ColumnSet",
"columns": [
{
"width": "auto",
"items": [
{
"type": "Image",
"url": "https://truthvouch.com/logo.svg",
"size": "Small"
}
]
},
{
"width": "stretch",
"items": [
{
"type": "TextBlock",
"text": "TruthVouch Alert",
"weight": "Bolder",
"size": "Large"
}
]
}
]
}
]
},
{
"type": "Container",
"style": "Emphasis",
"items": [
{
"type": "TextBlock",
"text": "Hallucination Detected",
"weight": "Bolder",
"color": "Attention"
}
]
},
{
"type": "Container",
"items": [
{
"type": "FactSet",
"facts": [
{
"name": "Query:",
"value": "Is the Earth flat?"
},
{
"name": "Response:",
"value": "Yes, the Earth is flat"
},
{
"name": "Confidence:",
"value": "5% (CRITICAL)"
},
{
"name": "Category:",
"value": "Science"
}
]
}
]
}
],
"actions": [
{
"type": "Action.OpenUrl",
"title": "View in Dashboard",
"url": "https://dashboard.truthvouch.com/alerts/alert123"
},
{
"type": "Action.Submit",
"title": "Acknowledge",
"data": {"action": "acknowledge"}
},
{
"type": "Action.Submit",
"title": "Suppress Rule",
"data": {"action": "suppress"}
}
]
}
}
]
}
# Send to Teams channel
handler.send_to_channel(
team_id="team-id",
channel_id="channel-id",
card=card
)

Configure Alert Rules

# Route alerts to specific channels
handler.configure_alert_rule(
name="Critical Hallucinations",
trigger="confidence < 0.5",
teams=[
{
"team_id": "team-abc123",
"channel_id": "general",
"mention": "@on-call"
}
],
enabled=True
)
# Route by category
handler.configure_alert_rule(
name="Healthcare Alerts",
trigger="category = 'healthcare' AND confidence < 0.9",
teams=[
{
"team_id": "team-abc123",
"channel_id": "compliance",
"mention": "@compliance-team"
}
],
enabled=True
)

Proactive Messages

Send notifications via Teams bot:

# Send to individual user
handler.send_to_user(
user_id="user-id",
message="Your verification result is ready: 85% confidence"
)
# Send to chat thread
handler.send_to_chat(
chat_id="chat-id",
message="Waiting for your review..."
)

Message Extensions

Enable TruthVouch as a Teams message extension:

from flask import Flask, request
app = Flask(__name__)
@app.route("/teams/invoke", methods=["POST"])
def handle_message_extension():
"""Handle Teams message extension invoke."""
payload = request.get_json()
if payload["type"] == "composeExtension/fetchTask":
# Return task module for verification UI
return {
"task": {
"type": "continue",
"value": {
"title": "Verify Content",
"height": 500,
"width": 600,
"url": "https://app.truthvouch.com/teams/verify"
}
}
}
elif payload["type"] == "composeExtension/submitAction":
# Process verification submission
text = payload["data"]["text"]
result = tv_client.verify_fact(text=text)
# Return results
return {
"composeExtension": {
"type": "result",
"attachmentLayout": "list",
"attachments": [
{
"contentType": "application/vnd.microsoft.teams.card.o365connector",
"contentUrl": None,
"content": {
"@type": "MessageCard",
"@context": "https://schema.org/extensions",
"summary": f"Verification: {result.confidence:.0%}",
"themeColor": "0078D7",
"sections": [
{
"activityTitle": "Verification Result",
"facts": [
{
"name": "Confidence",
"value": f"{result.confidence:.0%}"
}
]
}
]
}
}
]
}
}

Webhooks

Set up Teams webhook for incoming notifications:

from truthvouch.integrations.teams import TeamsWebhookHandler
# Get webhook URL from Teams
webhook_url = "https://outlook.webhook.office.com/webhookb2/..."
handler = TeamsWebhookHandler(webhook_url=webhook_url)
# Send JSON payload
alert = {
"type": "message",
"attachments": [{
"contentType": "application/vnd.microsoft.card.adaptive",
"content": {
"type": "AdaptiveCard",
"version": "1.4",
"body": [{
"type": "TextBlock",
"text": "Alert received",
"weight": "Bolder"
}]
}
}]
}
handler.send(alert)

Interactive Forms

Create verification workflows:

@app.route("/teams/task", methods=["POST"])
def render_task():
"""Render interactive form for content verification."""
return {
"task": {
"type": "continue",
"value": {
"title": "Verify Content",
"height": 500,
"width": 600,
"card": {
"contentType": "application/vnd.microsoft.card.adaptive",
"content": {
"type": "AdaptiveCard",
"version": "1.4",
"body": [
{
"type": "TextBlock",
"text": "Submit content for verification",
"weight": "Bolder"
},
{
"type": "Input.Text",
"id": "content",
"placeholder": "Enter claim to verify...",
"isMultiline": True
},
{
"type": "Input.ChoiceSet",
"id": "category",
"label": "Category",
"choices": [
{"title": "General", "value": "general"},
{"title": "Healthcare", "value": "healthcare"},
{"title": "Financial", "value": "financial"}
]
}
],
"actions": [
{
"type": "Action.Submit",
"title": "Verify"
}
]
}
}
}
}
}

Best Practices

Formatting

  • Use Adaptive Cards for rich formatting
  • Include facts for quick scanning
  • Add action buttons for common operations
  • Use color to indicate severity

Notifications

  • Route critical alerts to on-call channel
  • Use @mentions sparingly (avoid fatigue)
  • Group related alerts in threads
  • Include deep links to dashboard

Rate Limiting

  • Respect Teams rate limits (50 req/min)
  • Batch multiple alerts
  • Implement backoff for retries

Troubleshooting

Q: Cards not rendering properly

  • Validate schema against Adaptive Card spec
  • Check Teams client version
  • Use schema validator tool

Q: Mentions not working

  • Verify bot has permission to mention
  • Check user ID format
  • Ensure user is in channel

Q: Webhook delivery failing

  • Verify webhook URL is valid and active
  • Check payload format
  • Implement retry logic with backoff

Next Steps