Краткое руководство. Создание исходящего вызова с помощью службы автоматизации вызовов
СЛУЖБЫ КОММУНИКАЦИИ AZURE API автоматизации вызовов — это эффективный способ создания интерактивных интерфейсов звонков. В этом кратком руководстве мы рассмотрим способ выполнения исходящего вызова и распознавания различных событий в вызове.
Необходимые компоненты
- Учетная запись Azure с активной подпиской. Создайте учетную запись бесплатно .
- Развернутый ресурс Служб коммуникации. Создайте ресурс Служб коммуникации.
- Номер телефона в ресурсе Службы коммуникации Azure, который может совершать исходящие звонки. Если у вас есть бесплатная подписка, вы можете получить пробный номер телефона.
- Создание и размещение Azure Dev Tunnel. Инструкции см. здесь.
- Создайте и подключите службы Azure AI с несколькими службами к Службы коммуникации Azure ресурсу.
- Создайте настраиваемый поддомен для ресурса служб искусственного интеллекта Azure.
- (Необязательно) Пользователь Microsoft Teams с включенной лицензией
voice
на телефон. Для добавления пользователей Teams в звонок требуется лицензия на телефон Teams. Дополнительные сведения о лицензиях Teams см. здесь. Узнайте о включении телефонной системы здесьvoice
.
Пример кода
Скачайте или клонируйте пример кода из GitHub.
Перейдите в CallAutomation_OutboundCalling
папку и откройте решение в редакторе кода.
Настройка и размещение Azure DevTunnel
Azure DevTunnels — это служба Azure, которая позволяет совместно использовать локальные веб-службы, размещенные в Интернете. Выполните команды, чтобы подключить локальную среду разработки к общедоступному Интернету. DevTunnels создает URL-адрес постоянной конечной точки и разрешает анонимный доступ. Мы используем эту конечную точку для уведомления приложения о вызове событий из службы автоматизации вызовов Службы коммуникации Azure.
devtunnel create --allow-anonymous
devtunnel port create -p 8080
devtunnel host
Кроме того, следуйте инструкциям по настройке Azure DevTunnel в Visual Studio
Обновление конфигурации приложения
Затем обновите Program.cs
файл со следующими значениями:
acsConnectionString
: строка подключения для ресурса Службы коммуникации Azure. Вы можете найти Службы коммуникации Azure строка подключения, используя приведенные здесь инструкции.callbackUriHost
: после инициализации узла DevTunnel обновите это поле с помощью этого URI.acsPhonenumber
: обновите это поле с Службы коммуникации Azure номер телефона, который вы приобрели. Этот номер телефона должен использовать формат номера телефона E164 (например, +18881234567)targetPhonenumber
: обновите поле с номером телефона, который вы хотите вызвать приложение. Этот номер телефона должен использовать формат номера телефона E164 (например, +18881234567)cognitiveServiceEndpoint
: обновите поле с конечной точкой служб ИИ Azure.targetTeamsUserId
: (необязательно) поле обновления с идентификатором пользователя Microsoft Teams, который вы хотите добавить в вызов. См. раздел "Использование API Graph" для получения идентификатора пользователя Teams.
// Your ACS resource connection string
var acsConnectionString = "<ACS_CONNECTION_STRING>";
// Your ACS resource phone number will act as source number to start outbound call
var acsPhonenumber = "<ACS_PHONE_NUMBER>";
// Target phone number you want to receive the call.
var targetPhonenumber = "<TARGET_PHONE_NUMBER>";
// Base url of the app
var callbackUriHost = "<CALLBACK_URI_HOST_WITH_PROTOCOL>";
// Your cognitive service endpoint
var cognitiveServiceEndpoint = "<COGNITIVE_SERVICE_ENDPOINT>";
// (Optional) User Id of the target teams user you want to receive the call.
var targetTeamsUserId = "<TARGET_TEAMS_USER_ID>";
Вызов исходящего трафика
Чтобы сделать исходящий вызов из Службы коммуникации Azure, в этом примере используется targetPhonenumber
определенный ранее в приложении вызов с помощью CreateCallAsync
API. Этот код сделает исходящий звонок с помощью целевого номера телефона.
PhoneNumberIdentifier target = new PhoneNumberIdentifier(targetPhonenumber);
PhoneNumberIdentifier caller = new PhoneNumberIdentifier(acsPhonenumber);
var callbackUri = new Uri(callbackUriHost + "/api/callbacks");
CallInvite callInvite = new CallInvite(target, caller);
var createCallOptions = new CreateCallOptions(callInvite, callbackUri) {
CallIntelligenceOptions = new CallIntelligenceOptions() {
CognitiveServicesEndpoint = new Uri(cognitiveServiceEndpoint)
}
};
CreateCallResult createCallResult = await callAutomationClient.CreateCallAsync(createCallOptions);
Обработка событий автоматизации вызовов
Ранее в нашем приложении мы зарегистрировали callbackUriHost
службу автоматизации вызовов. Узел указывает конечную точку, которую служба должна уведомить нас о вызовах событий, которые происходят. Затем мы можем выполнять итерацию событий и обнаруживать конкретные события, которые мы хотим понять. В коде ниже мы отвечаем на CallConnected
событие.
app.MapPost("/api/callbacks", async (CloudEvent[] cloudEvents, ILogger < Program > logger) => {
foreach(var cloudEvent in cloudEvents) {
logger.LogInformation($"Event received: {JsonConvert.SerializeObject(cloudEvent)}");
CallAutomationEventBase parsedEvent = CallAutomationEventParser.Parse(cloudEvent);
logger.LogInformation($"{parsedEvent?.GetType().Name} parsedEvent received for call connection id: {parsedEvent?.CallConnectionId}");
var callConnection = callAutomationClient.GetCallConnection(parsedEvent.CallConnectionId);
var callMedia = callConnection.GetCallMedia();
if (parsedEvent is CallConnected) {
//Handle Call Connected Event
}
}
});
(Необязательно) Добавление пользователя Microsoft Teams в вызов
Вы можете добавить пользователя Microsoft Teams в вызов с помощью AddParticipantAsync
метода с MicrosoftTeamsUserIdentifier
идентификатором пользователя Teams. Сначала необходимо выполнить необходимый шаг авторизации для ресурса Службы коммуникации Azure, чтобы разрешить вызов пользователям Microsoft Teams. Кроме того, можно передать текст SourceDisplayName
, отображаемый в всплывающем уведомлении пользователя Teams.
await callConnection.AddParticipantAsync(
new CallInvite(new MicrosoftTeamsUserIdentifier(targetTeamsUserId))
{
SourceDisplayName = "Jack (Contoso Tech Support)"
});
Начало записи вызова
Служба автоматизации звонков также позволяет запускать запись и хранить записи голосовых и видеозвонков. Дополнительные сведения о различных возможностях см. в API записи вызовов.
CallLocator callLocator = new ServerCallLocator(parsedEvent.ServerCallId);
var recordingResult = await callAutomationClient.GetCallRecording().StartAsync(new StartRecordingOptions(callLocator));
recordingId = recordingResult.Value.RecordingId;
Воспроизведение приветственного сообщения и распознавания
TextSource
Используя службу, вы можете предоставить службе текст, который вы хотите синтезировать и использовать для приветственного сообщения. Служба автоматизации вызовов Службы коммуникации Azure воспроизводит это сообщение при событииCallConnected
.
Далее мы передаем текст в и CallMediaRecognizeChoiceOptions
вызов StartRecognizingAsync
. Это позволяет приложению распознавать параметр, который выбирает вызывающий объект.
if (parsedEvent is CallConnected callConnected) {
logger.LogInformation($"Start Recording...");
CallLocator callLocator = new ServerCallLocator(parsedEvent.ServerCallId);
var recordingResult = await callAutomationClient.GetCallRecording().StartAsync(new StartRecordingOptions(callLocator));
recordingId = recordingResult.Value.RecordingId;
var choices = GetChoices();
// prepare recognize tones
var recognizeOptions = GetMediaRecognizeChoiceOptions(mainMenu, targetPhonenumber, choices);
// Send request to recognize tones
await callMedia.StartRecognizingAsync(recognizeOptions);
}
CallMediaRecognizeChoiceOptions GetMediaRecognizeChoiceOptions(string content, string targetParticipant, List < RecognitionChoice > choices, string context = "") {
var playSource = new TextSource(content) {
VoiceName = SpeechToTextVoice
};
var recognizeOptions = new CallMediaRecognizeChoiceOptions(targetParticipant: new PhoneNumberIdentifier(targetParticipant), choices) {
InterruptCallMediaOperation = false,
InterruptPrompt = false,
InitialSilenceTimeout = TimeSpan.FromSeconds(10),
Prompt = playSource,
OperationContext = context
};
return recognizeOptions;
}
List < RecognitionChoice > GetChoices() {
return new List < RecognitionChoice > {
new RecognitionChoice("Confirm", new List < string > {
"Confirm",
"First",
"One"
}) {
Tone = DtmfTone.One
},
new RecognitionChoice("Cancel", new List < string > {
"Cancel",
"Second",
"Two"
}) {
Tone = DtmfTone.Two
}
};
}
Обработка событий выбора
Службы коммуникации Azure служба автоматизации вызовов активирует api/callbacks
веб-перехватчик, который мы настроили, и уведомит нас о событииRecognizeCompleted
. Это событие дает нам возможность реагировать на полученные входные данные и активировать действие. Затем приложение воспроизводит сообщение вызывающей стороне на основе полученных входных данных.
if (parsedEvent is RecognizeCompleted recognizeCompleted) {
var choiceResult = recognizeCompleted.RecognizeResult as ChoiceResult;
var labelDetected = choiceResult?.Label;
var phraseDetected = choiceResult?.RecognizedPhrase;
// If choice is detected by phrase, choiceResult.RecognizedPhrase will have the phrase detected,
// If choice is detected using dtmf tone, phrase will be null
logger.LogInformation("Recognize completed succesfully, labelDetected={labelDetected}, phraseDetected={phraseDetected}", labelDetected, phraseDetected);
var textToPlay = labelDetected.Equals(ConfirmChoiceLabel, StringComparison.OrdinalIgnoreCase) ? ConfirmedText : CancelText;
await HandlePlayAsync(callMedia, textToPlay);
}
async Task HandlePlayAsync(CallMedia callConnectionMedia, string text) {
// Play goodbye message
var GoodbyePlaySource = new TextSource(text) {
VoiceName = "en-US-NancyNeural"
};
await callConnectionMedia.PlayToAllAsync(GoodbyePlaySource);
}
Зависание и остановка записи
Наконец, когда мы обнаруживаем условие, которое имеет смысл для завершения вызова, мы можем использовать HangUpAsync
метод для зависания вызова.
if ((parsedEvent is PlayCompleted) || (parsedEvent is PlayFailed))
{
logger.LogInformation($"Stop recording and terminating call.");
callAutomationClient.GetCallRecording().Stop(recordingId);
await callConnection.HangUpAsync(true);
}
Выполнение кода
Чтобы запустить приложение с помощью VS Code, откройте окно терминала и выполните следующую команду.
dotnet run
Откройте http://localhost:8080/swagger/index.html
или URL-адрес туннеля разработки в браузере. URL-адрес туннеля выглядит следующим образом: <YOUR DEV TUNNEL ENDPOINT>/swagger/index.html
Необходимые компоненты
- Учетная запись Azure с активной подпиской. Создайте учетную запись бесплатно .
- Развернутый ресурс Служб коммуникации. Создайте ресурс Служб коммуникации.
- Номер телефона в ресурсе Службы коммуникации Azure, который может совершать исходящие звонки. Если у вас есть бесплатная подписка, вы можете получить пробный номер телефона.
- Создание и размещение Azure Dev Tunnel. Инструкции см. здесь.
- Создайте и подключите службы Azure AI с несколькими службами к Службы коммуникации Azure ресурсу.
- Создайте настраиваемый поддомен для ресурса служб искусственного интеллекта Azure.
- комплект SDK для Java (JDK) версии 11 или более поздней.
- Apache Maven.
- (Необязательно) Пользователь Microsoft Teams с включенной лицензией
voice
на телефон. Для добавления пользователей Teams в звонок требуется лицензия на телефон Teams. Дополнительные сведения о лицензиях Teams см. здесь. Дополнительные сведения оvoice
включении телефонной системы см. в разделе "Настройка телефонной системы".
Пример кода
Скачайте или клонируйте пример кода из GitHub.
Перейдите в CallAutomation_OutboundCalling
папку и откройте решение в редакторе кода.
Настройка и размещение Azure DevTunnel
Azure DevTunnels — это служба Azure, которая позволяет совместно использовать локальные веб-службы, размещенные в Интернете. Выполните команды DevTunnel, чтобы подключить локальную среду разработки к общедоступному Интернету. Затем DevTunnels создает туннель с URL-адресом постоянной конечной точки и разрешает анонимный доступ. Службы коммуникации Azure использует эту конечную точку для уведомления приложения о вызове событий из службы автоматизации вызовов Службы коммуникации Azure.
devtunnel create --allow-anonymous
devtunnel port create -p MY_SPRINGAPP_PORT
devtunnel host
Обновление конфигурации приложения
Затем откройте application.yml
файл в папке /resources
, чтобы настроить следующие значения:
connectionstring
: строка подключения для ресурса Службы коммуникации Azure. Вы можете найти Службы коммуникации Azure строка подключения, используя приведенные здесь инструкции.basecallbackuri
: после инициализации узла DevTunnel обновите это поле с помощью этого URI.callerphonenumber
: обновите это поле с Службы коммуникации Azure номер телефона, который вы приобрели. Этот номер телефона должен использовать формат номера телефона E164 (например, +18881234567)targetphonenumber
: обновите поле с номером телефона, который вы хотите вызвать приложение. Этот номер телефона должен использовать формат номера телефона E164 (например, +18881234567)cognitiveServiceEndpoint
: обновите поле с конечной точкой служб ИИ Azure.targetTeamsUserId
: (необязательно) поле обновления с идентификатором пользователя Microsoft Teams, который вы хотите добавить в вызов. См. раздел "Использование API Graph" для получения идентификатора пользователя Teams.
acs:
connectionstring: <YOUR ACS CONNECTION STRING>
basecallbackuri: <YOUR DEV TUNNEL ENDPOINT>
callerphonenumber: <YOUR ACS PHONE NUMBER ex. "+1425XXXAAAA">
targetphonenumber: <YOUR TARGET PHONE NUMBER ex. "+1425XXXAAAA">
cognitiveServiceEndpoint: <YOUR COGNITIVE SERVICE ENDPOINT>
targetTeamsUserId: <(OPTIONAL) YOUR TARGET TEAMS USER ID ex. "ab01bc12-d457-4995-a27b-c405ecfe4870">
Создание исходящего вызова и воспроизведение мультимедиа
Чтобы сделать исходящий вызов из Службы коммуникации Azure, в этом примере используется targetphonenumber
определенный в application.yml
файле вызов с помощью createCallWithResponse
API.
PhoneNumberIdentifier caller = new PhoneNumberIdentifier(appConfig.getCallerphonenumber());
PhoneNumberIdentifier target = new PhoneNumberIdentifier(appConfig.getTargetphonenumber());
CallInvite callInvite = new CallInvite(target, caller);
CreateCallOptions createCallOptions = new CreateCallOptions(callInvite, appConfig.getCallBackUri());
CallIntelligenceOptions callIntelligenceOptions = new CallIntelligenceOptions().setCognitiveServicesEndpoint(appConfig.getCognitiveServiceEndpoint());
createCallOptions = createCallOptions.setCallIntelligenceOptions(callIntelligenceOptions);
Response<CreateCallResult> result = client.createCallWithResponse(createCallOptions, Context.NONE);
(Необязательно) Добавление пользователя Microsoft Teams в вызов
Вы можете добавить пользователя Microsoft Teams в вызов с помощью addParticipant
метода с MicrosoftTeamsUserIdentifier
идентификатором пользователя Teams. Сначала необходимо выполнить необходимый шаг авторизации для ресурса Службы коммуникации Azure, чтобы разрешить вызов пользователям Microsoft Teams. Кроме того, можно передать текст SourceDisplayName
, отображаемый в всплывающем уведомлении пользователя Teams.
client.getCallConnection(callConnectionId).addParticipant(
new CallInvite(new MicrosoftTeamsUserIdentifier(targetTeamsUserId))
.setSourceDisplayName("Jack (Contoso Tech Support)"));
Начало записи вызова
Служба автоматизации звонков также позволяет запускать запись и хранить записи голосовых и видеозвонков. Дополнительные сведения о различных возможностях см. в API записи вызовов.
ServerCallLocator serverCallLocator = new ServerCallLocator(
client.getCallConnection(callConnectionId)
.getCallProperties()
.getServerCallId());
StartRecordingOptions startRecordingOptions = new StartRecordingOptions(serverCallLocator);
Response<RecordingStateResult> response = client.getCallRecording()
.startWithResponse(startRecordingOptions, Context.NONE);
recordingId = response.getValue().getRecordingId();
Реагирование на события вызова
Ранее в нашем приложении мы зарегистрировали basecallbackuri
службу автоматизации вызовов. URI указывает конечную точку, которую служба будет использовать для уведомления нас о вызове событий, которые происходят. Затем мы можем выполнять итерацию событий и обнаруживать конкретные события, которые мы хотим понять. В коде ниже мы отвечаем на CallConnected
событие.
List<CallAutomationEventBase> events = CallAutomationEventParser.parseEvents(reqBody);
for (CallAutomationEventBase event : events) {
String callConnectionId = event.getCallConnectionId();
if (event instanceof CallConnected) {
log.info("CallConnected event received");
}
else if (event instanceof RecognizeCompleted) {
log.info("Recognize Completed event received");
}
}
Воспроизведение приветственного сообщения и распознавания
TextSource
Используя службу, вы можете предоставить службе текст, который вы хотите синтезировать и использовать для приветственного сообщения. Служба автоматизации вызовов Службы коммуникации Azure воспроизводит это сообщение при событииCallConnected
.
Далее мы передаем текст в и CallMediaRecognizeChoiceOptions
вызов StartRecognizingAsync
. Это позволяет приложению распознавать параметр, который выбирает вызывающий объект.
var playSource = new TextSource().setText(content).setVoiceName("en-US-NancyNeural");
var recognizeOptions = new CallMediaRecognizeChoiceOptions(new PhoneNumberIdentifier(targetParticipant), getChoices())
.setInterruptCallMediaOperation(false)
.setInterruptPrompt(false)
.setInitialSilenceTimeout(Duration.ofSeconds(10))
.setPlayPrompt(playSource)
.setOperationContext(context);
client.getCallConnection(callConnectionId)
.getCallMedia()
.startRecognizing(recognizeOptions);
private List < RecognitionChoice > getChoices() {
var choices = Arrays.asList(
new RecognitionChoice().setLabel(confirmLabel).setPhrases(Arrays.asList("Confirm", "First", "One")).setTone(DtmfTone.ONE),
new RecognitionChoice().setLabel(cancelLabel).setPhrases(Arrays.asList("Cancel", "Second", "Two")).setTone(DtmfTone.TWO)
);
return choices;
}
Обработка событий выбора
Службы коммуникации Azure служба автоматизации вызовов активирует api/callbacks
веб-перехватчик, который мы настроили, и уведомит нас о событииRecognizeCompleted
. Это событие дает нам возможность реагировать на полученные входные данные и активировать действие. Затем приложение воспроизводит сообщение вызывающей стороне на основе полученных входных данных.
else if (event instanceof RecognizeCompleted) {
log.info("Recognize Completed event received");
RecognizeCompleted acsEvent = (RecognizeCompleted) event;
var choiceResult = (ChoiceResult) acsEvent.getRecognizeResult().get();
String labelDetected = choiceResult.getLabel();
String phraseDetected = choiceResult.getRecognizedPhrase();
log.info("Recognition completed, labelDetected=" + labelDetected + ", phraseDetected=" + phraseDetected + ", context=" + event.getOperationContext());
String textToPlay = labelDetected.equals(confirmLabel) ? confirmedText : cancelText;
handlePlay(callConnectionId, textToPlay);
}
private void handlePlay(final String callConnectionId, String textToPlay) {
var textPlay = new TextSource()
.setText(textToPlay)
.setVoiceName("en-US-NancyNeural");
client.getCallConnection(callConnectionId)
.getCallMedia()
.playToAll(textPlay);
}
Завершение вызова
Наконец, когда мы обнаруживаем условие, которое имеет смысл для завершения вызова, мы можем использовать hangUp
метод для зависания вызова.
client.getCallConnection(callConnectionId).hangUp(true);
Выполнение кода
Перейдите в каталог, содержащий файл pom.xml, и используйте следующие команды mvn:
- Скомпилируйте приложение:
mvn compile
- Создайте пакет:
mvn package
- Выполните приложение:
mvn exec:java
Необходимые компоненты
- Учетная запись Azure с активной подпиской. Создайте учетную запись бесплатно .
- Развернутый ресурс Служб коммуникации. Создайте ресурс Служб коммуникации.
- Номер телефона в ресурсе Службы коммуникации Azure, который может совершать исходящие звонки. Если у вас есть бесплатная подписка, вы можете получить пробный номер телефона.
- Создание и размещение Azure Dev Tunnel. Инструкции см. здесь.
-
- Создайте и подключите службы Azure AI с несколькими службами к Службы коммуникации Azure ресурсу.
- Создайте настраиваемый поддомен для ресурса служб искусственного интеллекта Azure.
- Node.js установка LTS.
- Установленный экземпляр Visual Studio Code.
- (Необязательно) Пользователь Microsoft Teams с включенной лицензией
voice
на телефон. Для добавления пользователей Teams в звонок требуется лицензия на телефон Teams. Дополнительные сведения о лицензиях Teams см. здесь. Дополнительные сведения оvoice
включении телефонной системы см. в разделе "Настройка телефонной системы".
Пример кода
Скачайте или клонируйте пример кода из GitHub.
Перейдите в CallAutomation_OutboundCalling
папку и откройте решение в редакторе кода.
Настройка среды
Скачайте пример кода и перейдите в каталог проекта и выполните npm
команду, которая устанавливает необходимые зависимости и настраивает среду разработчика.
npm install
Настройка и размещение Azure DevTunnel
Azure DevTunnels — это служба Azure, которая позволяет совместно использовать локальные веб-службы, размещенные в Интернете. Используйте команды КОМАНДНОй строки DevTunnel для подключения локальной среды разработки к общедоступному Интернету. Мы используем эту конечную точку для уведомления приложения о вызове событий из службы автоматизации вызовов Службы коммуникации Azure.
devtunnel create --allow-anonymous
devtunnel port create -p 8080
devtunnel host
Обновление конфигурации приложения
Затем обновите .env
файл со следующими значениями:
CONNECTION_STRING
: строка подключения для ресурса Службы коммуникации Azure. Вы можете найти Службы коммуникации Azure строка подключения, используя приведенные здесь инструкции.CALLBACK_URI
: после инициализации узла DevTunnel обновите это поле с помощью этого URI.TARGET_PHONE_NUMBER
: обновите поле с номером телефона, который вы хотите вызвать приложение. Этот номер телефона должен использовать формат номера телефона E164 (например, +18881234567)ACS_RESOURCE_PHONE_NUMBER
: обновите это поле с Службы коммуникации Azure номер телефона, который вы приобрели. Этот номер телефона должен использовать формат номера телефона E164 (например, +18881234567)COGNITIVE_SERVICES_ENDPOINT
: обновите поле с конечной точкой служб ИИ Azure.TARGET_TEAMS_USER_ID
: (необязательно) поле обновления с идентификатором пользователя Microsoft Teams, который вы хотите добавить в вызов. См. раздел "Использование API Graph" для получения идентификатора пользователя Teams.
CONNECTION_STRING="<YOUR_CONNECTION_STRING>"
ACS_RESOURCE_PHONE_NUMBER ="<YOUR_ACS_NUMBER>"
TARGET_PHONE_NUMBER="<+1XXXXXXXXXX>"
CALLBACK_URI="<VS_TUNNEL_URL>"
COGNITIVE_SERVICES_ENDPOINT="<COGNITIVE_SERVICES_ENDPOINT>"
TARGET_TEAMS_USER_ID="<TARGET_TEAMS_USER_ID>"
Создание исходящего вызова и воспроизведение мультимедиа
Чтобы сделать исходящий звонок из Службы коммуникации Azure, используйте номер телефона, указанный в среде. Убедитесь, что номер телефона находится в формате номера телефона E164 (например, +18881234567)
Код выполняет исходящий вызов с помощью предоставленного вами target_phone_number и размещения исходящего вызова к этому номеру:
const callInvite: CallInvite = {
targetParticipant: callee,
sourceCallIdNumber: {
phoneNumber: process.env.ACS_RESOURCE_PHONE_NUMBER || "",
},
};
const options: CreateCallOptions = {
cognitiveServicesEndpoint: process.env.COGNITIVE_SERVICES_ENDPOINT
};
console.log("Placing outbound call...");
acsClient.createCall(callInvite, process.env.CALLBACK_URI + "/api/callbacks", options);
(Необязательно) Добавление пользователя Microsoft Teams в вызов
Вы можете добавить пользователя Microsoft Teams в вызов с помощью метода со свойством addParticipant
microsoftTeamsUserId
. Сначала необходимо выполнить необходимый шаг авторизации для ресурса Службы коммуникации Azure, чтобы разрешить вызов пользователям Microsoft Teams. Кроме того, можно передать текст sourceDisplayName
, отображаемый в всплывающем уведомлении пользователя Teams.
await acsClient.getCallConnection(callConnectionId).addParticipant({
targetParticipant: { microsoftTeamsUserId: process.env.TARGET_TEAMS_USER_ID },
sourceDisplayName: "Jack (Contoso Tech Support)"
});
Начало записи вызова
Служба автоматизации звонков также позволяет запускать запись и хранить записи голосовых и видеозвонков. Дополнительные сведения о различных возможностях см. в API записи вызовов.
const callLocator: CallLocator = {
id: serverCallId,
kind: "serverCallLocator",
};
const recordingOptions: StartRecordingOptions = {
callLocator: callLocator,
};
const response = await acsClient.getCallRecording().start(recordingOptions);
recordingId = response.recordingId;
Реагирование на события вызова
Ранее в нашем приложении мы зарегистрировали CALLBACK_URI
службу автоматизации вызовов. Универсальный код ресурса (URI) указывает конечную точку, которую служба использует для уведомления о вызове событий, которые происходят. Затем мы можем выполнять итерацию событий и обнаруживать конкретные события, которые мы хотим понять. Мы отвечаем на CallConnected
событие, чтобы получать уведомления и инициировать подчиненные операции. TextSource
Используя службу, вы можете предоставить службе текст, который вы хотите синтезировать и использовать для приветственного сообщения. Служба автоматизации вызовов Службы коммуникации Azure воспроизводит это сообщение при событииCallConnected
.
Далее мы передаем текст в и CallMediaRecognizeChoiceOptions
вызов StartRecognizingAsync
. Это позволяет приложению распознавать параметр, который выбирает вызывающий объект.
callConnectionId = eventData.callConnectionId;
serverCallId = eventData.serverCallId;
console.log("Call back event received, callConnectionId=%s, serverCallId=%s, eventType=%s", callConnectionId, serverCallId, event.type);
callConnection = acsClient.getCallConnection(callConnectionId);
const callMedia = callConnection.getCallMedia();
if (event.type === "Microsoft.Communication.CallConnected") {
console.log("Received CallConnected event");
await startRecording();
await startRecognizing(callMedia, mainMenu, "");
}
async function startRecognizing(callMedia: CallMedia, textToPlay: string, context: string) {
const playSource: TextSource = {
text: textToPlay,
voiceName: "en-US-NancyNeural",
kind: "textSource"
};
const recognizeOptions: CallMediaRecognizeChoiceOptions = {
choices: await getChoices(),
interruptPrompt: false,
initialSilenceTimeoutInSeconds: 10,
playPrompt: playSource,
operationContext: context,
kind: "callMediaRecognizeChoiceOptions"
};
await callMedia.startRecognizing(callee, recognizeOptions)
}
Обработка событий выбора
Службы коммуникации Azure служба автоматизации вызовов активирует api/callbacks
веб-перехватчик, который мы настроили, и уведомит нас о событииRecognizeCompleted
. Это событие дает нам возможность реагировать на полученные входные данные и активировать действие. Затем приложение воспроизводит сообщение вызывающей стороне на основе полученных входных данных.
else if (event.type === "Microsoft.Communication.RecognizeCompleted") {
if(eventData.recognitionType === "choices"){
console.log("Recognition completed, event=%s, resultInformation=%s",eventData, eventData.resultInformation);
var context = eventData.operationContext;
const labelDetected = eventData.choiceResult.label;
const phraseDetected = eventData.choiceResult.recognizedPhrase;
console.log("Recognition completed, labelDetected=%s, phraseDetected=%s, context=%s", labelDetected, phraseDetected, eventData.operationContext);
const textToPlay = labelDetected === confirmLabel ? confirmText : cancelText;
await handlePlay(callMedia, textToPlay);
}
}
async function handlePlay(callConnectionMedia:CallMedia, textContent:string){
const play : TextSource = { text:textContent , voiceName: "en-US-NancyNeural", kind: "textSource"}
await callConnectionMedia.playToAll([play]);
}
Завершение вызова
Наконец, когда мы обнаруживаем условие, которое имеет смысл для завершения вызова, мы можем использовать hangUp()
метод для зависания вызова.
await acsClient.getCallRecording().stop(recordingId);
callConnection.hangUp(true);
Выполнение кода
Чтобы запустить приложение, откройте окно терминала и выполните следующую команду:
npm run dev
Необходимые компоненты
- Учетная запись Azure с активной подпиской. Создайте учетную запись бесплатно .
- Развернутый ресурс Служб коммуникации. Создайте ресурс Служб коммуникации.
- Номер телефона в ресурсе Службы коммуникации Azure, который может совершать исходящие звонки. Если у вас есть бесплатная подписка, вы можете получить пробный номер телефона.
- Создание и размещение Azure Dev Tunnel. Инструкции см. здесь.
- Создайте и подключите службы Azure AI с несколькими службами к Службы коммуникации Azure ресурсу.
- Создайте настраиваемый поддомен для ресурса служб искусственного интеллекта Azure.
- Python версии 3.7 и выше.
- (Необязательно) Пользователь Microsoft Teams с включенной лицензией
voice
на телефон. Для добавления пользователей Teams в звонок требуется лицензия на телефон Teams. Дополнительные сведения о лицензиях Teams см. здесь. Дополнительные сведения оvoice
включении телефонной системы см. в разделе "Настройка телефонной системы".
Пример кода
Скачайте или клонируйте пример кода из GitHub.
Перейдите в CallAutomation_OutboundCalling
папку и откройте решение в редакторе кода.
Настройка среды Python
Создайте и активируйте среду Python и установите необходимые пакеты с помощью следующей команды. Дополнительные сведения об управлении пакетами см. здесь
pip install -r requirements.txt
Настройка и размещение Azure DevTunnel
Azure DevTunnels — это служба Azure, которая позволяет совместно использовать локальные веб-службы, размещенные в Интернете. Используйте команды для подключения локальной среды разработки к общедоступному Интернету. DevTunnels создает туннель с URL-адресом постоянной конечной точки и разрешает анонимный доступ. Мы используем эту конечную точку для уведомления приложения о вызове событий из службы автоматизации вызовов Службы коммуникации Azure.
devtunnel create --allow-anonymous
devtunnel port create -p 8080
devtunnel host
Обновление конфигурации приложения
Затем обновите main.py
файл со следующими значениями:
ACS_CONNECTION_STRING
: строка подключения для ресурса Службы коммуникации Azure. Вы можете найти Службы коммуникации Azure строка подключения, используя приведенные здесь инструкции.CALLBACK_URI_HOST
: после инициализации узла DevTunnel обновите это поле с помощью этого URI.TARGET_PHONE_NUMBER
: обновите поле с номером телефона, который вы хотите вызвать приложение. Этот номер телефона должен использовать формат номера телефона E164 (например, +18881234567)ACS_PHONE_NUMBER
: обновите это поле с Службы коммуникации Azure номер телефона, который вы приобрели. Этот номер телефона должен использовать формат номера телефона E164 (например, +18881234567)COGNITIVE_SERVICES_ENDPOINT
: обновите поле с конечной точкой служб ИИ Azure.TARGET_TEAMS_USER_ID
: (необязательно) поле обновления с идентификатором пользователя Microsoft Teams, который вы хотите добавить в вызов. См. раздел "Использование API Graph" для получения идентификатора пользователя Teams.
# Your ACS resource connection string
ACS_CONNECTION_STRING = "<ACS_CONNECTION_STRING>"
# Your ACS resource phone number will act as source number to start outbound call
ACS_PHONE_NUMBER = "<ACS_PHONE_NUMBER>"
# Target phone number you want to receive the call.
TARGET_PHONE_NUMBER = "<TARGET_PHONE_NUMBER>"
# Callback events URI to handle callback events.
CALLBACK_URI_HOST = "<CALLBACK_URI_HOST_WITH_PROTOCOL>"
CALLBACK_EVENTS_URI = CALLBACK_URI_HOST + "/api/callbacks"
#Your Cognitive service endpoint
COGNITIVE_SERVICES_ENDPOINT = "<COGNITIVE_SERVICES_ENDPOINT>"
#(OPTIONAL) Your target Microsoft Teams user Id ex. "ab01bc12-d457-4995-a27b-c405ecfe4870"
TARGET_TEAMS_USER_ID = "<TARGET_TEAMS_USER_ID>"
Вызов исходящего трафика
Чтобы сделать исходящий звонок из Службы коммуникации Azure, сначала укажите номер телефона, который вы хотите получить. Чтобы сделать его простым, можно обновить target_phone_number
номер телефона в формате номера телефона E164 (например, +18881234567)
Выполните исходящий вызов с помощью предоставленного вами target_phone_number:
target_participant = PhoneNumberIdentifier(TARGET_PHONE_NUMBER)
source_caller = PhoneNumberIdentifier(ACS_PHONE_NUMBER)
call_invite = CallInvite(target=target_participant, source_caller_id_number=source_caller)
call_connection_properties = call_automation_client.create_call(call_invite, CALLBACK_EVENTS_URI,
cognitive_services_endpoint=COGNITIVE_SERVICES_ENDPOINT)
app.logger.info("Created call with connection id: %s",
call_connection_properties.call_connection_id)
return redirect("/")
(Необязательно) Добавление пользователя Microsoft Teams в вызов
Вы можете добавить пользователя Microsoft Teams в вызов с помощью add_participant
метода с MicrosoftTeamsUserIdentifier
идентификатором пользователя Teams. Сначала необходимо выполнить необходимый шаг авторизации для ресурса Службы коммуникации Azure, чтобы разрешить вызов пользователям Microsoft Teams. Кроме того, можно передать текст source_display_name
, отображаемый в всплывающем уведомлении пользователя Teams.
call_connection_client.add_participant(target_participant = CallInvite(
target = MicrosoftTeamsUserIdentifier(user_id=TARGET_TEAMS_USER_ID),
source_display_name = "Jack (Contoso Tech Support)"))
Начало записи вызова
Служба автоматизации звонков также позволяет запускать запись и хранить записи голосовых и видеозвонков. Дополнительные сведения о различных возможностях см. в API записи вызовов.
recording_properties = call_automation_client.start_recording(ServerCallLocator(event.data['serverCallId']))
recording_id = recording_properties.recording_id
Реагирование на события вызова
Ранее в нашем приложении мы зарегистрировали CALLBACK_URI_HOST
службу автоматизации вызовов. Универсальный код ресурса (URI) указывает конечную точку, которую служба использует для уведомления о вызове событий, которые происходят. Затем мы можем выполнять итерацию событий и обнаруживать конкретные события, которые мы хотим понять. В коде ниже мы отвечаем на CallConnected
событие.
@app.route('/api/callbacks', methods=['POST'])
def callback_events_handler():
for event_dict in request.json:
event = CloudEvent.from_dict(event_dict)
if event.type == "Microsoft.Communication.CallConnected":
# Handle Call Connected Event
...
return Response(status=200)
Воспроизведение приветственного сообщения и распознавания
TextSource
Используя службу, вы можете предоставить службе текст, который вы хотите синтезировать и использовать для приветственного сообщения. Служба автоматизации вызовов Службы коммуникации Azure воспроизводит это сообщение при событииCallConnected
.
Далее мы передаем текст в и CallMediaRecognizeChoiceOptions
вызов StartRecognizingAsync
. Это позволяет приложению распознавать параметр, который выбирает вызывающий объект.
get_media_recognize_choice_options(
call_connection_client=call_connection_client,
text_to_play=MainMenu,
target_participant=target_participant,
choices=get_choices(),context="")
def get_media_recognize_choice_options(call_connection_client: CallConnectionClient, text_to_play: str, target_participant:str, choices: any, context: str):
play_source = TextSource (text= text_to_play, voice_name= SpeechToTextVoice)
call_connection_client.start_recognizing_media(
input_type=RecognizeInputType.CHOICES,
target_participant=target_participant,
choices=choices,
play_prompt=play_source,
interrupt_prompt=False,
initial_silence_timeout=10,
operation_context=context
)
def get_choices():
choices = [
RecognitionChoice(label = ConfirmChoiceLabel, phrases= ["Confirm", "First", "One"], tone = DtmfTone.ONE),
RecognitionChoice(label = CancelChoiceLabel, phrases= ["Cancel", "Second", "Two"], tone = DtmfTone.TWO)
]
return choices
Обработка событий выбора
Службы коммуникации Azure служба автоматизации вызовов активирует api/callbacks
веб-перехватчик, который мы настроили, и уведомит нас о событииRecognizeCompleted
. Это событие дает нам возможность реагировать на полученные входные данные и активировать действие. Затем приложение воспроизводит сообщение вызывающей стороне на основе полученных входных данных.
elif event.type == "Microsoft.Communication.RecognizeCompleted":
app.logger.info("Recognize completed: data=%s", event.data)
if event.data['recognitionType'] == "choices":
labelDetected = event.data['choiceResult']['label'];
phraseDetected = event.data['choiceResult']['recognizedPhrase'];
app.logger.info("Recognition completed, labelDetected=%s, phraseDetected=%s, context=%s", labelDetected, phraseDetected, event.data.get('operationContext'))
if labelDetected == ConfirmChoiceLabel:
textToPlay = ConfirmedText
else:
textToPlay = CancelText
handle_play(call_connection_client = call_connection_client, text_to_play = textToPlay)
def handle_play(call_connection_client: CallConnectionClient, text_to_play: str):
play_source = TextSource(text = text_to_play, voice_name = SpeechToTextVoice)
call_connection_client.play_media_to_all(play_source)
Завершение вызова
Наконец, когда мы обнаруживаем условие, которое имеет смысл для завершения вызова, мы можем использовать hang_up()
метод для зависания вызова. Наконец, мы также можем безопасно остановить операцию записи вызовов.
call_automation_client.stop_recording(recording_id)
call_connection_client.hang_up(is_for_everyone=True)
Выполнение кода
Чтобы запустить приложение с помощью VS Code, откройте окно терминала и выполните следующую команду.
python main.py