【问题标题】:How to do multiple call using nexmo in-app voice?如何使用 nexmo 应用内语音进行多个通话?
【发布时间】:2020-07-23 10:03:28
【问题描述】:

您好,我尝试按照本教程 https://developer.nexmo.com/client-sdk/tutorials/app-to-phone/client-sdk/app-to-phone/js-code/javascript 在应用程序中创建语音并将其与 laravel 结合使用。它可以像3个用户同时使用它来拨打多个电话吗?似乎当我尝试同时使用它进行多个调用时,连接使用相同的 websocket。

这是我的 javascript 代码:

// contact button on table 1
dataTableAdminLeader.on('click', '.call-button', function(){
  $('#phone-call-modal').modal('show');
  let id                  = $(this).data('id');
  let master_number_id    = $(this).data('master_numbers_id');
  let target_number       = $(this).data('number');
  // input reset
  document.querySelector('#target-phone').value = target_number;
  document.querySelector('#master-number-id').value = master_number_id;
  document.querySelector('#id-edit').value = id;
  document.querySelector('#master-numbers-id-edit').value = master_number_id;
  // ajax object 
  const xhr               = new XMLHttpRequest();
  // all constant needed for call
  const USER_JWT          = "{{ $jwt_token }}";
  const phoneNumberInput  = document.querySelector("#cs-phone");
  const statusElement     = document.querySelector("#status-call");
  // button object selector
  const callButton        = document.querySelector(".btn-call");
  const hangupButton      = document.querySelector(".btn-hangup");
  const updateButton      = document.querySelector(".btn-update");
  const closeButton       = document.querySelector('.btn-close');
  const statusButton      = document.querySelector('.btn-status');
  // input object selector
  let campaign_result     = document.querySelector('#campaignresult');
  let note_contacted      = document.querySelector('#note_contacted');
  let note_container      = document.querySelector('.note_container');
  let campaignContainer   = document.querySelector('.campaign-container');
  // call status check
  let callStatusCompleted = false;
  let callStatusAnswered  = false;
  // reset property
  campaign_result.value   = "";
  note_container.style    = 'display: none';
  // listening to event
  campaign_result.addEventListener('change', function(){
    if(campaign_result.value == 2){
      note_container.style.removeProperty('display');
      note_contacted.setAttribute('required', 'required');
    }else{
      note_container.style = 'display: none';
      note_contacted.removeAttribute('required');
    }
  });
  // nexmo status reset
  statusElement.innerText = '';
  // nexmo call button reset
  callButton.style.display = "inline";
  hangupButton.style.display = "none";
  // timeouts set
  setTimeout(() => {
    callButton.removeAttribute('disabled');
  }, 4000);
  // nexmo object start
  new NexmoClient({ debug: true }).login(USER_JWT).then(app => {
    callButton.addEventListener("click", event => {
      event.preventDefault();
      let number = phoneNumberInput.value;
      if (number !== ""){
        app.callServer(number);
      } else {
        statusElement.innerText = 'Please enter your phone number.';
      }
    });
    app.on("member:call", (member, call) => {
      console.log('member:call:oke:',app);
      // object selector reset
      callButton.style.display = 'none';
      closeButton.style.display = 'none';
      hangupButton.style.removeProperty('display');
      statusButton.style.removeProperty('display');
      // event when hangup button clicked
      hangupButton.addEventListener("click", () => {
        call.hangUp();
      });
    });
    app.on("call:status:changed",(call) => {
      console.log('Periodik : ', call.status);
      // animation call
      let statusAnimation = `<p class="saving">Call status: ${call.status}<span>.</span><span>.</span><span>.</span></p>`;
      // assign call animation to nexmo status display
      statusElement.innerHTML = statusAnimation;
      // filter nexmo status condition
      switch(call.status) {
        case call.CALL_STATUS.STARTED:
          console.log('Case call status: ', call.status);
          break;
        case call.CALL_STATUS.RINGING:
          // ajax params
          params = `id=${id}&master_number_id=${master_number_id}&status=${call.status}`;
          xhr.open('POST', '{{ url('/call/update') }}', false);
          xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
          xhr.send(params);
          xhr.onload = function(){
            let response = JSON.parse(this.responseText);
            console.log('xhr: ',response);
          }
          dataTableAdminLeader.ajax.reload();
          console.log('Case call status: ', call.status);
          break;
        case call.CALL_STATUS.FAILED:
          callStatusAnswered = false;
          callButton.style.display = 'none';
          hangupButton.style.display = 'none';
          closeButton.style.display = 'none';
          statusButton.style.removeProperty('display');
          // ajax send
          params = `id=${id}&master_number_id=${master_number_id}&status=${call.status}`;
          xhr.open('POST', '{{ url('/call/update') }}', false);
          xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
          xhr.send(params);
          xhr.onload = function(){
            let response = JSON.parse(this.responseText);
            console.log('xhr: ',response);
          }
          dataTableAdminLeader.ajax.reload();
          console.log('Case call status: ', call.status);
          break;
        case call.CALL_STATUS.CANCELLED:
          callStatusAnswered = false;
          callButton.style.removeProperty('display');
          hangupButton.style.display = 'none';
          closeButton.style.removeProperty('display');
          statusButton.style.display = 'none';
          // ajax send
          params = `id=${id}&master_number_id=${master_number_id}&status=${call.status}`;
          xhr.open('POST', '{{ url('/call/update') }}', false);
          xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
          xhr.send(params);
          xhr.onload = function(){
            let response = JSON.parse(this.responseText);
            console.log('xhr: ',response);
          }
          dataTableAdminLeader.ajax.reload();
          console.log('Case call status: ', call.status);
          break;
        case call.CALL_STATUS.BUSY:
          callStatusAnswered = false;
          callButton.style.display = 'none';
          hangupButton.style.display = 'none';
          closeButton.style.removeProperty('display');
          statusButton.style.display = 'none';
          // ajax send
          params = `id=${id}&master_number_id=${master_number_id}&status=${call.status}`;
          xhr.open('POST', '{{ url('/call/update') }}', false);
          xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
          xhr.send(params);
          xhr.onload = function(){
            let response = JSON.parse(this.responseText);
            console.log('xhr: ',response);
          }
          dataTableAdminLeader.ajax.reload();
          console.log('Case call status: ', call.status);
          break;
        case call.CALL_STATUS.TIMEOUT:
          callStatusAnswered = false;
          callButton.style.display = 'none';
          hangupButton.style.display = 'none';
          closeButton.style.removeProperty('display');
          statusButton.style.display = 'none';
          // ajax send
          params = `id=${id}&master_number_id=${master_number_id}&status=${call.status}`;
          xhr.open('POST', '{{ url('/call/update') }}', false);
          xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
          xhr.send(params);
          xhr.onload = function(){
            let response = JSON.parse(this.responseText);
            console.log('xhr: ',response);
          }
          dataTableAdminLeader.ajax.reload();
          console.log('Case call status: ', call.status);
          break;
        case call.CALL_STATUS.REJECTED:
          callStatusAnswered = false;
          callButton.style.display = 'none';
          hangupButton.style.display = 'none';
          closeButton.style.removeProperty('display');
          statusButton.style.display = 'none';
          // ajax send
          params = `id=${id}&master_number_id=${master_number_id}&status=${call.status}`;
          xhr.open('POST', '{{ url('/call/update') }}', false);
          xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
          xhr.send(params);
          xhr.onload = function(){
            let response = JSON.parse(this.responseText);
            console.log('xhr: ',response);
          }
          dataTableAdminLeader.ajax.reload();
          console.log('Case call status: ', call.status);
          break;
        case call.CALL_STATUS.UNANSWERED:
          callStatusAnswered = false;
          callButton.style.display = 'none';
          hangupButton.style.display = 'none';
          closeButton.style.removeProperty('display');
          statusButton.style.display = 'none';
          // ajax send
          params = `id=${id}&master_number_id=${master_number_id}&status=${call.status}`;
          xhr.open('POST', '{{ url('/call/update') }}', false);
          xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
          xhr.send(params);
          xhr.onload = function(){
            let response = JSON.parse(this.responseText);
            console.log('xhr: ',response);
          }
          dataTableAdminLeader.ajax.reload();
          console.log('Case call status: ', call.status);
          break;
        case call.CALL_STATUS.COMPLETED:
          call.hangUp();
          callStatusCompleted = true;
          callButton.style.display = 'none';
          hangupButton.style.display = 'none';
          updateButton.style.removeProperty('display');
          closeButton.style.display = 'none';
          statusButton.style.display = 'none';
          campaignContainer.style.removeProperty('display');
          dataTableAdminLeader.ajax.reload();
          console.log('Case call status: ', call.status);
          break;
        case call.CALL_STATUS.ANSWERED:
          callStatusAnswered = true;
          callButton.style.display = 'none';
          hangupButton.style.removeProperty('display');
          closeButton.style.display = 'none';
          statusButton.style.display = 'none';
          // ajax send
          params = `id=${id}&master_number_id=${master_number_id}&status=${call.status}`;
          xhr.open('POST', '{{ url('/call/update') }}', false);
          xhr.setRequestHeader('Content-type', 'application/x-www-form-urlencoded');
          xhr.send(params);
          xhr.onload = function(){
            let response = JSON.parse(this.responseText);
            console.log('xhr: ',response);
          }
          console.log('Case call status: ', call.status);
          break;
        default:
          console.log('Case call status: ', call.status);
      }
    });
  }).catch(function(){
    alert('Network Problem, refresh page and try again later. Please contact dev team if this problem not fix in few minutes.');
    console.error;
    $('#phone-call-modal').modal('hide');
  });
});

【问题讨论】:

    标签: laravel websocket socket.io nexmo


    【解决方案1】:

    您可以使用 Vonage Voice API 和客户端 SDK 连续拨打多个外拨电话。 callServer() 函数将您希望拨打的电话号码作为参数,如 Client SDK documentation 中所述。

    您在上面演示的代码接收来自表单输入的电话号码参数:const phoneNumberInput = document.querySelector("#cs-phone");。这是一个电话号码的输入。您需要在 Laravel 应用程序中修改表单以输入多个电话号码,并在连续调用 callServer() 时遍历它们。

    您还可以在API Reference Documentation 上阅读有关语音 API 以及各种参数及其数据类型的更多信息。

    【讨论】:

    • 抱歉,我的问题中的“多个”是指 3 个用户/客服使用相同的路由同时拨打不同的号码。
    • 不用担心。是的,您可以通过此路由连续多次进行 API 调用。每个 API 调用都会连续发起一个新的语音调用。 this guide 中提到了容量限制。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-12-28
    • 1970-01-01
    • 2023-04-09
    • 2020-04-14
    • 1970-01-01
    • 2014-02-20
    • 2019-10-01
    相关资源
    最近更新 更多