Gérer les appels des utilisateurs Teams avec les SDK d’appel Communication Services

Découvrez comment gérer les appels avec les kits de développement logiciel (SDK) Azure Communication Services. Nous allons apprendre à passer des appels, ainsi qu’à gérer leurs participants et leurs propriétés.

Prérequis

Installer le SDK

Utilisez la commande npm install pour installer les kits SDK Appel Azure Communication Services et communs pour JavaScript.

npm install @azure/communication-common --save
npm install @azure/communication-calling --save

Initialiser les objets nécessaires

Créez une instance CallClient pour lancer la pile d’appels. Vous pouvez configurer la journalisation du Kit de développement logiciel (SDK) Appel avec l’instance AzureLogger et la méthode setLogLevel. Vous pouvez avoir accès à deviceManager pour le système d’exploitation avec la méthode getDeviceManager.

Utilisez ensuite la méthode createTeamsCallAgent pour créer de manière asynchrone une instance TeamsCallAgent qui gérera les appels entrants et sortants pour un utilisateur Teams. La méthode prend CommunicationTokenCredential comme argument représentant un jeton d’accès pour l’utilisateur Teams.

const { CallClient } = require('@azure/communication-calling');
const { AzureCommunicationTokenCredential} = require('@azure/communication-common');
const { AzureLogger, setLogLevel } = require("@azure/logger");

// Set the logger's log level
setLogLevel('verbose');

// Redirect log output to wherever desired. To console, file, buffer, REST API, etc...
AzureLogger.log = (...args) => {
    console.log(...args); // Redirect log output to console
};

const userToken = '<USER_TOKEN>';
callClient = new CallClient();
const tokenCredential = new AzureCommunicationTokenCredential(userToken);
const teamsCallAgent = await callClient.createTeamsCallAgent(tokenCredential);
const deviceManager = await callClient.getDeviceManager();

Passer un appel

Démarrez un appel synchrone à deux ou de groupe avec l’API startCall sur teamsCallAgent. Vous pouvez fournir MicrosoftTeamsUserIdentifier ou PhoneNumberIdentifier en tant que paramètre pour définir la cible de l’appel. La méthode retourne l’instance TeamsCall qui vous permet de vous abonner à des événements d’appel.

Remarque

Démarrer un appel de groupe avec teamsCallAgent requiert un threadId de conversation lors de l’appel de la méthode startCall. L’instance TeamsCall créée a une propriété threadId qui capture ce thread. Le Kit de développement logiciel (SDK) Communication Services Appel ne synchronise pas les participants à la conversation et la liste d’appels. Microsoft encourage les développeurs à maintenir la liste synchronisée afin d’optimiser expérience utilisateur. Découvrez comment gérer le thread de conversation.

Démarrer un appel VoIP à deux avec un utilisateur de Teams :

const userCallee = { microsoftTeamsUserId: '<MICROSOFT_TEAMS_USER_ID>' };
const oneToOneCall = teamsCallAgent.startCall(userCallee);

Démarrer un appel téléphonique à deux vers le numéro de téléphone E.164 :

const phoneCallee = { phoneNumber: '<PHONE_NUMBER_E164_FORMAT>' }
const oneToOneCall = teamsCallAgent.startCall(phoneCallee );

Démarrer un appel de groupe à un utilisateur Teams avec VoIP et numéro de téléphone :

const userCallee = { microsoftTeamsUserId: '<MICROSOFT_TEAMS_USER_ID>' }
const phoneCallee = { phoneNumber: '<PHONE_NUMBER_E164_FORMAT>'};
const groupCall = teamsCallAgent.startCall([userCallee, phoneCallee], { threadId: '<THREAD_ID>' });

Participation à un appel

Rejoindre une réunion Teams

Vous pouvez participer à des réunions Teams avec la méthode join sur l’instance teamsCallAgent. Des utilisateurs Teams peuvent participer à une réunion Teams en fournissant un TeamsMeetingLinkLocator, un TeamsMeetingCoordinatesLocator ou un TeamsMeetingIdLocator.

Participer à une réunion Teams avec l’URL de la réunion :

const meetingCall = teamsCallAgent.join({ meetingLink: '<MEETING_LINK>' });

Participer à une réunion Teams avec une combinaison d’ID de thread, d’ID d’organisateur, d’ID de locataire et d’ID de message :

const meetingCall = teamsCallAgent.join({ threadId: '<THREAD_ID>', organizerId: '<ORGANIZER_ID>', tenantId: '<TENANT_ID>', messageId: '<MESSAGE_ID>' });

Participer à une réunion Teams avec le code de réunion et le code secret :

const meetingCall = teamsCallAgent.join({ meetingId: '<MEETING_CODE>', passcode: '<PASSCODE>'});

Participer à une réunion Teams avec l’ID de réunion et le code secret :

Les développeurs peuvent connecter des participants à une réunion Teams de plusieurs façons. L’une des méthodes consiste à utiliser un ID de réunion et un code secret, ce qui permet aux personnes de rejoindre la réunion Teams à partir d’un appareil ou d’une application. Vous devez toujours fournir l’ID de réunion et le code secret pour participer à la réunion. Le code secret respecte la casse.

  • Format de l’ID de réunion et du code secret :

    • ID de réunion : 12 chiffres.
    • Code secret : 6 caractères
  • À quelle fréquence l’ID de réunion et le code secret doivent-ils être actualisés ?

    • L’ID de réunion et le code secret ne changent plus une fois créés. Les développeurs n’ont pas besoin de les actualiser.
    • Un organisateur de réunion Teams ne peut pas régénérer l’ID de réunion et le code secret.
  • Existe-t-il une différence dans l’expérience de réunion Teams si une personne rejoint via l’URL ou l’ID de réunion et le code secret ?

    • Non, les participants ont la même expérience s’ils rejoignent une réunion Teams à l’aide de l’URL de réunion Teams ou de l’ID de réunion et du code secret.
  • Comment les développeurs doivent-ils stocker et gérer les codes secrets ?

    • L’ID de réunion et le code secret sont des coordonnées pour participer à la réunion. Les développeurs doivent les traiter comme des secrets, qui doivent être chiffrés et, s’ils sont stockés, vérifier qu’ils se trouvent dans un environnement dont l’accès est contrôlé.
    • Si les coordonnées sont exposées, tout le monde peut participer à la réunion et ruiner l’expérience pour tous les participants à la réunion.
  • Comment obtenir l’ID de réunion et le code secret ?

    1. API Graph : utilisez l’API Graph pour récupérer des informations sur la ressource onlineMeeting et vérifiez l’objet dans la propriété joinMeetingIdSettings.
    2. Teams : dans votre application Teams, accédez à l’application Calendar et ouvrez les détails d’une réunion. Les réunions en ligne ont un ID et un code secret de réunion dans la définition de la réunion.
    3. Outlook : vous pouvez trouver l’ID de la réunion et le code secret dans les événements du calendrier ou dans les e-mails d’invitation à la réunion.
    4. Les développeurs ne peuvent pas récupérer l’ID de réunion et le code secret en appelant le Kit de développement logiciel (SDK) ni le récupérer à partir des journaux de console détaillés.
  • Comment vérifier que l’ID de réunion et le code secret sont corrects ?

Recevoir un appel entrant Teams

Vous pouvez vous abonner à un événement incomingCall sur une instance teamsCallAgent pour enregistrer les appels entrants à l’utilisateur Teams. L’événement a une propriété teamsIncomingCall avec une instance TeamsIncomingCall grâce à laquelle vous pouvez accept ou reject l’appel entrant.

const incomingCallHandler = async (args: { teamsIncomingCall: TeamsIncomingCall }) => {
    const incomingCall = args.teamsIncomingCall;
    // Get Teams incoming call ID
    const incomingCallId = incomingCall.id;
    // Get information about this Call. This API is provided as a preview for developers
    // and may change based on feedback that we receive. Do not use this API in a production environment.
    // To use this API please use 'beta' release of Azure Communication Services Calling Web SDK
    const callInfo = incomingCall.info;
    // Get information about caller
    const callerInfo = incomingCall.callerInfo
    // Accept the call
    const teamsCall = await incomingCall.accept();
    // Reject the call
    incomingCall.reject();
    // Subscribe to callEnded event and get the call end reason
    incomingCall.on('callEnded', args => {
        console.log(args.callEndReason);
    });
    // callEndReason is also a property of IncomingCall
    var callEndReason = incomingCall.callEndReason;
};
teamsCallAgent.on('incomingCall', incomingCallHandler);

Activer et désactiver la vidéo

Vous pouvez obtenir votre collection de flux vidéo locaux à partir de la propriété localVideoStreams dans l’instance TeamsCall. Si elle est activée, la collection contient un flux de partage d’écran et des flux vidéo de caméra. Vous pouvez obtenir les flux vidéo de participants distants en inspectant la propriété TeamsCall.remoteParticipants où chaque participant a une collection de flux vidéo dans la propriété videoStreams.

Activer et désactiver le son

Vous pouvez utiliser les API asynchrones mute et unmute sur l’instance TeamsCall pour désactiver ou activer des utilisateurs Teams localement. La désactivation locale du micro empêche l’envoi d’audio à d’autres participants.

//mute local device
await call.mute();
//unmute local device
await call.unmute();

Désactiver le son des autres participants

Pour désactiver le son de tous les autres participants ou désactiver le son d’un participant en particulier, vous pouvez utiliser les API asynchrones muteAllRemoteParticipants sur l’appel et mute sur le participant distant :

//mute all participants except yourself
await call.muteAllRemoteParticipants();

//mute a specific participant
await call.remoteParticipants[0].mute();

Remarque

Cet API est fourni en tant qu’aperçu pour les développeurs et peut être modifié en fonction des commentaires que nous avons reçus. N’utilisez pas cet API dans un environnement de production. Pour utiliser cette API, utilisez la version bêta d’Azure Communication Services Calling Web SDK.

Gérer les participants distants

Les autres participants à un appel sont disponibles dans l’instance TeamsCall sous la propriété remoteParticipants. Il s’agit d’une collection d’objets RemoteParticipant. Vous pouvez répertorier, ajouter et supprimer les autres participants à l’appel.

Remarque

L’ajout d’une méthode de participant requiert un threadId de conversation. Le Kit de développement logiciel (SDK) Communication Services Appel ne synchronise pas les participants à la conversation et la liste d’appels. Microsoft encourage les développeurs à maintenir la liste synchronisée afin d’optimiser expérience utilisateur. Découvrez comment gérer le thread de conversation.

Vous pouvez ajouter un utilisateur ou un numéro de téléphone Teams à un appel ou à une réunion Teams en appelant la méthode addParticipant sur l’objet TeamsCall. La méthode accepte les identificateurs MicrosoftTeamsUserIdentifier ou PhoneNumberIdentifier en entrée. Elle retourne de façon synchrone l’instance de RemoteParticipant et déclenche l’événement remoteParticipantsUpdated sur l’instance TeamsCall.

Vous pouvez supprimer un participant d’un appel ou d’une réunion Teams en appelant la méthode removeParticipant sur l’instance TeamsCall de manière asynchrone. La méthode accepte les identificateurs MicrosoftTeamsUserIdentifier ou PhoneNumberIdentifier en entrée. La méthode est résolue quand RemoteParticipant est supprimé de la collection remoteParticipants, et l’événement remoteParticipantsUpdated sur l’instance TeamsCall déclenché.

Répertorier les autres participants à un appel :

const participants = call.remoteParticipants; // [remoteParticipant, remoteParticipant....]

Ajouter un utilisateur et un numéro de téléphone Teams à un appel ou à une réunion Teams :

const teamsUser = { microsoftTeamsUserId: '<MICROSOFT_TEAMS_USER_ID>' };
const phoneUser = { phoneNumber: '<PHONE_NUMBER_E164_FORMAT>' }
const remoteParticipant = call.addParticipant(teamsUser , { threadId: '<THREAD_ID>' });
const remoteParticipant2 = call.addParticipant(phoneUser , { threadId: '<THREAD_ID>' });

Supprimer un utilisateur et un numéro de téléphone Teams d’une appel ou d’une réunion Teams :

const teamsUser = { microsoftTeamsUserId: '<MICROSOFT_TEAMS_USER_ID>' };
const phoneUser = { phoneNumber: '<PHONE_NUMBER_E164_FORMAT>' }
await call.removeParticipant(teamsUser);
await call.removeParticipant(phoneUser);

Participants distants

Les participants distants représentent un point de terminaison connecté à l’appel ou à la réunion Teams en cours. La classe remoteParticipant a l’ensemble suivant de propriétés et de collections :

  • identifier : retourne l’un des identificateurs CommunicationUserIdentifier, MicrosoftTeamsUserIdentifier, PhoneNumberIdentifier ou UnknownIdentifier.
const identifier = remoteParticipant.identifier;
  • state : retourne une string représentant un état d’un participant distant. L’état peut avoir l’une des valeurs suivantes :
Valeur d’état Lorsque le répertoire Description
Idle InitialState Il s’agit du premier état du participant.
Connecting Après Idle État transitoire pendant qu’un participant se connecte à l’appel.
Ringing Après Connecting Le participant a reçu une notification incomingCall ou un client Teams sonne.
Connected Après Ringing, Connecting, EarlyMedia ou InLobby Le participant a accepté l’invitation à l’appel ou a rejoint l’appel. Le média circule vers le participant.
Hold Après Connected Le participant à l’appel est en attente.
EarlyMedia Après Connecting Le média est lu avant qu’un participant se connecte à l’appel.
InLobby Après Ringing, Connecting ou EarlyMedia Le participant se trouve dans la salle d’attente de réunion Teams.
Disconnected État final Le participant est déconnecté de l’appel. Si le participant distant perd sa connectivité réseau, son état passe à Disconnected au bout de deux minutes.

États des participants distants dans les appels individuels ou de groupe : Diagramme des états d’appel de participant distant pour les appels individuels ou de groupe.

États des participants distants aux réunions Teams : Diagramme des états d’appel de participant distant pour les réunions Teams.

const state = remoteParticipant.state;
  • callEndReason : retourne un objet contenant des informations supplémentaires sur la raison pour laquelle l’appel s’est terminé. La propriété code retourne un nombre associé à la raison, et subCode retourne un nombre associé au code et à la raison. Pour plus d’informations sur les codes d’erreur, consultez Résolution des problèmes liés aux codes de réponse de fin d’appel.
const callEndReason = remoteParticipant.callEndReason;
const callEndReasonCode = callEndReason.code
const callEndReasonSubCode = callEndReason.subCode
  • isMuted : retourne une valeur Boolean représentant un état désactivé local.
const isMuted = remoteParticipant.isMuted;
  • isSpeaking : retourne une valeur Boolean représentant l’état de l’audio non vide envoyé.
const isSpeaking = remoteParticipant.isSpeaking;
  • videoStreams : retourne la collection d’objets RemoteVideoStream envoyés par les participants.
const videoStreams = remoteParticipant.videoStreams; // [RemoteVideoStream, ...]
  • displayName : retourne une string représentant un nom d’affichage. Le Kit de développement logiciel (SDK) Communication Services Calling ne définit pas cette valeur pour les utilisateurs Teams.
const displayName = remoteParticipant.displayName;

Appeler

  • id : retourne une chaîne représentant un identificateur d’appel unique.
const callId = call.id;

info : Retourne des informations sur l’appel :

Remarque

Cet API est fourni en tant qu’aperçu pour les développeurs et peut être modifié en fonction des commentaires que nous avons reçus. N’utilisez pas cet API dans un environnement de production. Pour utiliser cette API, utilisez la version « bêta » du Kit de développement logiciel (SDK) Azure Communication Services Appel web.

info : retourne un objet contenant das informations sur l’appel. La propriété threadId est une chaîne représentant l’ID de thread de conversation affiché dans le client Teams.

const callInfo = call.info;
const threadId = call.info.threadId;

remoteParticipants : retourne une collection d’objets remoteParticipant représentant d’autres participants à l’appel ou à la réunion Teams.

const remoteParticipants = call.remoteParticipants;

callerInfo : retourne l’objet CallerInfo pour les appels entrants. La propriété identifier peut être l’un des objets suivants CommunicationUserIdentifier, MicrosoftTeamsUserIdentifier, PhoneNumberIdentifier ou UnknownIdentifier. La propriété displayName est une chaîne représentant le nom à afficher si elle est définie.

const callerIdentity = call.callerInfo.identifier;
const callerIdentity = call.callerInfo.displayName;

state : retourne une chaîne représentant l’état de l’appel. La propriété peut avoir l’une des valeurs suivantes :

Valeur d’état Lorsque le répertoire Description
None InitialState État initial de l’appel.
Connecting Après None État dans lequel un appel ou une réunion Teams est passé, rejoint ou accepté.
Ringing Après Connecting Le participant distant a reçu l’événement incomingCall ou un client Teams sonne.
EarlyMedia Après Ringing ou Connecting Le média est lu avant que l’appel soit connecté.
Connected Après Ringing, EarlyMedia, InLobby, LocalHold et RemoteHold L’appel est connecté. Le média circule entre les points de terminaison locaux et les participants distants.
LocalHold Après Connected L’appel a été mis en attente par un participant local. Aucun média ne circule entre le point de terminaison local et les participants distants.
RemoteHold Après Connected L’appel a été mis en attente par un participant distant. Aucun média ne circule entre le point de terminaison local et les participants distants.
InLobby Après Ringing ou Connecting Le participant distant se trouve dans la salle d’attente de réunion Teams. Aucun média ne circule entre le point de terminaison local et les participants distants.
Disconnecting Après n’importe quel état État de transition avant que l’appel passe à l’état Disconnected.
Disconnected État final État final de l’appel. Si la connexion réseau est perdue, l’état passe à Disconnected au bout de deux minutes.

États pour les appels individuels ou les appels de groupe : Diagramme avec les états des appels individuels ou de groupe.

États des réunions Teams : Diagramme avec les états d’appel des réunions Teams.

const callState = call.state;

callEndReason : retourne un objet CallEndReason contenant des informations supplémentaires sur l’appel s’est terminé. La propriété code retourne un nombre associé à la raison, et subCode retourne un nombre associé au code et à la raison. Pour plus d’informations sur les codes d’erreur, consultez Résolution des problèmes liés aux codes de réponse de fin d’appel.

const callEndReason = call.callEndReason;
const callEndReasonCode = callEndReason.code
const callEndReasonSubCode = callEndReason.subCode

direction : retourne un string représentant la direction de l’appel. La propriété peut avoir l’une des valeurs suivantes : Incoming ou Outgoing.

const isIncoming = call.direction == 'Incoming';
const isOutgoing = call.direction == 'Outgoing';

isMuted : retourne la valeur Boolean représentant un état désactivé local.

const muted = call.isMuted;

isScreenSharingOn : retourne la valeur Boolean true si vous envoyez un flux de partage d’écran à d’autres participants.

const isScreenSharingOn = call.isScreenSharingOn;

localVideoStreams : retourne une collection d’objets LocalVideoStream représentant des flux vidéo envoyés aux participants distants.

const localVideoStreams = call.localVideoStreams;

Gérer le thread de conversation

Fournir un ID de conversation est obligatoire pour effectuer des appels de groupe et ajouter des participants à des appels existants. Une conversation et un appel associés ont une liste distincte de participants. Avant d’ajouter des participants à l’appel, ajoutez l’utilisateur à la conversation pour offrir la meilleure expérience utilisateur et répondre aux exigences en matière de barrière des informations. L’ajout d’un utilisateur à l’appel sans l’ajouter à la conversation peut entraîner des exceptions si une barrière des informations est configurée.

Prenons le scénario suivant, où Alice appelle Bob, ajoute Charlie à l’appel, puis, 3 minutes plus tard, supprime Charlie de l’appel.

  1. Créez un thread de conversation entre Alice, Bob et Charlie. Conservez le threadId de conversation pour plus tard.
  2. Alice appelle Bob et Charlie à l’aide de la méthode startCall sur une instance TeamsCallAgent.
  3. Ajoutez Dan au thread de conversation avec threadId en utilisant l’API Graph de conversation pour ajouter un membre
  4. Alice ajoute Dan à l’appel à l’aide de la méthode addParticipant sur call, et spécifie le threadId
  5. Alice supprime Dan de l’appel à l’aide de la méthode removeParticipant sur call, et spécifie le threadId
  6. Supprimez Dan du thread de conversation avec threadId en utilisant l’API Graph de conversation pour supprimer un membre

Si l’utilisateur Teams arrête l’enregistrement d’appel, l’enregistrement est placé dans la conversation associée au thread. L’ID de conversation fourni a un impact sur l’expérience des utilisateurs Teams dans les clients Teams.

Recommandations pour la gestion de l’ID de conversation :

  • Escalade de l’appel téléphonique individuel en ajoutant un autre participant téléphonique : utilisez l’API Graph pour obtenir l’ID de conversation existant avec seulement un utilisateur Teams comme participant ou créez une conversation de groupe avec les participants : ID de l’utilisateur Teams et « 00000000-0000-0000-0000-000000000000 ».
  • Appel de groupe avec un seul utilisateur Teams et plusieurs participants par téléphone : utilisez l’API Graph pour obtenir l’ID de conversation existant avec seulement un utilisateur Teams comme participant ou créez une conversation de groupe avec les participants : ID de l’utilisateur Teams et « 00000000-0000-0000-0000-000000000000 ».
  • Appel de groupe avec plus de 2 utilisateurs Teams : utilisez l’API Graph pour obtenir ou créer une conversation de groupe avec les utilisateurs Teams.