Skip to main content

Microsoft Teams

WednesdayAI connects to Microsoft Teams through the Bot Framework. Teams ships as a plugin — it is not bundled with the core install — and requires an Azure Bot registration plus a Teams app package.
Teams setup is the most involved of all channels: Azure Bot, app manifest, RSC permissions, and (for channel media/history) Microsoft Graph admin consent. Budget time for it.

Install the plugin

From a local git checkout:
If you choose Teams during onboarding and a git checkout is detected, WednesdayAI offers the local install path automatically.

Setup overview

1

Create an Azure Bot

At Create Azure Bot, use Single Tenant (new multi-tenant bots were deprecated after 2025-07-31) and Create new Microsoft App ID. From the resource, collect the App ID, a client secret (App password), and the Directory (tenant) ID.
2

Set the messaging endpoint

In the Azure Bot Configuration, set the messaging endpoint to your webhook URL, e.g. https://your-domain.com/api/messages. For local dev, tunnel port 3978 (see below). Then enable the Microsoft Teams channel under Channels.
3

Build and upload a Teams app package

Reference the bot in a Teams app manifest with scopes personal, team, groupChat, supportsFiles: true, the RSC permissions below, and 32x32 / 192x192 icons. The Teams Developer Portal can generate the package for you.
webApplicationInfo.id must match your Azure Bot App ID exactly. If these values differ, app authentication will fail silently.
4

Configure WednesdayAI

Or via env: MSTEAMS_APP_ID, MSTEAMS_APP_PASSWORD, MSTEAMS_TENANT_ID.
5

Start the gateway

The Teams channel starts automatically once the plugin is installed and credentials are present. Verify with Azure Test in Web Chat before testing in Teams.

Local development tunnel

Teams cannot reach localhost. Use a tunnel:
Tailscale Funnel also works (tailscale funnel 3978).

Access control

Use stable AAD object IDs in allowFrom. UPNs and display names are mutable, so name matching is disabled by default — re-enable it only via the break-glass channels.msteams.dangerouslyAllowNameMatching: true. The configure wizard resolves names to IDs via Graph when permissions allow.
Group chats are blocked by default (groupPolicy: "allowlist" with no allowlist). Set groupAllowFrom, or use groupPolicy: "open" (still mention-gated). Channels are mention-gated by default; override per team/channel with requireMention.

RSC vs Graph permissions

Teams Resource-Specific Consent (RSC) permissions go in the app manifest and cover real-time text. Microsoft Graph Application permissions (with tenant admin consent) are needed for channel/group media and message history. Minimum RSC permissions in the manifest: ChannelMessage.Read.Group, ChannelMessage.Send.Group, Member.Read.Group, ChatMessage.Read.Chat, Owner.Read.Group, ChannelSettings.Read.Group, TeamMember.Read.Group, TeamSettings.Read.Group. For channel media and history, add Graph ChannelMessage.Read.All and Chat.Read.All (or ChatMessage.Read.All) and grant admin consent. After any permission change, bump the manifest version, re-upload, reinstall in the team, and fully quit and relaunch Teams.

Sending files in group chats

DMs use the FileConsentCard flow out of the box. Group chats and channels require a SharePoint upload (bots have no personal OneDrive). Add Graph Sites.ReadWrite.All (and optionally Chat.Read.All for per-user sharing links), grant admin consent, fetch your SharePoint site ID, then set channels.msteams.sharePointSiteId. Inline images work everywhere without SharePoint.

Target formats

Teams also supports polls and arbitrary Adaptive Cards via the card parameter.

Reply style

Teams has two channel UI styles that share one data model, and the API does not expose which a channel uses. Set channels.msteams.replyStyle (thread for classic Posts, top-level for Slack-like Threads), with per-team and per-channel overrides under channels.msteams.teams.<id>....

Troubleshooting

Mentions are required by default. Set channels.msteams.requireMention: false or configure it per team/channel.
Graph permissions or admin consent are missing. Add the Graph permissions, grant consent, reinstall the app, and fully quit/relaunch Teams.
Expected when testing manually without an Azure JWT — it means the endpoint is reachable but auth failed. Use Azure Web Chat to test properly.
Remove and re-add the app, then fully quit Teams (not just close the window) to clear cached metadata.
Teams retries slow webhooks. WednesdayAI returns quickly and replies proactively, but very slow model responses can still cause retries.