Guia de início rápido: fazer uma chamada de saída usando a automação de chamadas

As APIs de Automação de Chamadas dos Serviços de Comunicação do Azure são uma maneira poderosa de criar experiências de chamada interativas. Neste início rápido, abordamos uma maneira de fazer uma chamada de saída e reconhecer vários eventos na chamada.

Pré-requisitos

  • Uma conta do Azure com uma subscrição ativa. Crie uma conta gratuitamente.
  • Um recurso de Serviços de Comunicação implantado. Crie um recurso de Serviços de Comunicação.
  • Um número de telefone em seu recurso dos Serviços de Comunicação do Azure que pode fazer chamadas de saída. Se tiver uma subscrição gratuita, pode obter um número de telefone de avaliação.
  • Crie e hospede um Túnel de Desenvolvimento do Azure. Instruções aqui.
  • Crie e conecte um serviço de IA do Azure Multisserviço ao seu recurso dos Serviços de Comunicação do Azure.
  • Crie um subdomínio personalizado para seu recurso de serviços de IA do Azure.
  • (Opcional) Um utilizador do Microsoft Teams com uma licença telefónica. A licença por telefone do Teams é necessária para adicionar usuários do Teams à chamada. Saiba mais sobre as licenças do Teams aqui.

Código de exemplo

Baixe ou clone o código de exemplo de início rápido do GitHub.

Navegue até a CallAutomation_OutboundCalling pasta e abra a solução em um editor de código.

Configurar e hospedar seu Azure DevTunnel

O Azure DevTunnels é um serviço do Azure que permite compartilhar serviços Web locais hospedados na Internet. Execute os comandos para conectar seu ambiente de desenvolvimento local à Internet pública. DevTunnels cria uma URL de ponto de extremidade persistente e que permite acesso anônimo. Usamos esse ponto de extremidade para notificar seu aplicativo sobre eventos de chamada do serviço de Automação de Chamadas dos Serviços de Comunicação do Azure.

devtunnel create --allow-anonymous
devtunnel port create -p 8080
devtunnel host

Atualize a configuração do aplicativo

Em seguida, atualize seu Program.cs arquivo com os seguintes valores:

  • acsConnectionString: A cadeia de conexão para seu recurso dos Serviços de Comunicação do Azure. Você pode encontrar sua cadeia de conexão dos Serviços de Comunicação do Azure usando as instruções aqui.
  • callbackUriHost: Depois de inicializar o host DevTunnel, atualize este campo com esse URI.
  • acsPhonenumber: atualize este campo com o número de telefone dos Serviços de Comunicação do Azure que adquiriu. Este número de telefone deve usar o formato de número de telefone E164 (por exemplo, +18881234567)
  • targetPhonenumber: campo de atualização com o número de telefone para o qual você gostaria que seu aplicativo ligasse. Este número de telefone deve usar o formato de número de telefone E164 (por exemplo, +18881234567)
  • cognitiveServiceEndpoint: campo de atualização com seu ponto de extremidade de serviços de IA do Azure.
  • targetTeamsUserId: Campo de atualização (opcional) com o ID de usuário do Microsoft Teams que você gostaria de adicionar à chamada. Consulte Usar a API do Graph para obter o ID de usuário do 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>";

Fazer uma chamada de saída

Para fazer a chamada de saída dos Serviços de Comunicação do Azure, este exemplo usa o targetPhonenumber que você definiu anteriormente no aplicativo para criar a chamada usando a CreateCallAsync API. Este código fará uma chamada de saída usando o número de telefone 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);

Manipular eventos de automação de chamadas

No início da nossa aplicação, registámos o callbackUriHost Serviço de Automatização de Chamadas. O host indica o ponto de extremidade que o serviço requer para nos notificar de eventos de chamada que acontecem. Podemos então iterar através dos eventos e detetar eventos específicos que nosso aplicativo deseja entender. No código abaixo respondemos ao CallConnected evento.

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) Adicionar um usuário do Microsoft Teams à chamada

Você pode adicionar um usuário do Microsoft Teams à chamada usando o AddParticipantAsync método com um MicrosoftTeamsUserIdentifier e a ID do usuário do Teams. Primeiro, você precisa concluir a etapa de pré-requisito Autorização para seu Recurso de Serviços de Comunicação do Azure para habilitar chamadas para usuários do Microsoft Teams. Opcionalmente, você também pode passar um SourceDisplayName para controlar o texto exibido na notificação do sistema para o usuário do Teams.

await callConnection.AddParticipantAsync(
    new CallInvite(new MicrosoftTeamsUserIdentifier(targetTeamsUserId))
    {
        SourceDisplayName = "Jack (Contoso Tech Support)"
    });

Iniciar a gravação de uma chamada

O serviço de automação de chamadas também permite a capacidade de iniciar a gravação e armazenar gravações de chamadas de voz e vídeo. Você pode saber mais sobre os vários recursos nas APIs de gravação de chamadas aqui.

CallLocator callLocator = new ServerCallLocator(parsedEvent.ServerCallId);
var recordingResult = await callAutomationClient.GetCallRecording().StartAsync(new StartRecordingOptions(callLocator));
recordingId = recordingResult.Value.RecordingId;

Reproduza a mensagem de boas-vindas e reconheça

Usando o TextSource, você pode fornecer ao serviço o texto que deseja sintetizar e usar para sua mensagem de boas-vindas. O serviço de Automação de Chamadas dos CallConnected Serviços de Comunicação do Azure reproduz esta mensagem no evento.

Em seguida, passamos o texto para o e, em CallMediaRecognizeChoiceOptions seguida, chamamos StartRecognizingAsync. Isso permite que seu aplicativo reconheça a opção escolhida pelo chamador.

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

Manipular eventos de escolha

A Automação de Chamadas dos Serviços de Comunicação do Azure aciona o api/callbacks webhook que configuramos e nos notificará com o RecognizeCompleted evento. O evento nos dá a capacidade de responder às entradas recebidas e desencadear uma ação. Em seguida, o aplicativo reproduz uma mensagem para o chamador com base na entrada específica recebida.

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

Desligue e pare de gravar

Finalmente, quando detetamos uma condição que faz sentido para encerrarmos a chamada, podemos usar o HangUpAsync método para desligar a chamada.

if ((parsedEvent is PlayCompleted) || (parsedEvent is PlayFailed))
{
    logger.LogInformation($"Stop recording and terminating call.");
    callAutomationClient.GetCallRecording().Stop(recordingId);
    await callConnection.HangUpAsync(true);
}

Executar o código

Para executar o aplicativo com o VS Code, abra uma janela do Terminal e execute o seguinte comando

dotnet run

Pré-requisitos

Código de exemplo

Baixe ou clone o código de exemplo de início rápido do GitHub.

Navegue até a CallAutomation_OutboundCalling pasta e abra a solução em um editor de código.

Configurar e hospedar seu Azure DevTunnel

O Azure DevTunnels é um serviço do Azure que permite compartilhar serviços Web locais hospedados na Internet. Execute os comandos DevTunnel para conectar seu ambiente de desenvolvimento local à Internet pública. Em seguida, o DevTunnels cria um túnel com uma URL de ponto de extremidade persistente e que permite acesso anônimo. Os Serviços de Comunicação do Azure usam esse ponto de extremidade para notificar seu aplicativo sobre eventos de chamada do serviço de Automação de Chamadas dos Serviços de Comunicação do Azure.

devtunnel create --allow-anonymous
devtunnel port create -p MY_SPRINGAPP_PORT
devtunnel host

Atualize a configuração do aplicativo

Em seguida, abra o application.yml/resources arquivo na pasta para configurar os seguintes valores:

  • connectionstring: A cadeia de conexão para seu recurso dos Serviços de Comunicação do Azure. Você pode encontrar sua cadeia de conexão dos Serviços de Comunicação do Azure usando as instruções aqui.
  • basecallbackuri: Depois de inicializar o host DevTunnel, atualize este campo com esse URI.
  • callerphonenumber: atualize este campo com o número de telefone dos Serviços de Comunicação do Azure que adquiriu. Este número de telefone deve usar o formato de número de telefone E164 (por exemplo, +18881234567)
  • targetphonenumber: campo de atualização com o número de telefone para o qual você gostaria que seu aplicativo ligasse. Este número de telefone deve usar o formato de número de telefone E164 (por exemplo, +18881234567)
  • cognitiveServiceEndpoint: campo de atualização com seu ponto de extremidade de serviços de IA do Azure.
  • targetTeamsUserId: Campo de atualização (opcional) com o ID de usuário do Microsoft Teams que você gostaria de adicionar à chamada. Consulte Usar a API do Graph para obter o ID de usuário do 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">

Fazer uma chamada de saída e reproduzir mídia

Para fazer a chamada de saída dos Serviços de Comunicação do Azure, este exemplo usa o targetphonenumber que você definiu no application.yml arquivo para criar a chamada usando a 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);

(Opcional) Adicionar um usuário do Microsoft Teams à chamada

Você pode adicionar um usuário do Microsoft Teams à chamada usando o addParticipant método com um MicrosoftTeamsUserIdentifier e a ID do usuário do Teams. Primeiro, você precisa concluir a etapa de pré-requisito Autorização para seu Recurso de Serviços de Comunicação do Azure para habilitar chamadas para usuários do Microsoft Teams. Opcionalmente, você também pode passar um SourceDisplayName para controlar o texto exibido na notificação do sistema para o usuário do Teams.

client.getCallConnection(callConnectionId).addParticipant(
    new CallInvite(new MicrosoftTeamsUserIdentifier(targetTeamsUserId))
        .setSourceDisplayName("Jack (Contoso Tech Support)"));

Iniciar a gravação de uma chamada

O serviço de automação de chamadas também permite a capacidade de iniciar a gravação e armazenar gravações de chamadas de voz e vídeo. Você pode saber mais sobre os vários recursos nas APIs de gravação de chamadas aqui.

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 chamada

No início da nossa aplicação, registámos o basecallbackuri Serviço de Automatização de Chamadas. O URI indica o ponto de extremidade que o serviço usará para nos notificar sobre eventos de chamada que acontecem. Podemos então iterar através dos eventos e detetar eventos específicos que nosso aplicativo deseja entender. No código abaixo respondemos ao CallConnected evento.

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

Reproduza a mensagem de boas-vindas e reconheça

Usando o TextSource, você pode fornecer ao serviço o texto que deseja sintetizar e usar para sua mensagem de boas-vindas. O serviço de Automação de Chamadas dos CallConnected Serviços de Comunicação do Azure reproduz esta mensagem no evento.

Em seguida, passamos o texto para o e, em CallMediaRecognizeChoiceOptions seguida, chamamos StartRecognizingAsync. Isso permite que seu aplicativo reconheça a opção escolhida pelo chamador.

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

Manipular eventos de escolha

A Automação de Chamadas dos Serviços de Comunicação do Azure aciona o api/callbacks webhook que configuramos e nos notificará com o RecognizeCompleted evento. O evento nos dá a capacidade de responder às entradas recebidas e desencadear uma ação. Em seguida, o aplicativo reproduz uma mensagem para o chamador com base na entrada específica recebida.

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

Desligue a chamada

Finalmente, quando detetamos uma condição que faz sentido para encerrarmos a chamada, podemos usar o hangUp método para desligar a chamada.

client.getCallConnection(callConnectionId).hangUp(true);

Executar o código

Navegue até o diretório que contém o arquivo pom.xml e use os seguintes comandos mvn:

  • Compile o aplicativo: mvn compile
  • Crie o pacote: mvn package
  • Execute o aplicativo: mvn exec:java

Pré-requisitos

  • Uma conta do Azure com uma subscrição ativa. Crie uma conta gratuitamente.
  • Um recurso de Serviços de Comunicação implantado. Crie um recurso de Serviços de Comunicação.
  • Um número de telefone em seu recurso dos Serviços de Comunicação do Azure que pode fazer chamadas de saída. Se tiver uma subscrição gratuita, pode obter um número de telefone de avaliação.
  • Crie e hospede um Túnel de Desenvolvimento do Azure. Instruções aqui.
  • Crie um subdomínio personalizado para seu recurso de serviços de IA do Azure.
  • Node.js Instalação LTS.
  • Visual Studio Code instalado.
  • (Opcional) Um utilizador do Microsoft Teams com uma licença telefónica. A licença por telefone do Teams é necessária para adicionar usuários do Teams à chamada. Saiba mais sobre as licenças do Teams aqui.

Código de exemplo

Baixe ou clone o código de exemplo de início rápido do GitHub.

Navegue até a CallAutomation_OutboundCalling pasta e abra a solução em um editor de código.

Configurar o ambiente

Baixe o código de exemplo e navegue até o diretório do projeto e execute o npm comando que instala as dependências necessárias e configura seu ambiente de desenvolvedor.

npm install

Configurar e hospedar seu Azure DevTunnel

O Azure DevTunnels é um serviço do Azure que permite compartilhar serviços Web locais hospedados na Internet. Use os comandos da CLI do DevTunnel para conectar seu ambiente de desenvolvimento local à Internet pública. Usamos esse ponto de extremidade para notificar seu aplicativo sobre eventos de chamada do serviço de Automação de Chamadas dos Serviços de Comunicação do Azure.

devtunnel create --allow-anonymous
devtunnel port create -p 8080
devtunnel host

Atualize a configuração do aplicativo

Em seguida, atualize o arquivo com os .env seguintes valores:

  • CONNECTION_STRING: A cadeia de conexão para seu recurso dos Serviços de Comunicação do Azure. Você pode encontrar sua cadeia de conexão dos Serviços de Comunicação do Azure usando as instruções aqui.
  • CALLBACK_URI: Depois de inicializar o host DevTunnel, atualize este campo com esse URI.
  • TARGET_PHONE_NUMBER: campo de atualização com o número de telefone para o qual você gostaria que seu aplicativo ligasse. Este número de telefone deve usar o formato de número de telefone E164 (por exemplo, +18881234567)
  • ACS_RESOURCE_PHONE_NUMBER: atualize este campo com o número de telefone dos Serviços de Comunicação do Azure que adquiriu. Este número de telefone deve usar o formato de número de telefone E164 (por exemplo, +18881234567)
  • COGNITIVE_SERVICES_ENDPOINT: campo de atualização com seu ponto de extremidade de serviços de IA do Azure.
  • TARGET_TEAMS_USER_ID: Campo de atualização (opcional) com o ID de usuário do Microsoft Teams que você gostaria de adicionar à chamada. Consulte Usar a API do Graph para obter o ID de usuário do 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>"

Fazer uma chamada de saída e reproduzir mídia

Para fazer a chamada de saída dos Serviços de Comunicação do Azure, use o número de telefone fornecido ao ambiente. Certifique-se de que o número de telefone está no formato de número de telefone E164 (por exemplo, +18881234567)

O código faz uma chamada de saída usando o target_phone_number que você forneceu e faz uma chamada de saída para esse 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) Adicionar um usuário do Microsoft Teams à chamada

Você pode adicionar um usuário do Microsoft Teams à chamada usando o addParticipant método com a microsoftTeamsUserId propriedade. Primeiro, você precisa concluir a etapa de pré-requisito Autorização para seu Recurso de Serviços de Comunicação do Azure para habilitar chamadas para usuários do Microsoft Teams. Opcionalmente, você também pode passar um sourceDisplayName para controlar o texto exibido na notificação do sistema para o usuário do Teams.

await acsClient.getCallConnection(callConnectionId).addParticipant({
    targetParticipant: { microsoftTeamsUserId: process.env.TARGET_TEAMS_USER_ID },
    sourceDisplayName: "Jack (Contoso Tech Support)"
});

Iniciar a gravação de uma chamada

O serviço de automação de chamadas também permite a capacidade de iniciar a gravação e armazenar gravações de chamadas de voz e vídeo. Você pode saber mais sobre os vários recursos nas APIs de gravação de chamadas aqui.

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 chamada

No início da nossa aplicação, registámos o CALLBACK_URI Serviço de Automatização de Chamadas. O URI indica o ponto de extremidade que o serviço usa para nos notificar sobre eventos de chamada que acontecem. Podemos então iterar através dos eventos e detetar eventos específicos que nosso aplicativo deseja entender. Respondemos ao CallConnected evento para sermos notificados e iniciarmos operações a jusante. Usando o TextSource, você pode fornecer ao serviço o texto que deseja sintetizar e usar para sua mensagem de boas-vindas. O serviço de Automação de Chamadas dos CallConnected Serviços de Comunicação do Azure reproduz esta mensagem no evento.

Em seguida, passamos o texto para o e, em CallMediaRecognizeChoiceOptions seguida, chamamos StartRecognizingAsync. Isso permite que seu aplicativo reconheça a opção escolhida pelo chamador.

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

Manipular eventos de escolha

A Automação de Chamadas dos Serviços de Comunicação do Azure aciona o api/callbacks webhook que configuramos e nos notificará com o RecognizeCompleted evento. O evento nos dá a capacidade de responder às entradas recebidas e desencadear uma ação. Em seguida, o aplicativo reproduz uma mensagem para o chamador com base na entrada específica recebida.

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

Desligue a chamada

Finalmente, quando detetamos uma condição que faz sentido para encerrarmos a chamada, podemos usar o hangUp() método para desligar a chamada.

  await acsClient.getCallRecording().stop(recordingId);
  callConnection.hangUp(true);

Executar o código

Para executar o aplicativo, abra uma janela do Terminal e execute o seguinte comando:

  npm run dev

Pré-requisitos

  • Uma conta do Azure com uma subscrição ativa. Crie uma conta gratuitamente.
  • Um recurso de Serviços de Comunicação implantado. Crie um recurso de Serviços de Comunicação.
  • Um número de telefone em seu recurso dos Serviços de Comunicação do Azure que pode fazer chamadas de saída. Se tiver uma subscrição gratuita, pode obter um número de telefone de avaliação.
  • Crie e hospede um Túnel de Desenvolvimento do Azure. Instruções aqui.
  • Crie e conecte um serviço de IA do Azure Multisserviço ao seu recurso dos Serviços de Comunicação do Azure.
  • Crie um subdomínio personalizado para seu recurso de serviços de IA do Azure.
  • Python 3.7+.
  • (Opcional) Um utilizador do Microsoft Teams com uma licença telefónica. A licença por telefone do Teams é necessária para adicionar usuários do Teams à chamada. Saiba mais sobre as licenças do Teams aqui.

Código de exemplo

Baixe ou clone o código de exemplo de início rápido do GitHub.

Navegue até a CallAutomation_OutboundCalling pasta e abra a solução em um editor de código.

Configurar o ambiente Python

Crie e ative o ambiente python e instale os pacotes necessários usando o seguinte comando. Você pode saber mais sobre como gerenciar pacotes aqui

pip install -r requirements.txt

Configurar e hospedar seu Azure DevTunnel

O Azure DevTunnels é um serviço do Azure que permite compartilhar serviços Web locais hospedados na Internet. Use os comandos para conectar seu ambiente de desenvolvimento local à Internet pública. DevTunnels cria um túnel com uma URL de ponto de extremidade persistente e que permite acesso anônimo. Usamos esse ponto de extremidade para notificar seu aplicativo sobre eventos de chamada do serviço de Automação de Chamadas dos Serviços de Comunicação do Azure.

devtunnel create --allow-anonymous
devtunnel port create -p 8080
devtunnel host

Atualize a configuração do aplicativo

Em seguida, atualize o main.py arquivo com os seguintes valores:

  • ACS_CONNECTION_STRING: A cadeia de conexão para seu recurso dos Serviços de Comunicação do Azure. Você pode encontrar sua cadeia de conexão dos Serviços de Comunicação do Azure usando as instruções aqui.
  • CALLBACK_URI_HOST: Depois de inicializar o host DevTunnel, atualize este campo com esse URI.
  • TARGET_PHONE_NUMBER: campo de atualização com o número de telefone para o qual você gostaria que seu aplicativo ligasse. Este número de telefone deve usar o formato de número de telefone E164 (por exemplo, +18881234567)
  • ACS_PHONE_NUMBER: atualize este campo com o número de telefone dos Serviços de Comunicação do Azure que adquiriu. Este número de telefone deve usar o formato de número de telefone E164 (por exemplo, +18881234567)
  • COGNITIVE_SERVICES_ENDPOINT: campo de atualização com seu ponto de extremidade de serviços de IA do Azure.
  • TARGET_TEAMS_USER_ID: Campo de atualização (opcional) com o ID de usuário do Microsoft Teams que você gostaria de adicionar à chamada. Consulte Usar a API do Graph para obter o ID de usuário do 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>"

Fazer uma chamada de saída

Para fazer a chamada de saída dos Serviços de Comunicação do Azure, primeiro forneça o número de telefone que deseja receber a chamada. Para simplificar, você pode atualizar o target_phone_number com um número de telefone no formato de número de telefone E164 (por exemplo, +18881234567)

Faça uma chamada de saída usando o target_phone_number que você forneceu:

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) Adicionar um usuário do Microsoft Teams à chamada

Você pode adicionar um usuário do Microsoft Teams à chamada usando o add_participant método com um MicrosoftTeamsUserIdentifier e a ID do usuário do Teams. Primeiro, você precisa concluir a etapa de pré-requisito Autorização para seu Recurso de Serviços de Comunicação do Azure para habilitar chamadas para usuários do Microsoft Teams. Opcionalmente, você também pode passar um source_display_name para controlar o texto exibido na notificação do sistema para o usuário do 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 a gravação de uma chamada

O serviço de automação de chamadas também permite a capacidade de iniciar a gravação e armazenar gravações de chamadas de voz e vídeo. Você pode saber mais sobre os vários recursos nas APIs de gravação de chamadas aqui.

recording_properties = call_automation_client.start_recording(ServerCallLocator(event.data['serverCallId']))
recording_id = recording_properties.recording_id

Responder a eventos de chamada

No início da nossa aplicação, registámos o CALLBACK_URI_HOST Serviço de Automatização de Chamadas. O URI indica o ponto de extremidade que o serviço usa para nos notificar sobre eventos de chamada que acontecem. Podemos então iterar através dos eventos e detetar eventos específicos que nosso aplicativo deseja entender. No código abaixo respondemos ao CallConnected evento.

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

Reproduza a mensagem de boas-vindas e reconheça

Usando o TextSource, você pode fornecer ao serviço o texto que deseja sintetizar e usar para sua mensagem de boas-vindas. O serviço de Automação de Chamadas dos CallConnected Serviços de Comunicação do Azure reproduz esta mensagem no evento.

Em seguida, passamos o texto para o e, em CallMediaRecognizeChoiceOptions seguida, chamamos StartRecognizingAsync. Isso permite que seu aplicativo reconheça a opção escolhida pelo chamador.


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 

Manipular eventos de escolha

A Automação de Chamadas dos Serviços de Comunicação do Azure aciona o api/callbacks webhook que configuramos e nos notificará com o RecognizeCompleted evento. O evento nos dá a capacidade de responder às entradas recebidas e desencadear uma ação. Em seguida, o aplicativo reproduz uma mensagem para o chamador com base na entrada específica recebida.

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)

Desligue a chamada

Finalmente, quando detetamos uma condição que faz sentido para encerrarmos a chamada, podemos usar o hang_up() método para desligar a chamada. Finalmente, também podemos parar com segurança a operação de gravação de chamadas.

call_automation_client.stop_recording(recording_id)
call_connection_client.hang_up(is_for_everyone=True)

Executar o código

Para executar o aplicativo com o VS Code, abra uma janela do Terminal e execute o seguinte comando

python main.py