我正在使用Swift和Python的新Twilio可编程语音SDK。我已经开始了相应的快速启动项目,并且大部分工作都是如此。我能够获得有效的访问令牌,我能够成功创建一个呼叫,我甚至能够接收呼叫。问题出在房子的来电方面。
当我尝试通过Swift SDK拨打电话时,呼叫会在开始响铃之前断开连接。
我在Twilio文档中读到,如果您不处理client.calls.create
事件,status_callback
函数将立即返回完成状态。我试图添加这个,但每当我这样做时,我都会收到错误,指出密钥status_callback
不是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()
}
}
答案 0 :(得分:2)
Twilio开发者传道者在这里。
您的Swift代码表示您的电话号码现在已在服务器上进行硬编码。正如Robert所说,问题在于,当您从Twilio回调到/outbound
端点时,您正在使用REST API生成呼叫。
实际发生的是当你在设备上generate the call in Swift启动应用程序的调用时。然后,Twilio向您的/outbound
端点发出HTTP请求,以查看如何处理该呼叫。因此,您需要回复generating a new call with the REST API,而不是TwiML来告诉Twilio接下来的呼叫该怎么做。
在这种情况下,听起来你正试图dial直接进入另一个number。为此,您应该尝试以下响应:
@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)
如果有帮助,请告诉我。
答案 1 :(得分:1)
注意:我还在您使用Twilio支持创建的故障单中作出回复。
请检查您的帐户调试程序,查看您收到的所有错误通知。这是一个例子:
尝试从中检索内容 https://voiceapp-twilio.herokuapp.com/outgoing https://voiceapp-twilio.herokuapp.com/outgoing返回了HTTP 状态代码500。
Python Web服务器返回了一条错误消息,其中包括:
TypeError:create()得到了一个意外的关键字参数 ' status_events' // Werkzeug Debugger
它看起来像Python outgoing()函数中的代码错误。最值得注意的是,当您实际应该返回TwiML时,您正在尝试使用REST API来创建新的调用。您应该返回包含拨号动词的TwiML以创建拨出呼叫支路。