Primeira chamada de saída

serverCall() inicia uma chamada de saída enviando o contexto da chamada para a API da Vonage. A API da Vonage, então, invoca seu webhook de resposta com o contexto como custom_data, e seu webhook retorna um NCCO que determina o roteamento.

Fluxo de saída

  1. Chamadas do aplicativo cliente serverCall(context).
  2. A API da Vonage chama seu webhook de resposta com o contexto como custom_data.
  3. Seu webhook retorna NCCO.
  4. A API da Vonage conecta a mídia ao destinatário da chamada.

Trecho do cliente

const context = {
  to: 'sip:alice@example.com',
  from: 'agent-123'
};

try {
  const callId = await client.serverCall(context);
  console.log(`Outbound call started, callId: ${callId}`);
} catch (error) {
  console.error('Failed to start outbound call', error);
}
 val context = mapOf(
     "to" to "sip:alice@example.com",
     "from" to "agent-123"
 )

 client.serverCall(context) { error, callId ->
     if (error != null) {
         println("Failed to start outbound call: $error")
         return@serverCall
     }

     println("Outbound call started, callId: $callId")
 }
 HashMap<String, String> context = new HashMap<>();
 context.put("to", "sip:alice@example.com");
 context.put("from", "agent-123");

 client.serverCall(context, (error, callId) -> {
     if (error != null) {
         System.out.println("Failed to start outbound call: " + error);
         return null;
     }

     System.out.println("Outbound call started, callId: " + callId);
     return null;
 });
 let context = [
     "to": "sip:alice@example.com",
     "from": "agent-123"
 ]

 client.serverCall(context) { error, callId in
     guard error == nil, let callId = callId else {
         print("Failed to start outbound call: \(error?.localizedDescription ?? "unknown")")
         return
     }

     print("Outbound call started, callId: \(callId)")
 }
 NSDictionary *context = @{
     @"to": @"sip:alice@example.com",
     @"from": @"agent-123"
 };

 [client serverCall:context callback:^(NSError * _Nullable error, VGCallId _Nullable callId) {
     if (error != nil || callId == nil) {
         NSLog(@"Failed to start outbound call: %@", error);
         return;
     }

     NSLog(@"Outbound call started, callId: %@", callId);
 }];

Webhook de resposta do servidor

O exemplo abaixo ilustra o formato exigido para a resposta do webhook. Sua implementação concreta irá variar de acordo com a linguagem e a estrutura de seu backend.

Seu webhook de resposta deve estar acessível publicamente e retornar um NCCO válido.

Uso "type": "app" no endpoint de conexão para encaminhar a chamada para um Client SDK por nome de usuário. Use "type": "phone" para encaminhar para um número da PSTN. Consulte o Tipos de terminais do NCCO Connect para todas as opções.

const customData =
  (req.body.custom_data as { to?: string } | undefined) ?? {};
const destination = customData.to ?? 'callee-username';

const answerNcco = [
  {
    action: 'connect',
    endpoint: [
      {
        type: 'app',
        user: destination
      }
    ]
  }
];

res.json(answerNcco);

Referência NCCO: aqui

Tratamento de erros

serverCall pode falhar se não houver uma sessão ativa, se o estabelecimento da chamada atingir o tempo limite ou se a API da Vonage encontrar um problema com o seu webhook. Sempre trate o erro:

try {
  const callId = await client.serverCall({ context });
  console.log("Call started:", callId);
} catch (error) {
  console.error("Call failed:", error.type, error.message);
}
client.serverCall(context) { error, callId ->
    if (error != null) {
        println("Call failed: ${error.message}")
        // Common causes:
        // - No active session (call createSession first)
        // - Network timeout
        // - Answer webhook returned invalid NCCO
        return@serverCall
    }
    println("Call started: $callId")
}
client.serverCall(context) { error, callId in
    if let error = error {
        print("Call failed: \(error.localizedDescription)")
        return
    }
    print("Call started: \(callId ?? "")")
}

Para obter uma lista completa dos tipos de erros possíveis, consulte Erros.