Python Twilio可编程语音呼叫立即完成

Python Twilio可编程语音呼叫立即完成,python,ios,twilio,Python,Ios,Twilio,我正在使用带有Swift和Python的新的Twilio可编程语音SDK。我已经开始了各自的快速启动项目,并且在大多数情况下,这些项目都是有效的。我能够获得一个有效的访问令牌,我能够成功地创建一个呼叫,我甚至能够接收呼叫。问题出在打电话的那一方 当我试图通过Swift SDK拨打电话时,电话在另一端开始响之前就断开了 我在Twilio文档中读到,client.calls.create函数将立即返回完成状态,如果您不处理status\u回调事件。我曾尝试添加此项,但每次添加时,都会出现一个错误,即

我正在使用带有Swift和Python的新的Twilio可编程语音SDK。我已经开始了各自的快速启动项目,并且在大多数情况下,这些项目都是有效的。我能够获得一个有效的访问令牌,我能够成功地创建一个呼叫,我甚至能够接收呼叫。问题出在打电话的那一方

当我试图通过Swift SDK拨打电话时,电话在另一端开始响之前就断开了

我在Twilio文档中读到,
client.calls.create
函数将立即返回完成状态,如果您不处理
status\u回调
事件。我曾尝试添加此项,但每次添加时,都会出现一个错误,即键
status\u回调
不是
client.calls.create
函数的有效参数。此外,我在任何地方都找不到任何实际如何处理呼叫状态的示例

我的问题是我到底做错了什么?任何帮助都将不胜感激

这是我的Python代码

@app.route('/outgoing', methods=['GET', 'POST'])
def outgoing():

  account_sid = os.environ.get("ACCOUNT_SID", ACCOUNT_SID)
  api_key = os.environ.get("API_KEY", API_KEY)
  api_key_secret = os.environ.get("API_KEY_SECRET", API_KEY_SECRET)

  from_number = [HARD_CODED_PHONE_NUMBER_FOR_CALLER]
  to_number = [HARD_CODED_PHONE_NUMBER_FOR_RECIPIENT]

  client = Client(api_key, api_key_secret, account_sid)
  call = client.calls.create(url='http://twimlets.com/holdmusic?Bucket=com.twilio.music.ambient', to=to_number, from_=from_number)

  # return str(call.sid)
  resp = twilio.twiml.Response()
  resp.say("Thank you for calling");
  return str(resp)
这是我的相关iOS代码。请记住,这不是我的全部来源。我只提供了在这种情况下需要的东西。我的完整源代码确实包括处理注册表和邀请代理。我也没有包括显示/隐藏活动调用UI的源代码,因为这没有问题。这只是为了说明我是如何打电话和接收呼叫完成委托的

class VoiceManager: NSObject, PKPushRegistryDelegate, TVONotificationDelegate, TVOCallDelegate, AVAudioPlayerDelegate {

    //MARK: - Singleton

    static let sharedManager = VoiceManager()

    //MARK: - Private Constants

    private let baseURLString = [MY_WEBAPP_ENDPOINT]
    private let accessTokenEndpoint = "/accessToken"

    //MARK: - Private Variables

    private var deviceTokenString:String?

    private var callInvite: TVOCallInvite?
    private var call: TVOCall?
    private var status: VoiceStatus = .idle

    //MARK: - Getters

    private func fetchAccessToken() -> String? {

        guard let accessTokenURL = URL(string: baseURLString + accessTokenEndpoint) else {
            return nil
        }

        return try? String.init(contentsOf: accessTokenURL, encoding: .utf8)
    }

    func placeCall(withParameters params: VoiceParameters, completion: @escaping (_ success: Bool, _ error: VAError?) -> Void) {

        if (call != nil) {
            call?.disconnect()
            completion(false, .phoneCallInProgress)
            status = .callEnded
            hideActiveCallUI()

        } else {

            guard let accessToken = fetchAccessToken() else {
                completion(false, .phoneAccessTokenFetchFailed)
                return
            }

            guard let paramsDict = params.toDictionary() else {
                completion(false, .phoneAccessTokenFetchFailed)
                return
            }

            playOutgoingRingtone(completion: { [weak self] in

                if let strongSelf = self {

                    strongSelf.call = VoiceClient.sharedInstance().call(accessToken, params: [:], delegate: strongSelf) //NOTE: The params here are not necessary as the phone numbers for now are hard coded on the server

                    if (strongSelf.call == nil) {
                        strongSelf.status = .callEnded
                        completion(false, .phoneCallFailed)
                        return

                    } else {
                        strongSelf.status = .callConnecting
                        self?.showActiveCallUI(withParameters: params)
                        completion(true, nil)
                    }
                }
            })
        }
    }

    // MARK: TVOCallDelegate
    func callDidConnect(_ call: TVOCall) {

        NSLog("callDidConnect:")

        self.call = call
        status = .inCall

        routeAudioToSpeaker()
    }

    func callDidDisconnect(_ call: TVOCall) {

        NSLog("callDidDisconnect:")

        playDisconnectSound()

        self.call = nil
        status = .callEnded

        hideActiveCallUI()
    }

    func call(_ call: TVOCall, didFailWithError error: Error) {

        NSLog("call:didFailWithError: \(error)");

        self.call = nil
        status = .callEnded
        hideActiveCallUI()
    }
}

注意:我也在您使用Twilio支持创建的票证中做出了回应

请检查您的帐户调试器,查看您收到的所有错误通知。下面是一个例子:

尝试从中检索内容 返回HTTP 状态代码500

Python web服务器返回了一条错误消息,其中包括:

TypeError:create()获取了意外的关键字参数 'status\u events'//Werkzeug调试器


这看起来像是Python outgoing()函数中的代码错误。最值得注意的是,您正试图使用RESTAPI创建一个新调用,而实际上您应该返回TwiML。您应该返回包含拨号动词的TwiML,以创建传出呼叫分支。

Twilio developer evangelist在此

您的Swift代码表示您的电话号码现在已在服务器上硬编码。正如Robert所说的那样,问题在于当您从Twilio获得对
/outbound
端点的回调时,您正在使用RESTAPI生成调用

实际发生的情况是,当您在设备上启动应用程序调用时。Twilio然后向您的
/outbound
端点发出HTTP请求,以查看如何处理该调用。因此,你需要用回复来告诉Twilio下一步该如何处理这个电话

在这种情况下,听起来你是在试图直奔另一个目标。为此,您应该尝试以下响应:

@app.route('/outgoing', methods=['GET', 'POST'])
def outgoing():
  from_number = [HARD_CODED_PHONE_NUMBER_FOR_CALLER]
  to_number = [HARD_CODED_PHONE_NUMBER_FOR_RECIPIENT]

  resp = twilio.twiml.Response()
  with resp.dial(callerId=from_number) as r:
    r.number(to_number)
  return str(resp)

如果有帮助,请告诉我。

您的TwiML应用程序语音URL指向什么?上面的
/出站
路线?是的,上面的是/出站路线。我已尝试将其设置为/incoming,但我不确定如何正确处理该事件。当我让它指向那里并调用“拨号”命令时,它仍然会断开原始呼叫,但当收件人接听时,它会在原始设备上给我回电话。嗨,感谢我们的回复。我已经回复了Twilio支持的问题,就是这个问题!好的,是的,我不明白这里要做什么,因为文档并没有真正说明当你接到一个出站呼叫时要做什么。所有快速入门项目所做的就是调用say命令。我非常感谢这里的帮助!