首页 > 解决方案 > twilio/python/flask:呼叫转移,但如果没有及时回答,则重定向到语音信箱

问题描述

我已经编写了一个烧瓶应用程序(使用 python3),我已经在 twilio 注册了它来响应我的 twilio 提供的电话号码的来电。我可以让它路由到语音邮件,挂断,忽略呼叫,然后转发到另一个电话号码,我在这里打电话给这个target号码。

但是有一个功能我无法弄清楚如何在这个twilio//应用程序中实现pythonflask如果我的应用程序逻辑没有拒绝来电号码,我希望将呼叫转发到目标号码。但是,如果没有人在 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/voicemail?Email=USER@DOMAIN.COM&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 中实现这一点。

标签: python-3.xflasktwilio

解决方案


您应该为 forward() 函数的动词定义一个动作 URL。对该操作 URL 的请求(将引导回 Flask 应用程序的 URL)上的 DialCallStatus 将让您知道调用是否成功。如果调用未成功“完成”,您将路由到您的 VM 逻辑,否则 . 动词的默认超时是 30 秒,所以你很好。

关键逻辑在下面的函数中,将逻辑移植到 Python 应该不难。

在函数中创建语音邮件操作 https://www.twilio.com/docs/wireless/tutorials/communications-guides/implement-voicemail#create-voicemail-action-in-functions

所以基本上对于上述功能,如果 DialCallStatus 完成,您要挂断呼叫,否则路由到 VM/Twimlet。


推荐阅读