Gestire le chiamate per gli utenti di Teams con l'SDK per chiamate di Servizi di comunicazione
Informazioni su come gestire chiamate con SDK di Servizi di comunicazione di Azure. Si apprenderà come effettuare chiamate e gestirne i partecipanti e le proprietà.
Prerequisiti
- Un account Azure con una sottoscrizione attiva. Creare un account gratuitamente.
- Una risorsa di Servizi di comunicazione distribuita. Creare una risorsa di Servizi di comunicazione.
- Un
User Access Token
per abilitare il client di chiamata. Per altre informazioni, vedere come ottenere unUser Access Token
- Facoltativo: completare l'avvio rapido per iniziare ad aggiungere funzionalità per chiamate video all'applicazione
Installazione dell'SDK
Usare il comando npm install
per installare l'SDK comuni e di chiamata dei Servizi di comunicazione di Azure per JavaScript.
npm install @azure/communication-common --save
npm install @azure/communication-calling --save
Inizializzare gli oggetti necessari
Creare un'istanza CallClient
per avviare lo stack di chiamate. È possibile configurare la registrazione dell'SDK per chiamate con l'istanza AzureLogger
e il metodo setLogLevel
. È possibile ottenere l'accesso a deviceManager
per il sistema operativo con il metodo getDeviceManager
.
Usare quindi il metodo createTeamsCallAgent
per creare in modo asincrono un'istanza TeamsCallAgent
che gestirà le chiamate in ingresso e in uscita per un utente di Teams. Il metodo accetta CommunicationTokenCredential
come argomento che rappresenta il token di accesso per l'utente di 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();
Effettua una chiamata
Avviare una chiamata uno-a-uno o di gruppo sincrona con l'API startCall
in teamsCallAgent
. È possibile specificare MicrosoftTeamsUserIdentifier
o PhoneNumberIdentifier
come parametro per definire la destinazione della chiamata. Il metodo restituisce l'istanza TeamsCall
che consente di sottoscrivere gli eventi di chiamata.
Nota
Avviare una chiamata di gruppo con teamsCallAgent
richiede threadId
della chat quando si chiama il metodo startCall
. L'istanza TeamsCall
creata ha la proprietà threadId
che acquisisce questo thread. L'SDK di chiamata dei Servizi di comunicazione non mantiene sincronizzati i partecipanti negli elenchi delle chat e delle chiamate. Microsft incoraggia gli sviluppatori a mantenere sincronizzato il roster per un'esperienza utente ottimale. Informazioni su come gestire il thread di chat.
Avviare una chiamata Voice-over IP (VoIP) uno-a-uno all'utente di Teams:
const userCallee = { microsoftTeamsUserId: '<MICROSOFT_TEAMS_USER_ID>' };
const oneToOneCall = teamsCallAgent.startCall(userCallee);
Avviare una telefonata uno-a-uno al numero di telefono E.164:
const phoneCallee = { phoneNumber: '<PHONE_NUMBER_E164_FORMAT>' }
const oneToOneCall = teamsCallAgent.startCall(phoneCallee );
Avviare una chiamata di gruppo all'utente di Teams con Voice-over IP (VoIP) e numero di telefono:
const userCallee = { microsoftTeamsUserId: '<MICROSOFT_TEAMS_USER_ID>' }
const phoneCallee = { phoneNumber: '<PHONE_NUMBER_E164_FORMAT>'};
const groupCall = teamsCallAgent.startCall([userCallee, phoneCallee], { threadId: '<THREAD_ID>' });
Partecipare a una chiamata
Partecipare a una riunione di Teams
È possibile partecipare alle riunioni di Teams con il metodo join
nell'istanza teamsCallAgent
. Gli utenti di Teams possono partecipare alla riunione di Teams fornendo un TeamsMeetingLinkLocator
, TeamsMeetingCoordinatesLocator
o TeamsMeetingIdLocator
.
Partecipare alla riunione di Teams con l'URL della riunione:
const meetingCall = teamsCallAgent.join({ meetingLink: '<MEETING_LINK>' });
Partecipare alla riunione di Teams con combinazione di ID thread, ID organizzatore, ID tenant e ID messaggio:
const meetingCall = teamsCallAgent.join({ threadId: '<THREAD_ID>', organizerId: '<ORGANIZER_ID>', tenantId: '<TENANT_ID>', messageId: '<MESSAGE_ID>' });
Partecipare alla riunione di Teams con codice di riunione e passcode:
const meetingCall = teamsCallAgent.join({ meetingId: '<MEETING_CODE>', passcode: '<PASSCODE>'});
Partecipare alla riunione di Teams con ID riunione e passcode:
Gli sviluppatori possono connettere i partecipanti a una riunione di Teams in diversi modi. Un modo consiste nell'usare un ID riunione e un passcode, che consente agli utenti di partecipare alla riunione di Teams a cui sono invitati da un dispositivo o un'applicazione. È sempre necessario specificare sia l'ID riunione che il passcode per partecipare alla riunione. Il passcode fa distinzione tra maiuscole e minuscole.
Formato dell'ID riunione e del passcode:
- ID riunione: 12 cifre.
- Passcode: 6 caratteri
Con quale frequenza è necessario aggiornare l'ID riunione e il passcode?
- L'ID riunione e il passcode non cambiano dopo la creazione. Gli sviluppatori non devono aggiornare uno dei due.
- Un organizzatore della riunione di Teams non può rigenerare l'ID riunione e il passcode.
Esiste una differenza nell'esperienza di riunione di Teams se una persona partecipa tramite URL o ID riunione e passcode?
- No, i partecipanti hanno la stessa esperienza se partecipano a una riunione di Teams usando l'URL della riunione di Teams o l'ID riunione e il passcode.
In che modo gli sviluppatori devono archiviare e gestire i passcode?
- L'ID riunione e il passcode sono coordinate per partecipare alla riunione. Gli sviluppatori devono considerarli segreti, che devono essere crittografati e, se archiviati, assicurarsi che si trovino in un ambiente controllato dall'accesso.
- Se le coordinate sono esposte, chiunque può partecipare alla riunione e rovinare l'esperienza per tutti gli utenti della riunione.
Come ottenere l'ID riunione e il passcode?
- API Graph: usare l'API Graph per recuperare informazioni sulla risorsa
onlineMeeting
e controllare l'oggetto nella proprietàjoinMeetingIdSettings
. - Teams: nell'applicazione Teams andare all'app
Calendar
e aprire i dettagli di una riunione. Le riunioni online hanno ID riunione e passcode nella definizione della riunione. - Outlook: è possibile trovare l'ID riunione e il passcode negli eventi del calendario o negli inviti alle riunioni tramite e-mail.
- Gli sviluppatori non possono recuperare l'ID riunione e il passcode tramite la chiamata dell'SDK o recuperarli dai log dettagliati della console.
- API Graph: usare l'API Graph per recuperare informazioni sulla risorsa
Come è possibile verificare che l'ID riunione e il passcode siano corretti?
- MeetingId e verifica passcode possono essere eseguiti tramite: https://www.microsoft.com/en-us/microsoft-teams/join-a-meeting.
Ricevere una chiamata in arrivo di Teams
È possibile sottoscrivere l'evento incomingCall
nell'istanza teamsCallAgent
per registrare le chiamate in ingresso all'utente di Teams. L'evento ha una proprietà teamsIncomingCall
con un'istanza TeamsIncomingCall
che consente di accept
o reject
la chiamata in ingresso.
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);
Abilitare e disabilitare il video
È possibile ottenere la raccolta di flussi video locale dalla proprietà localVideoStreams
nell'istanza TeamsCall
. Se abilitata, la raccolta contiene un flusso di condivisione dello schermo e feed video della fotocamera. È possibile ottenere flussi video dei partecipanti remoti esaminando la proprietà TeamsCall
.remoteParticipants
dove ogni partecipante ha una raccolta di flussi video nella proprietà videoStreams
.
Disattivare e attivare l'audio
È possibile usare le API asincrone mute
e unmute
nell'istanza TeamsCall
per disattivare o disattivare l'audio degli utenti di Teams in locale. L'audio locale impedisce l'invio dell'audio ad altri partecipanti.
//mute local device
await call.mute();
//unmute local device
await call.unmute();
Disattivare l'audio per altri partecipanti
Per disattivare l’audio per tutti gli altri partecipanti o per un partecipante specifico, usare le API asincrone muteAllRemoteParticipants
sulla chiamata e mute
sul partecipante in remoto:
//mute all participants except yourself
await call.muteAllRemoteParticipants();
//mute a specific participant
await call.remoteParticipants[0].mute();
Nota
Questa API viene fornita come anteprima per gli sviluppatori e potrebbe essere modificata in base ai commenti ricevuti. Non usare questa API in un ambiente di produzione. Per usare questa API, usare la versione 'beta' di Azure Communication Services Calling Web SDK
Gestire partecipanti remoti
Altri partecipanti alla chiamata sono disponibili nell'istanza TeamsCall
nella proprietà remoteParticipants
. Una raccolta di oggetti RemoteParticipant
. È possibile elencare, aggiungere e rimuovere altri partecipanti dalla chiamata.
Nota
L'aggiunta di un metodo partecipante richiede threadId
della chat. L'SDK di chiamata dei Servizi di comunicazione non mantiene sincronizzati i partecipanti negli elenchi delle chat e delle chiamate. Microsft incoraggia gli sviluppatori a mantenere sincronizzato il roster per un'esperienza utente ottimale. Informazioni su come gestire il thread di chat.
È possibile aggiungere un nuovo utente o numero di telefono di Teams alla chiamata di Teams o alla riunione di Teams chiamando il metodo addParticipant
sull'oggetto TeamsCall
. Il metodo accetta identificatori MicrosoftTeamsUserIdentifier
o PhoneNumberIdentifier
come input e restituisce in modo sincrono l'istanza di RemoteParticipant
e attiva l'evento remoteParticipantsUpdated
nell'istanza TeamsCall
.
È possibile rimuovere un partecipante dalla chiamata di Teams o dalla riunione di Teams richiamando il metodo removeParticipant
nell'istanza TeamsCall
in modo asincrono. Il metodo accetta identificatori MicrosoftTeamsUserIdentifier
o PhoneNumberIdentifier
come input. Il metodo viene risolto quando RemoteParticipant
viene rimosso dalla raccolta remoteParticipants
e l'evento remoteParticipantsUpdated
nell'istanza TeamsCall
viene attivato.
Elencare altri partecipanti alla chiamata:
const participants = call.remoteParticipants; // [remoteParticipant, remoteParticipant....]
Aggiungere l'utente e il numero di telefono di Teams alla chiamata di Teams o alla riunione di 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>' });
Rimuovere l'utente e il numero di telefono di Teams dalla chiamata di Teams o dalla riunione di Teams:
const teamsUser = { microsoftTeamsUserId: '<MICROSOFT_TEAMS_USER_ID>' };
const phoneUser = { phoneNumber: '<PHONE_NUMBER_E164_FORMAT>' }
await call.removeParticipant(teamsUser);
await call.removeParticipant(phoneUser);
Partecipanti remoti
I partecipanti remoti rappresentano un endpoint connesso alla chiamata di Teams in corso o alla riunione di Teams. La classe remoteParticipant
include il set di proprietà e raccolte seguente:
identifier
: restituisce uno degli identificatori seguenti:CommunicationUserIdentifier
,MicrosoftTeamsUserIdentifier
,PhoneNumberIdentifier
oUnknownIdentifier
.
const identifier = remoteParticipant.identifier;
state
: restituisce un oggettostring
che rappresenta uno stato di un partecipante remoto. Lo stato può avere uno dei valori seguenti:
Valore di stato | Se | Descrizione |
---|---|---|
Idle |
Stato iniziale | Questo è il primo stato del partecipante |
Connecting |
Dopo Idle |
Stato di transizione mentre un partecipante si connette alla chiamata. |
Ringing |
Dopo Connecting |
Il partecipante ha ricevuto una notifica incomingCall o il client di Teams sta suonando |
Connected |
Dopo Ringing , Connecting EarlyMedia , o InLobby |
Il partecipante ha accettato l'invito alla chiamata o ha partecipato alla chiamata. I contenuti multimediali passano verso il partecipante. |
Hold |
Dopo Connected |
Il partecipante della chiamata è in attesa. |
EarlyMedia |
Dopo Connecting |
Il supporto viene riprodotto prima che un partecipante si connetta alla chiamata |
InLobby |
Dopo Ringing , Connecting o EarlyMedia |
Il partecipante si trova nella sala di attesa delle riunioni di Teams. |
Disconnected |
Stato finale | Il partecipante viene disconnesso dalla chiamata. Se il partecipante in remoto perde la connettività di rete, il suo stato diventa Disconnected dopo due minuti. |
Stati dei partecipanti remoti in chiamate uno-a-uno o di gruppo:
Stati dei partecipanti remoti alle riunioni di Teams:
const state = remoteParticipant.state;
callEndReason
: restituisce un oggetto contenente informazioni aggiuntive sul motivo per cui la chiamata è terminata. La proprietàcode
restituisce un numero associato al motivo esubCode
restituisce un numero associato al codice e al motivo. Per altre informazioni sui codici di errore, vedere Risoluzione dei problemi relativi ai codici di risposta di fine chiamata.
const callEndReason = remoteParticipant.callEndReason;
const callEndReasonCode = callEndReason.code
const callEndReasonSubCode = callEndReason.subCode
isMuted
: restituisce il valoreBoolean
che rappresenta lo stato dell'audio locale.
const isMuted = remoteParticipant.isMuted;
isSpeaking
: restituisce il valoreBoolean
che rappresenta lo stato dell'audio non interrotto inviato.
const isSpeaking = remoteParticipant.isSpeaking;
videoStreams
: restituisce l'insieme di oggettiRemoteVideoStream
inviati dai partecipanti.
const videoStreams = remoteParticipant.videoStreams; // [RemoteVideoStream, ...]
displayName
: restituisce unstring
che rappresenta il nome visualizzato. Servizi di comunicazione che chiamano SDK non imposta questo valore per gli utenti di Teams.
const displayName = remoteParticipant.displayName;
Call
id
: restituisce una stringa che rappresenta un identificatore di chiamata univoco.
const callId = call.id;
• info
: restituisce informazioni sulla chiamata:
Nota
Questa API viene fornita come anteprima per gli sviluppatori e potrebbe essere modificata in base ai commenti ricevuti. Non usare questa API in un ambiente di produzione. Per usare questa API, usare la versione "beta" di Azure Communication Services Calling Web SDK
• info
: restituisce un oggetto contenente informazioni sulla chiamata. La proprietà threadId
è una stringa che rappresenta l'ID thread della chat visualizzato nel client teams.
const callInfo = call.info;
const threadId = call.info.threadId;
• remoteParticipants
: restituisce una raccolta di oggetti remoteParticipant
che rappresentano altri partecipanti alla riunione di Teams o teams.
const remoteParticipants = call.remoteParticipants;
• callerInfo
: restituisce l'oggetto CallerInfo
per le chiamate in ingresso. La proprietà identifier
può essere uno degli oggetti seguenti CommunicationUserIdentifier
, MicrosoftTeamsUserIdentifier
, PhoneNumberIdentifier
o UnknownIdentifier
. La proprietà displayName
è una stringa che rappresenta il nome da visualizzare se impostata.
const callerIdentity = call.callerInfo.identifier;
const callerIdentity = call.callerInfo.displayName;
• state
: restituisce una stringa che rappresenta lo stato della chiamata. Di seguito vengono indicati i possibili valori della proprietà:
Valore di stato | Se | Descrizione |
---|---|---|
None |
Stato iniziale | Stato iniziale della chiamata. |
Connecting |
Dopo None |
Stato quando viene inserita, unita o accettata una riunione di Teams o una chiamata di Teams. |
Ringing |
Dopo Connecting |
Il partecipante remoto ha ricevuto l'evento incomingCall o il client teams sta suonando. |
EarlyMedia |
Dopo Ringing o Connecting |
Il supporto viene riprodotto prima che la chiamata sia connessa. |
Connected |
Dopo Ringing , EarlyMedia InLobby , LocalHold , e RemoteHold |
La chiamata è connessa. I supporti vengono trasmessi tra endpoint locali e partecipanti remoti. |
LocalHold |
Dopo Connected |
La chiamata è stata sospesa da un partecipante locale. Nessun elemento multimediale è in flusso tra l'endpoint locale e i partecipanti in remoto. |
RemoteHold |
Dopo Connected |
La chiamata è stata messa in attesa da un partecipante remoto. Nessun elemento multimediale è in flusso tra l'endpoint locale e i partecipanti in remoto. |
InLobby |
Dopo Ringing o Connecting |
Il partecipante remoto si trova nella sala di attesa delle riunioni di Teams. Nessun elemento multimediale è in flusso tra l'endpoint locale e i partecipanti in remoto. |
Disconnecting |
Dopo qualsiasi stato | Stato di transizione prima che la chiamata passi a uno stato Disconnected . |
Disconnected |
Stato finale | Stato finale della chiamata. Se la connessione di rete va persa, lo stato diventa Disconnected dopo due minuti. |
Stati per chiamate uno-a-uno o di gruppo:
Stati per le riunioni di Teams:
const callState = call.state;
• callEndReason
: restituisce un oggetto CallEndReason
contenente informazioni aggiuntive sulla chiamata terminata. La proprietà code
restituisce un numero associato al motivo e subCode
restituisce un numero associato al codice e al motivo. Per altre informazioni sui codici di errore, vedere Risoluzione dei problemi relativi ai codici di risposta di fine chiamata.
const callEndReason = call.callEndReason;
const callEndReasonCode = callEndReason.code
const callEndReasonSubCode = callEndReason.subCode
• direction
: restituisce un string
che rappresenta la direzione della chiamata. Di seguito vengono indicati i possibili valori della proprietà: "Ricevuta' o Outgoing
.
const isIncoming = call.direction == 'Incoming';
const isOutgoing = call.direction == 'Outgoing';
• isMuted
: restituisce il valore Boolean
che rappresenta lo stato dell'audio locale.
const muted = call.isMuted;
• isScreenSharingOn
: restituisce il valore true Boolean
se si invia un flusso di condivisione dello schermo ad altri partecipanti.
const isScreenSharingOn = call.isScreenSharingOn;
• localVideoStreams
: restituisce una raccolta di LocalVideoStream
oggetti che rappresentano i flussi video inviati ai partecipanti remoti.
const localVideoStreams = call.localVideoStreams;
Gestire il thread di chat
Importante
L'ID chat facoltativo è disponibile solo nella versione 1.29.1 o successiva di Calling SDK per JavaScript. Se si usa una versione precedente, assicurarsi di fornire manualmente un ID chat univoco.
Fornire un ID chat è facoltativo per effettuare chiamate di gruppo e aggiungere partecipanti alle chiamate esistenti. La chat e la chiamata associata hanno un elenco separato di partecipanti. Prima di aggiungere partecipanti alla chiamata, aggiungere l'utente alla chat per offrire la migliore esperienza utente e soddisfare i requisiti delle barriere informative. L'aggiunta di un utente alla chiamata senza aggiungere l'utente alla chat può comportare eccezioni se viene configurata una barriera informativa.
Si consideri lo scenario seguente, in cui Alice effettua una chiamata a Bob, quindi Alice aggiunge Charlie e 3 minuti dopo Alice rimuove Charlie dalla chiamata.
- Creare un thread di chat tra Alice, Bob e Charlie. Mantenere la chat
threadId
per un secondo momento. - Alice chiama Bob e Charlie usando il metodo
startCall
nell'istanzaTeamsCallAgent
. - Aggiungere Dan al thread di chat con
threadId
usando l'API Chat Graph per aggiungere un membro - Alice aggiunge Dan alla chiamata utilizzando il metodo
addParticipant
sucall
e specifica ilthreadId
- Alice rimuove Dan dalla chiamata utilizzando il metodo
removeParticipant
sucall
e specifica ilthreadId
- Rimuovere Dan dal thread di chat con
threadId
usando l'Api Chat Graph per rimuovere il membro
Se l'utente di Teams interrompe la registrazione delle chiamate, la registrazione viene inserita nella chat associata al thread. L'ID chat fornito influisce sull'esperienza degli utenti di Teams nei client di Teams.
Raccomandazioni per la gestione dell'ID chat:
- Escalation della telefonata 1:1 aggiungendo un altro partecipante telefonico:
- Il metodo
addParticipant
consente di specificare l'ID chat del parametro facoltativo. Se il parametro non viene specificato, viene creata una nuova chat di gruppo e tutti i partecipanti vengono aggiunti all'elenco di partecipanti di chiamata e chat. Se viene specificato il parametro, gli utenti di Teams possono visualizzare la chiamata in corso associata a questa chat di gruppo nell'app Teams. È possibile creare una nuova chat di gruppo tramite l'API Graph.addParticipant(participant: MicrosoftTeamsUserIdentifier | PhoneNumberIdentifier | MicrosoftTeamsAppIdentifier | UnknownIdentifier)
- Il metodo
- Avviare una chiamata di gruppo con un singolo utente di Microsoft 365 e più partecipanti al telefono:
- L'API del metodo
startCall
consente di avviare una chiamata di gruppo con più partecipanti e, facoltativamente, fornire l'ID chat. Se il parametro non viene specificato, viene creata una nuova chat di gruppo e tutti i partecipanti a Microsoft 365 vengono aggiunti all'elenco di partecipanti di chiamata e chat. Se viene specificato il parametro, gli utenti di Teams possono visualizzare la chiamata in corso associata a questa chat di gruppo nell'app Teams. È possibile creare una nuova chat di gruppo tramite l'API Graph.startCall(MicrosoftTeamsUserIdentifier | PhoneNumberIdentifier | MicrosoftTeamsAppIdentifier | UnknownIdentifier)[])
- Usare l'API Graph per ottenere l'ID chat esistente con solo l'utente di Teams come partecipante o creare una nuova chat di gruppo con partecipanti: ID utente di Teams e "0000000-0000-0000-0000000000000".
- L'API del metodo
- Avviare la chiamata di gruppo con più di 2 utenti di Microsoft 365:
- (Modo facoltativo) Quando si effettua una chiamata di gruppo con più di 2 utenti di Microsoft 365 che usano ACS Calling SDK, l'SDK creerà automaticamente il thread per impostazione predefinita.
startCall(MicrosoftTeamsUserIdentifier | PhoneNumberIdentifier | MicrosoftTeamsAppIdentifier | UnknownIdentifier)[])
- Se necessario, lo sviluppatore può fornire un ID di chat univoco per avviare la chiamata di gruppo o aggiungere partecipanti. In questo caso, ACS Calling SDK userà l'ID chat specificato per creare la chiamata di gruppo. Viene creato un thread di chat per gli utenti di Teams e questo thread è associato alla chiamata di gruppo per gli utenti nell'app Teams. Ciò consente loro di chattare durante la chiamata. La gestione dei thread di chat può essere eseguita tramite l'API Graph
- (Modo facoltativo) Quando si effettua una chiamata di gruppo con più di 2 utenti di Microsoft 365 che usano ACS Calling SDK, l'SDK creerà automaticamente il thread per impostazione predefinita.