Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
@chat-adapter/teams
Microsoft Teams adapter for Chat SDK. Configure with Azure Bot Service.
Installation
pnpm add @chat-adapter/teams
Usage
The adapter auto-detects TEAMS_APP_ID, TEAMS_APP_PASSWORD, and TEAMS_APP_TENANT_ID from environment variables:
import { Chat } from "chat";
import { createTeamsAdapter } from "@chat-adapter/teams";
const bot = new Chat({
userName: "mybot",
adapters: {
teams: createTeamsAdapter({
appType: "SingleTenant",
}),
},
});
bot.onNewMention(async (thread, message) => {
await thread.post("Hello from Teams!");
});
Azure Bot setup
1. Create Azure Bot resource
- Go to portal.azure.com
- Click Create a resource
- Search for Azure Bot and select it
- Click Create and fill in:
- Bot handle: Unique identifier for your bot
- Subscription: Your Azure subscription
- Resource group: Create new or use existing
- Pricing tier: F0 (free) for testing
- Type of App: Single Tenant (recommended for enterprise)
- Creation type: Create new Microsoft App ID
- Click Review + create then Create
2. Get app credentials
- Go to your Bot resource then Configuration
- Copy Microsoft App ID as
TEAMS_APP_ID - Click Manage Password (next to Microsoft App ID)
- In the App Registration page, go to Certificates & secrets
- Click New client secret, add description, select expiry, click Add
- Copy the Value immediately (shown only once) as
TEAMS_APP_PASSWORD - Go to Overview and copy Directory (tenant) ID as
TEAMS_APP_TENANT_ID
3. Configure messaging endpoint
- In your Azure Bot resource, go to Configuration
- Set Messaging endpoint to
https://your-domain.com/api/webhooks/teams - Click Apply
4. Enable Teams channel
- In your Azure Bot resource, go to Channels
- Click Microsoft Teams
- Accept the terms of service
- Click Apply
5. Create Teams app package
Create a manifest.json file:
{
"$schema": "https://developer.microsoft.com/en-us/json-schemas/teams/v1.16/MicrosoftTeams.schema.json",
"manifestVersion": "1.16",
"version": "1.0.0",
"id": "your_app_id_here",
"packageName": "com.yourcompany.chatbot",
"developer": {
"name": "Your Company",
"websiteUrl": "https://your-domain.com",
"privacyUrl": "https://your-domain.com/privacy",
"termsOfUseUrl": "https://your-domain.com/terms"
},
"name": {
"short": "Chat Bot",
"full": "Chat SDK Demo Bot"
},
"description": {
"short": "A chat bot powered by Chat SDK",
"full": "A chat bot powered by Chat SDK that responds to messages and commands."
},
"icons": {
"outline": "outline.png",
"color": "color.png"
},
"accentColor": "#FFFFFF",
"bots": [
{
"botId": "your_app_id_here",
"scopes": ["personal", "team", "groupchat"],
"supportsFiles": false,
"isNotificationOnly": false
}
],
"permissions": ["identity", "messageTeamMembers"],
"validDomains": ["your-domain.com"]
}
Create icon files (32x32 outline.png and 192x192 color.png), then zip all three files together.
6. Upload app to Teams
For testing (sideloading):
- In Teams, click Apps in the sidebar
- Click Manage your apps then Upload an app
- Click Upload a custom app and select your zip file
For organization-wide deployment:
- Go to Teams Admin Center
- Go to Teams apps then Manage apps
- Click Upload new app and select your zip file
- Go to Setup policies to control who can use the app
Configuration
All options are auto-detected from environment variables when not provided. Internally, the adapter maps these options to the Teams SDK (@microsoft/teams.apps).
| Option | Required | Description |
|---|---|---|
appId |
No* | Azure Bot App ID. Auto-detected from TEAMS_APP_ID |
appPassword |
No** | Azure Bot App Password. Auto-detected from TEAMS_APP_PASSWORD |
federated |
No** | Federated (workload identity) authentication config |
appType |
No | "MultiTenant" or "SingleTenant" (default: "MultiTenant") |
appTenantId |
For SingleTenant | Azure AD Tenant ID. Auto-detected from TEAMS_APP_TENANT_ID |
userName |
No | Bot display name (default: "bot") |
logger |
No | Logger instance (defaults to ConsoleLogger("info")) |
*appId is required — either via config or TEAMS_APP_ID env var.
**Exactly one authentication method is required: appPassword or federated. When neither is provided, TEAMS_APP_PASSWORD is auto-detected from environment.
Authentication methods
The adapter supports two authentication methods. When no explicit auth is provided, TEAMS_APP_PASSWORD is auto-detected from environment variables.
Client secret (default)
The simplest option — provide appPassword directly or set TEAMS_APP_PASSWORD:
createTeamsAdapter({
appPassword: "your_app_password_here",
});
Federated (workload identity)
For environments with managed identities (e.g. Azure Kubernetes Service, GitHub Actions). Maps to managedIdentityClientId in the Teams SDK:
createTeamsAdapter({
federated: {
clientId: "your_managed_identity_client_id_here",
},
});
Environment variables
TEAMS_APP_ID=...
TEAMS_APP_PASSWORD=...
TEAMS_APP_TENANT_ID=... # Required for SingleTenant apps
Features
Messaging
| Feature | Supported |
|---|---|
| Post message | Yes |
| Edit message | Yes |
| Delete message | Yes |
| File uploads | Yes |
| Streaming | Post+Edit fallback |
Rich content
| Feature | Supported |
|---|---|
| Card format | Adaptive Cards |
| Buttons | Yes |
| Link buttons | Yes |
| Select menus | No |
| Tables | GFM |
| Fields | Yes |
| Images in cards | Yes |
| Modals | Yes |
Conversations
| Feature | Supported |
|---|---|
| Slash commands | No |
| Mentions | Yes |
| Add reactions | No |
| Remove reactions | No |
| Receive reactions | Yes |
| Typing indicator | Yes |
| DMs | Yes |
| Ephemeral messages | No (DM fallback) |
Message history
| Feature | Supported |
|---|---|
| Fetch messages | Yes (requires Graph permissions) |
| Fetch single message | No |
| Fetch thread info | Yes |
| Fetch channel messages | Yes (requires Graph permissions) |
| List threads | Yes (requires Graph permissions) |
| Fetch channel info | Yes (requires Graph permissions) |
| Post channel message | Yes |
Message history (fetchMessages)
Fetching message history requires the Microsoft Graph API with client credentials flow. To enable it:
- Set
appTenantIdin the adapter config (orTEAMS_APP_TENANT_IDenv var) - Grant one of these Azure AD app permissions:
ChatMessage.Read.ChatChat.Read.AllChat.Read.WhereInstalled
Without these permissions, fetchMessages will throw a NotImplementedError.
Receiving all messages
By default, Teams bots only receive messages when directly @-mentioned. To receive all messages in a channel or group chat, add Resource-Specific Consent (RSC) permissions to your Teams app manifest:
{
"authorization": {
"permissions": {
"resourceSpecific": [
{
"name": "ChannelMessage.Read.Group",
"type": "Application"
}
]
}
}
}
Alternatively, configure the bot in Azure to receive all messages.
Troubleshooting
"Unauthorized" error
- Verify
TEAMS_APP_IDand your chosen auth credential are correct - For client secret auth, check that
TEAMS_APP_PASSWORDis valid and not expired - For federated auth, verify the managed identity client ID is correct and that federated credentials are configured in Azure AD
- For SingleTenant apps, ensure
TEAMS_APP_TENANT_IDis set - Check that the messaging endpoint URL is correct in Azure
Bot not appearing in Teams
- Verify the Teams channel is enabled in Azure Bot
- Check that the app manifest is correctly configured
- Ensure the app is installed in the workspace/team
Messages not received
- Verify the messaging endpoint URL is correct
- Check that your server is accessible from the internet
- Review Azure Bot logs for errors
License
MIT