Microsoft Teams

Deploy bots to Microsoft Teams with Adaptive Cards, mentions, and conversation threading.

Install

pnpm add @chat-adapter/teams

Quick start

The adapter auto-detects TEAMS_APP_ID, TEAMS_APP_PASSWORD, and TEAMS_APP_TENANT_ID from the environment.

lib/bot.ts
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!");
});

Configuration

Prop

Type

appId is required. Exactly one authentication method (appPassword or federated) must be provided.

Authentication

The Teams CLI handles AAD app registration, client secret generation, bot registration, and Teams channel setup in one command.

Install the CLI

npm install -g @microsoft/teams.cli@preview

1. Create the app

teams login
teams status
teams app create --name "My Bot" --endpoint "https://your-domain.com/api/webhooks/teams" --env .env

For local development, use a tunnel (e.g. devtunnel, ngrok) to expose your local server.

Credentials (CLIENT_ID, CLIENT_SECRET, TENANT_ID) are written to .env. Rename them to match the adapter:

TEAMS_APP_ID=<CLIENT_ID>
TEAMS_APP_PASSWORD=<CLIENT_SECRET>
TEAMS_APP_TENANT_ID=<TENANT_ID>

2. Install in Teams

Get a direct install link:

teams app get <appId> --install-link

Or download the app package for sideloading and upload via Apps then Manage your apps then Upload an app then Upload a custom app.

3. Verify

teams app doctor <appId>

Authentication methods

Client secret (default) — provide appPassword or set TEAMS_APP_PASSWORD:

createTeamsAdapter({
  appPassword: "your_app_password_here",
});

Federated (workload identity) — for environments with managed identities (e.g. AKS, GitHub Actions). Maps to managedIdentityClientId in the Teams SDK:

createTeamsAdapter({
  federated: {
    clientId: "your_managed_identity_client_id_here",
  },
});

Advanced

User lookup

The adapter supports looking up user profiles via the Microsoft Graph API. To enable it:

  1. Grant the User.Read.All application permission in your Azure AD app registration.
  2. Grant admin consent for the permission.
const user = await bot.getUser(message.author);
console.log(user?.email);    // "alice@contoso.com"
console.log(user?.fullName); // "Alice Smith"

The adapter caches each user's Azure AD object ID from incoming activities, so getUser only works for users who have previously interacted with the bot.

Message history

Fetching message history requires TEAMS_APP_TENANT_ID and the right permissions depending on the conversation type:

ContextPermissionTypeAdmin consent?
ChannelChannelMessage.Read.GroupRSCNo
Group chatChatMessage.Read.ChatRSCNo
DMChat.Read.AllAzure ADYes

RSC permissions are set via the Teams CLI (no admin consent needed):

teams app rsc add <appId> ChannelMessage.Read.Group --type Application
teams app rsc add <appId> ChatMessage.Read.Chat --type Application

For DM message history, RSC is not sufficient. Add Chat.Read.All via the Azure CLI:

az ad app permission add \
  --id <appId> \
  --api 00000003-0000-0000-c000-000000000000 \
  --api-permissions 6b7d71aa-70aa-4810-a8d9-5d9fb2830017=Role

az ad app permission admin-consent --id <appId>

Receiving all messages

By default, Teams bots only receive messages when directly @-mentioned. The RSC permissions above also enable receiving all messages in channels and group chats as a side effect.

Troubleshooting

Run teams app doctor <appId> to diagnose common issues — bot registration, AAD app health, manifest consistency, and endpoint reachability.

Feature support

Messaging

FeatureSupported
Post message
Edit message
Delete message
File uploads
StreamingNative (DMs) / Buffered
Scheduled messages

Rich content

FeatureSupported
Card formatAdaptive Cards
Buttons
Link buttons
Select menus
TablesGFM
Fields
Images in cards
Modals

Conversations

FeatureSupported
Slash commands
Mentions
Add reactions
Remove reactions
Typing indicator
DMs
Ephemeral messages
User lookupCached
Parent subject
Native client
Custom API endpoint

Message history

FeatureSupported
Fetch messagesRequires Graph permissions
Fetch single message
Fetch thread info
Fetch channel messagesRequires Graph permissions
List threadsRequires Graph permissions
Fetch channel infoRequires Graph permissions
Post channel message