Deploy Magpie to Microsoft Teams using Azure Bot Framework
The Teams adapter enables Magpie to receive tasks via Microsoft Teams messages. It runs as an HTTP webhook server that handles Bot Framework activities with OAuth2 authentication and optional HMAC signature validation.
# Required: Azure Bot credentialsTEAMS_APP_ID=00000000-0000-0000-0000-000000000000TEAMS_APP_SECRET=your~client.secret_here-1234567890# Optional: Server listen address (default: 0.0.0.0:3978)TEAMS_LISTEN_ADDR=0.0.0.0:3978# Optional: HMAC signature validation secret# (configured in Azure Bot → Configuration → Messaging endpoint settings)TEAMS_HMAC_SECRET=your_webhook_secret_here# Repository configurationMAGPIE_REPO_DIR=/path/to/your/repoMAGPIE_BASE_BRANCH=mainMAGPIE_GITHUB_ORG=your-org # Optional: for org-scoped repo cloning# CI commandsMAGPIE_TEST_CMD="npm test"MAGPIE_LINT_CMD="npm run lint"MAGPIE_MAX_CI_ROUNDS=2# Optional: Plane.so issue trackingPLANE_BASE_URL=https://your-plane.soPLANE_API_KEY=your_plane_api_keyPLANE_WORKSPACE_SLUG=your-workspacePLANE_PROJECT_ID=your-project-id# Optional: Daytona sandbox executionDAYTONA_API_KEY=your_daytona_keyDAYTONA_BASE_URL=https://app.daytona.io/apiDAYTONA_ORGANIZATION_ID=your-org-idDAYTONA_SANDBOX_CLASS=small
The TEAMS_APP_ID is your Application (client) ID from the Azure AD app registration. The TEAMS_APP_SECRET is the client secret value (not the secret ID).
Teams includes <at>...</at> XML tags in message text. Magpie strips these before processing:
crates/magpie-teams/src/webhook.rs:62-73
pub fn strip_teams_mention(text: &str) -> String { let mut result = text.to_string(); while let Some(start) = result.find("<at>") { if let Some(end) = result[start..].find("</at>") { let remove_end = start + end + "</at>".len(); result = format!("{}{}", &result[..start], &result[remove_end..]); } else { break; } } result.trim().to_string()}
Example:
Input: <at>Magpie</at> fix the login bugOutput: fix the login bug
[Unit]Description=Magpie Teams WebhookAfter=network.target[Service]Type=simpleUser=magpieWorkingDirectory=/opt/magpieEnvironmentFile=/opt/magpie/.envExecStart=/opt/magpie/magpie-teamsRestart=alwaysRestartSec=10[Install]WantedBy=multi-user.target
info magpie-teams listening on 0.0.0.0:3978info received Teams message user="Alice" task="fix the bug"info pipeline complete status=Success pr=Some("https://github.com/org/repo/pull/42")warn HMAC validation failederror failed to send ack: token request failed (401)
Invalid credentials: Verify TEAMS_APP_ID and TEAMS_APP_SECRET match your Azure AD app registration.
# Test token acquisition manuallycurl -X POST https://login.microsoftonline.com/botframework.com/oauth2/v2.0/token \ -d "grant_type=client_credentials" \ -d "client_id=YOUR_APP_ID" \ -d "client_secret=YOUR_SECRET" \ -d "scope=https://api.botframework.com/.default"
Common causes:
Wrong secret (copied secret ID instead of value)
Expired secret (Azure secrets have configurable lifetimes)
Wrong tenant (multitenant vs single-tenant mismatch)
HMAC validation failures
Signature mismatch: Ensure TEAMS_HMAC_SECRET matches the webhook secret in Azure Bot configuration.Debug logs:
warn HMAC validation failed
Fix:
Go to Azure Bot → Configuration → Messaging endpoint
Copy the Webhook signature secret
Update TEAMS_HMAC_SECRET in .env
Restart Magpie
Disable for testing:
unset TEAMS_HMAC_SECRETcargo run -p magpie-teams
Webhook receives no messages
Messaging endpoint not configured: Verify Azure Bot → Configuration → Messaging endpoint is set to your server’s public URL.Firewall blocking: Ensure your server accepts inbound HTTPS on port 443 (or HTTP on 80 for ngrok).Test connectivity:
# From Azure Bot → Test in Web Chat# Send a message and check Magpie logs
ngrok for local testing:
ngrok http 3978# Update messaging endpoint to: https://abc123.ngrok.io/api/messages
Bot doesn't reply in Teams
serviceUrl mismatch: The serviceUrl in the activity must match the Bot Framework endpoint.Token expired: AuthManager caches tokens for 3600 seconds. If the bot was idle for >1 hour, the first reply may fail. Check logs for “token request failed”.Rate limiting: Bot Framework has rate limits (60 requests/minute per bot). High-frequency replies may be throttled.Debug logs:
error failed to send pipeline result: token request failed (401)