Microsoft Teams

CommunicationUnified CollaborationAPIBot DevelopmentPower PlatformMicrosoft 365

Communication Tool

Microsoft Teams

Overview

Microsoft Teams is a Microsoft 365 integrated collaboration platform. It integrates chat, video conferencing, and file sharing, providing large-scale video conferencing features supporting up to 250 participants. It features rich enterprise functionality and extensive automation capabilities through Power Platform integration.

Details

Microsoft Teams is a Microsoft 365 integrated business collaboration platform launched in 2017. Currently serving 250 million active users, it shows higher growth rates than Slack in Microsoft environment enterprises. It differentiates itself with enterprise security features and Office 365 integration, expanding its share in the enterprise market.

In 2024-2025, significant AI enhancements were introduced including Teams AI library, new Meeting AI Insights API, and Microsoft 365 Agents Toolkit. With the introduction of app manifest v1.22, support for custom activity icons, meeting insights API, and deep integration with Power Platform (Power Automate, Power Virtual Agents, Copilot Studio), no-code and low-code development has been greatly streamlined.

Using Teams Bot Framework enables advanced bot development in JavaScript, C#, and Python, with integration across Microsoft 365 using Graph API and rich user interface construction through Adaptive Cards UI.

Pros and Cons

Pros

  • Complete Microsoft 365 Integration: Seamless connectivity with Office, SharePoint, OneDrive
  • Enterprise Security: Advanced authentication/authorization and compliance features
  • Large-scale Meeting Support: Video conferencing for up to 250 participants, webinar functionality
  • Power Platform Integration: No-code/low-code automation and bot development
  • Rich APIs: Graph API, Bot Framework, Teams API
  • Enhanced AI Features: Teams AI library, Meeting AI Insights API
  • Azure AD Integration: Single sign-on, conditional access
  • Rich Development Tools: Teams Toolkit (Microsoft 365 Agents Toolkit)

Cons

  • Microsoft Dependency: Strong dependency on Microsoft ecosystem
  • Learning Curve: Complexity due to rich features
  • Licensing Structure: Complex pricing and licensing structure
  • Customization Limitations: UI/UX customization restrictions
  • Performance: Performance issues in large organizations
  • Third-party Integration: Limitations in integration with competitor services

Key Links

Code Examples

Bot Development with Teams AI Library (JavaScript)

import { Application, TurnState } from '@microsoft/teams-ai';
import { MemoryStorage } from 'botbuilder';

// Initialize storage and app
const storage = new MemoryStorage();
const app = new Application({
  storage,
  ai: {
    planner: {
      model: 'gpt-3.5-turbo',
      apiKey: process.env.OPENAI_API_KEY,
    }
  }
});

// Message handler
app.activity('message', async (context, state) => {
  const replyText = `Echo: ${context.activity.text}`;
  await context.sendActivity(replyText);
});

// Register AI action
app.ai.action('createTask', async (context, state, data) => {
  const { title, description } = data;
  
  // Task creation logic
  state.conversation.tasks = state.conversation.tasks || [];
  state.conversation.tasks.push({ title, description, completed: false });
  
  await context.sendActivity(`Task "${title}" created successfully!`);
  return true;
});

// Start the app
app.start();

Bot Framework (C#)

using Microsoft.Bot.Builder;
using Microsoft.Bot.Framework;
using Microsoft.Teams.AI;

public class TeamsBot : ActivityHandler
{
    private readonly ILogger<TeamsBot> _logger;
    private readonly IConfiguration _config;

    public TeamsBot(ILogger<TeamsBot> logger, IConfiguration config)
    {
        _logger = logger;
        _config = config;
    }

    protected override async Task OnMessageActivityAsync(
        ITurnContext<IMessageActivity> turnContext, 
        CancellationToken cancellationToken)
    {
        var replyText = $"Echo: {turnContext.Activity.Text}";
        await turnContext.SendActivityAsync(
            MessageFactory.Text(replyText), 
            cancellationToken);
    }

    protected override async Task OnMembersAddedAsync(
        IList<ChannelAccount> membersAdded,
        ITurnContext<IConversationUpdateActivity> turnContext,
        CancellationToken cancellationToken)
    {
        var welcomeText = "Welcome to the Teams Bot!";
        foreach (var member in membersAdded)
        {
            if (member.Id != turnContext.Activity.Recipient.Id)
            {
                await turnContext.SendActivityAsync(
                    MessageFactory.Text(welcomeText), 
                    cancellationToken);
            }
        }
    }
}

// Configuration in Startup.cs
public void ConfigureServices(IServiceCollection services)
{
    services.AddHttpClient().AddControllers().AddNewtonsoftJson();
    
    // Bot Framework setup
    services.AddSingleton<IBotFrameworkHttpAdapter, AdapterWithErrorHandler>();
    services.AddTransient<IBot, TeamsBot>();
    
    // Teams AI setup
    services.AddSingleton<IStorage, MemoryStorage>();
}

Rich UI with Adaptive Cards

// Create Adaptive Card
const adaptiveCard = {
  type: 'AdaptiveCard',
  version: '1.4',
  body: [
    {
      type: 'TextBlock',
      text: 'Task Management',
      weight: 'Bolder',
      size: 'Medium'
    },
    {
      type: 'Input.Text',
      id: 'taskTitle',
      placeholder: 'Enter task title'
    },
    {
      type: 'Input.Text',
      id: 'taskDescription',
      placeholder: 'Enter task description',
      isMultiline: true
    }
  ],
  actions: [
    {
      type: 'Action.Submit',
      title: 'Create Task',
      data: {
        action: 'createTask'
      }
    }
  ]
};

// Send Adaptive Card
app.message('create task', async (context, state) => {
  const cardAttachment = {
    contentType: 'application/vnd.microsoft.card.adaptive',
    content: adaptiveCard
  };

  await context.sendActivity({
    attachments: [cardAttachment]
  });
});

// Handle Adaptive Card submission
app.adaptiveCards.actionSubmit('createTask', async (context, state, data) => {
  const { taskTitle, taskDescription } = data;
  
  // Task creation processing
  await context.sendActivity(`Task "${taskTitle}" created: ${taskDescription}`);
});

Microsoft Graph API Integration

import { Client } from '@microsoft/microsoft-graph-client';

// Initialize Graph client
const getGraphClient = (accessToken) => {
  return Client.init({
    authProvider: (done) => {
      done(null, accessToken);
    }
  });
};

// Get channel list
app.message('list channels', async (context, state) => {
  try {
    const token = await getAccessToken(context);
    const graphClient = getGraphClient(token);
    
    const teamId = context.activity.channelData.team.id;
    const channels = await graphClient
      .api(`/teams/${teamId}/channels`)
      .get();
    
    const channelList = channels.value
      .map(channel => `- ${channel.displayName}`)
      .join('\n');
    
    await context.sendActivity(`Channels:\n${channelList}`);
  } catch (error) {
    await context.sendActivity('Error accessing Graph API');
  }
});

// Get file list (SharePoint integration)
app.message('list files', async (context, state) => {
  try {
    const token = await getAccessToken(context);
    const graphClient = getGraphClient(token);
    
    const teamId = context.activity.channelData.team.id;
    const files = await graphClient
      .api(`/groups/${teamId}/drive/root/children`)
      .get();
    
    const fileList = files.value
      .map(file => `- [${file.name}](${file.webUrl})`)
      .join('\n');
    
    await context.sendActivity(`Files:\n${fileList}`);
  } catch (error) {
    await context.sendActivity('Error accessing files');
  }
});

Power Automate Integration

// Trigger Power Automate flow
app.message('trigger flow', async (context, state) => {
  const flowUrl = process.env.POWER_AUTOMATE_FLOW_URL;
  const payload = {
    userMessage: context.activity.text,
    userId: context.activity.from.id,
    teamId: context.activity.channelData.team.id,
    channelId: context.activity.channelData.channel.id
  };

  try {
    const response = await fetch(flowUrl, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(payload)
    });

    if (response.ok) {
      const result = await response.json();
      await context.sendActivity(`Flow executed: ${result.message}`);
    } else {
      await context.sendActivity('Failed to trigger flow');
    }
  } catch (error) {
    await context.sendActivity('Error triggering Power Automate flow');
  }
});

Meeting AI Insights API Usage (2024 New Feature)

import { Client } from '@microsoft/microsoft-graph-client';

// Get meeting insights
app.message('meeting insights', async (context, state) => {
  try {
    const token = await getAccessToken(context);
    const graphClient = getGraphClient(token);
    
    // Get latest meeting
    const meetings = await graphClient
      .api('/me/onlineMeetings')
      .orderby('creationDateTime desc')
      .top(1)
      .get();
    
    if (meetings.value.length > 0) {
      const meetingId = meetings.value[0].id;
      
      // Get meeting insights
      const insights = await graphClient
        .api(`/me/onlineMeetings/${meetingId}/insights`)
        .get();
      
      const summary = insights.summary || 'No summary available';
      const actionItems = insights.actionItems || [];
      
      let message = `**Meeting Summary:**\n${summary}\n\n`;
      
      if (actionItems.length > 0) {
        message += '**Action Items:**\n';
        actionItems.forEach((item, index) => {
          message += `${index + 1}. ${item.description}\n`;
        });
      }
      
      await context.sendActivity(message);
    } else {
      await context.sendActivity('No recent meetings found');
    }
  } catch (error) {
    await context.sendActivity('Error retrieving meeting insights');
  }
});

Teams Toolkit Manifest Configuration

{
  "$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.22/MicrosoftTeams.schema.json",
  "manifestVersion": "1.22",
  "version": "1.0.0",
  "id": "${{TEAMS_APP_ID}}",
  "developer": {
    "name": "Your Company",
    "websiteUrl": "https://www.yourcompany.com",
    "privacyUrl": "https://www.yourcompany.com/privacy",
    "termsOfUseUrl": "https://www.yourcompany.com/terms"
  },
  "icons": {
    "color": "color.png",
    "outline": "outline.png"
  },
  "name": {
    "short": "Teams AI Bot",
    "full": "Teams AI Powered Bot"
  },
  "description": {
    "short": "AI-powered Teams bot",
    "full": "Advanced Teams bot with AI capabilities"
  },
  "accentColor": "#FFFFFF",
  "bots": [
    {
      "botId": "${{BOT_ID}}",
      "scopes": [
        "personal",
        "team",
        "groupchat"
      ],
      "supportsFiles": false,
      "isNotificationOnly": false,
      "commandLists": [
        {
          "scopes": [
            "personal",
            "team",
            "groupchat"
          ],
          "commands": [
            {
              "title": "Help",
              "description": "Show help information"
            },
            {
              "title": "Create Task",
              "description": "Create a new task"
            }
          ]
        }
      ]
    }
  ],
  "permissions": [
    "identity",
    "messageTeamMembers"
  ],
  "validDomains": [
    "${{BOT_DOMAIN}}"
  ]
}

Environment Variables Configuration

# .env file
# Bot Framework
BOT_ID=your-bot-id
BOT_PASSWORD=your-bot-password
MicrosoftAppId=your-app-id
MicrosoftAppPassword=your-app-password

# Azure OpenAI / OpenAI
AZURE_OPENAI_API_KEY=your-azure-openai-key
AZURE_OPENAI_ENDPOINT=https://your-resource.openai.azure.com/
OPENAI_API_KEY=your-openai-key

# Microsoft Graph
MICROSOFT_APP_ID=your-graph-app-id
MICROSOFT_APP_SECRET=your-graph-app-secret

# Power Automate
POWER_AUTOMATE_FLOW_URL=https://prod-xx.eastus.logic.azure.com/workflows/xxx

# Teams Toolkit
TEAMS_APP_ID=your-teams-app-id
BOT_DOMAIN=your-bot-domain.com

Docker Configuration Example

FROM node:18-alpine

WORKDIR /app

# Install dependencies
COPY package*.json ./
RUN npm ci --only=production

# Copy application
COPY . .

# Environment variables
ENV NODE_ENV=production
ENV PORT=3978

EXPOSE 3978

# Run application
CMD ["npm", "start"]