This document provides full technical documentation for the SOW Analyzer Teams Bot application. It is intended for:
This document describes:
—
The SOW Analyzer is a document ingestion and analysis system exposed through Microsoft Teams.
Users interact with the system by uploading a PDF Statement of Work directly into a 1:1 Teams chat with a bot. The system:
At no point does the system store uploaded SOWs long-term.
—
User uploads PDF in Teams → Teams stores file in OneDrive/SharePoint → Teams sends attachment metadata to bot → Bot validates + downloads file → Bot POSTs PDF to analyzer endpoint → Analyzer extracts text and compares templates → Azure OpenAI produces structured diff → Result returned to Teams
—
| Component | Tenant |
| ———- | ——– |
| Teams users | CDW Tenant |
| Bot App Registration | CDW Tenant |
| Azure Bot Service | Azure Tenant |
| Web App (FastAPI) | Azure Tenant |
| Azure OpenAI | Azure Tenant |
| Blob Storage (templates) | Azure Tenant |
The bot uses a single-tenant App Registration in the CDW Tenant.
This App Registration:
Required environment variables:
MicrosoftAppId MicrosoftAppPassword MicrosoftAppTenantId
The bot will reject any token whose AppId does not match `MicrosoftAppId`.
—
Key configuration:
"bots": [
{
"botId": "<MicrosoftAppId>",
"scopes": ["personal"],
"supportsFiles": true
}
]
| Interaction | Supported |
| ———— | ———– |
| 1:1 Chat | YES |
| Group Chat | NO |
| Channel | NO |
| Adaptive Cards | Optional |
| Message Extensions | NO |
Teams uploads files to OneDrive or SharePoint, then sends metadata to the bot.
Expected attachment type:
application/vnd.microsoft.teams.file.download.info
The bot does not receive raw bytes directly.
—
Acts as the FastAPI entry point for:
—
Implements all Teams bot logic.
BotFrameworkAdapterSettings( MicrosoftAppId, MicrosoftAppPassword, channel_auth_tenant=MicrosoftAppTenantId )
This enforces:
1. Trust incoming service URL 2. Ignore non-message activities 3. Extract attachments 4. If no attachment → return silently 5. Extract filename + download URL 6. Enforce `.pdf` extension 7. Download file bytes 8. Validate PDF magic bytes (`%PDF`) 9. POST file to analyzer 10. Format and send result
Two layers:
Maximum allowed size enforced before analysis.
—
Performs AI-driven comparison between uploaded SOW and known templates.
{
"chosen_template_title": "string",
"summary": "string",
"missing_sections": [],
"extra_sections": [],
"changed_clauses": {}
}
—
Provides access to stored SOW templates.
—
—
| Condition | Message |
| ——— | ——— |
| Non-PDF upload | “I can only analyze PDF files” |
| Download failure | “I couldn’t download the file” |
| Analyzer failure | “Analysis failed” |
—
—
—
—
The system:
—
Future enhancements may include: