Voice Interactive Service APIs

Connect Yeastar S-Series VoIP PBX and Application System to offer customers voice interactive service.

Scenario

IVR (Interactive Voice Response) is an automated telephony system that interacts with human callers. IVR responds customers with pre-recorded voice or TTS (Text to Speech) prompts, and provides guidance for customers by voice menus. IVR is widely used in information query & confirmation, questionnaire, satisfaction survey and promotion. With Yeastar S-Series VoIP PBX API, Application System and PBX can be integrated to help customers accomplish routine tasks in the IVR, assist company in automatically gathering and confirming customers information and so on, which saves man-hours and improves work efficiency.

Example of IVR application

Take service-processing as an example: Application System makes an outbound call to a customer, plays a voice prompt to inform customer of service type and provides guidance for operation. After customer enters corresponding verification code, the service is processed successfully.

  1. The Application System sends a request to API interface to make an outbound call to a customer via IVR. When customer answers the call, the system plays the prompt of IVR 6500.
  2. Customer presses 1 on keypad according to voice prompt. PBX responds by transferring the call to IVR 6501, and prompting customer to enter verification code.
  3. Customer enters verification code according to voice prompt. When receiving the key event, PBX plays hold music to customer, generates a DTMF report, and sends the DTMF report to Application System.
  4. After receiving DTMF report, the Application System verifies customer information (in DTMF report), and sends a call-transfer request to PBX according to the verification result.
    • Verify success: PBX transfers the call to IVR 6502, and plays a voice prompt to inform customer of the successful operation.
    • Verify failed: PBX transfers the call to IVR 6503, and plays a voice prompt to inform customer of the wrong code and require a re-entered verification code.

Make an outbound call through IVR

  1. Application System sends a request to API interface to make an outbound call through IVR.
  2. After receiving the request, PBX makes an outbound call to customer through IVR.

    For API interface, refer to Call an External Number via IVR.

  3. PBX informs Application System of call status in real time.

    For API report of ringing status, refer to 'Ringing' Report and 'Ring Back' Report. For API report of answering status, refer to 'Answer a Call' Report.

DTMF report

  1. Customer presses keys on keypad according to voice prompt.
  2. PBX gathers key information, generates a 'Keypress' Report and sends the report to Application System.

Transfer outbound call to IVR

  1. After receiving a DTMF report and verifying customer information (in DTMF report), Application System sends a request to API interface to transfer the call to IVR.
  2. After receiving the request, PBX transfers the call to corresponding IVR, and plays the IVR's voice prompt to customer.

    For API interface, refer to Transfer Outbound Calls.

IVR configuration

  1. On PBX web page, add an IVR.

  2. Configure IVR prompt.

    The wav file generated from TTS should be mounted to network drive so that PBX can retrieve the file.

    1. Upload IVR prompt to network drive, and set the IVR folder to "Shared".

    2. Mount the network drive to PBX.

      The path for the first mounted network drive is /tmp/media/networkdisk1.

  3. Set IVR voice menu.

    Contact Yeastar Support to obtain the script of IVR voice menu.

    Log in PBX web page, go to /ysdisk/support//customcfg/extensions_support.conf via SSH, and edit extensions_support.conf.

    • IVR 6500: Inform customer of current service type, and prompt customer to press 1 on keypad for appointment.
      [ivr_6500]
      exten = 6500,1,NoOp(6500)
      exten = 6500,n,Set(TIMEOUT(digit)=3)
      exten = 6500,n,Background(/tmp/media/networkdisk1/notice) //notice.wav   This is xxx Service
      exten = 6500,n,Background(/tmp/media/networkdisk1/${EXTEN}) //The file is named after callee's phone number. Different voice prompts for different callees. The file is temporarily named as test.wav. Prompt message: Make an appointment for road test on March 12
      exten = 6500,n,Background(/tmp/media/networkdisk1/confirm}) //confirm.wav  Press 1 to confirm
      exten = 6500,n,UserEvent(PlayPromptEnd,Ivrid: ${EXTEN})
      exten = 6500,n,WaitExten(1)
      exten = 6500,n,Set(TIMEOUT(digit)=3)
      exten = 6500,n,Background(/tmp/media/networkdisk1/notice) //notice.wav This is xxx Service
      exten = 6500,n,Background(/tmp/media/networkdisk1/${EXTEN}) //The file is named after callee's phone number. Different voice prompts for different callees. The file is temporarily named as test.wav. Prompt message: Make an appointment for road test on March 12
      exten = 6500,n,Background(/tmp/media/networkdisk1/confirm}) //confirm.wav   Press 1 to confirm
      exten = 6500,n,UserEvent(PlayPromptEnd,Ivrid: ${EXTEN})
      exten = 6500,n,WaitExten(1)
      exten = 6500,n,ExecIf($[${Ivr2outbound} = yes]?Set(CDR(Ivr2outbound)=yes))
      exten = 6500,n,ExecIf($[${Ivr2outbound} = yes]?Set(CDR(INGORELOCAL1CDR)=yes))
      exten = 6500,n,Goto(t,1)
      exten = 1,1,ExecIf($[${Ivr2outbound} = yes]?Set(CDR(Ivr2outbound)=yes))
      exten = 1,2,ExecIf($[${Ivr2outbound} = yes]?Set(CDR(INGORELOCAL1CDR)=yes))
      exten = 1,3,ExecIf($[${CHANDISABLERECORD} = yes]?Noop(skip setting disablerecord again):Set(CHANDISABLERECORD=no))
      exten = 1,4,Goto(ivrs,6501,1)
      exten = unknown,1,NoOp(No Action)
    • IVR6501: Prompt the customer to press 1 on keypad to enter IVR 6501, and then enter verification code . After entering verification code, the customer can hear another prompt and hold music.
      [ivr_6501]
      exten = 6501,1,NoOp(6501)
      exten = 6501,n,Set(TIMEOUT(digit)=3)
      exten = 6501,n,Background(/tmp/media/networkdisk1/password) //password.wav  Enter the verification code for appointment, and end with #
      exten = 6501,n,UserEvent(PlayPromptEnd,Ivrid: ${EXTEN})
      exten = 6501,n,WaitExten(4)
      exten = 6501,n,Set(TIMEOUT(digit)=3)
      exten = 6501,n,Background(/tmp/media/networkdisk1/password) //password.wav  Enter the verification code for appointment, and end with #
      exten = 6501,n,UserEvent(PlayPromptEnd,Ivrid: ${EXTEN})
      exten = 6501,n,WaitExten(4)
      exten = 6501,n,ExecIf($[${Ivr2outbound} = yes]?Set(CDR(Ivr2outbound)=yes))
      exten = 6501,n,ExecIf($[${Ivr2outbound} = yes]?Set(CDR(INGORELOCAL1CDR)=yes))
      exten = _X.#,1,UserEvent(DtmfEndString,Info: ${EXTEN})
      exten = _X.#,n,Playback(/tmp/media/networkdisk1/holdon) //holdon.wav   Wait a moment, please
      exten = _X.#,n,Playback(/tmp/media/networkdisk1/macroform-the_simplicity) //Play hold music
      exten = _X.#,n,Playback(/tmp/media/networkdisk1/holdon) //Wait a moment, please
      exten = _X.#,n,Playback(/tmp/media/networkdisk1/macroform-the_simplicity) //Play hold music
      exten = _X.#,n,NoOp(exten:${EXTEN})
      exten = _X.#,n,Goto(ivrs,6501,1)
      exten = 6501,n,Goto(t,1)
      exten = t,1,ExecIf($[${Ivr2outbound} = yes]?Set(CDR(Ivr2outbound)=yes))
      exten = t,2,ExecIf($[${Ivr2outbound} = yes]?Set(CDR(INGORELOCAL1CDR)=yes))
      exten = t,3,ExecIf($[${CHANDISABLERECORD} = yes]?Noop(skip setting disablerecord again):Set(CHANDISABLERECORD=no))
      exten = t,4,Goto(always-Hangup,h,1)
      exten = unknown,1,NoOp(No Action)
    • IVR6502: If verification succeeds, transfer the call to IVR 6502 to inform customer of the successful operation, and then end the call.
      [ivr_6502]
      exten = 6502,1,NoOp(6502)
      exten = 6502,n,Set(TIMEOUT(digit)=3)
      exten = 6502,n,Background(/tmp/media/networkdisk1/ok) //Appointment made, bye
      exten = 6502,n,UserEvent(PlayPromptEnd,Ivrid: ${EXTEN})
      exten = 6502,n,WaitExten(1)
      exten = 6502,n,ExecIf($[${Ivr2outbound} = yes]?Set(CDR(Ivr2outbound)=yes))
      exten = 6502,n,ExecIf($[${Ivr2outbound} = yes]?Set(CDR(INGORELOCAL1CDR)=yes))
      exten = 6502,n,Goto(t,1)
      exten = t,1,ExecIf($[${Ivr2outbound} = yes]?Set(CDR(Ivr2outbound)=yes))
      exten = t,2,ExecIf($[${Ivr2outbound} = yes]?Set(CDR(INGORELOCAL1CDR)=yes))
      exten = t,3,ExecIf($[${CHANDISABLERECORD} = yes]?Noop(skip setting disablerecord again):Set(CHANDISABLERECORD=no))
      exten = t,4,Goto(always-Hangup,h,1)
      exten = unknown,1,NoOp(No Action)
    • IVR6503: If verification fails, transfer the call to IVR 6503 to ask customer to re-enter verification code. When the code is verified successfully, transfer the call to IVR 6502; if not, transfer the call to IVR 6503.
      [ivr_6503]
      exten = 6503,1,NoOp(6503)
      exten = 6503,n,Set(TIMEOUT(digit)=3)
      exten = 6503,n,Background(/tmp/media/networkdisk1/password1) //password1.wav Verification code error, please re-enter the verification code for appointment, and end with #
      exten = 6503,n,UserEvent(PlayPromptEnd,Ivrid: ${EXTEN})
      exten = 6503,n,WaitExten(4)
      exten = 6503,n,Set(TIMEOUT(digit)=3)
      exten = 6503,n,Background(/tmp/media/networkdisk1/password1) //password1.wav Verification code error, please re-enter the verification code for appointment, and end with #
      exten = 6503,n,UserEvent(PlayPromptEnd,Ivrid: ${EXTEN})
      exten = 6503,n,WaitExten(4)
      exten = 6503,n,ExecIf($[${Ivr2outbound} = yes]?Set(CDR(Ivr2outbound)=yes))
      exten = 6503,n,ExecIf($[${Ivr2outbound} = yes]?Set(CDR(INGORELOCAL1CDR)=yes))
      exten = _X.#,1,UserEvent(DtmfEndString,Info: ${EXTEN})
      exten = _X.#,n,Playback(/tmp/media/networkdisk1/holdon) //holdon.wav Wait a moment, please
      exten = _X.#,n,Playback(/tmp/media/networkdisk1/macroform-the_simplicity) //Play hold music
      exten = _X.#,n,Playback(/tmp/media/networkdisk1/holdon) //Wait a moment, please
      exten = _X.#,n,Playback(/tmp/media/networkdisk1/macroform-the_simplicity) //Play hold music
      exten = _X.#,n,NoOp(exten:${EXTEN})
      exten = _X.#,n,Goto(ivrs,6503,1)
      exten = 6503,n,Goto(t,1)
      exten = t,1,ExecIf($[${Ivr2outbound} = yes]?Set(CDR(Ivr2outbound)=yes))
      exten = t,2,ExecIf($[${Ivr2outbound} = yes]?Set(CDR(INGORELOCAL1CDR)=yes))
      exten = t,3,ExecIf($[${CHANDISABLERECORD} = yes]?Noop(skip setting disablerecord again):Set(CHANDISABLERECORD=no))
      exten = t,4,Goto(always-Hangup,h,1)
      exten = unknown,1,NoOp(No Action)