OneApp Docs
PackagesIntegrations

Microsoft Teams Integration

Enterprise-grade Microsoft Teams integration for OneApp — bot messaging, embedded tab apps, real-time notifications, meeting briefs, and cross-platform activity tracking.

Quick Start

Already familiar with Teams apps? Skip to Quick Start →

Why Teams integration?

Without Teams integration:

  • Context switching — Users leave Teams to access OneApp, lose workflow momentum
  • Manual updates — Copy-paste information between Teams and OneApp
  • Missed notifications — Important canvas updates lost in email or separate apps
  • Meeting prep burden — Manually gather context before meetings
  • Disconnected activity — No visibility into cross-platform usage

Teams integration solves this with embedded canvas access, bot-powered messaging, real-time notifications, pre-meeting briefs, and unified activity tracking.

Production-ready with Azure AD SSO, Adaptive Cards v1.4, Graph API integration, Server-Sent Events for real-time updates, and comprehensive error handling.

Use cases

  • In-Teams canvas access — View and interact with canvases without leaving Teams
  • Bot conversations — Ask questions, get insights, run reports via Teams chat
  • Real-time notifications — Instant alerts for mentions, approvals, canvas updates
  • Meeting integration — Pre-meeting briefs with relevant canvases, post-meeting summaries
  • Activity tracking — Unified view of user activity across Teams and web
  • Channel integration — Link Teams channels to canvases for team collaboration

Architecture overview

┌─────────────────────────────────────────────────────────────────┐
│                     Microsoft Teams                              │
├─────────────────────────────────────────────────────────────────┤
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────────────┐   │
│  │   Bot App    │  │   Tab App    │  │ Meeting Side Panel   │   │
│  │  (Messages)  │  │ (Dashboard)  │  │  (Briefs/Notes)      │   │
│  └──────┬───────┘  └──────┬───────┘  └──────────┬───────────┘   │
└─────────┼─────────────────┼─────────────────────┼───────────────┘
          │                 │                     │
          ▼                 ▼                     ▼
┌─────────────────────────────────────────────────────────────────┐
│                      OneApp Backend                              │
├─────────────────────────────────────────────────────────────────┤
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────────────┐   │
│  │  /api/teams  │  │ /teams-tab   │  │ /api/teams/meetings  │   │
│  │   webhooks   │  │   pages      │  │    integration       │   │
│  └──────┬───────┘  └──────┬───────┘  └──────────┬───────────┘   │
│         │                 │                     │               │
│         ▼                 ▼                     ▼               │
│  ┌─────────────────────────────────────────────────────────┐    │
│  │                   Teams Service Layer                    │    │
│  │  ┌────────────┐ ┌────────────┐ ┌────────────────────┐   │    │
│  │  │ Graph API  │ │ Bot SDK    │ │ Notifications SSE  │   │    │
│  │  │  Client    │ │ Handler    │ │ Service            │   │    │
│  │  └────────────┘ └────────────┘ └────────────────────┘   │    │
│  └─────────────────────────────────────────────────────────┘    │
└─────────────────────────────────────────────────────────────────┘

Prerequisites

Before setting up Teams integration, ensure you have:

Bot Framework Deprecation

Microsoft Bot Framework SDK support ends December 31, 2025. New Teams apps should use the Teams AI v2 SDK. Plan migration from Bot Framework to Teams AI v2.

Azure AD App Registration

  1. Azure Portal access with Application Administrator role
  2. App Registration with the following API permissions:
    • User.Read — Basic user profile
    • Channel.ReadBasic.All — Read channel info
    • ChannelMessage.Send — Send messages to channels
    • Team.ReadBasic.All — Read team info
    • TeamsTab.ReadWrite.All — Manage tabs
    • OnlineMeetings.Read — Read meeting info

Teams Admin Center

  1. Teams admin access to upload custom apps
  2. Custom app policy allowing sideloaded apps (for development)
  3. App catalog access for organization-wide deployment

Environment Variables

# Azure AD Configuration
AZURE_AD_CLIENT_ID=your-client-id
AZURE_AD_CLIENT_SECRET=your-client-secret
AZURE_AD_TENANT_ID=your-tenant-id

# Teams Bot Configuration
TEAMS_BOT_ID=your-bot-id
TEAMS_BOT_PASSWORD=your-bot-password

# App URLs
NEXT_PUBLIC_APP_URL=https://oneapp.onedigital.com
TEAMS_WEBHOOK_URL=https://oneapp.onedigital.com/api/integrations/teams/webhooks

Quick Start

1. Install dependencies

# Teams SDK and Graph API client
pnpm --filter=oneapp-onstage add @microsoft/teams-js @microsoft/microsoft-graph-client

# Bot Framework (if not installed)
pnpm --filter=oneapp-onstage add botbuilder

2. Configure environment

Create or update .env.local:

.env.local
AZURE_AD_CLIENT_ID=your-azure-ad-client-id
AZURE_AD_CLIENT_SECRET=your-azure-ad-client-secret
AZURE_AD_TENANT_ID=your-azure-ad-tenant-id
TEAMS_BOT_ID=your-teams-bot-id
TEAMS_BOT_PASSWORD=your-teams-bot-password

3. Deploy Teams manifest

# Navigate to Teams app directory
cd platform/apps/oneapp-onstage/teams-app

# Update manifest.json with your app IDs
# Then create the app package
zip -r oneapp-teams.zip manifest.json icon-color.png icon-outline.png

# Upload to Teams Admin Center or sideload for testing

4. Test the integration

  1. Open Microsoft Teams
  2. Search for "OneApp" in the app catalog
  3. Install the app to a team or personal scope
  4. Start a conversation with the bot

Features

Bot Messaging

The Teams bot enables natural language interaction with OneApp canvases.

lib/teams/bot-handler.ts
import { handleTeamsMessage } from "#/lib/teams";

// Bot receives message and processes it
const response = await handleTeamsMessage({
  userId: activity.from.id,
  text: activity.text,
  conversationId: activity.conversation.id
});

// Send response as Adaptive Card
await context.sendActivity({
  attachments: [CardFactory.adaptiveCard(response.card)]
});

Supported commands:

  • Ask questions about canvas content
  • Request insights and reports
  • Get canvas summaries
  • Search across canvases

Tab App

Embed OneApp dashboards and canvases directly in Teams.

Personal Tab — User's personal dashboard with recent canvases:

app/teams-tab/page.tsx
"use client";

import { useEffect, useState } from "react";
import * as microsoftTeams from "@microsoft/teams-js";

export default function TeamsTabPage() {
  const [initialized, setInitialized] = useState(false);

  useEffect(() => {
    microsoftTeams.app.initialize().then(() => {
      setInitialized(true);
    });
  }, []);

  if (!initialized) return <div>Loading Teams context...;

  return <CanvasDashboard />;
}

Configurable Tab — Add canvases to channels:

api/integrations/teams/tab/config/route.ts
export async function GET(): Promise<Response> {
  const html = `
    <!DOCTYPE html>
    <html>
      <head>
        <script src="https://res.cdn.office.net/teams-js/2.47.2/js/MicrosoftTeams.min.js"></script>
      </head>
      <body>
        <h1>Configure OneApp Tab</h1>
        <select id="canvasSelect">
          <option value="dashboard">Dashboard</option>
          <option value="canvas">Specific Canvas</option>
        </select>
        <script>
          microsoftTeams.app.initialize();
          microsoftTeams.pages.config.registerOnSaveHandler((saveEvent) => {
            microsoftTeams.pages.config.setConfig({
              suggestedDisplayName: "OneApp",
              contentUrl: window.location.origin + "/teams-tab",
            });
            saveEvent.notifySuccess();
          });
        </script>
      </body>
    </html>
  `;
  return new Response(html, { headers: { "Content-Type": "text/html" } });
}

Real-Time Notifications

Server-Sent Events (SSE) for instant notifications in Teams.

:::warning Webhook Performance Graph webhook notifications must be processed within 10 seconds:

  • If you can process within 3 seconds, return 200 OK
  • If processing takes longer, persist to a queue and return 202 Accepted
  • If you take >10 seconds, Microsoft Graph will retry or drop the notification :::
lib/teams/notifications.ts
import { sendNotification, NotificationType } from "#/lib/teams/notifications";

// Send notification to user
await sendNotification({
  userId: "user-123",
  type: NotificationType.CANVAS_MENTION,
  title: "You were mentioned",
  body: "John mentioned you in Q4 Planning canvas",
  data: { canvasId: "canvas-456" }
});

Notification types:

  • MESSAGE — New messages in linked channels
  • APPROVAL_REQUEST — Approval workflow requests
  • CANVAS_ACCESS — Canvas shared with user
  • INSIGHT_READY — AI insight generation complete
  • MEETING_STARTING — Linked meeting about to start
  • MENTION — User mentioned in canvas

Configure notification preferences:

components/teams/notification-preferences.tsx
import { NotificationPreferences } from "#/components/teams/notification-preferences";

// User can configure which notifications they receive
<NotificationPreferences
  userId={session.user.id}
  onSave={handlePreferencesSave}
/>

Meeting Integration

Pre-meeting briefs and post-meeting summaries with AI-powered insights.

lib/teams/meeting-integration.ts
import {
  generatePreMeetingBrief,
  generatePostMeetingSummary,
  createPreMeetingBriefCard
} from "#/lib/teams/meeting-integration";

// Generate pre-meeting brief
const brief = await generatePreMeetingBrief({
  meetingId: "meeting-123",
  userId: "user-456",
  attendees: ["user-789", "user-012"]
});

// Create Adaptive Card for Teams
const card = createPreMeetingBriefCard(brief);

// Send to meeting chat
await sendToMeetingChat(meetingId, card);

Brief includes:

  • Meeting agenda and context
  • Relevant canvases for the meeting
  • Recent activity from attendees
  • AI-suggested discussion points

Post-meeting summary:

  • Action items extracted from notes
  • Key decisions documented
  • Follow-up tasks assigned
  • Canvas updates suggested

API Routes

Webhooks

Handle incoming Teams events:

POST /api/integrations/teams/webhooks

Processes bot messages, channel events, and meeting notifications.

Messages

Send messages to Teams channels:

POST /api/integrations/teams/messages
// Request body
{
  channelId: string;
  message: string;
  cardData?: AdaptiveCardData;
}

Notifications

Stream endpoint (SSE):

GET /api/integrations/teams/notifications/stream

Preferences endpoint:

GET/PUT /api/integrations/teams/notifications/preferences

Tab Configuration

GET /api/integrations/teams/tab/config

Returns HTML configuration page for Teams tab setup.

Teams Manifest

The Teams app manifest defines your app's capabilities:

teams-app/manifest.json
{
  "$schema": "https://developer.microsoft.com/json-schemas/teams/v1.16/MicrosoftTeams.schema.json",
  "manifestVersion": "1.16",
  "version": "1.4.0",
  "id": "{{TEAMS_APP_ID}}",
  "packageName": "com.onedigital.oneapp.teams",
  "name": {
    "short": "OneApp",
    "full": "OneApp - AI-Powered Canvas Platform"
  },
  "description": {
    "short": "Access OneApp canvases in Teams",
    "full": "Seamlessly access your OneApp canvases, get AI-powered insights, and collaborate with your team without leaving Microsoft Teams."
  },
  "developer": {
    "name": "OneDigital",
    "websiteUrl": "https://oneapp.onedigital.com",
    "privacyUrl": "https://oneapp.onedigital.com/privacy",
    "termsOfUseUrl": "https://oneapp.onedigital.com/terms"
  },
  "bots": [
    {
      "botId": "{{TEAMS_BOT_ID}}",
      "scopes": ["personal", "team", "groupchat"],
      "supportsFiles": false,
      "isNotificationOnly": false,
      "commandLists": [
        {
          "scopes": ["personal", "team"],
          "commands": [
            { "title": "help", "description": "Get help with OneApp" },
            { "title": "search", "description": "Search your canvases" },
            { "title": "recent", "description": "View recent canvases" }
          ]
        }
      ]
    }
  ],
  "staticTabs": [
    {
      "entityId": "oneapp-dashboard",
      "name": "Dashboard",
      "contentUrl": "https://oneapp.onedigital.com/teams-tab",
      "scopes": ["personal"]
    }
  ],
  "configurableTabs": [
    {
      "configurationUrl": "https://oneapp.onedigital.com/api/integrations/teams/tab/config",
      "canUpdateConfiguration": true,
      "scopes": ["team", "groupchat"],
      "context": ["channelTab", "privateChatTab", "meetingChatTab", "meetingSidePanel"]
    }
  ],
  "permissions": ["identity", "messageTeamMembers"],
  "validDomains": ["oneapp.onedigital.com", "*.onedigital.com"]
}

Mobile Compatibility

Important: Microsoft Teams mobile apps only support Adaptive Cards up to version 1.2. Cards using v1.4 or v1.5 features may not render correctly on mobile devices.

If your organization has mobile users:

  1. Use Adaptive Cards v1.2 or lower
  2. If using v1.4/1.5 features, include fallbackText property
  3. Test on Teams mobile app (iOS/Android) before deploying

Activity Tracking

Track user activity across Teams and web for unified analytics.

lib/teams/activity-logger.ts
import { logTeamsActivity, ActivityType } from "#/lib/teams/activity-logger";

// Log when user views canvas in Teams
await logTeamsActivity({
  userId: "user-123",
  activityType: ActivityType.CANVAS_VIEW,
  metadata: {
    canvasId: "canvas-456",
    source: "teams-tab",
    teamId: "team-789"
  }
});

Activity types:

  • BOT_MESSAGE — User sent message to bot
  • CANVAS_VIEW — Canvas viewed in Teams tab
  • SSO_LOGIN — User authenticated via Teams SSO
  • APPROVAL_ACTION — Approval request handled
  • REPORT_GENERATED — Report created from Teams

Testing

Local Development

  1. Use ngrok for local webhook testing:

    ngrok http 3000
  2. Update manifest with ngrok URL:

    "validDomains": ["your-ngrok-url.ngrok.io"]
  3. Sideload the app in Teams Developer Portal

Test Scenarios

ScenarioStepsExpected Result
Bot messageSend "help" to botReceive help card
Tab loadOpen personal tabDashboard displays
NotificationTrigger canvas mentionSSE notification received
Meeting briefJoin meeting with linked canvasPre-meeting brief card appears

Debugging

Enable debug logging:

DEBUG=teams:* pnpm dev

Check Teams Developer Portal for:

  • Bot message delivery status
  • Tab loading errors
  • Manifest validation issues

Deployment

Production Checklist

  • Azure AD app configured with production redirect URIs
  • Teams manifest updated with production URLs
  • Environment variables set in production
  • SSL certificates valid for all domains
  • Rate limiting configured for webhook endpoints
  • Error monitoring enabled (Sentry/LogRocket)

Teams Admin Center Deployment

  1. Create app package:

    cd teams-app
    zip -r oneapp-teams.zip manifest.json icon-*.png
  2. Upload to Admin Center:

    • Go to Teams Admin Center → Teams apps → Manage apps
    • Click "Upload" and select the zip file
    • Configure app policies for your organization
  3. Monitor adoption:

    • Check usage analytics in Admin Center
    • Review bot conversation metrics
    • Track tab engagement

Troubleshooting

Common Issues

Bot not responding:

  • Verify TEAMS_BOT_ID and TEAMS_BOT_PASSWORD are correct
  • Check webhook URL is accessible from Teams
  • Ensure bot is enabled in Azure Bot Service

Tab not loading:

  • Confirm validDomains includes your app URL
  • Check for mixed content (HTTPS required)
  • Verify Teams JS SDK is initializing

SSO failures:

  • Azure AD app must have Teams SSO configured
  • Token audience must match your app ID
  • Redirect URIs must be registered

Notifications not received:

  • Check SSE connection is established
  • Verify user has notifications enabled
  • Confirm notification preferences allow the type

Error Codes

CodeDescriptionResolution
TEAMS_001Bot authentication failedCheck bot credentials
TEAMS_002Graph API permission deniedAdd required permissions
TEAMS_003Tab context unavailableEnsure Teams SDK initialized
TEAMS_004Meeting not foundVerify meeting ID and permissions

On this page