我已经写了一个烧瓶应用程序(使用python3),我已经注册了twilio来响应来自我的twilio提供的电话号码的来电。我可以让它路由到语音邮件,挂机,忽略通话,转发到另一个电话号码,我在这里称之为target
号码。
但是有一个功能我无法弄清楚如何在这个twilio
/ python
/ flask
应用程序中实现。如果我的应用程序的逻辑没有拒绝传入的号码,我希望将呼叫转发到目标号码。但如果没有人在30秒内回答这个号码,我希望将呼叫定向到我通过twimlets
建立的语音邮件。我不知道如何在这里实现这种条件转发/语音邮件逻辑。
这必须发生在以下代码底部附近的answer_call
方法中:
import re
from flask import Flask, Response, redirect, request, send_file
from twilio.twiml.voice_response import VoiceResponse
app = Flask(__name__)
ngrokurl = 'http://XXXXXXXX.ngrok.io'
vmbase = 'http://twimlets.com/[email protected]&Transcribe=False'
vmpath = '/path/to/voicemessage.mp3'
vmurl = os.path.join(ngrokurl, 'vm')
fwd = '+1-111-111-11111'
def num(n):
return re.compile(n)
whitelist = [
num(r'^[+]11100000000$'),
num(r'^[+]11111100000$'),
num(r'^[+]11111111100$'),
]
ignorelist = [
num(r'^[+]2000'),
]
hanguplist = [
num(r'^[+]3000'),
]
def number_in(n, numlist):
if not n or not numlist:
return False
for item in numlist:
if item.search(n):
return True
return False
def voicemail():
return redirect(
'{}&Message={}'.format(vmbase, vmurl),
302
)
def ignore():
resp = VoiceResponse()
resp.play(vmurl, loop=1)
return Response(str(resp), 200, mimetype='application/xml')
def hangup():
resp = VoiceResponse()
resp.hangup()
return Response(str(resp), 200, mimetype='application/xml')
def forward():
resp = VoiceResponse()
resp.dial(fwd)
return Response(str(resp), 200, mimetype='application/xml')
@app.route('/answer', methods=['GET', 'POST'])
def answer_call():
'''
Main flask route for answering phone calls.
'''
number = request.args.get('From', None)
if not number:
return hangup()
if number_in(number, whitelist):
# Whitelisted numbers are directly forwarded.
#
# However, what I want to do here is forward to
# the target number, but then to redirect
# to voicemail if the call isn't answered
# after, say, 30 seconds. Don't know how ... ???
#
return forward()
## return voicemail()
elif number_in(number, ignorelist):
return ignore()
elif number_in(number, hanguplist):
return hangup()
else:
#
# Same question here: how do I forward
# to the target but then redirect
# to voicemail if the call isn't answered?
#
return forward()
## return voicemail()
@app.route('/vm', methods=['GET', 'POST'])
def vm():
'''
URL for the voicemail recording used within the
twimlets voicemail call. See `vmurl`, above.
'''
return send_file(vmpath, 'audio/mpeg')
if __name__ == "__main__":
app.run(debug=True)
提前感谢您提供的任何指示或建议。
PS:我知道有关于如何在python / flask环境之外执行此操作的文档。但是,我无法弄清楚如何在python / flask中实现这一点。
您应该为forward()函数定义动词的动作URL。对该操作URL的请求上的DialCallStatus(它将返回到Flask应用程序的URL)将告诉您调用是否成功。如果呼叫未成功“完成”,则将路由到VM逻辑,否则。动词的默认超时是30秒,所以你很好。
关键逻辑在下面的函数中,将逻辑移植到Python应该不难。
所以基本上对于上面的函数,如果DialCallStatus完成,你想要挂断电话,否则路由到VM / Twimlet。
感谢Alan的帮助,我解决了它。下面的代码替换了我的初始示例中的forward
和answer_call
,并添加了一个新的call_result
方法。关于我的例子的其他所有内容保持不变。
现在,REST-ful应用程序会将已批准的号码列入白名单并阻止不需要的号码。任何已批准或未阻止的号码都将转发到目标电话号码。如果20秒后没有人回答,应用程序会将呼叫路由到我的twimlet
实施的语音邮件。
显然,这个示例应用程序包含硬编码的过滤器,它只包含虚拟数据。在现实生活中,每次调用时我都会从数据存储区加载这些文件。这样,我可以从REST-ful应用程序外部修改这些过滤器,而无需重新编译甚至重新启动该应用程序。
到目前为止,我的初始编码运行良好。
def forward():
resp = VoiceResponse()
resp.dial(
fwd,
action=url_for('call_result'),
method='GET',
timeout=20
)
return Response(str(resp), 200, mimetype='application/xml')
@app.route('/answer', methods=['GET', 'POST'])
def answer_call():
number = request.args.get('From', None)
if not number:
return hangup()
elif number_in(number, whitelist):
return forward()
elif number_in(number, ignorelist):
return ignore()
elif number_in(number, hanguplist):
return hangup()
else:
return forward()
@app.route('/call', methods=['GET', 'POST'])
def call_result():
status = request.args.get('DialCallStatus', None)
if not status or status != 'completed':
return voicemail()
else:
return Response(str(resp), 200, mimetype='application/xml')