Plivo呼入SIP中继问题:无法添加目标号码信息
解决多个Plivo号码转接至Asterisk时的号码区分问题
我来帮你搞定这个问题——你需要根据不同的Plivo呼入号码来处理转接,核心是利用Plivo触发中继应用时发送的请求参数,其中To参数就是当前呼入的那个Plivo号码,我们可以通过它来识别不同的号码并动态生成Plivo XML。
下面分两种常见场景给出具体解决方案:
场景1:根据不同Plivo号码转接至Asterisk不同目的地
如果你的需求是不同的Plivo号码对应Asterisk里不同的分机/线路,可以通过判断To参数的值,动态生成对应的转接目标。
下面用Python Flask举个实际的代码例子(你也可以用其他后端语言实现,逻辑完全一致):
from flask import Flask, request, make_response import plivo app = Flask(__name__) @app.route('/plivo-incoming', methods=['POST']) def handle_incoming_call(): # 获取呼入的Plivo号码(Plivo会通过POST请求自动传递这个参数) incoming_plivo_num = request.form.get('To') # 根据不同的Plivo号码设置对应的Asterisk目标 target_sip_uri = "" if incoming_plivo_num == "+18001234567": # 比如这个号码转接至Asterisk分机1001 target_sip_uri = "sip:1001@your-asterisk-ip:5060" elif incoming_plivo_num == "+18007654321": # 这个号码转接至Asterisk分机1002 target_sip_uri = "sip:1002@your-asterisk-ip:5060" else: # 默认转接至总机 target_sip_uri = "sip:main-line@your-asterisk-ip:5060" # 生成Plivo XML响应 xml_response = plivo.XML.Response() dial_element = xml_response.addDial(callerId="18004321321") dial_element.addUser(target_sip_uri) # 返回XML格式的响应给Plivo return make_response(xml_response.to_xml(), 200, {"Content-Type": "application/xml"}) if __name__ == '__main__': app.run(host='0.0.0.0', port=5000)
场景2:将Plivo号码信息传递给Asterisk内部处理
如果希望把呼入的Plivo号码信息传给Asterisk,让Asterisk内部根据这个号码做逻辑处理(比如触发不同IVR),可以通过自定义SIP头或者在SIP URI中附加参数的方式实现。
方法1:添加自定义SIP头
在生成Plivo XML时,给Dial元素添加自定义头,把Plivo号码传递过去:
from flask import Flask, request, make_response import plivo app = Flask(__name__) @app.route('/plivo-incoming', methods=['POST']) def handle_incoming_call(): incoming_plivo_num = request.form.get('To') xml_response = plivo.XML.Response() dial_element = xml_response.addDial(callerId="18004321321") # 添加自定义SIP头,将Plivo号码传给Asterisk dial_element.addHeader("X-Incoming-Plivo-Number", incoming_plivo_num) dial_element.addUser("sip:yoda12312312@phone.plivo.com") return make_response(xml_response.to_xml(), 200, {"Content-Type": "application/xml"})
之后在Asterisk的拨号计划中,就可以通过SIP_HEADER(X-Incoming-Plivo-Number)变量获取这个号码,比如:
[from-plivo] exten => _.,1,NoOp(Incoming Plivo Number: ${SIP_HEADER(X-Incoming-Plivo-Number)}) ; 根据号码执行不同逻辑 same => n,GotoIf($["${SIP_HEADER(X-Incoming-Plivo-Number)}"="+18001234567"]?ivr-sales,1) same => n,GotoIf($["${SIP_HEADER(X-Incoming-Plivo-Number)}"="+18007654321"]?ivr-support,1) same => n,Dial(SIP/main-line)
方法2:在SIP URI中附加参数
也可以直接把Plivo号码作为参数附加在SIP URI后面:
target_uri = f"sip:yoda12312312@phone.plivo.com?plivo_num={incoming_plivo_num}" dial_element.addUser(target_uri)
在Asterisk中,可以通过${ARG1}或者解析SIP URI的方式获取这个参数(具体取决于你的Asterisk配置)。
最后要注意的点
- 确保你的中继应用服务器能被Plivo访问到(需要公网IP+开放对应端口)
- 在Plivo控制台中,把每个号码的呼入设置都指向你的中继应用URL
- 测试时可以打印Plivo发送的所有请求参数,确认
To参数的格式(比如是否带+号)
内容的提问来源于stack exchange,提问作者Nickolai Druz'
相关产品推荐
相关产品推荐

