You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

IVR模块VXML外呼转接授权异常问题排查求助

问题

近期搭建公司IVR系统优化来电管理,需求是根据呼叫者需求转接至外部号码(如手机),但执行转接时系统返回错误:Authorization error: External call transfer not authorized,日志中对应error connection noauthorization异常。已核查用户权限未发现异常,以下是transfercallExternal.tpl的代码片段:

<?xml version="1.0" encoding="ISO-8859-1"?>
<vxml xmlns="http://www.w3.org/2001/vxml"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xsi:schemaLocation="http://www.w3.org/2001/vxml http://www.w3.org/TR/voicexml21/vxml.xsd"
      version="2.1" application="$vxmlUniverse.getDocumentRootURL($application.name)">

    #set ($breakTimeMetric = "ms")
    #if ($this.isCallTransferMultiple)
    #set ($rerout = "enable")
    #else
    #set ($rerout = "disable")
    #end

    <form id="$this.label">
        <block>
            #set( $index = 1 )
            #set( $languages = $vxmlUniverse.getApplicationLanguages($application.name) )
            #foreach( $languageName in $languages )
            #if( $index == 1 )
            <if cond="application.languageCode == '$languageName'">
                <goto next="#$languageName"/>
                #else
                #if($index == $languages.size())
                <else/>
                #else
                <elseif cond="application.languageCode == '$languageName'"/>
                #end
                <goto next="#$languageName"/>
                #end
                #if($index == $languages.size())
            </if>
            #end
            #set( $index = $index + 1 )
            #end
        </block>

    </form>

    #foreach( $languageName in $languages )
    #generateForm( $languageName )
    #end

    <form id="transfert">
        <var name="phoneNumber" expr="application.${this.phoneNumber.name}"/>
        <!-- Use specifics atos property -->
        <property name="net.company.ss.transfer.multiple" value="$rerout"/>
        <property name="net.company.ss.transfer.context.binary" value="$this.isCallContextBinary"/>
        <property name="net.company.ss.transfer.caller.number" value="application.${this.phoneNumber.name}"/>
        <property name="net.company.ss.transfer.caller.view" value="$this.callerView"/>

        <transfer
                name="callTransfer"
                connecttimeout="${this.connectTimeout}s"
                destexpr="'tel:' + phoneNumber"
                type="consultation"
                #if ($this.waitingSound !="" )
                transferaudio="${this.waitingSound}"
                #end
                >

            <!-- ******************* -->
            <!-- Transfer SUCCESSFUL -->
            <!-- ******************* -->
            <!-- catch the transfer success and exit -->
            <!-- catch the transfer success and exit -->
            <catch event="connection.disconnect.transfer">
                <log>connection disconnect transfer</log>
                #foreach( $choice in $this.outputs.successOutput)
                <goto
                        next="$vxmlUniverse.getModuleURL($application.name, ${choice.scriptRefName}, ${choice.moduleRefName})"/>
                #end

            </catch>


            <!-- **************** -->
            <!-- No authorization -->
            <!-- **************** -->
            <catch event="error.connection.noauthorization">
                <log>error connection noauthorization</log>
                #foreach( $choice in $this.outputs.failureOutput)
                <goto
                        next="$vxmlUniverse.getModuleURL($application.name, ${choice.scriptRefName}, ${choice.moduleRefName})"/>
                #end
            </catch>

            <!-- *************** -->
            <!-- Bad destination -->
            <!-- *************** -->
            <catch event="error.connection.baddestination">
                <log>error connection baddestination</log>
                #foreach( $choice in $this.outputs.failureOutput)
                <goto
                        next="$vxmlUniverse.getModuleURL($application.name, ${choice.scriptRefName}, ${choice.moduleRefName})"/>
                #end
            </catch>

            <!-- ******** -->
            <!-- No route -->
            <!-- ******** -->
            <catch event="error.connection.noroute">
                <log>error connection noroute</log>
                #foreach( $choice in $this.outputs.failureOutput)
                <goto
                        next="$vxmlUniverse.getModuleURL($application.name, ${choice.scriptRefName}, ${choice.moduleRefName})"/>
                #end
            </catch>

            <!-- *********** -->
            <!-- No resource -->
            <!-- *********** -->
            <catch event="error.connection.noresource">
                <log>error connection noresource</log>
                #foreach( $choice in $this.outputs.failureOutput)
                <goto
                        next="$vxmlUniverse.getModuleURL($application.name, ${choice.scriptRefName}, ${choice.moduleRefName})"/>
                #end
            </catch>

            <!-- **************** -->
            <!-- Connection error -->
            <!-- **************** -->
            <!-- catch the transfer errors -->
            <catch event="error.connection">
                <log>error connection</log>
                #foreach( $choice in $this.outputs.failureOutput)
                <goto
                        next="$vxmlUniverse.getModuleURL($application.name, ${choice.scriptRefName}, ${choice.moduleRefName})"/>
                #end
            </catch>

            <!-- ********************************* -->
            <!-- Unsupported transfer consultation -->
            <!-- ********************************* -->
            <catch event="error.unsupported.transfer.consultation">
                <log expr="error unsupported transfer consultation"/>
                #foreach( $choice in $this.outputs.failureOutput)
                <goto
                        next="$vxmlUniverse.getModuleURL($application.name, ${choice.scriptRefName}, ${choice.moduleRefName})"/>
                #end
            </catch>

            <!-- *************** -->
            <!-- Unsupported URI -->
            <!-- *************** -->
            <catch event="error.unsupported.uri">
                <log expr="error unsupported uri"/>
                #foreach( $choice in $this.outputs.failureOutput)
                <goto
                        next="$vxmlUniverse.getModuleURL($application.name, ${choice.scriptRefName}, ${choice.moduleRefName})"/>
                #end
            </catch>

            <filled>
                #foreach( $choice in $this.outputs.successOutput)
                <goto
                        next="$vxmlUniverse.getModuleURL($application.name, ${choice.scriptRefName}, ${choice.moduleRefName})"/>
                #end
            </filled>

        </transfer>
    </form>

</vxml>

现求助:

  1. 是否遇到过IVR模块中外呼转接至外部号码的类似授权问题?
  2. IVR配置中是否有遗漏的特定参数?

解决方案

类似授权问题的常见场景

这类问题在VXML IVR系统中很普遍,核心原因集中在三个层面:

  • 平台全局限制:多数IVR部署平台默认禁用外部号码转接,需在后台控制台开启“允许外呼转移”的全局权限,这和普通用户账号权限是分开的。
  • 号码白名单机制:部分系统要求所有可转接的外部号码必须提前加入白名单,即便账号有转接权限,不在白名单内的号码也会触发授权失败。
  • 套餐服务限制:如果IVR绑定的服务套餐不包含外呼转接功能,系统会直接返回授权错误。

可能遗漏的配置参数

从你的VXML代码来看,已配置了net.company.ss.transfer系列自定义属性,但还有几个关键配置需排查:

  • 平台级转接开关:检查IVR管理后台,是否存在“启用外部号码转接”“允许外呼转移”之类的全局配置项,这是最容易被忽略的点。
  • 号码格式配置:部分系统要求转接号码必须带国家码(如tel:+8613xxxxxxxxx),若phoneNumber变量仅存储本地号码,需添加前缀,或配置net.company.ss.transfer.number.format属性指定格式规则。
  • 转接类型权限:你使用的是type="consultation"(咨询式转接),部分平台需单独开启该类型的转接权限,如果仅开启盲转(type="blind")权限,也会触发授权错误。
  • 应用级权限设置:检查当前IVR应用的权限配置,是否勾选了“外部呼叫转移”权限,部分系统会区分账号权限和应用独立权限。

内容的提问来源于stack exchange,提问作者Simo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.15 13:07:02