Inicio rápido: cómo realizar una llamada saliente mediante la automatización de llamadas
Las API de automatización de llamadas de Azure Communication Services son una manera eficaz de crear experiencias de llamada interactivas. En este inicio rápido, explicamos una manera de realizar una llamada saliente y de reconocer varios eventos en la llamada.
Requisitos previos
- Una cuenta de Azure con una suscripción activa. Cree una cuenta gratuita.
- Un recurso de Communication Services implementado. Cree un recurso de Communication Services.
- Un número de teléfono en el recurso de Azure Communication Services que puede realizar llamadas salientes. Si tiene una suscripción gratuita, puede obtener un número de teléfono de prueba.
- Crear y hospedar Azure Dev Tunnel. Consulte las instrucciones aquí.
- Crea y conecta una instancia de servicios de Azure AI de multiservicio al recurso de Azure Communication Services.
- Crea un subdominio personalizado para el recurso de servicios de Azure AI.
- (Opcional) Un usuario de Microsoft Teams con una licencia de teléfono que está habilitado para
voice
. La licencia de teléfono de Teams es necesaria para agregar usuarios de Teams a la llamada. Obtén aquí más información sobre las licencias de Teams. Obtenga información sobre cómo habilitar el sistema telefónico convoice
aquí.
Código de ejemplo
Descargue o clone el código de ejemplo de inicio rápido desde GitHub.
Vaya a la carpeta CallAutomation_OutboundCalling
y abra la solución en un editor de código.
Configurar y hospedar Azure DevTunnel
Azure DevTunnels es un servicio de Azure que permite compartir servicios web locales hospedados en internet. Ejecute los comandos para conectar el entorno de desarrollo local a la red pública de internet. DevTunnels crea una dirección URL de punto de conexión persistente que permite el acceso anónimo. Usamos este punto de conexión para notificar a la aplicación los eventos de llamada desde el servicio de automatización de llamadas de Azure Communication Services.
devtunnel create --allow-anonymous
devtunnel port create -p 8080
devtunnel host
Como alternativa, siga las instrucciones para configurar Azure DevTunnel en Visual Studio
Actualización de la configuración de la aplicación
A continuación, actualice el archivo Program.cs
con los siguientes valores:
acsConnectionString
: la cadena de conexión del recurso de Azure Communication Services. Puede encontrar la cadena de conexión de Azure Communication Services mediante las instrucciones que se indican aquí.callbackUriHost
: una vez que haya inicializado el host de DevTunnel, actualice este campo con ese URI.acsPhonenumber
: actualice este campo con el número de teléfono de Azure Communication Services que ha adquirido. Dicho número de teléfono debe usar el formato de número de teléfono E164 (por ejemplo, +18881234567)targetPhonenumber
: actualice el campo con el número de teléfono al que quiere que la aplicación llame. Dicho número de teléfono debe usar el formato de número de teléfono E164 (por ejemplo, +18881234567)cognitiveServiceEndpoint
: actualiza el campo con el punto de conexión de servicios de Azure AI.targetTeamsUserId
: (opcional) actualiza el campo con el id. de usuario de Microsoft Teams que quieres agregar a la llamada. Consulta Uso de Graph API para obtener el id. de usuario de 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>";
Realización de una llamada saliente
Para realizar la llamada de salida desde Azure Communication Services, en este ejemplo se usa el targetPhonenumber
que definiste anteriormente en la aplicación a fin de crear la llamada mediante la API CreateCallAsync
. Este código realizará una llamada saliente usando el número de teléfono de destino.
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);
Controlar eventos de automatización de llamadas
Anteriormente en nuestra aplicación, registramos el callbackUriHost
en el servicio de automatización de llamadas. El host indica el punto de conexión que el servicio requiere para notificarnos los eventos de llamada que se producen. Después, podemos recorrer en iteración los eventos y detectar los eventos específicos que la aplicación quiere comprender. En el código que aparece a continuación, respondemos al evento 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
}
}
});
(Opcional) Incorporación de un usuario de Microsoft Teams a la llamada
Puedes agregar un usuario de Microsoft Teams a la llamada mediante el método AddParticipantAsync
con un elemento MicrosoftTeamsUserIdentifier
y el id. del usuario de Teams. Primero debes completar el paso de requisito previo: Autorización para el recurso de Azure Communication Services a fin de habilitar la llamada a usuarios de Microsoft Teams. Opcionalmente, también puedes pasar un elemento SourceDisplayName
a fin de controlar el texto que se muestra en la notificación del sistema para el usuario de Teams.
await callConnection.AddParticipantAsync(
new CallInvite(new MicrosoftTeamsUserIdentifier(targetTeamsUserId))
{
SourceDisplayName = "Jack (Contoso Tech Support)"
});
Iniciar la grabación de una llamada
El servicio de automatización de llamadas también permite iniciar la grabación y almacenar grabaciones de llamadas de voz y vídeo. Puede obtener más información sobre las distintas funcionalidades de las API de grabación de llamadas aquí.
CallLocator callLocator = new ServerCallLocator(parsedEvent.ServerCallId);
var recordingResult = await callAutomationClient.GetCallRecording().StartAsync(new StartRecordingOptions(callLocator));
recordingId = recordingResult.Value.RecordingId;
Reproducir mensaje de bienvenida y reconocer
Con TextSource
, puedes proporcionar al servicio el texto que quieres sintetizar y usar para el mensaje de bienvenida. El servicio de automatización de llamadas de Azure Communication Services reproduce este mensaje tras el evento CallConnected
.
A continuación, pasamos el texto a CallMediaRecognizeChoiceOptions
y, después, llamamos a StartRecognizingAsync
. Esto permite que la aplicación reconozca la opción que elige el autor de la llamada.
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
}
};
}
Control de eventos de elección
La Automatización de llamadas de Azure Communication Services desencadena el api/callbacks
en el webhook que tenemos configurado y nos notificará el evento RecognizeCompleted
. El evento nos ofrece la capacidad de responder a la entrada recibida y de desencadenar una acción. Después, la aplicación reproduce un mensaje al autor de la llamada en función de la entrada específica recibida.
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);
}
Colgar y detener la grabación
Por último, cuando detectamos una condición que hace que tenga sentido finalizar la llamada, podemos usar el método HangUpAsync
para colgar.
if ((parsedEvent is PlayCompleted) || (parsedEvent is PlayFailed))
{
logger.LogInformation($"Stop recording and terminating call.");
callAutomationClient.GetCallRecording().Stop(recordingId);
await callConnection.HangUpAsync(true);
}
Ejecución del código
Para ejecutar la aplicación con VS Code, abra una ventana de terminal y ejecute el siguiente comando
dotnet run
Abra http://localhost:8080/swagger/index.html
o la dirección URL del túnel de desarrollo en el explorador. La dirección URL del túnel tiene el siguiente aspecto: <YOUR DEV TUNNEL ENDPOINT>/swagger/index.html
Requisitos previos
- Una cuenta de Azure con una suscripción activa. Cree una cuenta gratuita.
- Un recurso de Communication Services implementado. Cree un recurso de Communication Services.
- Un número de teléfono en el recurso de Azure Communication Services que puede realizar llamadas salientes. Si tiene una suscripción gratuita, puede obtener un número de teléfono de prueba.
- Crear y hospedar Azure Dev Tunnel. Consulte las instrucciones aquí.
- Crea y conecta una instancia de servicios de Azure AI de multiservicio al recurso de Azure Communication Services.
- Crea un subdominio personalizado para el recurso de servicios de Azure AI.
- Kit de desarrollo de Java (JDK), versión 11 o posterior.
- Apache Maven.
- (Opcional) Un usuario de Microsoft Teams con una licencia de teléfono que está habilitado para
voice
. La licencia de teléfono de Teams es necesaria para agregar usuarios de Teams a la llamada. Obtén aquí más información sobre las licencias de Teams. Para obtener más información sobre cómo habilitarvoice
en el sistema telefónico, consulte configuración del sistema telefónico.
Código de ejemplo
Descargue o clone el código de ejemplo de inicio rápido desde GitHub.
Vaya a la carpeta CallAutomation_OutboundCalling
y abra la solución en un editor de código.
Configurar y hospedar Azure DevTunnel
Azure DevTunnels es un servicio de Azure que permite compartir servicios web locales hospedados en internet. Ejecute los comandos de DevTunnel para conectar el entorno de desarrollo local a la red pública de internet. A continuación, DevTunnels crea un túnel con una dirección URL de punto de conexión persistente que permite el acceso anónimo. Azure Communication Services usa este punto de conexión para notificar a la aplicación los eventos de llamada desde el servicio de automatización de llamadas de Azure Communication Services.
devtunnel create --allow-anonymous
devtunnel port create -p MY_SPRINGAPP_PORT
devtunnel host
Actualización de la configuración de la aplicación
A continuación, abra el archivo application.yml
en la carpeta /resources
para configurar los valores siguientes:
connectionstring
: la cadena de conexión del recurso de Azure Communication Services. Puede encontrar la cadena de conexión de Azure Communication Services mediante las instrucciones que se indican aquí.basecallbackuri
: una vez que haya inicializado el host de DevTunnel, actualice este campo con ese URI.callerphonenumber
: actualice este campo con el número de teléfono de Azure Communication Services que ha adquirido. Dicho número de teléfono debe usar el formato de número de teléfono E164 (por ejemplo, +18881234567)targetphonenumber
: actualice el campo con el número de teléfono al que quiere que la aplicación llame. Dicho número de teléfono debe usar el formato de número de teléfono E164 (por ejemplo, +18881234567)cognitiveServiceEndpoint
: actualiza el campo con el punto de conexión de servicios de Azure AI.targetTeamsUserId
: (opcional) actualiza el campo con el id. de usuario de Microsoft Teams que quieres agregar a la llamada. Consulta Uso de Graph API para obtener el id. de usuario de 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. "00aa00aa-bb11-cc22-dd33-44ee44ee44ee">
Realizar una llamada saliente y reproducir elementos multimedia
Para realizar la llamada de salida desde Azure Communication Services, en este ejemplo se usa el elemento targetphonenumber
que definiste en el archivo application.yml
a fin de crear la llamada mediante la API createCallWithResponse
.
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);
(Opcional) Incorporación de un usuario de Microsoft Teams a la llamada
Puedes agregar un usuario de Microsoft Teams a la llamada mediante el método addParticipant
con un elemento MicrosoftTeamsUserIdentifier
y el id. del usuario de Teams. Primero debes completar el paso de requisito previo: Autorización para el recurso de Azure Communication Services a fin de habilitar la llamada a usuarios de Microsoft Teams. Opcionalmente, también puedes pasar un elemento SourceDisplayName
a fin de controlar el texto que se muestra en la notificación del sistema para el usuario de Teams.
client.getCallConnection(callConnectionId).addParticipant(
new CallInvite(new MicrosoftTeamsUserIdentifier(targetTeamsUserId))
.setSourceDisplayName("Jack (Contoso Tech Support)"));
Iniciar la grabación de una llamada
El servicio de automatización de llamadas también permite iniciar la grabación y almacenar grabaciones de llamadas de voz y vídeo. Puede obtener más información sobre las distintas funcionalidades de las API de grabación de llamadas aquí.
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();
Responder a eventos de llamada
Anteriormente en nuestra aplicación, registramos el basecallbackuri
en el servicio de automatización de llamadas. El URI indica el punto de conexión que el servicio usará para notificarnos los eventos de llamada que se produzcan. Después, podemos recorrer en iteración los eventos y detectar los eventos específicos que la aplicación quiere comprender. En el código que aparece a continuación, respondemos al evento 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");
}
}
Reproducir mensaje de bienvenida y reconocer
Con TextSource
, puedes proporcionar al servicio el texto que quieres sintetizar y usar para el mensaje de bienvenida. El servicio de automatización de llamadas de Azure Communication Services reproduce este mensaje tras el evento CallConnected
.
A continuación, pasamos el texto a CallMediaRecognizeChoiceOptions
y, después, llamamos a StartRecognizingAsync
. Esto permite que la aplicación reconozca la opción que elige el autor de la llamada.
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;
}
Control de eventos de elección
La Automatización de llamadas de Azure Communication Services desencadena el api/callbacks
en el webhook que tenemos configurado y nos notificará el evento RecognizeCompleted
. El evento nos ofrece la capacidad de responder a la entrada recibida y de desencadenar una acción. Después, la aplicación reproduce un mensaje al autor de la llamada en función de la entrada específica recibida.
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);
}
Finalización de la llamada
Por último, cuando detectamos una condición que hace que tenga sentido finalizar la llamada, podemos usar el método hangUp
para colgar.
client.getCallConnection(callConnectionId).hangUp(true);
Ejecución del código
Navegue hasta el directorio que contiene el archivo pom.xml y use los siguientes comandos de mvn:
- Compilar la aplicación:
mvn compile
- Compilar el paquete:
mvn package
- Ejecutar la aplicación:
mvn exec:java
Requisitos previos
- Una cuenta de Azure con una suscripción activa. Cree una cuenta gratuita.
- Un recurso de Communication Services implementado. Cree un recurso de Communication Services.
- Un número de teléfono en el recurso de Azure Communication Services que puede realizar llamadas salientes. Si tiene una suscripción gratuita, puede obtener un número de teléfono de prueba.
- Crear y hospedar Azure Dev Tunnel. Consulte las instrucciones aquí.
- Crea un subdominio personalizado para el recurso de servicios de Azure AI.
- Instalación de LTS de Node.js.
- Visual Studio Code instalado.
- (Opcional) Un usuario de Microsoft Teams con una licencia de teléfono que está habilitado para
voice
. La licencia de teléfono de Teams es necesaria para agregar usuarios de Teams a la llamada. Obtén aquí más información sobre las licencias de Teams. Para obtener más información sobre cómo habilitarvoice
en el sistema telefónico, consulte configuración del sistema telefónico.
Código de ejemplo
Descargue o clone el código de ejemplo de inicio rápido desde GitHub.
Vaya a la carpeta CallAutomation_OutboundCalling
y abra la solución en un editor de código.
Configuración del entorno
Descargue el código de ejemplo, vaya al directorio del proyecto, ejecute el comando npm
que instala las dependencias necesarias y configure el entorno de desarrollador.
npm install
Configurar y hospedar Azure DevTunnel
Azure DevTunnels es un servicio de Azure que permite compartir servicios web locales hospedados en internet. Use los comandos de la CLI de DevTunnel para conectar el entorno de desarrollo local a la red pública de internet. Usamos este punto de conexión para notificar a la aplicación los eventos de llamada desde el servicio de automatización de llamadas de Azure Communication Services.
devtunnel create --allow-anonymous
devtunnel port create -p 8080
devtunnel host
Actualización de la configuración de la aplicación
A continuación, actualice el archivo .env
con los siguientes valores:
CONNECTION_STRING
: la cadena de conexión del recurso de Azure Communication Services. Puede encontrar la cadena de conexión de Azure Communication Services mediante las instrucciones que se indican aquí.CALLBACK_URI
: una vez que haya inicializado el host de DevTunnel, actualice este campo con ese URI.TARGET_PHONE_NUMBER
: actualice el campo con el número de teléfono al que quiere que la aplicación llame. Dicho número de teléfono debe usar el formato de número de teléfono E164 (por ejemplo, +18881234567)ACS_RESOURCE_PHONE_NUMBER
: actualice este campo con el número de teléfono de Azure Communication Services que ha adquirido. Dicho número de teléfono debe usar el formato de número de teléfono E164 (por ejemplo, +18881234567)COGNITIVE_SERVICES_ENDPOINT
: actualiza el campo con el punto de conexión de servicios de Azure AI.TARGET_TEAMS_USER_ID
: (opcional) actualiza el campo con el id. de usuario de Microsoft Teams que quieres agregar a la llamada. Consulta Uso de Graph API para obtener el id. de usuario de 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>"
Realizar una llamada saliente y reproducir elementos multimedia
Para realizar la llamada saliente desde Azure Communication Services, usa el número de teléfono que proporcionaste al entorno. Asegúrese de que el número de teléfono tiene el formato de número de teléfono E164 (por ejemplo, +18881234567)
El código realiza una llamada saliente usando el target_phone_number que ha proporcionado y realiza una llamada saliente a ese número:
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);
(Opcional) Incorporación de un usuario de Microsoft Teams a la llamada
Puedes agregar un usuario de Microsoft Teams a la llamada mediante el método addParticipant
con la propiedad microsoftTeamsUserId
. Primero debes completar el paso de requisito previo: Autorización para el recurso de Azure Communication Services a fin de habilitar la llamada a usuarios de Microsoft Teams. Opcionalmente, también puedes pasar un elemento sourceDisplayName
a fin de controlar el texto que se muestra en la notificación del sistema para el usuario de Teams.
await acsClient.getCallConnection(callConnectionId).addParticipant({
targetParticipant: { microsoftTeamsUserId: process.env.TARGET_TEAMS_USER_ID },
sourceDisplayName: "Jack (Contoso Tech Support)"
});
Iniciar la grabación de una llamada
El servicio de automatización de llamadas también permite iniciar la grabación y almacenar grabaciones de llamadas de voz y vídeo. Puede obtener más información sobre las distintas funcionalidades de las API de grabación de llamadas aquí.
const callLocator: CallLocator = {
id: serverCallId,
kind: "serverCallLocator",
};
const recordingOptions: StartRecordingOptions = {
callLocator: callLocator,
};
const response = await acsClient.getCallRecording().start(recordingOptions);
recordingId = response.recordingId;
Responder a eventos de llamada
Anteriormente en nuestra aplicación, registramos el CALLBACK_URI
en el servicio de automatización de llamadas. El URI indica el punto de conexión que el servicio usa para notificarnos los eventos de llamada que se producen. Después, podemos recorrer en iteración los eventos y detectar los eventos específicos que la aplicación quiere comprender. Respondemos al evento CallConnected
para recibir notificaciones e iniciar operaciones de bajada. Con TextSource
, puedes proporcionar al servicio el texto que quieres sintetizar y usar para el mensaje de bienvenida. El servicio de automatización de llamadas de Azure Communication Services reproduce este mensaje tras el evento CallConnected
.
A continuación, pasamos el texto a CallMediaRecognizeChoiceOptions
y, después, llamamos a StartRecognizingAsync
. Esto permite que la aplicación reconozca la opción que elige el autor de la llamada.
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)
}
Control de eventos de elección
La Automatización de llamadas de Azure Communication Services desencadena el api/callbacks
en el webhook que tenemos configurado y nos notificará el evento RecognizeCompleted
. El evento nos ofrece la capacidad de responder a la entrada recibida y de desencadenar una acción. Después, la aplicación reproduce un mensaje al autor de la llamada en función de la entrada específica recibida.
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]);
}
Finalización de la llamada
Por último, cuando detectamos una condición que hace que tenga sentido finalizar la llamada, podemos usar el método hangUp()
para colgar.
await acsClient.getCallRecording().stop(recordingId);
callConnection.hangUp(true);
Ejecución del código
Para ejecutar la aplicación, abra una ventana de terminal y ejecute el siguiente comando:
npm run dev
Requisitos previos
- Una cuenta de Azure con una suscripción activa. Cree una cuenta gratuita.
- Un recurso de Communication Services implementado. Cree un recurso de Communication Services.
- Un número de teléfono en el recurso de Azure Communication Services que puede realizar llamadas salientes. Si tiene una suscripción gratuita, puede obtener un número de teléfono de prueba.
- Crear y hospedar Azure Dev Tunnel. Consulte las instrucciones aquí.
- Crea y conecta una instancia de servicios de Azure AI de multiservicio al recurso de Azure Communication Services.
- Crea un subdominio personalizado para el recurso de servicios de Azure AI.
- Versión 3.7 o superiores de Python.
- (Opcional) Un usuario de Microsoft Teams con una licencia de teléfono que está habilitado para
voice
. La licencia de teléfono de Teams es necesaria para agregar usuarios de Teams a la llamada. Obtén aquí más información sobre las licencias de Teams. Para obtener más información sobre cómo habilitarvoice
en el sistema telefónico, consulte configuración del sistema telefónico.
Código de ejemplo
Descargue o clone el código de ejemplo de inicio rápido desde GitHub.
Vaya a la carpeta CallAutomation_OutboundCalling
y abra la solución en un editor de código.
Configuración del entorno de Python
Cree y active el entorno de Python e instale los paquetes necesarios mediante el comando siguiente. Puede obtener más información sobre cómo administrar paquetes aquí
pip install -r requirements.txt
Configurar y hospedar Azure DevTunnel
Azure DevTunnels es un servicio de Azure que permite compartir servicios web locales hospedados en internet. Use los comandos para conectar el entorno de desarrollo local a la red pública de internet. DevTunnels crea un túnel con una dirección URL de punto de conexión persistente que permite el acceso anónimo. Usamos este punto de conexión para notificar a la aplicación los eventos de llamada desde el servicio de automatización de llamadas de Azure Communication Services.
devtunnel create --allow-anonymous
devtunnel port create -p 8080
devtunnel host
Actualización de la configuración de la aplicación
A continuación, actualice el archivo main.py
con los siguientes valores:
ACS_CONNECTION_STRING
: la cadena de conexión del recurso de Azure Communication Services. Puede encontrar la cadena de conexión de Azure Communication Services mediante las instrucciones que se indican aquí.CALLBACK_URI_HOST
: una vez que haya inicializado el host de DevTunnel, actualice este campo con ese URI.TARGET_PHONE_NUMBER
: actualice el campo con el número de teléfono al que quiere que la aplicación llame. Dicho número de teléfono debe usar el formato de número de teléfono E164 (por ejemplo, +18881234567)ACS_PHONE_NUMBER
: actualice este campo con el número de teléfono de Azure Communication Services que ha adquirido. Dicho número de teléfono debe usar el formato de número de teléfono E164 (por ejemplo, +18881234567)COGNITIVE_SERVICES_ENDPOINT
: actualiza el campo con el punto de conexión de servicios de Azure AI.TARGET_TEAMS_USER_ID
: (opcional) actualiza el campo con el id. de usuario de Microsoft Teams que quieres agregar a la llamada. Consulta Uso de Graph API para obtener el id. de usuario de 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. "00aa00aa-bb11-cc22-dd33-44ee44ee44ee"
TARGET_TEAMS_USER_ID = "<TARGET_TEAMS_USER_ID>"
Realización de una llamada saliente
Para realizar la llamada saliente desde Azure Communication Services, primero debes proporcionar el número de teléfono que quieres que reciba la llamada. Para simplificarlo, puede actualizar target_phone_number
con un número de teléfono que tenga el formato de número de teléfono E164 (por ejemplo, +18881234567)
Realice una llamada saliente con el target_phone_number que ha proporcionado:
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("/")
(Opcional) Incorporación de un usuario de Microsoft Teams a la llamada
Puedes agregar un usuario de Microsoft Teams a la llamada mediante el método add_participant
con un elemento MicrosoftTeamsUserIdentifier
y el id. del usuario de Teams. Primero debes completar el paso de requisito previo: Autorización para el recurso de Azure Communication Services a fin de habilitar la llamada a usuarios de Microsoft Teams. Opcionalmente, también puedes pasar un elemento source_display_name
a fin de controlar el texto que se muestra en la notificación del sistema para el usuario de Teams.
call_connection_client.add_participant(target_participant = CallInvite(
target = MicrosoftTeamsUserIdentifier(user_id=TARGET_TEAMS_USER_ID),
source_display_name = "Jack (Contoso Tech Support)"))
Iniciar la grabación de una llamada
El servicio de automatización de llamadas también permite iniciar la grabación y almacenar grabaciones de llamadas de voz y vídeo. Puede obtener más información sobre las distintas funcionalidades de las API de grabación de llamadas aquí.
recording_properties = call_automation_client.start_recording(ServerCallLocator(event.data['serverCallId']))
recording_id = recording_properties.recording_id
Responder a eventos de llamada
Anteriormente en nuestra aplicación, registramos el CALLBACK_URI_HOST
en el servicio de automatización de llamadas. El URI indica el punto de conexión que el servicio usa para notificarnos los eventos de llamada que se producen. Después, podemos recorrer en iteración los eventos y detectar los eventos específicos que la aplicación quiere comprender. En el código que aparece a continuación, respondemos al evento 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)
Reproducir mensaje de bienvenida y reconocer
Con TextSource
, puedes proporcionar al servicio el texto que quieres sintetizar y usar para el mensaje de bienvenida. El servicio de automatización de llamadas de Azure Communication Services reproduce este mensaje tras el evento CallConnected
.
A continuación, pasamos el texto a CallMediaRecognizeChoiceOptions
y, después, llamamos a StartRecognizingAsync
. Esto permite que la aplicación reconozca la opción que elige el autor de la llamada.
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
Control de eventos de elección
La Automatización de llamadas de Azure Communication Services desencadena el api/callbacks
en el webhook que tenemos configurado y nos notificará el evento RecognizeCompleted
. El evento nos ofrece la capacidad de responder a la entrada recibida y de desencadenar una acción. Después, la aplicación reproduce un mensaje al autor de la llamada en función de la entrada específica recibida.
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)
Finalización de la llamada
Por último, cuando detectamos una condición que hace que tenga sentido finalizar la llamada, podemos usar el método hang_up()
para colgar. Por último, también podemos detener de forma segura la operación de grabación de llamadas.
call_automation_client.stop_recording(recording_id)
call_connection_client.hang_up(is_for_everyone=True)
Ejecución del código
Para ejecutar la aplicación con VS Code, abra una ventana de terminal y ejecute el siguiente comando
python main.py