在环形系统中处理忙/无应答

2024-04-20 04:00:02 发布

您现在位置:Python中文网/ 问答频道 /正文

我已经围绕这个主题做了一些搜索,并参考了相关的API参考,但是我仍然在努力实现这一点。在

我试图用Python/Flask和Python-twilio库构建一个系统,该系统将执行以下操作:

  1. 用户来电,听到消息
  2. 应用程序同时拨出n个组中的第一个组,其中一个组是一个包含元数据(如名称)的数字列表。在代码中用数字列表的值表示的dict。(k[v]=[0,1,n])
  3. 如果小组中有人(代理人)回答,请他们输入确认数字以继续。确认后,将它们连接到用户。在
  4. 如果组中的代理没有接听,请尝试组中的下一个代理(拨打他们的号码),然后返回步骤3。在

好吧,代码也一样。这已经被分解成基本的逻辑。不幸的是,我还没有完全掌握Flask应用程序的状态,所以我一直在使用Python全局变量访问。我想远离这一点,因为如果有两个调用应用程序,应用程序可能会工作不正常。在

# excluding flask import/setup
from twilio import twiml
from twilio.rest import TwilioRestClient

agents = OrderedDict()
agents['Foo'] = ["+440000000000", "+440000000001"]
agents['Bar'] = ["+440000000002", "+440000000003"]

caller = None
@app.route('/notify', methods=['POST'])
def notify():
    """Log all call status callbacks"""
    global caller
    called = request.values.get('Called')
    call_status = request.values.get('CallStatus') 
    timestamp = request.values.get('Timestamp') # e.g. Wed, 02 Mar 2016 15:42:30 +0000
    call_statuses = {
        "initiated": "[%s@%s] INITIATED",
        "ringing": "[%s@%s] RINGING",
        "in-progress": "[%s@%s] IN-PROGRESS",
        "answered": "[%s@%s] ANSWERED",
        "failed": "[%s@%s] CALL FAILED",
        "no-answer": "[%s@%s] NO ANSWER",
        "busy": "[%s@%s] BUSY",
        "completed": "[%s@%s] COMPLETED"
        }
    called_name = [i for i in agents.items() if called in i][0][0]
    print("--%s-- %s" % (timestamp, call_statuses[call_status] % (called_name, called)))

    return jsonify({"status": 200})

def new_twilio_client():
    _ = TwilioRestClient(app.config['TWILIO_ACCOUNT_SID'], app.config['TWILIO_AUTH_TOKEN'])
    return _

@app.route('/welcome', methods=['GET'])
def welcome():
    global caller
    response = twiml.Response()
    response.say("Welcome message", voice="alice")
    caller = request.values.get("Caller")
    # log the call/caller here
    response.redirect(url_for(".start"), _external=True, method="GET")
    return str(response)

@app.route('/start', methods=['GET'])
def start():
    response = twiml.Response()
    response.say("Trying first agent")
    response.enqueue("q")
    client = new_twilio_client()
    for number in agents['Foo']:
        client.calls.create(to=number, Timeout=12, ifMachine="Hangup", statusCallbackEvent="initiated ringing answered completed", StatusCallback=url_for(".notify", _external=True), from_=app.config['TWILIO_CALLER_ID'], url=url_for(".whisper", _external=True), method="GET")        
    return str(response)

@app.route("/whisper", methods=['GET'])
def whisper():
    """Ask agent if they want to accept the call"""
    global call_sid
    response = twiml.Response()
    client = new_twilio_client()
    response.say("Press 1 to accept this call")
    response.gather(action=url_for(".did_agent_accept", _external=True), numDigits=1, timeout=3)
    return str(response)

@app.route("/did_agent_accept", methods=['POST'])
def did_agent_accept():
    """Determine if the agent accepted the call"""
    response = twiml.Response()
    digit = request.values.get('Digits', None)
    if digit == "1":
        with response.dial() as dial:
            # drop the agent into the queue we made earlier
            dial.queue("q", url=url_for(".thanks_for_waiting", _external=True))
    else:
        response.reject()
    return str(response)

@app.route("/thanks_for_waiting", methods=['GET'])
def thanks_for_waiting():
    """Thank the user"""
    response = twiml.Response()
    response.say("Thanks for waiting. You will now be connected.")
    return str(response)

@app.route('/sorry', methods=['GET'])
def sorry():
    response = twiml.Response()
    response.say("Sorry, trying again")
    response.redirect(url=url_for(".start", _external=True), method="GET")
    return str(response)

因此,我在这里使用了Twilio的排队功能将调用者放入队列中,然后使用restapi调用第一个代理的关联号码。当它们拾取并响应聚集谓词时,它们将被放入队列中。在

我遇到了一个障碍:

  • 由于回调功能的异步特性,管理无应答状态,以确定应用程序是否应该尝试下一组号码,这是很困难的。我尝试过一种解决方案,即维护一个全局列表,该列表在调用notify()时更新,最后一个给出非应答状态的数字被添加到该列表中。然后,我将agents[agent]列表的长度与这个全局列表进行比较,如果匹配,我将修改调用以尝试下一个组,但是最终结果是幻象/不正确的调用。在

我的问题是,我如何着手进行这个实时电话修改,以便清除任何现有的来电到前一组?如何改进此代码的设计?有什么明显的东西我错过了吗?如有任何建议,我们将不胜感激。在


Tags: theappurl列表forgetreturnresponse