teams-api
Microsoft Teams automation using Graph API, Bot Framework, Adaptive Cards, and webhooks for enterprise messaging and collaboration
What this skill does
# Microsoft Teams API Skill
Master Microsoft Teams automation using the Microsoft Graph API and Bot Framework. This skill covers channel messaging, adaptive cards, bot development, webhooks, and enterprise integration patterns for Microsoft 365 environments.
## When to Use This Skill
### USE when:
- Building bots for Microsoft 365 organizations
- Creating enterprise notification systems
- Integrating with Azure DevOps and Microsoft ecosystem
- Building approval workflows in Teams
- Automating meeting scheduling and management
- Creating messaging extensions for Teams apps
- Implementing compliance-aware messaging solutions
- Building internal tools with Adaptive Cards
### DON'T USE when:
- Organization uses Slack primarily (use slack-api)
- Need simple webhooks only (use incoming webhooks directly)
- No Microsoft 365 subscription available
- Building consumer-facing chat applications
- Need real-time gaming or high-frequency updates
## Prerequisites
### Azure App Registration
```bash
# 1. Go to Azure Portal -> Azure Active Directory -> App registrations
# 2. New registration:
# - Name: "Teams Bot App"
# - Supported account types: Accounts in this organizational directory
# - Redirect URI: Web - https://your-app.azurewebsites.net/auth
# Required API Permissions (Microsoft Graph):
# Application permissions:
# - ChannelMessage.Send - Send channel messages
# - Chat.ReadWrite.All - Read/write chats
# - Team.ReadBasic.All - Read team info
# - User.Read.All - Read user profiles
# - Group.Read.All - Read group info
# - OnlineMeetings.ReadWrite.All - Create meetings
# Delegated permissions:
# - Chat.ReadWrite - User chat access
# - Team.ReadBasic.All - User team access
# - ChannelMessage.Send - User can send messages
# 3. Create client secret:
# - Certificates & secrets -> New client secret
# - Save the value (shown only once)
```
### Python Environment Setup
```bash
# Create virtual environment
python -m venv teams-bot-env
source teams-bot-env/bin/activate # Linux/macOS
# Install dependencies
pip install azure-identity msgraph-sdk botbuilder-core aiohttp
# Create requirements.txt
cat > requirements.txt << 'EOF'
azure-identity>=1.14.0
msgraph-sdk>=1.0.0
botbuilder-core>=4.14.0
botbuilder-integration-aiohttp>=4.14.0
aiohttp>=3.9.0
python-dotenv>=1.0.0
requests>=2.31.0
EOF
# Environment variables
cat > .env << 'EOF'
AZURE_TENANT_ID=your-tenant-id
AZURE_CLIENT_ID=your-client-id
AZURE_CLIENT_SECRET=your-client-secret
MICROSOFT_APP_ID=your-bot-app-id
MICROSOFT_APP_PASSWORD=your-bot-password
TEAMS_WEBHOOK_URL=your-webhook-url
EOF
```
### Bot Framework Registration
```bash
# 1. Go to https://dev.botframework.com/bots/new
# 2. Or use Azure Portal -> Create a resource -> Bot Channels Registration
# Bot configuration:
# - Messaging endpoint: https://your-app.azurewebsites.net/api/messages
# - Microsoft App ID: from App Registration
# - Enable Teams channel
# For local development with ngrok:
ngrok http 3978
# Update messaging endpoint to ngrok URL
```
## Core Capabilities
### 1. Microsoft Graph API Client
```python
# graph_client.py
# ABOUTME: Microsoft Graph API client for Teams operations
# ABOUTME: Handles authentication and common API calls
from azure.identity import ClientSecretCredential
from msgraph import GraphServiceClient
from msgraph.generated.models.chat_message import ChatMessage
from msgraph.generated.models.item_body import ItemBody
from msgraph.generated.models.body_type import BodyType
import os
from dotenv import load_dotenv
load_dotenv()
class TeamsGraphClient:
"""Microsoft Graph client for Teams operations"""
def __init__(self):
self.credential = ClientSecretCredential(
tenant_id=os.environ["AZURE_TENANT_ID"],
client_id=os.environ["AZURE_CLIENT_ID"],
client_secret=os.environ["AZURE_CLIENT_SECRET"]
)
self.client = GraphServiceClient(
credentials=self.credential,
scopes=["https://graph.microsoft.com/.default"]
)
async def send_channel_message(
self,
team_id: str,
channel_id: str,
content: str,
content_type: str = "html"
):
"""Send a message to a Teams channel"""
message = ChatMessage(
body=ItemBody(
content_type=BodyType.Html if content_type == "html" else BodyType.Text,
content=content
)
)
result = await self.client.teams.by_team_id(team_id) \
.channels.by_channel_id(channel_id) \
.messages.post(message)
return result
async def send_chat_message(
self,
chat_id: str,
content: str
):
"""Send a message to a chat (1:1 or group)"""
message = ChatMessage(
body=ItemBody(
content_type=BodyType.Html,
content=content
)
)
result = await self.client.chats.by_chat_id(chat_id) \
.messages.post(message)
return result
async def list_teams(self):
"""List all teams the app has access to"""
result = await self.client.groups.get()
teams = [g for g in result.value if g.resource_provisioning_options
and "Team" in g.resource_provisioning_options]
return teams
async def list_channels(self, team_id: str):
"""List channels in a team"""
result = await self.client.teams.by_team_id(team_id) \
.channels.get()
return result.value
async def get_channel_messages(
self,
team_id: str,
channel_id: str,
top: int = 50
):
"""Get recent messages from a channel"""
result = await self.client.teams.by_team_id(team_id) \
.channels.by_channel_id(channel_id) \
.messages.get(
request_configuration=lambda config:
setattr(config.query_parameters, 'top', top)
)
return result.value
async def reply_to_message(
self,
team_id: str,
channel_id: str,
message_id: str,
content: str
):
"""Reply to a channel message"""
reply = ChatMessage(
body=ItemBody(
content_type=BodyType.Html,
content=content
)
)
result = await self.client.teams.by_team_id(team_id) \
.channels.by_channel_id(channel_id) \
.messages.by_chat_message_id(message_id) \
.replies.post(reply)
return result
async def create_online_meeting(
self,
subject: str,
start_time: str,
end_time: str,
attendees: list
):
"""Create an online meeting"""
from msgraph.generated.models.online_meeting import OnlineMeeting
from msgraph.generated.models.meeting_participants import MeetingParticipants
from msgraph.generated.models.meeting_participant_info import MeetingParticipantInfo
from msgraph.generated.models.identity_set import IdentitySet
from msgraph.generated.models.identity import Identity
participant_list = [
MeetingParticipantInfo(
identity=IdentitySet(
user=Identity(id=attendee)
)
)
for attendee in attendees
]
meeting = OnlineMeeting(
subject=subject,
start_date_time=start_time,
end_date_time=end_time,
participants=MeetingParticipants(
attendees=participant_list
)
)
result = await self.client.me.online_meetings.post(meeting)
return result
async def get_user_by_email(self, email: str):
"""Get user details by email"""
result = await self.client.users.by_user_id(email).gRelated in communication
calendly-api
IncludedCalendly scheduling automation using REST API v2 for managing event types, availability, bookings, webhooks, and scheduling workflows
miro-api
IncludedMiro whiteboard automation using REST API v2 and Python SDK for creating boards, frames, shapes, connectors, and collaborative visual workflows
slack-api
IncludedSlack bot development and workspace automation using Web API, Events API, Socket Mode, and Block Kit for building interactive messaging applications
Customer Support Reply
IncludedCraft empathetic, effective customer support responses that solve problems
Press Release Writer
IncludedWrite professional press releases that get media attention and coverage
Internal Memo Creator
IncludedWrite clear, professional internal memos for company communication