Introduction
En 2026, Microsoft Teams est au cœur des environnements collaboratifs d'entreprise, avec plus de 320 millions d'utilisateurs actifs mensuels. Les bots avancés transcendent les réponses simples pour orchestrer des workflows complexes : envoi de messages proactifs via Microsoft Graph API, gestion dynamique d'équipes, intégration IA pour analyses en temps réel. Ce tutoriel avancé vous guide pas à pas pour créer un bot Node.js/TypeScript qui (1) répond aux commandes utilisateur, (2) authentifie via Azure AD, (3) liste les canaux d'une équipe via Graph, et (4) envoie des notifications proactives. Idéal pour automatiser les alertes de sécurité ou les résumés de réunions. Avec du code 100% fonctionnel, des configs complètes et des pièges avancés évités, ce guide est bookmark-worthy pour tout architecte Microsoft 365. Durée estimée : 2h pour un déploiement live.
Prérequis
- Compte Azure gratuit (crédit 200$ offert)
- Node.js 20+ et npm 10+
- Azure CLI 2.60+ installé
- Connaissances avancées en TypeScript, OAuth 2.0 et REST APIs
- Visual Studio Code avec extensions Azure et TypeScript
- Accès admin Teams pour sideloading d'apps
Installation des dépendances
mkdir teams-bot-avance
cd teams-bot-avance
npm init -y
npm install @microsoft/botframework-sdk@4.21.2 restify@11.1.0 dotenv@16.4.5 @azure/identity@4.2.1 @microsoft/microsoft-graph-client@3.0.7 typescript@5.6.2 @types/node@22.7.4 @types/restify@8.5.10 ts-node@10.9.2
npm install -D nodemon
npx tsc --initCette commande initialise un projet Node.js avec les SDK essentiels : Bot Framework pour les interactions Teams, Graph Client pour les appels API avancés, et Azure Identity pour l'auth app-only. Les types TypeScript assurent une complétion IntelliSense robuste. Piège : Vérifiez les versions compatibles 2026 pour éviter les breaking changes en v5+ du SDK.
Configuration de l'app registration Azure
Connectez-vous à Azure CLI (az login) et créez une App Registration via le portail Azure (App registrations > New). Notez Application (client) ID, Tenant ID et générez un Client Secret. Ajoutez les API permissions : Microsoft Graph > Application permissions (Teams.Read.All, Channel.ReadBasic.All, ChatMessage.Send). Accordez l'admin consent. Pour le bot, exposez l'endpoint /api/messages comme Single Sign-On et Messaging endpoint (https://votre-bot.azurewebsites.net/api/messages). Analogy : C'est comme un passeport OAuth pour votre bot, sans ça, Graph bloquera les appels proactifs.
Création de la ressource Bot via Azure CLI
az login
az account set --subscription "Votre Subscription ID"
az bot create --name "teams-bot-avance" --resource-group "rg-teams-bot" --kind bot --sku S1 --location westeurope --endpoint "https://teams-bot-avance.azurewebsites.net/api/messages" --microsoft-app-id "votre-app-id"Cette CLI crée une ressource Bot Service payante (S1 pour prod) liée à votre App Registration. Elle configure automatiquement le messaging endpoint pour Teams. Piège : Utilisez --kind bot pour Teams ; --location proche de vos users pour <100ms latency. Remplacez les placeholders par vos vraies valeurs.
Fichier de configuration environnement
MICROSOFT_APP_ID=votre-app-id
MICROSOFT_APP_PASSWORD=votre-client-secret
TENANT_ID=votre-tenant-id
BOT_ENDPOINT=https://teams-bot-avance.azurewebsites.net/api/messages
GRAPH_SCOPE=https://graph.microsoft.com/.defaultCe fichier .env stocke les secrets critiques pour l'auth Bot Framework et Graph. Jamais commiter en Git ! Utilisez Azure Key Vault en prod. Piège : Le GRAPH_SCOPE est pour app permissions ; pour delegated, utilisez user scopes.
Structure du projet et tsconfig
Créez les dossiers src/ et placez .env à la racine. Modifiez tsconfig.json pour target ES2022 et module NodeNext. Lancez npm run dev avec nodemon : "dev": "nodemon --exec ts-node src/bot.ts". Cette base scalable supporte les hot-reloads pour itérations rapides.
Code principal du bot avec Graph intégration
import * as restify from 'restify';
import { BotFrameworkAdapter, MemoryStorage, ConversationState, UserState } from 'botbuilder';
import { Client } from '@microsoft/microsoft-graph-client';
import { ClientSecretCredential } from '@azure/identity';
import * as dotenv from 'dotenv';
dotenv.config();
const adapter = new BotFrameworkAdapter({
appId: process.env.MICROSOFT_APP_ID!,
appPassword: process.env.MICROSOFT_APP_PASSWORD!
});
const storage = new MemoryStorage();
const conversationState = new ConversationState(storage);
const userState = new UserState(storage);
const server = restify.createServer();
server.listen(process.env.port || process.env.PORT || 3978, () => {
console.log(`${server.name} listening to ${server.url}`);
});
server.post('/api/messages', (req, res) => {
adapter.processActivity(req, res, async (context) => {
if (context.activity.type === 'message') {
const text = context.activity.text?.toLowerCase();
if (text === 'list channels') {
await sendChannelsList(context);
} else {
await context.sendActivity(`Echo: ${context.activity.text}`);
}
}
});
});
async function sendChannelsList(context: any) {
const tenantId = process.env.TENANT_ID!;
const clientId = process.env.MICROSOFT_APP_ID!;
const clientSecret = process.env.MICROSOFT_APP_PASSWORD!;
const credential = new ClientSecretCredential(tenantId, clientId, clientSecret);
const graphClient = Client.initWithMiddleware({ authProvider: { getAccessToken: () => credential.getToken('https://graph.microsoft.com/.default') } });
try {
// Récup teamId et channelId depuis activity (simplifié pour demo)
const teamId = 'votre-team-id'; // À adapter dynamiquement via context
const channels = await graphClient.api(`/teams/${teamId}/channels`).get();
await context.sendActivity(`Canaux: ${channels.value.map((c: any) => c.displayName).join(', ')}`);
} catch (error) {
await context.sendActivity('Erreur Graph: ' + (error as Error).message);
}
}Ce bot écoute les messages Teams, répond à 'list channels' via Graph API pour lister les canaux d'une équipe (remplacez teamId par extraction dynamique de context.activity.teamInformation.id). L'auth app-only via ClientSecretCredential permet des appels server-side puissants. Piège : MemoryStorage pour dev seulement ; passez à CosmosDB en prod pour état persistant multi-sessions.
Manifest XML pour app Teams
<?xml version="1.0" encoding="UTF-8"?>
<TeamAppManifest xmlns="http://schemas.microsoft.com/Office/2018/03/addins" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ID>votre-app-id</ID>
<Version>1.0.0</Version>
<Name>Bot Avancé Teams</Name>
<Description>Bot avec Graph pour gestion équipes</Description>
<Developer>
<Name>Votre Entreprise</Name>
<Website>https://learni-group.com</Website>
</Developer>
<Icons>
<Color>color.png</Color>
<Outline>outline.png</Outline>
</Icons>
<Bots>
<Bot Id="votre-app-id" Scopes="team personal">
<SupportsFiles>Select false;Open false</SupportsFiles>
<IsNotificationOnly false Commands="[]" />
<SupportsCalling false />
<SupportsVideo false />
</Bot>
</Bots>
<ValidDomains>
<Domain>token.botframework.com</Domain>
<Domain>graph.microsoft.com</Domain>
</ValidDomains>
<WebApplicationInfo>
<Id>votre-app-id</Id>
<Resource>https://Rsc.pivot</Resource>
</WebApplicationInfo>
</TeamAppManifest>Ce manifest complet package votre bot comme app Teams sideloadable. Ajoutez icons 192x192 PNG. Scopes="team personal" active dans chats perso/équipes. Piège : WebApplicationInfo requis pour SSO Graph delegated ; testez validation via Developer Portal.
Ajout messages proactifs avec Graph
Pour l'avancé : Utilisez chatMessage.Send Graph pour notifier users sans interaction préalable. Stockez conversationReference en DB, puis POST /chats/{chatId}/messages. Exemple dans sendProactive.ts : Extrayez ref de context.activity.conversation.reference, adaptez le code bot ci-dessus. Nécessite Chat.Create permission.
Script déploiement Azure
npm run build
az webapp up --name teams-bot-avance --resource-group rg-teams-bot --runtime "NODE|20-lts" --env-vars MICROSOFT_APP_ID=$MICROSOFT_APP_ID MICROSOFT_APP_PASSWORD=$MICROSOFT_APP_PASSWORD TENANT_ID=$TENANT_ID
az bot authsetting appsetting set --name teams-bot-avance --resource-group rg-teams-bot --settings MicrosoftAppId=votre-app-id MicrosoftAppPassword=votre-secretCe script build TS et déploie sur App Service, injecte env vars sécurisées. authsetting lie au Bot Service. Piège : --runtime NODE|20-lts pour 2026 ; scalez avec --plan B2 pour traffic élevé.
Package.json avec scripts
{
"name": "teams-bot-avance",
"version": "1.0.0",
"scripts": {
"build": "tsc",
"dev": "nodemon --exec ts-node src/bot.ts",
"start": "node dist/bot.js"
},
"dependencies": {
"@azure/identity": "^4.2.1",
"@microsoft/botframework-sdk": "^4.21.2",
"@microsoft/microsoft-graph-client": "^3.0.7",
"dotenv": "^16.4.5",
"restify": "^11.1.0"
},
"devDependencies": {
"@types/node": "^22.7.4",
"@types/restify": "^8.5.10",
"nodemon": "^3.1.7",
"ts-node": "^10.9.2",
"typescript": "^5.6.2"
}
}Scripts prêts pour dev/prod. build compile TS vers dist/. Piège : Ajoutez "type": "module" si ESM ; testez local avec ngrok pour Teams tunneling.
Bonnes pratiques
- Persistance état : Remplacez MemoryStorage par Azure CosmosDB pour scalabilité horizontale.
- Rate limiting Graph : Implémentez retry avec exponential backoff (429 errors).
- Sécurité : Utilisez Managed Identity au lieu de secrets ; auditez permissions least-privilege.
- Logging : Intégrez Application Insights pour traces end-to-end.
- Tests : Mock Graph avec MSW ; CI/CD via GitHub Actions avec az CLI.
Erreurs courantes à éviter
- Auth fail (AADSTS700 : Vérifiez tenant/client ID ; admin consent manquant.
- CORS/Endpoint non exposé : Ajoutez bot endpoint dans Azure Portal > Channels > Teams.
- Proactive sans ref : Toujours stocker conversationReference avant fin turn.
- TeamId dynamique : Extrayez de
activity.channelData.tenant.idpas hardcoded.
Pour aller plus loin
Passez au niveau expert avec Bot Framework Composer pour low-code IA, ou intégrez Azure OpenAI pour chatbots conversationnels. Explorez Microsoft Graph Teams API docs. Formations complètes : Learni Group Formations Microsoft 365. Rejoignez notre Discord pour Q&A live.