Skip to content

teams-automation

otc-awesome-llm is the Optum LLM library providing version-controlled prompts, chatmodes, instructions, and agent modes for infrastructure operations via native IDE integrations

IDE:
claude
Version:
11.3.0
plugin
claude-code
teams-automation

Microsoft Teams Automation Skill - Architectural Design

Overview

This directory contains the architectural design and implementation blueprint for the teams-automation skill, a Microsoft Teams adaptation of the successful outlook-automation skill. The design leverages Microsoft Graph API instead of browser automation, providing a modern, cross-platform solution for Teams message processing.

Authentication setup (read this first)

The plugin reads from two possible token sources and prefers the one that's already populated:

  1. LegionIO-stored token at ~/.legionio/tokens/microsoft_teams.json — recommended.

    • Setup: brew install legionio (already covered by your environment if you use Kai/Legion); then legionio auth teams. Browser pops, complete Optum SSO.
    • LegionIO's Entra app (8709c80b-2196-427b-80f6-7fcc4f9cae8b) is admin-consented in the UHG tenant for the full Teams content surface — Chat.Read, ChannelMessage.Read.All, OnlineMeetingTranscript.Read.All, Files.Read.All, Notes.Read.All, ~50 scopes total. No additional admin consent needed.
    • Token is refreshed by re-running legionio auth teams when it expires (~1 hour).
  2. InteractiveBrowserAuth fallback — used when no Legion token is present.

    • First call opens a browser for Optum SSO using the Microsoft Graph Command Line Tools appId (14d82eec-204b-4c2f-b7e8-296a70dab67e).
    • Admin-consented in UHG for SharePoint / OneDrive / Group metadata, but NOT for Mail.Read, Calendars.Read, Chat.Read, or ChannelMessage.Read.All. Requesting those triggers the admin-approval workflow.
    • Use this path when Legion isn't installed or for cross-tenant work.

Programmatic override: TeamsClient(prefer_legion=False) forces the InteractiveBrowserAuth fallback. Default is prefer_legion=True.

See issue #487 for the full discovery / rationale.

Architecture Documents

📐 ARCHITECTURE.md

Comprehensive architectural overview including:

  • Key differences from Outlook version
  • Component architecture and responsibilities
  • Authentication flow using OAuth2
  • Message retrieval approach
  • Security considerations
  • Technology stack

🗺️ IMPLEMENTATION_ROADMAP.md

Detailed week-by-week implementation guide:

  • Phase 1: Core Authentication (Week 1)
  • Phase 2: API Client (Week 2)
  • Phase 3: Message Processing (Week 3)
  • Phase 4: Chronological Processing (Week 3-4)
  • Phase 5: Security Hardening (Week 4)
  • Phase 6: Testing & Documentation (Week 5)

🔄 OUTLOOK_VS_TEAMS.md

Comprehensive comparison between the two skills:

  • Technology stack differences
  • Component mapping
  • Data structure changes
  • Migration guide for users
  • Performance comparisons

📁 DIRECTORY_STRUCTURE.md

Complete plugin file structure with:

  • Directory layout
  • File purposes
  • Implementation order
  • Configuration locations

🔒 SECURITY_ARCHITECTURE.md

In-depth security design covering:

  • OAuth2 authentication security
  • API security measures
  • Teams-specific threat mitigation
  • Audit and compliance features
  • Incident response procedures

Key Design Decisions

1. Microsoft Graph API

  • Why: Cross-platform support, reliability, performance
  • How: RESTful API calls with OAuth2 authentication
  • Benefit: No browser dependencies, works on all platforms

2. OAuth2 Device Code Flow

  • Why: Secure, no client secrets, user-controlled
  • How: MSAL library with Azure AD integration
  • Benefit: Enterprise-grade security with automatic token refresh

3. Maintained Security Architecture

  • Why: Proven security model from outlook-automation
  • How: Adapted components for Teams-specific threats
  • Benefit: Protection against prompt injection and API abuse

4. Chronological Processing with State

  • Why: Handle large message volumes efficiently
  • How: Persistent state with skip/resume capability
  • Benefit: Interruption resilience and selective processing

Quick Start for Implementation

  1. Review Architecture: Start with ARCHITECTURE.md
  2. Follow Roadmap: Use IMPLEMENTATION_ROADMAP.md week by week
  3. Understand Differences: Study OUTLOOK_VS_TEAMS.md
  4. Create Structure: Follow DIRECTORY_STRUCTURE.md
  5. Implement Security: Apply SECURITY_ARCHITECTURE.md

Core Components to Implement

Authentication Layer

  • teams_auth.py - OAuth2 device code flow
  • secure_credentials.py - Enhanced for token storage

API Integration

  • teams_client.py - Microsoft Graph API wrapper
  • message_processor.py - Message format conversion

Features

  • message_digest.py - Categorized summaries
  • task_extractor.py - AI-powered task extraction
  • chronological_reader.py - Process oldest first

Security

  • security_validator.py - Operation validation
  • message_sanitizer.py - Teams-specific threats

Success Criteria

Authentication: Users can authenticate via device code flow ✅ Message Retrieval: Successfully retrieve messages from Teams ✅ Processing: Chronological processing with state management ✅ Security: All operations validated, sanitization working ✅ Performance: Handle 1000+ messages efficiently ✅ Cross-Platform: Works on Windows, macOS, Linux

Next Steps

This architectural design provides the foundation for implementing a secure, scalable Microsoft Teams automation skill. The modular design allows for incremental development while maintaining the security-first approach that made outlook-automation successful.

To begin implementation:

  1. Set up Azure AD app registration
  2. Start with Phase 1 (Core Authentication)
  3. Test each component thoroughly
  4. Follow security best practices throughout

Enhanced Features

UserSearchStrategy

The teams-automation skill includes an advanced UserSearchStrategy component that provides intelligent recipient disambiguation:

Key Features

  • Deterministic Name Matching: Handles both "First Last" and "Last, First" name formats consistently
  • Self-messaging Prevention: Detects and prevents users from attempting to message themselves
  • Smart Disambiguation: Prioritizes individual users over groups when searching for person names
  • Name Normalization: Converts different name formats to a standard format for reliable matching
  • 3-word Name Support: Recognizes names with middle names (e.g., "Mary Jane Smith")

Example Usage

from user_search import UserSearchStrategy

# Initialize with current user to prevent self-messaging
strategy = UserSearchStrategy(current_user="John Doe")

# Search results from Teams
results = [
    {"name": "John Doe Team", "subtitle": "Group • 25 members"},
    {"name": "Doe, John", "subtitle": "Direct message"}
]

# Find best match (will prioritize individual over group)
best_match = strategy.find_best_match("John Doe", results)
# Returns: Individual "Doe, John" with high confidence

# Prevents self-messaging
self_result = strategy.find_best_match("John Doe", results)
# Returns: Error with 0.0 confidence and self-messaging warning

SmartElementLocator

The skill also includes retry logic for handling Microsoft Teams' dynamic UI:

  • Exponential Backoff: Automatically retries failed element interactions
  • Fallback Selectors: Provides alternative ways to locate elements
  • Transient Error Handling: Gracefully handles "Resource temporarily unavailable" errors
  • Configurable Timeouts: Adjustable retry attempts and delays

Related Resources

Full content query (PR #485)

The plugin's TeamsClient now exposes the full chat + channel query surface required by the unified m365-query plugin:

  • list_chats(top) — recent chats with members expanded
  • get_chat_messages(chat_id, since, limit) — paginated chat history
  • get_chat_thread(chat_id) — full thread with mentions + attachments
  • search_chat_messages(query) — Graph search over chatMessage entities
  • list_channel_messages(team_id, channel_id, since, limit) — channel posts
  • search_channel_messages(query, scope_team_ids) — Graph search filtered by team
  • summarize_unread() — unread totals + recent senders

Construct with TeamsClient(full_query_scopes=True) to inject the broader DEFAULT_TEAMS_SCOPES_FULL scope set when the user has not pinned their own scopes in ~/.claude/teams-automation.local.md.

CLI:

python teams_graph_client.py chats --top 20
python teams_graph_client.py search --query "TOPIC"
python teams_graph_client.py thread --chat-id <id>
python teams_graph_client.py unread

This architectural design was created as part of the teams-automation skill development for the otc-awesome-llm project.

Related Assets