Compartir a través de


Administración de llamadas para usuarios de Teams con el SDK de llamada de Communication Services

Aprenda a administrar llamadas con los SDK de Azure Communication Services. Aquí se va a aprender a realizar llamadas y a administrar sus participantes y sus propiedades.

Requisitos previos

Instalación del SDK

Use el comando npm install para instalar los SDK comunes y de llamada de Azure Communication Services para JavaScript.

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

Inicialización de los objetos necesarios

Cree una instancia CallClient para iniciar la pila de llamadas. Puede configurar el registro de llamadas al SDK con la instancia AzureLogger y el método setLogLevel. Puede obtener acceso a deviceManager para el sistema operativo con el método getDeviceManager.

A continuación, use el método createTeamsCallAgent para crear de forma asincrónica una instancia TeamsCallAgent que administrará las llamadas entrantes y salientes para un usuario de Teams. El método toma CommunicationTokenCredential como argumento que representa el token de acceso para el usuario de 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();

Realización de una llamada

Inicie una llamada sincrónica de uno a uno o en grupo con la API startCall en teamsCallAgent. Puede proporcionar MicrosoftTeamsUserIdentifier o PhoneNumberIdentifier como parámetro para definir el destino de la llamada. El método devuelve la instancia de TeamsCall que permite suscribirse a eventos de llamada.

Nota:

Iniciar una llamada en grupo con teamsCallAgent requiere el threadId del chat al llamar al método startCall. La instancia creada TeamsCall tiene la propiedad threadId que captura este subproceso. El SDK de llamadas de Communication Services no mantiene sincronizados a los participantes en la lista de llamadas y chat. Microsoft anima a los desarrolladores a mantener sincronizada la lista para obtener la mejor experiencia de usuario. Obtenga información sobre cómo administrar subproceso de chat.

Inicie una llamada de voz a uno a través de la IP (VoIP) al usuario de Teams:

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

Inicie una llamada telefónica de uno a uno al número de teléfono E.164:

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

Inicie una llamada en grupo al usuario de Teams con IP a través de voz (VoIP) y el número de teléfono:

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

Unirse a una llamada

Unirse a reunión de Teams

Puede unirse a reuniones de Teams con el método join en la instancia de teamsCallAgent. Los usuarios de Teams pueden unirse a la reunión de Teams proporcionando un TeamsMeetingLinkLocator, TeamsMeetingCoordinatesLocatoro TeamsMeetingIdLocator.

Únase a la reunión de Teams con la dirección URL de la reunión:

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

Únase a la reunión de Teams con la combinación de identificador de subproceso, identificador de organizador, identificador de inquilino e identificador de mensaje:

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

Únase a la reunión de Teams con el código de la reunión y la contraseña:

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

Únase a la reunión de Teams con el Id. de la reunión y el código de acceso:

Los desarrolladores pueden usar varias maneras de unirse a la reunión de Teams. Uno de ellos es el Id. de reunión y código de acceso, que permite a las personas unirse a la reunión de Teams a la que han sido invitadas desde un dispositivo o aplicación. Para entrar en la reunión, siempre es necesario proporcionar el Id. de la reunión y el código de acceso. El código de acceso distingue entre mayúsculas y minúsculas.

  • El formato del id. de reunión y el código de acceso es:

    • Id. de reunión: 12 dígitos.
    • Código de acceso: 6 caracteres
  • ¿Con qué frecuencia necesita actualizar el Id. de reunión y el código de acceso?

    • El Id. de reunión y el código de acceso no cambian una vez creados. Los desarrolladores no necesitan actualizar ninguno de ellos para el cambio.
    • El organizador de la reunión de Teams no puede regenerar el Id. y el código de acceso de la reunión.
  • ¿Hay alguna diferencia en la experiencia de reunión de Teams si el usuario se une a través de la dirección URL o el Id. de reunión y el código de acceso?

    • No. Los usuarios tendrán la misma experiencia de usuario si se unen a la reunión de Teams a través de la URL de la reunión de Teams o del Id. de la reunión y el código de acceso.
  • ¿Cómo deben almacenar y administrar los desarrolladores el código de acceso?

    • El Id. de reunión y el código de acceso son coordenadas para unirse a la reunión. Los desarrolladores deben tratarlo como secreto, que se debe cifrar y si se almacenan detrás del control de acceso.
    • Si las coordenadas están expuestas, cualquiera puede unirse a la reunión y arruinar la experiencia de todos los presentes.
  • ¿Cómo obtener el Id. de reunión y el código de acceso?

    1. Graph API: use Graph API para recuperar información sobre el recurso onlineMeeting y comprobar el objeto en la propiedad joinMeetingIdSettings.
    2. Teams: en la aplicación de Teams, vaya a la aplicación Calendar y abra los detalles de una reunión. Las reuniones en línea tienen el identificador de reunión y el código de acceso en la definición de la reunión.
    3. Outlook: Puede encontrar el Id. de reunión y el código de acceso en eventos de calendario o en invitaciones de reunión por correo electrónico.
    4. Los desarrolladores no pueden recuperar el Id. de reunión y el código de acceso a través del SDK de llamada o recuperarlo de registros detallados de la consola.
  • ¿Cómo puedo comprobar que el Id. de reunión y el código de acceso son correctos?

Recepción de una llamada entrante de Teams

Puede suscribirse al evento incomingCall en la instancia teamsCallAgent para registrar llamadas entrantes al usuario de Teams. El evento tiene una propiedad teamsIncomingCall con instancia TeamsIncomingCall que le permite accept (aceptar) o reject (rechazar) la llamada entrante.

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);

Habilitar y deshabilitar vídeo

Puede obtener la colección de secuencias de vídeo local desde la propiedad localVideoStreams en la instancia TeamsCall. Si está habilitada, la colección contendrá una secuencia de uso compartido de pantalla y fuentes de vídeo. Puede obtener secuencias de vídeo de participantes remotos inspeccionando la propiedad TeamsCall.remoteParticipants, donde cada participante tiene una colección de secuencias de vídeo en la propiedad videoStreams.

Silenciar y Reactivar audio

Puede usar las API asincrónicas mute y unmute en la instancia TeamsCall para silenciar o reactivar el sonido de los usuarios de Teams de forma local. La silenciación local impedirá que se envíe audio a otros participantes.

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

Silenciar a otros participantes

Para silenciar a todos los demás participantes o silenciar a un participante específico, puede usar las API asincrónicas muteAllRemoteParticipants en la llamada y mute en el participante remoto:

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

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

Nota:

Esta API se ofrece a los desarrolladores como versión preliminar y puede cambiar en función de los comentarios que recibamos. No utilice esta API en un entorno de producción. Para usar esta API, use la versión "beta" del SDK web de llamada de Azure Communication Services.

Administración de participantes remotos

Otros participantes de la llamada están disponibles en la instancia TeamsCall en la propiedad remoteParticipants. Es una colección de objetos RemoteParticipant. Puede enumerar, agregar y quitar otros participantes de la llamada.

Nota:

El método de agregar un participante requiere el threadId del chat. El SDK de llamadas de Communication Services no mantiene sincronizados a los participantes en la lista de llamadas y chat. Microsoft anima a los desarrolladores a mantener sincronizada la lista para obtener la mejor experiencia de usuario. Obtenga información sobre cómo administrar subproceso de chat.

Puede agregar un nuevo número de teléfono o usuario de Teams a la llamada de Teams o a la reunión de Teams llamando al método addParticipant en el objeto TeamsCall. El método acepta los identificadores MicrosoftTeamsUserIdentifier y PhoneNumberIdentifier como entrada, devuelve sincrónicamente la instancia RemoteParticipant y desencadena el evento remoteParticipantsUpdated en la instancia TeamsCall.

Puede quitar un participante de la llamada de Teams o la reunión de Teams invocando el método removeParticipant en la instancia TeamsCall de forma asincrónica. El método acepta identificadores MicrosoftTeamsUserIdentifier y PhoneNumberIdentifier como entrada. El método se resuelve cuando se quita RemoteParticipant de la colección remoteParticipants y se desencadena el evento remoteParticipantsUpdated en la instancia TeamsCall.

Enumerar otros participantes de la llamada:

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

Agregue el número de teléfono y el usuario de Teams a la llamada de Teams o a la reunión de 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>' });

Quite el número de teléfono y el usuario de Teams de la llamada de Teams o de la reunión de Teams:

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

Participantes remotos

Los participantes remotos representan un punto de conexión conectado a la llamada de Teams en curso o a la reunión de Teams. La clase remoteParticipant tiene el siguiente conjunto de propiedades y colecciones:

  • identifier: Devuelve uno de los siguientes identificadores: CommunicationUserIdentifier, MicrosoftTeamsUserIdentifier, PhoneNumberIdentifier o UnknownIdentifier.
const identifier = remoteParticipant.identifier;
  • state: Devuelve un objeto string que representa un estado de un participante remoto. El estado puede tener uno de los siguientes valores:
Valor de estado Cuando Descripción
Idle Estado inicial Este es el primer estado del participante.
Connecting Después de Idle Estado de transición mientras un participante se conecta a la llamada.
Ringing Después de Connecting El participante recibió una notificación de incomingCall (llamada entrante) o el cliente de Teams está llamando.
Connected Después de Ringing, Connecting, EarlyMedia o InLobby El participante aceptó la invitación de llamada o se unió a la llamada. Los elementos multimedia fluyen hacia el participante.
Hold Después de Connected El participante de la llamada está en espera.
EarlyMedia Después de Connecting El medio se reproduce antes de que un participante se conecte a la llamada.
InLobby Después de Ringing, Connecting o EarlyMedia El participante está en la sala de espera de la reunión de Teams.
Disconnected Estado final El participante se desconecta de la llamada. Si el participante remoto pierde la conectividad de red, su estado cambia a Disconnected tras dos minutos.

Estados de los participantes remotos en llamadas individuales o de grupo: Diagram of remote participant's call states for one-to-one or group calls.

Estados de participantes remotos en reuniones de Teams: Diagram of remote participant's call states for Teams meetings.

const state = remoteParticipant.state;
  • callEndReason: Devuelve un objeto que contiene información adicional sobre el motivo por el que finalizó la llamada. La propiedad code devuelve un número asociado al motivo y subCode devuelve un número asociado al código y al motivo. Puede encontrar más información sobre los códigos de error.
const callEndReason = remoteParticipant.callEndReason;
const callEndReasonCode = callEndReason.code
const callEndReasonSubCode = callEndReason.subCode
  • isMuted: Devuelve el valor Boolean, que representa un estado de silenciación local.
const isMuted = remoteParticipant.isMuted;
  • isSpeaking: Devuelve el valor Boolean, que representa el estado del audio no vacío que se envía.
const isSpeaking = remoteParticipant.isSpeaking;
  • videoStreams: Devuelve la colección de objetos RemoteVideoStream que envían los participantes.
const videoStreams = remoteParticipant.videoStreams; // [RemoteVideoStream, ...]
  • displayName: Devuelve una string, que representa el nombre para mostrar. El SDK de llamadas de Communication Services no establece este valor para los usuarios de Teams.
const displayName = remoteParticipant.displayName;

Call

  • id: Devuelve una cadena que representa un identificador de llamada único.
const callId = call.id;

info: Devuelve información sobre la llamada:

Nota:

Esta API se ofrece a los desarrolladores como versión preliminar y puede cambiar en función de los comentarios que recibamos. No utilice esta API en un entorno de producción. Para usar esta API, use la versión 'beta' de Azure Communication Services Calling Web SDK.

info: Devuelve el objeto que contiene información sobre la llamada. La propiedad threadId es una cadena que representa el identificador de subproceso del chat que se muestra en el cliente de Teams.

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

remoteParticipants: Devuelve una colección de objetos remoteParticipant, que representan a otros participantes en la llamada o reunión de Teams.

const remoteParticipants = call.remoteParticipants;

callerInfo: Devuelve el objeto CallerInfo si se trata de una llamada entrante. La propiedad identifier puede ser uno de los siguientes objetos: CommunicationUserIdentifier, MicrosoftTeamsUserIdentifier, PhoneNumberIdentifiero UnknownIdentifier. La propiedad displayName es una cadena que representa el nombre que se va a mostrar si se establece.

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

state: Devuelve una cadena que representa el estado de la llamada. La propiedad puede tener uno de los siguientes valores:

Valor de estado Cuando Descripción
None Estado inicial Estado inicial de la llamada.
Connecting Después de None Estado cuando se empieza, se une o acepta una llamada de Teams o una reunión de Teams.
Ringing Después de Connecting El participante remoto ha recibido el evento incomingCall o el cliente de Teams está llamando.
EarlyMedia Después de Ringing o Connecting El elemento multimedia se reproduce antes de que se conecte la llamada.
Connected Después de Ringing, EarlyMedia, InLobby, LocalHold y RemoteHold La llamada está conectada. Los medios fluyen entre los puntos de conexión locales y los participantes remotos.
LocalHold Después de Connected Un participante local ha puesto la llamada en espera. No hay flujo de medios entre el punto de conexión local y los participantes remotos.
RemoteHold Después de Connected Un participante remoto ha puesto la llamada en espera. No hay flujo de medios entre el punto de conexión local y los participantes remotos.
InLobby Después de Ringing o Connecting El participante remoto está en la sala de espera de la reunión de Teams. No hay flujo de medios entre el punto de conexión local y los participantes remotos.
Disconnecting Después de cualquier estado Estado de transición antes de que la llamada vaya al estado Disconnected (desconectado).
Disconnected Estado final Estado final de la llamada. Si se pierde la conexión de red, el estado cambia a Disconnected después de dos minutos.

Estados para llamadas individuales o de grupo: Diagram with call's states for one-to-one or group calls.

Estados para reuniones de Teams: Diagram with call's states for Teams meetings.

const callState = call.state;

callEndReason: Devuelve el objeto CallEndReason, que contiene información adicional sobre la llamada finalizada. La propiedad code devuelve un número asociado al motivo y subCode devuelve un número asociado al código y al motivo. Puede encontrar más información sobre los códigos de error.

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

direction: Devuelve una string, que representa la dirección de la llamada. La propiedad puede tener uno de los siguientes valores: "Incoming" (entrante) o Outgoing (saliente).

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

isMuted: Devuelve el valor Boolean, que representa un estado de silenciación local.

const muted = call.isMuted;

isScreenSharingOn: Devuelve el valor true Boolean si envía secuencias de uso compartido de pantalla a otros participantes.

const isScreenSharingOn = call.isScreenSharingOn;

localVideoStreams: Devuelve una colección de objetos LocalVideoStream, que representan las secuencias de vídeo que se envían a los participantes remotos.

const localVideoStreams = call.localVideoStreams;

Administración de subprocesos de chat

La aportación de un id. de chat es obligatoria para realizar llamadas en grupo y agregar participantes a llamadas existentes. El chat y la llamada asociados tienen una lista independiente de participantes. Antes de agregar participantes a la llamada, agregue el usuario al chat para proporcionar la mejor experiencia del usuario y satisfacer los requisitos de barrera de información. Agregar un usuario a la llamada sin agregar el usuario al chat puede dar lugar a excepciones si se configura una barrera de información.

Tenga en cuenta el siguiente escenario, donde Alice realiza una llamada a Bob, agrega a Charlie y, 3 minutos después, Alice saca a Charlie de la llamada.

  1. Se crea un hilo de chat entre Alice, Bob y Charlie. Se mantiene el threadId del chat para más adelante.
  2. Alice llama a Bob y Charlie mediante el método startCall en la instancia TeamsCallAgent.
  3. Añade a Dan al subproceso de chat con threadId mediante Chat Graph API para agregar miembro.
  4. Alice agrega Dan a la llamada mediante el método addParticipant en call y especifica el threadId.
  5. Alice quita Dan de la llamada mediante el método removeParticipant en call y especifica el threadId.
  6. Quita a Dan del subproceso de chat con threadId mediante el Chat Graph API para quitar a un miembro.

Si el usuario de Teams detiene la grabación de llamadas, la grabación se coloca en el chat asociado al subproceso. El id. de chat proporcionado afecta a la experiencia de los usuarios y los clientes de Teams.

Recomendaciones para la administración del id. de chat:

  • Escalación de la llamada 1:1 agregando otro participante: use Graph API para obtener el id. de chat con solo un usuario de Teams como participante, o cree un nuevo chat de grupo con participantes: id. de usuario de Teams y "00000000-0000-0000-0000-000000000000"
  • Llamada de grupo con un usuario de Teams y varios participantes: use Graph API para obtener el id. de chat con solo un usuario de Teams como participante, o cree un nuevo chat de grupo con participantes: id. de usuario de Teams y "00000000-0000-0000-0000-000000000000"
  • Llamada de grupo con más de dos usuarios de Teams: use Graph API para obtener o crear un chat de grupo con los usuarios de Teams