IVR 语音互动服务应用方案

通过 API 对接 S系列 IPPBX 和业务系统,提供语音互动服务。

应用场景

语音互动服务,是一种功能强大的电话自动服务系统。它用预先录制或 TTS 文本转语音技术合成的语音进行自动应答,为客户提供语音菜单导航,常用于信息查询与确认、问卷调查、满意度调查、业务推广等。S系列 IPPBX 提供的 API 接口,可以将业务系统与 PBX 结合,通过 IVR 语音交互引导客户操作,自动完成客户的信息收集,信息确认等工作,减少人力投入,提高业务办理效率。

IVR 应用流程示例

以业务办理为例,系统呼叫用户,通过 IVR 播放业务内容和操作提示,自动引导用户输入验证码,完成业务办理。

  1. 业务系统请求 PBX 通过 IVR 呼叫用户,用户接听后,向客户播报 IVR 6500 语音。
  2. 客户根据语音提示操作按 1 键,PBX 响应按键事件,将通话转接给 IVR 6501,提示用户输入验证码。
  3. 客户根据语音提示输入验证码。PBX 收到按键信息,向客户播放等待音乐,并生成 DTMF 按键报告,将用户信息发送给业务系统。
  4. 业务系统收到按键信息报告,校验客户数据。根据校验结果向 PBX 发送通话转接请求。
    • 校验成功,PBX 将当前通话转接 IVR 6502,语音提示用户业务受理成功。
    • 校验失败,PBX 将当前通话转接 IVR 6503,提示客户验证码有误,重新输入。

IVR 拨打外线

  1. 业务系统向 PBX API 接口发送 IVR 外呼请求。
  2. PBX 收到请求,使用 IVR 呼叫客户。

    IVR 外呼对接接口请参阅 IVR 拨打外线

  3. PBX 向业务系统实时发送当前呼叫的状态。

    通话状态接口请参阅 CallStatus(通话状态变更事件)

DTMF 按键报告

  1. 客户根据语音提示输入相关信息。
  2. PBX 收集相关的按键信息,生成 “按键信息”报告,并发送给业务系统。

呼出转接 IVR

  1. 业务系统收到 DTMF 报告,验证用户信息后,向 PBX 发送通话转接请求。
  2. PBX 收到请求,将通话转接给相应的 IVR,向客户播放相应的 IVR 语音。

    对接接口请参阅 呼叫转移(盲转)

IVR 语音菜单设置

  1. 在 PBX 上创建 IVR。

  2. 设置 IVR 语音文件。

    语音由 TTS 产生 wav 文件,放到网络磁盘位置供 PBX 调用。

    1. 将 IVR 语音上传到网络存储盘,并将存储 IVR 语音的文件夹设置为共享。

    2. 将网络存储盘挂载到 PBX。

      第一个网络磁盘挂载后,路径为 /tmp/media/networkdisk1

  3. 设置 IVR 语音菜单。

    联系Yeastar技术支持获取 IVR 语音菜单脚本。

    登录 PBX 网页,使用 SSH 方式,进入/ysdisk/support//customcfg/extensions_support.conf,编辑 extensions_support.conf 文件。

    • IVR 6500:语音播报语音当前业务类型,并告知按 1 键进预约。
      [ivr_6500]
      exten = 6500,1,NoOp(6500)
      exten = 6500,n,Set(TIMEOUT(digit)=3)
      exten = 6500,n,Background(/tmp/media/networkdisk1/notice) //notice.wav   这里是 xxx 业务受理平台
      exten = 6500,n,Background(/tmp/media/networkdisk1/${EXTEN}) //以被叫手机号为命名的文件,每个被叫的语音都不一样。文件暂命名phone.wav。语音内容:为您预约3月12日科目二考试
      exten = 6500,n,Background(/tmp/media/networkdisk1/confirm}) //confirm.wav  同意请按 1
      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 这里是 XXX 业务受理平台
      exten = 6500,n,Background(/tmp/media/networkdisk1/${EXTEN}) //以被叫手机号为命名的文件,每个被叫的语音都不一样。文件暂命名test.wav。语音内容:为您预约3月12日科目二考试
      exten = 6500,n,Background(/tmp/media/networkdisk1/confirm}) //confirm.wav   同意请按1
      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:当客户听到语音提示后,按1,进入 IVR6501,可以输入短信验证码,输入完毕会继续听到相关语音,以及等待音乐。
      [ivr_6501]
      exten = 6501,1,NoOp(6501)
      exten = 6501,n,Set(TIMEOUT(digit)=3)
      exten = 6501,n,Background(/tmp/media/networkdisk1/password) //password.wav  请输入您收到约考短信验证码,按#号键结束
      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  请输入您收到约考短信验证码,按#号键结束
      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   请稍后
      exten = _X.#,n,Playback(/tmp/media/networkdisk1/macroform-the_simplicity) //播放等待音乐
      exten = _X.#,n,Playback(/tmp/media/networkdisk1/holdon) //请稍后
      exten = _X.#,n,Playback(/tmp/media/networkdisk1/macroform-the_simplicity) //播放等待音乐
      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:当系统验证通过后,转 IVR6502,告知客户业务办理成功,并挂断电话。
      [ivr_6502]
      exten = 6502,1,NoOp(6502)
      exten = 6502,n,Set(TIMEOUT(digit)=3)
      exten = 6502,n,Background(/tmp/media/networkdisk1/ok) //已经预约成功,再见!
      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:当短信验证失败,转 IVR6503,告知客户重新输入短信验证码,并且根据验证成功与否转 IVR6502 或 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验证码错误,请输入您收到约考短信验证码,按#号键结束
      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验证码错误,请输入您收到约考短信验证码,按#号键结束
      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请稍后
      exten = _X.#,n,Playback(/tmp/media/networkdisk1/macroform-the_simplicity) //播放保留音乐
      exten = _X.#,n,Playback(/tmp/media/networkdisk1/holdon) //请稍后
      exten = _X.#,n,Playback(/tmp/media/networkdisk1/macroform-the_simplicity) //播放保留音乐
      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)