@chat-adapter/teams
v4.22.0
Published
Microsoft Teams adapter for chat
Readme
@chat-adapter/teams
Microsoft Teams adapter for Chat SDK. Configure with Azure Bot Service.
Installation
pnpm add @chat-adapter/teamsUsage
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.
| 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 |
| certificate | No** | Certificate-based authentication config |
| 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 |
| 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, certificate, or federated.
Authentication methods
The adapter supports three mutually exclusive 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",
});Certificate
Authenticate with a PEM certificate. Provide either certificateThumbprint or x5c (public certificate for subject-name validation):
createTeamsAdapter({
certificate: {
certificatePrivateKey: "-----BEGIN RSA PRIVATE KEY-----\n...",
certificateThumbprint: "AB1234...", // hex-encoded thumbprint
},
});Or with subject-name validation:
createTeamsAdapter({
certificate: {
certificatePrivateKey: "-----BEGIN RSA PRIVATE KEY-----\n...",
x5c: "-----BEGIN CERTIFICATE-----\n...",
},
});Federated (workload identity)
For environments with managed identities (e.g. Azure Kubernetes Service, GitHub Actions):
createTeamsAdapter({
federated: {
clientId: "your_managed_identity_client_id_here",
clientAudience: "api://AzureADTokenExchange", // optional, this is the default
},
});Environment variables
TEAMS_APP_ID=...
TEAMS_APP_PASSWORD=...
TEAMS_APP_TENANT_ID=... # Required for SingleTenantFeatures
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 | No |
Conversations
| Feature | Supported | |---------|-----------| | Slash commands | No | | Mentions | Yes | | Add reactions | No | | Remove reactions | No | | Typing indicator | No | | DMs | Yes | | Ephemeral messages | No (DM fallback) |
Message history
| Feature | Supported | |---------|-----------| | Fetch messages | Yes | | Fetch single message | No | | Fetch thread info | Yes | | Fetch channel messages | Yes | | List threads | Yes | | Fetch channel info | Yes | | Post channel message | Yes |
Limitations
- Adding reactions: Teams Bot Framework doesn't support bots adding reactions. Calling
addReaction()orremoveReaction()throws aNotImplementedError. The bot can still receive reaction events viaonReaction(). - Typing indicators: Not available via Bot Framework.
startTyping()is a no-op.
Message history (fetchMessages)
Fetching message history requires the Microsoft Graph API with client credentials flow. To enable it:
- Set
appTenantIdin the adapter config - Grant one of these Azure AD app permissions:
ChatMessage.Read.ChatChat.Read.AllChat.Read.WhereInstalled
Without these permissions, fetchMessages will not be able to retrieve channel history.
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 - For certificate auth, ensure the private key and thumbprint/x5c match what's registered in Azure AD
- For federated auth, verify the managed identity client ID and audience are correct
- 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
