Управление вызовами для пользователей Teams с помощью пакета SDK для вызовов служб коммуникации
Узнайте, как управлять вызовами с помощью пакетов SDK Службы коммуникации Azure. Мы научимся размещать вызовы, управлять своими участниками и свойствами.
Необходимые компоненты
- Учетная запись Azure с активной подпиской. Создайте учетную запись бесплатно .
- Развернутый ресурс Служб коммуникации. Создайте ресурс Служб коммуникации.
User Access Token
для включения клиента вызова. Дополнительные сведения о том, как получитьUser Access Token
- Необязательно. Выполните краткое руководство по началу работы с добавлением видеозвонка в приложение
Установка пакета SDK
С помощью команды npm install
вы можете установить пакеты SDK JavaScript Служб коммуникации Azure для вызовов и типичных операций.
npm install @azure/communication-common --save
npm install @azure/communication-calling --save
Инициализация обязательных объектов
CallClient
Создайте экземпляр для запуска стека вызовов. Ведение журнала вызовов пакета SDK можно настроить с помощью экземпляра AzureLogger
и setLogLevel
метода. Вы можете получить доступ к deviceManager
операционной системе с помощью метода getDeviceManager
.
Затем используйте метод createTeamsCallAgent
для асинхронного создания экземпляра TeamsCallAgent
, который будет управлять входящими и исходящими вызовами для пользователя Teams. Метод принимает CommunicationTokenCredential
в качестве аргумента, представляющего маркер доступа для пользователя 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();
Осуществление вызовов
Запустите синхронный вызов "один к одному" или "групп" с помощью startCall
API teamsCallAgent
. Можно указать MicrosoftTeamsUserIdentifier
или PhoneNumberIdentifier
как параметр, чтобы определить целевой объект вызова. Метод возвращает TeamsCall
экземпляр, позволяющий подписываться на вызовы событий.
Примечание.
Запустите групповой вызов с teamsCallAgent
помощью метода чата threadId
startCall
. Созданный TeamsCall
экземпляр имеет свойство threadId
, записывающее этот поток. Пакет SDK для звонков служб коммуникации не поддерживает участников чата и вызовов в синхронизации. Microsft призывает разработчиков сохранять список в синхронизации для лучшего взаимодействия с пользователем. Узнайте, как управлять потоком чата.
Запустите вызов ip-адреса голосовой связи (VoIP) для пользователя Teams:
const userCallee = { microsoftTeamsUserId: '<MICROSOFT_TEAMS_USER_ID>' };
const oneToOneCall = teamsCallAgent.startCall(userCallee);
Запустите телефонный звонок по телефону E.164:
const phoneCallee = { phoneNumber: '<PHONE_NUMBER_E164_FORMAT>' }
const oneToOneCall = teamsCallAgent.startCall(phoneCallee );
Запустите групповой звонок пользователю Teams с IP-адресом голосовой связи (VoIP) и номером телефона:
const userCallee = { microsoftTeamsUserId: '<MICROSOFT_TEAMS_USER_ID>' }
const phoneCallee = { phoneNumber: '<PHONE_NUMBER_E164_FORMAT>'};
const groupCall = teamsCallAgent.startCall([userCallee, phoneCallee], { threadId: '<THREAD_ID>' });
Присоединиться к звонку
Подключение к собранию Teams
Собрания Teams можно присоединить к методу join
в экземпляре teamsCallAgent
. Пользователи Teams могут присоединяться к собранию TeamsMeetingLinkLocator
TeamsMeetingCoordinatesLocator
Teams, предоставляя или TeamsMeetingIdLocator
.
Присоединение к собранию Teams с URL-адресом собрания:
const meetingCall = teamsCallAgent.join({ meetingLink: '<MEETING_LINK>' });
Присоединяйтесь к собранию Teams с сочетанием идентификатора потока, идентификатора организатора, идентификатора клиента и идентификатора сообщения:
const meetingCall = teamsCallAgent.join({ threadId: '<THREAD_ID>', organizerId: '<ORGANIZER_ID>', tenantId: '<TENANT_ID>', messageId: '<MESSAGE_ID>' });
Присоединяйтесь к собранию Teams с кодом собрания и секретным кодом:
const meetingCall = teamsCallAgent.join({ meetingId: '<MEETING_CODE>', passcode: '<PASSCODE>'});
Присоединяйтесь к собранию Teams с идентификатором собрания и секретным кодом:
Разработчики могут подключать участников к собранию Teams несколькими способами. Одним из способов является использование идентификатора собрания и секретного кода, который позволяет пользователям присоединяться к собранию Teams, к которому они приглашены на устройство или приложение. Для присоединения к собранию всегда необходимо указать идентификатор собрания и секретный код. Секретный код учитывает регистр.
Формат идентификатора собрания и секретного кода:
- Идентификатор собрания: 12 цифр.
- Секретный код: 6 символов
Как часто необходимо обновить идентификатор собрания и секретный код?
- Идентификатор собрания и секретный код не изменяются после создания. Разработчикам не нужно обновлять их.
- Организатор собраний Teams не может повторно создать идентификатор собрания и секретный код.
Есть ли разница в собрании Teams, если пользователь присоединяется через URL-адрес или идентификатор собрания и секретный код?
- Нет, участники имеют тот же интерфейс, если они присоединяются к собранию Teams с помощью URL-адреса собрания Teams или идентификатора собрания и секретного кода.
Как разработчики должны хранить секретные коды и управлять ими?
- Идентификатор собрания и секретный код — это координаты для присоединения к собранию. Разработчики должны рассматривать их как секреты, которые должны быть зашифрованы, и если они хранятся, убедитесь, что они находятся в управляемой среде доступа.
- Если координаты предоставляются, любой пользователь может присоединиться к собранию и разрушить опыт для всех участников собрания.
Как получить идентификатор собрания и секретный код?
- API Graph: используйте API Graph для получения сведений о
onlineMeeting
ресурсе и проверки объекта в свойствеjoinMeetingIdSettings
. - Teams: в приложении Teams перейдите к
Calendar
приложению и откройте сведения о собрании. В онлайн-собраниях есть идентификатор собрания и секретный код в определении собрания. - Outlook: идентификатор собрания и секретный код можно найти в событиях календаря или приглашениях на собрание электронной почты.
- Разработчики не могут получить идентификатор собрания и секретный код с помощью вызова пакета SDK или получить его из подробных журналов консоли.
- API Graph: используйте API Graph для получения сведений о
Как проверить правильность идентификатора собрания и секретного кода?
- Проверка идентификатора и секретного кода можно выполнить с помощью: https://www.microsoft.com/en-us/microsoft-teams/join-a-meeting
Получение входящего вызова Teams
Вы можете подписаться на incomingCall
событие на teamsCallAgent
экземпляре, чтобы зарегистрировать входящие вызовы пользователю Teams. Событие имеет свойство с TeamsIncomingCall
экземпляромteamsIncomingCall
, который позволяет или reject
входящий accept
вызов.
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);
Включение и отключение видео
Вы можете получить локальную коллекцию видеопотоков из свойства localVideoStreams
в экземпляре TeamsCall
. Если этот параметр включен, коллекция содержит поток общего доступа к экранам и видеотрансляции камеры. Видеопотоки удаленных участников можно получить, проверяя свойство TeamsCall
.remoteParticipants
где каждый участник имеет коллекцию видеопотоков в свойстве videoStreams
.
Отключить звук и включить звук
Вы можете использовать mute
и unmute
асинхронные API в экземпляре TeamsCall
, чтобы отключить или отменить отключение пользователей Teams локально. Локальное отключение запрещает отправку звука другим участникам.
//mute local device
await call.mute();
//unmute local device
await call.unmute();
Отключение звука других участников
Чтобы отключить звук всех остальных участников или отключить определенный участник, можно использовать асинхронные API muteAllRemoteParticipants
для вызова и mute
удаленного участника:
//mute all participants except yourself
await call.muteAllRemoteParticipants();
//mute a specific participant
await call.remoteParticipants[0].mute();
Примечание.
Этот API предоставляется в качестве предварительной версии для разработчиков и может быть изменен на основе полученных нами отзывов. Не используйте этот API в рабочей среде. Чтобы использовать этот API, используйте бета-версию Службы коммуникации Azure вызывающего веб-пакета SDK
Управление удаленными участниками
Другие участники вызова доступны в TeamsCall
экземпляре в свойстве remoteParticipants
. Это коллекция RemoteParticipant
объектов. Вы можете перечислить, добавить и удалить других участников из вызова.
Примечание.
Для добавления метода участника требуется чат threadId
. Пакет SDK для звонков служб коммуникации не поддерживает участников чата и вызовов в синхронизации. Microsft призывает разработчиков сохранять список в синхронизации для лучшего взаимодействия с пользователем. Узнайте, как управлять потоком чата.
Вы можете добавить новый пользователь Teams или номер телефона в звонок Teams или собрание Teams, вызвав метод addParticipant
в объекте TeamsCall
. Метод принимает идентификаторы MicrosoftTeamsUserIdentifier
или PhoneNumberIdentifier
в качестве входных данных и возвращает синхронно экземпляр RemoteParticipant
и активирует событие remoteParticipantsUpdated
в экземпляре TeamsCall
.
Вы можете удалить участника из вызова Teams или собрания Teams, вызвав removeParticipant
метод в экземпляре TeamsCall
асинхронно. Метод принимает идентификаторы MicrosoftTeamsUserIdentifier
или PhoneNumberIdentifier
входные данные. Метод разрешается при RemoteParticipant
удалении из remoteParticipants
коллекции, а событие remoteParticipantsUpdated
в TeamsCall
экземпляре активируется.
Перечисление других участников вызова:
const participants = call.remoteParticipants; // [remoteParticipant, remoteParticipant....]
Добавьте номер пользователя и телефона Teams в собрание 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>' });
Удалите номер пользователя и телефона Teams из звонка Teams или собрания Teams:
const teamsUser = { microsoftTeamsUserId: '<MICROSOFT_TEAMS_USER_ID>' };
const phoneUser = { phoneNumber: '<PHONE_NUMBER_E164_FORMAT>' }
await call.removeParticipant(teamsUser);
await call.removeParticipant(phoneUser);
Удаленные участники
Удаленные участники представляют конечную точку, подключенную к текущему вызову Teams или собранию Teams. remoteParticipant
Класс имеет следующий набор свойств и коллекций:
identifier
: возвращает один из следующих идентификаторов:CommunicationUserIdentifier
, ,MicrosoftTeamsUserIdentifier
PhoneNumberIdentifier
илиUnknownIdentifier
.
const identifier = remoteParticipant.identifier;
state
: возвращаетstring
состояние удаленного участника. Состояние может иметь одно из следующих значений:
Значение состояния | When | Description |
---|---|---|
Idle |
Начальное состояние | Это первое состояние участника |
Connecting |
После Idle |
Состояние перехода во время подключения участника к вызову. |
Ringing |
После Connecting |
Участник получил incomingCall уведомление или клиент Teams звонит |
Connected |
После Ringing , или EarlyMedia Connecting InLobby |
Участник принял приглашение на звонок или присоединился к вызову. Носитель передается к участнику. |
Hold |
После Connected |
Участник звонка находится на удержании. |
EarlyMedia |
После Connecting |
Носитель воспроизводится перед подключением участника к вызову |
InLobby |
После Ringing или Connecting EarlyMedia |
Участник находится в лобби собраний Teams. |
Disconnected |
Конечное состояние | Обозначает завершение вызова для участника. Если у удаленного участника пропадает подключение к сети, через две минуты его состояние меняется на Disconnected . |
Состояния удаленных участников в вызовах один к одному или группам:
Состояния удаленных участников собраний Teams:
const state = remoteParticipant.state;
callEndReason
: возвращает объект, содержащий дополнительные сведения о причине завершения вызова. Свойствоcode
возвращает число, связанное с причиной, иsubCode
возвращает число, связанное с кодом и причиной. Дополнительные сведения о кодах ошибок см. в разделе "Устранение неполадок кодов ответов на вызов".
const callEndReason = remoteParticipant.callEndReason;
const callEndReasonCode = callEndReason.code
const callEndReasonSubCode = callEndReason.subCode
isMuted
: возвращаетBoolean
значение, представляющее состояние локального отключения.
const isMuted = remoteParticipant.isMuted;
isSpeaking
: возвращаетBoolean
значение, представляющее состояние отправки звука nonempty.
const isSpeaking = remoteParticipant.isSpeaking;
videoStreams
: возвращает коллекцию объектов, отправленныхRemoteVideoStream
участниками.
const videoStreams = remoteParticipant.videoStreams; // [RemoteVideoStream, ...]
displayName
: возвращаетstring
отображаемое имя. Пакет SDK для вызовов служб коммуникации не устанавливает это значение для пользователей Teams.
const displayName = remoteParticipant.displayName;
Позвонить
id
: возвращает строку, представляющую уникальный идентификатор вызова.
const callId = call.id;
• info
: возвращает сведения о вызове:
Примечание.
Этот API предоставляется в качестве предварительной версии для разработчиков и может быть изменен на основе полученных нами отзывов. Не используйте этот API в рабочей среде. Чтобы использовать этот API, используйте выпуск бета-версии Службы коммуникации Azure вызова веб-пакета SDK
• info
Возвращает объект, содержащий сведения о вызове. Это свойство threadId
представляет собой строку, представляющую идентификатор потока чата, показанный в клиенте Teams.
const callInfo = call.info;
const threadId = call.info.threadId;
• remoteParticipants
Возвращает коллекцию remoteParticipant
объектов, представляющих других участников вызова Teams или собрания Teams.
const remoteParticipants = call.remoteParticipants;
• callerInfo
: возвращает CallerInfo
объект для входящих вызовов. Свойство identifier
может быть одним из следующих объектовCommunicationUserIdentifier
, MicrosoftTeamsUserIdentifier
PhoneNumberIdentifier
или UnknownIdentifier
. Свойство displayName
представляет собой строку, представляющую имя для отображения, если задано.
const callerIdentity = call.callerInfo.identifier;
const callerIdentity = call.callerInfo.displayName;
• state
Возвращает строку, представляющую состояние вызова. Свойство может принимать одно из следующих значений:
Значение состояния | When | Description |
---|---|---|
None |
Начальное состояние | Начальное состояние вызова. |
Connecting |
После None |
Состояние, когда вызов Teams или собрание Teams помещается, присоединяется или принимается. |
Ringing |
После Connecting |
Удаленный incomingCall участник получил событие или клиент Teams звонит. |
EarlyMedia |
После Ringing или Connecting |
Носитель воспроизводится перед подключением звонка. |
Connected |
ПослеRinging , , , LocalHold EarlyMedia InLobby иRemoteHold |
Вызов подключен. Носитель осуществляется между локальными конечными точками и удаленными участниками. |
LocalHold |
После Connected |
Звонок был помещен на удержание местным участником. Передача мультимедиа между локальной конечной точкой и удаленными участниками не выполняется; |
RemoteHold |
После Connected |
Звонок был помещен на удержание удаленным участником. Передача мультимедиа между локальной конечной точкой и удаленными участниками не выполняется; |
InLobby |
После Ringing или Connecting |
Удаленный участник находится в лобби собраний Teams. Передача мультимедиа между локальной конечной точкой и удаленными участниками не выполняется; |
Disconnecting |
После любого состояния | Состояние перехода перед вызовом Disconnected переходит в состояние. |
Disconnected |
Конечное состояние | Окончательное состояние вызова. При потере сетевого подключения состояние меняется на Disconnected через две минуты. |
Состояния для вызовов один к одному или группам:
Состояния собраний Teams:
const callState = call.state;
• callEndReason
Возвращает объект CallEndReason
, содержащий дополнительные сведения о завершении вызова. Свойство code
возвращает число, связанное с причиной, и subCode
возвращает число, связанное с кодом и причиной. Дополнительные сведения о кодах ошибок см. в разделе "Устранение неполадок кодов ответов на вызов".
const callEndReason = call.callEndReason;
const callEndReasonCode = callEndReason.code
const callEndReasonSubCode = callEndReason.subCode
• direction
: возвращает string
направление вызова. Свойство может иметь одно из следующих значений: "Входящий" или Outgoing
.
const isIncoming = call.direction == 'Incoming';
const isOutgoing = call.direction == 'Outgoing';
• isMuted
: возвращает Boolean
значение, представляющее состояние локального отключения.
const muted = call.isMuted;
• isScreenSharingOn
— возвращает Boolean
значение true, если вы отправляете поток общего доступа к экрану другим участникам.
const isScreenSharingOn = call.isScreenSharingOn;
• localVideoStreams
Возвращает коллекцию LocalVideoStream
объектов, представляющую видеопотоки, отправляемые удаленным участникам.
const localVideoStreams = call.localVideoStreams;
Управление потоком чата
Внимание
Необязательный идентификатор чата доступен только в версии 1.29.1 или более поздней версии пакета SDK для Вызова для JavaScript. Если вы используете более раннюю версию, укажите уникальный идентификатор чата вручную.
Предоставление идентификатора чата является необязательным для выполнения групповых звонков и добавления участников в существующие звонки. Связанный чат и звонок имеют отдельный список участников. Перед добавлением участников в звонок добавьте пользователя в чат, чтобы обеспечить лучший интерфейс пользователя и удовлетворить требования к информационным барьерам. Добавление пользователя в звонок без добавления пользователя в чат может привести к исключениям, если настроен информационный барьер.
Рассмотрим следующий сценарий, где Алиса делает звонок Бобу, то Алиса добавляет Чарли, и 3 минут спустя Алиса удаляет Чарли из звонка.
- Создайте поток чата между Алиса, Бобом и Чарли. Сохраните чат
threadId
позже. - Алиса вызывает Боба и Чарли с помощью
startCall
метода наTeamsCallAgent
экземпляре. - Добавление Дэна в поток чата с
threadId
помощью API Graph чата для добавления участника - Алиса добавляет Дэна в вызов с помощью
addParticipant
методаcall
и указываетthreadId
- Алиса удаляет Дэна из вызова с помощью
removeParticipant
методаcall
и указываетthreadId
- Удаление Дэна из потока чата с
threadId
помощью API Graph чата для удаления члена
Если пользователь Teams останавливает запись звонка, запись помещается в чат, связанный с потоком. Предоставленный идентификатор чата влияет на взаимодействие пользователей Teams в клиентах Teams.
Рекомендации по управлению идентификатором чата:
- Эскалация телефонного звонка 1:1 путем добавления другого участника телефона:
- Метод
addParticipant
позволяет указать необязательный идентификатор чата параметров. Если параметр не указан, создается новый групповый чат, а все участники добавляются в список участников звонка и чата. Если указан параметр, пользователи Teams могут видеть текущий звонок, связанный с этим групповым чатом в приложении Teams. Вы можете создать новый групповый чат с помощью API Graph.addParticipant(participant: MicrosoftTeamsUserIdentifier | PhoneNumberIdentifier | MicrosoftTeamsAppIdentifier | UnknownIdentifier)
- Метод
- Запустите групповой звонок с одним пользователем Microsoft 365 и несколькими участниками телефона:
- API метода
startCall
позволяет запускать групповый вызов с несколькими участниками и при необходимости предоставлять идентификатор чата. Если параметр не указан, создается новый групповый чат, а все участники Microsoft 365 добавляются в список участников звонка и чата. Если указан параметр, пользователи Teams могут видеть текущий звонок, связанный с этим групповым чатом в приложении Teams. Вы можете создать новый групповый чат с помощью API Graph.startCall(MicrosoftTeamsUserIdentifier | PhoneNumberIdentifier | MicrosoftTeamsAppIdentifier | UnknownIdentifier)[])
- Используйте API Graph для получения существующего идентификатора чата только с пользователем Teams в качестве участника или создания нового группового чата с участниками: идентификатор пользователя Teams и "0000000-0000-0000-000000000000000000".
- API метода
- Запустите групповой вызов с более чем 2 пользователями Microsoft 365:
- (Необязательный способ) При выполнении группового вызова с более чем 2 пользователями Microsoft 365 с помощью пакета SDK для вызовов ACS пакет SDK автоматически создаст поток по умолчанию.
startCall(MicrosoftTeamsUserIdentifier | PhoneNumberIdentifier | MicrosoftTeamsAppIdentifier | UnknownIdentifier)[])
- При желании разработчик может предоставить уникальный идентификатор чата для запуска группового звонка или добавления участников. В этом случае пакет SDK для вызовов ACS будет использовать заданный идентификатор чата для создания группового вызова. Поток чата создается для пользователей Teams, и этот поток связан с групповым вызовом для пользователей в приложении Teams. Это позволяет им общаться во время звонка. Управление потоками чата можно выполнить с помощью API Graph
- (Необязательный способ) При выполнении группового вызова с более чем 2 пользователями Microsoft 365 с помощью пакета SDK для вызовов ACS пакет SDK автоматически создаст поток по умолчанию.