2017-02-04 79 views
2

我正在关注使用Heroku上的python部署的,并且能够拨打电话。这是我遇到的问题。我没有修改任何TVOIncomingCall实例或PKPushRegistry的init或委托逻辑。实际上,当我编译时,日志说"pushRegistry:didUpdatePushCredentials:forType""Successfully registered for VoIP push notifications."这让我觉得我的server.py中的传入处理程序是问题。使用Twilio可编程语音SDK接收呼叫

我的问题是这样的:在python中,什么是正确的方式来触发VoIP推送通知来通知用户来电?我已经在我的应用程序中启用了VoIP服务,并生成了VoIP服务证书(.p12),并收到了有效的PUSH_CREDENTIAL_SID我的努力,但如何处理?

快速入门说打我的服务器的'placeCall'端点,所以我更新我的Twilio号码的传入路径,并相应地在仪表板中指出它,但这会导致“应用程序错误已发生”响应,每当有人打电话给我的Twilio号码。

这里是我的server.py相关代码:

import os 
from flask import Flask, request 
from twilio.jwt.access_token import AccessToken, VoiceGrant 
from twilio.rest import Client 
import twilio.twiml 

ACCOUNT_SID = 'ACxxxxxxxx' 
API_KEY = 'SKxxxxxxxxxxxxxxxx' 
API_KEY_SECRET = 'xxxxxxxxxxxxxxxx' 
PUSH_CREDENTIAL_SID = 'CRxxxxxxxxxxxxxxxx' 
APP_SID = 'APxxxxxxxxxxxxxxxx' 
ACCOUNT_AUTH = 'xxxxxxxxxxxxxxxx' 

IDENTITY = 'MyApp' #not literally 

app = Flask(__name__) 

@app.route('/accessToken') 
def token(): 
    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) 
    push_credential_sid = os.environ.get("PUSH_CREDENTIAL_SID", PUSH_CREDENTIAL_SID) 
    app_sid = os.environ.get("APP_SID", APP_SID) 

    grant = VoiceGrant(
    push_credential_sid = push_credential_sid, 
    outgoing_application_sid = app_sid 
) 

    token = AccessToken(account_sid, api_key, api_key_secret, IDENTITY) 
    token.add_grant(grant) 

    return str(token) 


@app.route('/placeCall', methods=['GET', 'POST']) 
def placeCall(): 
    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) 
    push_credential_sid = os.environ.get("PUSH_CREDENTIAL_SID", PUSH_CREDENTIAL_SID) 
    app_sid = os.environ.get("APP_SID", APP_SID) 

    CALLER_ID = request.values.get('From') 
    IDENTITY = request.values.get('To') 

    #client = Client(api_key, api_key_secret, account_sid) 
    client = Client(api_key, api_key_secret, account_sid, app_sid, push_credential_sid) 
    call = client.calls.create(to='client:' + IDENTITY, from_= 'client:' + CALLER_ID) 
    return str(call.sid) 

Identity值显然是错误的。我认为它需要等同于某个应用程序实例的引用。在快速启动python示例中,IDENTITY = 'voice_test'另外,PUSH_CREDENTIAL_SID在哪里起作用?

在此先感谢。

UPDATE
______

按@ philnash的评论,我已经嵌套在dial动词内部client名词。这是我的新/incoming端点:

@app.route('/incoming', methods=['GET', 'POST']) 
def incoming(): 
    CALLER_ID = request.values.get('From') 
    resp = twilio.twiml.Response() 
    resp.dial(client = IDENTITY, callerId = CALLER_ID, record = "record-from-answer-dual") 
    return str(resp) 

现在,这导致在调试器,说明“未知的或意外的嵌套元素”作为一个可能的原因的“架构验证警告”。我是否错误地注册了客户端?旧的SDK允许你显式传入你的clientName作为参数。

IDENTITY串在我的server.py是:

  1. 定义的任何方法范围之外。
  2. 用于生成accessToken
  3. 嵌套在client名词的dial动词。

回答

1

Twilio开发者传道这里。

/placeCall终端不适合您的Twilio号码的来电webhook。在这个例子中,它被用来简单地生成一个到客户端的呼叫。

而是,您的传入呼叫webhook应该指向一个端点,该端点将返回一些TwiML指示Twilio拨打您的客户端。 TwiML只是XML的一个子集,您需要的元素是<Dial>,嵌套<Client>。你的端点应该返回类似于:

<Response> 
    <Dial> 
    <Client>YOUR_CLIENT_NAME</Client> 
    </Dial> 
</Response> 

让我知道这是否有帮助。

更新

基于对问题的更新,我们现在需要产生这种TwiML Python编写的。您可以使用Python的with语法将nest TwiMLTwilio Python helper library一起使用。我相信这应该工作:

@app.route('/incoming', methods=['GET', 'POST']) 
def incoming(): 
    CALLER_ID = request.values.get('From') 
    resp = twilio.twiml.Response() 
    with resp.dial(callerId = CALLER_ID, record = "record-from-answer-dual") as dial: 
     dial.client(IDENTITY) 
    return str(resp) 
+0

感谢菲尔的回应!我已经更新了我原来的问题。请参阅更新部分中的注释。 :) –

+0

感谢您的更新。我认为你没有正确地进行嵌套,请检查我的更新答案。行! – philnash

+0

行!现在我们到了某个地方!更新服务器与您的建议,现在变得'错误 - 52134 - 无效APNs设备令牌'。我将重新生成并上传新的VoIP服务证书并更新我的推送凭据SID。感谢菲尔。 –

0

使用新的推送凭证SID更新应用服务器的server.py文件中的PUSH_CREDENTIAL_SID值。它跟以下常量在文件的顶部:

ACCOUNT_SID = 'AC***' 
API_KEY = 'SK***' 
API_KEY_SECRET = '***' 
PUSH_CREDENTIAL_SID = 'CR***' 
APP_SID = 'AP***' 

而在你placeCall功能:

def placeCall(): 
    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) 
    push_credential_sid = os.environ.get("PUSH_CREDENTIAL_SID", PUSH_CREDENTIAL_SID) 
    app_sid = os.environ.get("APP_SID", APP_SID) 

好像你还缺少从上面该APP_SID是参考包含一些调用说明的TwiML app

+0

谢谢你的回应梅根!我应该从一开始就共享更多的代码,但大部分你所说的实际上已经在我的server.py中。我没有在'placeCall'函数中包含最后两行。但是,它现在在那里,但调用我的Twilio号码仍然导致可怕的“应用程序错误已发生”响应消息。 –